@labpane/os 0.0.0-stage → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +177 -2
- package/dist/LICENSE +21 -0
- package/dist/index.js +1968 -0
- package/dist/index.js.map +7 -0
- package/dist/os/context.d.ts +67 -0
- package/dist/os/drag-content.d.ts +11 -0
- package/dist/os/frame.d.ts +25 -0
- package/dist/os/icons.d.ts +4 -0
- package/dist/os/index.d.ts +6 -0
- package/dist/os/layout.d.ts +58 -0
- package/dist/os/surface.d.ts +24 -0
- package/dist/os/tabs.d.ts +23 -0
- package/dist/os/toolbar.d.ts +9 -0
- package/dist/os/unsaved-changes.d.ts +3 -0
- package/dist/os/window.d.ts +15 -0
- package/dist/os/workspace-frame.d.ts +6 -0
- package/dist/os/workspace.d.ts +38 -0
- package/dist/styles.css +1 -0
- package/dist/styles.d.ts +1 -0
- package/package.json +59 -4
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../workspace.tsx", "../context.ts", "../surface.tsx", "../layout.ts", "../toolbar.tsx", "../tabs.tsx", "../icons.tsx", "../frame.tsx", "../drag-content.ts", "../unsaved-changes.ts", "../workspace-frame.tsx", "../window.tsx"],
|
|
4
|
+
"sourcesContent": ["import {\n useEffect,\n useId,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type CSSProperties,\n} from \"react\";\nimport { WorkspaceSurface, position } from \"./surface.js\";\nimport { WorkspaceToolbar } from \"./toolbar.js\";\nimport {\n panes,\n reconcileLayout,\n updateLayout,\n type Box,\n type Layout,\n type Pane,\n} from \"./layout.js\";\nimport {\n WorkspaceId,\n WorkspaceDensity,\n useWorkspaceIds,\n useTabSize,\n type Density,\n type WorkspaceMenu,\n} from \"./context.js\";\nimport { UnsavedChanges } from \"./unsaved-changes.js\";\n\nexport type WorkspaceTab = {\n key: string;\n label: string;\n icon?: ReactNode;\n actions?: ReactNode;\n href?: string;\n scrollKey?: string;\n opener?: string;\n fill?: boolean;\n};\nexport type WorkspaceProps<T extends WorkspaceTab> = {\n density?: Density;\n tabs: readonly T[];\n active?: string;\n onSelect: (key: string) => void;\n onClose: (key: string, next?: string) => void;\n onDuplicate?: (key: string) => string;\n leading?: ReactNode;\n trailing?: ReactNode;\n toolbar?: (pane: WorkspacePane) => ReactNode;\n menu?: WorkspaceMenu;\n confirmClose?: (tab: T) => boolean | Promise<boolean>;\n layout: Layout;\n onLayoutChange: (layout: Layout) => void;\n className?: string;\n children: (tab: T, pane: WorkspacePane) => ReactNode;\n empty: (pane: WorkspacePane) => ReactNode;\n};\nexport type WorkspacePane = {\n id: string;\n tabs: string[];\n active?: string;\n focus: (key: string) => void;\n};\n\nexport function Workspace<T extends WorkspaceTab>(props: WorkspaceProps<T>) {\n const id = useId();\n return (\n <WorkspaceId.Provider value={id}>\n <WorkspaceDensity.Provider value={props.density ?? 100}>\n <WorkspaceContent {...props} />\n </WorkspaceDensity.Provider>\n </WorkspaceId.Provider>\n );\n}\n\nfunction WorkspaceContent<T extends WorkspaceTab>({\n density = 100,\n tabs,\n active,\n onSelect,\n onClose,\n onDuplicate,\n leading,\n trailing,\n toolbar,\n menu,\n confirmClose,\n layout,\n onLayoutChange: change,\n className,\n children,\n empty,\n}: WorkspaceProps<T>) {\n const ids = useWorkspaceIds();\n const { height, logoSize } = useTabSize();\n const corner = useRef<HTMLDivElement>(null);\n const [reserve, setReserve] = useState(0);\n const hasTrailing = !!trailing;\n useLayoutEffect(() => {\n const element = corner.current;\n if (!element) return setReserve(0);\n const observer = new ResizeObserver(() => setReserve(element.offsetWidth));\n observer.observe(element);\n return () => observer.disconnect();\n }, [hasTrailing]);\n const root = useRef<HTMLDivElement>(null);\n const preferredPane = useRef<string | undefined>(undefined);\n const visibleLayout = reconcileLayout(\n layout,\n tabs.map((t) => t.key),\n active,\n preferredPane.current,\n );\n useLayoutEffect(() => {\n if (visibleLayout !== layout) change(visibleLayout);\n // oxlint-disable-next-line react-hooks/exhaustive-deps -- onLayoutChange may be inline\n }, [visibleLayout, layout]);\n const dirty = useRef(new Map<symbol, string>());\n useEffect(() => {\n const warn = (event: BeforeUnloadEvent) => {\n if (dirty.current.size) event.preventDefault();\n };\n addEventListener(\"beforeunload\", warn);\n return () => removeEventListener(\"beforeunload\", warn);\n }, []);\n function close(key: string) {\n const pane = panes(visibleLayout).find((p) => p.tabs.includes(key));\n if (!pane) return;\n const remaining = pane.tabs.filter((k) => k !== key);\n const opener = tabs.find((tab) => tab.key === key)?.opener;\n const neighbor =\n remaining.find((key) => key === opener) ??\n remaining[Math.min(pane.tabs.indexOf(key), remaining.length - 1)] ??\n tabs.find((t) => t.key !== key)?.key;\n onClose(key, neighbor);\n requestAnimationFrame(() =>\n (\n document.getElementById(\n ids.tab(key === pane.active ? (neighbor ?? \"\") : (pane.active ?? \"\")),\n ) ??\n root.current?.querySelector<HTMLElement>(\n \".lab-toolbar-end button, [data-pane-sheet]\",\n )\n )?.focus({ preventScroll: true }),\n );\n }\n const focus = (key: string) =>\n requestAnimationFrame(() => document.getElementById(ids.tab(key))?.focus());\n const paneOf = (pane: Pane): WorkspacePane => ({\n id: pane.id,\n tabs: pane.tabs,\n active: pane.active,\n focus,\n });\n return (\n <>\n {/* oxlint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- F6 moves between panes */}\n <div\n ref={root}\n role=\"region\"\n aria-label=\"Workspace\"\n data-density={density}\n style={\n {\n \"--lab-tab-height\": `${height}px`,\n \"--lab-logo-size\": `${logoSize}px`,\n } as CSSProperties\n }\n className={className ? `lab-workspace ${className}` : \"lab-workspace\"}\n onKeyDown={(event) => {\n if (event.key !== \"F6\") return;\n event.preventDefault();\n const selected = Array.from(\n event.currentTarget.querySelectorAll<HTMLElement>(\n '[role=\"tab\"][aria-selected=\"true\"]',\n ),\n );\n const owner = document.activeElement?.closest(\n '[data-pane-header], [role=\"tabpanel\"]',\n );\n const index = selected.findIndex(\n (tab) =>\n owner?.contains(tab) ||\n tab.getAttribute(\"aria-controls\") === owner?.id,\n );\n selected[\n (index + (event.shiftKey ? selected.length - 1 : 1)) %\n selected.length\n ]?.focus();\n }}\n >\n {trailing && (\n <div ref={corner} className=\"lab-trailing\" style={{ height }}>\n {trailing}\n </div>\n )}\n <WorkspaceSurface\n layout={visibleLayout}\n change={change}\n menu={menu}\n header={(pane, first, last, docking, surface) => (\n <WorkspaceToolbar\n leading={first ? leading : undefined}\n reserve={last ? reserve : undefined}\n end={toolbar?.(paneOf(pane))}\n menu={menu}\n onActivate={() => {\n preferredPane.current = pane.id;\n }}\n docking={docking}\n surface={surface}\n items={pane.tabs.map((key) => tabs.find((t) => t.key === key)!)}\n active={pane.active}\n onSelect={onSelect}\n onDuplicate={\n onDuplicate\n ? (key) => {\n const copy = onDuplicate(key),\n index = pane.tabs.indexOf(key) + 1;\n change(\n updateLayout(visibleLayout, pane.id, () => ({\n ...pane,\n tabs: [\n ...pane.tabs.slice(0, index),\n copy,\n ...pane.tabs.slice(index),\n ],\n active: copy,\n })),\n );\n return copy;\n }\n : undefined\n }\n onClose={(key) => {\n if (![...dirty.current.values()].includes(key))\n return close(key);\n const tab = tabs.find((tab) => tab.key === key)!;\n const element = document.getElementById(ids.tab(key));\n Promise.resolve(\n confirmClose\n ? confirmClose(tab)\n : confirm(`Discard changes in ${tab.label}?`),\n ).then((discard) => {\n if (discard) close(key);\n else requestAnimationFrame(() => element?.focus());\n });\n }}\n onReorder={(keys) =>\n change(\n updateLayout(visibleLayout, pane.id, (node) => ({\n ...(node as Pane),\n tabs: keys,\n })),\n )\n }\n />\n )}\n content={(regions, transition, lifted) => (\n <>\n {tabs.map((tab) => {\n const region = regions.find((r) =>\n r.pane.tabs.includes(tab.key),\n )!;\n return (\n <TabPanel\n key={tab.key}\n tab={tab}\n hidden={\n tab.key !== region.pane.active && tab.key !== lifted\n }\n pane={region.pane.id}\n box={region.box}\n transition={transition}\n focus={() => {\n preferredPane.current = region.pane.id;\n if (active !== tab.key) onSelect(tab.key);\n }}\n >\n <UnsavedChanges.Provider\n value={(source, changed) =>\n changed\n ? dirty.current.set(source, tab.key)\n : dirty.current.delete(source)\n }\n >\n {children(tab, paneOf(region.pane))}\n </UnsavedChanges.Provider>\n </TabPanel>\n );\n })}\n {!tabs.length && (\n <TabPanel\n hidden={false}\n pane={regions[0]!.pane.id}\n box={regions[0]!.box}\n transition={transition}\n >\n {empty(paneOf(regions[0]!.pane))}\n </TabPanel>\n )}\n </>\n )}\n />\n </div>\n </>\n );\n}\n\nfunction TabPanel({\n tab,\n hidden,\n pane,\n box,\n transition,\n focus,\n children,\n}: {\n tab?: WorkspaceTab;\n hidden: boolean;\n pane: string;\n box: Box;\n transition: boolean;\n focus?: () => void;\n children: ReactNode;\n}) {\n const ids = useWorkspaceIds();\n const { height, borderWidth } = useTabSize();\n const viewport = useRef<HTMLElement>(null);\n useLayoutEffect(() => {\n viewport.current?.scrollTo(0, 0);\n }, [tab?.scrollKey]);\n return (\n // oxlint-disable-next-line jsx-a11y/no-noninteractive-element-interactions -- focusable panel\n <section\n ref={viewport}\n id={tab ? ids.panel(tab.key) : undefined}\n role={tab ? \"tabpanel\" : undefined}\n aria-labelledby={tab ? ids.tab(tab.key) : undefined}\n tabIndex={0}\n data-pane-sheet={pane}\n hidden={hidden}\n className=\"lab-panel\"\n style={{\n borderWidth,\n ...(tab?.fill ? { padding: 0, overflow: \"hidden\" } : {}),\n ...position({\n ...box,\n y: box.y + height - 1,\n height: box.height - height + 1,\n }),\n transitionDuration: transition\n ? \"var(--workspace-duration, 180ms)\"\n : \"0ms\",\n }}\n onPointerDownCapture={(event) => {\n event.currentTarget.dataset.pointer = \"\";\n focus?.();\n }}\n onFocusCapture={focus}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget as Node | null))\n delete event.currentTarget.dataset.pointer;\n }}\n >\n {children}\n </section>\n );\n}\n", "import {\n createContext,\n useContext,\n useMemo,\n type ReactElement,\n type ReactNode,\n} from \"react\";\n\nexport const WorkspaceId = createContext(\"\");\nexport const densityPresets = {\n comfortable: {\n value: 100,\n width: 192,\n height: 44,\n contentHeight: 36,\n columnGap: 8,\n rowGap: 8,\n logoSize: 24,\n borderWidth: 1,\n },\n compact: {\n value: 50,\n width: 168,\n height: 34,\n contentHeight: 30,\n columnGap: 6,\n rowGap: 4,\n logoSize: 20,\n borderWidth: 0.75,\n },\n dense: {\n value: 0,\n width: 152,\n height: 26,\n contentHeight: 24,\n columnGap: 4,\n rowGap: 2,\n logoSize: 16,\n borderWidth: 0.5,\n },\n};\nexport type Density = number;\nexport function densitySize(density: Density) {\n const value = Number.isFinite(density)\n ? Math.max(0, Math.min(100, density))\n : 100;\n const { dense, compact, comfortable } = densityPresets;\n const [from, to] =\n value < compact.value ? [dense, compact] : [compact, comfortable];\n const amount = (value - from.value) / (to.value - from.value);\n return Object.fromEntries(\n (Object.keys(from) as (keyof typeof from)[]).map((key) => [\n key,\n from[key] + (to[key] - from[key]) * amount,\n ]),\n ) as typeof from;\n}\nexport const WorkspaceDensity = createContext<Density>(100);\nexport const fitTabWidth = (width: number, available: number, count: number) =>\n Math.min(width, Math.max(128, (available - 16) / Math.max(1, count)));\nexport function useTabSize() {\n const density = useContext(WorkspaceDensity);\n return useMemo(() => densitySize(density), [density]);\n}\nexport function useWorkspaceIds() {\n const prefix = useContext(WorkspaceId);\n return {\n tab: (key: string) => `${prefix}-tab-${encodeURIComponent(key)}`,\n panel: (key: string) => `${prefix}-panel-${encodeURIComponent(key)}`,\n };\n}\n\nexport type WorkspaceAction = {\n label: string;\n onSelect: () => void;\n disabled?: boolean;\n} | null;\n// WorkspaceMenu wraps a tab or divider in the app's menu; tab is the key of the tab it opens on\nexport type WorkspaceMenu = (\n target: ReactElement,\n actions: WorkspaceAction[],\n restoreFocus?: () => void,\n tab?: string,\n) => ReactNode;\n", "import {\n useWorkspaceIds,\n useTabSize,\n fitTabWidth,\n type WorkspaceMenu,\n} from \"./context.js\";\nimport {\n Fragment,\n useLayoutEffect,\n useRef,\n useState,\n type ReactNode,\n type CSSProperties,\n} from \"react\";\nimport {\n dockTab,\n dropRegion,\n layoutBoxes,\n minimum,\n minimumSize,\n panes,\n updateLayout,\n type Box,\n type Edge,\n type Layout,\n type Pane,\n} from \"./layout.js\";\nimport type { TabDrag } from \"./tabs.js\";\n\nexport const position = (box: Box): CSSProperties => ({\n left: box.x,\n top: box.y,\n width: box.width,\n height: box.height,\n});\nexport type Docking = {\n move: (drag: TabDrag) => boolean;\n drop: () => boolean;\n cancel: () => void;\n split: (key: string, edge: Edge) => boolean;\n next: (key: string) => void;\n paneCount: number;\n insertion?: number;\n};\ntype Preview = { key: string; pane?: string; edge?: Edge; index?: number };\n\nexport function WorkspaceSurface({\n layout,\n change,\n header,\n content,\n menu,\n}: {\n layout: Layout;\n change: (layout: Layout) => void;\n menu?: WorkspaceMenu;\n header: (\n pane: Pane,\n first: boolean,\n last: boolean,\n docking: Docking,\n surface: (key?: string) => HTMLElement | null,\n ) => ReactNode;\n content: (\n panes: { pane: Pane; box: Box }[],\n transition: boolean,\n lifted?: string,\n ) => ReactNode;\n}) {\n const ids = useWorkspaceIds();\n const {\n height: tabHeight,\n width: tabWidth,\n columnGap,\n rowGap,\n } = useTabSize();\n const gutter = { x: columnGap, y: rowGap };\n const board = useRef<HTMLDivElement>(null);\n const [size, setSize] = useState({ width: 0, height: 0 });\n const [preview, setPreview] = useState<Preview>();\n const previewRef = useRef<Preview | undefined>(undefined);\n const [resizing, setResizing] = useState(false);\n const geometry = [\n size.width,\n size.height,\n tabHeight,\n columnGap,\n rowGap,\n ].join();\n const previousGeometry = useRef(geometry);\n const stableGeometry = previousGeometry.current === geometry;\n useLayoutEffect(() => {\n previousGeometry.current = geometry;\n }, [geometry]);\n useLayoutEffect(() => {\n const observer = new ResizeObserver(([entry]) => {\n const { width, height } = entry!.contentRect;\n setSize({ width, height });\n });\n observer.observe(board.current!);\n return () => observer.disconnect();\n }, []);\n const { leaves, dividers } = layoutBoxes(\n layout,\n size.width,\n size.height,\n gutter,\n ),\n required = minimumSize(layout, gutter);\n const show = (next?: Preview) => {\n if (\n previewRef.current?.pane === next?.pane &&\n previewRef.current?.edge === next?.edge &&\n previewRef.current?.index === next?.index &&\n previewRef.current?.key === next?.key\n )\n return;\n previewRef.current = next;\n setPreview(next);\n };\n const canSplit = (box: Box, edge: Edge) =>\n edge === \"bottom\"\n ? box.height >= minimum.y * 2 + rowGap\n : box.width >= minimum.x * 2 + columnGap;\n const docking: Docking = {\n paneCount: leaves.length,\n next: (key) => {\n const index = leaves.findIndex((p) => p.pane.tabs.includes(key));\n change(\n dockTab(layout, key, leaves[(index + 1) % leaves.length]!.pane.id),\n );\n },\n move: ({ key, x, y, detached: wasDetached }) => {\n const bounds = board.current!.getBoundingClientRect(),\n localX = x - bounds.left,\n localY = y - bounds.top;\n const target = leaves.find(\n (p) =>\n localX >= p.x &&\n localX <= p.x + p.width &&\n localY >= p.y &&\n localY <= p.y + p.height,\n );\n const source = leaves.find((p) => p.pane.tabs.includes(key))!;\n const margin = wasDetached ? 8 : 24;\n const detached =\n localY > source.y + tabHeight + margin ||\n localY < source.y - margin ||\n (!!target &&\n (localX < source.x - margin ||\n localX > source.x + source.width + margin));\n if (!detached) {\n show();\n return false;\n }\n let edge: Edge | undefined;\n if (target && localY > target.y + tabHeight) {\n if (localY > target.y + target.height * 0.72) edge = \"bottom\";\n else if (localX < target.x + target.width * 0.28) edge = \"left\";\n else if (localX > target.x + target.width * 0.72) edge = \"right\";\n }\n const valid =\n target &&\n (!edge || canSplit(target, edge)) &&\n (!target.pane.tabs.includes(key) ||\n (!!edge && target.pane.tabs.length > 1));\n let index: number | undefined;\n if (valid && !edge) {\n const nav = board.current!.querySelector<HTMLElement>(\n `[data-pane-header=\"${CSS.escape(target.pane.id)}\"] [role=\"tablist\"]`,\n );\n const header = nav?.closest<HTMLElement>(\"[data-pane-header]\");\n index = target.pane.tabs.length;\n if (nav && header && localY <= target.y + tabHeight) {\n const strip = nav.parentElement!;\n const inset =\n strip.getBoundingClientRect().left -\n header.getBoundingClientRect().left;\n const trailing =\n strip.parentElement!.nextElementSibling?.getBoundingClientRect()\n .width ?? 0;\n const available = target.width - inset - trailing - 4;\n const width = fitTabWidth(\n tabWidth,\n available,\n target.pane.tabs.length + 1,\n );\n const overflow =\n width * (target.pane.tabs.length + 1) + 16 - available;\n const arrows = overflow > 1 ? Math.min(28, tabHeight) : 0;\n const scroll = Math.min(\n nav.scrollLeft,\n Math.max(0, overflow + arrows * 2),\n );\n index = Math.max(\n 0,\n Math.min(\n target.pane.tabs.length,\n Math.round(\n (localX - target.x - inset - arrows + scroll - 8) / width,\n ),\n ),\n );\n }\n }\n show(valid ? { pane: target.pane.id, key, edge, index } : { key });\n return true;\n },\n drop: () => {\n const target = previewRef.current;\n show();\n if (!target?.pane) return false;\n change(\n dockTab(layout, target.key, target.pane, target.edge, target.index),\n );\n return true;\n },\n cancel: () => show(),\n split: (key, edge) => {\n const target = leaves.find((p) => p.pane.tabs.includes(key));\n if (!target || target.pane.tabs.length < 2 || !canSplit(target, edge))\n return false;\n change(dockTab(layout, key, target.pane.id, edge));\n return true;\n },\n };\n const lifted = preview?.key;\n const regions = leaves.map(({ pane, ...box }) => {\n if (lifted && pane.tabs.includes(lifted)) {\n const remaining = pane.tabs.filter((key) => key !== lifted);\n pane = {\n ...pane,\n active:\n remaining[Math.min(pane.tabs.indexOf(lifted), remaining.length - 1)],\n };\n }\n if (preview?.pane !== pane.id || !preview.edge) return { pane, box };\n const drop = dropRegion(box, preview.edge, gutter);\n if (preview.edge === \"left\")\n return {\n pane,\n box: { ...box, x: drop.x + drop.width + columnGap, width: drop.width },\n };\n if (preview.edge === \"right\")\n return { pane, box: { ...box, width: drop.width } };\n return { pane, box: { ...box, height: drop.y - box.y - rowGap } };\n });\n const transition = !resizing && size.width > 0 && stableGeometry;\n const top = Math.min(...leaves.map((leaf) => leaf.y));\n const topRight = leaves\n .filter((leaf) => leaf.y === top)\n .reduce<(typeof leaves)[number] | undefined>(\n (best, leaf) => (!best || leaf.x > best.x ? leaf : best),\n undefined,\n )?.pane.id;\n return (\n <div className=\"lab-surface\">\n <div\n ref={board}\n className=\"lab-board\"\n style={{\n minWidth: required.x,\n minHeight: required.y,\n }}\n >\n {regions.map(({ pane, box }, index) => (\n <div\n key={pane.id}\n data-pane-header={pane.id}\n className=\"lab-pane-header\"\n style={{\n ...position({ ...box, height: tabHeight }),\n transitionDuration: transition\n ? \"var(--workspace-duration, 180ms)\"\n : \"0ms\",\n }}\n >\n {header(\n pane,\n index === 0,\n pane.id === topRight,\n {\n ...docking,\n insertion:\n preview?.pane === pane.id ? preview.index : undefined,\n },\n (key = pane.active) =>\n board.current?.querySelector<HTMLElement>(\n key\n ? `[id=\"${CSS.escape(ids.panel(key))}\"]`\n : `[data-pane-sheet=\"${CSS.escape(pane.id)}\"]:not([hidden]):not([data-drag-content])`,\n ) ?? null,\n )}\n </div>\n ))}\n {content(regions, transition, lifted)}\n {dividers.map(({ split, bounds, ratio, low, high, ...box }) => {\n const axis = split.axis,\n horizontal = axis === \"x\",\n dimension = horizontal ? \"width\" : \"height\";\n const primary = panes(split.first).filter((p) => p.active);\n const resize = (value: number) =>\n change(\n updateLayout(layout, split.id, (node) => ({\n ...node,\n ratio: Math.max(low, Math.min(high, value)),\n })),\n );\n const target = (\n <div\n role=\"separator\"\n aria-label={horizontal ? \"Resize columns\" : \"Resize rows\"}\n aria-labelledby={primary.map((p) => ids.tab(p.active!)).join(\" \")}\n aria-controls={primary.map((p) => ids.panel(p.active!)).join(\" \")}\n aria-valuetext={`${Math.round(ratio * 100)}% ${horizontal ? \"width\" : \"height\"}`}\n title={\n menu\n ? \"Drag to resize, use arrow keys, or open resize actions with right-click or Shift+F10\"\n : \"Drag to resize or use arrow keys\"\n }\n aria-orientation={horizontal ? \"vertical\" : \"horizontal\"}\n aria-valuenow={Math.round(ratio * 100)}\n aria-valuemin={Math.round(low * 100)}\n aria-valuemax={Math.round(high * 100)}\n tabIndex={0}\n className=\"lab-divider\"\n style={position({\n ...box,\n [axis]: box[axis] + gutter[axis] / 2 - 12,\n [dimension]: 24,\n })}\n onDoubleClick={() => resize(horizontal ? 0.5 : 2 / 3)}\n onPointerDown={(event) => {\n if (event.button !== 0) return;\n event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n setResizing(true);\n }}\n onPointerMove={(event) => {\n if (!event.currentTarget.hasPointerCapture(event.pointerId))\n return;\n const b = board.current!.getBoundingClientRect();\n const coordinate = horizontal\n ? event.clientX - b.left\n : event.clientY - b.top;\n resize(\n (coordinate - bounds[axis]) /\n (bounds[dimension] - gutter[axis]),\n );\n }}\n onLostPointerCapture={() => setResizing(false)}\n onKeyDown={(event) => {\n const step = event.shiftKey ? 0.1 : 0.02;\n const values: Record<string, number> = {\n [horizontal ? \"ArrowLeft\" : \"ArrowUp\"]: ratio - step,\n [horizontal ? \"ArrowRight\" : \"ArrowDown\"]: ratio + step,\n Home: low,\n End: high,\n };\n const value = values[event.key];\n if (value === undefined) return;\n event.preventDefault();\n resize(value);\n }}\n />\n );\n return (\n <Fragment key={split.id}>\n {menu\n ? menu(target, [\n {\n label: horizontal ? \"Narrower\" : \"Shorter\",\n onSelect: () => resize(ratio - 0.1),\n },\n {\n label: horizontal ? \"Wider\" : \"Taller\",\n onSelect: () => resize(ratio + 0.1),\n },\n {\n label: \"Reset size\",\n onSelect: () => resize(horizontal ? 0.5 : 2 / 3),\n },\n ])\n : target}\n </Fragment>\n );\n })}\n <span role=\"status\" className=\"lab-sr-only\">\n {preview?.pane &&\n (preview.edge ? `Split ${preview.edge}` : \"Move tab here\")}\n </span>\n </div>\n </div>\n );\n}\n", "export type Pane = { id: string; tabs: string[]; active?: string };\nexport type Split = {\n id: string;\n axis: \"x\" | \"y\";\n ratio: number;\n first: Layout;\n second: Layout;\n};\nexport type Layout = Pane | Split;\nexport type Edge = \"left\" | \"right\" | \"bottom\";\nexport type Box = { x: number; y: number; width: number; height: number };\ntype PaneBox = Box & { pane: Pane };\nconst gutter = { x: 8, y: 8 };\nexport const minimum = { x: 280, y: 180 };\nexport const isSplit = (node: Layout): node is Split => \"axis\" in node;\nexport const panes = (node: Layout): Pane[] =>\n isSplit(node) ? [...panes(node.first), ...panes(node.second)] : [node];\nconst clamp = (n: number, low: number, high: number) =>\n Math.max(low, Math.min(high, n));\n\nexport function updateLayout(\n node: Layout,\n id: string,\n change: (node: Layout) => Layout,\n): Layout {\n if (node.id === id) return change(node);\n if (!isSplit(node)) return node;\n const first = updateLayout(node.first, id, change),\n second = updateLayout(node.second, id, change);\n return first === node.first && second === node.second\n ? node\n : { ...node, first, second };\n}\n\nexport function reconcileLayout(\n node: Layout,\n keys: string[],\n active?: string,\n preferred?: string,\n): Layout {\n if (!keys.length)\n return !isSplit(node) && !node.tabs.length && !node.active\n ? node\n : { id: \"primary\", tabs: [] };\n const seen = new Set<string>();\n const clean = (node: Layout): Layout | undefined => {\n if (isSplit(node)) {\n const first = clean(node.first),\n second = clean(node.second);\n return first && second\n ? first === node.first && second === node.second\n ? node\n : { ...node, first, second }\n : (first ?? second);\n }\n const tabs = node.tabs.filter(\n (key) => keys.includes(key) && !seen.has(key) && !!seen.add(key),\n );\n if (!tabs.length) return undefined;\n const selected = tabs.includes(active ?? \"\")\n ? active\n : tabs.includes(node.active ?? \"\")\n ? node.active\n : tabs[0];\n return tabs.length === node.tabs.length && selected === node.active\n ? node\n : { ...node, tabs, active: selected };\n };\n let next = clean(node) ?? { id: \"primary\", tabs: [] };\n const missing = keys.filter((key) => !seen.has(key));\n if (missing.length) {\n const leaves = panes(next),\n target = leaves.find((p) => p.id === preferred) ?? leaves[0]!;\n next = updateLayout(next, target.id, (node) => ({\n ...(node as Pane),\n tabs: [...target.tabs, ...missing],\n active: missing.includes(active ?? \"\")\n ? active\n : (target.active ?? missing[0]),\n }));\n }\n return next;\n}\n\nexport function restoreLayout(value: string | null, keys: string[]): Layout {\n const ids = new Set<string>();\n function read(value: unknown, depth = 0): Layout {\n const n = value as Partial<Pane & Split>;\n if (!n || depth > 12 || typeof n.id !== \"string\" || !n.id || ids.has(n.id))\n throw Error(\"Invalid layout\");\n ids.add(n.id);\n if (n.axis === \"x\" || n.axis === \"y\") {\n if (typeof n.ratio !== \"number\" || !Number.isFinite(n.ratio))\n throw Error(\"Invalid ratio\");\n return {\n id: n.id,\n axis: n.axis,\n ratio: clamp(n.ratio, 0.05, 0.95),\n first: read(n.first, depth + 1),\n second: read(n.second, depth + 1),\n };\n }\n if (!Array.isArray(n.tabs) || n.tabs.some((key) => typeof key !== \"string\"))\n throw Error(\"Invalid tabs\");\n return {\n id: n.id,\n tabs: n.tabs,\n active: typeof n.active === \"string\" ? n.active : undefined,\n };\n }\n try {\n return reconcileLayout(read(JSON.parse(value ?? \"null\")), keys);\n } catch {\n return { id: \"primary\", tabs: keys, active: keys[0] };\n }\n}\n\n// newId names a new pane or split; crypto.randomUUID only exists on HTTPS and localhost\nconst newId = () =>\n crypto.randomUUID?.() ??\n Array.from(crypto.getRandomValues(new Uint8Array(16)), (byte) =>\n byte.toString(16).padStart(2, \"0\"),\n ).join(\"\");\n\nexport function dockTab(\n layout: Layout,\n key: string,\n target: string,\n edge?: Edge,\n index?: number,\n): Layout {\n const leaves = panes(layout),\n source = leaves.find((p) => p.tabs.includes(key)),\n destination = leaves.find((p) => p.id === target);\n if (\n !source ||\n !destination ||\n (source === destination && (!edge || source.tabs.length === 1))\n )\n return layout;\n let next = updateLayout(layout, source.id, (node) => {\n const pane = node as Pane,\n index = pane.tabs.indexOf(key),\n tabs = pane.tabs.filter((k) => k !== key);\n return {\n ...pane,\n tabs,\n active:\n pane.active === key\n ? tabs[Math.min(index, tabs.length - 1)]\n : pane.active,\n };\n });\n next = updateLayout(next, target, (node) => {\n const pane = node as Pane;\n if (!edge) {\n const tabs = [...pane.tabs];\n tabs.splice(index ?? tabs.length, 0, key);\n return { ...pane, tabs, active: key };\n }\n const added: Pane = { id: newId(), tabs: [key], active: key };\n return {\n id: newId(),\n axis: edge === \"bottom\" ? \"y\" : \"x\",\n ratio: edge === \"bottom\" ? 2 / 3 : 0.5,\n first: edge === \"left\" ? added : pane,\n second: edge === \"left\" ? pane : added,\n };\n });\n return reconcileLayout(\n next,\n leaves.flatMap((p) => p.tabs),\n key,\n );\n}\n\nexport function minimumSize(\n node: Layout,\n gap = gutter,\n): { x: number; y: number } {\n if (!isSplit(node)) return minimum;\n const a = minimumSize(node.first, gap),\n b = minimumSize(node.second, gap);\n return node.axis === \"x\"\n ? { x: a.x + b.x + gap.x, y: Math.max(a.y, b.y) }\n : { x: Math.max(a.x, b.x), y: a.y + b.y + gap.y };\n}\n\nexport function layoutBoxes(\n layout: Layout,\n width: number,\n height: number,\n gap = gutter,\n) {\n const leaves: PaneBox[] = [],\n dividers: (Box & {\n split: Split;\n bounds: Box;\n ratio: number;\n low: number;\n high: number;\n })[] = [];\n function walk(node: Layout, box: Box) {\n if (!isSplit(node)) {\n leaves.push({ ...box, pane: node });\n return;\n }\n const axis = node.axis,\n dimension = axis === \"x\" ? \"width\" : \"height\",\n spacing = gap[axis],\n size = Math.max(1, box[dimension] - spacing);\n const low = minimumSize(node.first, gap)[axis] / size,\n high = 1 - minimumSize(node.second, gap)[axis] / size;\n const ratio = clamp(node.ratio, low, high),\n distance = clamp(Math.round(size * ratio), size * low, size * high);\n const first = { ...box, [dimension]: distance };\n const second = {\n ...box,\n [axis]: box[axis] + distance + spacing,\n [dimension]: size - distance,\n };\n dividers.push({\n ...box,\n [axis]: box[axis] + distance,\n [dimension]: spacing,\n split: node,\n bounds: box,\n ratio,\n low,\n high,\n });\n walk(node.first, first);\n walk(node.second, second);\n }\n const required = minimumSize(layout, gap);\n walk(layout, {\n x: 0,\n y: 0,\n width: Math.max(width, required.x),\n height: Math.max(height, required.y),\n });\n return { leaves, dividers };\n}\n\nexport function dropRegion(box: Box, edge?: Edge, gap = gutter): Box {\n if (edge === \"left\") return { ...box, width: (box.width - gap.x) / 2 };\n if (edge === \"right\")\n return {\n ...box,\n x: box.x + (box.width + gap.x) / 2,\n width: (box.width - gap.x) / 2,\n };\n if (edge === \"bottom\") {\n const height = Math.max(minimum.y, (box.height - gap.y) / 3);\n return { ...box, y: box.y + box.height - height, height };\n }\n return box;\n}\n", "import { useState, type ReactNode } from \"react\";\nimport { useTabSize } from \"./context.js\";\nimport { WorkspaceTabs, type WorkspaceTabsProps } from \"./tabs.js\";\n\nexport function WorkspaceToolbar({\n active,\n leading,\n reserve,\n end,\n onActivate,\n ...tabProps\n}: Omit<WorkspaceTabsProps, \"active\" | \"dragBoundary\"> & {\n leading?: ReactNode;\n reserve?: number;\n end?: ReactNode;\n active?: string;\n onActivate: () => void;\n}) {\n const { height } = useTabSize();\n const [header, setHeader] = useState<HTMLDivElement | null>(null);\n return (\n <div\n ref={setHeader}\n style={{ height }}\n className=\"lab-toolbar\"\n data-leading={leading ? \"\" : undefined}\n onPointerDownCapture={onActivate}\n onFocusCapture={onActivate}\n >\n {leading}\n <div className=\"lab-toolbar-tabs\">\n <WorkspaceTabs\n {...tabProps}\n dragBoundary={header}\n active={active ?? \"\"}\n />\n </div>\n <div className=\"lab-toolbar-end\">\n {end}\n {tabProps.items.find((tab) => tab.key === active)?.actions}\n </div>\n {!!reserve && (\n <div className=\"lab-toolbar-trailing\" style={{ width: reserve }} />\n )}\n </div>\n );\n}\n", "import {\n useWorkspaceIds,\n useTabSize,\n fitTabWidth,\n type WorkspaceAction,\n type WorkspaceMenu,\n} from \"./context.js\";\nimport * as React from \"react\";\nimport { createPortal } from \"react-dom\";\nimport { XIcon, ChevronLeftIcon, ChevronRightIcon } from \"./icons.js\";\nimport type { Docking } from \"./surface.js\";\nimport { TabSurface, paneShape, tabShape } from \"./frame.js\";\nimport type { WorkspaceTab } from \"./workspace.js\";\nimport { useDragContent } from \"./drag-content.js\";\n\nconst motion = { duration: 160, easing: \"cubic-bezier(.2,.8,.2,1)\" };\n\nexport type TabDrag = {\n key: string;\n x: number;\n y: number;\n detached: boolean;\n};\n\nexport type WorkspaceTabsProps = {\n items: readonly WorkspaceTab[];\n active: string;\n onClose: (key: string) => void;\n onDuplicate?: (key: string) => string;\n onReorder: (keys: string[]) => void;\n onSelect: (key: string) => void;\n dragBoundary: HTMLElement | null;\n surface: (key?: string) => HTMLElement | null;\n docking: Docking;\n menu?: WorkspaceMenu;\n};\n\nexport function WorkspaceTabs({\n items,\n active,\n onClose,\n onDuplicate,\n onReorder,\n onSelect,\n dragBoundary,\n surface,\n docking,\n menu,\n}: WorkspaceTabsProps) {\n const ids = useWorkspaceIds();\n const content = useDragContent();\n const density = useTabSize();\n const [metrics, setMetrics] = React.useState({\n available: Infinity,\n overflow: false,\n left: false,\n right: false,\n });\n const measured = React.useRef(metrics);\n const { available } = metrics;\n const size = {\n ...density,\n width: fitTabWidth(\n density.width,\n available,\n items.length + (docking.insertion === undefined ? 0 : 1),\n ),\n },\n { width: tabWidth, height, contentHeight } = size,\n width = tabWidth + 16;\n const links = items.map(({ key, label }) => [key, label] as const);\n const tabOrder = JSON.stringify(items.map(({ key }) => key));\n const labels = new Map(links);\n const navRef = React.useRef<HTMLDivElement>(null);\n const stripRef = React.useRef<HTMLDivElement>(null);\n const helpId = React.useId();\n const menuFocus = React.useRef<string | undefined>(undefined);\n const drag = React.useRef<\n | (TabDrag & {\n offset: number;\n offsetY: number;\n sheet: DOMRect;\n moved: boolean;\n order: string[];\n })\n | undefined\n >(undefined);\n const [dragging, setDragging] = React.useState<string>();\n const [pointerFocus, setPointerFocus] = React.useState(false);\n const [announcement, announce] = React.useState(\"\");\n const ghostRef = React.useRef<HTMLDivElement | null>(null);\n const ghost = React.useCallback((element: HTMLDivElement | null) => {\n ghostRef.current = element;\n if (element) element.inert = true;\n }, []);\n const frameRef = React.useRef<SVGSVGElement>(null);\n const maskedSheet = React.useRef<HTMLElement | null>(null);\n const maskedOutline = React.useRef<SVGPathElement | null>(null);\n const restoreFrame = () => {\n maskedSheet.current?.style.removeProperty(\"border-color\");\n maskedOutline.current?.style.removeProperty(\"visibility\");\n maskedSheet.current = null;\n maskedOutline.current = null;\n };\n const settling = React.useRef<Animation | undefined>(undefined);\n const positions = React.useRef({\n order: \"\",\n tabs: new Map<string, number>(),\n });\n const frame = React.useRef(0);\n const suppressClick = React.useRef(false);\n const tabElement = (key: string) =>\n navRef.current?.querySelector<HTMLElement>(\n `a[data-tab=\"${CSS.escape(key)}\"]`,\n )?.parentElement;\n const reveal = (key = active) => {\n const nav = navRef.current,\n tab = tabElement(key);\n if (!nav || !tab || drag.current?.moved || docking.insertion !== undefined)\n return;\n nav.scrollLeft = Math.max(\n tab.offsetLeft + tab.offsetWidth + 8 - nav.clientWidth,\n Math.min(nav.scrollLeft, tab.offsetLeft - 8),\n );\n };\n const draw = () => {\n const current = drag.current,\n ghost = ghostRef.current,\n nav = navRef.current,\n bounds = dragBoundary?.getBoundingClientRect(),\n floating = !!ghost && !!current?.detached,\n tab = (floating ? null : ghost) ?? tabElement(active),\n frame = frameRef.current;\n if (ghost && current?.moved && bounds) {\n const sheet = surface(current.key);\n const preview =\n floating && sheet\n ? content.lift(sheet, ghost, current.sheet)\n : undefined;\n const left = floating ? 8 : bounds.left + 8,\n right = floating ? innerWidth - 8 : bounds.right - 8;\n const x = Math.max(\n left,\n Math.min(current.x - current.offset, right - ghost.offsetWidth),\n );\n const y = floating\n ? Math.max(\n 0,\n Math.min(current.y - current.offsetY, innerHeight - height - 8),\n )\n : nav!.getBoundingClientRect().top;\n ghost.style.left = `${x}px`;\n ghost.style.top = `${y}px`;\n if (preview) {\n content.move(x - preview.offset, y + height - 1);\n const left = preview.offset - 8,\n right = preview.width - preview.offset - tabWidth - 8;\n ghost\n .querySelector(\"svg > path\")!\n .setAttribute(\"d\", tabShape(left, right, size)[0]);\n const outline =\n ghost.querySelector<SVGPathElement>(\"[data-tab-outline]\")!;\n outline.style.visibility = \"visible\";\n outline.setAttribute(\n \"d\",\n paneShape(left, right, height + preview.height - 1.5, true, size),\n );\n } else content.release();\n }\n restoreFrame();\n if (!tab || !bounds || !frame) {\n if (frame) frame.style.visibility = \"hidden\";\n return;\n }\n const box = tab.getBoundingClientRect();\n const sheet = surface(),\n sheetBox = sheet?.getBoundingClientRect();\n const attached = Math.abs(box.top - bounds.top) < 0.5 && !!sheet;\n const left = attached ? box.left - 8 - sheetBox!.left : 16,\n right = attached ? sheetBox!.right - box.right - 8 : 16;\n if (ghost && !floating) {\n const [fill, outline] = tabShape(\n Math.max(0, left),\n Math.max(0, right),\n size,\n );\n ghost.querySelector(\"svg > path\")!.setAttribute(\"d\", fill);\n ghost.querySelector(\"[data-tab-outline]\")!.setAttribute(\"d\", outline);\n }\n const stroke = tab.querySelector<SVGPathElement>(\"[data-tab-outline]\")!;\n stroke.style.visibility = attached ? \"hidden\" : \"visible\";\n maskedOutline.current = stroke;\n frame.style.visibility = attached ? \"visible\" : \"hidden\";\n if (!attached) return;\n sheet!.style.borderColor = \"transparent\";\n maskedSheet.current = sheet;\n const x = box.left - 8,\n bottom = sheetBox!.bottom - box.top - 0.5;\n const origin = frame.parentElement!.getBoundingClientRect();\n frame.style.left = `${x - origin.left}px`;\n frame.style.top = `${box.top - origin.top}px`;\n const viewport =\n ghost && !floating ? sheetBox! : nav!.getBoundingClientRect(),\n clipLeft = Math.max(-left, viewport.left - x),\n clipRight = Math.min(width + right, viewport.right - x);\n frame.style.clipPath = `polygon(${clipLeft}px 0px, ${clipRight}px 0px, ${clipRight}px ${height - 1}px, ${width + right}px ${height - 1}px, ${width + right}px ${bottom + 1}px, ${-left}px ${bottom + 1}px, ${-left}px ${height - 1}px, ${clipLeft}px ${height - 1}px)`;\n frame\n .querySelector(\"path\")!\n .setAttribute(\n \"d\",\n paneShape(left, right, bottom, !!ghost && !floating, size) +\n ((!ghost || floating) && clipLeft > 0\n ? ` M0 ${height - 0.5} H${Math.min(width, clipLeft)}`\n : \"\") +\n ((!ghost || floating) && clipRight < width\n ? ` M${Math.max(0, clipRight)} ${height - 0.5} H${width}`\n : \"\"),\n );\n };\n const animate = (element: HTMLElement, from: number) => {\n const transform = getComputedStyle(element).transform;\n if (transform !== \"none\") from += new DOMMatrixReadOnly(transform).m41;\n element.getAnimations().forEach((animation) => animation.cancel());\n if (!matchMedia(\"(prefers-reduced-motion: reduce)\").matches)\n element.animate(\n [{ transform: `translateX(${from}px)` }, { transform: \"none\" }],\n motion,\n );\n };\n const settle = (key: string) =>\n requestAnimationFrame(() => {\n if (drag.current) return;\n reveal(key);\n const ghost = ghostRef.current,\n slot = tabElement(key);\n if (\n !ghost ||\n !slot ||\n matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n ) {\n setDragging(undefined);\n return;\n }\n const from = ghost.getBoundingClientRect(),\n to = slot.getBoundingClientRect();\n settling.current = ghost.animate(\n [\n { transform: \"none\" },\n {\n transform: `translate(${to.left - from.left}px,${to.top - from.top}px)`,\n },\n ],\n { ...motion, fill: \"forwards\" },\n );\n settling.current.onfinish = () => setDragging(undefined);\n latest.current.refresh();\n });\n const finish = (cancel = false) => {\n const current = drag.current;\n if (!current) return;\n drag.current = undefined;\n suppressClick.current = current.moved;\n content.release();\n if (cancel) {\n docking.cancel();\n if (current.moved) onReorder(current.order);\n announce(\"\");\n }\n if (current.moved && (cancel || !docking.drop())) settle(current.key);\n else setDragging(undefined);\n };\n const move = (from: string, to: string) => {\n const order = links.map(([key]) => key),\n index = order.indexOf(to);\n if (from === to || index < 0) return;\n order.splice(order.indexOf(from), 1);\n order.splice(index, 0, from);\n onReorder(order);\n announce(`${labels.get(from)}: position ${index + 1} of ${order.length}`);\n };\n const focusTab = (key: string) =>\n requestAnimationFrame(() => document.getElementById(ids.tab(key))?.focus());\n const split = (key: string, edge: \"left\" | \"right\" | \"bottom\") => {\n announce(\n docking.split(key, edge)\n ? `${labels.get(key)} split ${edge}`\n : \"Open another tab or make this pane larger to split it\",\n );\n focusTab(key);\n };\n const keyDown = (event: React.KeyboardEvent, key: string, index: number) => {\n if (event.key === \"Escape\") return finish(true);\n const edges: Record<string, \"left\" | \"right\" | \"bottom\"> = {\n ArrowLeft: \"left\",\n ArrowRight: \"right\",\n ArrowDown: \"bottom\",\n };\n const edge = edges[event.key];\n if (event.altKey && edge) {\n if (event.shiftKey) split(key, edge);\n else if (edge !== \"bottom\")\n move(key, items[index + (edge === \"left\" ? -1 : 1)]?.key ?? key);\n else return;\n } else {\n if (event.altKey || event.ctrlKey || event.metaKey) return;\n const targets: Record<string, number> = {\n Home: 0,\n End: items.length - 1,\n ArrowLeft: (index + items.length - 1) % items.length,\n ArrowRight: (index + 1) % items.length,\n };\n const target = targets[event.key];\n if (target !== undefined)\n document.getElementById(ids.tab(items[target]!.key))?.focus();\n else if (event.key === \"Delete\") onClose(key);\n else if (event.key === \" \") onSelect(key);\n else return;\n }\n event.preventDefault();\n };\n const measure = () => {\n const nav = navRef.current,\n strip = stripRef.current;\n if (!nav || !strip || !dragBoundary) return;\n const trailing =\n strip.parentElement!.nextElementSibling?.getBoundingClientRect().width ??\n 0;\n const availableWidth = Math.max(\n 0,\n dragBoundary.getBoundingClientRect().right -\n strip.getBoundingClientRect().left -\n trailing -\n 4,\n );\n const inserting = docking.insertion === undefined ? 0 : 1;\n const count = items.length - (drag.current?.detached ? 1 : 0) + inserting;\n const next = {\n available: availableWidth,\n overflow:\n count *\n fitTabWidth(density.width, availableWidth, items.length + inserting) +\n 16 >\n availableWidth + 1,\n left: nav.scrollLeft > 1,\n right: nav.scrollLeft + nav.clientWidth < nav.scrollWidth - 1,\n };\n const current = measured.current;\n if (\n next.available !== current.available ||\n next.overflow !== current.overflow ||\n next.left !== current.left ||\n next.right !== current.right\n ) {\n measured.current = next;\n setMetrics(next);\n }\n };\n const follow = () => {\n const nav = navRef.current;\n if (\n [surface(), nav, ghostRef.current].some((element) =>\n element\n ?.getAnimations({ subtree: element === nav })\n .some((animation) => animation.playState === \"running\"),\n )\n )\n frame.current = requestAnimationFrame(() => latest.current.refresh());\n };\n const refresh = (resized = false) => {\n cancelAnimationFrame(frame.current);\n measure();\n if (resized) reveal();\n draw();\n follow();\n };\n const latest = React.useRef({ refresh, finish });\n const detached = !!dragging && !!drag.current?.detached;\n React.useLayoutEffect(() => {\n latest.current = { refresh, finish };\n const order = JSON.stringify([tabOrder, docking.insertion]);\n const previous = positions.current;\n positions.current = { order, tabs: new Map() };\n for (const element of navRef.current!\n .children as HTMLCollectionOf<HTMLElement>) {\n const key = element.querySelector(\"a\")?.dataset.tab;\n if (!key) continue;\n const left = element.offsetLeft,\n from = previous.tabs.get(key);\n if (\n previous.order !== order &&\n key !== dragging &&\n from !== undefined &&\n from !== left\n )\n animate(element, from - left);\n positions.current.tabs.set(key, left);\n }\n cancelAnimationFrame(frame.current);\n draw();\n follow();\n });\n React.useLayoutEffect(\n () => refresh(),\n // oxlint-disable-next-line react-hooks/exhaustive-deps -- the inputs refresh measures\n [\n dragBoundary,\n active,\n tabOrder,\n docking.insertion,\n tabWidth,\n height,\n metrics.overflow,\n dragging,\n detached,\n ],\n );\n // oxlint-disable-next-line react-hooks/exhaustive-deps -- only when the active tab or order changes\n React.useLayoutEffect(() => reveal(), [active, tabOrder, docking.insertion]);\n React.useLayoutEffect(() => {\n const nav = navRef.current!;\n const resize = () => latest.current.refresh(true),\n scroll = () => latest.current.refresh(),\n blur = () => latest.current.finish(true);\n const wheel = (event: WheelEvent) => {\n if (\n event.ctrlKey ||\n Math.abs(event.deltaX) >= Math.abs(event.deltaY) ||\n nav.scrollWidth <= nav.clientWidth\n )\n return;\n event.preventDefault();\n nav.scrollLeft +=\n event.deltaY *\n (event.deltaMode === 1\n ? 16\n : event.deltaMode === 2\n ? nav.clientWidth\n : 1);\n };\n const observer = new ResizeObserver(resize);\n for (const element of [\n nav,\n stripRef.current,\n dragBoundary,\n ...(dragBoundary?.children ?? []),\n surface(),\n ])\n if (element) observer.observe(element);\n addEventListener(\"scroll\", scroll, true);\n addEventListener(\"blur\", blur);\n nav.addEventListener(\"wheel\", wheel, { passive: false });\n return () => {\n observer.disconnect();\n removeEventListener(\"scroll\", scroll, true);\n removeEventListener(\"blur\", blur);\n nav.removeEventListener(\"wheel\", wheel);\n cancelAnimationFrame(frame.current);\n restoreFrame();\n };\n // oxlint-disable-next-line react-hooks/exhaustive-deps -- reruns when the active tab changes\n }, [active, dragBoundary]);\n const scrollButton = (direction: -1 | 1) =>\n metrics.overflow && (\n <button\n type=\"button\"\n className=\"lab-scroll\"\n style={{ width: Math.min(28, height), height: Math.min(28, height) }}\n aria-label={direction < 0 ? \"Scroll tabs left\" : \"Scroll tabs right\"}\n title={direction < 0 ? \"Scroll tabs left\" : \"Scroll tabs right\"}\n disabled={direction < 0 ? !metrics.left : !metrics.right}\n onClick={() => {\n const nav = navRef.current!;\n nav.scrollBy({\n left: direction * Math.max(tabWidth, nav.clientWidth - tabWidth),\n behavior: matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n ? \"instant\"\n : \"smooth\",\n });\n }}\n >\n {direction < 0 ? (\n <ChevronLeftIcon className=\"lab-icon\" />\n ) : (\n <ChevronRightIcon className=\"lab-icon\" />\n )}\n </button>\n );\n return (\n <div ref={stripRef} className=\"lab-tabs\">\n {scrollButton(-1)}\n <div\n ref={navRef}\n role={links.length ? \"tablist\" : undefined}\n aria-label={\n links.length ? `Workspace tabs: ${labels.get(active)}` : undefined\n }\n aria-describedby={links.length ? helpId : undefined}\n onKeyDownCapture={() => setPointerFocus(false)}\n onBlurCapture={() => setPointerFocus(false)}\n onPointerDownCapture={() => {\n content.release(false);\n settling.current?.cancel();\n setDragging(undefined);\n drag.current = undefined;\n suppressClick.current = false;\n }}\n onDragStart={(event) => event.preventDefault()}\n onClickCapture={(event) => {\n if (suppressClick.current) {\n event.preventDefault();\n event.stopPropagation();\n suppressClick.current = false;\n }\n }}\n onPointerMove={(event) => {\n const current = drag.current,\n nav = navRef.current,\n x = event.clientX;\n if (!(event.buttons & 1) || !current || !nav) return;\n if (\n !current.moved &&\n Math.hypot(x - current.x, event.clientY - current.y) < 6\n )\n return;\n if (!current.moved && active !== current.key) onSelect(current.key);\n current.moved = true;\n if (!nav.hasPointerCapture(event.pointerId))\n nav.setPointerCapture(event.pointerId);\n setDragging(current.key);\n event.preventDefault();\n current.x = x;\n current.y = event.clientY;\n current.detached = docking.move(current);\n if (!current.detached) {\n const { left, right } = nav.getBoundingClientRect();\n nav.scrollLeft += x < left + 24 ? -16 : x > right - 24 ? 16 : 0;\n const index = Math.max(\n 0,\n Math.min(\n items.length - 1,\n Math.floor(\n (Math.max(left + 8, Math.min(x, right - 8)) -\n left +\n nav.scrollLeft -\n 8) /\n tabWidth,\n ),\n ),\n );\n move(current.key, items[index]!.key);\n }\n refresh();\n }}\n onPointerUp={() => finish()}\n onPointerCancel={() => finish(true)}\n className=\"lab-tablist\"\n >\n {links.map(([key, text], index) => {\n const actions: WorkspaceAction[] = [\n ...(onDuplicate\n ? [\n {\n label: \"Duplicate tab\",\n onSelect: () => {\n menuFocus.current = onDuplicate(key);\n },\n },\n ]\n : []),\n {\n label: \"Move left\",\n onSelect: () => move(key, items[index - 1]!.key),\n disabled: !index,\n },\n {\n label: \"Move right\",\n onSelect: () => move(key, items[index + 1]!.key),\n disabled: index === items.length - 1,\n },\n {\n label: \"Move to next pane\",\n onSelect: () => docking.next(key),\n disabled: docking.paneCount < 2,\n },\n null,\n ...([\"left\", \"right\", \"bottom\"] as const).map((edge) => ({\n label: `Split ${edge === \"bottom\" ? \"below\" : edge}`,\n onSelect: () => split(key, edge),\n disabled: items.length < 2,\n })),\n null,\n { label: \"Close tab\", onSelect: () => onClose(key) },\n ];\n const target = (\n <div\n role=\"presentation\"\n className=\"lab-tab\"\n data-dragging={dragging === key || undefined}\n style={{\n paddingTop: height - contentHeight,\n marginRight:\n dragging === key && drag.current?.detached ? -tabWidth : 0,\n marginLeft: docking.insertion === index ? tabWidth : 0,\n zIndex:\n active === key ? links.length + 1 : links.length - index,\n }}\n >\n <TabSurface\n width={tabWidth}\n selected={active === key}\n keyboardFocus={!pointerFocus}\n />\n <a\n id={ids.tab(key)}\n role=\"tab\"\n tabIndex={active === key ? 0 : -1}\n aria-selected={active === key}\n aria-controls={ids.panel(key)}\n href={items[index]!.href}\n data-tab={key}\n style={{ width: tabWidth, height: contentHeight }}\n onClick={(event) => {\n const { metaKey, ctrlKey, shiftKey, altKey } = event;\n if (metaKey || ctrlKey || shiftKey || altKey) return;\n event.preventDefault();\n onSelect(key);\n }}\n onFocus={() => onSelect(key)}\n draggable={false}\n title={text}\n aria-keyshortcuts=\"ArrowLeft ArrowRight Home End Delete Alt+ArrowLeft Alt+ArrowRight Alt+Shift+ArrowLeft Alt+Shift+ArrowRight Alt+Shift+ArrowDown\"\n onKeyDown={(event) => keyDown(event, key, index)}\n onPointerDown={(event) => {\n if (event.button !== 0 || !event.isPrimary) return;\n if (event.pointerType === \"mouse\") event.preventDefault();\n event.currentTarget.setPointerCapture(event.pointerId);\n event.currentTarget.focus({ preventScroll: true });\n setPointerFocus(true);\n const box =\n event.currentTarget.parentElement!.getBoundingClientRect();\n drag.current = {\n key,\n offset: event.clientX - box.left,\n offsetY: event.clientY - box.top,\n sheet: surface()!.getBoundingClientRect(),\n x: event.clientX,\n y: event.clientY,\n detached: false,\n moved: false,\n order: links.map(([path]) => path),\n };\n }}\n className=\"lab-tab-link\"\n >\n {items[index]!.icon && (\n <span aria-hidden=\"true\" className=\"lab-tab-icon\">\n {items[index]!.icon}\n </span>\n )}\n <span className=\"lab-tab-label\">{text}</span>\n </a>\n <CloseTab label={text} onClick={() => onClose(key)} />\n </div>\n );\n return (\n <React.Fragment key={key}>\n {menu\n ? menu(\n target,\n actions,\n () => {\n focusTab(menuFocus.current ?? key);\n menuFocus.current = undefined;\n },\n key,\n )\n : target}\n </React.Fragment>\n );\n })}\n {docking.insertion === items.length && (\n <div\n aria-hidden=\"true\"\n style={{ width: tabWidth }}\n className=\"lab-tab-placeholder\"\n />\n )}\n </div>\n {scrollButton(1)}\n <span className=\"lab-sr-only\" aria-live=\"polite\">\n {announcement}\n </span>\n <span id={helpId} className=\"lab-sr-only\">\n Arrow keys switch tabs. Home and End select the first and last tab.\n Delete closes a tab. Alt plus Left or Right reorders. Alt plus Shift and\n Left, Right, or Down splits a pane. F6 moves between panes; Shift plus\n F6 moves back.\n {menu &&\n \" Right-click or press Shift plus F10 for tab actions without dragging.\"}\n </span>\n {active && (\n <svg\n ref={frameRef}\n aria-hidden=\"true\"\n data-pane-frame\n viewBox={`0 0 ${width} ${height}`}\n strokeWidth={size.borderWidth}\n style={{ width, height }}\n className=\"lab-pane-frame\"\n >\n <path className=\"lab-outline\" />\n </svg>\n )}\n {dragging &&\n createPortal(\n <div\n ref={ghost}\n data-dragged-tab\n aria-hidden=\"true\"\n style={{\n width: tabWidth,\n height,\n paddingTop: height - contentHeight,\n }}\n className=\"lab-ghost\"\n >\n <TabSurface selected width={tabWidth} />\n <span\n style={{ height: contentHeight }}\n className=\"lab-ghost-content\"\n >\n {items.find((item) => item.key === dragging)?.icon && (\n <span className=\"lab-tab-icon\">\n {items.find((item) => item.key === dragging)!.icon}\n </span>\n )}\n <span className=\"lab-tab-label\">{labels.get(dragging)}</span>\n </span>\n <CloseTab label={labels.get(dragging)!} />\n </div>,\n document.body,\n )}\n </div>\n );\n}\n\nfunction CloseTab({ label, onClick }: { label: string; onClick?: () => void }) {\n const { height, contentHeight } = useTabSize();\n return (\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={`Close ${label}`}\n title={`Close ${label}`}\n style={{ top: height - contentHeight / 2 }}\n className=\"lab-tab-close\"\n onClick={onClick}\n >\n <XIcon className=\"lab-tab-close-icon\" />\n </button>\n );\n}\n", "import type { SVGProps } from \"react\";\n\nconst icon = (strokeWidth: number, ...paths: string[]) =>\n function Icon(props: SVGProps<SVGSVGElement>) {\n return (\n <svg\n width={16}\n height={16}\n viewBox=\"0 0 16 16\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth={strokeWidth}\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n aria-hidden=\"true\"\n {...props}\n >\n {paths.map((d) => (\n <path key={d} d={d} />\n ))}\n </svg>\n );\n };\n\nexport const ChevronLeftIcon = icon(4 / 3, \"M10 4 6 8l4 4\");\nexport const ChevronRightIcon = icon(4 / 3, \"m6 4 4 4-4 4\");\nexport const XIcon = icon(7 / 6, \"m12 4-8 8\", \"m4 4 8 8\");\n", "import { densityPresets, useTabSize } from \"./context.js\";\n\ntype Point = [number, number];\nconst reach = 16;\nconst shoulder: Point[] = [\n [0, 43.5],\n [8.56, 43.5],\n [13, 30],\n [16, 21],\n [19, 12],\n [22, 8],\n [30, 8],\n];\n\nfunction corner(gap: number): Point[] {\n if (gap >= reach) return shoulder;\n const wall = 0.5 - gap,\n radius = Math.max(0, gap - 0.5);\n const source: Point[] = [\n [wall, 59],\n [wall, 50.44],\n [wall + radius * 0.4477, 43.5],\n [wall + radius, 43.5],\n [wall + radius * 1.5523, 43.5],\n ...shoulder.slice(2),\n ];\n const target: Point[] = [\n [wall, 59],\n [wall, 47.33],\n [wall, 28.4183],\n [wall, 24],\n [wall, 19.5817],\n [wall + 1.7909, 15.5817],\n [wall + 4.6863, 12.6863],\n [wall + 7.5817, 9.7909],\n [wall + 11.5817, 8],\n [wall + 16, 8],\n ];\n const t = 1 - gap / reach,\n amount = t * t * (3 - 2 * t);\n return source.map(([x, y], i) => [\n x + (target[i]![0] - x) * amount,\n y + (target[i]![1] - y) * amount,\n ]);\n}\n\nexport function tabShape(\n leftGap = reach,\n rightGap = reach,\n size = densityPresets.comfortable,\n) {\n const width = size.width + 16;\n const left = corner(leftGap);\n const right = corner(rightGap)\n .map(([x, y]) => [width - x, y] as Point)\n .reverse();\n const coords = ([x, y]: Point) =>\n [\n x,\n size.height -\n 0.5 +\n (y - 43.5) * (y < 43.5 ? (size.contentHeight - 0.5) / 35.5 : 1),\n ]\n .map((v) => Math.round(v * 1000) / 1000)\n .join(\" \");\n const curves = (points: Point[]) =>\n points\n .slice(1)\n .map((p, i) => (i % 3 === 0 ? \" C\" : \" \") + coords(p))\n .join(\"\");\n const outline = `M${coords(left[0]!)}${curves(left)} H${right[0]![0]}${curves(right)}`;\n return [\n `${outline} V${size.height + (leftGap < reach || rightGap < reach ? 15 : 0)} H${left[0]![0]} Z`,\n outline,\n ] as const;\n}\n\nexport function paneShape(\n leftGap: number,\n rightGap: number,\n bottom: number,\n morph = true,\n size = densityPresets.comfortable,\n) {\n const width = size.width + 16,\n baseline = size.height - 0.5,\n cornerBottom = size.height + 15;\n const left = 0.5 - leftGap,\n right = width + rightGap - 0.5;\n const rightCorner =\n morph && rightGap < reach\n ? \"\"\n : ` H${right - 15.5} A15.5 15.5 0 0 1 ${right} ${cornerBottom}`;\n const leftCorner =\n morph && leftGap < reach\n ? \"\"\n : ` A15.5 15.5 0 0 1 ${left + 15.5} ${baseline} H0`;\n return `${tabShape(morph ? leftGap : reach, morph ? rightGap : reach, size)[1]}${rightCorner} V${bottom - 15.5} A15.5 15.5 0 0 1 ${right - 15.5} ${bottom} H${left + 15.5} A15.5 15.5 0 0 1 ${left} ${bottom - 15.5} V${cornerBottom}${leftCorner} Z`;\n}\n\nexport function TabSurface({\n selected,\n keyboardFocus = false,\n width,\n}: {\n selected: boolean;\n keyboardFocus?: boolean;\n width?: number;\n}) {\n const density = useTabSize(),\n size = { ...density, width: width ?? density.width },\n viewWidth = size.width + 16;\n const [fill, outline] = tabShape(undefined, undefined, size);\n return (\n <svg\n aria-hidden=\"true\"\n viewBox={`0 0 ${viewWidth} ${size.height}`}\n strokeWidth={size.borderWidth}\n preserveAspectRatio=\"none\"\n className=\"lab-tab-surface\"\n >\n <path\n d={fill}\n className=\"lab-tab-fill\"\n data-selected={selected || undefined}\n />\n <path d={outline} data-tab-outline className=\"lab-outline\" />\n {keyboardFocus && <path d={outline} className=\"lab-tab-focus\" />}\n {!selected && (\n <path\n d={`M0 ${size.height - 0.5} H${viewWidth}`}\n className=\"lab-outline\"\n />\n )}\n </svg>\n );\n}\n", "import { useEffect, useRef } from \"react\";\n\nexport function useDragContent() {\n const generation = useRef(0);\n const current = useRef<\n | {\n element: HTMLElement;\n width: number;\n height: number;\n offset: number;\n inert: boolean;\n }\n | undefined\n >(undefined);\n const release = (animate = true) => {\n const preview = current.current;\n if (!preview) return;\n current.current = undefined;\n const version = ++generation.current;\n const { element, inert } = preview;\n const from = element.getBoundingClientRect();\n element.removeAttribute(\"data-drag-content\");\n element.inert = inert;\n element.style.transition = \"none\";\n for (const name of [\"x\", \"y\", \"width\", \"height\"])\n element.style.removeProperty(`--lab-drag-${name}`);\n requestAnimationFrame(() => {\n if (version !== generation.current) return;\n const to = element.getBoundingClientRect();\n element.style.removeProperty(\"transition\");\n if (\n !animate ||\n !element.isConnected ||\n !to.width ||\n matchMedia(\"(prefers-reduced-motion: reduce)\").matches\n )\n return;\n const resized =\n Math.abs(from.width - to.width) > 0.5 ||\n Math.abs(from.height - to.height) > 0.5;\n element.animate(\n [\n {\n transform: `translate(${from.left - to.left}px, ${from.top - to.top}px)`,\n width: `${from.width}px`,\n height: `${from.height}px`,\n filter: \"blur(0)\",\n opacity: 1,\n },\n {\n filter: resized ? \"blur(3px)\" : \"blur(0)\",\n opacity: resized ? 0.85 : 1,\n offset: 0.35,\n },\n {\n transform: \"none\",\n width: `${to.width}px`,\n height: `${to.height}px`,\n filter: \"blur(0)\",\n opacity: 1,\n },\n ],\n { duration: 220, easing: \"cubic-bezier(.2,.8,.2,1)\" },\n );\n });\n };\n useEffect(() => () => release(false), []);\n return {\n release,\n lift(element: HTMLElement, tab: HTMLElement, fallback: DOMRect) {\n if (current.current?.element !== element) {\n release(false);\n generation.current++;\n element.getAnimations().forEach((animation) => animation.cancel());\n const bounds = element.hidden\n ? fallback\n : element.getBoundingClientRect();\n current.current = {\n element,\n width: bounds.width,\n height: bounds.height,\n offset: Math.max(\n 8,\n Math.min(\n tab.getBoundingClientRect().left - bounds.left,\n bounds.width - tab.offsetWidth - 8,\n ),\n ),\n inert: element.inert,\n };\n for (const [name, value] of Object.entries({\n width: `${bounds.width}px`,\n height: `${bounds.height}px`,\n }))\n element.style.setProperty(`--lab-drag-${name}`, String(value));\n element.inert = true;\n element.setAttribute(\"data-drag-content\", \"\");\n }\n return current.current!;\n },\n move(x: number, y: number) {\n const element = current.current?.element;\n element?.style.setProperty(\"--lab-drag-x\", `${x}px`);\n element?.style.setProperty(\"--lab-drag-y\", `${y}px`);\n },\n };\n}\n", "import * as React from \"react\";\n\nexport const UnsavedChanges = React.createContext<\n ((source: symbol, dirty: boolean) => void) | undefined\n>(undefined);\nexport function useUnsavedChanges(dirty: boolean) {\n const report = React.useContext(UnsavedChanges);\n const source = React.useRef(Symbol());\n React.useLayoutEffect(() => {\n const id = source.current;\n report?.(id, dirty);\n return () => report?.(id, false);\n }, [dirty, report]);\n}\n", "import {\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\n\nexport function WorkspaceFrame({\n expanded,\n change,\n children,\n}: {\n expanded: boolean;\n change: (expanded: boolean) => void;\n children: ReactNode;\n}) {\n const viewport = useRef<HTMLDivElement>(null);\n const drag = useRef<{ x: number; width: number } | undefined>(undefined);\n const [available, setAvailable] = useState(0);\n const [draft, setDraft] = useState<number>();\n const compact = Math.min(1600, available);\n const width = draft ?? (expanded ? available : compact);\n const cancel = () => {\n drag.current = undefined;\n setDraft(undefined);\n };\n useLayoutEffect(() => {\n const observer = new ResizeObserver(() => {\n setAvailable(viewport.current!.clientWidth);\n cancel();\n });\n observer.observe(viewport.current!);\n addEventListener(\"blur\", cancel);\n return () => {\n observer.disconnect();\n removeEventListener(\"blur\", cancel);\n };\n }, []);\n return (\n <div ref={viewport} className=\"lab-frame\">\n <div\n className=\"lab-frame-content\"\n style={\n {\n width: available ? width : \"100%\",\n maxWidth: expanded ? undefined : (draft ?? 1600),\n \"--workspace-duration\": draft === undefined ? undefined : \"0ms\",\n } as CSSProperties\n }\n >\n {children}\n {available > compact &&\n [\"left\", \"right\"].map((side) => (\n <div\n key={side}\n role=\"separator\"\n aria-label={`Resize workspace from ${side}`}\n aria-orientation=\"vertical\"\n aria-valuemin={0}\n aria-valuemax={100}\n aria-valuenow={Math.round(\n ((width - compact) / (available - compact)) * 100,\n )}\n aria-valuetext={\n width === compact\n ? \"Centered\"\n : width === available\n ? \"Full width\"\n : \"Resizing\"\n }\n title=\"Drag outward for full width or inward to center. Double-click to toggle; arrow keys also resize.\"\n tabIndex={0}\n className=\"lab-frame-handle\"\n style={{ [side]: -24 }}\n onDoubleClick={() => change(!expanded)}\n onPointerDown={(event) => {\n if (event.button !== 0) return;\n event.preventDefault();\n event.currentTarget.focus({ preventScroll: true });\n drag.current = { x: event.clientX, width };\n setDraft(width);\n event.currentTarget.setPointerCapture(event.pointerId);\n }}\n onPointerMove={(event) => {\n if (\n !drag.current ||\n !event.currentTarget.hasPointerCapture(event.pointerId)\n )\n return;\n const next =\n drag.current.width +\n (event.clientX - drag.current.x) * (side === \"left\" ? -2 : 2);\n const snap = Math.min(32, (available - compact) / 4);\n setDraft(\n next > available - snap\n ? available\n : next < compact + snap\n ? compact\n : next,\n );\n }}\n onPointerUp={(event) => {\n if (!drag.current) return;\n change(width > (compact + available) / 2);\n cancel();\n event.currentTarget.releasePointerCapture(event.pointerId);\n }}\n onLostPointerCapture={cancel}\n onPointerCancel={cancel}\n onKeyDown={(event) => {\n if (event.key === \"Escape\" && drag.current) {\n event.preventDefault();\n cancel();\n } else if (\n [\"ArrowLeft\", \"ArrowRight\", \"Home\", \"End\"].includes(event.key)\n ) {\n event.preventDefault();\n cancel();\n change(\n event.key === \"End\" ||\n event.key ===\n (side === \"left\" ? \"ArrowLeft\" : \"ArrowRight\"),\n );\n }\n }}\n />\n ))}\n </div>\n </div>\n );\n}\n", "import {\n useEffect,\n useLayoutEffect,\n useRef,\n useState,\n type CSSProperties,\n type ReactNode,\n} from \"react\";\n\nexport type WindowEdge = \"n\" | \"s\" | \"e\" | \"w\" | \"ne\" | \"nw\" | \"se\" | \"sw\";\n// WindowHost connects the workspace to a desktop shell such as Wails, Tauri, or Electron\nexport type WindowHost = {\n platform: \"windows\" | \"macos\" | \"linux\";\n minimize: () => void;\n toggleMaximize: () => void;\n close: () => void;\n drag?: () => void;\n resize?: (edge: WindowEdge) => void;\n fullscreen?: (on: boolean) => void;\n};\n\nconst client = typeof window !== \"undefined\";\nconst maximized = () =>\n client &&\n outerWidth >= screen.availWidth &&\n outerHeight >= screen.availHeight;\nconst isFullscreen = (host?: WindowHost) =>\n client &&\n (host?.fullscreen\n ? innerWidth >= screen.width && innerHeight >= screen.height\n : !!document.fullscreenElement);\nconst setFullscreen = (host: WindowHost | undefined, on: boolean) => {\n if (host?.fullscreen) host.fullscreen(on);\n else if (on) void document.documentElement.requestFullscreen?.();\n else if (document.fullscreenElement) void document.exitFullscreen();\n};\nconst interactive =\n \"a, button, input, select, textarea, label, summary, [contenteditable], [role=button], [role=tab], [role=separator], [role=menuitem], .lab-tab\";\nconst draggable = (target: EventTarget | null) =>\n target instanceof Element &&\n !target.closest(interactive) &&\n (!!target.closest(\".lab-toolbar, [data-window-drag]\") ||\n target.matches(\".lab-workspace\") ||\n !!target.querySelector(\".lab-workspace\"));\n\n// useFullscreen tracks full screen: the window's with a host, the page's without\nexport function useFullscreen(host?: WindowHost) {\n const [full, setFull] = useState(() => isFullscreen(host));\n useEffect(() => {\n const update = () => setFull(isFullscreen(host));\n update();\n window.addEventListener(\"resize\", update);\n document.addEventListener(\"fullscreenchange\", update);\n return () => {\n window.removeEventListener(\"resize\", update);\n document.removeEventListener(\"fullscreenchange\", update);\n };\n }, [host]);\n return [full, (on: boolean) => setFullscreen(host, on)] as const;\n}\n\n// useWindowFrame drags, maximises, and resizes a frameless window, and handles the full screen key\nexport function useWindowFrame(host?: WindowHost) {\n useEffect(() => {\n if (!host) return;\n const root = document.documentElement;\n let armed = false;\n let cursor = \"\";\n const edgeAt = (x: number, y: number) => {\n if (!host.resize || maximized()) return \"\";\n const vertical = y < 6 ? \"n\" : y > innerHeight - 6 ? \"s\" : \"\";\n const horizontal = x < 6 ? \"w\" : x > innerWidth - 6 ? \"e\" : \"\";\n return (vertical + horizontal) as WindowEdge | \"\";\n };\n const move = (event: MouseEvent) => {\n if (armed && event.buttons === 1) {\n armed = false;\n host.drag!();\n } else if (!event.buttons) {\n const edge = edgeAt(event.clientX, event.clientY);\n const next = edge && `${edge}-resize`;\n if (next !== cursor) root.style.cursor = cursor = next;\n }\n };\n const down = (event: MouseEvent) => {\n if (event.button !== 0) return;\n const edge = edgeAt(event.clientX, event.clientY);\n if (edge) {\n event.preventDefault();\n host.resize!(edge);\n } else\n armed = !!host.drag && event.detail === 1 && draggable(event.target);\n };\n const up = () => {\n armed = false;\n };\n const dblclick = (event: MouseEvent) => {\n if (draggable(event.target)) host.toggleMaximize();\n };\n const key = (event: KeyboardEvent) => {\n const shortcut =\n host.platform === \"macos\"\n ? event.ctrlKey && event.metaKey && event.code === \"KeyF\"\n : event.key === \"F11\";\n if (!host.fullscreen || !shortcut) return;\n event.preventDefault();\n host.fullscreen(!isFullscreen(host));\n };\n window.addEventListener(\"mousemove\", move);\n window.addEventListener(\"mousedown\", down);\n window.addEventListener(\"mouseup\", up);\n window.addEventListener(\"dblclick\", dblclick);\n window.addEventListener(\"keydown\", key);\n return () => {\n window.removeEventListener(\"mousemove\", move);\n window.removeEventListener(\"mousedown\", down);\n window.removeEventListener(\"mouseup\", up);\n window.removeEventListener(\"dblclick\", dblclick);\n window.removeEventListener(\"keydown\", key);\n if (cursor) root.style.cursor = \"\";\n };\n }, [host]);\n}\n\nconst glyph = (children: ReactNode) => (\n <svg\n aria-hidden=\"true\"\n viewBox=\"0 0 10 10\"\n width=\"10\"\n height=\"10\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"1\"\n >\n {children}\n </svg>\n);\n\n// WindowControls are caption buttons for the workspace's trailing slot, flush in the window's corner\nexport function WindowControls({ host }: { host: WindowHost }) {\n const [full] = useFullscreen(host);\n const [max, setMax] = useState(maximized);\n const [top, setTop] = useState(0);\n const spacer = useRef<HTMLDivElement>(null);\n const hidden = host.platform === \"macos\" || full;\n const measure = () => {\n setMax(maximized());\n if (spacer.current) setTop(spacer.current.getBoundingClientRect().top);\n };\n useLayoutEffect(measure);\n useEffect(() => {\n window.addEventListener(\"resize\", measure);\n return () => window.removeEventListener(\"resize\", measure);\n }, []);\n if (hidden) return null;\n const button = (\n label: string,\n action: () => void,\n icon: ReactNode,\n close?: boolean,\n ) => (\n <button\n type=\"button\"\n tabIndex={-1}\n aria-label={label}\n title={label}\n className={\n close ? \"lab-window-button lab-window-close\" : \"lab-window-button\"\n }\n onClick={action}\n >\n {icon}\n </button>\n );\n return (\n <div\n ref={spacer}\n className=\"lab-window-controls\"\n style={{ \"--lab-window-top\": `${top}px` } as CSSProperties}\n >\n <div className=\"lab-window-buttons\">\n {button(\n \"Minimize\",\n () => host.minimize(),\n glyph(<path d=\"M0 5.5h10\" />),\n )}\n {button(\n max ? \"Restore\" : \"Maximize\",\n () => host.toggleMaximize(),\n max\n ? glyph(\n <>\n <rect x=\"0.5\" y=\"2.5\" width=\"7\" height=\"7\" rx=\"1\" />\n <path d=\"M2.5 2.5v-1a1 1 0 0 1 1-1h5a1 1 0 0 1 1 1v5a1 1 0 0 1-1 1h-1\" />\n </>,\n )\n : glyph(<rect x=\"0.5\" y=\"0.5\" width=\"9\" height=\"9\" rx=\"1\" />),\n )}\n {button(\n \"Close\",\n () => host.close(),\n glyph(<path d=\"m0.5 0.5 9 9m0-9-9 9\" />),\n true,\n )}\n </div>\n </div>\n );\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["useEffect", "useId", "useLayoutEffect", "useRef", "useState", "node", "value", "index", "gutter", "header", "useState", "jsx", "jsx", "jsxs", "useRef", "jsx", "jsxs", "ghost", "frame", "sheet", "left", "right", "x", "jsx", "jsxs", "useState", "React", "Fragment", "jsx", "jsxs", "useId", "corner", "useRef", "useState", "useLayoutEffect", "useEffect", "key", "tab", "useLayoutEffect", "useRef", "useState", "jsx", "jsxs", "useEffect", "useLayoutEffect", "useRef", "useState", "Fragment", "jsx", "jsxs", "icon"]
|
|
7
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { type ReactElement, type ReactNode } from "react";
|
|
2
|
+
export declare const WorkspaceId: import("react").Context<string>;
|
|
3
|
+
export declare const densityPresets: {
|
|
4
|
+
comfortable: {
|
|
5
|
+
value: number;
|
|
6
|
+
width: number;
|
|
7
|
+
height: number;
|
|
8
|
+
contentHeight: number;
|
|
9
|
+
columnGap: number;
|
|
10
|
+
rowGap: number;
|
|
11
|
+
logoSize: number;
|
|
12
|
+
borderWidth: number;
|
|
13
|
+
};
|
|
14
|
+
compact: {
|
|
15
|
+
value: number;
|
|
16
|
+
width: number;
|
|
17
|
+
height: number;
|
|
18
|
+
contentHeight: number;
|
|
19
|
+
columnGap: number;
|
|
20
|
+
rowGap: number;
|
|
21
|
+
logoSize: number;
|
|
22
|
+
borderWidth: number;
|
|
23
|
+
};
|
|
24
|
+
dense: {
|
|
25
|
+
value: number;
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
contentHeight: number;
|
|
29
|
+
columnGap: number;
|
|
30
|
+
rowGap: number;
|
|
31
|
+
logoSize: number;
|
|
32
|
+
borderWidth: number;
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
export type Density = number;
|
|
36
|
+
export declare function densitySize(density: Density): {
|
|
37
|
+
value: number;
|
|
38
|
+
width: number;
|
|
39
|
+
height: number;
|
|
40
|
+
contentHeight: number;
|
|
41
|
+
columnGap: number;
|
|
42
|
+
rowGap: number;
|
|
43
|
+
logoSize: number;
|
|
44
|
+
borderWidth: number;
|
|
45
|
+
};
|
|
46
|
+
export declare const WorkspaceDensity: import("react").Context<number>;
|
|
47
|
+
export declare const fitTabWidth: (width: number, available: number, count: number) => number;
|
|
48
|
+
export declare function useTabSize(): {
|
|
49
|
+
value: number;
|
|
50
|
+
width: number;
|
|
51
|
+
height: number;
|
|
52
|
+
contentHeight: number;
|
|
53
|
+
columnGap: number;
|
|
54
|
+
rowGap: number;
|
|
55
|
+
logoSize: number;
|
|
56
|
+
borderWidth: number;
|
|
57
|
+
};
|
|
58
|
+
export declare function useWorkspaceIds(): {
|
|
59
|
+
tab: (key: string) => string;
|
|
60
|
+
panel: (key: string) => string;
|
|
61
|
+
};
|
|
62
|
+
export type WorkspaceAction = {
|
|
63
|
+
label: string;
|
|
64
|
+
onSelect: () => void;
|
|
65
|
+
disabled?: boolean;
|
|
66
|
+
} | null;
|
|
67
|
+
export type WorkspaceMenu = (target: ReactElement, actions: WorkspaceAction[], restoreFocus?: () => void, tab?: string) => ReactNode;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare function useDragContent(): {
|
|
2
|
+
release: (animate?: boolean) => void;
|
|
3
|
+
lift(element: HTMLElement, tab: HTMLElement, fallback: DOMRect): {
|
|
4
|
+
element: HTMLElement;
|
|
5
|
+
width: number;
|
|
6
|
+
height: number;
|
|
7
|
+
offset: number;
|
|
8
|
+
inert: boolean;
|
|
9
|
+
};
|
|
10
|
+
move(x: number, y: number): void;
|
|
11
|
+
};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
export declare function tabShape(leftGap?: number, rightGap?: number, size?: {
|
|
2
|
+
value: number;
|
|
3
|
+
width: number;
|
|
4
|
+
height: number;
|
|
5
|
+
contentHeight: number;
|
|
6
|
+
columnGap: number;
|
|
7
|
+
rowGap: number;
|
|
8
|
+
logoSize: number;
|
|
9
|
+
borderWidth: number;
|
|
10
|
+
}): readonly [`${string} V${number} H${number} Z`, string];
|
|
11
|
+
export declare function paneShape(leftGap: number, rightGap: number, bottom: number, morph?: boolean, size?: {
|
|
12
|
+
value: number;
|
|
13
|
+
width: number;
|
|
14
|
+
height: number;
|
|
15
|
+
contentHeight: number;
|
|
16
|
+
columnGap: number;
|
|
17
|
+
rowGap: number;
|
|
18
|
+
logoSize: number;
|
|
19
|
+
borderWidth: number;
|
|
20
|
+
}): string;
|
|
21
|
+
export declare function TabSurface({ selected, keyboardFocus, width, }: {
|
|
22
|
+
selected: boolean;
|
|
23
|
+
keyboardFocus?: boolean;
|
|
24
|
+
width?: number;
|
|
25
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { SVGProps } from "react";
|
|
2
|
+
export declare const ChevronLeftIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
|
|
3
|
+
export declare const ChevronRightIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
|
|
4
|
+
export declare const XIcon: (props: SVGProps<SVGSVGElement>) => import("react").JSX.Element;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export { Workspace, type WorkspaceTab, type WorkspaceProps, type WorkspacePane, } from "./workspace.js";
|
|
2
|
+
export { WorkspaceFrame } from "./workspace-frame.js";
|
|
3
|
+
export { densityPresets, densitySize, type Density as WorkspaceDensity, type WorkspaceAction, type WorkspaceMenu, } from "./context.js";
|
|
4
|
+
export { useUnsavedChanges } from "./unsaved-changes.js";
|
|
5
|
+
export { restoreLayout, reconcileLayout, dockTab, panes, type Layout, type Pane, type Split, } from "./layout.js";
|
|
6
|
+
export { WindowControls, useFullscreen, useWindowFrame, type WindowEdge, type WindowHost, } from "./window.js";
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
export type Pane = {
|
|
2
|
+
id: string;
|
|
3
|
+
tabs: string[];
|
|
4
|
+
active?: string;
|
|
5
|
+
};
|
|
6
|
+
export type Split = {
|
|
7
|
+
id: string;
|
|
8
|
+
axis: "x" | "y";
|
|
9
|
+
ratio: number;
|
|
10
|
+
first: Layout;
|
|
11
|
+
second: Layout;
|
|
12
|
+
};
|
|
13
|
+
export type Layout = Pane | Split;
|
|
14
|
+
export type Edge = "left" | "right" | "bottom";
|
|
15
|
+
export type Box = {
|
|
16
|
+
x: number;
|
|
17
|
+
y: number;
|
|
18
|
+
width: number;
|
|
19
|
+
height: number;
|
|
20
|
+
};
|
|
21
|
+
type PaneBox = Box & {
|
|
22
|
+
pane: Pane;
|
|
23
|
+
};
|
|
24
|
+
export declare const minimum: {
|
|
25
|
+
x: number;
|
|
26
|
+
y: number;
|
|
27
|
+
};
|
|
28
|
+
export declare const isSplit: (node: Layout) => node is Split;
|
|
29
|
+
export declare const panes: (node: Layout) => Pane[];
|
|
30
|
+
export declare function updateLayout(node: Layout, id: string, change: (node: Layout) => Layout): Layout;
|
|
31
|
+
export declare function reconcileLayout(node: Layout, keys: string[], active?: string, preferred?: string): Layout;
|
|
32
|
+
export declare function restoreLayout(value: string | null, keys: string[]): Layout;
|
|
33
|
+
export declare function dockTab(layout: Layout, key: string, target: string, edge?: Edge, index?: number): Layout;
|
|
34
|
+
export declare function minimumSize(node: Layout, gap?: {
|
|
35
|
+
x: number;
|
|
36
|
+
y: number;
|
|
37
|
+
}): {
|
|
38
|
+
x: number;
|
|
39
|
+
y: number;
|
|
40
|
+
};
|
|
41
|
+
export declare function layoutBoxes(layout: Layout, width: number, height: number, gap?: {
|
|
42
|
+
x: number;
|
|
43
|
+
y: number;
|
|
44
|
+
}): {
|
|
45
|
+
leaves: PaneBox[];
|
|
46
|
+
dividers: (Box & {
|
|
47
|
+
split: Split;
|
|
48
|
+
bounds: Box;
|
|
49
|
+
ratio: number;
|
|
50
|
+
low: number;
|
|
51
|
+
high: number;
|
|
52
|
+
})[];
|
|
53
|
+
};
|
|
54
|
+
export declare function dropRegion(box: Box, edge?: Edge, gap?: {
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
}): Box;
|
|
58
|
+
export {};
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type WorkspaceMenu } from "./context.js";
|
|
2
|
+
import { type ReactNode, type CSSProperties } from "react";
|
|
3
|
+
import { type Box, type Edge, type Layout, type Pane } from "./layout.js";
|
|
4
|
+
import type { TabDrag } from "./tabs.js";
|
|
5
|
+
export declare const position: (box: Box) => CSSProperties;
|
|
6
|
+
export type Docking = {
|
|
7
|
+
move: (drag: TabDrag) => boolean;
|
|
8
|
+
drop: () => boolean;
|
|
9
|
+
cancel: () => void;
|
|
10
|
+
split: (key: string, edge: Edge) => boolean;
|
|
11
|
+
next: (key: string) => void;
|
|
12
|
+
paneCount: number;
|
|
13
|
+
insertion?: number;
|
|
14
|
+
};
|
|
15
|
+
export declare function WorkspaceSurface({ layout, change, header, content, menu, }: {
|
|
16
|
+
layout: Layout;
|
|
17
|
+
change: (layout: Layout) => void;
|
|
18
|
+
menu?: WorkspaceMenu;
|
|
19
|
+
header: (pane: Pane, first: boolean, last: boolean, docking: Docking, surface: (key?: string) => HTMLElement | null) => ReactNode;
|
|
20
|
+
content: (panes: {
|
|
21
|
+
pane: Pane;
|
|
22
|
+
box: Box;
|
|
23
|
+
}[], transition: boolean, lifted?: string) => ReactNode;
|
|
24
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { type WorkspaceMenu } from "./context.js";
|
|
2
|
+
import * as React from "react";
|
|
3
|
+
import type { Docking } from "./surface.js";
|
|
4
|
+
import type { WorkspaceTab } from "./workspace.js";
|
|
5
|
+
export type TabDrag = {
|
|
6
|
+
key: string;
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
detached: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type WorkspaceTabsProps = {
|
|
12
|
+
items: readonly WorkspaceTab[];
|
|
13
|
+
active: string;
|
|
14
|
+
onClose: (key: string) => void;
|
|
15
|
+
onDuplicate?: (key: string) => string;
|
|
16
|
+
onReorder: (keys: string[]) => void;
|
|
17
|
+
onSelect: (key: string) => void;
|
|
18
|
+
dragBoundary: HTMLElement | null;
|
|
19
|
+
surface: (key?: string) => HTMLElement | null;
|
|
20
|
+
docking: Docking;
|
|
21
|
+
menu?: WorkspaceMenu;
|
|
22
|
+
};
|
|
23
|
+
export declare function WorkspaceTabs({ items, active, onClose, onDuplicate, onReorder, onSelect, dragBoundary, surface, docking, menu, }: WorkspaceTabsProps): React.JSX.Element;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type WorkspaceTabsProps } from "./tabs.js";
|
|
3
|
+
export declare function WorkspaceToolbar({ active, leading, reserve, end, onActivate, ...tabProps }: Omit<WorkspaceTabsProps, "active" | "dragBoundary"> & {
|
|
4
|
+
leading?: ReactNode;
|
|
5
|
+
reserve?: number;
|
|
6
|
+
end?: ReactNode;
|
|
7
|
+
active?: string;
|
|
8
|
+
onActivate: () => void;
|
|
9
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type WindowEdge = "n" | "s" | "e" | "w" | "ne" | "nw" | "se" | "sw";
|
|
2
|
+
export type WindowHost = {
|
|
3
|
+
platform: "windows" | "macos" | "linux";
|
|
4
|
+
minimize: () => void;
|
|
5
|
+
toggleMaximize: () => void;
|
|
6
|
+
close: () => void;
|
|
7
|
+
drag?: () => void;
|
|
8
|
+
resize?: (edge: WindowEdge) => void;
|
|
9
|
+
fullscreen?: (on: boolean) => void;
|
|
10
|
+
};
|
|
11
|
+
export declare function useFullscreen(host?: WindowHost): readonly [boolean, (on: boolean) => void];
|
|
12
|
+
export declare function useWindowFrame(host?: WindowHost): void;
|
|
13
|
+
export declare function WindowControls({ host }: {
|
|
14
|
+
host: WindowHost;
|
|
15
|
+
}): import("react").JSX.Element | null;
|