diff options
| author | zwlucas <lucas.fariamo08@gmail.com> | 2026-06-05 20:52:54 +0000 |
|---|---|---|
| committer | zwlucas <lucas.fariamo08@gmail.com> | 2026-06-05 20:52:54 +0000 |
| commit | 09f964451d7d92e9891430ec4595c1276d486aab (patch) | |
| tree | 28da4483f5c28924a8c47fceb648b1baebe88224 /src/components/TitleBar/TitleBar.tsx | |
| download | yace-master.tar.gz yace-master.zip | |
Signed-off-by: zwlucas <lucas.fariamo08@gmail.com>
Diffstat (limited to 'src/components/TitleBar/TitleBar.tsx')
| -rw-r--r-- | src/components/TitleBar/TitleBar.tsx | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/components/TitleBar/TitleBar.tsx b/src/components/TitleBar/TitleBar.tsx new file mode 100644 index 0000000..6a491df --- /dev/null +++ b/src/components/TitleBar/TitleBar.tsx @@ -0,0 +1,94 @@ +import { useState, useEffect } from 'react' +import { appWindow } from '@tauri-apps/api/window' + +function MinimizeIcon() { + return ( + <svg width="10" height="10" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round"> + <line x1="2" y1="10" x2="10" y2="10" /> + </svg> + ) +} + +function MaximizeIcon() { + return ( + <svg width="10" height="10" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"> + <rect x="1.5" y="1.5" width="9" height="9" rx="1" /> + </svg> + ) +} + +function RestoreIcon() { + return ( + <svg width="10" height="10" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round"> + <rect x="3" y="0.5" width="8" height="8" rx="1" fill="var(--color-editor-bg)" /> + <rect x="0.5" y="3" width="8" height="8" rx="1" /> + </svg> + ) +} + +function CloseIcon() { + return ( + <svg width="10" height="10" viewBox="0 0 12 12" fill="none" stroke="currentColor" strokeWidth="1.8" strokeLinecap="round"> + <line x1="2" y1="2" x2="10" y2="10" /> + <line x1="10" y1="2" x2="2" y2="10" /> + </svg> + ) +} + +export default function TitleBar() { + const [isMaximized, setIsMaximized] = useState(false) + + useEffect(() => { + appWindow.isMaximized().then(setIsMaximized) + + let unlisten: (() => void) | undefined + appWindow.onResized(() => { + appWindow.isMaximized().then(setIsMaximized) + }).then((fn) => { unlisten = fn }) + + return () => { unlisten?.() } + }, []) + + return ( + <div + className="flex items-center h-titlebar bg-editor-bg shrink-0 select-none" + data-tauri-drag-region + > + <div className="flex items-center gap-2 px-3 text-ui-sm font-medium text-text-secondary shrink-0" data-tauri-drag-region> + <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="text-accent"> + <polyline points="16 18 22 12 16 6" /> + <polyline points="8 6 2 12 8 18" /> + </svg> + YACE + </div> + + <div className="flex-1" data-tauri-drag-region /> + + <div className="flex h-full" data-tauri-drag-region=""> + <button + onClick={() => appWindow.minimize()} + className="flex items-center justify-center w-[46px] h-full text-text-muted transition-colors duration-fast hover:bg-white/10 hover:text-text-primary active:bg-white/5" + aria-label="Minimize" + > + <MinimizeIcon /> + </button> + + <button + onClick={() => appWindow.toggleMaximize()} + className="flex items-center justify-center w-[46px] h-full text-text-muted transition-colors duration-fast hover:bg-white/10 hover:text-text-primary active:bg-white/5" + aria-label={isMaximized ? 'Restore' : 'Maximize'} + > + {isMaximized ? <RestoreIcon /> : <MaximizeIcon />} + </button> + + <button + onClick={() => appWindow.close()} + className="flex items-center justify-center w-[46px] h-full text-text-muted transition-colors duration-fast hover:bg-[#e81123] hover:text-white active:bg-[#bf0f1d]" + aria-label="Close" + > + <CloseIcon /> + </button> + </div> + </div> + ) +} |