@dashfoo/react 0.3.0 → 0.4.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
@@ -15,7 +15,7 @@ paint.
15
15
  It builds on three engines:
16
16
 
17
17
  - **[react-resizable-panels](https://github.com/bvaughn/react-resizable-panels)** for splitter resize (the resize adapter is the only file that imports it).
18
- - **[@dnd-kit/dom](https://github.com/clauderic/dnd-kit) 0.4** — the framework-agnostic core (no React bindings) — for drag (the drag adapter is the only file that touches it; pointer-only).
18
+ - **[@dnd-kit/dom](https://github.com/clauderic/dnd-kit) 0.5** — the framework-agnostic core (no React bindings) — for drag (the drag adapter is the only file that touches it; pointer-only).
19
19
  - **[@dashfoo/core](https://www.npmjs.com/package/@dashfoo/core)** for the document: a zod schema, a pure reducer, and the XState machines that drive state and the drag lifecycle.
20
20
 
21
21
  ## Install
@@ -59,27 +59,29 @@ a sized parent and add your CSS (see the [attribute reference](#data-dashfoo-att
59
59
 
60
60
  ## `DashfooLayout` props
61
61
 
62
- | Prop | Type | Default | Description |
63
- | ------------------------- | -------------------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------- |
64
- | `model` | `Dashfoo` | — | Controlled document. When set, the prop is the source of truth. |
65
- | `defaultModel` | `Dashfoo` | — | Uncontrolled initial document. The component owns it from there. |
66
- | `onModelChange` | `(model: Dashfoo, action?: Action) => void` | — | Called after every change with the next model and the action that caused it. |
67
- | `components` | `Record<string, ComponentType<{ node: TabNode }>>` | — | Registry mapping `tab.component` keys to components. |
68
- | `factory` | `(tab: TabNode) => ReactNode` | — | Render override. When provided, it resolves every tab and `components` is ignored. |
69
- | `persist` | `string \| { key; storage?; debounceMs? }` | — | Auto-save the model (uncontrolled mode only). A bare string is a localStorage key. |
70
- | `onAction` | `(action: Action) => Action \| null` | — | Intercept each action before it commits — return it, a replacement, or `null` to veto. |
71
- | `onActiveTabsetChange` | `(id: string \| undefined) => void` | — | Fires when the active tabset changes. |
72
- | `onMaximizedTabsetChange` | `(id: string \| undefined) => void` | — | Fires when a tabset is maximized or restored. |
73
- | `renderTabLabel` | `(tab: TabNode) => ReactNode` | — | Override the tab label (the accessible name stays `tab.name`). |
74
- | `renderTabsetToolbar` | `(tabset: TabsetNode) => ReactNode` | — | Inject custom controls into a tabset's toolbar. |
75
- | `editable` | `boolean` | `true` | `false` renders a static layout: no drag, close, rename, or splitter resize. Tab selection, maximize, and the ref API keep working. |
76
- | `closableTabs` | `boolean` | `true` | Show the per-tab close control. |
77
- | `renamableTabs` | `boolean` | `true` | Allow double-click inline rename. |
78
- | `maximizable` | `boolean` | `true` | Show the tabset maximize/restore control. |
79
- | `draggableTabs` | `boolean` | `true` | Allow individual tabs to be dragged between tabsets. |
80
- | `draggableTabsets` | `boolean` | `true` | Show the grip that drags a whole tabset. |
81
- | `resizableSplits` | `boolean` | `true` | Allow dragging the splitters; `false` disables them in place (gutters keep their size). |
82
- | `keepMounted` | `boolean` | `false` | Keep inactive tab panels mounted (hidden) so their state survives a tab switch. |
62
+ | Prop | Type | Default | Description |
63
+ | ------------------------- | ----------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
64
+ | `model` | `Dashfoo` | — | Controlled document. When set, the prop is the source of truth. |
65
+ | `defaultModel` | `Dashfoo` | — | Uncontrolled initial document. The component owns it from there. |
66
+ | `onModelChange` | `(model: Dashfoo, action?: Action) => void` | — | Called after every change with the next model and the action that caused it. |
67
+ | `components` | `Record<string, ComponentType<{ node: TabNode }>>` | — | Registry mapping `tab.component` keys to components. |
68
+ | `factory` | `(tab: TabNode) => ReactNode` | — | Render override. When provided, it resolves every tab and `components` is ignored. |
69
+ | `persist` | `string \| { key; storage?; debounceMs? }` | — | Auto-save the model (uncontrolled mode only). A bare string is a localStorage key. |
70
+ | `onAction` | `(action: Action) => Action \| null` | — | Intercept each action before it commits — return it, a replacement, or `null` to veto. |
71
+ | `onActiveTabsetChange` | `(id: string \| undefined) => void` | — | Fires when the active tabset changes. |
72
+ | `onMaximizedTabsetChange` | `(id: string \| undefined) => void` | — | Fires when a tabset is maximized or restored. |
73
+ | `renderTabLabel` | `(tab: TabNode) => ReactNode` | — | Override the tab label (the accessible name stays `tab.name`). |
74
+ | `renderTabsetToolbar` | `(tabset: TabsetNode) => ReactNode` | — | Inject custom controls into a tabset's toolbar. |
75
+ | `editable` | `boolean` | `true` | `false` renders a static layout: no drag, close, rename, or splitter resize. Tab selection, maximize, and the ref API keep working. |
76
+ | `closableTabs` | `boolean` | `true` | Show the per-tab close control. |
77
+ | `renamableTabs` | `boolean` | `true` | Allow double-click inline rename. |
78
+ | `maximizable` | `boolean` | `true` | Show the tabset maximize/restore control. |
79
+ | `draggableTabs` | `boolean` | `true` | Allow individual tabs to be dragged between tabsets. |
80
+ | `draggableTabsets` | `boolean` | `true` | Show the grip that drags a whole tabset. |
81
+ | `resizableSplits` | `boolean` | `true` | Allow dragging the splitters; `false` disables them in place (gutters keep their size). |
82
+ | `keepMounted` | `boolean` | `false` | Keep inactive tab panels mounted (hidden) so their state survives a tab switch. |
83
+ | `responsive` | `{ maxWidth: number; orientation? }` | — | At/below `maxWidth` (the layout's own container width) render a stacked column and lock drag + resize. View-only projection — no remount, state preserved. See below. |
84
+ | `snap` | `{ step?: number; divisions?: number \| "panels"; threshold?: number }` | — | Magnetic splitter snapping onto a grid — the union of `step` (multiples of a fixed percent) and `divisions` (even splits: `100/d`, or `"panels"` to divide by the row's panel count, so a 3-panel row snaps to thirds). Within `threshold` percent (default `4`) it snaps and commits on release as one undo step. Off when omitted; replaces `global.snap`; a row overrides via its own `snap` (`{}` disables). Locked off in compact mode. |
83
85
 
84
86
  You must pass either `model` or `defaultModel`. Passing neither throws.
85
87
 
@@ -250,6 +252,31 @@ keyboard access.
250
252
  | `label` | `string` | `""` | The drag preview chip text. |
251
253
  | `disabled` | `boolean` | `false` | Unregisters the source while true. |
252
254
 
255
+ ## Responsive layouts
256
+
257
+ Panels are weight-based, so the tree already scales with its container. To
258
+ _restructure_ on small screens, give `DashfooLayout` a `responsive` prop:
259
+
260
+ ```tsx
261
+ <DashfooLayout defaultModel={model} factory={renderPanel} responsive={{ maxWidth: 720 }} />
262
+ ```
263
+
264
+ At or below `maxWidth` — measured on the layout's own container, not the viewport
265
+ — the layout renders as a single stacked column and **locks every structural
266
+ interaction** (tab/tabset drag, split resize), leaving tap-to-switch and
267
+ maximize. This mirrors VS Code: docking is a desktop interaction, so narrow
268
+ screens get a read-only, navigable view instead of unusable hit targets.
269
+
270
+ The stacked view is a **derived projection** — the model in the store is never
271
+ mutated, so the layout is never remounted and widening past `maxWidth` restores
272
+ the desktop arrangement exactly. Undo history, persistence, selection, and
273
+ mounted panels all survive the breakpoint cross. The theme grows tab hit targets
274
+ to 44px under `@media (pointer: coarse)` so tap-to-switch stays usable.
275
+
276
+ Hand-built layouts (the `Layout.*` primitives) get the same behavior with
277
+ `useContainerWidth` + `stackModel`; for _distinct_ per-breakpoint models, use
278
+ `useResponsiveModel`. Both feed reactive props with no `key`/remount.
279
+
253
280
  ## Persistence
254
281
 
255
282
  The `persist` prop saves an uncontrolled layout and restores it on load. It loads
@@ -285,7 +312,7 @@ in `onModelChange`.
285
312
 
286
313
  The lower-level `usePersistence` load/save primitive (that `persist` is built on)
287
314
  is also exported, for hosts that drive the store directly. See the
288
- [persistence guide](https://docs.dashfoo.dev/persistence) for the storage seam,
315
+ [persistence guide](https://docs.dashfoo.com/persistence) for the storage seam,
289
316
  validation pipeline, and SSR notes.
290
317
 
291
318
  ### Options
@@ -557,7 +584,8 @@ type Persistence;
557
584
  type PersistConfig;
558
585
 
559
586
  // Responsive
560
- useResponsiveModel;
587
+ useContainerWidth; // [ref, width] via ResizeObserver — the hand-built building block
588
+ useResponsiveModel; // per-breakpoint model + lock flags (no remount)
561
589
  matchBreakpoint; // does a breakpoint apply at a given width
562
590
  activeBreakpoint; // first matching breakpoint, else the last (the catch-all)
563
591
  type Breakpoint;
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { Action, Dashfoo, DockLocation, DragSubject, DropIntent, RowNode, TabNode, TabsetNode } from "@dashfoo/core";
2
- import { ComponentProps, ComponentType, ReactNode } from "react";
1
+ import { Action, Dashfoo, DockLocation, DragSubject, DropIntent, Orientation, RowNode, SnapConfig, TabNode, TabsetNode } from "@dashfoo/core";
2
+ import { ComponentProps, ComponentType, ReactNode, Ref } from "react";
3
3
  import { DragDropManager } from "@dnd-kit/dom";
4
4
  //#region src/hooks/persistence.d.ts
5
5
  type StorageAdapter = {
@@ -68,6 +68,11 @@ type DashfooLayoutProps = {
68
68
  renderTabLabel?: (tab: TabNode) => ReactNode;
69
69
  renderTabsetToolbar?: (tabset: TabsetNode) => ReactNode;
70
70
  resizableSplits?: boolean;
71
+ responsive?: {
72
+ maxWidth: number;
73
+ orientation?: Orientation;
74
+ };
75
+ snap?: SnapConfig;
71
76
  };
72
77
  declare const DashfooLayout: import("react").ForwardRefExoticComponent<DashfooLayoutProps & import("react").RefAttributes<DashfooHandle>>;
73
78
  //#endregion
@@ -117,6 +122,8 @@ type LayoutRootProps = Omit<ComponentProps<"div">, "children"> & {
117
122
  renderTabLabel?: (tab: TabNode) => ReactNode;
118
123
  renderTabsetToolbar?: (tabset: TabsetNode) => ReactNode;
119
124
  resizableSplits?: boolean;
125
+ rootRef?: Ref<HTMLDivElement>;
126
+ snap?: SnapConfig;
120
127
  };
121
128
  //#endregion
122
129
  //#region src/components/row-view.d.ts
@@ -152,6 +159,8 @@ declare const Layout: {
152
159
  renderTabLabel,
153
160
  renderTabsetToolbar,
154
161
  resizableSplits,
162
+ rootRef,
163
+ snap,
155
164
  style,
156
165
  ...props
157
166
  }: LayoutRootProps) => import("react").ReactNode;
@@ -325,6 +334,7 @@ type LayoutState = {
325
334
  renderTabLabel: ((tab: TabNode) => ReactNode) | undefined;
326
335
  renderTabsetToolbar: ((tabset: TabsetNode) => ReactNode) | undefined;
327
336
  resizableSplits: boolean;
337
+ snap: SnapConfig | null;
328
338
  splitDock: boolean;
329
339
  tabLocation: "bottom" | "top";
330
340
  tabsetMinSize: number;
@@ -334,6 +344,7 @@ declare const useLayout: <T>(selector: (state: LayoutState) => T) => T;
334
344
  //#endregion
335
345
  //#region src/hooks/responsive.d.ts
336
346
  type Breakpoint = {
347
+ compact?: boolean;
337
348
  id: string;
338
349
  model: Dashfoo;
339
350
  query?: {
@@ -348,11 +359,15 @@ type UseResponsiveModelOptions = {
348
359
  type ResponsiveModel = {
349
360
  breakpoint: string;
350
361
  containerRef: (element: HTMLElement | null) => void;
351
- defaultModel: Dashfoo;
352
- key: string;
362
+ draggableTabs: boolean;
363
+ draggableTabsets: boolean;
364
+ isCompact: boolean;
365
+ model: Dashfoo;
366
+ resizableSplits: boolean;
353
367
  };
354
368
  declare const matchBreakpoint: (breakpoint: Breakpoint, width: number) => boolean;
355
369
  declare const activeBreakpoint: (breakpoints: Array<Breakpoint>, width: number) => Breakpoint;
370
+ declare const useContainerWidth: () => [(element: HTMLElement | null) => void, number];
356
371
  declare const useResponsiveModel: ({
357
372
  breakpoints
358
373
  }: UseResponsiveModelOptions) => ResponsiveModel;
@@ -377,5 +392,5 @@ type UseDashfooStoreOptions = {
377
392
  };
378
393
  declare const useDashfooStore: (options: UseDashfooStoreOptions) => DashfooStore;
379
394
  //#endregion
380
- 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, useDashfooStore, useDragSubject, useDropIntent, useExternalTabSource, useLayout, usePersistence, useResponsiveModel, useTab, useTabset };
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 };
381
396
  //# 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/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,tabNodeSchema as l,toJSON as u,zoneRect as d}from"@dashfoo/core";import{Fragment as f,createContext as p,createElement as m,forwardRef as h,useCallback as g,useContext as _,useEffect as v,useId as y,useImperativeHandle as b,useInsertionEffect as x,useLayoutEffect as S,useMemo as C,useRef as w,useState as T}from"react";import{useActorRef as E,useSelector as D}from"@xstate/react";import{Accessibility as O,DragDropManager as k,Draggable as A,Feedback as ee,PointerSensor as te}from"@dnd-kit/dom";import{createStore as j,useStore as M}from"zustand";import{Fragment as ne,jsx as N,jsxs as P}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)}}},F={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=w(e);v(()=>{n.current=e});let[r]=T(()=>{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}});v(()=>{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=w(e?.key);v(()=>{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=w(null),s=w(null),c=g(()=>{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=g(e=>{let t=n.current;t!==null&&(s.current={key:t.key,storage:t.storage,value:u(e)},o.current!==null&&clearTimeout(o.current),o.current=setTimeout(c,t.debounceMs))},[c]);return v(()=>{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]),{clear:g(()=>{o.current!==null&&(clearTimeout(o.current),o.current=null),s.current=null;let e=n.current;e!==null&&e.storage.removeItem(e.key)},[]),initialModel:r,save:l}},ce=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=E(n,{input:{model:o(f)}}),m=D(p,e=>e.context.history);v(()=>{a!==void 0&&p.send({model:o(a),type:`SET_MODEL`})},[p,a]);let h=a??m.present,_=g((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=g(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)}})();_(n.before,n.after,t)},[p,a,_,c]),b=g(()=>{if(a!==void 0)return;let e=p.getSnapshot().context.history.present;p.send({type:`UNDO`});let t=p.getSnapshot().context.history.present;_(e,t)},[p,a,_]);return{canRedo:()=>e(p.getSnapshot().context.history),canUndo:()=>t(p.getSnapshot().context.history),dispatch:y,model:h,redo:g(()=>{if(a!==void 0)return;let e=p.getSnapshot().context.history.present;p.send({type:`REDO`});let t=p.getSnapshot().context.history.present;_(e,t)},[p,a,_]),setModel:g(e=>{p.send({model:o(e),type:`SET_MODEL`})},[p]),undo:b}},le=(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,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(`
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},ue=()=>new k({plugins:e=>e.filter(e=>e!==O&&e!==ee),sensors:()=>[te.configure({preventActivation:le})]}),I=p(null),L=p(null),R=()=>j(()=>({intent:null,intentOwner:null,subject:null})),de=(e,t)=>e===t||e!==null&&t!==null&&e.index===t.index&&e.location===t.location&&e.targetId===t.targetId,fe=(e,t)=>e===t||e!==null&&t!==null&&e.id===t.id&&e.kind===t.kind,pe=R(),z=p(null),me=()=>{let e=w(null),t=w(null);return{draggableRef:t,elementRef:e,ref:g(n=>{e.current=n,t.current&&(t.current.element=n??void 0)},[])}},B=(e,t,n)=>{let r=_(I),i=_(L),a=r?.manager??i,{draggableRef:o,elementRef:s,ref:c}=me(),{data:l,id:u}=e;return v(()=>{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]),v(()=>{let e=o.current;e&&(e.data={...l,label:n})},[l,o,n]),{ref:c}},he=(e,t=!1,n=``)=>B({data:C(()=>({type:`tab`}),[]),id:e},t,n),ge=(e,t=!1,n=``)=>B({data:C(()=>({tabsetId:e,type:`tabset`}),[e]),id:`grip-${e}`},t,n),_e=e=>{let t=_(I);return{ref:g(n=>{t?.registerTabset(e,n)},[t,e])}},ve=({createTab:e,disabled:t=!1,label:n=``})=>{let r=y(),i=w(e);return v(()=>{i.current=e}),B({data:C(()=>({createTab:()=>i.current(),type:`external`}),[]),id:`external-${r}`},t,n)},V=()=>M(_(z)??pe,e=>e.subject),ye=()=>M(_(z)??pe,e=>e.intent),be=e=>j(()=>e),H=p(null),U=e=>{let t=_(H);if(t===null)throw Error(`dashfoo components must be rendered inside <DashfooLayout> or <Layout.Root>.`);return M(t,e)},xe=(e,t)=>e.x>=t.x&&e.x<=t.x+t.width&&e.y>=t.y&&e.y<=t.y+t.height,Se=(e,t)=>{let n=e.findIndex(e=>t<e.x+e.width/2);return n===-1?e.length:n},Ce=(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}},we=(e,t,n)=>!(e===`grip-${t}`||n.length===1&&n[0]===e),Te=new Set,W=(e,t)=>{Te.has(e)||(Te.add(e),console.warn(`[dashfoo] ${t}`))},Ee={boxSizing:`border-box`,pointerEvents:`none`,position:`fixed`,transition:`var(--dashfoo-dock-transition, left 60ms, top 60ms, width 60ms, height 60ms)`,zIndex:9999},De=e=>({...Ee,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}),Oe=e=>({...De(e),borderRadius:`var(--dashfoo-dock-line-radius, 2px)`}),ke=(e,t)=>[...e.querySelectorAll(`[data-dashfoo="tab-item"]`)].flatMap(e=>e.querySelector(`[data-dashfoo="tab"]`)?.dataset.tabId===t?[]:[e.getBoundingClientRect()]),Ae=({actorRef:e,getTabsetElement:t})=>{let n=D(e,e=>e.context.intent),r=D(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 N(`div`,{"data-dashfoo":`dock-indicator`,style:Oe(Ce(e.getBoundingClientRect(),ke(e,r),n.index??0))})}return N(`div`,{"data-dashfoo":`dock-indicator`,style:De(d(i.getBoundingClientRect(),n.location))})},je={left:0,position:`fixed`,top:0,zIndex:9999},Me=({overlayRef:e,preview:t})=>t?N(`div`,{"data-dashfoo":`drag-preview`,ref:e,style:{...je,transform:`translate(${t.x}px, ${t.y}px)`},children:t.label}):null,Ne=(e,t)=>[...e.querySelectorAll(`[data-dashfoo="tab"]`)].flatMap(e=>e.dataset.tabId===t?[]:[e.getBoundingClientRect()]),Pe=(e,t,n,r)=>{let i=t.querySelector(`[data-dashfoo="tabstrip"]`);if(i&&xe(n,i.getBoundingClientRect()))return{index:Se(Ne(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:Ne(i,r).length,location:o,targetId:e}:{location:o,targetId:e}},G={x:12,y:8},Fe=e=>{let t=e?.data?.label;return typeof t==`string`?t:``},Ie=e=>typeof e==`function`,Le=e=>{let t=e.data;if(t?.type===`tabset`)return{id:String(t.tabsetId),kind:`tabset`};if(t?.type===`external`){if(!Ie(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=l.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`}},Re=({children:e,onCommit:t,splitDock:n})=>{let i=E(r),a=_(H),o=w(new Map),s=w(null),[c,l]=T(null),u=_(L),[d]=T(()=>u?null:ue());x(()=>()=>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=_(z),[m]=T(()=>p??R()),h=y();v(()=>{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}):(!de(r.intent,t)||r.intentOwner!==h)&&m.setState({intent:t,intentOwner:h}),fe(m.getState().subject,n)||m.setState({subject:n})});return()=>{e.unsubscribe()}},[i,h,m]),v(()=>{let e=i.on(`COMMIT`,e=>{if(a?.getState().editable===!1)return;let n=t??a?.getState().dispatch;if(!n){W(`drag-layer-no-commit`,`Layout.DragLayer has neither an onCommit prop nor a <Layout.Root> above it; drops are ignored`);return}n(e.action)});return()=>{e.unsubscribe()}},[i,a,t]);let b=g((e,t)=>{t?o.current.set(e,t):o.current.delete(e)},[]),S=g(e=>o.current.get(e),[]),D=g(e=>{for(let[t,n]of o.current)if(xe(e,n.getBoundingClientRect()))return{element:n,id:t}},[]),O=g((e,t,r,i)=>{if(a?.getState().editable===!1||!we(i,e,[...t.querySelectorAll(`[data-dashfoo="tab"]`)].map(e=>e.dataset.tabId??``)))return null;let o=Pe(e,t,r,i);return!(n??a?.getState().splitDock??!0)&&o.location.startsWith(`split-`)?{location:`center`,targetId:e}:o},[a,n]),k=g(e=>{let t=s.current;t&&(t.style.transform=`translate(${e.x+G.x}px, ${e.y+G.y}px)`)},[]),A=g(e=>{s.current=e},[]);v(()=>{let e=e=>{let t=e.operation.source;if(!t)return;let n=Le(t);if(!n)return;let r=e.operation.position.current;l({label:Fe(t),x:r.x+G.x,y:r.y+G.y}),i.send({subject:n,type:`START`})},t=e=>{let t=e.operation,n=t.position.current;k(n);let r=t.source?String(t.source.id):void 0,a=D(n);i.send({intent:a?O(a.id,a.element,n,r):null,type:`OVER`})},n=e=>{if(l(null),e.canceled){i.send({type:`CANCEL`});return}let t=e.operation,n=t.position.current,r=t.source?String(t.source.id):void 0,a=D(n);a&&i.send({intent:O(a.id,a.element,n,r),type:`OVER`}),i.send({type:`DROP`})},r=f.monitor.addEventListener(`dragstart`,e),a=f.monitor.addEventListener(`dragmove`,t),o=f.monitor.addEventListener(`dragend`,n);return()=>{r(),a(),o()}},[i,f,k,O,D]);let ee=C(()=>({manager:f,registerTabset:b}),[f,b]);return N(I.Provider,{value:ee,children:P(z.Provider,{value:m,children:[e,N(Ae,{actorRef:i,getTabsetElement:S}),N(Me,{overlayRef:A,preview:c})]})})},ze={display:`flex`,height:`100%`,width:`100%`},Be=({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,style:m,...h})=>{let g=c.global,_={closableTabs:a&&t&&g.tabEnableClose!==!1,dispatch:n,draggableTabs:a&&r&&g.tabEnableDrag!==!1,draggableTabsets:a&&i,editable:a,keepMounted:o,maximizable:s&&g.tabSetEnableMaximize!==!1,maximizedTabsetId:c.maximizedTabsetId,renamableTabs:a&&l&&g.tabEnableRename!==!1,renderTab:u,renderTabLabel:d,renderTabsetToolbar:f,resizableSplits:a&&p&&g.enableSplitResize!==!1,splitDock:g.enableSplitDock!==!1,tabLocation:g.tabLocation??`top`,tabsetMinSize:g.tabSetMinSize??320,tabStripEnabled:g.tabSetEnableTabStrip!==!1},[v]=T(()=>be(_));S(()=>{v.setState(_)});let y=g.splitterSize===void 0?{...ze,...m}:{...ze,"--dashfoo-splitter-size":`${g.splitterSize}px`,...m};return N(H.Provider,{value:v,children:N(`div`,{...h,"data-dashfoo":`layout`,style:y,children:e})})},K=(e,t)=>`dashfoo-tab-${e}-${t}`,q=e=>`dashfoo-panel-${e}`,Ve=(e,t,n)=>e?.querySelector(`#${CSS.escape(K(t,n))}`)??null,He=e=>j((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&&W(`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`}),Ve(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&&Ve(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){W(`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`})}})),J=p(null),Y=e=>{let t=_(J);if(t===null)throw Error(`dashfoo Tabset parts must be rendered inside <Tabset.Root>.`);return M(t,e)},Ue=p(null),X=()=>{let e=_(Ue);if(e===null)throw Error(`dashfoo tab parts must be rendered inside <Tabset.Tab>.`);return e},We={flex:1,minHeight:0,overflow:`auto`},Ge=({render:e,tab:t})=>{let n=U(e=>e.renderTab);return e?e(t):n(t)},Ke=({children:e,style:t,...n})=>{let r=Y(e=>e.node),i=Y(e=>e.visualSelected),a=U(e=>e.keepMounted),o={...We,...t};if(a&&r.children.length>0)return r.children.map((t,a)=>m(`div`,{...n,"aria-labelledby":K(r.id,t.id),"data-dashfoo":`tabcontent`,hidden:a!==i||void 0,id:a===i?q(r.id):void 0,key:t.id,role:a===i?`tabpanel`:void 0,style:o,tabIndex:a===i?0:void 0},N(Ge,{render:e,tab:t})));let s=r.children[i];return s?N(`div`,{...n,"aria-labelledby":K(r.id,s.id),"data-dashfoo":`tabcontent`,id:q(r.id),role:`tabpanel`,style:o,tabIndex:0,children:N(Ge,{render:e,tab:s})}):N(`div`,{...n,"data-dashfoo":`tabcontent`,style:o})},qe=()=>P(`svg`,{"aria-hidden":`true`,fill:`currentColor`,height:`10`,viewBox:`0 0 10 10`,width:`10`,children:[N(`circle`,{cx:`2`,cy:`5`,r:`1`}),N(`circle`,{cx:`5`,cy:`5`,r:`1`}),N(`circle`,{cx:`8`,cy:`5`,r:`1`})]}),Je={position:`absolute`,right:0,top:`100%`,zIndex:10},Ye=({items:e,onSelect:t})=>{let[n,r]=T(!1),[i,a]=T(0),o=w(null),s=w(null),c=w([]);v(()=>{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]),v(()=>{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 P(`div`,{"data-dashfoo":`tab-overflow-root`,ref:o,style:{position:`relative`},children:[N(`button`,{"aria-expanded":n,"aria-haspopup":`menu`,"aria-label":`More tabs`,"data-dashfoo":`tab-overflow`,onClick:d,ref:s,type:`button`,children:N(qe,{})}),n?N(`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:Je,tabIndex:-1,children:e.map((e,t)=>N(`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]})},Xe=()=>{let e=Y(e=>e.overflowItems),t=Y(e=>e.selectOverflowTab);return e.length===0?null:N(Ye,{items:e,onSelect:t})},Ze=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]:[]})},Qe=(e,t)=>{let[n,r]=T([]);return v(()=>{let t=()=>{r(t=>{let n=e?Ze(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},$e=(e,t)=>t+1<e?t+1:t-1,et={display:`flex`,flexDirection:`column`,height:`100%`,minHeight:0,minWidth:0,width:`100%`},tt=({children:e,node:t,ref:n,style:r,...i})=>{let a=U(e=>e.closableTabs),o=U(e=>e.dispatch),s=U(e=>e.maximizable),c=U(e=>e.maximizedTabsetId),l=U(e=>e.renamableTabs),u=U(e=>e.tabLocation),{ref:d}=_e(t.id),f=V(),p=w(null),m=c===t.id,h=s&&t.enableMaximize!==!1,g=a&&t.enableClose!==!1,_=l,y=f?.kind===`tab`?t.children.findIndex(e=>e.id===f.id):-1,b=y!==-1&&y===t.selected?$e(t.children.length,y):t.selected,x=t.children[b],E=f?.kind===`tabset`&&f.id===t.id,D={activeTab:x,dispatch:o,isMaximized:m,node:t,showMaximize:h,tabsClosable:g,tabsRenamable:_,visualSelected:b},[O]=T(()=>He(D));S(()=>{O.setState(D)});let k=Qe(M(O,e=>e.tablistElement),t.children.map(e=>`${e.id}:${e.name}`).join(`|`)),A=C(()=>{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 S(()=>{O.setState({overflowItems:A})},[A,O]),v(()=>{if(!O.getState().restoreFocus)return;O.setState({restoreFocus:!1});let e=t.children[t.selected]?.id;e?p.current?.querySelector(`#${CSS.escape(K(t.id,e))}`)?.focus():p.current?.focus()},[t.children,t.selected,t.id,O]),N(J.Provider,{value:O,children:N(`div`,{...i,"data-dashfoo":`tabset`,"data-dragging-source":E||void 0,"data-tab-location":u,ref:e=>{d(e),p.current=e,typeof n==`function`?n(e):n&&(n.current=e)},style:{...et,...r},tabIndex:-1,children:e})})},nt=(e,t)=>{typeof e==`function`?e(t):e&&(e.current=t)},Z=(...e)=>t=>{for(let n of e)nt(n,t)},rt=({children:e,ref:t,tab:n,...r})=>{let i=_(J),a=Y(e=>e.node),o=Y(e=>e.editingTabId===n.id),s=V(),c=s?.kind===`tab`&&s.id===n.id,l=w(null),u=w(!1),d=a.children.findIndex(e=>e.id===n.id);v(()=>{i?.getState().node.children.some(e=>e.id===n.id)===!1&&W(`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]),v(()=>{u.current&&!o&&l.current?.querySelector(`[data-dashfoo="tab"]`)?.focus(),u.current=o},[o]);let f=C(()=>({index:d,tab:n}),[d,n]),p=C(()=>Z(l,t),[t]);return N(Ue.Provider,{value:f,children:N(`span`,{...r,"data-dashfoo":`tab-item`,"data-dragging":c||void 0,ref:p,children:e})})},it=({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=U(e=>e.draggableTabs),m=U(e=>e.renderTabLabel),{ref:h}=he(o.id,!p||o.enableDrag===!1,o.name),g=C(()=>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 N(`button`,{"aria-label":m?o.name:void 0,...i,"aria-controls":q(s.id),"aria-selected":_,"data-dashfoo":`tab`,"data-tab-id":o.id,id:K(s.id,o.id),onClick:y,onDoubleClick:b,ref:g,role:`tab`,tabIndex:_?0:-1,type:`button`,children:e??(m?m(o):o.name)})},at={pointerEvents:`none`},Q=({children:e})=>N(`svg`,{"aria-hidden":`true`,fill:`none`,height:`12`,stroke:`currentColor`,strokeLinecap:`round`,strokeLinejoin:`round`,strokeWidth:`2`,style:at,viewBox:`0 0 24 24`,width:`12`,children:e}),ot=()=>P(Q,{children:[N(`path`,{d:`M18 6 6 18`}),N(`path`,{d:`m6 6 12 12`})]}),st=()=>P(Q,{children:[N(`circle`,{cx:`12`,cy:`5`,r:`1`}),N(`circle`,{cx:`19`,cy:`5`,r:`1`}),N(`circle`,{cx:`5`,cy:`5`,r:`1`}),N(`circle`,{cx:`12`,cy:`12`,r:`1`}),N(`circle`,{cx:`19`,cy:`12`,r:`1`}),N(`circle`,{cx:`5`,cy:`12`,r:`1`}),N(`circle`,{cx:`12`,cy:`19`,r:`1`}),N(`circle`,{cx:`19`,cy:`19`,r:`1`}),N(`circle`,{cx:`5`,cy:`19`,r:`1`})]}),ct=({maximized:e})=>e?P(Q,{children:[N(`path`,{d:`m14 10 7-7`}),N(`path`,{d:`M20 10h-6V4`}),N(`path`,{d:`m3 21 7-7`}),N(`path`,{d:`M4 14h6v6`})]}):P(Q,{children:[N(`path`,{d:`M15 3h6v6`}),N(`path`,{d:`m21 3-7 7`}),N(`path`,{d:`m3 21 7-7`}),N(`path`,{d:`M9 21H3v-6`})]}),lt=({defaultValue:e,onBlur:t,onKeyDown:n,ref:r,...i})=>{let{tab:a}=X(),o=Y(e=>e.cancelRename),s=Y(e=>e.commitRename),c=w(null),l=w(!1);v(()=>{c.current?.focus(),c.current?.select()},[]);let u=e=>{n?.(e),e.key===`Enter`?(l.current=!0,s(a.id,e.currentTarget.value)):e.key===`Escape`&&(l.current=!0,o())},d=e=>{t?.(e),!l.current&&(l.current=!0,s(a.id,e.currentTarget.value))};return N(`input`,{"aria-label":`Rename ${a.name}`,...i,"data-dashfoo":`tab-rename`,defaultValue:e??a.name,onBlur:d,onKeyDown:u,ref:e=>{c.current=e,typeof r==`function`?r(e):r&&(r.current=e)},type:`text`})},ut=e=>{let{tab:t}=X(),n=Y(e=>e.editingTabId===t.id),r=Y(e=>e.registerRenameInput);return v(()=>r(),[r]),n?N(lt,{...e}):null},dt=({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 N(`button`,{"aria-label":`Close ${i.name}`,...n,"data-dashfoo":`tab-close`,onClick:l,tabIndex:r===c?0:-1,type:`button`,children:e??N(ot,{})})},ft={display:`flex`,flexShrink:0},pt={display:`flex`,minWidth:0,overflowX:`auto`},mt=({style:e,...t})=>N(`div`,{...t,"data-dashfoo":`tabstrip`,style:{...ft,...e}}),ht=({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=C(()=>Z(a,t),[a,t]);return N(`div`,{"aria-label":i.name??`Tabs`,...r,"aria-orientation":`horizontal`,"data-dashfoo":`tablist`,onKeyDown:s,ref:c,role:`tablist`,style:{...pt,...n},tabIndex:-1})},gt={alignItems:`center`,display:`flex`,flexShrink:0,marginInlineStart:`auto`},_t=({style:e,...t})=>N(`div`,{...t,"data-dashfoo":`tabset-toolbar`,style:{...gt,...e}}),vt=({children:e,ref:t,...n})=>{let r=Y(e=>e.activeTab?.name??``),i=Y(e=>e.isMaximized),a=Y(e=>e.node),o=!U(e=>e.draggableTabsets)||i,{ref:s}=ge(a.id,o,r),c=C(()=>Z(s,t),[s,t]);return o?null:N(`button`,{"aria-label":`Move tabset`,...n,"data-dashfoo":`tabset-grip`,ref:c,type:`button`,children:e??N(st,{})})},yt=({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 N(`button`,{"aria-label":r?`Restore`:`Maximize`,...n,"aria-pressed":r,"data-dashfoo":`tabset-maximize`,onClick:o,type:`button`,children:e??N(ct,{maximized:r})})},bt=()=>{let e=U(e=>e.draggableTabsets),t=U(e=>e.renderTabsetToolbar),n=U(e=>e.tabLocation),r=U(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?P(mt,{children:[N(ht,{children:a.children.map(e=>P(rt,{tab:e,children:[N(it,{}),N(ut,{}),N(dt,{})]},e.id))}),s?P(_t,{children:[N(Xe,{}),N(vt,{}),t?.(a),N(yt,{})]}):null]}):null,l=N(Ke,{});return n===`bottom`?P(ne,{children:[l,c]}):P(ne,{children:[c,l]})},xt=({node:e})=>N(tt,{node:e,children:N(bt,{})}),St=e=>`${e.value}${e.unit}`,Ct=e=>e?.unit===`px`?e.value:void 0,wt={display:`flex`,flex:1,minHeight:0,minWidth:0},Tt=.01,Et=(e,t)=>e.reduce((e,n)=>(e[n.id]=(n.weight??1)/t*100,e),{}),Dt=(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])<=Tt):!1},Ot=(e,t,n)=>{let r=Ct(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=Ot(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)},kt=({node:e,renderTabset:t})=>{let n=U(e=>e.dispatch),r=U(e=>e.resizableSplits),i=U(e=>e.tabsetMinSize),a=e.orientation===`row`?`horizontal`:`vertical`,o=e.children.reduce((e,t)=>e+(t.weight??1),0),s=C(()=>Et(e.children,o),[e.children,o]),c=w(!1),l=w(null),u=w(!1);return S(()=>{let e=l.current;if(!e||Dt(e.getLayout(),s))return;u.current=!0,e.setLayout(s);let t=requestAnimationFrame(()=>{u.current=!1});return()=>{cancelAnimationFrame(t),u.current=!1}},[s]),N(re,{"data-dashfoo":`row`,disabled:!r,groupRef:l,onLayoutChanged:t=>{if(!c.current){c.current=!0;return}if(u.current||!r)return;let i=e.children.map(e=>t[e.id]??e.weight??1);i.some((t,n)=>Math.abs(t-(e.children[n]?.weight??1))>Tt)&&n({rowId:e.id,type:`adjustSplit`,weights:i})},orientation:a,style:wt,children:e.children.map((n,a)=>{let s=(n.weight??1)/o*100,c=n.min?St(n.min):void 0;if(c===void 0){let t=Ot(n,e.orientation,i);c=t===void 0?void 0:`${t}px`}let l=n.max?St(n.max):void 0;return P(f,{children:[a>0?N(ae,{"data-dashfoo":`splitter`,disabled:!r}):null,N(ie,{defaultSize:`${s}%`,id:n.id,maxSize:l,minSize:c,children:n.type===`row`?N(kt,{node:n,renderTabset:t}):t?.(n)??N(xt,{node:n})})]},n.id)})},e.children.map(e=>e.id).join(`|`))},$={DragLayer:Re,Root:Be,Rows:kt,Tabset:xt},At=(e,t)=>e===void 0||!t?null:typeof e==`string`?{debounceMs:300,key:e,storage:F}:{debounceMs:e.debounceMs??300,key:e.key,storage:e.storage??F},jt=new Set,Mt=h((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:d=!0,model:f,onAction:p,onActiveTabsetChange:m,onMaximizedTabsetChange:h,onModelChange:_,persist:v,renamableTabs:y=!0,renderTabLabel:x,renderTabsetToolbar:S,resizableSplits:w=!0}=e,T=se(C(()=>At(v,a!==void 0),[v,a]),a),E=g((e,t)=>{T.save(e),_?.(e,t)},[_,T]),D=ce({defaultModel:T.initialModel??a,model:f,onAction:p,onActiveTabsetChange:m,onMaximizedTabsetChange:h,onModelChange:E});b(t,()=>({addTab:(e,t)=>D.dispatch({index:t.index,location:t.location??`center`,tab:e,targetId:t.targetId,type:`addNode`}),canRedo:D.canRedo,canUndo:D.canUndo,closeTab:e=>D.dispatch({tabId:e,type:`deleteTab`}),dispatch:D.dispatch,getModel:()=>D.model,maximizeTabset:e=>D.dispatch({tabsetId:e,type:`setMaximizedTabset`}),redo:D.redo,renameTab:(e,t)=>D.dispatch({name:t,tabId:e,type:`renameTab`}),resetLayout:()=>{T.clear(),a!==void 0&&D.setModel(a)},selectTab:(e,t)=>D.dispatch({index:t,tabsetId:e,type:`selectTab`}),undo:D.undo}),[a,T,D]);let O=g(e=>{if(l)return l(e);let t=r?.[e.component];return t?N(t,{node:e}):(r&&!jt.has(e.component)&&(jt.add(e.component),console.warn(`[dashfoo] no component registered for "${e.component}"`)),null)},[r,l]),k=D.model.maximizedTabsetId?i(D.model,D.model.maximizedTabsetId):void 0;return N($.Root,{closableTabs:n,dispatch:D.dispatch,draggableTabs:o,draggableTabsets:s,editable:c,keepMounted:u,maximizable:d,model:D.model,renamableTabs:y,renderTab:O,renderTabLabel:x,renderTabsetToolbar:S,resizableSplits:w,children:N($.DragLayer,{children:k?N($.Tabset,{node:k}):N($.Rows,{node:D.model.layout})})})});Mt.displayName=`DashfooLayout`;const Nt=({children:e})=>{let[t]=T(ue);x(()=>()=>t.destroy(),[t]);let[n]=T(R);return N(L.Provider,{value:t,children:N(z.Provider,{value:n,children:e})})},Pt={Badge:e=>N(`span`,{...e,"data-dashfoo":`panel-badge`}),Body:e=>N(`div`,{...e,"data-dashfoo":`panel-body`}),Header:e=>N(`div`,{...e,"data-dashfoo":`panel-header`}),Icon:e=>N(`span`,{...e,"data-dashfoo":`panel-icon`}),Root:e=>N(`div`,{...e,"data-dashfoo":`panel`}),Title:e=>N(`span`,{...e,"data-dashfoo":`panel-title`})},Ft={CloseButton:dt,Content:Ke,Grip:vt,MaximizeButton:yt,OverflowMenu:Xe,RenameInput:ut,Root:tt,Tab:rt,Tablist:ht,TabStrip:mt,Toolbar:_t,Trigger:it},It=()=>typeof window<`u`&&typeof window.matchMedia==`function`,Lt=(e,t)=>{let{query:n}=e;return n?`maxWidth`in n?t<=n.maxWidth:It()&&window.matchMedia(n.media).matches:!0},Rt=(e,t)=>{let n=e.at(-1);if(!n)throw Error(`useResponsiveModel requires at least one breakpoint.`);return e.find(e=>Lt(e,t))??n},zt=({breakpoints:e})=>{let[t,n]=T(1/0),[,r]=T(0),i=w(null),a=g(e=>{if(i.current?.disconnect(),!e)return;let t=new ResizeObserver(e=>{let t=e[0];t&&n(t.contentRect.width)});t.observe(e),i.current=t},[]);v(()=>()=>{i.current?.disconnect()},[]),v(()=>{if(!It())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 o=Rt(e,t);return{breakpoint:o.id,containerRef:a,defaultModel:o.model,key:o.id}};export{Nt as DashfooDragProvider,Mt as DashfooLayout,$ as Layout,Pt as Panel,Ft as Tabset,Rt as activeBreakpoint,F as localStorageAdapter,Lt as matchBreakpoint,oe as memoryStorageAdapter,ce as useDashfooStore,V as useDragSubject,ye as useDropIntent,ve as useExternalTabSource,U as useLayout,se as usePersistence,zt as useResponsiveModel,X as useTab,Y as useTabset};
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};
9
9
  //# sourceMappingURL=index.js.map