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/README.md +91 -168
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +166 -110
- package/dist/index.d.ts +166 -110
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -12
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
|
-
|
|
13
|
+
id: string;
|
|
14
|
+
tabs: string[];
|
|
15
|
+
activeTabId: string;
|
|
14
16
|
locked?: boolean;
|
|
15
|
-
|
|
17
|
+
tabsMetadata?: Record<string, Record<string, unknown>>;
|
|
16
18
|
}
|
|
17
19
|
type TreeNode = SplitNode | PaneNode;
|
|
18
20
|
|
|
19
|
-
interface
|
|
20
|
-
/**
|
|
21
|
-
|
|
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
|
|
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
|
-
/**
|
|
55
|
-
|
|
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
|
-
/**
|
|
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
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
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
|
-
|
|
71
|
+
setActiveId: Dispatch<SetStateAction<string | null>>;
|
|
72
|
+
activeType: 'pane' | 'tab' | null;
|
|
73
|
+
setActiveType: Dispatch<SetStateAction<'pane' | 'tab' | null>>;
|
|
103
74
|
dismissIntentId: string | null;
|
|
104
|
-
|
|
75
|
+
setDismissIntentId: Dispatch<SetStateAction<string | null>>;
|
|
76
|
+
containerRef: RefObject<HTMLElement | null>;
|
|
105
77
|
setContainerRef: (element: HTMLElement | null) => void;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
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
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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
|
|
202
|
+
/** Closes and removes the active tab from the layout tree. */
|
|
217
203
|
remove: () => void;
|
|
218
|
-
/** The metadata values associated with
|
|
204
|
+
/** The metadata values associated with the active tab, or undefined. */
|
|
219
205
|
metadata: Record<string, unknown> | undefined;
|
|
220
|
-
/** Updates the metadata of
|
|
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
|
|
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,
|
|
274
|
+
declare function removePane(tree: TreeNode | null, paneId: string): TreeNode | null;
|
|
256
275
|
/**
|
|
257
|
-
* Tree Helper:
|
|
276
|
+
* Tree Helper: Remove a tab from a pane and consolidate the tree structure if no tabs remain.
|
|
258
277
|
*/
|
|
259
|
-
declare function
|
|
278
|
+
declare function removeTab(tree: TreeNode | null, tabId: string): TreeNode | null;
|
|
260
279
|
/**
|
|
261
|
-
* Tree Helper:
|
|
280
|
+
* Tree Helper: Insert a pane by splitting an existing target node.
|
|
262
281
|
*/
|
|
263
|
-
declare function
|
|
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
|
|
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
|
|
296
|
+
* Update metadata on a specific tab node using an updater function.
|
|
278
297
|
*/
|
|
279
|
-
declare function
|
|
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
|
|
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
|