@dashfoo/react 0.4.0 → 0.5.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 CHANGED
@@ -76,6 +76,7 @@ a sized parent and add your CSS (see the [attribute reference](#data-dashfoo-att
76
76
  | `closableTabs` | `boolean` | `true` | Show the per-tab close control. |
77
77
  | `renamableTabs` | `boolean` | `true` | Allow double-click inline rename. |
78
78
  | `maximizable` | `boolean` | `true` | Show the tabset maximize/restore control. |
79
+ | `floatable` | `boolean` | `false` | Show a per-tabset control that floats the panel into a movable, resizable overlay, and render any floating panels. See below. |
79
80
  | `draggableTabs` | `boolean` | `true` | Allow individual tabs to be dragged between tabsets. |
80
81
  | `draggableTabsets` | `boolean` | `true` | Show the grip that drags a whole tabset. |
81
82
  | `resizableSplits` | `boolean` | `true` | Allow dragging the splitters; `false` disables them in place (gutters keep their size). |
@@ -86,9 +87,10 @@ a sized parent and add your CSS (see the [attribute reference](#data-dashfoo-att
86
87
  You must pass either `model` or `defaultModel`. Passing neither throws.
87
88
 
88
89
  A `ref` exposes a `DashfooHandle` for imperative control:
89
- `addTab`, `closeTab`, `selectTab`, `renameTab`, `maximizeTabset`, `dispatch`,
90
- `getModel`, `undo` / `redo` / `canUndo` / `canRedo`, and `resetLayout()` (reset to
91
- the original `defaultModel`, clearing undo history and any persisted copy).
90
+ `addTab`, `closeTab`, `selectTab`, `renameTab`, `maximizeTabset`, `floatTab`,
91
+ `dockFloat`, `dispatch`, `getModel`, `undo` / `redo` / `canUndo` / `canRedo`,
92
+ and `resetLayout()` (reset to the original `defaultModel`, clearing undo history and
93
+ any persisted copy).
92
94
 
93
95
  ```tsx
94
96
  const ref = useRef<DashfooHandle>(null);
@@ -175,6 +177,7 @@ with the right role and ARIA wiring, ready for you to style.
175
177
  - **Close** — a `[data-dashfoo="tab-close"]` button next to each tab label, shown when closing is enabled. Dispatches `deleteTab`.
176
178
  - **Rename** — double-click a tab to swap its label for a `[data-dashfoo="tab-rename"]` input. Enter commits, Escape cancels, blur commits. A trimmed, changed value dispatches `renameTab`; focus returns to the tab afterward.
177
179
  - **Maximize** — a `[data-dashfoo="tabset-maximize"]` toggle in the tabset toolbar. Dispatches `setMaximizedTabset`; one maximized tabset fills the frame and `aria-pressed` reflects state.
180
+ - **Float** — a `[data-dashfoo="tabset-float"]` button in the tabset toolbar, shown when `floatable`. Floats the tabset into a movable, resizable overlay (`floatTabset`); the float's `[data-dashfoo="float-dock"]` control docks it back (`dockFloat`). See "Floating panels" below.
178
181
  - **Tabs** — roving-tabindex keyboard model (WAI-ARIA APG): Arrow keys move and select, Home/End jump to the ends, focus follows selection.
179
182
  - **Drag-to-dock** — drag a tab to restack it or split a tabset (when split-dock is on). A `[data-dashfoo="dock-indicator"]` previews where it lands.
180
183
 
@@ -277,6 +280,52 @@ Hand-built layouts (the `Layout.*` primitives) get the same behavior with
277
280
  `useContainerWidth` + `stackModel`; for _distinct_ per-breakpoint models, use
278
281
  `useResponsiveModel`. Both feed reactive props with no `key`/remount.
279
282
 
283
+ ## Floating panels
284
+
285
+ Pass `floatable` to let a panel float out into a movable, resizable overlay,
286
+ FlexLayout style:
287
+
288
+ ```tsx
289
+ <DashfooLayout defaultModel={model} factory={renderPanel} floatable />
290
+ ```
291
+
292
+ Each tabset toolbar gains a `[data-dashfoo="tabset-float"]` control that floats the
293
+ whole tabset into an overlay (dispatching `floatTabset`). Drag its
294
+ `[data-dashfoo="float-titlebar"]` to move it anywhere on the page, the edge/corner
295
+ handles to resize, the `[data-dashfoo="float-minimize"]` control to collapse it to a
296
+ chip, and the `[data-dashfoo="float-dock"]` "Dock back" control to return it
297
+ (`dockFloat`). Floating panels are first-class model nodes (`Dashfoo.floats` in
298
+ `@dashfoo/core`), so they serialize and round-trip like docked panels.
299
+
300
+ How it works:
301
+
302
+ - **Same React tree, full drag-dock.** A float renders through the normal
303
+ `Layout.Rows` in the same tree, sharing one drag manager with the docked layout —
304
+ so app context (a theme provider, a query client), event handling, your
305
+ stylesheet, and **dragging tabs into and out of a float** all just work. The
306
+ overlay is `pointer-events: none`, so empty space stays click-through to the
307
+ docked layout underneath.
308
+ - **Drag anywhere + resize commit one step.** The overlay is viewport-fixed, so a
309
+ float drags across the whole page. Drag and resize update the DOM imperatively and
310
+ dispatch a single `moveFloat` on release, so a drag is one undo step.
311
+ - **Named, renamable title.** Each float carries its own name ("Panel", "Panel 1",
312
+ …), shown as the window title — never the active tab's. Double-click the title to
313
+ rename it (`renameFloat`).
314
+ - **Minimize.** The minimize control collapses a float to a chip
315
+ (`setFloatMinimized`); tapping the chip restores it to its saved rect.
316
+ - **Dock back as a panel.** "Dock back" returns the float as its own panel — all its
317
+ tabs, grouped — instead of flattening them into another tabset.
318
+ - **Bring to front.** Clicking anywhere in a float — body, a tab, or chrome —
319
+ raises it above the others.
320
+ - **Honors `editable`.** Under `editable={false}` a float is static: its content
321
+ stays selectable and it still raises to the front, but move, resize, rename,
322
+ minimize, and dock-back are switched off (no `moveFloat` / `renameFloat` /
323
+ `setFloatMinimized` / `dockFloat`).
324
+
325
+ Hand-built layouts opt in by wrapping the tree's content with `Layout.FloatLayer`
326
+ (passing `floats` + `global`) and adding `Tabset.FloatButton`. `Tabset.FloatButton`
327
+ hides itself (and warns) if no `Layout.FloatLayer` is present.
328
+
280
329
  ## Persistence
281
330
 
282
331
  The `persist` prop saves an uncontrolled layout and restores it on load. It loads
@@ -370,14 +419,27 @@ you.
370
419
  | `tab` | `button` | `role="tab"`. Carries `aria-selected` and `data-tab-id`. |
371
420
  | `tab-close` | `button` | Per-tab close. `aria-label="Close <name>"`. |
372
421
  | `tab-rename` | `input` | Inline rename editor, shown during a rename. |
373
- | `tabset-toolbar` | `div` | Trailing controls in the strip: overflow menu, grip, custom toolbar slot, maximize. |
422
+ | `tabset-toolbar` | `div` | Trailing controls in the strip: overflow menu, grip, custom toolbar slot, pop-out, maximize. |
374
423
  | `tab-overflow-root` | `div` | Wraps the overflow trigger and its menu; rendered when tabs don't fit the strip. |
375
424
  | `tab-overflow` | `button` | Overflow menu trigger. `aria-label="More tabs"`. |
376
425
  | `tab-overflow-menu` | `div` | `role="menu"`, lists the hidden tabs while open. |
377
426
  | `tab-overflow-item` | `button` | `role="menuitem"`, one hidden tab; selecting it activates the tab. |
378
427
  | `tabset-grip` | `button` | Drags the whole tabset. `aria-label="Move tabset"`; shown when `draggableTabsets` is on and the tabset is not maximized. |
428
+ | `tabset-float` | `button` | Floats the tabset into a movable overlay. `aria-label="Float panel"`; shown when `floatable` is on and not maximized. |
379
429
  | `tabset-maximize` | `button` | Maximize/restore toggle. `aria-pressed` reflects state. |
380
430
  | `tabcontent` | `div` | `role="tabpanel"`, the active tab's content (or empty when none). |
431
+ | `float-overlay` | `div` | The `pointer-events: none` overlay covering the layout; holds the floats. |
432
+ | `float` | `div` | A floating panel's elevated frame. `display: flex; flex-direction: column`, positioned absolutely. |
433
+ | `float-titlebar` | `div` | The float's drag handle / title bar (grip + title + dock control). |
434
+ | `float-grip` | `span` | Drag-affordance dots in the title bar (decorative, `aria-hidden`). |
435
+ | `float-title` | `span` | The float's window title (its own name); double-click to rename. `aria-hidden` grip precedes it. |
436
+ | `float-rename` | `input` | The inline title editor, shown while renaming. `aria-label="Rename <name>"`. |
437
+ | `float-minimize` | `button` | Collapses the float to a chip. `aria-label="Minimize panel"`. |
438
+ | `float-dock` | `button` | Docks the panel back into the main layout. `aria-label="Dock panel back into the main layout"`. |
439
+ | `float-body` | `div` | The float's content area; holds the panel's layout. |
440
+ | `float-resize` | `div` | An edge/corner resize handle (eight in total); `data-edge` is the direction. |
441
+ | `float-chip` | `button` | A minimized float: a rounded chip you click (or drag) to restore. |
442
+ | `float-chip-label` | `span` | The chip's panel title. |
381
443
  | `dock-indicator` | `div` | The drag preview overlay (insertion line or zone pane). `pointer-events: none`. |
382
444
  | `drag-preview` | `div` | The chip that follows the pointer during a drag, showing the dragged label. |
383
445
  | `separator` | rrp `Separator` | rrp emits `data-separator` with `aria-orientation`; style splitters here. |
@@ -454,24 +516,26 @@ and overlays outside the layout observe the same drag).
454
516
  same parts yourself when you need custom chrome. Two compound namespaces, same
455
517
  pattern as `Panel`:
456
518
 
457
- | Part | Element | Role |
458
- | ----------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
459
- | `Layout.Root` | `div[data-dashfoo="layout"]` | Creates the layout store. Takes `model`, `dispatch`, `renderTab`, and the chrome flags `DashfooLayout` accepts. |
460
- | `Layout.DragLayer` | none (overlays) | Opts the tree into drag-dock. Omit it and everything else still works, just without dragging. |
461
- | `Layout.Rows` | rrp split tree | Renders a `RowNode` recursively. `renderTabset` swaps in a custom tabset composition at every leaf. |
462
- | `Layout.Tabset` | — | The stock tabset composition, for leaves that don't need custom chrome. |
463
- | `Tabset.Root` | `div[data-dashfoo="tabset"]` | Creates the per-tabset store; owns drop registration, overflow measurement, and focus restore after close. |
464
- | `Tabset.TabStrip` | `div[data-dashfoo="tabstrip"]` | The strip row (drag hit-testing targets this attribute). |
465
- | `Tabset.Tablist` | `div[data-dashfoo="tablist"]` | `role="tablist"` + roving-tabindex arrow/Home/End navigation. |
466
- | `Tabset.Tab` | `span[data-dashfoo="tab-item"]` | Per-tab wrapper; provides identity to the parts inside. |
467
- | `Tabset.Trigger` | `button[data-dashfoo="tab"]` | The tab button: select on click, rename on double-click, draggable. Children override the label. |
468
- | `Tabset.RenameInput` | `input[data-dashfoo="tab-rename"]` | Inline rename editor; renders only while its tab is being renamed. |
469
- | `Tabset.CloseButton` | `button[data-dashfoo="tab-close"]` | Closes the tab with focus restore; hides when the tab isn't closable. |
470
- | `Tabset.Content` | `div[data-dashfoo="tabcontent"]` | The `role="tabpanel"` pane(s); honors `keepMounted`. Children render-prop overrides `renderTab`. |
471
- | `Tabset.Toolbar` | `div[data-dashfoo="tabset-toolbar"]` | Trailing toolbar container. |
472
- | `Tabset.OverflowMenu` | menu button | Lists clipped tabs; hides when nothing overflows. |
473
- | `Tabset.Grip` | `button[data-dashfoo="tabset-grip"]` | Drag handle for the whole tabset; hides when tabset dragging is off. |
474
- | `Tabset.MaximizeButton` | `button[data-dashfoo="tabset-maximize"]` | Maximize/restore toggle; hides when maximize is off. |
519
+ | Part | Element | Role |
520
+ | ----------------------- | ---------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
521
+ | `Layout.Root` | `div[data-dashfoo="layout"]` | Creates the layout store. Takes `model`, `dispatch`, `renderTab`, and the chrome flags `DashfooLayout` accepts. |
522
+ | `Layout.DragLayer` | none (overlays) | Opts the tree into drag-dock. Omit it and everything else still works, just without dragging. |
523
+ | `Layout.Rows` | rrp split tree | Renders a `RowNode` recursively. `renderTabset` swaps in a custom tabset composition at every leaf. |
524
+ | `Layout.Tabset` | — | The stock tabset composition, for leaves that don't need custom chrome. |
525
+ | `Layout.FloatLayer` | overlay | Wrap the tree's content to enable floating panels; renders `model.floats` as draggable overlays. Takes `floats` + `global`. |
526
+ | `Tabset.Root` | `div[data-dashfoo="tabset"]` | Creates the per-tabset store; owns drop registration, overflow measurement, and focus restore after close. |
527
+ | `Tabset.TabStrip` | `div[data-dashfoo="tabstrip"]` | The strip row (drag hit-testing targets this attribute). |
528
+ | `Tabset.Tablist` | `div[data-dashfoo="tablist"]` | `role="tablist"` + roving-tabindex arrow/Home/End navigation. |
529
+ | `Tabset.Tab` | `span[data-dashfoo="tab-item"]` | Per-tab wrapper; provides identity to the parts inside. |
530
+ | `Tabset.Trigger` | `button[data-dashfoo="tab"]` | The tab button: select on click, rename on double-click, draggable. Children override the label. |
531
+ | `Tabset.RenameInput` | `input[data-dashfoo="tab-rename"]` | Inline rename editor; renders only while its tab is being renamed. |
532
+ | `Tabset.CloseButton` | `button[data-dashfoo="tab-close"]` | Closes the tab with focus restore; hides when the tab isn't closable. |
533
+ | `Tabset.Content` | `div[data-dashfoo="tabcontent"]` | The `role="tabpanel"` pane(s); honors `keepMounted`. Children render-prop overrides `renderTab`. |
534
+ | `Tabset.Toolbar` | `div[data-dashfoo="tabset-toolbar"]` | Trailing toolbar container. |
535
+ | `Tabset.OverflowMenu` | menu button | Lists clipped tabs; hides when nothing overflows. |
536
+ | `Tabset.Grip` | `button[data-dashfoo="tabset-grip"]` | Drag handle for the whole tabset; hides when tabset dragging is off. |
537
+ | `Tabset.MaximizeButton` | `button[data-dashfoo="tabset-maximize"]` | Maximize/restore toggle; hides when maximize is off. |
538
+ | `Tabset.FloatButton` | `button[data-dashfoo="tabset-float"]` | Floats the tabset into a movable overlay; hides when `floatable` is off or the tabset is maximized. |
475
539
 
476
540
  All parts spread native props (`className`, `style`, handlers) like `Panel`;
477
541
  the structural attributes (`role`, ids, `data-dashfoo`) are applied after the
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Action, Dashfoo, DockLocation, DragSubject, DropIntent, Orientation, RowNode, SnapConfig, TabNode, TabsetNode } from "@dashfoo/core";
1
+ import { Action, Dashfoo, DockLocation, DragSubject, DropIntent, FloatNode, GlobalAttributes, Orientation, RowNode, SnapConfig, TabNode, TabsetNode } from "@dashfoo/core";
2
2
  import { ComponentProps, ComponentType, ReactNode, Ref } from "react";
3
3
  import { DragDropManager } from "@dnd-kit/dom";
4
4
  //#region src/hooks/persistence.d.ts
@@ -40,6 +40,8 @@ type DashfooHandle = {
40
40
  canUndo: () => boolean;
41
41
  closeTab: (tabId: string) => void;
42
42
  dispatch: (action: Action) => void;
43
+ dockFloat: (floatId: string) => void;
44
+ floatTab: (tabId: string) => void;
43
45
  getModel: () => Dashfoo;
44
46
  maximizeTabset: (tabsetId: string | null) => void;
45
47
  redo: () => void;
@@ -56,6 +58,7 @@ type DashfooLayoutProps = {
56
58
  draggableTabsets?: boolean;
57
59
  editable?: boolean;
58
60
  factory?: (tab: TabNode) => ReactNode;
61
+ floatable?: boolean;
59
62
  keepMounted?: boolean;
60
63
  maximizable?: boolean;
61
64
  model?: Dashfoo;
@@ -106,6 +109,13 @@ type DragProviderProps = {
106
109
  splitDock?: boolean;
107
110
  };
108
111
  //#endregion
112
+ //#region src/components/float-layer.d.ts
113
+ type FloatLayerProps = {
114
+ children: ReactNode;
115
+ floats: Array<FloatNode>;
116
+ global: GlobalAttributes;
117
+ };
118
+ //#endregion
109
119
  //#region src/components/layout-root.d.ts
110
120
  type LayoutRootProps = Omit<ComponentProps<"div">, "children"> & {
111
121
  children: ReactNode;
@@ -114,6 +124,7 @@ type LayoutRootProps = Omit<ComponentProps<"div">, "children"> & {
114
124
  draggableTabs?: boolean;
115
125
  draggableTabsets?: boolean;
116
126
  editable?: boolean;
127
+ floatable?: boolean;
117
128
  keepMounted?: boolean;
118
129
  maximizable?: boolean;
119
130
  model: Dashfoo;
@@ -144,6 +155,11 @@ declare const Layout: {
144
155
  onCommit,
145
156
  splitDock
146
157
  }: DragProviderProps) => import("react").ReactNode;
158
+ readonly FloatLayer: ({
159
+ children,
160
+ floats,
161
+ global
162
+ }: FloatLayerProps) => import("react").ReactNode;
147
163
  readonly Root: ({
148
164
  children,
149
165
  closableTabs,
@@ -151,6 +167,7 @@ declare const Layout: {
151
167
  draggableTabs,
152
168
  draggableTabsets,
153
169
  editable,
170
+ floatable,
154
171
  keepMounted,
155
172
  maximizable,
156
173
  model,
@@ -202,6 +219,7 @@ type TabsetContentProps = Omit<ComponentProps<"div">, "children"> & {
202
219
  type TabsetToolbarProps = ComponentProps<"div">;
203
220
  type TabsetGripProps = ComponentProps<"button">;
204
221
  type TabsetMaximizeButtonProps = ComponentProps<"button">;
222
+ type TabsetFloatButtonProps = ComponentProps<"button">;
205
223
  //#endregion
206
224
  //#region src/components/tabset/tabset-root.d.ts
207
225
  type TabsetRootProps = ComponentProps<"div"> & {
@@ -230,6 +248,11 @@ declare const Tabset: {
230
248
  style,
231
249
  ...props
232
250
  }: TabsetContentProps) => import("react").ReactNode;
251
+ readonly FloatButton: ({
252
+ children,
253
+ onClick,
254
+ ...props
255
+ }: TabsetFloatButtonProps) => import("react").ReactNode;
233
256
  readonly Grip: ({
234
257
  children,
235
258
  ref: userRef,
@@ -326,6 +349,7 @@ type LayoutState = {
326
349
  draggableTabs: boolean;
327
350
  draggableTabsets: boolean;
328
351
  editable: boolean;
352
+ floatable: boolean;
329
353
  keepMounted: boolean;
330
354
  maximizable: boolean;
331
355
  maximizedTabsetId: string | undefined;
@@ -392,5 +416,5 @@ type UseDashfooStoreOptions = {
392
416
  };
393
417
  declare const useDashfooStore: (options: UseDashfooStoreOptions) => DashfooStore;
394
418
  //#endregion
395
- export { type Breakpoint, DashfooDragProvider, type DashfooHandle, DashfooLayout, type DashfooLayoutProps, type DashfooStore, type ExternalTabSourceOptions, Layout, type DragProviderProps as LayoutDragLayerProps, type LayoutRootProps, type RowViewProps as LayoutRowsProps, type LayoutState, type TabsetViewProps as LayoutTabsetProps, Panel, type PanelBadgeProps, type PanelBodyProps, type PanelHeaderProps, type PanelIconProps, type PanelRootProps, type PanelTitleProps, type PersistConfig, type Persistence, type ResponsiveModel, type StorageAdapter, type TabComponent, type TabContextValue, Tabset, type TabsetCloseButtonProps, type TabsetContentProps, type TabsetGripProps, type TabsetMaximizeButtonProps, type TabsetRenameInputProps, type TabsetRootProps, type TabsetState, type TabsetTabProps, type TabsetTabStripProps, type TabsetTablistProps, type TabsetToolbarProps, type TabsetTriggerProps, type UseDashfooStoreOptions, type UseResponsiveModelOptions, activeBreakpoint, localStorageAdapter, matchBreakpoint, memoryStorageAdapter, useContainerWidth, useDashfooStore, useDragSubject, useDropIntent, useExternalTabSource, useLayout, usePersistence, useResponsiveModel, useTab, useTabset };
419
+ export { type Breakpoint, DashfooDragProvider, type DashfooHandle, DashfooLayout, type DashfooLayoutProps, type DashfooStore, type ExternalTabSourceOptions, Layout, type DragProviderProps as LayoutDragLayerProps, type FloatLayerProps as LayoutFloatLayerProps, type LayoutRootProps, type RowViewProps as LayoutRowsProps, type LayoutState, type TabsetViewProps as LayoutTabsetProps, Panel, type PanelBadgeProps, type PanelBodyProps, type PanelHeaderProps, type PanelIconProps, type PanelRootProps, type PanelTitleProps, type PersistConfig, type Persistence, type ResponsiveModel, type StorageAdapter, type TabComponent, type TabContextValue, Tabset, type TabsetCloseButtonProps, type TabsetContentProps, type TabsetFloatButtonProps, type TabsetGripProps, type TabsetMaximizeButtonProps, type TabsetRenameInputProps, type TabsetRootProps, type TabsetState, type TabsetTabProps, type TabsetTabStripProps, type TabsetTablistProps, type TabsetToolbarProps, type TabsetTriggerProps, type UseDashfooStoreOptions, type UseResponsiveModelOptions, activeBreakpoint, localStorageAdapter, matchBreakpoint, memoryStorageAdapter, useContainerWidth, useDashfooStore, useDragSubject, useDropIntent, useExternalTabSource, useLayout, usePersistence, useResponsiveModel, useTab, useTabset };
396
420
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/hooks/persistence.ts","../src/components/dashfoo-layout.tsx","../src/components/drag-root.tsx","../src/hooks/drag-hooks.tsx","../src/components/drag-adapter.tsx","../src/components/layout-root.tsx","../src/components/row-view.tsx","../src/components/tabset/tabset-view.tsx","../src/components/layout.tsx","../src/components/panel.tsx","../src/components/tabset/tabset-tab-controls.tsx","../src/components/tabset/tabset-content.tsx","../src/components/tabset/tabset-toolbar.tsx","../src/components/tabset/tabset-root.tsx","../src/components/tabset/tabset-tab.tsx","../src/components/tabset/tabset-tablist.tsx","../src/components/tabset/tabset.ts","../src/components/tab-overflow.tsx","../src/components/tabset/tabset-store.ts","../src/hooks/layout-store.ts","../src/hooks/responsive.ts","../src/hooks/store.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/hooks/persistence.ts","../src/components/dashfoo-layout.tsx","../src/components/drag-root.tsx","../src/hooks/drag-hooks.tsx","../src/components/drag-adapter.tsx","../src/components/float-layer.tsx","../src/components/layout-root.tsx","../src/components/row-view.tsx","../src/components/tabset/tabset-view.tsx","../src/components/layout.tsx","../src/components/panel.tsx","../src/components/tabset/tabset-tab-controls.tsx","../src/components/tabset/tabset-content.tsx","../src/components/tabset/tabset-toolbar.tsx","../src/components/tabset/tabset-root.tsx","../src/components/tabset/tabset-tab.tsx","../src/components/tabset/tabset-tablist.tsx","../src/components/tabset/tabset.ts","../src/components/tab-overflow.tsx","../src/components/tabset/tabset-store.ts","../src/hooks/layout-store.ts","../src/hooks/responsive.ts","../src/hooks/store.ts"],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
- "use client";import{canRedo as e,canUndo as t,dashfooMachine as n,dragDockMachine as r,findTabset as i,fromJSON as a,normalize as o,reducer as s,resolveDockTarget as c,snapEnabled as l,snapSizes as u,stackModel as d,tabNodeSchema as f,toJSON as p,zoneRect as m}from"@dashfoo/core";import{Fragment as h,createContext as g,createElement as _,forwardRef as v,useCallback as y,useContext as b,useEffect as x,useId as S,useImperativeHandle as C,useInsertionEffect as w,useLayoutEffect as T,useMemo as E,useRef as D,useState as O}from"react";import{useActorRef as k,useSelector as A}from"@xstate/react";import{Accessibility as j,DragDropManager as ee,Draggable as te,Feedback as ne,PointerSensor as M}from"@dnd-kit/dom";import{createStore as N,useStore as P}from"zustand";import{Fragment as F,jsx as I,jsxs as L}from"react/jsx-runtime";import{Group as re,Panel as ie,Separator as ae}from"react-resizable-panels";const oe=()=>{let e=new Map;return{getItem:t=>e.get(t)??null,removeItem:t=>{e.delete(t)},setItem:(t,n)=>{e.set(t,n)}}},R={getItem:e=>{if(typeof window>`u`)return null;try{return window.localStorage.getItem(e)}catch{return null}},removeItem:e=>{if(!(typeof window>`u`))try{window.localStorage.removeItem(e)}catch{}},setItem:(e,t)=>{if(!(typeof window>`u`))try{window.localStorage.setItem(e,t)}catch(e){console.warn(`[dashfoo] failed to persist layout`,e)}}},se=(e,t)=>{let n=D(e);x(()=>{n.current=e});let[r]=O(()=>{if(e===null||t===void 0)return t;let n=e.storage.getItem(e.key);if(n===null)return t;try{return a(n)}catch{return t}});x(()=>{let e=n.current;if(e===null)return;let t=e.storage.getItem(e.key);if(t!==null)try{a(t)}catch(t){console.warn(`[dashfoo] discarding unreadable persisted layout`,t),e.storage.removeItem(e.key)}},[]);let i=D(e?.key);x(()=>{e!==null&&e.key!==i.current&&(console.warn(`[dashfoo] persist key changed for a mounted layout; the displayed layout still reflects the previous key — remount (key={persistKey}) to load the new key`),i.current=e.key)},[e]);let o=D(null),s=D(null),c=y(()=>{o.current!==null&&(clearTimeout(o.current),o.current=null),s.current!==null&&(s.current.storage.setItem(s.current.key,s.current.value),s.current=null)},[]),l=y(e=>{let t=n.current;t!==null&&(s.current={key:t.key,storage:t.storage,value:p(e)},o.current!==null&&clearTimeout(o.current),o.current=setTimeout(c,t.debounceMs))},[c]);x(()=>{let e=()=>{c()},t=()=>{document.visibilityState===`hidden`&&c()};return window.addEventListener(`pagehide`,e),document.addEventListener(`visibilitychange`,t),()=>{window.removeEventListener(`pagehide`,e),document.removeEventListener(`visibilitychange`,t),c()}},[c]);let u=y(()=>{o.current!==null&&(clearTimeout(o.current),o.current=null),s.current=null;let e=n.current;e!==null&&e.storage.removeItem(e.key)},[]);return E(()=>({clear:u,initialModel:r,save:l}),[u,r,l])},ce=()=>typeof window<`u`&&typeof window.matchMedia==`function`,le=(e,t)=>{let{query:n}=e;return n?`maxWidth`in n?t<=n.maxWidth:ce()&&window.matchMedia(n.media).matches:!0},ue=(e,t)=>{let n=e.at(-1);if(!n)throw Error(`useResponsiveModel requires at least one breakpoint.`);return e.find(e=>le(e,t))??n},z=()=>{let[e,t]=O(1/0),n=D(null),r=y(e=>{if(n.current?.disconnect(),!e)return;let r=new ResizeObserver(e=>{let n=e[0];n&&t(n.contentRect.width)});r.observe(e),n.current=r},[]);return x(()=>()=>{n.current?.disconnect()},[]),[r,e]},de=({breakpoints:e})=>{let[t,n]=z(),[,r]=O(0);x(()=>{if(!ce())return;let t=e.flatMap(e=>e.query&&`media`in e.query?[window.matchMedia(e.query.media)]:[]);if(t.length===0)return;let n=()=>{r(e=>e+1)};for(let e of t)e.addEventListener(`change`,n);return()=>{for(let e of t)e.removeEventListener(`change`,n)}},[e]);let i=ue(e,n),a=i.compact===!0;return{breakpoint:i.id,containerRef:t,draggableTabs:!a,draggableTabsets:!a,isCompact:a,model:i.model,resizableSplits:!a}},fe=r=>{let{defaultModel:i,model:a,onAction:c,onActiveTabsetChange:l,onMaximizedTabsetChange:u,onModelChange:d}=r,f=a??i;if(f===void 0)throw Error("useDashfooStore requires either a `model` or a `defaultModel`.");let p=k(n,{input:{model:o(f)}}),m=A(p,e=>e.context.history);x(()=>{a!==void 0&&p.send({model:o(a),type:`SET_MODEL`})},[p,a]);let h=a??m.present,g=y((e,t,n)=>{Object.is(e,t)||(d?.(t,n),t.activeTabsetId!==e.activeTabsetId&&l?.(t.activeTabsetId),t.maximizedTabsetId!==e.maximizedTabsetId&&u?.(t.maximizedTabsetId))},[d,l,u]),_=y(e=>{let t=c?c(e):e;if(!t)return;let n=(()=>{if(a===void 0){let e=p.getSnapshot().context.history.present;return p.send({action:t,type:`DISPATCH`}),{after:p.getSnapshot().context.history.present,before:e}}return{after:s(a,t),before:o(a)}})();g(n.before,n.after,t)},[p,a,g,c]),v=y(()=>{if(a!==void 0)return;let e=p.getSnapshot().context.history.present;p.send({type:`UNDO`});let t=p.getSnapshot().context.history.present;g(e,t)},[p,a,g]),b=y(()=>{if(a!==void 0)return;let e=p.getSnapshot().context.history.present;p.send({type:`REDO`});let t=p.getSnapshot().context.history.present;g(e,t)},[p,a,g]),S=y(e=>{p.send({model:o(e),type:`SET_MODEL`})},[p]);return E(()=>({canRedo:()=>e(p.getSnapshot().context.history),canUndo:()=>t(p.getSnapshot().context.history),dispatch:_,model:h,redo:b,setModel:S,undo:v}),[p,_,h,b,S,v])},pe=(e,t)=>{let{target:n}=e;if(!(n instanceof Element))return!1;let r=n.closest(`
1
+ "use client";import{canRedo as e,canUndo as t,dashfooMachine as n,dragDockMachine as r,findTabset as i,fromJSON as a,normalize as o,reducer as s,resolveDockTarget as c,snapEnabled as l,snapSizes as u,stackModel as d,tabNodeSchema as f,toJSON as p,zoneRect as m}from"@dashfoo/core";import{Fragment as h,createContext as g,forwardRef as _,useCallback as v,useContext as y,useEffect as b,useId as x,useImperativeHandle as S,useInsertionEffect as C,useLayoutEffect as w,useMemo as T,useRef as E,useState as D}from"react";import{Accessibility as O,DragDropManager as k,Draggable as A,Feedback as j,PointerSensor as ee}from"@dnd-kit/dom";import{createStore as M,useStore as N}from"zustand";import{useActorRef as te,useSelector as P}from"@xstate/react";import{Fragment as F,jsx as I,jsxs as L}from"react/jsx-runtime";import{Group as R,Panel as z,Separator as ne}from"react-resizable-panels";const B=(e,t)=>{let{target:n}=e;if(!(n instanceof Element))return!1;let r=n.closest(`
2
2
  input:not([disabled]),
3
3
  select:not([disabled]),
4
4
  textarea:not([disabled]),
5
5
  button:not([disabled]),
6
6
  a[href],
7
7
  [contenteditable]:not([contenteditable="false"])
8
- `);return r!==null&&r!==t.element},me=()=>new ee({plugins:e=>e.filter(e=>e!==j&&e!==ne),sensors:()=>[M.configure({preventActivation:pe})]}),B=g(null),V=g(null),H=()=>N(()=>({intent:null,intentOwner:null,subject:null})),he=(e,t)=>e===t||e!==null&&t!==null&&e.index===t.index&&e.location===t.location&&e.targetId===t.targetId,ge=(e,t)=>e===t||e!==null&&t!==null&&e.id===t.id&&e.kind===t.kind,_e=H(),U=g(null),ve=()=>{let e=D(null),t=D(null);return{draggableRef:t,elementRef:e,ref:y(n=>{e.current=n,t.current&&(t.current.element=n??void 0)},[])}},W=(e,t,n)=>{let r=b(B),i=b(V),a=r?.manager??i,{draggableRef:o,elementRef:s,ref:c}=ve(),{data:l,id:u}=e;return x(()=>{if(!a||t)return;let e=new te({data:{...l,label:``},id:u},a);return e.element=s.current??void 0,o.current=e,()=>{e.destroy(),o.current=null}},[l,t,o,s,u,a]),x(()=>{let e=o.current;e&&(e.data={...l,label:n})},[l,o,n]),{ref:c}},ye=(e,t=!1,n=``)=>W({data:E(()=>({type:`tab`}),[]),id:e},t,n),be=(e,t=!1,n=``)=>W({data:E(()=>({tabsetId:e,type:`tabset`}),[e]),id:`grip-${e}`},t,n),xe=e=>{let t=b(B);return{ref:y(n=>{t?.registerTabset(e,n)},[t,e])}},Se=({createTab:e,disabled:t=!1,label:n=``})=>{let r=S(),i=D(e);return x(()=>{i.current=e}),W({data:E(()=>({createTab:()=>i.current(),type:`external`}),[]),id:`external-${r}`},t,n)},Ce=()=>P(b(U)??_e,e=>e.subject),we=()=>P(b(U)??_e,e=>e.intent),Te=e=>N(()=>e),Ee=g(null),G=e=>{let t=b(Ee);if(t===null)throw Error(`dashfoo components must be rendered inside <DashfooLayout> or <Layout.Root>.`);return P(t,e)},De=(e,t)=>e.x>=t.x&&e.x<=t.x+t.width&&e.y>=t.y&&e.y<=t.y+t.height,Oe=(e,t)=>{let n=e.findIndex(e=>t<e.x+e.width/2);return n===-1?e.length:n},ke=(e,t,n)=>{let r=t[n],i=t.at(-1),a=(r?.x??(i?i.x+i.width:e.x))-4/2;return{height:e.height,width:4,x:Math.max(e.x,Math.min(a,e.x+e.width-4)),y:e.y}},Ae=(e,t,n)=>!(e===`grip-${t}`||n.length===1&&n[0]===e),je=new Set,K=(e,t)=>{je.has(e)||(je.add(e),console.warn(`[dashfoo] ${t}`))},Me={boxSizing:`border-box`,pointerEvents:`none`,position:`fixed`,transition:`var(--dashfoo-dock-transition, left 60ms, top 60ms, width 60ms, height 60ms)`,zIndex:9999},Ne=e=>({...Me,background:`var(--dashfoo-dock-fill, oklch(0.556 0 0 / 0.18))`,border:`var(--dashfoo-dock-border-width, 1px) solid var(--dashfoo-dock-border, oklch(0.708 0 0 / 0.75))`,borderRadius:`var(--dashfoo-dock-radius, 6px)`,height:e.height,left:e.x,top:e.y,width:e.width}),Pe=e=>({...Ne(e),borderRadius:`var(--dashfoo-dock-line-radius, 2px)`}),Fe=(e,t)=>[...e.querySelectorAll(`[data-dashfoo="tab-item"]`)].flatMap(e=>e.querySelector(`[data-dashfoo="tab"]`)?.dataset.tabId===t?[]:[e.getBoundingClientRect()]),Ie=({actorRef:e,getTabsetElement:t})=>{let n=A(e,e=>e.context.intent),r=A(e,e=>e.context.subject?.id);if(!n)return null;let i=t(n.targetId);if(!i)return null;if(n.location===`center`){let e=i.querySelector(`[data-dashfoo="tabstrip"]`);if(e)return I(`div`,{"data-dashfoo":`dock-indicator`,style:Pe(ke(e.getBoundingClientRect(),Fe(e,r),n.index??0))})}return I(`div`,{"data-dashfoo":`dock-indicator`,style:Ne(m(i.getBoundingClientRect(),n.location))})},Le={left:0,position:`fixed`,top:0,zIndex:9999},Re=({overlayRef:e,preview:t})=>t?I(`div`,{"data-dashfoo":`drag-preview`,ref:e,style:{...Le,transform:`translate(${t.x}px, ${t.y}px)`},children:t.label}):null,ze=(e,t)=>[...e.querySelectorAll(`[data-dashfoo="tab"]`)].flatMap(e=>e.dataset.tabId===t?[]:[e.getBoundingClientRect()]),Be=(e,t,n,r)=>{let i=t.querySelector(`[data-dashfoo="tabstrip"]`);if(i&&De(n,i.getBoundingClientRect()))return{index:Oe(ze(i,r),n.x),location:`center`,targetId:e};let a=c(n,t.getBoundingClientRect()),o=a.kind===`tab`?`center`:`split-${a.edge}`;return o===`center`&&i?{index:ze(i,r).length,location:o,targetId:e}:{location:o,targetId:e}},q={x:12,y:8},Ve=e=>{let t=e?.data?.label;return typeof t==`string`?t:``},He=e=>typeof e==`function`,Ue=e=>{let t=e.data;if(t?.type===`tabset`)return{id:String(t.tabsetId),kind:`tabset`};if(t?.type===`external`){if(!He(t.createTab))return console.warn(`[dashfoo] external drag source is missing its createTab function`),null;let n;try{n=t.createTab()}catch(e){return console.warn(`[dashfoo] external drag source createTab threw`,e),null}let r=f.safeParse(n);return r.success?{id:String(e.id),kind:`external`,tab:r.data}:(console.warn(`[dashfoo] external drag source returned an invalid tab`,r.error),null)}return{id:String(e.id),kind:`tab`}},We=({children:e,onCommit:t,splitDock:n})=>{let i=k(r),a=b(Ee),[o]=O(()=>new Map),s=D(null),[c,l]=O(null),u=b(V),[d]=O(()=>u?null:me());w(()=>()=>d?.destroy(),[d]);let f=u??d;if(f===null)throw Error(`[dashfoo] DashfooDragProvider unmounted while its layout is still mounted; keep the provider above the layout or remount the layout`);let p=b(U),[m]=O(()=>p??H()),h=S();x(()=>{let e=i.subscribe(e=>{let{intent:t,subject:n}=e.context,r=m.getState();t===null?r.intent!==null&&r.intentOwner===h&&m.setState({intent:null,intentOwner:null}):(!he(r.intent,t)||r.intentOwner!==h)&&m.setState({intent:t,intentOwner:h}),ge(m.getState().subject,n)||m.setState({subject:n})});return()=>{e.unsubscribe()}},[i,h,m]);let g=D(t),_=D(n);x(()=>{g.current=t,_.current=n}),x(()=>{let e=i.on(`COMMIT`,e=>{if(a?.getState().editable===!1)return;let t=g.current??a?.getState().dispatch;if(!t){K(`drag-layer-no-commit`,`Layout.DragLayer has neither an onCommit prop nor a <Layout.Root> above it; drops are ignored`);return}t(e.action)});return()=>{e.unsubscribe()}},[i,a]);let v=y((e,t)=>{t?o.set(e,t):o.delete(e)},[o]),C=y(e=>o.get(e),[o]),T=y(e=>{s.current=e},[]);x(()=>{let e=e=>{for(let[t,n]of o)if(De(e,n.getBoundingClientRect()))return{element:n,id:t}},t=(e,t,n,r)=>{if(a?.getState().editable===!1||!Ae(r,e,[...t.querySelectorAll(`[data-dashfoo="tab"]`)].map(e=>e.dataset.tabId??``)))return null;let i=Be(e,t,n,r);return!(_.current??a?.getState().splitDock??!0)&&i.location.startsWith(`split-`)?{location:`center`,targetId:e}:i},n=e=>{let t=s.current;t&&(t.style.transform=`translate(${e.x+q.x}px, ${e.y+q.y}px)`)},r=e=>{let t=e.operation.source;if(!t)return;let n=Ue(t);if(!n)return;let r=e.operation.position.current;l({label:Ve(t),x:r.x+q.x,y:r.y+q.y}),i.send({subject:n,type:`START`})},c=r=>{let a=r.operation,o=a.position.current;n(o);let s=a.source?String(a.source.id):void 0,c=e(o);i.send({intent:c?t(c.id,c.element,o,s):null,type:`OVER`})},u=n=>{if(l(null),n.canceled){i.send({type:`CANCEL`});return}let r=n.operation,a=r.position.current,o=r.source?String(r.source.id):void 0,s=e(a);s&&i.send({intent:t(s.id,s.element,a,o),type:`OVER`}),i.send({type:`DROP`})},d=f.monitor.addEventListener(`dragstart`,r),p=f.monitor.addEventListener(`dragmove`,c),m=f.monitor.addEventListener(`dragend`,u);return()=>{d(),p(),m()}},[i,a,f,o]);let A=E(()=>({manager:f,registerTabset:v}),[f,v]);return I(B.Provider,{value:A,children:L(U.Provider,{value:m,children:[e,I(Ie,{actorRef:i,getTabsetElement:C}),I(Re,{overlayRef:T,preview:c})]})})},Ge={display:`flex`,height:`100%`,width:`100%`},Ke=({children:e,closableTabs:t=!0,dispatch:n,draggableTabs:r=!0,draggableTabsets:i=!0,editable:a=!0,keepMounted:o=!1,maximizable:s=!0,model:c,renamableTabs:l=!0,renderTab:u,renderTabLabel:d,renderTabsetToolbar:f,resizableSplits:p=!0,rootRef:m,snap:h,style:g,..._})=>{let v=c.global,y={closableTabs:a&&t&&v.tabEnableClose!==!1,dispatch:n,draggableTabs:a&&r&&v.tabEnableDrag!==!1,draggableTabsets:a&&i,editable:a,keepMounted:o,maximizable:s&&v.tabSetEnableMaximize!==!1,maximizedTabsetId:c.maximizedTabsetId,renamableTabs:a&&l&&v.tabEnableRename!==!1,renderTab:u,renderTabLabel:d,renderTabsetToolbar:f,resizableSplits:a&&p&&v.enableSplitResize!==!1,snap:h??v.snap??null,splitDock:v.enableSplitDock!==!1,tabLocation:v.tabLocation??`top`,tabsetMinSize:v.tabSetMinSize??320,tabStripEnabled:v.tabSetEnableTabStrip!==!1},[b]=O(()=>Te(y));T(()=>{b.setState(y)});let x=v.splitterSize===void 0?{...Ge,...g}:{...Ge,"--dashfoo-splitter-size":`${v.splitterSize}px`,...g};return I(Ee.Provider,{value:b,children:I(`div`,{..._,"data-dashfoo":`layout`,ref:m,style:x,children:e})})},J=(e,t)=>`dashfoo-tab-${e}-${t}`,qe=e=>`dashfoo-panel-${e}`,Je=(e,t,n)=>e?.querySelector(`#${CSS.escape(J(t,n))}`)??null,Ye=e=>N((t,n)=>({...e,cancelRename:()=>t({editingTabId:null}),closeTab:e=>{t({restoreFocus:!0}),n().dispatch({tabId:e,type:`deleteTab`})},commitRename:(e,r)=>{t({editingTabId:null});let{node:i,renameTab:a}=n(),o=r.trim(),s=i.children.find(t=>t.id===e)?.name;o&&o!==s&&a(e,o)},editingTabId:null,overflowItems:[],registerRenameInput:()=>(t(e=>({renameInputCount:e.renameInputCount+1})),()=>t(e=>({renameInputCount:e.renameInputCount-1}))),registerTablist:e=>{if(e){let r=n().tablistElement;r&&r!==e&&K(`duplicate-tablist-${n().node.id}`,`more than one <Tabset.Tablist> under the same <Tabset.Root>; the last one wins for keyboard focus and overflow`),t({tablistElement:e});return}t({tablistElement:null})},renameInputCount:0,renameTab:(e,t)=>n().dispatch({name:t,tabId:e,type:`renameTab`}),restoreFocus:!1,selectOverflowTab:e=>{let{dispatch:t,node:r,tablistElement:i}=n(),a=r.children.findIndex(t=>t.id===e);a!==-1&&(t({index:a,tabsetId:r.id,type:`selectTab`}),Je(i,r.id,e)?.scrollIntoView({block:`nearest`,inline:`nearest`}))},selectTab:(e,t)=>{let{dispatch:r,node:i,tablistElement:a}=n();if(r({index:e,tabsetId:i.id,type:`selectTab`}),t?.focus){let t=i.children[e]?.id;t&&Je(a,i.id,t)?.focus()}},startEditing:e=>{let{node:r,renameInputCount:i,tabsRenamable:a}=n(),o=r.children.find(t=>t.id===e);if(!(!a||o?.enableRename===!1)){if(i===0){K(`missing-rename-input-${r.id}`,`startEditing needs a <Tabset.RenameInput> in the composition; ignoring`);return}t({editingTabId:e})}},tablistElement:null,toggleMaximize:()=>{let{dispatch:e,isMaximized:t,node:r}=n();e({tabsetId:t?null:r.id,type:`setMaximizedTabset`})}})),Xe=g(null),Y=e=>{let t=b(Xe);if(t===null)throw Error(`dashfoo Tabset parts must be rendered inside <Tabset.Root>.`);return P(t,e)},Ze=g(null),X=()=>{let e=b(Ze);if(e===null)throw Error(`dashfoo tab parts must be rendered inside <Tabset.Tab>.`);return e},Qe={flex:1,minHeight:0,overflow:`auto`},$e=({render:e,tab:t})=>{let n=G(e=>e.renderTab);return e?e(t):n(t)},et=({children:e,style:t,...n})=>{let r=Y(e=>e.node),i=Y(e=>e.visualSelected),a=G(e=>e.keepMounted),o={...Qe,...t};if(a&&r.children.length>0)return r.children.map((t,a)=>_(`div`,{...n,"aria-labelledby":J(r.id,t.id),"data-dashfoo":`tabcontent`,hidden:a!==i||void 0,id:a===i?qe(r.id):void 0,key:t.id,role:a===i?`tabpanel`:void 0,style:o,tabIndex:a===i?0:void 0},I($e,{render:e,tab:t})));let s=r.children[i];return s?I(`div`,{...n,"aria-labelledby":J(r.id,s.id),"data-dashfoo":`tabcontent`,id:qe(r.id),role:`tabpanel`,style:o,tabIndex:0,children:I($e,{render:e,tab:s})}):I(`div`,{...n,"data-dashfoo":`tabcontent`,style:o})},tt=()=>L(`svg`,{"aria-hidden":`true`,fill:`currentColor`,height:`10`,viewBox:`0 0 10 10`,width:`10`,children:[I(`circle`,{cx:`2`,cy:`5`,r:`1`}),I(`circle`,{cx:`5`,cy:`5`,r:`1`}),I(`circle`,{cx:`8`,cy:`5`,r:`1`})]}),nt={position:`absolute`,right:0,top:`100%`,zIndex:10},rt=({items:e,onSelect:t})=>{let[n,r]=O(!1),[i,a]=O(0),o=D(null),s=D(null),c=D([]);x(()=>{if(!n)return;let e=e=>{e.target instanceof Node&&!o.current?.contains(e.target)&&r(!1)};return document.addEventListener(`pointerdown`,e),()=>{document.removeEventListener(`pointerdown`,e)}},[n]),x(()=>{n&&c.current[0]?.focus()},[n]);let l=()=>{r(!1),s.current?.focus()},u=e=>{a(e),c.current[e]?.focus()},d=()=>{a(0),r(e=>!e)},f=e=>{t(e),l()};return L(`div`,{"data-dashfoo":`tab-overflow-root`,ref:o,style:{position:`relative`},children:[I(`button`,{"aria-expanded":n,"aria-haspopup":`menu`,"aria-label":`More tabs`,"data-dashfoo":`tab-overflow`,onClick:d,ref:s,type:`button`,children:I(tt,{})}),n?I(`div`,{"data-dashfoo":`tab-overflow-menu`,onBlur:e=>{e.relatedTarget instanceof Node&&o.current?.contains(e.relatedTarget)||r(!1)},onKeyDown:t=>{let n=e.length-1;switch(t.key){case`ArrowDown`:t.preventDefault(),u(i>=n?0:i+1);break;case`ArrowUp`:t.preventDefault(),u(i<=0?n:i-1);break;case`Home`:t.preventDefault(),u(0);break;case`End`:t.preventDefault(),u(n);break;case`Escape`:t.preventDefault(),l();break;default:break}},role:`menu`,style:nt,tabIndex:-1,children:e.map((e,t)=>I(`button`,{"data-dashfoo":`tab-overflow-item`,onClick:()=>f(e.id),ref:e=>{c.current[t]=e},role:`menuitem`,tabIndex:t===i?0:-1,type:`button`,children:e.name},e.id))}):null]})},it=()=>{let e=Y(e=>e.overflowItems),t=Y(e=>e.selectOverflowTab);return e.length===0?null:I(rt,{items:e,onSelect:t})},at=e=>{let t=e.getBoundingClientRect();return[...e.querySelectorAll(`[data-dashfoo="tab"]`)].flatMap(e=>{let n=e.getBoundingClientRect();return(n.right>t.right+1||n.left<t.left-1)&&e.dataset.tabId?[e.dataset.tabId]:[]})},ot=(e,t)=>{let[n,r]=O([]);return x(()=>{let t=()=>{r(t=>{let n=e?at(e):[];return n.length===0&&t.length===0?t:n})};if(t(),!e)return;let n=new ResizeObserver(t);return n.observe(e),e.addEventListener(`scroll`,t,{passive:!0}),()=>{n.disconnect(),e.removeEventListener(`scroll`,t)}},[e,t]),n},st=(e,t)=>t+1<e?t+1:t-1,ct={display:`flex`,flexDirection:`column`,height:`100%`,minHeight:0,minWidth:0,width:`100%`},lt=({children:e,node:t,ref:n,style:r,...i})=>{let a=G(e=>e.closableTabs),o=G(e=>e.dispatch),s=G(e=>e.maximizable),c=G(e=>e.maximizedTabsetId),l=G(e=>e.renamableTabs),u=G(e=>e.tabLocation),{ref:d}=xe(t.id),f=Ce(),p=D(null),m=c===t.id,h=s&&t.enableMaximize!==!1,g=a&&t.enableClose!==!1,_=l,v=f?.kind===`tab`?t.children.findIndex(e=>e.id===f.id):-1,y=v!==-1&&v===t.selected?st(t.children.length,v):t.selected,b=t.children[y],S=f?.kind===`tabset`&&f.id===t.id,C={activeTab:b,dispatch:o,isMaximized:m,node:t,showMaximize:h,tabsClosable:g,tabsRenamable:_,visualSelected:y},[w]=O(()=>Ye(C));T(()=>{w.setState(C)});let k=ot(P(w,e=>e.tablistElement),t.children.map(e=>`${e.id}:${e.name}`).join(`|`)),A=E(()=>{let e=new Map(t.children.map(e=>[e.id,e.name]));return k.map(t=>({id:t,name:e.get(t)??t}))},[k,t.children]);return T(()=>{w.setState({overflowItems:A})},[A,w]),x(()=>{if(!w.getState().restoreFocus)return;w.setState({restoreFocus:!1});let e=t.children[t.selected]?.id;e?p.current?.querySelector(`#${CSS.escape(J(t.id,e))}`)?.focus():p.current?.focus()},[t.children,t.selected,t.id,w]),I(Xe.Provider,{value:w,children:I(`div`,{...i,"data-dashfoo":`tabset`,"data-dragging-source":S||void 0,"data-tab-location":u,ref:e=>{d(e),p.current=e,typeof n==`function`?n(e):n&&(n.current=e)},style:{...ct,...r},tabIndex:-1,children:e})})},ut=(e,t)=>{typeof e==`function`?e(t):e&&(e.current=t)},Z=(...e)=>t=>{for(let n of e)ut(n,t)},dt=({children:e,ref:t,tab:n,...r})=>{let i=b(Xe),a=Y(e=>e.node),o=Y(e=>e.editingTabId===n.id),s=Ce(),c=s?.kind===`tab`&&s.id===n.id,l=D(null),u=D(!1),d=a.children.findIndex(e=>e.id===n.id);x(()=>{i?.getState().node.children.some(e=>e.id===n.id)===!1&&K(`orphan-tab-${n.id}`,`<Tabset.Tab> for "${n.id}" is not a child of its Tabset.Root's node; it renders but can never be selected`)},[d===-1,i,n.id]),x(()=>{u.current&&!o&&l.current?.querySelector(`[data-dashfoo="tab"]`)?.focus(),u.current=o},[o]);let f=E(()=>({index:d,tab:n}),[d,n]),p=E(()=>Z(l,t),[t]);return I(Ze.Provider,{value:f,children:I(`span`,{...r,"data-dashfoo":`tab-item`,"data-dragging":c||void 0,ref:p,children:e})})},ft=({children:e,onClick:t,onDoubleClick:n,ref:r,...i})=>{let{index:a,tab:o}=X(),s=Y(e=>e.node),c=Y(e=>e.editingTabId===o.id),l=Y(e=>e.selectTab),u=Y(e=>e.startEditing),d=Y(e=>e.tabsRenamable),f=Y(e=>e.visualSelected),p=G(e=>e.draggableTabs),m=G(e=>e.renderTabLabel),{ref:h}=ye(o.id,!p||o.enableDrag===!1,o.name),g=E(()=>Z(h,r),[h,r]);if(c)return null;let _=a===f,v=d&&o.enableRename!==!1,y=e=>{t?.(e),l(a)},b=e=>{n?.(e),v&&u(o.id)};return I(`button`,{"aria-label":m?o.name:void 0,...i,"aria-controls":qe(s.id),"aria-selected":_,"data-dashfoo":`tab`,"data-tab-id":o.id,id:J(s.id,o.id),onClick:y,onDoubleClick:b,ref:g,role:`tab`,tabIndex:_?0:-1,type:`button`,children:e??(m?m(o):o.name)})},pt={pointerEvents:`none`},Q=({children:e})=>I(`svg`,{"aria-hidden":`true`,fill:`none`,height:`12`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,style:pt,viewBox:`0 0 24 24`,width:`12`,children:e}),mt=()=>L(Q,{children:[I(`path`,{d:`M18 6 6 18`}),I(`path`,{d:`m6 6 12 12`})]}),ht=()=>L(Q,{children:[I(`circle`,{cx:`12`,cy:`5`,r:`1`}),I(`circle`,{cx:`19`,cy:`5`,r:`1`}),I(`circle`,{cx:`5`,cy:`5`,r:`1`}),I(`circle`,{cx:`12`,cy:`12`,r:`1`}),I(`circle`,{cx:`19`,cy:`12`,r:`1`}),I(`circle`,{cx:`5`,cy:`12`,r:`1`}),I(`circle`,{cx:`12`,cy:`19`,r:`1`}),I(`circle`,{cx:`19`,cy:`19`,r:`1`}),I(`circle`,{cx:`5`,cy:`19`,r:`1`})]}),gt=({maximized:e})=>e?L(Q,{children:[I(`path`,{d:`m14 10 7-7`}),I(`path`,{d:`M20 10h-6V4`}),I(`path`,{d:`m3 21 7-7`}),I(`path`,{d:`M4 14h6v6`})]}):L(Q,{children:[I(`path`,{d:`M15 3h6v6`}),I(`path`,{d:`m21 3-7 7`}),I(`path`,{d:`m3 21 7-7`}),I(`path`,{d:`M9 21H3v-6`})]}),_t=({defaultValue:e,onBlur:t,onKeyDown:n,ref:r,...i})=>{let{tab:a}=X(),o=Y(e=>e.cancelRename),s=Y(e=>e.commitRename),c=D(null),l=D(!1),u=E(()=>Z(c,r),[r]);x(()=>{c.current?.focus(),c.current?.select()},[]);let d=e=>{n?.(e),e.key===`Enter`?(l.current=!0,s(a.id,e.currentTarget.value)):e.key===`Escape`&&(l.current=!0,o())},f=e=>{t?.(e),!l.current&&(l.current=!0,s(a.id,e.currentTarget.value))};return I(`input`,{"aria-label":`Rename ${a.name}`,...i,"data-dashfoo":`tab-rename`,defaultValue:e??a.name,onBlur:f,onKeyDown:d,ref:u,type:`text`})},vt=e=>{let{tab:t}=X(),n=Y(e=>e.editingTabId===t.id),r=Y(e=>e.registerRenameInput);return x(()=>r(),[r]),n?I(_t,{...e}):null},yt=({children:e,onClick:t,...n})=>{let{index:r,tab:i}=X(),a=Y(e=>e.closeTab),o=Y(e=>e.editingTabId===i.id),s=Y(e=>e.tabsClosable),c=Y(e=>e.visualSelected);if(!(s&&i.enableClose!==!1)||o)return null;let l=e=>{t?.(e),e.stopPropagation(),a(i.id)};return I(`button`,{"aria-label":`Close ${i.name}`,...n,"data-dashfoo":`tab-close`,onClick:l,tabIndex:r===c?0:-1,type:`button`,children:e??I(mt,{})})},bt={display:`flex`,flexShrink:0},xt={display:`flex`,minWidth:0,overflowX:`auto`},St=({style:e,...t})=>I(`div`,{...t,"data-dashfoo":`tabstrip`,style:{...bt,...e}}),Ct=({onKeyDown:e,ref:t,style:n,...r})=>{let i=Y(e=>e.node),a=Y(e=>e.registerTablist),o=Y(e=>e.selectTab),s=t=>{if(e?.(t),t.defaultPrevented||!(t.target instanceof HTMLElement)||!t.target.closest(`[role="tab"]`))return;let n=i.children.length;if(n===0)return;let r={ArrowLeft:(i.selected-1+n)%n,ArrowRight:(i.selected+1)%n,End:n-1,Home:0}[t.key];r!==void 0&&(t.preventDefault(),o(r,{focus:!0}))},c=E(()=>Z(a,t),[a,t]);return I(`div`,{"aria-label":i.name??`Tabs`,...r,"aria-orientation":`horizontal`,"data-dashfoo":`tablist`,onKeyDown:s,ref:c,role:`tablist`,style:{...xt,...n},tabIndex:-1})},wt={alignItems:`center`,display:`flex`,flexShrink:0,marginInlineStart:`auto`},Tt=({style:e,...t})=>I(`div`,{...t,"data-dashfoo":`tabset-toolbar`,style:{...wt,...e}}),Et=({children:e,ref:t,...n})=>{let r=Y(e=>e.activeTab?.name??``),i=Y(e=>e.isMaximized),a=Y(e=>e.node),o=!G(e=>e.draggableTabsets)||i,{ref:s}=be(a.id,o,r),c=E(()=>Z(s,t),[s,t]);return o?null:I(`button`,{"aria-label":`Move tabset`,...n,"data-dashfoo":`tabset-grip`,ref:c,type:`button`,children:e??I(ht,{})})},Dt=({children:e,onClick:t,...n})=>{let r=Y(e=>e.isMaximized),i=Y(e=>e.showMaximize),a=Y(e=>e.toggleMaximize);if(!i)return null;let o=e=>{t?.(e),a()};return I(`button`,{"aria-label":r?`Restore`:`Maximize`,...n,"aria-pressed":r,"data-dashfoo":`tabset-maximize`,onClick:o,type:`button`,children:e??I(gt,{maximized:r})})},Ot=I(et,{}),kt=()=>{let e=G(e=>e.draggableTabsets),t=G(e=>e.renderTabsetToolbar),n=G(e=>e.tabLocation),r=G(e=>e.tabStripEnabled),i=Y(e=>e.isMaximized),a=Y(e=>e.node),o=Y(e=>e.overflowItems.length),s=Y(e=>e.showMaximize)||t!==void 0||o>0||e&&!i,c=r?L(St,{children:[I(Ct,{children:a.children.map(e=>L(dt,{tab:e,children:[I(ft,{}),I(vt,{}),I(yt,{})]},e.id))}),s?L(Tt,{children:[I(it,{}),I(Et,{}),t?.(a),I(Dt,{})]}):null]}):null;return n===`bottom`?L(F,{children:[Ot,c]}):L(F,{children:[c,Ot]})},At=({node:e})=>I(lt,{node:e,children:I(kt,{})}),jt=e=>`${e.value}${e.unit}`,Mt=e=>e?.unit===`px`?e.value:void 0,Nt={display:`flex`,flex:1,minHeight:0,minWidth:0},Pt=.01,Ft=(e,t)=>e.reduce((e,n)=>(e[n.id]=(n.weight??1)/t*100,e),{}),It=(e,t)=>t.map(t=>e[t.id]??0),Lt=(e,t)=>t.reduce((t,n,r)=>(t[n.id]=e[r]??0,t),{}),Rt=(e,t)=>{let n=Object.keys(e),r=Object.keys(t);return n.length===r.length?r.every(n=>Math.abs((e[n]??NaN)-t[n])<=Pt):!1},zt=(e,t,n)=>{let r=Mt(e.min);if(r!==void 0)return r;if(e.min!==void 0)return;if(e.type===`tabset`)return n;let i=[];for(let r of e.children){let e=zt(r,t,n);if(e===void 0)return;i.push(e)}if(i.length!==0)return e.orientation===t?i.reduce((e,t)=>e+t,0):Math.max(...i)},Bt=({node:e,renderTabset:t})=>{let n=G(e=>e.dispatch),r=G(e=>e.resizableSplits),i=G(e=>e.tabsetMinSize),a=G(e=>e.snap),o=e.snap??a,s=l(o),c=e.orientation===`row`?`horizontal`:`vertical`,d=e.children.reduce((e,t)=>e+(t.weight??1),0),f=E(()=>Ft(e.children,d),[e.children,d]),p=D(!1),m=D(null),g=D(null),_=D(!1),v=D(null),y=D(!1),b=D(null),[x,S]=O(null),C=e=>{e!==b.current&&(b.current=e,S(e))},w=e=>{let t=g.current;t&&(e?t.dataset.dashfooSnapping=`true`:delete t.dataset.dashfooSnapping)};return T(()=>{let e=m.current;if(!e)return;let t=e.getLayout();if(!(Object.keys(t).length===Object.keys(f).length&&Object.keys(f).every(e=>e in t))||Rt(t,f))return;_.current=!0,e.setLayout(f);let n=requestAnimationFrame(()=>{_.current=!1});return()=>{cancelAnimationFrame(n),_.current=!1}},[f]),I(re,{"data-dashfoo":`row`,disabled:!r,elementRef:g,groupRef:m,onLayoutChange:s?t=>{if(y.current||_.current||!r||o===null||!s)return;let n=v.current;if(n===null)return;let{sizes:i,snapped:a}=u(It(t,e.children),n,o);if(C(a?n:null),!a){w(!1);return}w(!0);let c=m.current,l=Lt(i,e.children);!c||Rt(t,l)||(y.current=!0,c.setLayout(l),y.current=!1)}:void 0,onLayoutChanged:t=>{if(!p.current){p.current=!0;return}if(_.current)return;let i=v.current;if(v.current=null,C(null),w(!1),!r)return;let a=e.children.map(e=>t[e.id]??e.weight??1);i!==null&&o!==null&&s&&(a=u(a,i,o).sizes),a.some((t,n)=>Math.abs(t-(e.children[n]?.weight??1))>Pt)&&n({rowId:e.id,type:`adjustSplit`,weights:a})},orientation:c,style:Nt,children:e.children.map((n,a)=>{let o=(n.weight??1)/d*100,c=n.min?jt(n.min):void 0;if(c===void 0){let t=zt(n,e.orientation,i);c=t===void 0?void 0:`${t}px`}let l=n.max?jt(n.max):void 0;return L(h,{children:[a>0?I(ae,{"data-dashfoo":`splitter`,"data-dashfoo-snapped":x===a-1?`true`:void 0,disabled:!r,onPointerDown:s&&r?()=>{v.current=a-1}:void 0}):null,I(ie,{defaultSize:`${o}%`,id:n.id,maxSize:l,minSize:c,children:n.type===`row`?I(Bt,{node:n,renderTabset:t}):t?.(n)??I(At,{node:n})})]},n.id)})},e.id)},$={DragLayer:We,Root:Ke,Rows:Bt,Tabset:At},Vt=(e,t)=>e===void 0||!t?null:typeof e==`string`?{debounceMs:300,key:e,storage:R}:{debounceMs:e.debounceMs??300,key:e.key,storage:e.storage??R},Ht=new Set,Ut=v((e,t)=>{let{closableTabs:n=!0,components:r,defaultModel:a,draggableTabs:o=!0,draggableTabsets:s=!0,editable:c=!0,factory:l,keepMounted:u=!1,maximizable:f=!0,model:p,onAction:m,onActiveTabsetChange:h,onMaximizedTabsetChange:g,onModelChange:_,persist:v,renamableTabs:b=!0,renderTabLabel:x,renderTabsetToolbar:S,resizableSplits:w=!0,responsive:T,snap:O}=e,k=se(E(()=>Vt(v,a!==void 0),[v,a]),a),A=y((e,t)=>{k.save(e),_?.(e,t)},[_,k]),j=fe({defaultModel:k.initialModel??a,model:p,onAction:m,onActiveTabsetChange:h,onMaximizedTabsetChange:g,onModelChange:A});C(t,()=>({addTab:(e,t)=>j.dispatch({index:t.index,location:t.location??`center`,tab:e,targetId:t.targetId,type:`addNode`}),canRedo:j.canRedo,canUndo:j.canUndo,closeTab:e=>j.dispatch({tabId:e,type:`deleteTab`}),dispatch:j.dispatch,getModel:()=>j.model,maximizeTabset:e=>j.dispatch({tabsetId:e,type:`setMaximizedTabset`}),redo:j.redo,renameTab:(e,t)=>j.dispatch({name:t,tabId:e,type:`renameTab`}),resetLayout:()=>{k.clear(),a!==void 0&&j.setModel(a)},selectTab:(e,t)=>j.dispatch({index:t,tabsetId:e,type:`selectTab`}),undo:j.undo}),[a,k,j]);let ee=y(e=>{if(l)return l(e);let t=r?.[e.component];return t?I(t,{node:e}):(r&&!Ht.has(e.component)&&(Ht.add(e.component),console.warn(`[dashfoo] no component registered for "${e.component}"`)),null)},[r,l]),[te,ne]=z(),M=T!==void 0&&ne<=T.maxWidth,N=E(()=>M?d(j.model,T?.orientation):j.model,[M,T?.orientation,j.model]),P=D(M);P.current=M;let F=y(e=>{P.current&&e.type===`adjustSplit`||j.dispatch(e)},[j]),L=N.maximizedTabsetId?i(N,N.maximizedTabsetId):void 0;return I($.Root,{closableTabs:n,dispatch:F,draggableTabs:M?!1:o,draggableTabsets:M?!1:s,editable:c,keepMounted:u,maximizable:f,model:N,renamableTabs:b,renderTab:ee,renderTabLabel:x,renderTabsetToolbar:S,resizableSplits:M?!1:w,rootRef:te,snap:O,children:I($.DragLayer,{children:L?I($.Tabset,{node:L}):I($.Rows,{node:N.layout})})})});Ut.displayName=`DashfooLayout`;const Wt=({children:e})=>{let[t]=O(me);w(()=>()=>t.destroy(),[t]);let[n]=O(H);return I(V.Provider,{value:t,children:I(U.Provider,{value:n,children:e})})},Gt={Badge:e=>I(`span`,{...e,"data-dashfoo":`panel-badge`}),Body:e=>I(`div`,{...e,"data-dashfoo":`panel-body`}),Header:e=>I(`div`,{...e,"data-dashfoo":`panel-header`}),Icon:e=>I(`span`,{...e,"data-dashfoo":`panel-icon`}),Root:e=>I(`div`,{...e,"data-dashfoo":`panel`}),Title:e=>I(`span`,{...e,"data-dashfoo":`panel-title`})},Kt={CloseButton:yt,Content:et,Grip:Et,MaximizeButton:Dt,OverflowMenu:it,RenameInput:vt,Root:lt,Tab:dt,Tablist:Ct,TabStrip:St,Toolbar:Tt,Trigger:ft};export{Wt as DashfooDragProvider,Ut as DashfooLayout,$ as Layout,Gt as Panel,Kt as Tabset,ue as activeBreakpoint,R as localStorageAdapter,le as matchBreakpoint,oe as memoryStorageAdapter,z as useContainerWidth,fe as useDashfooStore,Ce as useDragSubject,we as useDropIntent,Se as useExternalTabSource,G as useLayout,se as usePersistence,de as useResponsiveModel,X as useTab,Y as useTabset};
8
+ `);return r!==null&&r!==t.element},V=()=>new k({plugins:e=>e.filter(e=>e!==O&&e!==j),sensors:()=>[ee.configure({preventActivation:B})]}),re=g(null),H=g(null),ie=()=>M(()=>({intent:null,intentOwner:null,subject:null})),ae=(e,t)=>e===t||e!==null&&t!==null&&e.index===t.index&&e.location===t.location&&e.targetId===t.targetId,oe=(e,t)=>e===t||e!==null&&t!==null&&e.id===t.id&&e.kind===t.kind,se=ie(),U=g(null),ce=()=>{let e=E(null),t=E(null);return{draggableRef:t,elementRef:e,ref:v(n=>{e.current=n,t.current&&(t.current.element=n??void 0)},[])}},le=(e,t,n)=>{let r=y(re),i=y(H),a=r?.manager??i,{draggableRef:o,elementRef:s,ref:c}=ce(),{data:l,id:u}=e;return b(()=>{if(!a||t)return;let e=new A({data:{...l,label:``},id:u},a);return e.element=s.current??void 0,o.current=e,()=>{e.destroy(),o.current=null}},[l,t,o,s,u,a]),b(()=>{let e=o.current;e&&(e.data={...l,label:n})},[l,o,n]),{ref:c}},ue=(e,t=!1,n=``)=>le({data:T(()=>({type:`tab`}),[]),id:e},t,n),de=(e,t=!1,n=``)=>le({data:T(()=>({tabsetId:e,type:`tabset`}),[e]),id:`grip-${e}`},t,n),fe=e=>{let t=y(re);return{ref:v(n=>{t?.registerTabset(e,n)},[t,e])}},pe=({createTab:e,disabled:t=!1,label:n=``})=>{let r=x(),i=E(e);return b(()=>{i.current=e}),le({data:T(()=>({createTab:()=>i.current(),type:`external`}),[]),id:`external-${r}`},t,n)},me=()=>N(y(U)??se,e=>e.subject),he=()=>N(y(U)??se,e=>e.intent),ge=()=>{let e=new Map;return{getItem:t=>e.get(t)??null,removeItem:t=>{e.delete(t)},setItem:(t,n)=>{e.set(t,n)}}},_e={getItem:e=>{if(typeof window>`u`)return null;try{return window.localStorage.getItem(e)}catch{return null}},removeItem:e=>{if(!(typeof window>`u`))try{window.localStorage.removeItem(e)}catch{}},setItem:(e,t)=>{if(!(typeof window>`u`))try{window.localStorage.setItem(e,t)}catch(e){console.warn(`[dashfoo] failed to persist layout`,e)}}},ve=(e,t)=>{let n=E(e);b(()=>{n.current=e});let[r]=D(()=>{if(e===null||t===void 0)return t;let n=e.storage.getItem(e.key);if(n===null)return t;try{return a(n)}catch{return t}});b(()=>{let e=n.current;if(e===null)return;let t=e.storage.getItem(e.key);if(t!==null)try{a(t)}catch(t){console.warn(`[dashfoo] discarding unreadable persisted layout`,t),e.storage.removeItem(e.key)}},[]);let i=E(e?.key);b(()=>{e!==null&&e.key!==i.current&&(console.warn(`[dashfoo] persist key changed for a mounted layout; the displayed layout still reflects the previous key — remount (key={persistKey}) to load the new key`),i.current=e.key)},[e]);let o=E(null),s=E(null),c=v(()=>{o.current!==null&&(clearTimeout(o.current),o.current=null),s.current!==null&&(s.current.storage.setItem(s.current.key,s.current.value),s.current=null)},[]),l=v(e=>{let t=n.current;t!==null&&(s.current={key:t.key,storage:t.storage,value:p(e)},o.current!==null&&clearTimeout(o.current),o.current=setTimeout(c,t.debounceMs))},[c]);b(()=>{let e=()=>{c()},t=()=>{document.visibilityState===`hidden`&&c()};return window.addEventListener(`pagehide`,e),document.addEventListener(`visibilitychange`,t),()=>{window.removeEventListener(`pagehide`,e),document.removeEventListener(`visibilitychange`,t),c()}},[c]);let u=v(()=>{o.current!==null&&(clearTimeout(o.current),o.current=null),s.current=null;let e=n.current;e!==null&&e.storage.removeItem(e.key)},[]);return T(()=>({clear:u,initialModel:r,save:l}),[u,r,l])},ye=()=>typeof window<`u`&&typeof window.matchMedia==`function`,be=(e,t)=>{let{query:n}=e;return n?`maxWidth`in n?t<=n.maxWidth:ye()&&window.matchMedia(n.media).matches:!0},xe=(e,t)=>{let n=e.at(-1);if(!n)throw Error(`useResponsiveModel requires at least one breakpoint.`);return e.find(e=>be(e,t))??n},Se=()=>{let[e,t]=D(1/0),n=E(null),r=v(e=>{if(n.current?.disconnect(),!e)return;let r=new ResizeObserver(e=>{let n=e[0];n&&t(n.contentRect.width)});r.observe(e),n.current=r},[]);return b(()=>()=>{n.current?.disconnect()},[]),[r,e]},Ce=({breakpoints:e})=>{let[t,n]=Se(),[,r]=D(0);b(()=>{if(!ye())return;let t=e.flatMap(e=>e.query&&`media`in e.query?[window.matchMedia(e.query.media)]:[]);if(t.length===0)return;let n=()=>{r(e=>e+1)};for(let e of t)e.addEventListener(`change`,n);return()=>{for(let e of t)e.removeEventListener(`change`,n)}},[e]);let i=xe(e,n),a=i.compact===!0;return{breakpoint:i.id,containerRef:t,draggableTabs:!a,draggableTabsets:!a,isCompact:a,model:i.model,resizableSplits:!a}},we=r=>{let{defaultModel:i,model:a,onAction:c,onActiveTabsetChange:l,onMaximizedTabsetChange:u,onModelChange:d}=r,f=a??i;if(f===void 0)throw Error("useDashfooStore requires either a `model` or a `defaultModel`.");let p=te(n,{input:{model:o(f)}}),m=P(p,e=>e.context.history);b(()=>{a!==void 0&&p.send({model:o(a),type:`SET_MODEL`})},[p,a]);let h=a??m.present,g=v((e,t,n)=>{Object.is(e,t)||(d?.(t,n),t.activeTabsetId!==e.activeTabsetId&&l?.(t.activeTabsetId),t.maximizedTabsetId!==e.maximizedTabsetId&&u?.(t.maximizedTabsetId))},[d,l,u]),_=v(e=>{let t=c?c(e):e;if(!t)return;let n=(()=>{if(a===void 0){let e=p.getSnapshot().context.history.present;return p.send({action:t,type:`DISPATCH`}),{after:p.getSnapshot().context.history.present,before:e}}return{after:s(a,t),before:o(a)}})();g(n.before,n.after,t)},[p,a,g,c]),y=v(()=>{if(a!==void 0)return;let e=p.getSnapshot().context.history.present;p.send({type:`UNDO`});let t=p.getSnapshot().context.history.present;g(e,t)},[p,a,g]),x=v(()=>{if(a!==void 0)return;let e=p.getSnapshot().context.history.present;p.send({type:`REDO`});let t=p.getSnapshot().context.history.present;g(e,t)},[p,a,g]),S=v(e=>{p.send({model:o(e),type:`SET_MODEL`})},[p]);return T(()=>({canRedo:()=>e(p.getSnapshot().context.history),canUndo:()=>t(p.getSnapshot().context.history),dispatch:_,model:h,redo:x,setModel:S,undo:y}),[p,_,h,x,S,y])},Te=({children:e})=>{let[t]=D(V);C(()=>()=>t.destroy(),[t]);let[n]=D(ie);return I(H.Provider,{value:t,children:I(U.Provider,{value:n,children:e})})},Ee=e=>M(()=>e),De=g(null),W=e=>{let t=y(De);if(t===null)throw Error(`dashfoo components must be rendered inside <DashfooLayout> or <Layout.Root>.`);return N(t,e)},Oe=(e,t)=>e.x>=t.x&&e.x<=t.x+t.width&&e.y>=t.y&&e.y<=t.y+t.height,ke=(e,t)=>{let n=e.findIndex(e=>t<e.x+e.width/2);return n===-1?e.length:n},Ae=(e,t,n)=>{let r=t[n],i=t.at(-1),a=(r?.x??(i?i.x+i.width:e.x))-4/2;return{height:e.height,width:4,x:Math.max(e.x,Math.min(a,e.x+e.width-4)),y:e.y}},je=(e,t,n)=>!(e===`grip-${t}`||n.length===1&&n[0]===e),Me=new Set,G=(e,t)=>{Me.has(e)||(Me.add(e),console.warn(`[dashfoo] ${t}`))},Ne={boxSizing:`border-box`,pointerEvents:`none`,position:`fixed`,transition:`var(--dashfoo-dock-transition, left 60ms, top 60ms, width 60ms, height 60ms)`,zIndex:9999},Pe=e=>({...Ne,background:`var(--dashfoo-dock-fill, oklch(0.556 0 0 / 0.18))`,border:`var(--dashfoo-dock-border-width, 1px) solid var(--dashfoo-dock-border, oklch(0.708 0 0 / 0.75))`,borderRadius:`var(--dashfoo-dock-radius, 6px)`,height:e.height,left:e.x,top:e.y,width:e.width}),Fe=e=>({...Pe(e),borderRadius:`var(--dashfoo-dock-line-radius, 2px)`}),Ie=(e,t)=>[...e.querySelectorAll(`[data-dashfoo="tab-item"]`)].flatMap(e=>e.querySelector(`[data-dashfoo="tab"]`)?.dataset.tabId===t?[]:[e.getBoundingClientRect()]),Le=({actorRef:e,getTabsetElement:t})=>{let n=P(e,e=>e.context.intent),r=P(e,e=>e.context.subject?.id);if(!n)return null;let i=t(n.targetId);if(!i)return null;if(n.location===`center`){let e=i.querySelector(`[data-dashfoo="tabstrip"]`);if(e)return I(`div`,{"data-dashfoo":`dock-indicator`,style:Fe(Ae(e.getBoundingClientRect(),Ie(e,r),n.index??0))})}return I(`div`,{"data-dashfoo":`dock-indicator`,style:Pe(m(i.getBoundingClientRect(),n.location))})},Re={left:0,position:`fixed`,top:0,zIndex:9999},ze=({overlayRef:e,preview:t})=>t?I(`div`,{"data-dashfoo":`drag-preview`,ref:e,style:{...Re,transform:`translate(${t.x}px, ${t.y}px)`},children:t.label}):null,Be=(e,t)=>[...e.querySelectorAll(`[data-dashfoo="tab"]`)].flatMap(e=>e.dataset.tabId===t?[]:[e.getBoundingClientRect()]),Ve=(e,t,n,r)=>{let i=t.querySelector(`[data-dashfoo="tabstrip"]`);if(i&&Oe(n,i.getBoundingClientRect()))return{index:ke(Be(i,r),n.x),location:`center`,targetId:e};let a=c(n,t.getBoundingClientRect()),o=a.kind===`tab`?`center`:`split-${a.edge}`;return o===`center`&&i?{index:Be(i,r).length,location:o,targetId:e}:{location:o,targetId:e}},K={x:12,y:8},He=e=>{let t=e?.data?.label;return typeof t==`string`?t:``},Ue=e=>typeof e==`function`,We=e=>{let t=e.data;if(t?.type===`tabset`)return{id:String(t.tabsetId),kind:`tabset`};if(t?.type===`external`){if(!Ue(t.createTab))return console.warn(`[dashfoo] external drag source is missing its createTab function`),null;let n;try{n=t.createTab()}catch(e){return console.warn(`[dashfoo] external drag source createTab threw`,e),null}let r=f.safeParse(n);return r.success?{id:String(e.id),kind:`external`,tab:r.data}:(console.warn(`[dashfoo] external drag source returned an invalid tab`,r.error),null)}return{id:String(e.id),kind:`tab`}},Ge=({children:e,onCommit:t,splitDock:n})=>{let i=te(r),a=y(De),[o]=D(()=>new Map),s=E(null),[c,l]=D(null),u=y(H),[d]=D(()=>u?null:V());C(()=>()=>d?.destroy(),[d]);let f=u??d;if(f===null)throw Error(`[dashfoo] DashfooDragProvider unmounted while its layout is still mounted; keep the provider above the layout or remount the layout`);let p=y(U),[m]=D(()=>p??ie()),h=x();b(()=>{let e=i.subscribe(e=>{let{intent:t,subject:n}=e.context,r=m.getState();t===null?r.intent!==null&&r.intentOwner===h&&m.setState({intent:null,intentOwner:null}):(!ae(r.intent,t)||r.intentOwner!==h)&&m.setState({intent:t,intentOwner:h}),oe(m.getState().subject,n)||m.setState({subject:n})});return()=>{e.unsubscribe()}},[i,h,m]);let g=E(t),_=E(n);b(()=>{g.current=t,_.current=n}),b(()=>{let e=i.on(`COMMIT`,e=>{if(a?.getState().editable===!1)return;let t=g.current??a?.getState().dispatch;if(!t){G(`drag-layer-no-commit`,`Layout.DragLayer has neither an onCommit prop nor a <Layout.Root> above it; drops are ignored`);return}t(e.action)});return()=>{e.unsubscribe()}},[i,a]);let S=v((e,t)=>{t?o.set(e,t):o.delete(e)},[o]),w=v(e=>o.get(e),[o]),O=v(e=>{s.current=e},[]);b(()=>{let e=e=>{let t=document.elementFromPoint(e.x,e.y);if(t){for(let[e,n]of o)if(n.contains(t))return{element:n,id:e}}},t=(e,t,n,r)=>{if(a?.getState().editable===!1||!je(r,e,[...t.querySelectorAll(`[data-dashfoo="tab"]`)].map(e=>e.dataset.tabId??``)))return null;let i=Ve(e,t,n,r);return!(_.current??a?.getState().splitDock??!0)&&i.location.startsWith(`split-`)?{location:`center`,targetId:e}:i},n=e=>{let t=s.current;t&&(t.style.transform=`translate(${e.x+K.x}px, ${e.y+K.y}px)`)},r=e=>{let t=e.operation.source;if(!t)return;let n=We(t);if(!n)return;let r=e.operation.position.current;l({label:He(t),x:r.x+K.x,y:r.y+K.y}),i.send({subject:n,type:`START`})},c=r=>{let a=r.operation,o=a.position.current;n(o);let s=a.source?String(a.source.id):void 0,c=e(o);i.send({intent:c?t(c.id,c.element,o,s):null,type:`OVER`})},u=n=>{if(l(null),n.canceled){i.send({type:`CANCEL`});return}let r=n.operation,a=r.position.current,o=r.source?String(r.source.id):void 0,s=e(a);s&&i.send({intent:t(s.id,s.element,a,o),type:`OVER`}),i.send({type:`DROP`})},d=f.monitor.addEventListener(`dragstart`,r),p=f.monitor.addEventListener(`dragmove`,c),m=f.monitor.addEventListener(`dragend`,u);return()=>{d(),p(),m()}},[i,a,f,o]);let k=T(()=>({manager:f,registerTabset:S}),[f,S]);return I(re.Provider,{value:k,children:L(U.Provider,{value:m,children:[e,I(Le,{actorRef:i,getTabsetElement:w}),I(ze,{overlayRef:O,preview:c})]})})},Ke=g(!1),qe=()=>y(Ke),Je=(e,t,n=e)=>({height:e.height,left:Math.max(0,Math.min(e.left,Math.max(0,t.width-n.width))),top:Math.max(0,Math.min(e.top,Math.max(0,t.height-n.height))),width:e.width}),Ye=e=>{let t=(e.closest(`[data-dashfoo="tabset"]`)??e).getBoundingClientRect();return Je({height:Math.max(120,Math.min(Math.round(t.height),340)),left:Math.round(t.left)+16,top:Math.round(t.top)+16,width:Math.max(200,Math.min(Math.round(t.width),480))},{height:window.innerHeight,width:window.innerWidth})},Xe=(e,t,n,r)=>{let{height:i,left:a,top:o,width:s}=e;return t.x===1?s=Math.max(200,e.width+n):t.x===-1&&(s=Math.max(200,e.width-n),a=Math.max(0,e.left+(e.width-s))),t.y===1?i=Math.max(120,e.height+r):t.y===-1&&(i=Math.max(120,e.height-r),o=Math.max(0,e.top+(e.height-i))),{height:i,left:a,top:o,width:s}},Ze={display:`flex`,height:`100%`,position:`relative`,width:`100%`},Qe=({children:e,closableTabs:t=!0,dispatch:n,draggableTabs:r=!0,draggableTabsets:i=!0,editable:a=!0,floatable:o=!1,keepMounted:s=!1,maximizable:c=!0,model:l,renamableTabs:u=!0,renderTab:d,renderTabLabel:f,renderTabsetToolbar:p,resizableSplits:m=!0,rootRef:h,snap:g,style:_,...v})=>{let y=l.global,b={closableTabs:a&&t&&y.tabEnableClose!==!1,dispatch:n,draggableTabs:a&&r&&y.tabEnableDrag!==!1,draggableTabsets:a&&i,editable:a,floatable:a&&o,keepMounted:s,maximizable:c&&y.tabSetEnableMaximize!==!1,maximizedTabsetId:l.maximizedTabsetId,renamableTabs:a&&u&&y.tabEnableRename!==!1,renderTab:d,renderTabLabel:f,renderTabsetToolbar:p,resizableSplits:a&&m&&y.enableSplitResize!==!1,snap:g??y.snap??null,splitDock:y.enableSplitDock!==!1,tabLocation:y.tabLocation??`top`,tabsetMinSize:y.tabSetMinSize??320,tabStripEnabled:y.tabSetEnableTabStrip!==!1},[x]=D(()=>Ee(b));w(()=>{x.setState(b)});let S=y.splitterSize===void 0?{...Ze,..._}:{...Ze,"--dashfoo-splitter-size":`${y.splitterSize}px`,..._};return I(De.Provider,{value:x,children:I(`div`,{...v,"data-dashfoo":`layout`,ref:h,style:S,children:e})})},q=(e,t)=>`dashfoo-tab-${e}-${t}`,$e=e=>`dashfoo-panel-${e}`,et=(e,t,n)=>e?.querySelector(`#${CSS.escape(q(t,n))}`)??null,tt=e=>M((t,n)=>({...e,cancelRename:()=>t({editingTabId:null}),closeTab:e=>{t({restoreFocus:!0}),n().dispatch({tabId:e,type:`deleteTab`})},commitRename:(e,r)=>{t({editingTabId:null});let{node:i,renameTab:a}=n(),o=r.trim(),s=i.children.find(t=>t.id===e)?.name;o&&o!==s&&a(e,o)},editingTabId:null,overflowItems:[],registerRenameInput:()=>(t(e=>({renameInputCount:e.renameInputCount+1})),()=>t(e=>({renameInputCount:e.renameInputCount-1}))),registerTablist:e=>{if(e){let r=n().tablistElement;r&&r!==e&&G(`duplicate-tablist-${n().node.id}`,`more than one <Tabset.Tablist> under the same <Tabset.Root>; the last one wins for keyboard focus and overflow`),t({tablistElement:e});return}t({tablistElement:null})},renameInputCount:0,renameTab:(e,t)=>n().dispatch({name:t,tabId:e,type:`renameTab`}),restoreFocus:!1,selectOverflowTab:e=>{let{dispatch:t,node:r,tablistElement:i}=n(),a=r.children.findIndex(t=>t.id===e);a!==-1&&(t({index:a,tabsetId:r.id,type:`selectTab`}),et(i,r.id,e)?.scrollIntoView({block:`nearest`,inline:`nearest`}))},selectTab:(e,t)=>{let{dispatch:r,node:i,tablistElement:a}=n();if(r({index:e,tabsetId:i.id,type:`selectTab`}),t?.focus){let t=i.children[e]?.id;t&&et(a,i.id,t)?.focus()}},startEditing:e=>{let{node:r,renameInputCount:i,tabsRenamable:a}=n(),o=r.children.find(t=>t.id===e);if(!(!a||o?.enableRename===!1)){if(i===0){G(`missing-rename-input-${r.id}`,`startEditing needs a <Tabset.RenameInput> in the composition; ignoring`);return}t({editingTabId:e})}},tablistElement:null,toggleMaximize:()=>{let{dispatch:e,isMaximized:t,node:r}=n();e({tabsetId:t?null:r.id,type:`setMaximizedTabset`})}})),nt=g(null),J=e=>{let t=y(nt);if(t===null)throw Error(`dashfoo Tabset parts must be rendered inside <Tabset.Root>.`);return N(t,e)},rt=g(null),Y=()=>{let e=y(rt);if(e===null)throw Error(`dashfoo tab parts must be rendered inside <Tabset.Tab>.`);return e},it={flex:1,minHeight:0,overflow:`auto`},at=({render:e,tab:t})=>{let n=W(e=>e.renderTab);return e?e(t):n(t)},ot=({children:e,style:t,...n})=>{let r=J(e=>e.node),i=J(e=>e.visualSelected),a=W(e=>e.keepMounted),o={...it,...t};if(a&&r.children.length>0)return r.children.map((t,a)=>I(`div`,{...n,"aria-labelledby":q(r.id,t.id),"data-dashfoo":`tabcontent`,hidden:a!==i||void 0,id:a===i?$e(r.id):void 0,role:a===i?`tabpanel`:void 0,style:o,tabIndex:a===i?0:void 0,children:I(at,{render:e,tab:t})},t.id));let s=r.children[i];return s?I(`div`,{...n,"aria-labelledby":q(r.id,s.id),"data-dashfoo":`tabcontent`,id:$e(r.id),role:`tabpanel`,style:o,tabIndex:0,children:I(at,{render:e,tab:s})}):I(`div`,{...n,"data-dashfoo":`tabcontent`,style:o})},st=()=>L(`svg`,{"aria-hidden":`true`,fill:`currentColor`,height:`10`,viewBox:`0 0 10 10`,width:`10`,children:[I(`circle`,{cx:`2`,cy:`5`,r:`1`}),I(`circle`,{cx:`5`,cy:`5`,r:`1`}),I(`circle`,{cx:`8`,cy:`5`,r:`1`})]}),ct={position:`absolute`,right:0,top:`100%`,zIndex:10},lt=({items:e,onSelect:t})=>{let[n,r]=D(!1),[i,a]=D(0),o=E(null),s=E(null),c=E([]);b(()=>{if(!n)return;let e=e=>{e.target instanceof Node&&!o.current?.contains(e.target)&&r(!1)};return document.addEventListener(`pointerdown`,e),()=>{document.removeEventListener(`pointerdown`,e)}},[n]),b(()=>{n&&c.current[0]?.focus()},[n]);let l=()=>{r(!1),s.current?.focus()},u=e=>{a(e),c.current[e]?.focus()},d=()=>{a(0),r(e=>!e)},f=e=>{t(e),l()};return L(`div`,{"data-dashfoo":`tab-overflow-root`,ref:o,style:{position:`relative`},children:[I(`button`,{"aria-expanded":n,"aria-haspopup":`menu`,"aria-label":`More tabs`,"data-dashfoo":`tab-overflow`,onClick:d,ref:s,type:`button`,children:I(st,{})}),n?I(`div`,{"data-dashfoo":`tab-overflow-menu`,onBlur:e=>{e.relatedTarget instanceof Node&&o.current?.contains(e.relatedTarget)||r(!1)},onKeyDown:t=>{let n=e.length-1;switch(t.key){case`ArrowDown`:t.preventDefault(),u(i>=n?0:i+1);break;case`ArrowUp`:t.preventDefault(),u(i<=0?n:i-1);break;case`Home`:t.preventDefault(),u(0);break;case`End`:t.preventDefault(),u(n);break;case`Escape`:t.preventDefault(),l();break;default:break}},role:`menu`,style:ct,tabIndex:-1,children:e.map((e,t)=>I(`button`,{"data-dashfoo":`tab-overflow-item`,onClick:()=>f(e.id),ref:e=>{c.current[t]=e},role:`menuitem`,tabIndex:t===i?0:-1,type:`button`,children:e.name},e.id))}):null]})},ut=()=>{let e=J(e=>e.overflowItems),t=J(e=>e.selectOverflowTab);return e.length===0?null:I(lt,{items:e,onSelect:t})},dt=e=>{let t=e.getBoundingClientRect();return[...e.querySelectorAll(`[data-dashfoo="tab"]`)].flatMap(e=>{let n=e.getBoundingClientRect();return(n.right>t.right+1||n.left<t.left-1)&&e.dataset.tabId?[e.dataset.tabId]:[]})},ft=(e,t)=>{let[n,r]=D([]);return b(()=>{let t=()=>{r(t=>{let n=e?dt(e):[];return n.length===0&&t.length===0?t:n})};if(t(),!e)return;let n=new ResizeObserver(t);return n.observe(e),e.addEventListener(`scroll`,t,{passive:!0}),()=>{n.disconnect(),e.removeEventListener(`scroll`,t)}},[e,t]),n},pt=(e,t)=>t+1<e?t+1:t-1,mt={display:`flex`,flexDirection:`column`,height:`100%`,minHeight:0,minWidth:0,width:`100%`},ht=({children:e,node:t,ref:n,style:r,...i})=>{let a=W(e=>e.closableTabs),o=W(e=>e.dispatch),s=W(e=>e.maximizable),c=W(e=>e.maximizedTabsetId),l=W(e=>e.renamableTabs),u=W(e=>e.tabLocation),{ref:d}=fe(t.id),f=me(),p=E(null),m=c===t.id,h=s&&t.enableMaximize!==!1,g=a&&t.enableClose!==!1,_=l,v=f?.kind===`tab`?t.children.findIndex(e=>e.id===f.id):-1,y=v!==-1&&v===t.selected?pt(t.children.length,v):t.selected,x=t.children[y],S=f?.kind===`tabset`&&f.id===t.id,C={activeTab:x,dispatch:o,isMaximized:m,node:t,showMaximize:h,tabsClosable:g,tabsRenamable:_,visualSelected:y},[O]=D(()=>tt(C));w(()=>{O.setState(C)});let k=ft(N(O,e=>e.tablistElement),t.children.map(e=>`${e.id}:${e.name}`).join(`|`)),A=T(()=>{let e=new Map(t.children.map(e=>[e.id,e.name]));return k.map(t=>({id:t,name:e.get(t)??t}))},[k,t.children]);return w(()=>{O.setState({overflowItems:A})},[A,O]),b(()=>{if(!O.getState().restoreFocus)return;O.setState({restoreFocus:!1});let e=t.children[t.selected]?.id;e?p.current?.querySelector(`#${CSS.escape(q(t.id,e))}`)?.focus():p.current?.focus()},[t.children,t.selected,t.id,O]),I(nt.Provider,{value:O,children:I(`div`,{...i,"data-dashfoo":`tabset`,"data-dragging-source":S||void 0,"data-tab-location":u,ref:e=>{d(e),p.current=e,typeof n==`function`?n(e):n&&(n.current=e)},style:{...mt,...r},tabIndex:-1,children:e})})},gt=(e,t)=>{typeof e==`function`?e(t):e&&(e.current=t)},X=(...e)=>t=>{for(let n of e)gt(n,t)},_t=({children:e,ref:t,tab:n,...r})=>{let i=y(nt),a=J(e=>e.node),o=J(e=>e.editingTabId===n.id),s=me(),c=s?.kind===`tab`&&s.id===n.id,l=E(null),u=E(!1),d=a.children.findIndex(e=>e.id===n.id);b(()=>{i?.getState().node.children.some(e=>e.id===n.id)===!1&&G(`orphan-tab-${n.id}`,`<Tabset.Tab> for "${n.id}" is not a child of its Tabset.Root's node; it renders but can never be selected`)},[d===-1,i,n.id]),b(()=>{u.current&&!o&&l.current?.querySelector(`[data-dashfoo="tab"]`)?.focus(),u.current=o},[o]);let f=T(()=>({index:d,tab:n}),[d,n]),p=T(()=>X(l,t),[t]);return I(rt.Provider,{value:f,children:I(`span`,{...r,"data-dashfoo":`tab-item`,"data-dragging":c||void 0,ref:p,children:e})})},vt=({children:e,onClick:t,onDoubleClick:n,ref:r,...i})=>{let{index:a,tab:o}=Y(),s=J(e=>e.node),c=J(e=>e.editingTabId===o.id),l=J(e=>e.selectTab),u=J(e=>e.startEditing),d=J(e=>e.tabsRenamable),f=J(e=>e.visualSelected),p=W(e=>e.draggableTabs),m=W(e=>e.renderTabLabel),{ref:h}=ue(o.id,!p||o.enableDrag===!1,o.name),g=T(()=>X(h,r),[h,r]);if(c)return null;let _=a===f,v=d&&o.enableRename!==!1,y=e=>{t?.(e),l(a)},b=e=>{n?.(e),v&&u(o.id)};return I(`button`,{"aria-label":m?o.name:void 0,...i,"aria-controls":$e(s.id),"aria-selected":_,"data-dashfoo":`tab`,"data-tab-id":o.id,id:q(s.id,o.id),onClick:y,onDoubleClick:b,ref:g,role:`tab`,tabIndex:_?0:-1,type:`button`,children:e??(m?m(o):o.name)})},yt={pointerEvents:`none`},Z=({children:e})=>I(`svg`,{"aria-hidden":`true`,fill:`none`,height:`12`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,style:yt,viewBox:`0 0 24 24`,width:`12`,children:e}),bt=()=>L(Z,{children:[I(`path`,{d:`M18 6 6 18`}),I(`path`,{d:`m6 6 12 12`})]}),xt=()=>L(Z,{children:[I(`circle`,{cx:`12`,cy:`5`,r:`1`}),I(`circle`,{cx:`19`,cy:`5`,r:`1`}),I(`circle`,{cx:`5`,cy:`5`,r:`1`}),I(`circle`,{cx:`12`,cy:`12`,r:`1`}),I(`circle`,{cx:`19`,cy:`12`,r:`1`}),I(`circle`,{cx:`5`,cy:`12`,r:`1`}),I(`circle`,{cx:`12`,cy:`19`,r:`1`}),I(`circle`,{cx:`19`,cy:`19`,r:`1`}),I(`circle`,{cx:`5`,cy:`19`,r:`1`})]}),St=({maximized:e})=>e?L(Z,{children:[I(`path`,{d:`m14 10 7-7`}),I(`path`,{d:`M20 10h-6V4`}),I(`path`,{d:`m3 21 7-7`}),I(`path`,{d:`M4 14h6v6`})]}):L(Z,{children:[I(`path`,{d:`M15 3h6v6`}),I(`path`,{d:`m21 3-7 7`}),I(`path`,{d:`m3 21 7-7`}),I(`path`,{d:`M9 21H3v-6`})]}),Ct=()=>L(Z,{children:[I(`rect`,{height:`14`,rx:`2`,width:`18`,x:`3`,y:`6`}),I(`path`,{d:`M3 10h18`})]}),wt=()=>I(Z,{children:I(`path`,{d:`M5 12h14`})}),Tt=()=>L(Z,{children:[I(`path`,{d:`M3 7V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2`}),I(`path`,{d:`M11 8 7 12l4 4`}),I(`path`,{d:`M7 12h10`})]}),Et=({defaultValue:e,onBlur:t,onKeyDown:n,ref:r,...i})=>{let{tab:a}=Y(),o=J(e=>e.cancelRename),s=J(e=>e.commitRename),c=E(null),l=E(!1),u=T(()=>X(c,r),[r]);b(()=>{c.current?.focus(),c.current?.select()},[]);let d=e=>{n?.(e),e.key===`Enter`?(l.current=!0,s(a.id,e.currentTarget.value)):e.key===`Escape`&&(l.current=!0,o())},f=e=>{t?.(e),!l.current&&(l.current=!0,s(a.id,e.currentTarget.value))};return I(`input`,{"aria-label":`Rename ${a.name}`,...i,"data-dashfoo":`tab-rename`,defaultValue:e??a.name,onBlur:f,onKeyDown:d,ref:u,type:`text`})},Dt=e=>{let{tab:t}=Y(),n=J(e=>e.editingTabId===t.id),r=J(e=>e.registerRenameInput);return b(()=>r(),[r]),n?I(Et,{...e}):null},Ot=({children:e,onClick:t,...n})=>{let{index:r,tab:i}=Y(),a=J(e=>e.closeTab),o=J(e=>e.editingTabId===i.id),s=J(e=>e.tabsClosable),c=J(e=>e.visualSelected);if(!(s&&i.enableClose!==!1)||o)return null;let l=e=>{t?.(e),e.stopPropagation(),a(i.id)};return I(`button`,{"aria-label":`Close ${i.name}`,...n,"data-dashfoo":`tab-close`,onClick:l,tabIndex:r===c?0:-1,type:`button`,children:e??I(bt,{})})},kt={display:`flex`,flexShrink:0},At={display:`flex`,minWidth:0,overflowX:`auto`},jt=({style:e,...t})=>I(`div`,{...t,"data-dashfoo":`tabstrip`,style:{...kt,...e}}),Mt=({onKeyDown:e,ref:t,style:n,...r})=>{let i=J(e=>e.node),a=J(e=>e.registerTablist),o=J(e=>e.selectTab),s=t=>{if(e?.(t),t.defaultPrevented||!(t.target instanceof HTMLElement)||!t.target.closest(`[role="tab"]`))return;let n=i.children.length;if(n===0)return;let r={ArrowLeft:(i.selected-1+n)%n,ArrowRight:(i.selected+1)%n,End:n-1,Home:0}[t.key];r!==void 0&&(t.preventDefault(),o(r,{focus:!0}))},c=T(()=>X(a,t),[a,t]);return I(`div`,{"aria-label":i.name??`Tabs`,...r,"aria-orientation":`horizontal`,"data-dashfoo":`tablist`,onKeyDown:s,ref:c,role:`tablist`,style:{...At,...n},tabIndex:-1})},Nt={alignItems:`center`,display:`flex`,flexShrink:0,marginInlineStart:`auto`},Pt=({style:e,...t})=>I(`div`,{...t,"data-dashfoo":`tabset-toolbar`,style:{...Nt,...e}}),Ft=({children:e,ref:t,...n})=>{let r=J(e=>e.activeTab?.name??``),i=J(e=>e.isMaximized),a=J(e=>e.node),o=!W(e=>e.draggableTabsets)||i,{ref:s}=de(a.id,o,r),c=T(()=>X(s,t),[s,t]);return o?null:I(`button`,{"aria-label":`Move tabset`,...n,"data-dashfoo":`tabset-grip`,ref:c,type:`button`,children:e??I(xt,{})})},It=({children:e,onClick:t,...n})=>{let r=J(e=>e.isMaximized),i=J(e=>e.showMaximize),a=J(e=>e.toggleMaximize);if(!i)return null;let o=e=>{t?.(e),a()};return I(`button`,{"aria-label":r?`Restore`:`Maximize`,...n,"aria-pressed":r,"data-dashfoo":`tabset-maximize`,onClick:o,type:`button`,children:e??I(St,{maximized:r})})},Lt=({children:e,onClick:t,...n})=>{let r=W(e=>e.floatable),i=W(e=>e.dispatch),a=J(e=>e.isMaximized),o=J(e=>e.node),s=qe();if(!r||a)return null;if(!s)return G(`float-no-layer`,`Tabset.FloatButton needs a <Layout.FloatLayer> around the layout (DashfooLayout adds one); the float control is hidden`),null;let c=e=>{t?.(e),i({geometry:Ye(e.currentTarget),tabsetId:o.id,type:`floatTabset`})};return I(`button`,{"aria-label":`Float panel`,...n,"data-dashfoo":`tabset-float`,onClick:c,type:`button`,children:e??I(Ct,{})})},Rt=I(ot,{}),zt=()=>{let e=W(e=>e.draggableTabsets),t=W(e=>e.floatable),n=W(e=>e.renderTabsetToolbar),r=W(e=>e.tabLocation),i=W(e=>e.tabStripEnabled),a=J(e=>e.isMaximized),o=J(e=>e.node),s=J(e=>e.overflowItems.length),c=J(e=>e.showMaximize)||n!==void 0||s>0||t&&!a||e&&!a,l=i?L(jt,{children:[I(Mt,{children:o.children.map(e=>L(_t,{tab:e,children:[I(vt,{}),I(Dt,{}),I(Ot,{})]},e.id))}),c?L(Pt,{children:[I(ut,{}),I(Ft,{}),n?.(o),I(Lt,{}),I(It,{})]}):null]}):null;return r===`bottom`?L(F,{children:[Rt,l]}):L(F,{children:[l,Rt]})},Bt=({node:e})=>I(ht,{node:e,children:I(zt,{})}),Vt=e=>`${e.value}${e.unit}`,Ht=e=>e?.unit===`px`?e.value:void 0,Ut={display:`flex`,flex:1,minHeight:0,minWidth:0},Wt=.01,Gt=(e,t)=>e.reduce((e,n)=>(e[n.id]=(n.weight??1)/t*100,e),{}),Kt=(e,t)=>t.map(t=>e[t.id]??0),qt=(e,t)=>t.reduce((t,n,r)=>(t[n.id]=e[r]??0,t),{}),Jt=(e,t)=>{let n=Object.keys(e),r=Object.keys(t);return n.length===r.length?r.every(n=>Math.abs((e[n]??NaN)-t[n])<=Wt):!1},Yt=(e,t,n)=>{let r=Ht(e.min);if(r!==void 0)return r;if(e.min!==void 0)return;if(e.type===`tabset`)return n;let i=[];for(let r of e.children){let e=Yt(r,t,n);if(e===void 0)return;i.push(e)}if(i.length!==0)return e.orientation===t?i.reduce((e,t)=>e+t,0):Math.max(...i)},Xt=({node:e,renderTabset:t})=>{let n=W(e=>e.dispatch),r=W(e=>e.resizableSplits),i=W(e=>e.tabsetMinSize),a=W(e=>e.snap),o=e.snap??a,s=l(o),c=e.orientation===`row`?`horizontal`:`vertical`,d=e.children.reduce((e,t)=>e+(t.weight??1),0),f=T(()=>Gt(e.children,d),[e.children,d]),p=E(!1),m=E(null),g=E(null),_=E(!1),v=E(null),y=E(!1),b=E(null),[x,S]=D(null),C=e=>{e!==b.current&&(b.current=e,S(e))},O=e=>{let t=g.current;t&&(e?t.dataset.dashfooSnapping=`true`:delete t.dataset.dashfooSnapping)};return w(()=>{let e=m.current;if(!e)return;let t=e.getLayout();if(!(Object.keys(t).length===Object.keys(f).length&&Object.keys(f).every(e=>e in t))||Jt(t,f))return;_.current=!0,e.setLayout(f);let n=requestAnimationFrame(()=>{_.current=!1});return()=>{cancelAnimationFrame(n),_.current=!1}},[f]),I(R,{"data-dashfoo":`row`,disabled:!r,elementRef:g,groupRef:m,onLayoutChange:s?t=>{if(y.current||_.current||!r||o===null||!s)return;let n=v.current;if(n===null)return;let{sizes:i,snapped:a}=u(Kt(t,e.children),n,o);if(C(a?n:null),!a){O(!1);return}O(!0);let c=m.current,l=qt(i,e.children);!c||Jt(t,l)||(y.current=!0,c.setLayout(l),y.current=!1)}:void 0,onLayoutChanged:t=>{if(!p.current){p.current=!0;return}if(_.current)return;let i=v.current;if(v.current=null,C(null),O(!1),!r)return;let a=e.children.map(e=>t[e.id]??e.weight??1);i!==null&&o!==null&&s&&(a=u(a,i,o).sizes),a.some((t,n)=>Math.abs(t-(e.children[n]?.weight??1))>Wt)&&n({rowId:e.id,type:`adjustSplit`,weights:a})},orientation:c,style:Ut,children:e.children.map((n,a)=>{let o=(n.weight??1)/d*100,c=n.min?Vt(n.min):void 0;if(c===void 0){let t=Yt(n,e.orientation,i);c=t===void 0?void 0:`${t}px`}let l=n.max?Vt(n.max):void 0;return L(h,{children:[a>0?I(ne,{"data-dashfoo":`splitter`,"data-dashfoo-snapped":x===a-1?`true`:void 0,disabled:!r,onPointerDown:s&&r?()=>{v.current=a-1}:void 0}):null,I(z,{defaultSize:`${o}%`,id:n.id,maxSize:l,minSize:c,children:n.type===`row`?I(Xt,{node:n,renderTabset:t}):t?.(n)??I(Bt,{node:n})})]},n.id)})},e.id)},Q=e=>e.name??`Panel`,Zt={alignItems:`center`,display:`flex`,flexShrink:0,gap:`0.375rem`,touchAction:`none`},Qt={flex:1,minWidth:0,overflow:`hidden`,textOverflow:`ellipsis`,whiteSpace:`nowrap`},$t={alignItems:`center`,cursor:`pointer`,display:`inline-flex`,flexShrink:0},en={flex:1,minHeight:0,position:`relative`},tn=[{edges:{x:0,y:-1},key:`n`,style:{cursor:`ns-resize`,height:6,insetInline:10,top:-3}},{edges:{x:0,y:1},key:`s`,style:{bottom:-3,cursor:`ns-resize`,height:6,insetInline:10}},{edges:{x:1,y:0},key:`e`,style:{cursor:`ew-resize`,insetBlock:10,right:-3,width:6}},{edges:{x:-1,y:0},key:`w`,style:{cursor:`ew-resize`,insetBlock:10,left:-3,width:6}},{edges:{x:1,y:-1},key:`ne`,style:{cursor:`nesw-resize`,height:14,right:-4,top:-4,width:14}},{edges:{x:-1,y:-1},key:`nw`,style:{cursor:`nwse-resize`,height:14,left:-4,top:-4,width:14}},{edges:{x:1,y:1},key:`se`,style:{bottom:-4,cursor:`nwse-resize`,height:14,right:-4,width:14}},{edges:{x:-1,y:1},key:`sw`,style:{bottom:-4,cursor:`nesw-resize`,height:14,left:-4,width:14}}],nn=new Map(tn.map(e=>[e.key,e.edges])),rn={height:34,width:168},an=({dispatch:e,node:t,onDone:n})=>{let r=E(null),i=E(!1);b(()=>{r.current?.focus(),r.current?.select()},[]);let a=r=>{let i=r.trim();i&&i!==Q(t)&&e({floatId:t.id,name:i,type:`renameFloat`}),n()};return I(`input`,{"aria-label":`Rename ${Q(t)}`,"data-dashfoo":`float-rename`,defaultValue:Q(t),onBlur:e=>{i.current||(i.current=!0,a(e.currentTarget.value))},onKeyDown:e=>{e.key===`Enter`?(i.current=!0,a(e.currentTarget.value)):e.key===`Escape`&&(i.current=!0,n())},onPointerDown:e=>e.stopPropagation(),ref:r,style:Qt,type:`text`})},on=({dispatch:e,node:t,renamable:n})=>{let[r,i]=D(!1);return n&&r?I(an,{dispatch:e,node:t,onDone:()=>i(!1)}):I(`span`,{"data-dashfoo":`float-title`,onDoubleClick:n?()=>i(!0):void 0,style:Qt,title:n?`Double-click to rename`:void 0,children:Q(t)})},sn=({global:e,node:t,onFocus:n,zIndex:r})=>{let i=W(e=>e.dispatch),a=W(e=>e.closableTabs),o=W(e=>e.draggableTabs),s=W(e=>e.editable),c=W(e=>e.renamableTabs),l=W(e=>e.resizableSplits),u=W(e=>e.keepMounted),d=W(e=>e.renderTab),f=W(e=>e.renderTabLabel),p=W(e=>e.renderTabsetToolbar),m=W(e=>e.snap),h=E(null),g=E(null),_=E(t.geometry),v=E(!1),y=e=>{h.current=e},b=()=>{s&&i({floatId:t.id,minimized:!1,type:`setFloatMinimized`})},x=e=>{let n=h.current;if(!n||!s)return;v.current=!1;let r=e.currentTarget.dataset.edge,i=n.offsetParent;g.current={bounds:{height:i?.clientHeight??0,width:i?.clientWidth??0},edges:r?nn.get(r)??null:null,pointerId:e.pointerId,start:t.geometry,startX:e.clientX,startY:e.clientY},_.current=t.geometry},S=e=>{let n=g.current,r=h.current;if(!n||!r||e.pointerId!==n.pointerId)return;let i=e.clientX-n.startX,a=e.clientY-n.startY;if(!v.current){if(Math.hypot(i,a)<=4)return;v.current=!0,r.setPointerCapture(n.pointerId)}let o=n.edges?Xe(n.start,n.edges,i,a):Je({...n.start,left:n.start.left+i,top:n.start.top+a},n.bounds,t.minimized?rn:void 0);_.current=o,r.style.left=`${o.left}px`,r.style.top=`${o.top}px`,t.minimized||(r.style.width=`${o.width}px`,r.style.height=`${o.height}px`)},C=e=>{let n=g.current;if(!(!n||e.pointerId!==n.pointerId)){if(g.current=null,!v.current){t.minimized&&b();return}h.current?.releasePointerCapture(e.pointerId),i({floatId:t.id,geometry:_.current,type:`moveFloat`})}};if(t.minimized)return L(`button`,{"aria-label":`Restore ${Q(t)} panel`,"data-dashfoo":`float-chip`,onKeyDown:e=>{(e.key===`Enter`||e.key===` `)&&(e.preventDefault(),b())},onPointerDown:x,onPointerDownCapture:n,onPointerMove:S,onPointerUp:C,ref:y,style:{left:t.geometry.left,pointerEvents:`auto`,position:`absolute`,top:t.geometry.top,zIndex:r},title:Q(t),type:`button`,children:[I(Ct,{}),I(`span`,{"data-dashfoo":`float-chip-label`,children:Q(t)})]});let w={global:e,layout:t.layout,version:1};return L(`div`,{"data-dashfoo":`float`,onPointerDownCapture:n,onPointerMove:S,onPointerUp:C,ref:y,style:{height:t.geometry.height,left:t.geometry.left,pointerEvents:`auto`,position:`absolute`,top:t.geometry.top,width:t.geometry.width,zIndex:r},children:[L(`div`,{"data-dashfoo":`float-titlebar`,onPointerDown:x,style:s?Zt:{...Zt,cursor:`default`},children:[I(`span`,{"aria-hidden":`true`,"data-dashfoo":`float-grip`,children:I(xt,{})}),I(on,{dispatch:i,node:t,renamable:s}),s&&L(F,{children:[I(`button`,{"aria-label":`Minimize panel`,"data-dashfoo":`float-minimize`,onClick:()=>i({floatId:t.id,minimized:!0,type:`setFloatMinimized`}),onPointerDown:e=>e.stopPropagation(),style:$t,type:`button`,children:I(wt,{})}),I(`button`,{"aria-label":`Dock panel back into the main layout`,"data-dashfoo":`float-dock`,onClick:()=>i({floatId:t.id,type:`dockFloat`}),onPointerDown:e=>e.stopPropagation(),style:$t,type:`button`,children:I(Tt,{})})]})]}),I(`div`,{"data-dashfoo":`float-body`,style:en,children:I(Qe,{closableTabs:a,dispatch:i,draggableTabs:o,draggableTabsets:!1,editable:s,floatable:!1,keepMounted:u,maximizable:!1,model:w,renamableTabs:c,renderTab:d,renderTabLabel:f,renderTabsetToolbar:p,resizableSplits:l,snap:m??void 0,children:I(Ge,{children:I(Xt,{node:t.layout})})})}),s&&tn.map(e=>I(`div`,{"data-dashfoo":`float-resize`,"data-edge":e.key,onPointerDown:x,style:{position:`absolute`,touchAction:`none`,zIndex:1,...e.style}},e.key))]})},cn={inset:0,pointerEvents:`none`,position:`fixed`},ln=({floats:e,global:t})=>{let[n,r]=D(null);return e.length===0?null:I(`div`,{"data-dashfoo":`float-overlay`,style:cn,children:e.map(e=>I(sn,{global:t,node:e,onFocus:()=>r(e.id),zIndex:e.id===n?2:1},e.id))})},$={DragLayer:Ge,FloatLayer:({children:e,floats:t,global:n})=>L(Ke.Provider,{value:!0,children:[e,I(ln,{floats:t,global:n})]}),Root:Qe,Rows:Xt,Tabset:Bt},un=(e,t)=>e===void 0||!t?null:typeof e==`string`?{debounceMs:300,key:e,storage:_e}:{debounceMs:e.debounceMs??300,key:e.key,storage:e.storage??_e},dn=new Set,fn=_((e,t)=>{let{closableTabs:n=!0,components:r,defaultModel:a,draggableTabs:o=!0,draggableTabsets:s=!0,editable:c=!0,factory:l,floatable:u=!1,keepMounted:f=!1,maximizable:p=!0,model:m,onAction:h,onActiveTabsetChange:g,onMaximizedTabsetChange:_,onModelChange:b,persist:x,renamableTabs:C=!0,renderTabLabel:w,renderTabsetToolbar:D,resizableSplits:O=!0,responsive:k,snap:A}=e,j=ve(T(()=>un(x,a!==void 0),[x,a]),a),ee=v((e,t)=>{j.save(e),b?.(e,t)},[b,j]),M=we({defaultModel:j.initialModel??a,model:m,onAction:h,onActiveTabsetChange:g,onMaximizedTabsetChange:_,onModelChange:ee}),N=y(H)!==null;S(t,()=>({addTab:(e,t)=>M.dispatch({index:t.index,location:t.location??`center`,tab:e,targetId:t.targetId,type:`addNode`}),canRedo:M.canRedo,canUndo:M.canUndo,closeTab:e=>M.dispatch({tabId:e,type:`deleteTab`}),dispatch:M.dispatch,dockFloat:e=>M.dispatch({floatId:e,type:`dockFloat`}),floatTab:e=>M.dispatch({tabId:e,type:`floatTab`}),getModel:()=>M.model,maximizeTabset:e=>M.dispatch({tabsetId:e,type:`setMaximizedTabset`}),redo:M.redo,renameTab:(e,t)=>M.dispatch({name:t,tabId:e,type:`renameTab`}),resetLayout:()=>{j.clear(),a!==void 0&&M.setModel(a)},selectTab:(e,t)=>M.dispatch({index:t,tabsetId:e,type:`selectTab`}),undo:M.undo}),[a,j,M]);let te=v(e=>{if(l)return l(e);let t=r?.[e.component];return t?I(t,{node:e}):(r&&!dn.has(e.component)&&(dn.add(e.component),console.warn(`[dashfoo] no component registered for "${e.component}"`)),null)},[r,l]),[P,F]=Se(),L=k!==void 0&&F<=k.maxWidth,R=T(()=>L?d(M.model,k?.orientation):M.model,[L,k?.orientation,M.model]),z=E(L);z.current=L;let ne=v(e=>{z.current&&e.type===`adjustSplit`||M.dispatch(e)},[M]),B=R.maximizedTabsetId?i(R,R.maximizedTabsetId):void 0,V=I($.FloatLayer,{floats:M.model.floats??[],global:M.model.global,children:I($.DragLayer,{children:B?I($.Tabset,{node:B}):I($.Rows,{node:R.layout})})});return I($.Root,{closableTabs:n,dispatch:ne,draggableTabs:L?!1:o,draggableTabsets:L?!1:s,editable:c,floatable:L?!1:u,keepMounted:f,maximizable:p,model:R,renamableTabs:C,renderTab:te,renderTabLabel:w,renderTabsetToolbar:D,resizableSplits:L?!1:O,rootRef:P,snap:A,children:N?V:I(Te,{children:V})})});fn.displayName=`DashfooLayout`;const pn={Badge:e=>I(`span`,{...e,"data-dashfoo":`panel-badge`}),Body:e=>I(`div`,{...e,"data-dashfoo":`panel-body`}),Header:e=>I(`div`,{...e,"data-dashfoo":`panel-header`}),Icon:e=>I(`span`,{...e,"data-dashfoo":`panel-icon`}),Root:e=>I(`div`,{...e,"data-dashfoo":`panel`}),Title:e=>I(`span`,{...e,"data-dashfoo":`panel-title`})},mn={CloseButton:Ot,Content:ot,FloatButton:Lt,Grip:Ft,MaximizeButton:It,OverflowMenu:ut,RenameInput:Dt,Root:ht,Tab:_t,Tablist:Mt,TabStrip:jt,Toolbar:Pt,Trigger:vt};export{Te as DashfooDragProvider,fn as DashfooLayout,$ as Layout,pn as Panel,mn as Tabset,xe as activeBreakpoint,_e as localStorageAdapter,be as matchBreakpoint,ge as memoryStorageAdapter,Se as useContainerWidth,we as useDashfooStore,me as useDragSubject,he as useDropIntent,pe as useExternalTabSource,W as useLayout,ve as usePersistence,Ce as useResponsiveModel,Y as useTab,J as useTabset};
9
9
  //# sourceMappingURL=index.js.map