返回 oh-my-ppt
WindowControls.tsx
根目录 / src / renderer / src / components / layout / WindowControls.tsx
1 import { useEffect, useState } from 'react'
2 import { Maximize, Minimize, Minus, X } from 'lucide-react'
3 import { ipc } from '@renderer/lib/ipc'
4
5 const isMac = ipc.getPlatform() === 'darwin'
6
7 export function WindowControls(): React.JSX.Element | null {
8 const [isFullscreen, setIsFullscreen] = useState(false)
9
10 useEffect(() => {
11 if (isMac) return
12 const unsubscribe = ipc.onWindowControlStateChanged((state) => setIsFullscreen(state.isFullscreen))
13 void ipc.getWindowControlState().then((state) => setIsFullscreen(state.isFullscreen))
14 return unsubscribe
15 }, [])
16
17 if (isMac) return null
18
19 const handleToggleFullscreen = (): void => {
20 void ipc.toggleFullscreenWindow().then((state) => setIsFullscreen(state.isFullscreen))
21 }
22
23 const controls = [
24 { label: 'Minimize', action: () => void ipc.minimizeWindow(), icon: Minus },
25 {
26 label: isFullscreen ? '退出全屏' : '全屏',
27 action: handleToggleFullscreen,
28 icon: isFullscreen ? Minimize : Maximize
29 },
30 { label: '关闭', action: () => void ipc.closeWindow(), icon: X, close: true }
31 ]
32
33 return (
34 <div className="app-no-drag ml-auto mr-2 flex shrink-0 items-center gap-1" aria-label="窗口控制">
35 {controls.map(({ label, action, icon: Icon, close }) => (
36 <button
37 key={label}
38 type="button"
39 onClick={action}
40 aria-label={label}
41 className={`inline-flex h-7 w-7 items-center justify-center rounded-md text-[#536044] transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[#789761] ${
42 close
43 ? 'hover:bg-[#c8554d] hover:text-white focus-visible:ring-[#c8554d]'
44 : 'hover:bg-[#e5dcc9]'
45 }`}
46 >
47 <Icon className="h-3.5 w-3.5" strokeWidth={1.8} />
48 </button>
49 ))}
50 </div>
51 )
52 }
53
53 lines Plain Text