react-zeugma 4.1.0 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +57 -24
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +184 -155
- package/dist/index.d.ts +184 -155
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import React__default, { Dispatch, SetStateAction, ReactNode, RefObject } from 'react';
|
|
3
|
+
|
|
4
|
+
declare const DEFAULT_SNAP_THRESHOLD = 8;
|
|
5
|
+
declare const DEFAULT_DRAG_ACTIVATION_DISTANCE = 8;
|
|
6
|
+
declare const DEFAULT_RESIZER_SIZE = 4;
|
|
2
7
|
|
|
3
8
|
type SplitDirection = 'row' | 'column';
|
|
4
9
|
interface SplitNode {
|
|
@@ -17,11 +22,12 @@ interface PaneNode {
|
|
|
17
22
|
tabsMetadata?: Record<string, Record<string, unknown>>;
|
|
18
23
|
}
|
|
19
24
|
type TreeNode = SplitNode | PaneNode;
|
|
20
|
-
|
|
21
25
|
interface UseZeugmaOptions {
|
|
22
|
-
/** Initial layout tree model defining pane organization
|
|
23
|
-
initialLayout
|
|
24
|
-
/**
|
|
26
|
+
/** Initial layout tree model defining pane organization for uncontrolled mode. Only used on initial mount. */
|
|
27
|
+
initialLayout?: TreeNode | null;
|
|
28
|
+
/** Controlled layout tree model. If provided, the hook will run in controlled mode and sync with this value. */
|
|
29
|
+
layout?: TreeNode | null;
|
|
30
|
+
/** Callback triggered when the layout changes via drag-and-drop actions, splits, moves, or resizes. */
|
|
25
31
|
onChange?: (newLayout: TreeNode | null) => void;
|
|
26
32
|
/** The ID of the pane that is currently taking up the full dashboard area. Null if no pane is fullscreen. */
|
|
27
33
|
fullscreenPaneId?: string | null;
|
|
@@ -45,9 +51,9 @@ interface UseZeugmaOptions {
|
|
|
45
51
|
onRemove?: (paneId: string) => void;
|
|
46
52
|
/** Callback triggered when dragging starts for a pane. */
|
|
47
53
|
onDragStart?: (activeId: string) => void;
|
|
48
|
-
/** Callback triggered when dragging ends, providing details on target pane and drop action (split or
|
|
54
|
+
/** Callback triggered when dragging ends, providing details on target pane and drop action (split or move). */
|
|
49
55
|
onDragEnd?: (activeId: string, overId: string | null, dropAction: {
|
|
50
|
-
type: 'split' | '
|
|
56
|
+
type: 'split' | 'move';
|
|
51
57
|
direction?: SplitDirection;
|
|
52
58
|
position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
|
|
53
59
|
} | null) => void;
|
|
@@ -61,12 +67,35 @@ interface UseZeugmaOptions {
|
|
|
61
67
|
onDismissIntentChange?: (paneId: string | null) => void;
|
|
62
68
|
}
|
|
63
69
|
interface ZeugmaController {
|
|
70
|
+
/** The current active layout tree structure, or null if empty. */
|
|
64
71
|
layout: TreeNode | null;
|
|
72
|
+
/** Updates the layout tree. */
|
|
65
73
|
setLayout: Dispatch<SetStateAction<TreeNode | null>>;
|
|
74
|
+
/** The ID of the pane currently zoomed to fullscreen, or null. */
|
|
66
75
|
fullscreenPaneId: string | null;
|
|
76
|
+
/** Programmatically sets the fullscreen pane ID. */
|
|
67
77
|
setFullscreenPaneId: (paneId: string | null) => void;
|
|
78
|
+
/** Whether the layout is globally locked. */
|
|
68
79
|
locked: boolean;
|
|
80
|
+
/** Programmatically updates the global locked status. */
|
|
69
81
|
setLocked: Dispatch<SetStateAction<boolean>>;
|
|
82
|
+
/** Removes the specified pane from the layout tree and collapses its parent split. */
|
|
83
|
+
removePane: (paneId: string) => void;
|
|
84
|
+
/** Appends/inserts a pane at the bottom-rightmost leaf of the layout tree. */
|
|
85
|
+
addPane: (paneId: string) => void;
|
|
86
|
+
/** Stable callback to update metadata for a specific tab. */
|
|
87
|
+
updateTabMetadata: (tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
|
|
88
|
+
/** Stable callback to update the locked status of a specific pane in the layout tree. */
|
|
89
|
+
updatePaneLock: (paneId: string, locked: boolean) => void;
|
|
90
|
+
/** Stable callback to activate a tab within a pane. */
|
|
91
|
+
selectTab: (paneId: string, tabId: string) => void;
|
|
92
|
+
/** Stable callback to merge a dragged tab/pane into another pane's tab list. */
|
|
93
|
+
mergeTab: (draggedTabId: string, targetPaneId: string) => void;
|
|
94
|
+
/** Stable callback to remove/close a specific tab from the layout. */
|
|
95
|
+
removeTab: (tabId: string) => void;
|
|
96
|
+
}
|
|
97
|
+
/** @internal */
|
|
98
|
+
interface ZeugmaInternalController extends ZeugmaController {
|
|
70
99
|
activeId: string | null;
|
|
71
100
|
setActiveId: Dispatch<SetStateAction<string | null>>;
|
|
72
101
|
activeType: 'pane' | 'tab' | null;
|
|
@@ -84,7 +113,7 @@ interface ZeugmaController {
|
|
|
84
113
|
onRemove?: (paneId: string) => void;
|
|
85
114
|
onDragStart?: (activeId: string) => void;
|
|
86
115
|
onDragEnd?: (activeId: string, overId: string | null, dropAction: {
|
|
87
|
-
type: 'split' | '
|
|
116
|
+
type: 'split' | 'move';
|
|
88
117
|
direction?: SplitDirection;
|
|
89
118
|
position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
|
|
90
119
|
} | null) => void;
|
|
@@ -92,18 +121,15 @@ interface ZeugmaController {
|
|
|
92
121
|
onResize?: (currentNode: SplitNode, percentage: number) => void;
|
|
93
122
|
onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
|
|
94
123
|
onDismissIntentChange?: (paneId: string | null) => void;
|
|
95
|
-
removePane: (paneId: string) => void;
|
|
96
|
-
addPane: (paneId: string) => void;
|
|
97
124
|
splitPane: (targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string) => void;
|
|
98
125
|
updateSplitPercentage: (currentNode: SplitNode, percentage: number) => void;
|
|
99
|
-
updateTabMetadata: (tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
|
|
100
|
-
updatePaneLock: (paneId: string, locked: boolean) => void;
|
|
101
|
-
selectTab: (paneId: string, tabId: string) => void;
|
|
102
|
-
mergeTab: (draggedTabId: string, targetPaneId: string) => void;
|
|
103
126
|
moveTab: (draggedTabId: string, targetTabId: string, position?: 'before' | 'after') => void;
|
|
104
|
-
removeTab: (tabId: string) => void;
|
|
105
127
|
}
|
|
106
128
|
interface ZeugmaClassNames {
|
|
129
|
+
/** CSS class applied to the root dashboard container. */
|
|
130
|
+
dashboard?: string;
|
|
131
|
+
/** CSS class applied to the root dashboard container when a drag-out dismiss is active. */
|
|
132
|
+
dashboardDismissActive?: string;
|
|
107
133
|
/** CSS class applied to the outer container div of each `<Pane>`. */
|
|
108
134
|
pane?: string;
|
|
109
135
|
/** CSS class applied to the pane container when locked. */
|
|
@@ -120,13 +146,15 @@ interface ZeugmaClassNames {
|
|
|
120
146
|
dashboardLocked?: string;
|
|
121
147
|
/** CSS class applied to drop zone indicator when hovering over a locked pane. */
|
|
122
148
|
lockedPreview?: string;
|
|
149
|
+
/** CSS class applied to tab container when dragging a tab over it. */
|
|
150
|
+
tabDropPreview?: string;
|
|
123
151
|
}
|
|
124
152
|
interface ZeugmaProps extends ZeugmaController {
|
|
125
153
|
/** Render function mapping unique pane IDs to React elements. Usually renders a <Pane> wrapper. */
|
|
126
154
|
renderPane: (paneId: string) => ReactNode;
|
|
127
155
|
/** Custom overlay renderer function used to customize the cursor-following drag preview for an active pane or tab. */
|
|
128
156
|
renderDragOverlay?: (activeId: string, type: 'pane' | 'tab') => ReactNode;
|
|
129
|
-
/** Optional CSS class name mapping overrides for custom styles of components like panes, drop
|
|
157
|
+
/** Optional CSS class name mapping overrides for custom styles of components like panes, drop previews, overlays, etc. */
|
|
130
158
|
classNames?: ZeugmaClassNames;
|
|
131
159
|
/** Render function mapping tab IDs to React elements. Used to render tab widgets inside portals. */
|
|
132
160
|
renderWidget?: (tabId: string) => ReactNode;
|
|
@@ -141,37 +169,33 @@ interface ZeugmaStateValue {
|
|
|
141
169
|
/** The current active layout tree structure, or null if empty. */
|
|
142
170
|
layout: TreeNode | null;
|
|
143
171
|
/** Callback to update the layout tree. */
|
|
144
|
-
|
|
172
|
+
setLayout: Dispatch<SetStateAction<TreeNode | null>>;
|
|
145
173
|
/** Renders the inner content of a pane given its unique ID. */
|
|
146
174
|
renderPane: (paneId: string) => ReactNode;
|
|
147
|
-
/** The ID of the pane currently being dragged, or null. */
|
|
148
|
-
activeId: string | null;
|
|
149
|
-
/** The ID of the pane currently targeted for dismiss/drag-out, or null. */
|
|
150
|
-
dismissIntentId: string | null;
|
|
151
|
-
/** Ref setter to measure and track the dashboard root container element. */
|
|
152
|
-
setContainerRef: (element: HTMLElement | null) => void;
|
|
153
175
|
/** The ID of the pane currently zoomed to fullscreen, or null. */
|
|
154
176
|
fullscreenPaneId: string | null;
|
|
155
177
|
/** Normalized or overridden CSS classes for custom layout styling. */
|
|
156
178
|
classNames: ZeugmaClassNames;
|
|
157
|
-
/**
|
|
179
|
+
/** Whether the layout is globally locked. */
|
|
180
|
+
locked: boolean;
|
|
181
|
+
}
|
|
182
|
+
/** @internal */
|
|
183
|
+
interface ZeugmaInternalStateValue extends ZeugmaStateValue {
|
|
184
|
+
/** The ID of the tab currently hovered over during a tab drag, or null. */
|
|
185
|
+
overTabId: string | null;
|
|
186
|
+
/** The position of the tab drop preview relative to the hovered tab ('before' | 'after'). */
|
|
187
|
+
overTabPosition: 'before' | 'after' | null;
|
|
188
|
+
activeId: string | null;
|
|
189
|
+
dismissIntentId: string | null;
|
|
190
|
+
setContainerRef: (element: HTMLElement | null) => void;
|
|
158
191
|
onRemove?: (paneId: string) => void;
|
|
159
|
-
/** Callback triggered to toggle fullscreen status for a pane. */
|
|
160
192
|
onFullscreenChange?: (paneId: string | null) => void;
|
|
161
|
-
/** Threshold in pixels to snap layout resizers to adjacent edges. */
|
|
162
193
|
snapThreshold?: number;
|
|
163
|
-
/** Callback triggered when a split pane starts being resized. */
|
|
164
194
|
onResizeStart?: (currentNode: SplitNode) => void;
|
|
165
|
-
/** Callback triggered continuously during a split pane resize. */
|
|
166
195
|
onResize?: (currentNode: SplitNode, percentage: number) => void;
|
|
167
|
-
/** Callback triggered when a split pane resize action is completed. */
|
|
168
196
|
onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
|
|
169
|
-
/** Minimum split percentage allowed when resizing. */
|
|
170
197
|
minSplitPercentage?: number;
|
|
171
|
-
/** Maximum split percentage allowed when resizing. */
|
|
172
198
|
maxSplitPercentage?: number;
|
|
173
|
-
/** Whether the layout is globally locked. */
|
|
174
|
-
locked: boolean;
|
|
175
199
|
}
|
|
176
200
|
/**
|
|
177
201
|
* Actions context — holds stable dispatch functions with permanent identity.
|
|
@@ -182,10 +206,6 @@ interface ZeugmaActionsValue {
|
|
|
182
206
|
removePane: (paneId: string) => void;
|
|
183
207
|
/** Appends/inserts a pane at the bottom-rightmost leaf of the layout tree. */
|
|
184
208
|
addPane: (paneId: string) => void;
|
|
185
|
-
/** Splits a target pane with a new pane in the specified direction and side. */
|
|
186
|
-
splitPane: (targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string) => void;
|
|
187
|
-
/** Updates the split percentage of a specific split branch node. */
|
|
188
|
-
updateSplitPercentage: (currentNode: SplitNode, percentage: number) => void;
|
|
189
209
|
/** Stable callback to update metadata for a specific tab. */
|
|
190
210
|
updateTabMetadata: (tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
|
|
191
211
|
/** Stable callback to update the locked status of a specific pane in the layout tree. */
|
|
@@ -194,22 +214,131 @@ interface ZeugmaActionsValue {
|
|
|
194
214
|
selectTab: (paneId: string, tabId: string) => void;
|
|
195
215
|
/** Stable callback to merge a dragged tab/pane into another pane's tab list. */
|
|
196
216
|
mergeTab: (draggedTabId: string, targetPaneId: string) => void;
|
|
197
|
-
/** Stable callback to move/reorder a tab to another pane next to a target tab. */
|
|
198
|
-
moveTab: (draggedTabId: string, targetTabId: string, position?: 'before' | 'after') => void;
|
|
199
217
|
/** Stable callback to remove/close a specific tab from the layout. */
|
|
200
218
|
removeTab: (tabId: string) => void;
|
|
201
219
|
}
|
|
202
220
|
interface ZeugmaContextValue extends ZeugmaStateValue, ZeugmaActionsValue {
|
|
203
221
|
}
|
|
222
|
+
interface PortalRegistryValue {
|
|
223
|
+
registerPortalTarget: (tabId: string, el: HTMLDivElement | null) => void;
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
declare function generateUniqueId(): string;
|
|
227
|
+
/**
|
|
228
|
+
* Tree Helper: Remove a pane container and consolidate the tree structure.
|
|
229
|
+
*/
|
|
230
|
+
declare function removePane(tree: TreeNode | null, paneId: string): TreeNode | null;
|
|
231
|
+
/**
|
|
232
|
+
* Tree Helper: Remove a tab from a pane and consolidate the tree structure if no tabs remain.
|
|
233
|
+
*/
|
|
234
|
+
declare function removeTab(tree: TreeNode | null, tabId: string): TreeNode | null;
|
|
235
|
+
/**
|
|
236
|
+
* Tree Helper: Insert a pane by splitting an existing target node.
|
|
237
|
+
*/
|
|
238
|
+
declare function splitPane(tree: TreeNode | null, targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string | PaneNode): TreeNode | null;
|
|
239
|
+
/**
|
|
240
|
+
* Tree Helper: Add a pane by recursively splitting the rightmost/bottommost pane in the tree.
|
|
241
|
+
*/
|
|
242
|
+
declare function addPane(tree: TreeNode | null, paneToAdd: string): TreeNode;
|
|
243
|
+
/**
|
|
244
|
+
* Tree Helper: Update split percentage recursively.
|
|
245
|
+
*/
|
|
246
|
+
declare function updateSplitPercentage(tree: TreeNode | null, target: SplitNode, newPercentage: number): TreeNode | null;
|
|
247
|
+
/**
|
|
248
|
+
* Find a PaneNode by its ID.
|
|
249
|
+
*/
|
|
250
|
+
declare function findPaneById(tree: TreeNode | null, paneId: string): PaneNode | null;
|
|
251
|
+
/**
|
|
252
|
+
* Find a PaneNode containing the given tab ID.
|
|
253
|
+
*/
|
|
254
|
+
declare function findPaneContainingTab(tree: TreeNode | null, tabId: string): PaneNode | null;
|
|
255
|
+
/**
|
|
256
|
+
* Update metadata on a specific tab node using an updater function.
|
|
257
|
+
*/
|
|
258
|
+
declare function updateTabMetadata(tree: TreeNode | null, tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined): TreeNode | null;
|
|
259
|
+
/**
|
|
260
|
+
* Update the locked status on a specific pane node in the layout tree.
|
|
261
|
+
*/
|
|
262
|
+
declare function updatePaneLock(tree: TreeNode | null, paneId: string, locked: boolean): TreeNode | null;
|
|
263
|
+
/**
|
|
264
|
+
* Tree Helper: Activate a tab within a pane.
|
|
265
|
+
*/
|
|
266
|
+
declare function selectTab(tree: TreeNode | null, paneId: string, tabId: string): TreeNode | null;
|
|
267
|
+
/**
|
|
268
|
+
* Tree Helper: Merge a tab into a target pane node.
|
|
269
|
+
*/
|
|
270
|
+
declare function mergeTab(tree: TreeNode | null, draggedTabId: string, targetPaneId: string): TreeNode | null;
|
|
271
|
+
/**
|
|
272
|
+
* Tree Helper: Move/reorder a tab inside or to a target pane next to a target tab.
|
|
273
|
+
*/
|
|
274
|
+
declare function moveTab(tree: TreeNode | null, draggedTabId: string, targetTabId: string, position?: 'before' | 'after'): TreeNode | null;
|
|
275
|
+
interface ComputedPane {
|
|
276
|
+
paneId: string;
|
|
277
|
+
left: number;
|
|
278
|
+
top: number;
|
|
279
|
+
width: number;
|
|
280
|
+
height: number;
|
|
281
|
+
node: PaneNode;
|
|
282
|
+
}
|
|
283
|
+
interface ComputedSplitter {
|
|
284
|
+
id: string;
|
|
285
|
+
currentNode: SplitNode;
|
|
286
|
+
direction: SplitDirection;
|
|
287
|
+
left: number;
|
|
288
|
+
top: number;
|
|
289
|
+
width: number;
|
|
290
|
+
height: number;
|
|
291
|
+
parentLeft: number;
|
|
292
|
+
parentTop: number;
|
|
293
|
+
parentWidth: number;
|
|
294
|
+
parentHeight: number;
|
|
295
|
+
}
|
|
296
|
+
declare function computeLayout(node: TreeNode | null, left?: number, top?: number, width?: number, height?: number, path?: string): {
|
|
297
|
+
panes: ComputedPane[];
|
|
298
|
+
splitters: ComputedSplitter[];
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Shared drag-session lifecycle utility.
|
|
303
|
+
*
|
|
304
|
+
* Handles the common boilerplate for pointer-based resize operations:
|
|
305
|
+
* - Adds `zeugma-resizing` class to `document.body`
|
|
306
|
+
* - Injects a global `cursor` style so the resize cursor stays active
|
|
307
|
+
* even when the pointer leaves the handle element
|
|
308
|
+
* - Sets `data-resizing` on the resizer element
|
|
309
|
+
* - Attaches `pointermove` / `pointerup` listeners to `document`
|
|
310
|
+
* - Cleans everything up on pointer-up
|
|
311
|
+
*
|
|
312
|
+
* Consumers provide domain-specific `onMove` and `onEnd` callbacks.
|
|
313
|
+
*/
|
|
314
|
+
interface DragSessionConfig {
|
|
315
|
+
/** CSS cursor to enforce globally during the drag */
|
|
316
|
+
cursor: 'col-resize' | 'row-resize';
|
|
317
|
+
/** The resizer DOM element (receives `data-resizing` attribute) */
|
|
318
|
+
resizerEl: HTMLElement;
|
|
319
|
+
/** Called on every `pointermove` during the drag */
|
|
320
|
+
onMove: (e: PointerEvent) => void;
|
|
321
|
+
/** Called once on `pointerup` — after cleanup has already run */
|
|
322
|
+
onEnd: () => void;
|
|
323
|
+
}
|
|
324
|
+
declare function createDragSession({ cursor, resizerEl, onMove, onEnd }: DragSessionConfig): void;
|
|
325
|
+
|
|
326
|
+
declare function safeJsonStringify(val: unknown): string;
|
|
327
|
+
|
|
328
|
+
declare const ZeugmaStateContext: React.Context<ZeugmaInternalStateValue | undefined>;
|
|
329
|
+
declare const ZeugmaActionsContext: React.Context<ZeugmaActionsValue | undefined>;
|
|
330
|
+
declare const PortalRegistryContext: React.Context<PortalRegistryValue | undefined>;
|
|
331
|
+
declare const useZeugmaState: () => ZeugmaStateValue;
|
|
332
|
+
declare const useZeugmaActions: () => ZeugmaActionsValue;
|
|
204
333
|
|
|
205
334
|
declare function useZeugma(options: UseZeugmaOptions): ZeugmaController;
|
|
206
335
|
|
|
207
336
|
declare const useZeugmaContext: () => ZeugmaContextValue;
|
|
208
337
|
|
|
209
|
-
declare const Zeugma:
|
|
338
|
+
declare const Zeugma: React__default.FC<ZeugmaProps>;
|
|
210
339
|
|
|
211
340
|
interface UseResizerProps {
|
|
212
|
-
containerRef:
|
|
341
|
+
containerRef: React__default.RefObject<HTMLDivElement | null>;
|
|
213
342
|
isRow: boolean;
|
|
214
343
|
direction: SplitDirection;
|
|
215
344
|
splitPercentage: number;
|
|
@@ -225,7 +354,7 @@ interface UseResizerProps {
|
|
|
225
354
|
parentWidth: number;
|
|
226
355
|
parentHeight: number;
|
|
227
356
|
}
|
|
228
|
-
declare function useResizer({ containerRef, isRow, direction, splitPercentage, resizerSize, snapThreshold, layout, currentNode, onLayoutChange, onResizeStart: localOnResizeStart, onResizeEnd: localOnResizeEnd, parentLeft, parentTop, parentWidth, parentHeight, }: UseResizerProps): (e:
|
|
357
|
+
declare function useResizer({ containerRef, isRow, direction, splitPercentage, resizerSize, snapThreshold, layout, currentNode, onLayoutChange, onResizeStart: localOnResizeStart, onResizeEnd: localOnResizeEnd, parentLeft, parentTop, parentWidth, parentHeight, }: UseResizerProps): (e: React__default.PointerEvent<HTMLDivElement>) => void;
|
|
229
358
|
|
|
230
359
|
interface PaneTreeProps {
|
|
231
360
|
/** The layout subtree node to render. If not specified, defaults to the root layout tree from the Zeugma context. */
|
|
@@ -235,10 +364,10 @@ interface PaneTreeProps {
|
|
|
235
364
|
/** Threshold distance in pixels to snap layout resizers to adjacent edges (default 8). */
|
|
236
365
|
snapThreshold?: number;
|
|
237
366
|
}
|
|
238
|
-
declare const PaneTree:
|
|
367
|
+
declare const PaneTree: React__default.FC<PaneTreeProps>;
|
|
239
368
|
|
|
240
369
|
interface ResizableContainerProps {
|
|
241
|
-
children:
|
|
370
|
+
children: React__default.ReactNode;
|
|
242
371
|
/** Whether the resizable container is active. When false, acts as a normal 100% height container. */
|
|
243
372
|
active?: boolean;
|
|
244
373
|
/** Current height in pixels (controlled mode) or default/initial height */
|
|
@@ -260,7 +389,7 @@ interface ResizableContainerProps {
|
|
|
260
389
|
/** CSS class applied to the resizer handle */
|
|
261
390
|
resizerClassName?: string;
|
|
262
391
|
}
|
|
263
|
-
declare const ResizableContainer:
|
|
392
|
+
declare const ResizableContainer: React__default.FC<ResizableContainerProps>;
|
|
264
393
|
|
|
265
394
|
interface PaneRenderProps {
|
|
266
395
|
/** True if the pane is actively being dragged. */
|
|
@@ -297,23 +426,23 @@ interface PaneProps {
|
|
|
297
426
|
/** The unique ID of the pane, matching a `paneId` in the layout tree schema. */
|
|
298
427
|
id: string;
|
|
299
428
|
/** Render prop function providing pane state (isDragging, isFullscreen, etc.) and handlers. */
|
|
300
|
-
children: (props: PaneRenderProps) =>
|
|
429
|
+
children: (props: PaneRenderProps) => React__default.ReactNode;
|
|
301
430
|
/** Optional inline CSS styles applied to the pane outer container. */
|
|
302
|
-
style?:
|
|
431
|
+
style?: React__default.CSSProperties;
|
|
303
432
|
/** Optional override to lock this specific pane. */
|
|
304
433
|
locked?: boolean;
|
|
305
434
|
}
|
|
306
|
-
declare const Pane:
|
|
435
|
+
declare const Pane: React__default.FC<PaneProps>;
|
|
307
436
|
|
|
308
437
|
interface DragHandleProps {
|
|
309
438
|
/** The children elements that will trigger dragging when held and dragged. */
|
|
310
|
-
children?:
|
|
439
|
+
children?: React__default.ReactNode;
|
|
311
440
|
/** Custom CSS class applied to the drag handle element. */
|
|
312
441
|
className?: string;
|
|
313
442
|
/** Optional inline CSS styles applied to the drag handle. */
|
|
314
|
-
style?:
|
|
443
|
+
style?: React__default.CSSProperties;
|
|
315
444
|
}
|
|
316
|
-
declare const DragHandle:
|
|
445
|
+
declare const DragHandle: React__default.FC<DragHandleProps>;
|
|
317
446
|
|
|
318
447
|
interface TabRenderProps {
|
|
319
448
|
isDragging: boolean;
|
|
@@ -325,112 +454,12 @@ interface TabProps {
|
|
|
325
454
|
/** Whether dragging is locked on this tab. */
|
|
326
455
|
locked?: boolean;
|
|
327
456
|
/** Render prop child function. */
|
|
328
|
-
children: (props: TabRenderProps) =>
|
|
457
|
+
children: (props: TabRenderProps) => React__default.ReactNode;
|
|
329
458
|
/** Custom CSS class applied to the tab wrapper. */
|
|
330
459
|
className?: string;
|
|
331
460
|
/** Custom inline CSS style applied to the tab wrapper. */
|
|
332
|
-
style?:
|
|
461
|
+
style?: React__default.CSSProperties;
|
|
333
462
|
}
|
|
334
|
-
declare const Tab:
|
|
335
|
-
|
|
336
|
-
declare const DEFAULT_SNAP_THRESHOLD = 8;
|
|
337
|
-
declare const DEFAULT_DRAG_ACTIVATION_DISTANCE = 8;
|
|
338
|
-
declare const DEFAULT_RESIZER_SIZE = 4;
|
|
339
|
-
|
|
340
|
-
declare function generateUniqueId(): string;
|
|
341
|
-
/**
|
|
342
|
-
* Tree Helper: Remove a pane container and consolidate the tree structure.
|
|
343
|
-
*/
|
|
344
|
-
declare function removePane(tree: TreeNode | null, paneId: string): TreeNode | null;
|
|
345
|
-
/**
|
|
346
|
-
* Tree Helper: Remove a tab from a pane and consolidate the tree structure if no tabs remain.
|
|
347
|
-
*/
|
|
348
|
-
declare function removeTab(tree: TreeNode | null, tabId: string): TreeNode | null;
|
|
349
|
-
/**
|
|
350
|
-
* Tree Helper: Insert a pane by splitting an existing target node.
|
|
351
|
-
*/
|
|
352
|
-
declare function splitPane(tree: TreeNode | null, targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string | PaneNode): TreeNode | null;
|
|
353
|
-
/**
|
|
354
|
-
* Tree Helper: Add a pane by recursively splitting the rightmost/bottommost pane in the tree.
|
|
355
|
-
*/
|
|
356
|
-
declare function addPane(tree: TreeNode | null, paneToAdd: string): TreeNode;
|
|
357
|
-
/**
|
|
358
|
-
* Tree Helper: Update split percentage recursively.
|
|
359
|
-
*/
|
|
360
|
-
declare function updateSplitPercentage(tree: TreeNode | null, target: SplitNode, newPercentage: number): TreeNode | null;
|
|
361
|
-
/**
|
|
362
|
-
* Find a PaneNode by its ID or by any of its tab IDs.
|
|
363
|
-
*/
|
|
364
|
-
declare function findPane(tree: TreeNode | null, paneId: string): PaneNode | null;
|
|
365
|
-
/**
|
|
366
|
-
* Update metadata on a specific tab node using an updater function.
|
|
367
|
-
*/
|
|
368
|
-
declare function updateTabMetadata(tree: TreeNode | null, tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined): TreeNode | null;
|
|
369
|
-
/**
|
|
370
|
-
* Update the locked status on a specific pane node in the layout tree.
|
|
371
|
-
*/
|
|
372
|
-
declare function updatePaneLock(tree: TreeNode | null, paneId: string, locked: boolean): TreeNode | null;
|
|
373
|
-
/**
|
|
374
|
-
* Tree Helper: Activate a tab within a pane.
|
|
375
|
-
*/
|
|
376
|
-
declare function selectTab(tree: TreeNode | null, paneId: string, tabId: string): TreeNode | null;
|
|
377
|
-
/**
|
|
378
|
-
* Tree Helper: Merge a tab into a target pane node.
|
|
379
|
-
*/
|
|
380
|
-
declare function mergeTab(tree: TreeNode | null, draggedTabId: string, targetPaneId: string): TreeNode | null;
|
|
381
|
-
/**
|
|
382
|
-
* Tree Helper: Move/reorder a tab inside or to a target pane next to a target tab.
|
|
383
|
-
*/
|
|
384
|
-
declare function moveTab(tree: TreeNode | null, draggedTabId: string, targetTabId: string, position?: 'before' | 'after'): TreeNode | null;
|
|
385
|
-
interface ComputedPane {
|
|
386
|
-
paneId: string;
|
|
387
|
-
left: number;
|
|
388
|
-
top: number;
|
|
389
|
-
width: number;
|
|
390
|
-
height: number;
|
|
391
|
-
node: PaneNode;
|
|
392
|
-
}
|
|
393
|
-
interface ComputedSplitter {
|
|
394
|
-
id: string;
|
|
395
|
-
currentNode: SplitNode;
|
|
396
|
-
direction: SplitDirection;
|
|
397
|
-
left: number;
|
|
398
|
-
top: number;
|
|
399
|
-
width: number;
|
|
400
|
-
height: number;
|
|
401
|
-
parentLeft: number;
|
|
402
|
-
parentTop: number;
|
|
403
|
-
parentWidth: number;
|
|
404
|
-
parentHeight: number;
|
|
405
|
-
}
|
|
406
|
-
declare function computeLayout(node: TreeNode | null, left?: number, top?: number, width?: number, height?: number, path?: string): {
|
|
407
|
-
panes: ComputedPane[];
|
|
408
|
-
splitters: ComputedSplitter[];
|
|
409
|
-
};
|
|
410
|
-
|
|
411
|
-
/**
|
|
412
|
-
* Shared drag-session lifecycle utility.
|
|
413
|
-
*
|
|
414
|
-
* Handles the common boilerplate for pointer-based resize operations:
|
|
415
|
-
* - Adds `zeugma-resizing` class to `document.body`
|
|
416
|
-
* - Injects a global `cursor` style so the resize cursor stays active
|
|
417
|
-
* even when the pointer leaves the handle element
|
|
418
|
-
* - Sets `data-resizing` on the resizer element
|
|
419
|
-
* - Attaches `pointermove` / `pointerup` listeners to `document`
|
|
420
|
-
* - Cleans everything up on pointer-up
|
|
421
|
-
*
|
|
422
|
-
* Consumers provide domain-specific `onMove` and `onEnd` callbacks.
|
|
423
|
-
*/
|
|
424
|
-
interface DragSessionConfig {
|
|
425
|
-
/** CSS cursor to enforce globally during the drag */
|
|
426
|
-
cursor: 'col-resize' | 'row-resize';
|
|
427
|
-
/** The resizer DOM element (receives `data-resizing` attribute) */
|
|
428
|
-
resizerEl: HTMLElement;
|
|
429
|
-
/** Called on every `pointermove` during the drag */
|
|
430
|
-
onMove: (e: PointerEvent) => void;
|
|
431
|
-
/** Called once on `pointerup` — after cleanup has already run */
|
|
432
|
-
onEnd: () => void;
|
|
433
|
-
}
|
|
434
|
-
declare function createDragSession({ cursor, resizerEl, onMove, onEnd }: DragSessionConfig): void;
|
|
463
|
+
declare const Tab: React__default.FC<TabProps>;
|
|
435
464
|
|
|
436
|
-
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 ZeugmaContextValue, type ZeugmaController, type ZeugmaProps, addPane, computeLayout, createDragSession,
|
|
465
|
+
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, PortalRegistryContext, type PortalRegistryValue, ResizableContainer, type ResizableContainerProps, type SplitDirection, type SplitNode, Tab, type TabProps, type TabRenderProps, type TreeNode, type UseZeugmaOptions, Zeugma, ZeugmaActionsContext, type ZeugmaActionsValue, type ZeugmaClassNames, type ZeugmaContextValue, type ZeugmaController, type ZeugmaInternalController, type ZeugmaInternalStateValue, type ZeugmaProps, ZeugmaStateContext, type ZeugmaStateValue, addPane, computeLayout, createDragSession, findPaneById, findPaneContainingTab, generateUniqueId, mergeTab, moveTab, removePane, removeTab, safeJsonStringify, selectTab, splitPane, updatePaneLock, updateSplitPercentage, updateTabMetadata, useResizer, useZeugma, useZeugmaActions, useZeugmaContext, useZeugmaState };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import tn,{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 ee=()=>{let e=useContext(ze);if(!e)throw new Error("useZeugmaState must be used within a Zeugma provider");return e},$e=()=>{let e=useContext(Ie);if(!e)throw new Error("useZeugmaActions must be used within a Zeugma provider");return e};function st(e){let t=useRef(null);return useEffect(()=>{if(!e){t.current=null;return}let r=n=>{t.current={x:n.clientX,y:n.clientY};},s=n=>{let o=n.touches[0]||n.changedTouches[0];o&&(t.current={x:o.clientX,y:o.clientY});};return window.addEventListener("pointermove",r,{passive:true}),window.addEventListener("touchmove",s,{passive:true}),()=>{window.removeEventListener("pointermove",r),window.removeEventListener("touchmove",s);}},[e]),t}function it(e){useEffect(()=>(e?document.body.style.setProperty("cursor","not-allowed","important"):document.body.style.removeProperty("cursor"),()=>{document.body.style.removeProperty("cursor");}),[e]);}function at(){let[e,t]=useState({}),r=useRef(true);useEffect(()=>(r.current=true,()=>{r.current=false;}),[]);let s=useCallback((n,o)=>{setTimeout(()=>{r.current&&t(i=>i[n]===o?i:{...i,[n]:o});},0);},[]);return {portalTargets:e,registerPortalTarget:s}}var ke=createContext(void 0);var Ht=8,At=8,Fn=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),s=be(e.second,t);return r===null?s:s===null?r:{...e,first:r,second:s}}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 o=e.activeTabId;e.activeTabId===t&&(o=n[0]);let i={...e.tabsMetadata};return delete i[t],{...e,tabs:n,activeTabId:o,tabsMetadata:Object.keys(i).length>0?i:void 0}}return e}let r=de(e.first,t),s=de(e.second,t);return r===null?s:s===null?r:{...e,first:r,second:s}}function ye(e,t,r,s,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 o=typeof n=="string"?{type:"pane",id:ie(),tabs:[n],activeTabId:n}:n,i=s==="left"||s==="top";return {type:"split",direction:r,first:i?o:e,second:i?e:o,splitPercentage:50}}return e}return {...e,first:ye(e.first,t,r,s,n)||e.first,second:ye(e.second,t,r,s,n)||e.second}}function lt(e,t){if(e===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t};function r(s,n){return s.type==="pane"?{type:"split",direction:n==="row"?"column":"row",splitPercentage:50,first:s,second:{type:"pane",id:ie(),tabs:[t],activeTabId:t}}:{...s,second:r(s.second,s.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 Ze(e,t,r){if(e===null)return null;if(e.type==="pane"){if(e.id===t||e.tabs.includes(t)){let s=e.tabsMetadata||{},n=s[t],o=r(n),i={...s};return o===void 0?delete i[t]:i[t]=o,{...e,tabsMetadata:Object.keys(i).length>0?i:void 0}}return e}return {...e,first:Ze(e.first,t,r)??e.first,second:Ze(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:s,...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 Ae(e,t,r){return e===null?null:e.type==="pane"?e.id===t||e.tabs.includes(t)?{...e,activeTabId:r}:e:{...e,first:Ae(e.first,t,r)??e.first,second:Ae(e.second,t,r)??e.second}}function ct(e,t,r){if(e===null)return null;let n=q(e,t)?.tabsMetadata?.[t],o=de(e,t);if(o===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(o)}function ut(e,t,r,s="before"){if(e===null)return null;let o=q(e,t)?.tabsMetadata?.[t],i=de(e,t);if(i===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t,tabsMetadata:o?{[t]:o}:void 0};function a(l){if(l.type==="pane"){if(l.id===r||l.tabs.includes(r)){let D=[...l.tabs].filter(x=>x!==t),c=D.indexOf(r);c<0&&(c=0),s==="after"&&(c+=1),D.splice(c,0,t);let T={...l.tabsMetadata};return o&&(T[t]=o),{...l,tabs:D,activeTabId:t,tabsMetadata:Object.keys(T).length>0?T:void 0}}return l}return {...l,first:a(l.first),second:a(l.second)}}return a(i)}function se(e,t=0,r=0,s=100,n=100,o="root"){if(e===null)return {panes:[],splitters:[]};if(e.type==="pane")return {panes:[{paneId:e.id,left:t,top:r,width:s,height:n,node:e}],splitters:[]};let{direction:i,splitPercentage:a,first:l,second:y}=e,c={id:`splitter-${o}-${i}`,currentNode:e,direction:i,left:i==="row"?t+s*(a/100):t,top:i==="column"?r+n*(a/100):r,width:i==="row"?0:s,height:i==="column"?0:n,parentLeft:t,parentTop:r,parentWidth:s,parentHeight:n},T={panes:[],splitters:[]},x={panes:[],splitters:[]};if(i==="row"){let v=s*(a/100);T=se(l,t,r,v,n,`${o}-L`),x=se(y,t+v,r,s-v,n,`${o}-R`);}else {let v=n*(a/100);T=se(l,t,r,s,v,`${o}-T`),x=se(y,t,r+v,s,n-v,`${o}-B`);}return {panes:[...T.panes,...x.panes],splitters:[c,...T.splitters,...x.splitters]}}function Ft(e){let{initialLayout:t,onChange:r,fullscreenPaneId:s,onFullscreenChange:n,locked:o=false,dragActivationDistance:i=8,snapThreshold:a=8,minSplitPercentage:l=5,maxSplitPercentage:y=95,enableDragToDismiss:D=false,dismissThreshold:c=60,onRemove:T,onDragStart:x,onDragEnd:v,onResizeStart:R,onResize:E,onResizeEnd:L,onDismissIntentChange:p}=e,[b,f]=useState(t),[z,A]=useState(s||null),[I,V]=useState(o),[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(o);},[o]),useEffect(()=>{s!==void 0&&A(s);},[s]);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=>lt(S,u));},[]),B=useCallback((u,S,P,ne)=>{f(Re=>{let Ye=q(Re,ne)??{type:"pane",id:ne,tabs:[ne],activeTabId:ne},Be=be(Re,ne);return ye(Be,u,S,P,Ye)});},[]),ae=useCallback((u,S)=>{f(P=>ve(P,u,S));},[]),W=useCallback((u,S)=>{f(P=>Ze(P,u,S));},[]),te=useCallback((u,S)=>{f(P=>He(P,u,S));},[]),le=useCallback((u,S)=>{f(P=>Ae(P,u,S));},[]),fe=useCallback((u,S)=>{f(P=>ct(P,u,S));},[]),me=useCallback((u,S,P)=>{f(ne=>ut(ne,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:T,onDragStart:x,onDragEnd:v,onResizeStart:R,onResize:E,onResizeEnd:L,onDismissIntentChange:p,removePane:N,addPane:d,splitPane:B,updateSplitPercentage:ae,updateTabMetadata:W,updatePaneLock:te,selectTab:le,mergeTab:fe,moveTab:me,removeTab:j}}var Ot=()=>{let e=ee(),t=$e();return {...e,...t}};var pt=({activeId:e,render:t,className:r})=>{let s=useRef(null);return useEffect(()=>{let n=o=>{s.current&&(s.current.style.transform=`translate(${o.clientX+12}px, ${o.clientY+12}px)`);};return document.addEventListener("pointermove",n),()=>document.removeEventListener("pointermove",n)},[]),jsx("div",{ref:s,className:r,style:{position:"fixed",top:0,left:0,zIndex:9999,pointerEvents:"none"},children:t(e)})};var Fe=class extends PointerSensor{static activators=[{eventName:"onPointerDown",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]},Oe=class extends TouchSensor{static activators=[{eventName:"onTouchStart",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]};function je(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 jt=e=>{let{renderPane:t,renderWidget:r,renderDragOverlay:s,classNames:n={},children:o,layout:i,setLayout:a,fullscreenPaneId:l,setFullscreenPaneId:y,locked:D,activeId:c,setActiveId:T,activeType:x,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:te,removeTab:le}=e,{portalTargets:fe,registerPortalTarget:me}=at(),j=useRef(null),u=st(c),[S,P]=useState(false);it(S);let ne=useCallback(g=>t(g),[t]),Re=useMemo(()=>n,[n.pane,n.paneLocked,n.dropPreview,n.dragOverlay,n.resizer,n.dismissPreview,n.dashboardLocked,n.lockedPreview]),Ye=useSensors(useSensor(Fe,{activationConstraint:{distance:b}}),useSensor(Oe,{activationConstraint:{delay:250,tolerance:5}})),Be=useCallback(g=>{let Z=pointerWithin(g);if(Z.length>0)return Z;if(g.active.id.toString().startsWith("tab-header-")){let re=g.droppableContainers.filter(J=>J.id.toString().startsWith("tab-drop-"));return closestCenter({...g,droppableContainers:re})}return []},[]),Dt=g=>{let Z=g.active.id.toString(),U=Z.startsWith("tab-header-"),re=U?Z.substring(11):Z;T(re),v(U?"tab":"pane");let J=g.activatorEvent;u.current=je(J),I&&L.current?j.current=L.current.getBoundingClientRect():j.current=null,K&&K(re);},Et=g=>{let{over:Z}=g,re=(Z?.id.toString()||"").startsWith("drop-locked-");if(P(re),!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,oe=null,X=null;if(u.current)oe=u.current.x,X=u.current.y;else {let H=je(we);H&&(oe=H.x+g.delta.x,X=H.y+g.delta.y);}let ce=0;if(oe!==null&&X!==null){let H=0,Q=0;oe<M.left?H=M.left-oe:oe>M.right&&(H=oe-M.right),X<M.top?Q=M.top-X:X>M.bottom&&(Q=X-M.bottom),ce=Math.sqrt(H*H+Q*Q);}else {let H=g.active.rect.current.translated;if(H){let Q=H.left+H.width/2,ge=H.top+H.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));},Ct=g=>{T(null),v(null),P(false);let{active:Z,over:U}=g,re=Z.id.toString(),J=re.startsWith("tab-header-"),C=J?re.substring(11):re,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",tt=U.rect,It=g.activatorEvent,Me=null;if(u.current)Me=u.current.x;else {let Le=je(It);Le&&(Me=Le.x+g.delta.x);}if(Me!==null){let Le=tt.left+tt.width/2;Me>Le&&(Ee="after");}te(C,Ne,Ee);}h&&h(C,Ne,{type:"swap",position:"center"});return}let oe=M.match(/^drop-(left|right|top|bottom)-(.+)$/);if(!oe){h&&h(C,null,null);return}let[,X,ce]=oe,De=q(i,C),H=De&&De.id===ce,Q=De&&De.tabs.length===1;if(C===ce||H&&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),zt=ye(Pe,ce,ge,X,ue);a(zt),h&&h(C,ce,{type:"split",direction:ge,position:X});},et=useCallback((g,Z)=>{O&&O(g,Z);},[O]),wt=useMemo(()=>({layout:i,onLayoutChange:g=>a(g),renderPane:ne,activeId:c,dismissIntentId:R,setContainerRef:p,fullscreenPaneId:l,classNames:Re,onRemove:w,onFullscreenChange:y,snapThreshold:f,onResizeStart:F,onResize:Y,onResizeEnd:et,minSplitPercentage:z,maxSplitPercentage:A,locked:D}),[i,c,R,p,l,Re,w,y,f,F,Y,z,A,a,ne,et,D]),Nt=useMemo(()=>({removePane:$,addPane:_,splitPane:k,updateSplitPercentage:N,updateTabMetadata:d,updatePaneLock:B,selectTab:ae,mergeTab:W,moveTab:te,removeTab:le}),[$,_,k,N,d,B,ae,W,te,le]),Mt=useMemo(()=>{let g=[];function Z(U){U&&(U.type==="pane"?g.push(...U.tabs):(Z(U.first),Z(U.second)));}return Z(i),g},[i]),Lt=useMemo(()=>({registerPortalTarget:me}),[me]);return jsx(Ie.Provider,{value:Nt,children:jsx(ze.Provider,{value:wt,children:jsxs(ke.Provider,{value:Lt,children:[jsx(DndContext,{id:"zeugma-dnd-context",sensors:Ye,collisionDetection:Be,onDragStart:Dt,onDragMove:Et,onDragEnd:Ct,children:o}),c&&x&&s&&jsx(pt,{activeId:c,render:g=>s(g,x),className:`${n.dragOverlay||""} ${c===R?n.dismissPreview||"zeugma-dismiss-preview":""}`.trim()}),jsx("div",{id:"zeugma-portal-host",style:{display:"none"},children:Mt.map(g=>jsx(Jt,{tabId:g,target:fe[g]||null,renderWidget:r},g))})]})})})},Jt=({tabId:e,target:t,renderWidget:r})=>{let[s,n]=useState(false),o=useRef(null);if(useEffect(()=>{n(true);},[]),useEffect(()=>{if(!s||!o.current)return;let a=o.current;if(t)t.appendChild(a);else {let l=document.getElementById("zeugma-hidden-portal-container");l||(l=document.createElement("div"),l.id="zeugma-hidden-portal-container",l.style.display="none",document.body.appendChild(l)),l.appendChild(a);}},[t,s]),useEffect(()=>()=>{o.current&&o.current.remove();},[]),!s)return null;o.current||(o.current=document.createElement("div"),o.current.className=`zeugma-portal-wrapper-${e}`,o.current.style.width="100%",o.current.style.height="100%");let i=o.current;return !i||!r?null:createPortal(r(e),i)};function Ve({cursor:e,resizerEl:t,onMove:r,onEnd:s}){document.body.classList.add("zeugma-resizing");let n=document.createElement("style");n.id="zeugma-global-cursor-style",n.textContent=`
|
|
1
|
+
import $t,{createContext,useContext,useState,useRef,useCallback,useEffect,useMemo}from'react';import {DndContext,useDraggable,useDroppable,useSensors,useSensor,pointerWithin,closestCenter,PointerSensor,TouchSensor}from'@dnd-kit/core';import {jsx,Fragment,jsxs}from'react/jsx-runtime';import {createPortal}from'react-dom';function Ae(e){let t=useRef(null);return useEffect(()=>{if(!e){t.current=null;return}let n=r=>{t.current={x:r.clientX,y:r.clientY};},s=r=>{let o=r.touches[0]||r.changedTouches[0];o&&(t.current={x:o.clientX,y:o.clientY});};return window.addEventListener("pointermove",n,{passive:true}),window.addEventListener("touchmove",s,{passive:true}),()=>{window.removeEventListener("pointermove",n),window.removeEventListener("touchmove",s);}},[e]),t}function Fe(e){useEffect(()=>(e?document.body.style.setProperty("cursor","not-allowed","important"):document.body.style.removeProperty("cursor"),()=>{document.body.style.removeProperty("cursor");}),[e]);}function Oe(){let[e,t]=useState({}),n=useRef(true);useEffect(()=>(n.current=true,()=>{n.current=false;}),[]);let s=useCallback((r,o)=>{n.current&&t(i=>i[r]===o?i:{...i,[r]:o});},[]);return {portalTargets:e,registerPortalTarget:s}}var dt=8,pt=8,gn=4;function ie(){return "pane-"+Math.random().toString(36).substring(2,11)}function ue(e,t){if(e===null)return null;if(e.type==="pane")return e.id===t?null:e;let n=ue(e.first,t),s=ue(e.second,t);return n===null?s:s===null?n:{...e,first:n,second:s}}function ae(e,t){if(e===null)return null;if(e.type==="pane"){if(e.tabs.includes(t)){let r=e.tabs.filter(a=>a!==t);if(r.length===0)return null;let o=e.activeTabId;e.activeTabId===t&&(o=r[0]);let i={...e.tabsMetadata};return delete i[t],{...e,tabs:r,activeTabId:o,tabsMetadata:Object.keys(i).length>0?i:void 0}}return e}let n=ae(e.first,t),s=ae(e.second,t);return n===null?s:s===null?n:{...e,first:n,second:s}}function me(e,t,n,s,r){if(e===null)return typeof r=="string"?{type:"pane",id:ie(),tabs:[r],activeTabId:r}:r;if(e.type==="pane"){if(e.id===t){let o=typeof r=="string"?{type:"pane",id:ie(),tabs:[r],activeTabId:r}:r,i=s==="left"||s==="top";return {type:"split",direction:n,first:i?o:e,second:i?e:o,splitPercentage:50}}return e}return {...e,first:me(e.first,t,n,s,r)||e.first,second:me(e.second,t,n,s,r)||e.second}}function Ve(e,t){if(e===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t};function n(s,r){return s.type==="pane"?{type:"split",direction:r==="row"?"column":"row",splitPercentage:50,first:s,second:{type:"pane",id:ie(),tabs:[t],activeTabId:t}}:{...s,second:n(s.second,s.direction)}}return n(e,null)}function de(e,t,n){return e===null?null:e===t?{...e,splitPercentage:n}:e.type==="split"?{...e,first:de(e.first,t,n)||e.first,second:de(e.second,t,n)||e.second}:e}function ee(e,t){return e===null?null:e.type==="pane"?e.id===t?e:null:ee(e.first,t)??ee(e.second,t)}function G(e,t){return e===null?null:e.type==="pane"?e.tabs.includes(t)?e:null:G(e.first,t)??G(e.second,t)}function he(e,t,n){if(e===null)return null;if(e.type==="pane"){if(e.tabs.includes(t)){let s=e.tabsMetadata||{},r=s[t],o=n(r),i={...s};return o===void 0?delete i[t]:i[t]=o,{...e,tabsMetadata:Object.keys(i).length>0?i:void 0}}return e}return {...e,first:he(e.first,t,n)??e.first,second:he(e.second,t,n)??e.second}}function Pe(e,t,n){if(e===null)return null;if(e.type==="pane"){if(e.id===t){if(n===false){let{locked:s,...r}=e;return r}return {...e,locked:n}}return e}return {...e,first:Pe(e.first,t,n)??e.first,second:Pe(e.second,t,n)??e.second}}function ye(e,t,n){return e===null?null:e.type==="pane"?e.id===t?{...e,activeTabId:n}:e:{...e,first:ye(e.first,t,n)??e.first,second:ye(e.second,t,n)??e.second}}function We(e,t,n){if(e===null)return null;let r=G(e,t)?.tabsMetadata?.[t],o=ae(e,t);if(o===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t,tabsMetadata:r?{[t]:r}:void 0};function i(a){if(a.type==="pane"){if(a.id===n){let u=[...a.tabs];u.includes(t)||u.push(t);let f={...a.tabsMetadata};return r&&(f[t]=r),{...a,tabs:u,activeTabId:t,tabsMetadata:Object.keys(f).length>0?f:void 0}}return a}return {...a,first:i(a.first),second:i(a.second)}}return i(o)}function Ue(e,t,n,s="before"){if(e===null)return null;let o=G(e,t)?.tabsMetadata?.[t],i=ae(e,t);if(i===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t,tabsMetadata:o?{[t]:o}:void 0};function a(u){if(u.type==="pane"){if(u.tabs.includes(n)){let I=[...u.tabs].filter(R=>R!==t),b=I.indexOf(n);b<0&&(b=0),s==="after"&&(b+=1),I.splice(b,0,t);let v={...u.tabsMetadata};return o&&(v[t]=o),{...u,tabs:I,activeTabId:t,tabsMetadata:Object.keys(v).length>0?v:void 0}}return u}return {...u,first:a(u.first),second:a(u.second)}}return a(i)}function se(e,t=0,n=0,s=100,r=100,o="root"){if(e===null)return {panes:[],splitters:[]};if(e.type==="pane")return {panes:[{paneId:e.id,left:t,top:n,width:s,height:r,node:e}],splitters:[]};let{direction:i,splitPercentage:a,first:u,second:f}=e,b={id:`splitter-${o}-${i}`,currentNode:e,direction:i,left:i==="row"?t+s*(a/100):t,top:i==="column"?n+r*(a/100):n,width:i==="row"?0:s,height:i==="column"?0:r,parentLeft:t,parentTop:n,parentWidth:s,parentHeight:r},v={panes:[],splitters:[]},R={panes:[],splitters:[]};if(i==="row"){let y=s*(a/100);v=se(u,t,n,y,r,`${o}-L`),R=se(f,t+y,n,s-y,r,`${o}-R`);}else {let y=r*(a/100);v=se(u,t,n,s,y,`${o}-T`),R=se(f,t,n+y,s,r-y,`${o}-B`);}return {panes:[...v.panes,...R.panes],splitters:[b,...v.splitters,...R.splitters]}}function Te({cursor:e,resizerEl:t,onMove:n,onEnd:s}){document.body.classList.add("zeugma-resizing");let r=document.createElement("style");r.id="zeugma-global-cursor-style",r.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 o=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",o),document.removeEventListener("pointerup",i),s();};document.addEventListener("pointermove",o),document.addEventListener("pointerup",i);}function Je({containerRef:e,isRow:t,direction:r,splitPercentage:s,resizerSize:n,snapThreshold:o,layout:i,currentNode:a,onLayoutChange:l,onResizeStart:y,onResizeEnd:D,parentLeft:c,parentTop:T,parentWidth:x,parentHeight:v}){let{onResizeStart:R,onResize:E,onResizeEnd:L,minSplitPercentage:p=5,maxSplitPercentage:b=95,locked:f=false}=ee();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=s,h=z.currentTarget,F=I.left+I.width*(c/100),Y=I.top+I.height*(T/100),O=I.width*(x/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;Ve({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,te=null;for(let j of _){let u=Math.abs(ae-j);u<o&&u<W&&(W=u,te=j);}let le=B;te!==null&&(le=t?(te-n/2-F)/(O-n)*100:(te-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,s,n,o,i,a,l,y,D,R,E,L,p,b,c,T,x,v])}var sn=({splitter:e,resizerSize:t,snapThreshold:r,containerRef:s})=>{let{layout:n,onLayoutChange:o,classNames:i,locked:a}=ee(),[l,y]=useState(false),{currentNode:D,direction:c,left:T,top:x,width:v,height:R,parentLeft:E,parentTop:L,parentWidth:p,parentHeight:b}=e,f=c==="row",z=Je({containerRef:s,isRow:f,direction:c,splitPercentage:D.splitPercentage,resizerSize:t,snapThreshold:r,layout:n,currentNode:D,onLayoutChange:o,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}, ${T}%) - ${t/2}px)`,top:`calc(${x}% + ${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(${T}% + ${t/2}px)`,top:`calc(var(--splitter-pos-${e.id}, ${x}%) - ${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})},an=tn.memo(({paneId:e,renderPane:t})=>jsx(Fragment,{children:t(e)}),(e,t)=>e.paneId===t.paneId&&e.renderPane===t.renderPane),ln=({tree:e,resizerSize:t=4,snapThreshold:r})=>{let{layout:s,renderPane:n,activeId:o,dismissIntentId:i,setContainerRef:a,fullscreenPaneId:l,snapThreshold:y,locked:D,classNames:c}=ee(),T=r!==void 0?r:y??8,x=e!==void 0?e:s,v=useRef(null),{panes:R,splitters:E}=useMemo(()=>x?se(x):{panes:[],splitters:[]},[x]);if(!x)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(an,{paneId:p.paneId,renderPane:n})},p.paneId)}),!l&&E.map(p=>jsx(sn,{splitter:p,resizerSize:t,snapThreshold:T,containerRef:v},p.id))]});if(e===void 0){let p=o!==null&&o===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 yt="zeugma-height:",pn="default-pane";function fn(e){try{let t=localStorage.getItem(yt+e);if(t!==null){let r=Number(t);if(Number.isFinite(r)&&r>0)return r}}catch{}return null}function Pt(e,t){try{localStorage.setItem(yt+e,String(Math.round(t)));}catch{}}var xt=({children:e,active:t=true,height:r,onHeightChange:s,minHeight:n=100,maxHeight:o=1/0,persist:i,localStorageKey:a,resizerHeight:l=6,className:y,resizerClassName:D})=>{let c=i?a||pn:null,T=()=>{let f=(c?fn(c):null)??r??400;return We(f,n,o)},[x,v]=useState(T),R=useRef(null),E=c?x:r??x,L=useRef(r);useEffect(()=>{if(r!==void 0&&r!==L.current){let f=We(r,n,o);v(f),c&&Pt(c,f);}L.current=r;},[r,n,o,c]);let p=useCallback(()=>o,[o]),b=useCallback(f=>{f.preventDefault();let z=f.clientY,A=E,I=p(),V=f.currentTarget,w=Tt(R.current),K=w?w.scrollTop:0,h=z,F=null,Y=(m,$)=>{let _=$-K,N=m-z+_,d=We(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),Ve({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=We(m,n,I),v(m),s&&s(m),c&&Pt(c,m);}});},[E,n,p,s,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":o===1/0?void 0:o})]}):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,r){return Math.max(t,Math.min(r,e))}function Tt(e){if(typeof window>"u"||!e)return null;let t=e.parentElement;if(!t)return document.documentElement;let s=window.getComputedStyle(t).overflowY;return s==="auto"||s==="scroll"?t:Tt(t)}var _e=createContext(null);var xn={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"}},Rt=({id:e,position:t,activeClassName:r})=>{let{setNodeRef:s,isOver:n}=useDroppable({id:e});return jsxs(Fragment,{children:[jsx("div",{ref:s,style:xn[t]}),n&&jsx("div",{className:r,style:Tn[t]})]})},Rn=({id:e,children:t,style:r,locked:s=false})=>{let{layout:n,activeId:o,classNames:i,fullscreenPaneId:a,onFullscreenChange:l,locked:y}=ee(),{removePane:D,updateTabMetadata:c,selectTab:T,removeTab:x}=$e(),v=useContext(ke);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=s||A,V=y||I,w=y||I,K=o!==null&&o!==e&&(!p.includes(o)||p.length>1)&&!w,{attributes:h,listeners:F,setNodeRef:Y}=useDraggable({id:e,disabled:V}),O=o!==null&&p.includes(o),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=>T(L,d),removeTab:d=>{m&&d===b&&l?.(null),x(d);},tabsMetadata:f,updateTabMetadata:(d,B)=>{c(d,B);},renderActiveTab:$}),[O,m,l,e,x,z,c,V,p,b,T,L,f,$]),k=useMemo(()=>V?{disabled:true}:{...F,...h},[F,h,V]),N=`${i.pane||""} ${I?i.paneLocked||"zeugma-pane-locked":""}`.trim();return jsx(_e.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(Rt,{id:`drop-${d}-${e}`,position:d,activeClassName:i.dropPreview},d))}),o!==null&&o!==e&&w&&jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:jsx(Rt,{id:`drop-locked-${e}`,position:"full",activeClassName:i.lockedPreview||"zeugma-locked-preview"})})]})})};var En=({children:e,className:t,style:r})=>{let s=useContext(_e);if(!s)throw new Error("<DragHandle> must be used inside a <Pane>");let{disabled:n,...o}=s;return jsx("div",{className:t,style:{cursor:n?"default":"grab",userSelect:n?"auto":"none",touchAction:n?"auto":"none",...r},...n?{}:o,children:e})};var Mn=({id:e,locked:t=false,children:r,className:s,style:n})=>{let{locked:o}=ee(),i=t||o,{attributes:a,listeners:l,setNodeRef:y,isDragging:D}=useDraggable({id:`tab-header-${e}`,disabled:i}),{setNodeRef:c,isOver:T}=useDroppable({id:`tab-drop-${e}`,disabled:i});return jsx("div",{ref:v=>{y(v),c(v);},className:s,style:{display:"inline-flex",cursor:i?"default":"grab",...n},...i?{}:l,...i?{}:a,children:r({isDragging:D,isOver:T})})};export{At as DEFAULT_DRAG_ACTIVATION_DISTANCE,Fn as DEFAULT_RESIZER_SIZE,Ht as DEFAULT_SNAP_THRESHOLD,En as DragHandle,Rn as Pane,ln as PaneTree,xt as ResizableContainer,Mn as Tab,jt as Zeugma,lt as addPane,se as computeLayout,Ve as createDragSession,q as findPane,ie as generateUniqueId,ct as mergeTab,ut as moveTab,be as removePane,de as removeTab,Ae as selectTab,ye as splitPane,He as updatePaneLock,ve as updateSplitPercentage,Ze as updateTabMetadata,Je as useResizer,Ft as useZeugma,Ot as useZeugmaContext};//# sourceMappingURL=index.js.map
|
|
6
|
+
`,document.head.appendChild(r),t.setAttribute("data-resizing","true");let o=a=>{n(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",o),document.removeEventListener("pointerup",i),s();};document.addEventListener("pointermove",o),document.addEventListener("pointerup",i);}function be(e){try{return JSON.stringify(e)}catch{return ""}}var Me=createContext(void 0),ze=createContext(void 0),xe=createContext(void 0),re=()=>{let e=useContext(Me);if(!e)throw new Error("useZeugmaState must be used within a Zeugma provider");return e},Se=()=>{let e=useContext(ze);if(!e)throw new Error("useZeugmaActions must be used within a Zeugma provider");return e};function mt(e){let{initialLayout:t,layout:n,onChange:s,fullscreenPaneId:r,onFullscreenChange:o,locked:i=false,dragActivationDistance:a=8,snapThreshold:u=8,minSplitPercentage:f=5,maxSplitPercentage:I=95,enableDragToDismiss:b=false,dismissThreshold:v=60,onRemove:R,onDragStart:y,onDragEnd:M,onResizeStart:m,onResize:D,onResizeEnd:g,onDismissIntentChange:C}=e,[T,L]=useState(()=>n!==void 0?n:t??null),[$,U]=useState(()=>be(n!==void 0?n:null)),[Y,z]=useState(r||null),[q,V]=useState(i),[B,J]=useState(null),[j,d]=useState(null),[x,Z]=useState(null),N=useRef(null),E=useCallback(c=>{N.current=c;},[]),l=useCallback(c=>{z(c),o?.(c);},[o]);if(useEffect(()=>{V(i);},[i]),useEffect(()=>{r!==void 0&&z(r);},[r]),n!==void 0){let c=be(n);c!==$&&(U(c),L(n));}let p=useCallback(c=>(...h)=>{let H=T,A=c(H,...h);be(H)!==be(A)&&(L(A),s?.(A));},[T,s]),P=useCallback(p((c,h)=>typeof h=="function"?h(c):h),[p]),Q=useCallback(p((c,h)=>ue(c,h)),[p]),W=useCallback(p((c,h)=>Ve(c,h)),[p]),O=useCallback(p((c,h,H,A,ne)=>{let ce=ee(c,h)??G(c,h);if(!ce)return c;let at=ee(c,ne)??G(c,ne)??{type:"pane",id:ne,tabs:[ne],activeTabId:ne},lt=ue(c,ne);return me(lt,ce.id,H,A,at)}),[p]),X=useCallback(p((c,h,H)=>de(c,h,H)),[p]),F=useCallback(p((c,h,H)=>he(c,h,H)),[p]),S=useCallback(p((c,h,H)=>{let A=ee(c,h)??G(c,h);return A?Pe(c,A.id,H):c}),[p]),w=useCallback(p((c,h,H)=>{let A=ee(c,h)??G(c,h);return A?ye(c,A.id,H):c}),[p]),k=useCallback(p((c,h,H)=>{let A=ee(c,H)??G(c,H);return A?We(c,h,A.id):c}),[p]),oe=useCallback(p((c,h,H,A)=>Ue(c,h,H,A)),[p]),te=useCallback(p((c,h)=>ae(c,h)),[p]);return {layout:T,setLayout:P,fullscreenPaneId:Y,setFullscreenPaneId:l,locked:q,setLocked:V,activeId:B,setActiveId:J,activeType:j,setActiveType:d,dismissIntentId:x,setDismissIntentId:Z,containerRef:N,setContainerRef:E,dragActivationDistance:a,snapThreshold:u,minSplitPercentage:f,maxSplitPercentage:I,enableDragToDismiss:b,dismissThreshold:v,onRemove:R,onDragStart:y,onDragEnd:M,onResizeStart:m,onResize:D,onResizeEnd:g,onDismissIntentChange:C,removePane:Q,addPane:W,splitPane:O,updateSplitPercentage:X,updateTabMetadata:F,updatePaneLock:S,selectTab:w,mergeTab:k,moveTab:oe,removeTab:te}}var gt=()=>{let e=re(),t=Se();return {...e,...t}};var Re=class extends PointerSensor{static activators=[{eventName:"onPointerDown",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]},De=class extends TouchSensor{static activators=[{eventName:"onTouchStart",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]};function Ce(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}function Xe(e){let{layout:t,setLayout:n,activeId:s,setActiveId:r,setActiveType:o,dismissIntentId:i,setDismissIntentId:a,setOverTabId:u,setOverTabPosition:f,containerRef:I,dragActivationDistance:b,enableDragToDismiss:v,dismissThreshold:R,onRemove:y,onDragStart:M,onDragEnd:m,onDismissIntentChange:D,removeTab:g,moveTab:C,selectTab:T}=e,L=useRef(null),$=Ae(s),[U,Y]=useState(false);Fe(U);let z=useSensors(useSensor(Re,{activationConstraint:{distance:b}}),useSensor(De,{activationConstraint:{delay:250,tolerance:5}})),q=useCallback(d=>{let x=pointerWithin(d);if(x.length>0)return x;if(d.active.id.toString().startsWith("tab-header-")){let N=d.droppableContainers.filter(E=>E.id.toString().startsWith("tab-drop-"));return closestCenter({...d,droppableContainers:N})}return []},[]);return {sensors:z,collisionDetection:q,onDragStart:d=>{let x=d.active.id.toString(),Z=x.startsWith("tab-header-"),N=Z?x.substring(11):x;r(N),o(Z?"tab":"pane"),u(null),f(null);let E=d.activatorEvent;if($.current=Ce(E),v&&I.current?L.current=I.current.getBoundingClientRect():L.current=null,Z){let l=G(t,N);l&&T(l.id,N);}M&&M(N);},onDragMove:d=>{let{over:x}=d,Z=x?.id.toString()||"",N=Z.startsWith("drop-locked-");Y(N);let E=Z.match(/^tab-drop-(.+)$/);if(E&&x){let[,S]=E,w=d.active.id.toString();if((w.startsWith("tab-header-")?w.substring(11):w)!==S){let te="before",c=x.rect,h=d.activatorEvent,H=null;if($.current)H=$.current.x;else {let A=Ce(h);A&&(H=A.x+d.delta.x);}if(H!==null){let A=c.left+c.width/2;H>A&&(te="after");}u(S),f(te);}else u(null),f(null);}else u(null),f(null);if(!v)return;let l=d.active.id.toString(),_=l.startsWith("tab-header-")?l.substring(11):l,P=L.current;if(!P){i!==null&&(a(null),D?.(null));return}let Q=d.activatorEvent,W=null,O=null;if($.current)W=$.current.x,O=$.current.y;else {let S=Ce(Q);S&&(W=S.x+d.delta.x,O=S.y+d.delta.y);}let X=0;if(W!==null&&O!==null){let S=0,w=0;W<P.left?S=P.left-W:W>P.right&&(S=W-P.right),O<P.top?w=P.top-O:O>P.bottom&&(w=O-P.bottom),X=Math.sqrt(S*S+w*w);}else {let S=d.active.rect.current.translated;if(S){let w=S.left+S.width/2,k=S.top+S.height/2,oe=0,te=0;w<P.left?oe=P.left-w:w>P.right&&(oe=w-P.right),k<P.top?te=P.top-k:k>P.bottom&&(te=k-P.bottom),X=Math.sqrt(oe*oe+te*te);}}X>R?i!==_&&(a(_),D?.(_)):i!==null&&(a(null),D?.(null));},onDragEnd:d=>{r(null),o(null),Y(false),u(null),f(null);let{active:x,over:Z}=d,N=x.id.toString(),E=N.startsWith("tab-header-"),l=E?N.substring(11):N,p=v&&i===l;if(a(null),D?.(null),L.current=null,p){y?y(l):g(l),m&&m(l,null,null);return}if(!Z){m&&m(l,null,null);return}let _=Z.id.toString();if(_.startsWith("drop-locked-")){m&&m(l,null,null);return}let P=_.match(/^tab-drop-(.+)$/);if(P){let[,c]=P;if(l!==c){let h="before",H=Z.rect,A=d.activatorEvent,ne=null;if($.current)ne=$.current.x;else {let ce=Ce(A);ce&&(ne=ce.x+d.delta.x);}if(ne!==null){let ce=H.left+H.width/2;ne>ce&&(h="after");}C(l,c,h),m&&m(l,c,{type:"move",position:"center"});}else m&&m(l,null,null);return}let Q=_.match(/^drop-(left|right|top|bottom)-(.+)$/);if(!Q){m&&m(l,null,null);return}let[,W,O]=Q,X=E?G(t,l):ee(t,l),F=X&&X.id===O,S=X&&X.tabs.length===1;if(l===O||F&&S){m&&m(l,null,null);return}let w=W==="left"||W==="right"?"row":"column",k;if(E){let h=G(t,l)?.tabsMetadata?.[l];k={type:"pane",id:ie(),tabs:[l],activeTabId:l,tabsMetadata:h?{[l]:h}:void 0};}else k=ee(t,l)??{type:"pane",id:ie(),tabs:[l],activeTabId:l};let oe=E?ae(t,l):ue(t,l),te=me(oe,O,w,W,k);n(te),m&&m(l,O,{type:"split",direction:w,position:W});},onDragCancel:()=>{r(null),o(null),Y(false),u(null),f(null),a(null),D?.(null),L.current=null;}}}var qe=({activeId:e,render:t,className:n})=>{let s=useRef(null);return useEffect(()=>{let r=o=>{s.current&&(s.current.style.transform=`translate(${o.clientX+12}px, ${o.clientY+12}px)`);};return document.addEventListener("pointermove",r),()=>document.removeEventListener("pointermove",r)},[]),jsx("div",{ref:s,className:n,style:{position:"fixed",top:0,left:0,zIndex:9999,pointerEvents:"none"},children:t(e)})};var Je=({tabId:e,target:t,renderWidget:n})=>{let[s,r]=useState(false),o=useRef(null);if(useEffect(()=>{r(true);},[]),useEffect(()=>{if(!s||!o.current)return;let a=o.current;if(t)t.appendChild(a);else {let u=document.getElementById("zeugma-hidden-portal-container");u||(u=document.createElement("div"),u.id="zeugma-hidden-portal-container",u.style.display="none",document.body.appendChild(u)),u.appendChild(a);}},[t,s]),useEffect(()=>()=>{o.current&&o.current.remove();},[]),!s)return null;o.current||(o.current=document.createElement("div"),o.current.className=`zeugma-portal-wrapper-${e}`,o.current.style.width="100%",o.current.style.height="100%");let i=o.current;return !i||!n?null:createPortal(n(e),i)};var Lt=e=>{let t=e,{renderPane:n,renderWidget:s,renderDragOverlay:r,classNames:o={},children:i,layout:a,setLayout:u,fullscreenPaneId:f,setFullscreenPaneId:I,locked:b,activeId:v,activeType:R,dismissIntentId:y,setContainerRef:M,snapThreshold:m,minSplitPercentage:D,maxSplitPercentage:g,onRemove:C,onResizeStart:T,onResize:L,onResizeEnd:$,removePane:U,addPane:Y,updateTabMetadata:z,updatePaneLock:q,selectTab:V,mergeTab:B,removeTab:J}=t,{portalTargets:j,registerPortalTarget:d}=Oe(),[x,Z]=useState(null),[N,E]=useState(null),l=Xe({...t,setOverTabId:Z,setOverTabPosition:E}),p=useCallback(F=>n(F),[n]),_=useMemo(()=>o,[o.dashboard,o.dashboardDismissActive,o.pane,o.paneLocked,o.dropPreview,o.dragOverlay,o.resizer,o.dismissPreview,o.dashboardLocked,o.lockedPreview,o.tabDropPreview]),P=useCallback((F,S)=>{$&&$(F,S);},[$]),Q=useMemo(()=>({layout:a,setLayout:u,renderPane:p,activeId:v,dismissIntentId:y,overTabId:x,overTabPosition:N,setContainerRef:M,fullscreenPaneId:f,classNames:_,onRemove:C,onFullscreenChange:I,snapThreshold:m,onResizeStart:T,onResize:L,onResizeEnd:P,minSplitPercentage:D,maxSplitPercentage:g,locked:b}),[a,v,y,x,N,M,f,_,C,I,m,T,L,D,g,u,p,P,b]),W=useMemo(()=>({removePane:U,addPane:Y,updateTabMetadata:z,updatePaneLock:q,selectTab:V,mergeTab:B,removeTab:J}),[U,Y,z,q,V,B,J]),O=useMemo(()=>{let F=[];function S(w){w&&(w.type==="pane"?F.push(...w.tabs):(S(w.first),S(w.second)));}return S(a),F},[a]),X=useMemo(()=>({registerPortalTarget:d}),[d]);return jsx(ze.Provider,{value:W,children:jsx(Me.Provider,{value:Q,children:jsxs(xe.Provider,{value:X,children:[jsx(DndContext,{id:"zeugma-dnd-context",...l,children:i}),v&&R&&r&&jsx(qe,{activeId:v,render:F=>r(F,R),className:`${o.dragOverlay||""} ${v===y&&o.dismissPreview||""}`.trim()}),jsx("div",{id:"zeugma-portal-host",style:{display:"none"},children:O.map(F=>jsx(Je,{tabId:F,target:j[F]||null,renderWidget:s},F))})]})})})};function Ze({containerRef:e,isRow:t,direction:n,splitPercentage:s,resizerSize:r,snapThreshold:o,layout:i,currentNode:a,onLayoutChange:u,onResizeStart:f,onResizeEnd:I,parentLeft:b,parentTop:v,parentWidth:R,parentHeight:y}){let{onResizeStart:M,onResize:m,onResizeEnd:D,minSplitPercentage:g=5,maxSplitPercentage:C=95,locked:T=false}=re();return useCallback(L=>{if(T)return;L.preventDefault();let $=e.current;if(!$)return;f&&f(),M&&M(a);let U=$.getBoundingClientRect(),Y=L.clientX,z=L.clientY,q=s,V=L.currentTarget,B=U.left+U.width*(b/100),J=U.top+U.height*(v/100),j=U.width*(R/100),d=U.height*(y/100),Z=Array.from(document.querySelectorAll('div[role="separator"][data-direction]')).filter(E=>E!==V&&E.getAttribute("data-direction")===n).map(E=>{let l=E.getBoundingClientRect();return t?l.left+l.width/2:l.top+l.height/2}),N=q;Te({cursor:t?"col-resize":"row-resize",resizerEl:V,onMove:E=>{let l=t?(E.clientX-Y)/j*100:(E.clientY-z)/d*100,p=q+l,_=t?B+(j-r)*(p/100)+r/2:J+(d-r)*(p/100)+r/2,P=1/0,Q=null;for(let F of Z){let S=Math.abs(_-F);S<o&&S<P&&(P=S,Q=F);}let W=p;Q!==null&&(W=t?(Q-r/2-B)/(j-r)*100:(Q-r/2-J)/(d-r)*100);let O=Math.max(g,Math.min(C,W));N=O;let X=de(i,a,O);if(X){let{panes:F,splitters:S}=se(X),w=e.current;if(w){for(let k of F)w.style.setProperty(`--pane-left-${k.paneId}`,`${k.left}%`),w.style.setProperty(`--pane-top-${k.paneId}`,`${k.top}%`),w.style.setProperty(`--pane-width-${k.paneId}`,`${k.width}%`),w.style.setProperty(`--pane-height-${k.paneId}`,`${k.height}%`);for(let k of S)w.style.setProperty(`--splitter-pos-${k.id}`,`${k.direction==="row"?k.left:k.top}%`);}}m&&m(a,O);},onEnd:()=>{let E=de(i,a,N),l=e.current;if(l){let{panes:p,splitters:_}=se(E);for(let P of p)l.style.removeProperty(`--pane-left-${P.paneId}`),l.style.removeProperty(`--pane-top-${P.paneId}`),l.style.removeProperty(`--pane-width-${P.paneId}`),l.style.removeProperty(`--pane-height-${P.paneId}`);for(let P of _)l.style.removeProperty(`--splitter-pos-${P.id}`);}u(E),I&&I(),D&&D(a,N);}});},[e,t,n,s,r,o,i,a,u,f,I,M,m,D,g,C,b,v,R,y])}var At=({splitter:e,resizerSize:t,snapThreshold:n,containerRef:s})=>{let{layout:r,setLayout:o,classNames:i,locked:a}=re(),[u,f]=useState(false),{currentNode:I,direction:b,left:v,top:R,width:y,height:M,parentLeft:m,parentTop:D,parentWidth:g,parentHeight:C}=e,T=b==="row",L=Ze({containerRef:s,isRow:T,direction:b,splitPercentage:I.splitPercentage,resizerSize:t,snapThreshold:n,layout:r,currentNode:I,onLayoutChange:o,onResizeStart:()=>f(true),onResizeEnd:()=>f(false),parentLeft:m,parentTop:D,parentWidth:g,parentHeight:C}),$=T?{position:"absolute",left:`calc(var(--splitter-pos-${e.id}, ${v}%) - ${t/2}px)`,top:`calc(${R}% + ${t/2}px)`,width:`${t}px`,height:`calc(${M}% - ${t}px)`,cursor:a?"default":"col-resize",pointerEvents:a?"none":"auto",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box"}:{position:"absolute",left:`calc(${v}% + ${t/2}px)`,top:`calc(var(--splitter-pos-${e.id}, ${R}%) - ${t/2}px)`,width:`calc(${y}% - ${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:i.resizer||"","data-direction":b,"data-resizing":u||void 0,style:$,onPointerDown:L,role:"separator","aria-valuenow":I.splitPercentage,"aria-valuemin":5,"aria-valuemax":95})},Ft=$t.memo(({paneId:e,renderPane:t})=>jsx(Fragment,{children:t(e)}),(e,t)=>e.paneId===t.paneId&&e.renderPane===t.renderPane),Ot=({tree:e,resizerSize:t=4,snapThreshold:n})=>{let{layout:s,renderPane:r,activeId:o,dismissIntentId:i,setContainerRef:a,fullscreenPaneId:u,snapThreshold:f,locked:I,classNames:b}=re(),v=n!==void 0?n:f??8,R=e!==void 0?e:s,y=useRef(null),{panes:M,splitters:m}=useMemo(()=>R?se(R):{panes:[],splitters:[]},[R]);if(!R)return null;let D=()=>jsxs(Fragment,{children:[M.map(g=>{let C=u===g.paneId;return jsx("div",{style:{position:"absolute",left:C?"0%":`var(--pane-left-${g.paneId}, ${g.left}%)`,top:C?"0%":`var(--pane-top-${g.paneId}, ${g.top}%)`,width:C?"100%":`var(--pane-width-${g.paneId}, ${g.width}%)`,height:C?"100%":`var(--pane-height-${g.paneId}, ${g.height}%)`,overflow:"hidden",zIndex:C?20:1,display:u&&!C?"none":"block",padding:C?"0px":`${t/2}px`,boxSizing:"border-box"},children:jsx(Ft,{paneId:g.paneId,renderPane:r})},g.paneId)}),!u&&m.map(g=>jsx(At,{splitter:g,resizerSize:t,snapThreshold:v,containerRef:y},g.id))]});if(e===void 0){let g=o!==null&&o===i,C=L=>{a(L),y.current=L;},T=`${b.dashboard||""} ${g&&b.dashboardDismissActive||""} ${I&&b.dashboardLocked||""}`.trim();return jsx("div",{ref:C,className:T,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:D()})}return jsx("div",{ref:y,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:D()})};var nt="zeugma-height:",_t="default-pane";function Yt(e){try{let t=localStorage.getItem(nt+e);if(t!==null){let n=Number(t);if(Number.isFinite(n)&&n>0)return n}}catch{}return null}function tt(e,t){try{localStorage.setItem(nt+e,String(Math.round(t)));}catch{}}var rt=({children:e,active:t=true,height:n,onHeightChange:s,minHeight:r=100,maxHeight:o=1/0,persist:i,localStorageKey:a,resizerHeight:u=6,className:f,resizerClassName:I})=>{let b=i?a||_t:null,v=()=>{let T=(b?Yt(b):null)??n??400;return Ee(T,r,o)},[R,y]=useState(v),M=useRef(null),m=b?R:n??R,D=useRef(n);useEffect(()=>{if(n!==void 0&&n!==D.current){let T=Ee(n,r,o);y(T),b&&tt(b,T);}D.current=n;},[n,r,o,b]);let g=useCallback(()=>o,[o]),C=useCallback(T=>{T.preventDefault();let L=T.clientY,$=m,U=g(),Y=T.currentTarget,z=ot(M.current),q=z?z.scrollTop:0,V=L,B=null,J=(d,x)=>{let Z=x-q,E=d-L+Z,l=Ee($+E,r,U);return M.current&&(M.current.style.height=`${l}px`),l},j=()=>{if(!z)return;let d=z===document.documentElement||z===document.body?{top:0,bottom:window.innerHeight}:z.getBoundingClientRect(),x=40,Z=10,N=0;V>d.bottom-x?N=Math.min(1,(V-(d.bottom-x))/x)*Z:V<d.top+x&&(N=-Math.min(1,(d.top+x-V)/x)*Z),N!==0&&(z.scrollTop+=N,J(V,z.scrollTop)),B=requestAnimationFrame(j);};B=requestAnimationFrame(j),Te({cursor:"row-resize",resizerEl:Y,onMove:d=>{V=d.clientY,z&&J(V,z.scrollTop);},onEnd:()=>{B!==null&&cancelAnimationFrame(B);let d=$;M.current&&(d=M.current.getBoundingClientRect().height),d=Ee(d,r,U),y(d),s&&s(d),b&&tt(b,d);}});},[m,r,g,s,b]);return t?jsxs("div",{ref:M,className:`zeugma-resizable-container ${f||""}`.trim(),style:{height:`${m}px`,position:"relative",overflow:"hidden",boxSizing:"border-box"},children:[jsx("div",{style:{height:`calc(100% - ${u}px)`,overflow:"hidden"},children:e}),jsx("div",{className:`zeugma-resizable-handle ${I||""}`.trim(),style:{height:`${u}px`,cursor:"row-resize",position:"relative",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box",flexShrink:0},onPointerDown:C,role:"separator","aria-orientation":"horizontal","aria-valuenow":Math.round(m),"aria-valuemin":r,"aria-valuemax":o===1/0?void 0:o})]}):jsx("div",{className:`zeugma-resizable-container disabled ${f||""}`.trim(),style:{height:"100%",position:"relative",overflow:"hidden",boxSizing:"border-box"},children:jsx("div",{style:{height:"100%",overflow:"hidden"},children:e})})};function Ee(e,t,n){return Math.max(t,Math.min(n,e))}function ot(e){if(typeof window>"u"||!e)return null;let t=e.parentElement;if(!t)return document.documentElement;let s=window.getComputedStyle(t).overflowY;return s==="auto"||s==="scroll"?t:ot(t)}var Ne=createContext(null);var en={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"}},st=({id:e,position:t,activeClassName:n})=>{let{setNodeRef:s,isOver:r}=useDroppable({id:e});return jsxs(Fragment,{children:[jsx("div",{ref:s,style:en[t]}),r&&jsx("div",{className:n,style:tn[t]})]})},nn=({id:e,children:t,style:n,locked:s=false})=>{let r=useRef(null),{layout:o,activeId:i,classNames:a,fullscreenPaneId:u,onFullscreenChange:f,locked:I}=re(),{removePane:b,updateTabMetadata:v,selectTab:R,removeTab:y}=Se(),M=useContext(xe);if(!M)throw new Error("Pane must be used within a Zeugma provider");let{registerPortalTarget:m}=M,D=useMemo(()=>ee(o,e),[o,e]),g=D?.id??e,C=D?.tabs??[e],T=D?.activeTabId??e,L=D?.tabsMetadata,$=L?.[e],U=D?.locked??false,Y=s||U,z=I||Y,q=I||Y,V=i!==null&&i!==e&&(!C.includes(i)||C.length>1)&&!q,{attributes:B,listeners:J,setNodeRef:j}=useDraggable({id:e,disabled:z}),d=i!==null&&C.includes(i),x=u===e,Z=useCallback(()=>jsx("div",{ref:r,id:`zeugma-tab-target-${T}`,className:"zeugma-tab-content-wrapper",style:{height:"100%",width:"100%"}}),[T]);useEffect(()=>{let p=r.current;return m(T,p),()=>{m(T,null);}},[T,m]);let N=useMemo(()=>({isDragging:d,isFullscreen:x,toggleFullscreen:()=>f?.(x?null:e),remove:()=>{x&&f?.(null),b(g);},metadata:$,updateMetadata:p=>{v(e,p);},locked:z,tabs:C,activeTabId:T,selectTab:p=>R(g,p),removeTab:p=>{x&&p===T&&f?.(null),y(p);},tabsMetadata:L,updateTabMetadata:(p,_)=>{v(p,_);},renderActiveTab:Z}),[d,x,f,e,y,$,v,z,C,T,R,g,L,Z]),E=useMemo(()=>z?{disabled:true}:{...J,...B},[J,B,z]),l=`${a.pane||""} ${Y&&a.paneLocked||""}`.trim();return jsx(Ne.Provider,{value:E,children:jsxs("div",{ref:j,className:l,style:{position:"relative",width:"100%",height:"100%",...n},children:[t(N),V&&jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:["top","bottom","left","right"].map(p=>jsx(st,{id:`drop-${p}-${e}`,position:p,activeClassName:a.dropPreview},p))}),i!==null&&i!==e&&q&&jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:jsx(st,{id:`drop-locked-${e}`,position:"full",activeClassName:a.lockedPreview||""})})]})})};var sn=({children:e,className:t,style:n})=>{let s=useContext(Ne);if(!s)throw new Error("<DragHandle> must be used inside a <Pane>");let{disabled:r,...o}=s;return jsx("div",{className:t,style:{cursor:r?"default":"grab",userSelect:r?"auto":"none",touchAction:r?"auto":"none",...n},...r?{}:o,children:e})};var un=({id:e,locked:t=false,children:n,className:s,style:r})=>{let{locked:o,classNames:i={},overTabId:a,overTabPosition:u}=re(),f=t||o,{attributes:I,listeners:b,setNodeRef:v,isDragging:R}=useDraggable({id:`tab-header-${e}`,disabled:f}),{setNodeRef:y,isOver:M}=useDroppable({id:`tab-drop-${e}`,disabled:f}),m=C=>{v(C),y(C);},D=M&&a===e,g=D?u:null;return jsxs("div",{ref:m,className:s,style:{display:"inline-flex",position:"relative",cursor:f?"default":"grab",...r},...f?{}:b,...f?{}:I,children:[n({isDragging:R,isOver:D}),D&&g&&jsx("div",{className:i.tabDropPreview||"",style:{position:"absolute",top:0,bottom:0,width:"2px",backgroundColor:"#6366f1",left:g==="before"?0:void 0,right:g==="after"?0:void 0,pointerEvents:"none",zIndex:10}})]})};export{pt as DEFAULT_DRAG_ACTIVATION_DISTANCE,gn as DEFAULT_RESIZER_SIZE,dt as DEFAULT_SNAP_THRESHOLD,sn as DragHandle,nn as Pane,Ot as PaneTree,xe as PortalRegistryContext,rt as ResizableContainer,un as Tab,Lt as Zeugma,ze as ZeugmaActionsContext,Me as ZeugmaStateContext,Ve as addPane,se as computeLayout,Te as createDragSession,ee as findPaneById,G as findPaneContainingTab,ie as generateUniqueId,We as mergeTab,Ue as moveTab,ue as removePane,ae as removeTab,be as safeJsonStringify,ye as selectTab,me as splitPane,Pe as updatePaneLock,de as updateSplitPercentage,he as updateTabMetadata,Ze as useResizer,mt as useZeugma,Se as useZeugmaActions,gt as useZeugmaContext,re as useZeugmaState};//# sourceMappingURL=index.js.map
|
|
7
7
|
//# sourceMappingURL=index.js.map
|