react-zeugma 2.3.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import React, { ReactNode } from 'react';
1
+ import React, { Dispatch, SetStateAction, RefObject, ReactNode } from 'react';
2
2
 
3
3
  type SplitDirection = 'row' | 'column';
4
4
  interface SplitNode {
@@ -10,53 +10,39 @@ interface SplitNode {
10
10
  }
11
11
  interface PaneNode {
12
12
  type: 'pane';
13
- paneId: string;
13
+ id: string;
14
+ tabs: string[];
15
+ activeTabId: string;
14
16
  locked?: boolean;
15
- metadata?: Record<string, unknown>;
17
+ tabsMetadata?: Record<string, Record<string, unknown>>;
16
18
  }
17
19
  type TreeNode = SplitNode | PaneNode;
18
20
 
19
- interface ZeugmaClassNames {
20
- /** CSS class applied to the outer container div of each `<Pane>`. */
21
- pane?: string;
22
- /** CSS class applied to the pane container when locked. */
23
- paneLocked?: string;
24
- /** CSS class applied to drop zone indicators when hovering over layout edges to split a pane. */
25
- dropPreview?: string;
26
- /** CSS class applied to the drop zone indicator when hovering over the center of a pane to swap. */
27
- swapPreview?: string;
28
- /** CSS class applied to the custom cursor-following drag preview portal wrapper. */
29
- dragOverlay?: string;
30
- /** CSS class applied to the drag-to-resize split bar handles. */
31
- resizer?: string;
32
- /** CSS class applied to the background dismiss zone indicator during a drag-out dismiss gesture. */
33
- dismissPreview?: string;
34
- /** CSS class applied to root container when dashboard is globally locked. */
35
- dashboardLocked?: string;
36
- /** CSS class applied to drop zone indicator when hovering over a locked pane. */
37
- lockedPreview?: string;
38
- }
39
- interface ZeugmaProps {
40
- /** The layout tree model (TreeNode) defining pane organization and split percentages. Set to null for empty layout. */
41
- layout: TreeNode | null;
21
+ interface UseZeugmaOptions {
22
+ /** Initial layout tree model defining pane organization and split percentages. Set to null for empty layout. */
23
+ initialLayout: TreeNode | null;
42
24
  /** Callback triggered when the layout changes via drag-and-drop actions, splits, swaps, or resizes. */
43
- onChange: (newLayout: TreeNode | null) => void;
44
- /** Render function mapping unique pane IDs to React elements. Usually renders a <Pane> wrapper. */
45
- renderPane: (paneId: string) => ReactNode;
46
- /** Custom overlay renderer function used to customize the cursor-following drag preview for an active pane. */
47
- renderDragOverlay?: (activeId: string) => ReactNode;
48
- /** Optional CSS class name mapping overrides for custom styles of components like panes, drop/swap previews, overlays, etc. */
49
- classNames?: ZeugmaClassNames;
25
+ onChange?: (newLayout: TreeNode | null) => void;
50
26
  /** The ID of the pane that is currently taking up the full dashboard area. Null if no pane is fullscreen. */
51
27
  fullscreenPaneId?: string | null;
52
28
  /** Callback triggered when a pane is toggled to/from fullscreen mode. Passes the active fullscreen paneId or null. */
53
29
  onFullscreenChange?: (paneId: string | null) => void;
54
- /** Callback triggered when a pane is removed from the dashboard layout tree. */
55
- onRemove?: (paneId: string) => void;
30
+ /** Whether the layout is locked. When locked, resizing, dragging, and dropping are disabled. */
31
+ locked?: boolean;
56
32
  /** Minimum pixel distance that a user must drag a pane handle before dragging triggers. Defaults to 8. */
57
33
  dragActivationDistance?: number;
58
34
  /** Threshold value in pixels for snapping layout resizing handles to adjacent edges. Defaults to 8. */
59
35
  snapThreshold?: number;
36
+ /** Minimum split percentage allowed when resizing split panes. Defaults to 5. */
37
+ minSplitPercentage?: number;
38
+ /** Maximum split percentage allowed when resizing split panes. Defaults to 95. */
39
+ maxSplitPercentage?: number;
40
+ /** Whether dragging a pane far enough outside the container triggers a drag-out/dismiss action. Defaults to false. */
41
+ enableDragToDismiss?: boolean;
42
+ /** The threshold in pixels beyond the container boundaries required to activate the drag-out/dismiss action. Defaults to 60. */
43
+ dismissThreshold?: number;
44
+ /** Callback triggered when a pane is removed from the dashboard layout tree. */
45
+ onRemove?: (paneId: string) => void;
60
46
  /** Callback triggered when dragging starts for a pane. */
61
47
  onDragStart?: (activeId: string) => void;
62
48
  /** Callback triggered when dragging ends, providing details on target pane and drop action (split or swap). */
@@ -71,84 +57,84 @@ interface ZeugmaProps {
71
57
  onResize?: (currentNode: SplitNode, percentage: number) => void;
72
58
  /** Callback triggered when the user stops dragging a resizing handle. Passes the final split percentage. */
73
59
  onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
74
- /** Minimum split percentage allowed when resizing split panes. Defaults to 5. */
75
- minSplitPercentage?: number;
76
- /** Maximum split percentage allowed when resizing split panes. Defaults to 95. */
77
- maxSplitPercentage?: number;
78
- /** Whether dragging a pane far enough outside the container triggers a drag-out/dismiss action. Defaults to false. */
79
- enableDragToDismiss?: boolean;
80
- /** The threshold in pixels beyond the container boundaries required to activate the drag-out/dismiss action. */
81
- dismissThreshold?: number;
82
- /** Callback triggered when the drag-out/dismiss intent changes (active pane ID or null when drag returns inside bounds). */
60
+ /** Callback triggered when the drag-out/dismiss intent changes. */
83
61
  onDismissIntentChange?: (paneId: string | null) => void;
84
- /** Whether the layout is locked. When locked, resizing, dragging, and dropping are disabled. */
85
- locked?: boolean;
86
- /** Child nodes nested inside the Zeugma context, usually containing a <PaneTree> or similar layout viewer. */
87
- children: ReactNode;
88
62
  }
89
- /**
90
- * State context — holds reactive values that change during runtime.
91
- * All consumers of this context will re-render when any of these values change.
92
- */
93
- interface ZeugmaStateValue {
94
- /** The current active layout tree structure, or null if empty. */
63
+ interface ZeugmaController {
95
64
  layout: TreeNode | null;
96
- /** Callback to update the layout tree. */
97
- onLayoutChange: (newLayout: TreeNode | null, localOnly?: boolean) => void;
98
- /** Renders the inner content of a pane given its unique ID. */
99
- renderPane: (paneId: string) => ReactNode;
100
- /** The ID of the pane currently being dragged, or null. */
65
+ setLayout: Dispatch<SetStateAction<TreeNode | null>>;
66
+ fullscreenPaneId: string | null;
67
+ setFullscreenPaneId: (paneId: string | null) => void;
68
+ locked: boolean;
69
+ setLocked: Dispatch<SetStateAction<boolean>>;
101
70
  activeId: string | null;
102
- /** The ID of the pane currently targeted for dismiss/drag-out, or null. */
71
+ setActiveId: Dispatch<SetStateAction<string | null>>;
72
+ activeType: 'pane' | 'tab' | null;
73
+ setActiveType: Dispatch<SetStateAction<'pane' | 'tab' | null>>;
103
74
  dismissIntentId: string | null;
104
- /** Ref setter to measure and track the dashboard root container element. */
75
+ setDismissIntentId: Dispatch<SetStateAction<string | null>>;
76
+ containerRef: RefObject<HTMLElement | null>;
105
77
  setContainerRef: (element: HTMLElement | null) => void;
106
- /** The ID of the pane currently zoomed to fullscreen, or null. */
107
- fullscreenPaneId: string | null;
108
- /** Normalized or overridden CSS classes for custom layout styling. */
109
- classNames: ZeugmaClassNames;
110
- /** Callback triggered when a pane is closed/removed from the dashboard. */
78
+ dragActivationDistance: number;
79
+ snapThreshold: number;
80
+ minSplitPercentage: number;
81
+ maxSplitPercentage: number;
82
+ enableDragToDismiss: boolean;
83
+ dismissThreshold: number;
111
84
  onRemove?: (paneId: string) => void;
112
- /** Callback triggered to toggle fullscreen status for a pane. */
113
- onFullscreenChange?: (paneId: string | null) => void;
114
- /** Threshold in pixels to snap layout resizers to adjacent edges. */
115
- snapThreshold?: number;
116
- /** Callback triggered when a split pane starts being resized. */
85
+ onDragStart?: (activeId: string) => void;
86
+ onDragEnd?: (activeId: string, overId: string | null, dropAction: {
87
+ type: 'split' | 'swap';
88
+ direction?: SplitDirection;
89
+ position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
90
+ } | null) => void;
117
91
  onResizeStart?: (currentNode: SplitNode) => void;
118
- /** Callback triggered continuously during a split pane resize. */
119
92
  onResize?: (currentNode: SplitNode, percentage: number) => void;
120
- /** Callback triggered when a split pane resize action is completed. */
121
93
  onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
122
- /** Minimum split percentage allowed when resizing. */
123
- minSplitPercentage?: number;
124
- /** Maximum split percentage allowed when resizing. */
125
- maxSplitPercentage?: number;
126
- /** Whether the layout is globally locked. */
127
- locked: boolean;
128
- }
129
- /**
130
- * Actions context — holds stable dispatch functions with permanent identity.
131
- * Consumers of only this context will never re-render from layout/drag state changes.
132
- */
133
- interface ZeugmaActionsValue {
134
- /** Removes the specified pane from the layout tree and collapses its parent split. */
94
+ onDismissIntentChange?: (paneId: string | null) => void;
135
95
  removePane: (paneId: string) => void;
136
- /** Appends/inserts a pane at the bottom-rightmost leaf of the layout tree. */
137
96
  addPane: (paneId: string) => void;
138
- /** Swaps the positions of two panes in the layout tree. */
139
- swapPanes: (paneIdA: string, paneIdB: string) => void;
140
- /** Splits a target pane with a new pane in the specified direction and side. */
141
97
  splitPane: (targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string) => void;
142
- /** Updates the split percentage of a specific split branch node. */
143
98
  updateSplitPercentage: (currentNode: SplitNode, percentage: number) => void;
144
- /** Stable callback to update metadata for a specific pane. */
145
- updatePaneMetadata: (paneId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
146
- /** Stable callback to update the locked status of a specific pane in the layout tree. */
99
+ updateTabMetadata: (tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
147
100
  updatePaneLock: (paneId: string, locked: boolean) => void;
101
+ selectTab: (paneId: string, tabId: string) => void;
102
+ mergeTab: (draggedTabId: string, targetPaneId: string) => void;
103
+ moveTab: (draggedTabId: string, targetTabId: string, position?: 'before' | 'after') => void;
104
+ removeTab: (tabId: string) => void;
105
+ }
106
+ interface ZeugmaClassNames {
107
+ /** CSS class applied to the outer container div of each `<Pane>`. */
108
+ pane?: string;
109
+ /** CSS class applied to the pane container when locked. */
110
+ paneLocked?: string;
111
+ /** CSS class applied to drop zone indicators when hovering over layout edges to split a pane. */
112
+ dropPreview?: string;
113
+ /** CSS class applied to the custom cursor-following drag preview portal wrapper. */
114
+ dragOverlay?: string;
115
+ /** CSS class applied to the drag-to-resize split bar handles. */
116
+ resizer?: string;
117
+ /** CSS class applied to the background dismiss zone indicator during a drag-out dismiss gesture. */
118
+ dismissPreview?: string;
119
+ /** CSS class applied to root container when dashboard is globally locked. */
120
+ dashboardLocked?: string;
121
+ /** CSS class applied to drop zone indicator when hovering over a locked pane. */
122
+ lockedPreview?: string;
123
+ }
124
+ interface ZeugmaProps extends ZeugmaController {
125
+ /** Render function mapping unique pane IDs to React elements. Usually renders a <Pane> wrapper. */
126
+ renderPane: (paneId: string) => ReactNode;
127
+ /** Custom overlay renderer function used to customize the cursor-following drag preview for an active pane or tab. */
128
+ renderDragOverlay?: (activeId: string, type: 'pane' | 'tab') => ReactNode;
129
+ /** Optional CSS class name mapping overrides for custom styles of components like panes, drop/swap previews, overlays, etc. */
130
+ classNames?: ZeugmaClassNames;
131
+ /** Render function mapping tab IDs to React elements. Used to render tab widgets inside portals. */
132
+ renderWidget?: (tabId: string) => ReactNode;
133
+ /** Child nodes nested inside the Zeugma context, usually containing a <PaneTree> or similar layout viewer. */
134
+ children: ReactNode;
148
135
  }
149
136
 
150
- declare const useZeugmaState: () => ZeugmaStateValue;
151
- declare const useZeugmaActions: () => ZeugmaActionsValue;
137
+ declare function useZeugma(options: UseZeugmaOptions): ZeugmaController;
152
138
 
153
139
  declare const Zeugma: React.FC<ZeugmaProps>;
154
140
 
@@ -213,14 +199,28 @@ interface PaneRenderProps {
213
199
  isFullscreen: boolean;
214
200
  /** Toggles the pane to and from fullscreen/zoomed mode. */
215
201
  toggleFullscreen: () => void;
216
- /** Closes and removes the pane from the layout tree. */
202
+ /** Closes and removes the active tab from the layout tree. */
217
203
  remove: () => void;
218
- /** The metadata values associated with this pane, or undefined. */
204
+ /** The metadata values associated with the active tab, or undefined. */
219
205
  metadata: Record<string, unknown> | undefined;
220
- /** Updates the metadata of this pane using an updater function. */
206
+ /** Updates the metadata of the active tab using an updater function. */
221
207
  updateMetadata: (updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
222
208
  /** True if this specific pane or the dashboard globally is locked. */
223
209
  locked: boolean;
210
+ /** The array of tab IDs in this pane. */
211
+ tabs: string[];
212
+ /** The currently active tab ID. */
213
+ activeTabId: string;
214
+ /** Selects a specific tab to make it active. */
215
+ selectTab: (tabId: string) => void;
216
+ /** Removes/closes a specific tab. */
217
+ removeTab: (tabId: string) => void;
218
+ /** The metadata values associated with all tabs in this pane. */
219
+ tabsMetadata: Record<string, Record<string, unknown>> | undefined;
220
+ /** Updates the metadata of a specific tab. */
221
+ updateTabMetadata: (tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
222
+ /** Renders the target placeholder element for the currently active tab in the pane. */
223
+ renderActiveTab: () => ReactNode;
224
224
  }
225
225
 
226
226
  interface PaneProps {
@@ -237,7 +237,7 @@ declare const Pane: React.FC<PaneProps>;
237
237
 
238
238
  interface DragHandleProps {
239
239
  /** The children elements that will trigger dragging when held and dragged. */
240
- children: React.ReactNode;
240
+ children?: React.ReactNode;
241
241
  /** Custom CSS class applied to the drag handle element. */
242
242
  className?: string;
243
243
  /** Optional inline CSS styles applied to the drag handle. */
@@ -245,22 +245,41 @@ interface DragHandleProps {
245
245
  }
246
246
  declare const DragHandle: React.FC<DragHandleProps>;
247
247
 
248
+ interface TabRenderProps {
249
+ isDragging: boolean;
250
+ isOver: boolean;
251
+ }
252
+ interface TabProps {
253
+ /** The unique ID of the tab, which corresponds to the pane/widget ID. */
254
+ id: string;
255
+ /** Whether dragging is locked on this tab. */
256
+ locked?: boolean;
257
+ /** Render prop child function. */
258
+ children: (props: TabRenderProps) => React.ReactNode;
259
+ /** Custom CSS class applied to the tab wrapper. */
260
+ className?: string;
261
+ /** Custom inline CSS style applied to the tab wrapper. */
262
+ style?: React.CSSProperties;
263
+ }
264
+ declare const Tab: React.FC<TabProps>;
265
+
248
266
  declare const DEFAULT_SNAP_THRESHOLD = 8;
249
267
  declare const DEFAULT_DRAG_ACTIVATION_DISTANCE = 8;
250
268
  declare const DEFAULT_RESIZER_SIZE = 4;
251
269
 
270
+ declare function generateUniqueId(): string;
252
271
  /**
253
- * Tree Helper: Remove a pane and consolidate the tree structure.
272
+ * Tree Helper: Remove a pane container and consolidate the tree structure.
254
273
  */
255
- declare function removePane(tree: TreeNode | null, idToRemove: string): TreeNode | null;
274
+ declare function removePane(tree: TreeNode | null, paneId: string): TreeNode | null;
256
275
  /**
257
- * Tree Helper: Insert a pane by splitting an existing target node.
276
+ * Tree Helper: Remove a tab from a pane and consolidate the tree structure if no tabs remain.
258
277
  */
259
- declare function splitPane(tree: TreeNode | null, targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string | PaneNode): TreeNode | null;
278
+ declare function removeTab(tree: TreeNode | null, tabId: string): TreeNode | null;
260
279
  /**
261
- * Tree Helper: Swap the position of two panes in the tree structure.
280
+ * Tree Helper: Insert a pane by splitting an existing target node.
262
281
  */
263
- declare function swapPanes(tree: TreeNode | null, idA: string, idB: string): TreeNode | null;
282
+ declare function splitPane(tree: TreeNode | null, targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string | PaneNode): TreeNode | null;
264
283
  /**
265
284
  * Tree Helper: Add a pane by recursively splitting the rightmost/bottommost pane in the tree.
266
285
  */
@@ -270,17 +289,54 @@ declare function addPane(tree: TreeNode | null, paneToAdd: string): TreeNode;
270
289
  */
271
290
  declare function updateSplitPercentage(tree: TreeNode | null, target: SplitNode, newPercentage: number): TreeNode | null;
272
291
  /**
273
- * Find a PaneNode by its paneId.
292
+ * Find a PaneNode by its ID or by any of its tab IDs.
274
293
  */
275
294
  declare function findPane(tree: TreeNode | null, paneId: string): PaneNode | null;
276
295
  /**
277
- * Update metadata on a specific pane node using an updater function.
296
+ * Update metadata on a specific tab node using an updater function.
278
297
  */
279
- declare function updatePaneMetadata(tree: TreeNode | null, paneId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined): TreeNode | null;
298
+ declare function updateTabMetadata(tree: TreeNode | null, tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined): TreeNode | null;
280
299
  /**
281
300
  * Update the locked status on a specific pane node in the layout tree.
282
301
  */
283
302
  declare function updatePaneLock(tree: TreeNode | null, paneId: string, locked: boolean): TreeNode | null;
303
+ /**
304
+ * Tree Helper: Activate a tab within a pane.
305
+ */
306
+ declare function selectTab(tree: TreeNode | null, paneId: string, tabId: string): TreeNode | null;
307
+ /**
308
+ * Tree Helper: Merge a tab into a target pane node.
309
+ */
310
+ declare function mergeTab(tree: TreeNode | null, draggedTabId: string, targetPaneId: string): TreeNode | null;
311
+ /**
312
+ * Tree Helper: Move/reorder a tab inside or to a target pane next to a target tab.
313
+ */
314
+ declare function moveTab(tree: TreeNode | null, draggedTabId: string, targetTabId: string, position?: 'before' | 'after'): TreeNode | null;
315
+ interface ComputedPane {
316
+ paneId: string;
317
+ left: number;
318
+ top: number;
319
+ width: number;
320
+ height: number;
321
+ node: PaneNode;
322
+ }
323
+ interface ComputedSplitter {
324
+ id: string;
325
+ currentNode: SplitNode;
326
+ direction: SplitDirection;
327
+ left: number;
328
+ top: number;
329
+ width: number;
330
+ height: number;
331
+ parentLeft: number;
332
+ parentTop: number;
333
+ parentWidth: number;
334
+ parentHeight: number;
335
+ }
336
+ declare function computeLayout(node: TreeNode | null, left?: number, top?: number, width?: number, height?: number, path?: string): {
337
+ panes: ComputedPane[];
338
+ splitters: ComputedSplitter[];
339
+ };
284
340
 
285
341
  /**
286
342
  * Shared drag-session lifecycle utility.
@@ -307,4 +363,4 @@ interface DragSessionConfig {
307
363
  }
308
364
  declare function createDragSession({ cursor, resizerEl, onMove, onEnd }: DragSessionConfig): void;
309
365
 
310
- export { DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_RESIZER_SIZE, DEFAULT_SNAP_THRESHOLD, DragHandle, type DragHandleProps, type DragSessionConfig, Pane, type PaneNode, type PaneProps, type PaneRenderProps, PaneTree, ResizableContainer, type ResizableContainerProps, type SplitDirection, type SplitNode, type TreeNode, Zeugma, type ZeugmaActionsValue, type ZeugmaClassNames, type ZeugmaProps, type ZeugmaStateValue, addPane, createDragSession, findPane, removePane, splitPane, swapPanes, updatePaneLock, updatePaneMetadata, updateSplitPercentage, useResizer, useZeugmaActions, useZeugmaState };
366
+ export { type ComputedPane, type ComputedSplitter, DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_RESIZER_SIZE, DEFAULT_SNAP_THRESHOLD, DragHandle, type DragHandleProps, type DragSessionConfig, Pane, type PaneNode, type PaneProps, type PaneRenderProps, PaneTree, ResizableContainer, type ResizableContainerProps, type SplitDirection, type SplitNode, Tab, type TabProps, type TabRenderProps, type TreeNode, type UseZeugmaOptions, Zeugma, type ZeugmaClassNames, type ZeugmaController, type ZeugmaProps, addPane, computeLayout, createDragSession, findPane, generateUniqueId, mergeTab, moveTab, removePane, removeTab, selectTab, splitPane, updatePaneLock, updateSplitPercentage, updateTabMetadata, useResizer, useZeugma };
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import {createContext,useContext,useState,useRef,useCallback,useMemo,useEffect}from'react';import {useSensors,useSensor,DndContext,pointerWithin,useDraggable,PointerSensor,TouchSensor,useDroppable}from'@dnd-kit/core';import {jsx,jsxs,Fragment}from'react/jsx-runtime';var ve=createContext(void 0),be=createContext(void 0);var G=()=>{let e=useContext(ve);if(!e)throw new Error("useZeugmaState must be used within a Zeugma provider");return e},Te=()=>{let e=useContext(be);if(!e)throw new Error("useZeugmaActions must be used within a Zeugma provider");return e};function Ue(e){let t=useRef(null);return useEffect(()=>{if(!e){t.current=null;return}let o=n=>{t.current={x:n.clientX,y:n.clientY};},r=n=>{let i=n.touches[0]||n.changedTouches[0];i&&(t.current={x:i.clientX,y:i.clientY});};return window.addEventListener("pointermove",o,{passive:true}),window.addEventListener("touchmove",r,{passive:true}),()=>{window.removeEventListener("pointermove",o),window.removeEventListener("touchmove",r);}},[e]),t}function We(e){useEffect(()=>(e?document.body.style.setProperty("cursor","not-allowed","important"):document.body.style.removeProperty("cursor"),()=>{document.body.style.removeProperty("cursor");}),[e]);}function ae(e,t){if(e===null)return null;if(e.type==="pane")return e.paneId===t?null:e;let o=ae(e.first,t),r=ae(e.second,t);return o===null?r:r===null?o:{...e,first:o,second:r}}function ue(e,t,o,r,n){if(e===null)return typeof n=="string"?{type:"pane",paneId:n}:n;if(e.type==="pane"){if(e.paneId===t){let i=typeof n=="string"?{type:"pane",paneId:n}:n,s=r==="left"||r==="top";return {type:"split",direction:o,first:s?i:e,second:s?e:i,splitPercentage:50}}return e}return {...e,first:ue(e.first,t,o,r,n)||e.first,second:ue(e.second,t,o,r,n)||e.second}}function ze(e,t,o){if(e===null)return null;let r=B(e,t),n=B(e,o);if(!r||!n)return e;function i(s){return s.type==="pane"?s.paneId===t?{...n}:s.paneId===o?{...r}:s:{...s,first:i(s.first),second:i(s.second)}}return i(e)}function Be(e,t){if(e===null)return {type:"pane",paneId:t};function o(r,n){return r.type==="pane"?{type:"split",direction:n==="row"?"column":"row",splitPercentage:50,first:r,second:{type:"pane",paneId:t}}:{...r,second:o(r.second,r.direction)}}return o(e,null)}function te(e,t,o){return e===null?null:e===t?{...e,splitPercentage:o}:e.type==="split"?{...e,first:te(e.first,t,o)||e.first,second:te(e.second,t,o)||e.second}:e}function B(e,t){return e===null?null:e.type==="pane"?e.paneId===t?e:null:B(e.first,t)??B(e.second,t)}function he(e,t,o){if(e===null)return null;if(e.type==="pane"){if(e.paneId===t){let r=o(e.metadata);if(r===void 0){let{metadata:n,...i}=e;return i}return {...e,metadata:r}}return e}return {...e,first:he(e.first,t,o)??e.first,second:he(e.second,t,o)??e.second}}function Pe(e,t,o){if(e===null)return null;if(e.type==="pane"){if(e.paneId===t){if(o===false){let{locked:r,...n}=e;return n}return {...e,locked:o}}return e}return {...e,first:Pe(e.first,t,o)??e.first,second:Pe(e.second,t,o)??e.second}}var st=8,at=8,Xt=4;var Xe=({activeId:e,render:t,className:o})=>{let r=useRef(null);return useEffect(()=>{let n=i=>{r.current&&(r.current.style.transform=`translate(${i.clientX+12}px, ${i.clientY+12}px)`);};return document.addEventListener("pointermove",n),()=>document.removeEventListener("pointermove",n)},[]),jsx("div",{ref:r,className:o,style:{position:"fixed",top:0,left:0,zIndex:9999,pointerEvents:"none"},children:t(e)})};var xe=class extends PointerSensor{static activators=[{eventName:"onPointerDown",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]},ye=class extends TouchSensor{static activators=[{eventName:"onTouchStart",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]};function Ke(e){if(e instanceof MouseEvent||e instanceof PointerEvent)return {x:e.clientX,y:e.clientY};if(typeof TouchEvent<"u"&&e instanceof TouchEvent){let t=e.touches[0]||e.changedTouches[0];if(t)return {x:t.clientX,y:t.clientY}}return null}var vt=({layout:e,onChange:t,renderPane:o,renderDragOverlay:r,classNames:n={},fullscreenPaneId:i=null,onFullscreenChange:s,onRemove:c,dragActivationDistance:x=8,snapThreshold:y=8,onDragStart:z,onDragEnd:a,onResizeStart:R,onResize:m,onResizeEnd:d,minSplitPercentage:E=5,maxSplitPercentage:L=95,enableDragToDismiss:S=false,dismissThreshold:f=60,onDismissIntentChange:v,locked:w=false,children:D})=>{let[u,b]=useState(e),[X,N]=useState(e);e!==X&&(N(e),b(e));let[k,Z]=useState(null),[I,C]=useState(null),Y=useRef(null),g=useRef(null),A=Ue(k),W=useCallback(l=>{Y.current=l;},[]),[O,M]=useState(false);We(O);let H=useCallback(l=>o(l),[o]),oe=useMemo(()=>n,[n.pane,n.paneLocked,n.dropPreview,n.swapPreview,n.dragOverlay,n.resizer,n.dismissPreview,n.dashboardLocked,n.lockedPreview]),Le=useSensors(useSensor(xe,{activationConstraint:{distance:x}}),useSensor(ye,{activationConstraint:{delay:250,tolerance:5}})),me=l=>{let p=l.active.id.toString();Z(p);let T=l.activatorEvent;A.current=Ke(T),S&&Y.current?g.current=Y.current.getBoundingClientRect():g.current=null,z&&z(p);},re=l=>{let{over:p}=l,P=(p?.id.toString()||"").startsWith("drop-locked-");if(M(P),!S)return;let K=l.active.id.toString(),h=g.current;if(!h){I!==null&&(C(null),v?.(null));return}let J=l.activatorEvent,U=null,F=null;if(A.current)U=A.current.x,F=A.current.y;else {let $=Ke(J);$&&(U=$.x+l.delta.x,F=$.y+l.delta.y);}let Q=0;if(U!==null&&F!==null){let $=0,V=0;U<h.left?$=h.left-U:U>h.right&&($=U-h.right),F<h.top?V=h.top-F:F>h.bottom&&(V=F-h.bottom),Q=Math.sqrt($*$+V*V);}else {let $=l.active.rect.current.translated;if($){let V=$.left+$.width/2,j=$.top+$.height/2,q=0,ee=0;V<h.left?q=h.left-V:V>h.right&&(q=V-h.right),j<h.top?ee=h.top-j:j>h.bottom&&(ee=j-h.bottom),Q=Math.sqrt(q*q+ee*ee);}}Q>f?I!==K&&(C(K),v?.(K)):I!==null&&(C(null),v?.(null));},ge=l=>{Z(null),M(false);let{active:p,over:T}=l,P=p.id.toString(),K=S&&I===P;if(C(null),v?.(null),g.current=null,K){c?c(P):le(P),a&&a(P,null,null);return}if(!T){a&&a(P,null,null);return}let h=T.id.toString();if(h.startsWith("drop-locked-")){a&&a(P,null,null);return}let J=h.match(/^drop-center-(.+)$/);if(J){let[,q]=J;if(P!==q){let ee=ze(u,P,q);b(ee),t(ee);}a&&a(P,q,{type:"swap",position:"center"});return}let U=h.match(/^drop-(left|right|top|bottom)-(.+)$/);if(!U){a&&a(P,null,null);return}let[,F,Q]=U;if(P===Q){a&&a(P,null,null);return}let Ne=F==="left"||F==="right"?"row":"column",$=B(u,P)??{type:"pane",paneId:P},V=ae(u,P),j=ue(V,Q,Ne,F,$);b(j),t(j),a&&a(P,Q,{type:"split",direction:Ne,position:F});},ie=useCallback((l,p=false)=>{b(l),p||t(l);},[t]),le=useCallback(l=>{let p=ae(u,l);b(p),t(p);},[u,t]),ce=useCallback(l=>{let p=Be(u,l);b(p),t(p);},[u,t]),se=useCallback((l,p)=>{let T=ze(u,l,p);b(T),t(T);},[u,t]),Ae=useCallback((l,p,T,P)=>{let K=B(u,P)??{type:"pane",paneId:P},h=ae(u,P),J=ue(h,l,p,T,K);b(J),t(J);},[u,t]),ke=useCallback((l,p)=>{let T=te(u,l,p);b(T),t(T);},[u,t]),He=useCallback((l,p)=>{let T=he(u,l,p);b(T),t(T);},[u,t]),Fe=useCallback((l,p)=>{let T=Pe(u,l,p);b(T),t(T);},[u,t]),Oe=useCallback((l,p)=>{d&&d(l,p);},[d]),ot=useMemo(()=>({layout:u,onLayoutChange:ie,renderPane:H,activeId:k,dismissIntentId:I,setContainerRef:W,fullscreenPaneId:i,classNames:oe,onRemove:c,onFullscreenChange:s,snapThreshold:y,onResizeStart:R,onResize:m,onResizeEnd:Oe,minSplitPercentage:E,maxSplitPercentage:L,locked:w}),[u,k,I,W,i,oe,c,s,y,R,m,E,L,ie,H,Oe,w]),rt=useMemo(()=>({removePane:le,addPane:ce,swapPanes:se,splitPane:Ae,updateSplitPercentage:ke,updatePaneMetadata:He,updatePaneLock:Fe}),[le,ce,se,Ae,ke,He,Fe]);return jsx(be.Provider,{value:rt,children:jsxs(ve.Provider,{value:ot,children:[jsx(DndContext,{id:"zeugma-dnd-context",sensors:Le,collisionDetection:pointerWithin,onDragStart:me,onDragMove:re,onDragEnd:ge,children:D}),k&&r&&jsx(Xe,{activeId:k,render:r,className:`${n.dragOverlay||""} ${k===I?n.dismissPreview||"zeugma-dismiss-preview":""}`.trim()})]})})};function Se({cursor:e,resizerEl:t,onMove:o,onEnd:r}){document.body.classList.add("zeugma-resizing");let n=document.createElement("style");n.id="zeugma-global-cursor-style",n.textContent=`
1
+ import en,{createContext,useState,useRef,useCallback,useEffect,useMemo,useContext}from'react';import {createPortal}from'react-dom';import {useSensors,useSensor,pointerWithin,closestCenter,DndContext,useDraggable,useDroppable,PointerSensor,TouchSensor}from'@dnd-kit/core';import {jsx,Fragment,jsxs}from'react/jsx-runtime';var ze=createContext(void 0),Ie=createContext(void 0);var oe=()=>{let e=useContext(ze);if(!e)throw new Error("useZeugmaState must be used within a Zeugma provider");return e},nt=()=>{let e=useContext(Ie);if(!e)throw new Error("useZeugmaActions must be used within a Zeugma provider");return e};function rt(e){let t=useRef(null);return useEffect(()=>{if(!e){t.current=null;return}let r=n=>{t.current={x:n.clientX,y:n.clientY};},o=n=>{let s=n.touches[0]||n.changedTouches[0];s&&(t.current={x:s.clientX,y:s.clientY});};return window.addEventListener("pointermove",r,{passive:true}),window.addEventListener("touchmove",o,{passive:true}),()=>{window.removeEventListener("pointermove",r),window.removeEventListener("touchmove",o);}},[e]),t}function ot(e){useEffect(()=>(e?document.body.style.setProperty("cursor","not-allowed","important"):document.body.style.removeProperty("cursor"),()=>{document.body.style.removeProperty("cursor");}),[e]);}function st(){let[e,t]=useState({}),r=useCallback((o,n)=>{t(s=>s[o]===n?s:{...s,[o]:n});},[]);return {portalTargets:e,registerPortalTarget:r}}var $e=createContext(void 0);var Ht=8,Zt=8,An=4;function ie(){return "pane-"+Math.random().toString(36).substring(2,11)}function be(e,t){if(e===null)return null;if(e.type==="pane")return e.id===t?null:e;let r=be(e.first,t),o=be(e.second,t);return r===null?o:o===null?r:{...e,first:r,second:o}}function de(e,t){if(e===null)return null;if(e.type==="pane"){if(e.tabs.includes(t)){let n=e.tabs.filter(a=>a!==t);if(n.length===0)return null;let s=e.activeTabId;e.activeTabId===t&&(s=n[0]);let i={...e.tabsMetadata};return delete i[t],{...e,tabs:n,activeTabId:s,tabsMetadata:Object.keys(i).length>0?i:void 0}}return e}let r=de(e.first,t),o=de(e.second,t);return r===null?o:o===null?r:{...e,first:r,second:o}}function ye(e,t,r,o,n){if(e===null)return typeof n=="string"?{type:"pane",id:ie(),tabs:[n],activeTabId:n}:n;if(e.type==="pane"){if(e.id===t||e.tabs.includes(t)){let s=typeof n=="string"?{type:"pane",id:ie(),tabs:[n],activeTabId:n}:n,i=o==="left"||o==="top";return {type:"split",direction:r,first:i?s:e,second:i?e:s,splitPercentage:50}}return e}return {...e,first:ye(e.first,t,r,o,n)||e.first,second:ye(e.second,t,r,o,n)||e.second}}function it(e,t){if(e===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t};function r(o,n){return o.type==="pane"?{type:"split",direction:n==="row"?"column":"row",splitPercentage:50,first:o,second:{type:"pane",id:ie(),tabs:[t],activeTabId:t}}:{...o,second:r(o.second,o.direction)}}return r(e,null)}function ve(e,t,r){return e===null?null:e===t?{...e,splitPercentage:r}:e.type==="split"?{...e,first:ve(e.first,t,r)||e.first,second:ve(e.second,t,r)||e.second}:e}function q(e,t){return e===null?null:e.type==="pane"?e.id===t||e.tabs.includes(t)?e:null:q(e.first,t)??q(e.second,t)}function ke(e,t,r){if(e===null)return null;if(e.type==="pane"){if(e.id===t||e.tabs.includes(t)){let o=e.tabsMetadata||{},n=o[t],s=r(n),i={...o};return s===void 0?delete i[t]:i[t]=s,{...e,tabsMetadata:Object.keys(i).length>0?i:void 0}}return e}return {...e,first:ke(e.first,t,r)??e.first,second:ke(e.second,t,r)??e.second}}function He(e,t,r){if(e===null)return null;if(e.type==="pane"){if(e.id===t||e.tabs.includes(t)){if(r===false){let{locked:o,...n}=e;return n}return {...e,locked:r}}return e}return {...e,first:He(e.first,t,r)??e.first,second:He(e.second,t,r)??e.second}}function Ze(e,t,r){return e===null?null:e.type==="pane"?e.id===t||e.tabs.includes(t)?{...e,activeTabId:r}:e:{...e,first:Ze(e.first,t,r)??e.first,second:Ze(e.second,t,r)??e.second}}function at(e,t,r){if(e===null)return null;let n=q(e,t)?.tabsMetadata?.[t],s=de(e,t);if(s===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t,tabsMetadata:n?{[t]:n}:void 0};function i(a){if(a.type==="pane"){if(a.id===r||a.tabs.includes(r)){let l=[...a.tabs];l.includes(t)||l.push(t);let y={...a.tabsMetadata};return n&&(y[t]=n),{...a,tabs:l,activeTabId:t,tabsMetadata:Object.keys(y).length>0?y:void 0}}return a}return {...a,first:i(a.first),second:i(a.second)}}return i(s)}function lt(e,t,r,o="before"){if(e===null)return null;let s=q(e,t)?.tabsMetadata?.[t],i=de(e,t);if(i===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t,tabsMetadata:s?{[t]:s}:void 0};function a(l){if(l.type==="pane"){if(l.id===r||l.tabs.includes(r)){let D=[...l.tabs].filter(T=>T!==t),c=D.indexOf(r);c<0&&(c=0),o==="after"&&(c+=1),D.splice(c,0,t);let x={...l.tabsMetadata};return s&&(x[t]=s),{...l,tabs:D,activeTabId:t,tabsMetadata:Object.keys(x).length>0?x:void 0}}return l}return {...l,first:a(l.first),second:a(l.second)}}return a(i)}function se(e,t=0,r=0,o=100,n=100,s="root"){if(e===null)return {panes:[],splitters:[]};if(e.type==="pane")return {panes:[{paneId:e.id,left:t,top:r,width:o,height:n,node:e}],splitters:[]};let{direction:i,splitPercentage:a,first:l,second:y}=e,c={id:`splitter-${s}-${i}`,currentNode:e,direction:i,left:i==="row"?t+o*(a/100):t,top:i==="column"?r+n*(a/100):r,width:i==="row"?0:o,height:i==="column"?0:n,parentLeft:t,parentTop:r,parentWidth:o,parentHeight:n},x={panes:[],splitters:[]},T={panes:[],splitters:[]};if(i==="row"){let v=o*(a/100);x=se(l,t,r,v,n,`${s}-L`),T=se(y,t+v,r,o-v,n,`${s}-R`);}else {let v=n*(a/100);x=se(l,t,r,o,v,`${s}-T`),T=se(y,t,r+v,o,n-v,`${s}-B`);}return {panes:[...x.panes,...T.panes],splitters:[c,...x.splitters,...T.splitters]}}function At(e){let{initialLayout:t,onChange:r,fullscreenPaneId:o,onFullscreenChange:n,locked:s=false,dragActivationDistance:i=8,snapThreshold:a=8,minSplitPercentage:l=5,maxSplitPercentage:y=95,enableDragToDismiss:D=false,dismissThreshold:c=60,onRemove:x,onDragStart:T,onDragEnd:v,onResizeStart:R,onResize:E,onResizeEnd:L,onDismissIntentChange:p}=e,[b,f]=useState(t),[z,A]=useState(o||null),[I,V]=useState(s),[w,K]=useState(null),[h,F]=useState(null),[Y,O]=useState(null),m=useRef(null),$=useCallback(u=>{m.current=u;},[]),_=useCallback(u=>{A(u),n?.(u);},[n]);useEffect(()=>{V(s);},[s]),useEffect(()=>{o!==void 0&&A(o);},[o]);let k=useRef(true);useEffect(()=>{if(k.current){k.current=false;return}r?.(b);},[b,r]);let N=useCallback(u=>{f(S=>be(S,u));},[]),d=useCallback(u=>{f(S=>it(S,u));},[]),B=useCallback((u,S,P,te)=>{f(Re=>{let _e=q(Re,te)??{type:"pane",id:te,tabs:[te],activeTabId:te},Ye=be(Re,te);return ye(Ye,u,S,P,_e)});},[]),ae=useCallback((u,S)=>{f(P=>ve(P,u,S));},[]),W=useCallback((u,S)=>{f(P=>ke(P,u,S));},[]),ee=useCallback((u,S)=>{f(P=>He(P,u,S));},[]),le=useCallback((u,S)=>{f(P=>Ze(P,u,S));},[]),fe=useCallback((u,S)=>{f(P=>at(P,u,S));},[]),me=useCallback((u,S,P)=>{f(te=>lt(te,u,S,P));},[]),j=useCallback(u=>{f(S=>de(S,u));},[]);return {layout:b,setLayout:f,fullscreenPaneId:z,setFullscreenPaneId:_,locked:I,setLocked:V,activeId:w,setActiveId:K,activeType:h,setActiveType:F,dismissIntentId:Y,setDismissIntentId:O,containerRef:m,setContainerRef:$,dragActivationDistance:i,snapThreshold:a,minSplitPercentage:l,maxSplitPercentage:y,enableDragToDismiss:D,dismissThreshold:c,onRemove:x,onDragStart:T,onDragEnd:v,onResizeStart:R,onResize:E,onResizeEnd:L,onDismissIntentChange:p,removePane:N,addPane:d,splitPane:B,updateSplitPercentage:ae,updateTabMetadata:W,updatePaneLock:ee,selectTab:le,mergeTab:fe,moveTab:me,removeTab:j}}var ut=({activeId:e,render:t,className:r})=>{let o=useRef(null);return useEffect(()=>{let n=s=>{o.current&&(o.current.style.transform=`translate(${s.clientX+12}px, ${s.clientY+12}px)`);};return document.addEventListener("pointermove",n),()=>document.removeEventListener("pointermove",n)},[]),jsx("div",{ref:o,className:r,style:{position:"fixed",top:0,left:0,zIndex:9999,pointerEvents:"none"},children:t(e)})};var Ae=class extends PointerSensor{static activators=[{eventName:"onPointerDown",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]},Fe=class extends TouchSensor{static activators=[{eventName:"onTouchStart",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]};function qe(e){if(e instanceof MouseEvent||e instanceof PointerEvent)return {x:e.clientX,y:e.clientY};if(typeof TouchEvent<"u"&&e instanceof TouchEvent){let t=e.touches[0]||e.changedTouches[0];if(t)return {x:t.clientX,y:t.clientY}}return null}var Kt=e=>{let{renderPane:t,renderWidget:r,renderDragOverlay:o,classNames:n={},children:s,layout:i,setLayout:a,fullscreenPaneId:l,setFullscreenPaneId:y,locked:D,activeId:c,setActiveId:x,activeType:T,setActiveType:v,dismissIntentId:R,setDismissIntentId:E,containerRef:L,setContainerRef:p,dragActivationDistance:b,snapThreshold:f,minSplitPercentage:z,maxSplitPercentage:A,enableDragToDismiss:I,dismissThreshold:V,onRemove:w,onDragStart:K,onDragEnd:h,onResizeStart:F,onResize:Y,onResizeEnd:O,onDismissIntentChange:m,removePane:$,addPane:_,splitPane:k,updateSplitPercentage:N,updateTabMetadata:d,updatePaneLock:B,selectTab:ae,mergeTab:W,moveTab:ee,removeTab:le}=e,{portalTargets:fe,registerPortalTarget:me}=st(),j=useRef(null),u=rt(c),[S,P]=useState(false);ot(S);let te=useCallback(g=>t(g),[t]),Re=useMemo(()=>n,[n.pane,n.paneLocked,n.dropPreview,n.dragOverlay,n.resizer,n.dismissPreview,n.dashboardLocked,n.lockedPreview]),_e=useSensors(useSensor(Ae,{activationConstraint:{distance:b}}),useSensor(Fe,{activationConstraint:{delay:250,tolerance:5}})),Ye=useCallback(g=>{let H=pointerWithin(g);if(H.length>0)return H;if(g.active.id.toString().startsWith("tab-header-")){let ne=g.droppableContainers.filter(J=>J.id.toString().startsWith("tab-drop-"));return closestCenter({...g,droppableContainers:ne})}return []},[]),Rt=g=>{let H=g.active.id.toString(),U=H.startsWith("tab-header-"),ne=U?H.substring(11):H;x(ne),v(U?"tab":"pane");let J=g.activatorEvent;u.current=qe(J),I&&L.current?j.current=L.current.getBoundingClientRect():j.current=null,K&&K(ne);},St=g=>{let{over:H}=g,ne=(H?.id.toString()||"").startsWith("drop-locked-");if(P(ne),!I)return;let J=g.active.id.toString(),Se=J.startsWith("tab-header-")?J.substring(11):J,M=j.current;if(!M){R!==null&&(E(null),m?.(null));return}let we=g.activatorEvent,re=null,X=null;if(u.current)re=u.current.x,X=u.current.y;else {let Z=qe(we);Z&&(re=Z.x+g.delta.x,X=Z.y+g.delta.y);}let ce=0;if(re!==null&&X!==null){let Z=0,Q=0;re<M.left?Z=M.left-re:re>M.right&&(Z=re-M.right),X<M.top?Q=M.top-X:X>M.bottom&&(Q=X-M.bottom),ce=Math.sqrt(Z*Z+Q*Q);}else {let Z=g.active.rect.current.translated;if(Z){let Q=Z.left+Z.width/2,ge=Z.top+Z.height/2,ue=0,Pe=0;Q<M.left?ue=M.left-Q:Q>M.right&&(ue=Q-M.right),ge<M.top?Pe=M.top-ge:ge>M.bottom&&(Pe=ge-M.bottom),ce=Math.sqrt(ue*ue+Pe*Pe);}}ce>V?R!==Se&&(E(Se),m?.(Se)):R!==null&&(E(null),m?.(null));},Dt=g=>{x(null),v(null),P(false);let{active:H,over:U}=g,ne=H.id.toString(),J=ne.startsWith("tab-header-"),C=J?ne.substring(11):ne,Se=I&&R===C;if(E(null),m?.(null),j.current=null,Se){w?w(C):le(C),h&&h(C,null,null);return}if(!U){h&&h(C,null,null);return}let M=U.id.toString();if(M.startsWith("drop-locked-")){h&&h(C,null,null);return}let we=M.match(/^tab-drop-(.+)$/);if(we){let[,Ne]=we;if(C!==Ne){let Ee="before",Je=U.rect,Lt=g.activatorEvent,Me=null;if(u.current)Me=u.current.x;else {let Le=qe(Lt);Le&&(Me=Le.x+g.delta.x);}if(Me!==null){let Le=Je.left+Je.width/2;Me>Le&&(Ee="after");}ee(C,Ne,Ee);}h&&h(C,Ne,{type:"swap",position:"center"});return}let re=M.match(/^drop-(left|right|top|bottom)-(.+)$/);if(!re){h&&h(C,null,null);return}let[,X,ce]=re,De=q(i,C),Z=De&&De.id===ce,Q=De&&De.tabs.length===1;if(C===ce||Z&&Q){h&&h(C,null,null);return}let ge=X==="left"||X==="right"?"row":"column",ue;if(J){let Ee=q(i,C)?.tabsMetadata?.[C];ue={type:"pane",id:ie(),tabs:[C],activeTabId:C,tabsMetadata:Ee?{[C]:Ee}:void 0};}else ue=q(i,C)??{type:"pane",id:ie(),tabs:[C],activeTabId:C};let Pe=J?de(i,C):be(i,C),Mt=ye(Pe,ce,ge,X,ue);a(Mt),h&&h(C,ce,{type:"split",direction:ge,position:X});},je=useCallback((g,H)=>{O&&O(g,H);},[O]),Et=useMemo(()=>({layout:i,onLayoutChange:g=>a(g),renderPane:te,activeId:c,dismissIntentId:R,setContainerRef:p,fullscreenPaneId:l,classNames:Re,onRemove:w,onFullscreenChange:y,snapThreshold:f,onResizeStart:F,onResize:Y,onResizeEnd:je,minSplitPercentage:z,maxSplitPercentage:A,locked:D}),[i,c,R,p,l,Re,w,y,f,F,Y,z,A,a,te,je,D]),Ct=useMemo(()=>({removePane:$,addPane:_,splitPane:k,updateSplitPercentage:N,updateTabMetadata:d,updatePaneLock:B,selectTab:ae,mergeTab:W,moveTab:ee,removeTab:le}),[$,_,k,N,d,B,ae,W,ee,le]),wt=useMemo(()=>{let g=[];function H(U){U&&(U.type==="pane"?g.push(...U.tabs):(H(U.first),H(U.second)));}return H(i),g},[i]),Nt=useMemo(()=>({registerPortalTarget:me}),[me]);return jsx(Ie.Provider,{value:Ct,children:jsx(ze.Provider,{value:Et,children:jsxs($e.Provider,{value:Nt,children:[jsx(DndContext,{id:"zeugma-dnd-context",sensors:_e,collisionDetection:Ye,onDragStart:Rt,onDragMove:St,onDragEnd:Dt,children:s}),c&&T&&o&&jsx(ut,{activeId:c,render:g=>o(g,T),className:`${n.dragOverlay||""} ${c===R?n.dismissPreview||"zeugma-dismiss-preview":""}`.trim()}),jsx("div",{id:"zeugma-portal-host",style:{display:"none"},children:wt.map(g=>jsx(jt,{tabId:g,target:fe[g]||null,renderWidget:r},g))})]})})})},jt=({tabId:e,target:t,renderWidget:r})=>{let o=useRef(null);!o.current&&typeof window<"u"&&(o.current=document.createElement("div"),o.current.className=`zeugma-portal-wrapper-${e}`,o.current.style.width="100%",o.current.style.height="100%");let n=o.current;return useEffect(()=>{if(n)if(t)t.appendChild(n);else {let s=document.getElementById("zeugma-hidden-portal-container");s||(s=document.createElement("div"),s.id="zeugma-hidden-portal-container",s.style.display="none",document.body.appendChild(s)),s.appendChild(n);}},[t,n]),useEffect(()=>()=>{o.current&&o.current.remove();},[]),!n||!r?null:createPortal(r(e),n)};function Oe({cursor:e,resizerEl:t,onMove:r,onEnd:o}){document.body.classList.add("zeugma-resizing");let n=document.createElement("style");n.id="zeugma-global-cursor-style",n.textContent=`
2
2
  * {
3
3
  cursor: ${e} !important;
4
4
  user-select: none !important;
5
5
  }
6
- `,document.head.appendChild(n),t.setAttribute("data-resizing","true");let i=c=>{o(c);},s=()=>{document.body.classList.remove("zeugma-resizing"),t.removeAttribute("data-resizing");let c=document.getElementById("zeugma-global-cursor-style");c&&c.remove(),document.removeEventListener("pointermove",i),document.removeEventListener("pointerup",s),r();};document.addEventListener("pointermove",i),document.addEventListener("pointerup",s);}function Ce({containerRef:e,isRow:t,direction:o,splitPercentage:r,resizerSize:n,snapThreshold:i,layout:s,currentNode:c,onLayoutChange:x,onResizeStart:y,onResizeEnd:z,parentLeft:a,parentTop:R,parentWidth:m,parentHeight:d}){let{onResizeStart:E,onResize:L,onResizeEnd:S,minSplitPercentage:f=5,maxSplitPercentage:v=95,locked:w=false}=G();return useCallback(D=>{if(w)return;D.preventDefault();let u=e.current;if(!u)return;y&&y(),E&&E(c);let b=u.getBoundingClientRect(),X=D.clientX,N=D.clientY,k=r,Z=D.currentTarget,I=b.left+b.width*(a/100),C=b.top+b.height*(R/100),Y=b.width*(m/100),g=b.height*(d/100),W=Array.from(document.querySelectorAll('div[role="separator"][data-direction]')).filter(M=>M!==Z&&M.getAttribute("data-direction")===o).map(M=>{let H=M.getBoundingClientRect();return t?H.left+H.width/2:H.top+H.height/2}),O=k;Se({cursor:t?"col-resize":"row-resize",resizerEl:Z,onMove:M=>{let H=t?(M.clientX-X)/Y*100:(M.clientY-N)/g*100,oe=k+H,Le=t?I+(Y-n)*(oe/100)+n/2:C+(g-n)*(oe/100)+n/2,me=1/0,re=null;for(let ce of W){let se=Math.abs(Le-ce);se<i&&se<me&&(me=se,re=ce);}let ge=oe;re!==null&&(ge=t?(re-n/2-I)/(Y-n)*100:(re-n/2-C)/(g-n)*100);let ie=Math.max(f,Math.min(v,ge));O=ie;let le=te(s,c,ie);x(le,true),L&&L(c,ie);},onEnd:()=>{let M=te(s,c,O);x(M),z&&z(),S&&S(c,O);}});},[e,t,o,r,n,i,s,c,x,y,z,E,L,S,f,v,a,R,m,d])}function pe(e,t=0,o=0,r=100,n=100,i="root"){if(e.type==="pane")return {panes:[{paneId:e.paneId,left:t,top:o,width:r,height:n,node:e}],splitters:[]};let{direction:s,splitPercentage:c,first:x,second:y}=e,a={id:`splitter-${i}-${s}`,currentNode:e,direction:s,left:s==="row"?t+r*(c/100):t,top:s==="column"?o+n*(c/100):o,width:s==="row"?0:r,height:s==="column"?0:n,parentLeft:t,parentTop:o,parentWidth:r,parentHeight:n},R={panes:[],splitters:[]},m={panes:[],splitters:[]};if(s==="row"){let d=r*(c/100);R=pe(x,t,o,d,n,`${i}-L`),m=pe(y,t+d,o,r-d,n,`${i}-R`);}else {let d=n*(c/100);R=pe(x,t,o,r,d,`${i}-T`),m=pe(y,t,o+d,r,n-d,`${i}-B`);}return {panes:[...R.panes,...m.panes],splitters:[a,...R.splitters,...m.splitters]}}var St=({splitter:e,resizerSize:t,snapThreshold:o,containerRef:r})=>{let{layout:n,onLayoutChange:i,classNames:s,locked:c}=G(),[x,y]=useState(false),{currentNode:z,direction:a,left:R,top:m,width:d,height:E,parentLeft:L,parentTop:S,parentWidth:f,parentHeight:v}=e,w=a==="row",D=Ce({containerRef:r,isRow:w,direction:a,splitPercentage:z.splitPercentage,resizerSize:t,snapThreshold:o,layout:n,currentNode:z,onLayoutChange:i,onResizeStart:()=>y(true),onResizeEnd:()=>y(false),parentLeft:L,parentTop:S,parentWidth:f,parentHeight:v}),u=w?{position:"absolute",left:`calc(${R}% - ${t/2}px)`,top:`${m}%`,width:`${t}px`,height:`${E}%`,cursor:c?"default":"col-resize",pointerEvents:c?"none":"auto",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box"}:{position:"absolute",left:`${R}%`,top:`calc(${m}% - ${t/2}px)`,width:`${d}%`,height:`${t}px`,cursor:c?"default":"row-resize",pointerEvents:c?"none":"auto",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box"};return jsx("div",{className:`zeugma-resizer ${s.resizer||""}`.trim(),"data-direction":a,"data-resizing":x||void 0,style:u,onPointerDown:D,role:"separator","aria-valuenow":z.splitPercentage,"aria-valuemin":5,"aria-valuemax":95})},wt=({tree:e,resizerSize:t=4,snapThreshold:o})=>{let{layout:r,renderPane:n,activeId:i,dismissIntentId:s,setContainerRef:c,fullscreenPaneId:x,snapThreshold:y,locked:z,classNames:a}=G(),R=o!==void 0?o:y??8,m=e!==void 0?e:r,d=useRef(null),{panes:E,splitters:L}=useMemo(()=>m?pe(m):{panes:[],splitters:[]},[m]);if(!m)return null;let S=()=>jsxs(Fragment,{children:[E.map(f=>{let v=x===f.paneId;return jsx("div",{style:{position:"absolute",left:v?"0%":`${f.left}%`,top:v?"0%":`${f.top}%`,width:v?"100%":`${f.width}%`,height:v?"100%":`${f.height}%`,overflow:"hidden",zIndex:v?20:1,display:x&&!v?"none":"block",padding:v?"0px":`${t/2}px`,boxSizing:"border-box"},children:n(f.paneId)},f.paneId)}),!x&&L.map(f=>jsx(St,{splitter:f,resizerSize:t,snapThreshold:R,containerRef:d},f.id))]});if(e===void 0){let f=i!==null&&i===s,v=D=>{c(D),d.current=D;},w=`zeugma-dashboard-root ${f?"zeugma-dashboard-dismiss-active":""} ${z?a.dashboardLocked||"zeugma-dashboard-locked":""}`.trim();return jsx("div",{ref:v,className:w,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:S()})}return jsx("div",{ref:d,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:S()})};var et="zeugma-height:",Tt="default-pane";function zt(e){try{let t=localStorage.getItem(et+e);if(t!==null){let o=Number(t);if(Number.isFinite(o)&&o>0)return o}}catch{}return null}function je(e,t){try{localStorage.setItem(et+e,String(Math.round(t)));}catch{}}var tt=({children:e,active:t=true,height:o,onHeightChange:r,minHeight:n=100,maxHeight:i=1/0,persist:s,localStorageKey:c,resizerHeight:x=6,className:y,resizerClassName:z})=>{let a=s?c||Tt:null,R=()=>{let w=(a?zt(a):null)??o??400;return we(w,n,i)},[m,d]=useState(R),E=useRef(null),L=a?m:o??m,S=useRef(o);useEffect(()=>{if(o!==void 0&&o!==S.current){let w=we(o,n,i);d(w),a&&je(a,w);}S.current=o;},[o,n,i,a]);let f=useCallback(()=>i,[i]),v=useCallback(w=>{w.preventDefault();let D=w.clientY,u=L,b=f(),X=w.currentTarget,N=nt(E.current),k=N?N.scrollTop:0,Z=D,I=null,C=(g,A)=>{let W=A-k,M=g-D+W,H=we(u+M,n,b);return E.current&&(E.current.style.height=`${H}px`),H},Y=()=>{if(!N)return;let g=N===document.documentElement||N===document.body?{top:0,bottom:window.innerHeight}:N.getBoundingClientRect(),A=40,W=10,O=0;Z>g.bottom-A?O=Math.min(1,(Z-(g.bottom-A))/A)*W:Z<g.top+A&&(O=-Math.min(1,(g.top+A-Z)/A)*W),O!==0&&(N.scrollTop+=O,C(Z,N.scrollTop)),I=requestAnimationFrame(Y);};I=requestAnimationFrame(Y),Se({cursor:"row-resize",resizerEl:X,onMove:g=>{Z=g.clientY,N&&C(Z,N.scrollTop);},onEnd:()=>{I!==null&&cancelAnimationFrame(I);let g=u;E.current&&(g=E.current.getBoundingClientRect().height),g=we(g,n,b),d(g),r&&r(g),a&&je(a,g);}});},[L,n,f,r,a]);return t?jsxs("div",{ref:E,className:`zeugma-resizable-container ${y||""}`.trim(),style:{height:`${L}px`,position:"relative",overflow:"hidden",boxSizing:"border-box"},children:[jsx("div",{style:{height:`calc(100% - ${x}px)`,overflow:"hidden"},children:e}),jsx("div",{className:`zeugma-resizable-handle ${z||""}`.trim(),style:{height:`${x}px`,cursor:"row-resize",position:"relative",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box",flexShrink:0},onPointerDown:v,role:"separator","aria-orientation":"horizontal","aria-valuenow":Math.round(L),"aria-valuemin":n,"aria-valuemax":i===1/0?void 0:i})]}):jsx("div",{className:`zeugma-resizable-container disabled ${y||""}`.trim(),style:{height:"100%",position:"relative",overflow:"hidden",boxSizing:"border-box"},children:jsx("div",{style:{height:"100%",overflow:"hidden"},children:e})})};function we(e,t,o){return Math.max(t,Math.min(o,e))}function nt(e){if(typeof window>"u"||!e)return null;let t=e.parentElement;if(!t)return document.documentElement;let r=window.getComputedStyle(t).overflowY;return r==="auto"||r==="scroll"?t:nt(t)}var Ee=createContext(null);var $t={top:{position:"absolute",top:0,left:"25%",width:"50%",height:"25%",zIndex:20,pointerEvents:"auto"},bottom:{position:"absolute",bottom:0,left:"25%",width:"50%",height:"25%",zIndex:20,pointerEvents:"auto"},left:{position:"absolute",top:"25%",left:0,width:"25%",height:"50%",zIndex:20,pointerEvents:"auto"},right:{position:"absolute",top:"25%",right:0,width:"25%",height:"50%",zIndex:20,pointerEvents:"auto"},center:{position:"absolute",top:"25%",left:"25%",width:"50%",height:"50%",zIndex:20,pointerEvents:"auto"},full:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:20,pointerEvents:"auto",cursor:"not-allowed"}},Zt={top:{position:"absolute",top:0,left:0,right:0,height:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},bottom:{position:"absolute",bottom:0,left:0,right:0,height:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},left:{position:"absolute",top:0,bottom:0,left:0,width:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},right:{position:"absolute",top:0,bottom:0,right:0,width:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},center:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:21,pointerEvents:"none",boxSizing:"border-box"},full:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:21,pointerEvents:"none",boxSizing:"border-box"}},$e=({id:e,position:t,activeClassName:o})=>{let{setNodeRef:r,isOver:n}=useDroppable({id:e});return jsxs(Fragment,{children:[jsx("div",{ref:r,style:$t[t]}),n&&jsx("div",{className:o,style:Zt[t]})]})},At=({id:e,children:t,style:o,locked:r=false})=>{let{layout:n,activeId:i,classNames:s,fullscreenPaneId:c,onRemove:x,onFullscreenChange:y,locked:z}=G(),{removePane:a,updatePaneMetadata:R}=Te(),m=useMemo(()=>B(n,e),[n,e]),d=m?.metadata,E=m?.locked??false,L=r||E,S=z||L,f=z||L,v=i!==null&&i!==e&&!f,{attributes:w,listeners:D,setNodeRef:u,isDragging:b}=useDraggable({id:e,disabled:S}),X=i===e||b,N=c===e,k=useMemo(()=>({isDragging:X,isFullscreen:N,toggleFullscreen:()=>y?.(N?null:e),remove:()=>{N&&y?.(null),x?x(e):a(e);},metadata:d,updateMetadata:C=>{R(e,C);},locked:S}),[X,N,y,e,x,a,d,R,S]),Z=useMemo(()=>S?{disabled:true}:{...D,...w},[D,w,S]),I=`${s.pane||""} ${L?s.paneLocked||"zeugma-pane-locked":""}`.trim();return jsx(Ee.Provider,{value:Z,children:jsxs("div",{ref:u,className:I,style:{position:"relative",width:"100%",height:"100%",...o},children:[t(k),v&&jsxs("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:[["top","bottom","left","right"].map(C=>jsx($e,{id:`drop-${C}-${e}`,position:C,activeClassName:s.dropPreview},C)),jsx($e,{id:`drop-center-${e}`,position:"center",activeClassName:s.swapPreview})]}),i!==null&&i!==e&&f&&jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:jsx($e,{id:`drop-locked-${e}`,position:"full",activeClassName:s.lockedPreview||"zeugma-locked-preview"})})]})})};var Ft=({children:e,className:t,style:o})=>{let r=useContext(Ee);if(!r)throw new Error("<DragHandle> must be used inside a <Pane>");let{disabled:n,...i}=r;return jsx("div",{className:t,style:{cursor:n?"default":"grab",userSelect:n?"auto":"none",touchAction:n?"auto":"none",...o},...n?{}:i,children:e})};export{at as DEFAULT_DRAG_ACTIVATION_DISTANCE,Xt as DEFAULT_RESIZER_SIZE,st as DEFAULT_SNAP_THRESHOLD,Ft as DragHandle,At as Pane,wt as PaneTree,tt as ResizableContainer,vt as Zeugma,Be as addPane,Se as createDragSession,B as findPane,ae as removePane,ue as splitPane,ze as swapPanes,Pe as updatePaneLock,he as updatePaneMetadata,te as updateSplitPercentage,Ce as useResizer,Te as useZeugmaActions,G as useZeugmaState};//# sourceMappingURL=index.js.map
6
+ `,document.head.appendChild(n),t.setAttribute("data-resizing","true");let s=a=>{r(a);},i=()=>{document.body.classList.remove("zeugma-resizing"),t.removeAttribute("data-resizing");let a=document.getElementById("zeugma-global-cursor-style");a&&a.remove(),document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",i),o();};document.addEventListener("pointermove",s),document.addEventListener("pointerup",i);}function Ge({containerRef:e,isRow:t,direction:r,splitPercentage:o,resizerSize:n,snapThreshold:s,layout:i,currentNode:a,onLayoutChange:l,onResizeStart:y,onResizeEnd:D,parentLeft:c,parentTop:x,parentWidth:T,parentHeight:v}){let{onResizeStart:R,onResize:E,onResizeEnd:L,minSplitPercentage:p=5,maxSplitPercentage:b=95,locked:f=false}=oe();return useCallback(z=>{if(f)return;z.preventDefault();let A=e.current;if(!A)return;y&&y(),R&&R(a);let I=A.getBoundingClientRect(),V=z.clientX,w=z.clientY,K=o,h=z.currentTarget,F=I.left+I.width*(c/100),Y=I.top+I.height*(x/100),O=I.width*(T/100),m=I.height*(v/100),_=Array.from(document.querySelectorAll('div[role="separator"][data-direction]')).filter(N=>N!==h&&N.getAttribute("data-direction")===r).map(N=>{let d=N.getBoundingClientRect();return t?d.left+d.width/2:d.top+d.height/2}),k=K;Oe({cursor:t?"col-resize":"row-resize",resizerEl:h,onMove:N=>{let d=t?(N.clientX-V)/O*100:(N.clientY-w)/m*100,B=K+d,ae=t?F+(O-n)*(B/100)+n/2:Y+(m-n)*(B/100)+n/2,W=1/0,ee=null;for(let j of _){let u=Math.abs(ae-j);u<s&&u<W&&(W=u,ee=j);}let le=B;ee!==null&&(le=t?(ee-n/2-F)/(O-n)*100:(ee-n/2-Y)/(m-n)*100);let fe=Math.max(p,Math.min(b,le));k=fe;let me=ve(i,a,fe);if(me){let{panes:j,splitters:u}=se(me),S=e.current;if(S){for(let P of j)S.style.setProperty(`--pane-left-${P.paneId}`,`${P.left}%`),S.style.setProperty(`--pane-top-${P.paneId}`,`${P.top}%`),S.style.setProperty(`--pane-width-${P.paneId}`,`${P.width}%`),S.style.setProperty(`--pane-height-${P.paneId}`,`${P.height}%`);for(let P of u)S.style.setProperty(`--splitter-pos-${P.id}`,`${P.direction==="row"?P.left:P.top}%`);}}E&&E(a,fe);},onEnd:()=>{let N=ve(i,a,k),d=e.current;if(d){let{panes:B,splitters:ae}=se(N);for(let W of B)d.style.removeProperty(`--pane-left-${W.paneId}`),d.style.removeProperty(`--pane-top-${W.paneId}`),d.style.removeProperty(`--pane-width-${W.paneId}`),d.style.removeProperty(`--pane-height-${W.paneId}`);for(let W of ae)d.style.removeProperty(`--splitter-pos-${W.id}`);}l(N),D&&D(),L&&L(a,k);}});},[e,t,r,o,n,s,i,a,l,y,D,R,E,L,p,b,c,x,T,v])}var on=({splitter:e,resizerSize:t,snapThreshold:r,containerRef:o})=>{let{layout:n,onLayoutChange:s,classNames:i,locked:a}=oe(),[l,y]=useState(false),{currentNode:D,direction:c,left:x,top:T,width:v,height:R,parentLeft:E,parentTop:L,parentWidth:p,parentHeight:b}=e,f=c==="row",z=Ge({containerRef:o,isRow:f,direction:c,splitPercentage:D.splitPercentage,resizerSize:t,snapThreshold:r,layout:n,currentNode:D,onLayoutChange:s,onResizeStart:()=>y(true),onResizeEnd:()=>y(false),parentLeft:E,parentTop:L,parentWidth:p,parentHeight:b}),A=f?{position:"absolute",left:`calc(var(--splitter-pos-${e.id}, ${x}%) - ${t/2}px)`,top:`calc(${T}% + ${t/2}px)`,width:`${t}px`,height:`calc(${R}% - ${t}px)`,cursor:a?"default":"col-resize",pointerEvents:a?"none":"auto",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box"}:{position:"absolute",left:`calc(${x}% + ${t/2}px)`,top:`calc(var(--splitter-pos-${e.id}, ${T}%) - ${t/2}px)`,width:`calc(${v}% - ${t}px)`,height:`${t}px`,cursor:a?"default":"row-resize",pointerEvents:a?"none":"auto",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box"};return jsx("div",{className:`zeugma-resizer ${i.resizer||""}`.trim(),"data-direction":c,"data-resizing":l||void 0,style:A,onPointerDown:z,role:"separator","aria-valuenow":D.splitPercentage,"aria-valuemin":5,"aria-valuemax":95})},sn=en.memo(({paneId:e,renderPane:t})=>jsx(Fragment,{children:t(e)}),(e,t)=>e.paneId===t.paneId&&e.renderPane===t.renderPane),an=({tree:e,resizerSize:t=4,snapThreshold:r})=>{let{layout:o,renderPane:n,activeId:s,dismissIntentId:i,setContainerRef:a,fullscreenPaneId:l,snapThreshold:y,locked:D,classNames:c}=oe(),x=r!==void 0?r:y??8,T=e!==void 0?e:o,v=useRef(null),{panes:R,splitters:E}=useMemo(()=>T?se(T):{panes:[],splitters:[]},[T]);if(!T)return null;let L=()=>jsxs(Fragment,{children:[R.map(p=>{let b=l===p.paneId;return jsx("div",{style:{position:"absolute",left:b?"0%":`var(--pane-left-${p.paneId}, ${p.left}%)`,top:b?"0%":`var(--pane-top-${p.paneId}, ${p.top}%)`,width:b?"100%":`var(--pane-width-${p.paneId}, ${p.width}%)`,height:b?"100%":`var(--pane-height-${p.paneId}, ${p.height}%)`,overflow:"hidden",zIndex:b?20:1,display:l&&!b?"none":"block",padding:b?"0px":`${t/2}px`,boxSizing:"border-box"},children:jsx(sn,{paneId:p.paneId,renderPane:n})},p.paneId)}),!l&&E.map(p=>jsx(on,{splitter:p,resizerSize:t,snapThreshold:x,containerRef:v},p.id))]});if(e===void 0){let p=s!==null&&s===i,b=z=>{a(z),v.current=z;},f=`zeugma-dashboard-root ${p?"zeugma-dashboard-dismiss-active":""} ${D?c.dashboardLocked||"zeugma-dashboard-locked":""}`.trim();return jsx("div",{ref:b,className:f,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:L()})}return jsx("div",{ref:v,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:L()})};var ht="zeugma-height:",dn="default-pane";function pn(e){try{let t=localStorage.getItem(ht+e);if(t!==null){let r=Number(t);if(Number.isFinite(r)&&r>0)return r}}catch{}return null}function vt(e,t){try{localStorage.setItem(ht+e,String(Math.round(t)));}catch{}}var Pt=({children:e,active:t=true,height:r,onHeightChange:o,minHeight:n=100,maxHeight:s=1/0,persist:i,localStorageKey:a,resizerHeight:l=6,className:y,resizerClassName:D})=>{let c=i?a||dn:null,x=()=>{let f=(c?pn(c):null)??r??400;return Ve(f,n,s)},[T,v]=useState(x),R=useRef(null),E=c?T:r??T,L=useRef(r);useEffect(()=>{if(r!==void 0&&r!==L.current){let f=Ve(r,n,s);v(f),c&&vt(c,f);}L.current=r;},[r,n,s,c]);let p=useCallback(()=>s,[s]),b=useCallback(f=>{f.preventDefault();let z=f.clientY,A=E,I=p(),V=f.currentTarget,w=yt(R.current),K=w?w.scrollTop:0,h=z,F=null,Y=(m,$)=>{let _=$-K,N=m-z+_,d=Ve(A+N,n,I);return R.current&&(R.current.style.height=`${d}px`),d},O=()=>{if(!w)return;let m=w===document.documentElement||w===document.body?{top:0,bottom:window.innerHeight}:w.getBoundingClientRect(),$=40,_=10,k=0;h>m.bottom-$?k=Math.min(1,(h-(m.bottom-$))/$)*_:h<m.top+$&&(k=-Math.min(1,(m.top+$-h)/$)*_),k!==0&&(w.scrollTop+=k,Y(h,w.scrollTop)),F=requestAnimationFrame(O);};F=requestAnimationFrame(O),Oe({cursor:"row-resize",resizerEl:V,onMove:m=>{h=m.clientY,w&&Y(h,w.scrollTop);},onEnd:()=>{F!==null&&cancelAnimationFrame(F);let m=A;R.current&&(m=R.current.getBoundingClientRect().height),m=Ve(m,n,I),v(m),o&&o(m),c&&vt(c,m);}});},[E,n,p,o,c]);return t?jsxs("div",{ref:R,className:`zeugma-resizable-container ${y||""}`.trim(),style:{height:`${E}px`,position:"relative",overflow:"hidden",boxSizing:"border-box"},children:[jsx("div",{style:{height:`calc(100% - ${l}px)`,overflow:"hidden"},children:e}),jsx("div",{className:`zeugma-resizable-handle ${D||""}`.trim(),style:{height:`${l}px`,cursor:"row-resize",position:"relative",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box",flexShrink:0},onPointerDown:b,role:"separator","aria-orientation":"horizontal","aria-valuenow":Math.round(E),"aria-valuemin":n,"aria-valuemax":s===1/0?void 0:s})]}):jsx("div",{className:`zeugma-resizable-container disabled ${y||""}`.trim(),style:{height:"100%",position:"relative",overflow:"hidden",boxSizing:"border-box"},children:jsx("div",{style:{height:"100%",overflow:"hidden"},children:e})})};function Ve(e,t,r){return Math.max(t,Math.min(r,e))}function yt(e){if(typeof window>"u"||!e)return null;let t=e.parentElement;if(!t)return document.documentElement;let o=window.getComputedStyle(t).overflowY;return o==="auto"||o==="scroll"?t:yt(t)}var Ue=createContext(null);var yn={top:{position:"absolute",top:0,left:"25%",width:"50%",height:"25%",zIndex:20,pointerEvents:"auto"},bottom:{position:"absolute",bottom:0,left:"25%",width:"50%",height:"25%",zIndex:20,pointerEvents:"auto"},left:{position:"absolute",top:"25%",left:0,width:"25%",height:"50%",zIndex:20,pointerEvents:"auto"},right:{position:"absolute",top:"25%",right:0,width:"25%",height:"50%",zIndex:20,pointerEvents:"auto"},full:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:20,pointerEvents:"auto",cursor:"not-allowed"}},Tn={top:{position:"absolute",top:0,left:0,right:0,height:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},bottom:{position:"absolute",bottom:0,left:0,right:0,height:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},left:{position:"absolute",top:0,bottom:0,left:0,width:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},right:{position:"absolute",top:0,bottom:0,right:0,width:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},full:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:21,pointerEvents:"none",boxSizing:"border-box"}},Tt=({id:e,position:t,activeClassName:r})=>{let{setNodeRef:o,isOver:n}=useDroppable({id:e});return jsxs(Fragment,{children:[jsx("div",{ref:o,style:yn[t]}),n&&jsx("div",{className:r,style:Tn[t]})]})},xn=({id:e,children:t,style:r,locked:o=false})=>{let{layout:n,activeId:s,classNames:i,fullscreenPaneId:a,onFullscreenChange:l,locked:y}=oe(),{removePane:D,updateTabMetadata:c,selectTab:x,removeTab:T}=nt(),v=useContext($e);if(!v)throw new Error("Pane must be used within a Zeugma provider");let{registerPortalTarget:R}=v,E=useMemo(()=>q(n,e),[n,e]),L=E?.id??e,p=E?.tabs??[e],b=E?.activeTabId??e,f=E?.tabsMetadata,z=f?.[e],A=E?.locked??false,I=o||A,V=y||I,w=y||I,K=s!==null&&s!==e&&(!p.includes(s)||p.length>1)&&!w,{attributes:h,listeners:F,setNodeRef:Y}=useDraggable({id:e,disabled:V}),O=s!==null&&p.includes(s),m=a===e,$=useCallback(()=>jsx("div",{id:`zeugma-tab-target-${b}`,className:"zeugma-tab-content-wrapper",style:{height:"100%",width:"100%"}}),[b]);useEffect(()=>{let d=document.getElementById(`zeugma-tab-target-${b}`);return R(b,d),()=>{R(b,null);}},[b,R]);let _=useMemo(()=>({isDragging:O,isFullscreen:m,toggleFullscreen:()=>l?.(m?null:e),remove:()=>{m&&l?.(null),D(L);},metadata:z,updateMetadata:d=>{c(e,d);},locked:V,tabs:p,activeTabId:b,selectTab:d=>x(L,d),removeTab:d=>{m&&d===b&&l?.(null),T(d);},tabsMetadata:f,updateTabMetadata:(d,B)=>{c(d,B);},renderActiveTab:$}),[O,m,l,e,T,z,c,V,p,b,x,L,f,$]),k=useMemo(()=>V?{disabled:true}:{...F,...h},[F,h,V]),N=`${i.pane||""} ${I?i.paneLocked||"zeugma-pane-locked":""}`.trim();return jsx(Ue.Provider,{value:k,children:jsxs("div",{ref:Y,className:N,style:{position:"relative",width:"100%",height:"100%",...r},children:[t(_),K&&jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:["top","bottom","left","right"].map(d=>jsx(Tt,{id:`drop-${d}-${e}`,position:d,activeClassName:i.dropPreview},d))}),s!==null&&s!==e&&w&&jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:jsx(Tt,{id:`drop-locked-${e}`,position:"full",activeClassName:i.lockedPreview||"zeugma-locked-preview"})})]})})};var Dn=({children:e,className:t,style:r})=>{let o=useContext(Ue);if(!o)throw new Error("<DragHandle> must be used inside a <Pane>");let{disabled:n,...s}=o;return jsx("div",{className:t,style:{cursor:n?"default":"grab",userSelect:n?"auto":"none",touchAction:n?"auto":"none",...r},...n?{}:s,children:e})};var Nn=({id:e,locked:t=false,children:r,className:o,style:n})=>{let{locked:s}=oe(),i=t||s,{attributes:a,listeners:l,setNodeRef:y,isDragging:D}=useDraggable({id:`tab-header-${e}`,disabled:i}),{setNodeRef:c,isOver:x}=useDroppable({id:`tab-drop-${e}`,disabled:i});return jsx("div",{ref:v=>{y(v),c(v);},className:o,style:{display:"inline-flex",cursor:i?"default":"grab",...n},...i?{}:l,...i?{}:a,children:r({isDragging:D,isOver:x})})};export{Zt as DEFAULT_DRAG_ACTIVATION_DISTANCE,An as DEFAULT_RESIZER_SIZE,Ht as DEFAULT_SNAP_THRESHOLD,Dn as DragHandle,xn as Pane,an as PaneTree,Pt as ResizableContainer,Nn as Tab,Kt as Zeugma,it as addPane,se as computeLayout,Oe as createDragSession,q as findPane,ie as generateUniqueId,at as mergeTab,lt as moveTab,be as removePane,de as removeTab,Ze as selectTab,ye as splitPane,He as updatePaneLock,ve as updateSplitPercentage,ke as updateTabMetadata,Ge as useResizer,At as useZeugma};//# sourceMappingURL=index.js.map
7
7
  //# sourceMappingURL=index.js.map