/ src / components / org-chart / org-chart-toolbar.tsx
org-chart-toolbar.tsx
 1  'use client'
 2  
 3  interface Props {
 4    onAutoLayout: () => void
 5    onZoomIn: () => void
 6    onZoomOut: () => void
 7    onFitToScreen: () => void
 8    scale: number
 9  }
10  
11  export function OrgChartToolbar({ onAutoLayout, onZoomIn, onZoomOut, onFitToScreen, scale }: Props) {
12    return (
13      <div className="absolute top-4 right-4 z-20 flex items-center gap-1 bg-raised/90 backdrop-blur-sm border border-white/[0.06] rounded-[10px] px-1.5 py-1 shadow-lg" onPointerDown={(e) => e.stopPropagation()}>
14        <ToolbarBtn title="Auto-layout" onClick={onAutoLayout}>
15          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
16            <rect x="3" y="3" width="7" height="7" rx="1" /><rect x="14" y="3" width="7" height="7" rx="1" />
17            <rect x="3" y="14" width="7" height="7" rx="1" /><rect x="14" y="14" width="7" height="7" rx="1" />
18          </svg>
19        </ToolbarBtn>
20        <div className="w-px h-5 bg-white/[0.08] mx-0.5" />
21        <ToolbarBtn title="Zoom in" onClick={onZoomIn}>
22          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
23            <circle cx="11" cy="11" r="8" /><line x1="21" y1="21" x2="16.65" y2="16.65" /><line x1="11" y1="8" x2="11" y2="14" /><line x1="8" y1="11" x2="14" y2="11" />
24          </svg>
25        </ToolbarBtn>
26        <span className="text-[10px] font-mono text-text-3 min-w-[36px] text-center">{Math.round(scale * 100)}%</span>
27        <ToolbarBtn title="Zoom out" onClick={onZoomOut}>
28          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
29            <circle cx="11" cy="11" r="8" /><line x1="21" y1="21" x2="16.65" y2="16.65" /><line x1="8" y1="11" x2="14" y2="11" />
30          </svg>
31        </ToolbarBtn>
32        <div className="w-px h-5 bg-white/[0.08] mx-0.5" />
33        <ToolbarBtn title="Fit to screen" onClick={onFitToScreen}>
34          <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round">
35            <path d="M8 3H5a2 2 0 0 0-2 2v3m18 0V5a2 2 0 0 0-2-2h-3m0 18h3a2 2 0 0 0 2-2v-3M3 16v3a2 2 0 0 0 2 2h3" />
36          </svg>
37        </ToolbarBtn>
38      </div>
39    )
40  }
41  
42  function ToolbarBtn({ children, title, onClick }: { children: React.ReactNode; title: string; onClick: () => void }) {
43    return (
44      <button
45        onClick={onClick}
46        title={title}
47        className="w-7 h-7 rounded-[6px] flex items-center justify-center transition-colors cursor-pointer bg-transparent border-none text-text-3 hover:text-text hover:bg-white/[0.06]"
48      >
49        {children}
50      </button>
51    )
52  }