aboutsummaryrefslogtreecommitdiff
path: root/src/components/TitleBar/TitleBar.tsx
blob: 6a491df75383a739d11e4e474a4a3cee2153ff58 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
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>
  )
}