aboutsummaryrefslogtreecommitdiff
path: root/src/components/StatusBar/StatusBar.tsx
diff options
context:
space:
mode:
authorzwlucas <lucas.fariamo08@gmail.com>2026-06-05 20:52:54 +0000
committerzwlucas <lucas.fariamo08@gmail.com>2026-06-05 20:52:54 +0000
commit09f964451d7d92e9891430ec4595c1276d486aab (patch)
tree28da4483f5c28924a8c47fceb648b1baebe88224 /src/components/StatusBar/StatusBar.tsx
downloadyace-master.tar.gz
yace-master.zip
feat: uploadHEADmaster
Signed-off-by: zwlucas <lucas.fariamo08@gmail.com>
Diffstat (limited to 'src/components/StatusBar/StatusBar.tsx')
-rw-r--r--src/components/StatusBar/StatusBar.tsx163
1 files changed, 163 insertions, 0 deletions
diff --git a/src/components/StatusBar/StatusBar.tsx b/src/components/StatusBar/StatusBar.tsx
new file mode 100644
index 0000000..49f9346
--- /dev/null
+++ b/src/components/StatusBar/StatusBar.tsx
@@ -0,0 +1,163 @@
+import { useEffect, useRef } from 'react'
+import { useTabsStore } from '@/stores/useTabsStore'
+import { useSettingsStore } from '@/stores/useSettingsStore'
+
+function BranchIcon() {
+ return (
+ <svg width="11" height="11" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="shrink-0 opacity-60">
+ <line x1="6" y1="3" x2="6" y2="15" />
+ <circle cx="18" cy="6" r="3" />
+ <circle cx="6" cy="18" r="3" />
+ <path d="M18 9a9 9 0 0 1-9 9" />
+ </svg>
+ )
+}
+
+function ErrorIcon() {
+ return (
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" className="shrink-0">
+ <circle cx="12" cy="12" r="10" />
+ <line x1="12" y1="8" x2="12" y2="12" />
+ <line x1="12" y1="16" x2="12.01" y2="16" />
+ </svg>
+ )
+}
+
+function EncodingIcon() {
+ return (
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="shrink-0 opacity-60">
+ <polyline points="16 18 22 12 16 6" />
+ <polyline points="8 6 2 12 8 18" />
+ </svg>
+ )
+}
+
+function Spinner() {
+ return (
+ <svg width="10" height="10" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round" className="shrink-0 animate-spin">
+ <path d="M21 12a9 9 0 1 1-6.219-8.56" />
+ </svg>
+ )
+}
+
+function Separator() {
+ return (
+ <div className="w-px h-3 mx-2 shrink-0" style={{ backgroundColor: 'var(--color-panel-border)' }} />
+ )
+}
+
+function StatusItem({
+ children,
+ title,
+ onClick,
+}: {
+ children: React.ReactNode
+ title?: string
+ onClick?: () => void
+}) {
+ return (
+ <button
+ className={`flex items-center gap-1 px-1.5 h-full text-[11px] font-medium transition-colors duration-fast ${onClick ? 'cursor-pointer' : 'cursor-default'} hover:text-text-primary`}
+ style={{ color: 'var(--color-text-muted)' }}
+ title={title}
+ onClick={onClick}
+ >
+ {children}
+ </button>
+ )
+}
+
+export default function StatusBar() {
+ const activeTab = useTabsStore((s) =>
+ s.activeTabId ? s.tabs.find((t) => t.id === s.activeTabId) ?? null : null
+ )
+ const cursorLine = useTabsStore((s) => s.cursorLine)
+ const cursorCol = useTabsStore((s) => s.cursorCol)
+ const savingId = useTabsStore((s) => s.savingId)
+ const statusMessage = useTabsStore((s) => s.statusMessage)
+ const clearStatusMessage = useTabsStore((s) => s.clearStatusMessage)
+ const tabSize = useSettingsStore((s) => s.tabSize)
+
+ const isSaving = savingId === activeTab?.id
+ const statusTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined)
+
+ useEffect(() => {
+ if (statusMessage) {
+ if (statusTimer.current) clearTimeout(statusTimer.current)
+ statusTimer.current = setTimeout(clearStatusMessage, 2000)
+ }
+ return () => { if (statusTimer.current) clearTimeout(statusTimer.current) }
+ }, [statusMessage, clearStatusMessage])
+
+ return (
+ <div className="flex items-center h-status shrink-0 select-none bg-activity-bg text-[11px] text-text-muted font-medium" role="status" aria-label="Application status">
+ <div className="flex items-center h-full">
+ <StatusItem title="Git branch: main">
+ <BranchIcon />
+ <span>main</span>
+ </StatusItem>
+
+ <Separator />
+
+ <StatusItem title="0 errors, 0 warnings">
+ <ErrorIcon />
+ <span className="font-mono tabular-nums text-semantic-error">0</span>
+ <span className="font-mono tabular-nums text-semantic-warning">0</span>
+ </StatusItem>
+ </div>
+
+ <div className="flex-1" />
+
+ <div className="flex items-center h-full">
+ {isSaving && (
+ <StatusItem title="Saving...">
+ <Spinner />
+ <span className="text-accent">Saving</span>
+ </StatusItem>
+ )}
+
+ {statusMessage && !isSaving && (
+ <StatusItem title={statusMessage}>
+ <span className={statusMessage === 'Saved' ? 'text-semantic-success' : 'text-semantic-error'}>
+ {statusMessage === 'Saved' ? '✓' : '✗'}
+ </span>
+ <span className={statusMessage === 'Saved' ? 'text-semantic-success' : 'text-semantic-error'}>
+ {statusMessage}
+ </span>
+ </StatusItem>
+ )}
+
+ {activeTab && (
+ <StatusItem title={`Language: ${activeTab.language}`}>
+ <span className="text-text-secondary">
+ {activeTab.language.charAt(0).toUpperCase() + activeTab.language.slice(1)}
+ </span>
+ </StatusItem>
+ )}
+
+ <Separator />
+
+ <StatusItem title={`Tab Size: ${tabSize}`}>
+ <span>Spaces: {tabSize}</span>
+ </StatusItem>
+
+ <Separator />
+
+ <StatusItem title="Encoding: UTF-8">
+ <EncodingIcon />
+ <span>UTF-8</span>
+ </StatusItem>
+
+ <Separator />
+
+ {activeTab && (
+ <StatusItem title={`Line ${cursorLine}, Column ${cursorCol}`}>
+ <span className="font-mono tabular-nums text-text-secondary">
+ Ln {cursorLine}, Col {cursorCol}
+ </span>
+ </StatusItem>
+ )}
+ </div>
+ </div>
+ )
+}