react-zeugma 1.4.1 → 2.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -16,81 +16,128 @@ interface PaneNode {
16
16
  type TreeNode = SplitNode | PaneNode;
17
17
 
18
18
  interface ZeugmaClassNames {
19
+ /** CSS class applied to the outer container div of each `<Pane>`. */
19
20
  pane?: string;
21
+ /** CSS class applied to drop zone indicators when hovering over layout edges to split a pane. */
20
22
  dropPreview?: string;
23
+ /** CSS class applied to the drop zone indicator when hovering over the center of a pane to swap. */
21
24
  swapPreview?: string;
25
+ /** CSS class applied to the custom cursor-following drag preview portal wrapper. */
22
26
  dragOverlay?: string;
27
+ /** CSS class applied to the drag-to-resize split bar handles. */
23
28
  resizer?: string;
29
+ /** CSS class applied to the background dismiss zone indicator during a drag-out dismiss gesture. */
24
30
  dismissPreview?: string;
25
31
  }
32
+ interface ZeugmaProps {
33
+ /** The layout tree model (TreeNode) defining pane organization and split percentages. Set to null for empty layout. */
34
+ layout: TreeNode | null;
35
+ /** Callback triggered when the layout changes via drag-and-drop actions, splits, swaps, or resizes. */
36
+ onChange: (newLayout: TreeNode | null) => void;
37
+ /** Render function mapping unique pane IDs to React elements. Usually renders a <Pane> wrapper. */
38
+ renderPane: (paneId: string) => ReactNode;
39
+ /** Custom overlay renderer function used to customize the cursor-following drag preview for an active pane. */
40
+ renderDragOverlay?: (activeId: string) => ReactNode;
41
+ /** Optional CSS class name mapping overrides for custom styles of components like panes, drop/swap previews, overlays, etc. */
42
+ classNames?: ZeugmaClassNames;
43
+ /** The ID of the pane that is currently taking up the full dashboard area. Null if no pane is fullscreen. */
44
+ fullscreenPaneId?: string | null;
45
+ /** Callback triggered when a pane is toggled to/from fullscreen mode. Passes the active fullscreen paneId or null. */
46
+ onFullscreenChange?: (paneId: string | null) => void;
47
+ /** Callback triggered when a pane is removed from the dashboard layout tree. */
48
+ onRemove?: (paneId: string) => void;
49
+ /** Minimum pixel distance that a user must drag a pane handle before dragging triggers. Defaults to 8. */
50
+ dragActivationDistance?: number;
51
+ /** Threshold value in pixels for snapping layout resizing handles to adjacent edges. Defaults to 8. */
52
+ snapThreshold?: number;
53
+ /** Callback triggered when dragging starts for a pane. */
54
+ onDragStart?: (activeId: string) => void;
55
+ /** Callback triggered when dragging ends, providing details on target pane and drop action (split or swap). */
56
+ onDragEnd?: (activeId: string, overId: string | null, dropAction: {
57
+ type: 'split' | 'swap';
58
+ direction?: SplitDirection;
59
+ position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
60
+ } | null) => void;
61
+ /** Callback triggered when the user starts dragging a resizing handle between split panes. */
62
+ onResizeStart?: (currentNode: SplitNode) => void;
63
+ /** Callback triggered continuously while the user is dragging a resizing handle. Passes the new split percentage. */
64
+ onResize?: (currentNode: SplitNode, percentage: number) => void;
65
+ /** Callback triggered when the user stops dragging a resizing handle. Passes the final split percentage. */
66
+ onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
67
+ /** Minimum split percentage allowed when resizing split panes. Defaults to 5. */
68
+ minSplitPercentage?: number;
69
+ /** Maximum split percentage allowed when resizing split panes. Defaults to 95. */
70
+ maxSplitPercentage?: number;
71
+ /** Whether dragging a pane far enough outside the container triggers a drag-out/dismiss action. Defaults to false. */
72
+ enableDragToDismiss?: boolean;
73
+ /** The threshold in pixels beyond the container boundaries required to activate the drag-out/dismiss action. */
74
+ dismissThreshold?: number;
75
+ /** Callback triggered when the drag-out/dismiss intent changes (active pane ID or null when drag returns inside bounds). */
76
+ onDismissIntentChange?: (paneId: string | null) => void;
77
+ /** Child nodes nested inside the Zeugma context, usually containing a <PaneTree> or similar layout viewer. */
78
+ children: ReactNode;
79
+ }
26
80
  /**
27
81
  * State context — holds reactive values that change during runtime.
28
82
  * All consumers of this context will re-render when any of these values change.
29
83
  */
30
- interface DashboardStateValue {
84
+ interface ZeugmaStateValue {
85
+ /** The current active layout tree structure, or null if empty. */
31
86
  layout: TreeNode | null;
87
+ /** Callback to update the layout tree. */
32
88
  onLayoutChange: (newLayout: TreeNode | null) => void;
89
+ /** Renders the inner content of a pane given its unique ID. */
33
90
  renderPane: (paneId: string) => ReactNode;
91
+ /** The ID of the pane currently being dragged, or null. */
34
92
  activeId: string | null;
93
+ /** The ID of the pane currently targeted for dismiss/drag-out, or null. */
35
94
  dismissIntentId: string | null;
95
+ /** Ref setter to measure and track the dashboard root container element. */
36
96
  setContainerRef: (element: HTMLElement | null) => void;
97
+ /** The ID of the pane currently zoomed to fullscreen, or null. */
37
98
  fullscreenPaneId: string | null;
99
+ /** Normalized or overridden CSS classes for custom layout styling. */
38
100
  classNames: ZeugmaClassNames;
101
+ /** Callback triggered when a pane is closed/removed from the dashboard. */
39
102
  onRemove?: (paneId: string) => void;
103
+ /** Callback triggered to toggle fullscreen status for a pane. */
40
104
  onFullscreenChange?: (paneId: string | null) => void;
105
+ /** Threshold in pixels to snap layout resizers to adjacent edges. */
41
106
  snapThreshold?: number;
107
+ /** Callback triggered when a split pane starts being resized. */
42
108
  onResizeStart?: (currentNode: SplitNode) => void;
109
+ /** Callback triggered continuously during a split pane resize. */
43
110
  onResize?: (currentNode: SplitNode, percentage: number) => void;
111
+ /** Callback triggered when a split pane resize action is completed. */
44
112
  onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
113
+ /** Minimum split percentage allowed when resizing. */
45
114
  minSplitPercentage?: number;
115
+ /** Maximum split percentage allowed when resizing. */
46
116
  maxSplitPercentage?: number;
47
117
  }
48
118
  /**
49
119
  * Actions context — holds stable dispatch functions with permanent identity.
50
120
  * Consumers of only this context will never re-render from layout/drag state changes.
51
121
  */
52
- interface DashboardActionsValue {
122
+ interface ZeugmaActionsValue {
123
+ /** Removes the specified pane from the layout tree and collapses its parent split. */
53
124
  removePane: (paneId: string) => void;
125
+ /** Appends/inserts a pane at the bottom-rightmost leaf of the layout tree. */
54
126
  addPane: (paneId: string) => void;
127
+ /** Swaps the positions of two panes in the layout tree. */
55
128
  swapPanes: (paneIdA: string, paneIdB: string) => void;
129
+ /** Splits a target pane with a new pane in the specified direction and side. */
56
130
  splitPane: (targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string) => void;
131
+ /** Updates the split percentage of a specific split branch node. */
57
132
  updateSplitPercentage: (currentNode: SplitNode, percentage: number) => void;
133
+ /** Stable callback to update metadata for a specific pane. */
58
134
  updatePaneMetadata: (paneId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
59
135
  }
60
136
 
61
- /** Returns only reactive state. Use when you need layout, activeId, classNames, etc. */
62
- declare const useDashboardState: () => DashboardStateValue;
63
- /** Returns only stable action dispatchers. Consumers of this hook never re-render from state changes. */
64
- declare const useDashboardActions: () => DashboardActionsValue;
137
+ declare const useZeugmaState: () => ZeugmaStateValue;
138
+ declare const useZeugmaActions: () => ZeugmaActionsValue;
65
139
 
66
- interface DashboardProviderProps {
67
- layout: TreeNode | null;
68
- onChange: (newLayout: TreeNode | null) => void;
69
- renderPane: (paneId: string) => ReactNode;
70
- renderDragOverlay?: (activeId: string) => ReactNode;
71
- classNames?: ZeugmaClassNames;
72
- fullscreenPaneId?: string | null;
73
- onFullscreenChange?: (paneId: string | null) => void;
74
- onRemove?: (paneId: string) => void;
75
- dragActivationDistance?: number;
76
- snapThreshold?: number;
77
- onDragStart?: (activeId: string) => void;
78
- onDragEnd?: (activeId: string, overId: string | null, dropAction: {
79
- type: 'split' | 'swap';
80
- direction?: SplitDirection;
81
- position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
82
- } | null) => void;
83
- onResizeStart?: (currentNode: SplitNode) => void;
84
- onResize?: (currentNode: SplitNode, percentage: number) => void;
85
- onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
86
- minSplitPercentage?: number;
87
- maxSplitPercentage?: number;
88
- enableDragToDismiss?: boolean;
89
- dismissThreshold?: number;
90
- onDismissIntentChange?: (paneId: string | null) => void;
91
- children: ReactNode;
92
- }
93
- declare const DashboardProvider: React.FC<DashboardProviderProps>;
140
+ declare const Zeugma: React.FC<ZeugmaProps>;
94
141
 
95
142
  interface UseResizerProps {
96
143
  containerRef: React.RefObject<HTMLDivElement | null>;
@@ -108,10 +155,11 @@ interface UseResizerProps {
108
155
  declare function useResizer({ containerRef, isRow, direction, splitPercentage, resizerSize, snapThreshold, layout, currentNode, onLayoutChange, onResizeStart: localOnResizeStart, onResizeEnd: localOnResizeEnd, }: UseResizerProps): (e: React.PointerEvent<HTMLDivElement>) => void;
109
156
 
110
157
  interface PaneTreeProps {
158
+ /** The layout subtree node to render. If not specified, defaults to the root layout tree from the Zeugma context. */
111
159
  tree?: TreeNode | null;
112
- /** Size of the resizer in pixels (default 4) */
160
+ /** Size/thickness of the split handle resizer bars in pixels (default 4). */
113
161
  resizerSize?: number;
114
- /** Threshold in pixels to snap to adjacent resizer edges (default 8) */
162
+ /** Threshold distance in pixels to snap layout resizers to adjacent edges (default 8). */
115
163
  snapThreshold?: number;
116
164
  }
117
165
  declare const PaneTree: React.FC<PaneTreeProps>;
@@ -142,24 +190,36 @@ interface ResizableContainerProps {
142
190
  declare const ResizableContainer: React.FC<ResizableContainerProps>;
143
191
 
144
192
  interface PaneRenderProps {
193
+ /** True if the pane is actively being dragged. */
145
194
  isDragging: boolean;
195
+ /** True if the pane currently occupies the fullscreen view. */
146
196
  isFullscreen: boolean;
197
+ /** Toggles the pane to and from fullscreen/zoomed mode. */
147
198
  toggleFullscreen: () => void;
199
+ /** Closes and removes the pane from the layout tree. */
148
200
  remove: () => void;
201
+ /** The metadata values associated with this pane, or undefined. */
149
202
  metadata: Record<string, unknown> | undefined;
203
+ /** Updates the metadata of this pane using an updater function. */
150
204
  updateMetadata: (updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
151
205
  }
152
206
 
153
207
  interface PaneProps {
208
+ /** The unique ID of the pane, matching a `paneId` in the layout tree schema. */
154
209
  id: string;
210
+ /** Render prop function providing pane state (isDragging, isFullscreen, etc.) and handlers. */
155
211
  children: (props: PaneRenderProps) => React.ReactNode;
212
+ /** Optional inline CSS styles applied to the pane outer container. */
156
213
  style?: React.CSSProperties;
157
214
  }
158
215
  declare const Pane: React.FC<PaneProps>;
159
216
 
160
217
  interface DragHandleProps {
218
+ /** The children elements that will trigger dragging when held and dragged. */
161
219
  children: React.ReactNode;
220
+ /** Custom CSS class applied to the drag handle element. */
162
221
  className?: string;
222
+ /** Optional inline CSS styles applied to the drag handle. */
163
223
  style?: React.CSSProperties;
164
224
  }
165
225
  declare const DragHandle: React.FC<DragHandleProps>;
@@ -188,10 +248,6 @@ declare function addPane(tree: TreeNode | null, paneToAdd: string): TreeNode;
188
248
  * Tree Helper: Update split percentage recursively.
189
249
  */
190
250
  declare function updateSplitPercentage(tree: TreeNode | null, target: SplitNode, newPercentage: number): TreeNode | null;
191
- /**
192
- * Tree Helper: Split the entire tree at the root using a dragged pane.
193
- */
194
- declare function splitRoot(tree: TreeNode | null, draggingId: string, splitType: 'left' | 'right' | 'top' | 'bottom'): TreeNode | null;
195
251
  /**
196
252
  * Find a PaneNode by its paneId.
197
253
  */
@@ -226,4 +282,4 @@ interface DragSessionConfig {
226
282
  }
227
283
  declare function createDragSession({ cursor, resizerEl, onMove, onEnd }: DragSessionConfig): void;
228
284
 
229
- export { DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_RESIZER_SIZE, DEFAULT_SNAP_THRESHOLD, type DashboardActionsValue, DashboardProvider, type DashboardStateValue, DragHandle, type DragSessionConfig, Pane, type PaneNode, type PaneRenderProps, PaneTree, ResizableContainer, type ResizableContainerProps, type SplitDirection, type SplitNode, type TreeNode, type ZeugmaClassNames, addPane, createDragSession, findPane, removePane, splitPane, splitRoot, swapPanes, updatePaneMetadata, updateSplitPercentage, useDashboardActions, useDashboardState, useResizer };
285
+ export { DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_RESIZER_SIZE, DEFAULT_SNAP_THRESHOLD, DragHandle, type DragHandleProps, type DragSessionConfig, Pane, type PaneNode, type PaneProps, type PaneRenderProps, PaneTree, ResizableContainer, type ResizableContainerProps, type SplitDirection, type SplitNode, type TreeNode, Zeugma, type ZeugmaActionsValue, type ZeugmaClassNames, type ZeugmaProps, type ZeugmaStateValue, addPane, createDragSession, findPane, removePane, splitPane, swapPanes, updatePaneMetadata, updateSplitPercentage, useResizer, useZeugmaActions, useZeugmaState };
package/dist/index.d.ts CHANGED
@@ -16,81 +16,128 @@ interface PaneNode {
16
16
  type TreeNode = SplitNode | PaneNode;
17
17
 
18
18
  interface ZeugmaClassNames {
19
+ /** CSS class applied to the outer container div of each `<Pane>`. */
19
20
  pane?: string;
21
+ /** CSS class applied to drop zone indicators when hovering over layout edges to split a pane. */
20
22
  dropPreview?: string;
23
+ /** CSS class applied to the drop zone indicator when hovering over the center of a pane to swap. */
21
24
  swapPreview?: string;
25
+ /** CSS class applied to the custom cursor-following drag preview portal wrapper. */
22
26
  dragOverlay?: string;
27
+ /** CSS class applied to the drag-to-resize split bar handles. */
23
28
  resizer?: string;
29
+ /** CSS class applied to the background dismiss zone indicator during a drag-out dismiss gesture. */
24
30
  dismissPreview?: string;
25
31
  }
32
+ interface ZeugmaProps {
33
+ /** The layout tree model (TreeNode) defining pane organization and split percentages. Set to null for empty layout. */
34
+ layout: TreeNode | null;
35
+ /** Callback triggered when the layout changes via drag-and-drop actions, splits, swaps, or resizes. */
36
+ onChange: (newLayout: TreeNode | null) => void;
37
+ /** Render function mapping unique pane IDs to React elements. Usually renders a <Pane> wrapper. */
38
+ renderPane: (paneId: string) => ReactNode;
39
+ /** Custom overlay renderer function used to customize the cursor-following drag preview for an active pane. */
40
+ renderDragOverlay?: (activeId: string) => ReactNode;
41
+ /** Optional CSS class name mapping overrides for custom styles of components like panes, drop/swap previews, overlays, etc. */
42
+ classNames?: ZeugmaClassNames;
43
+ /** The ID of the pane that is currently taking up the full dashboard area. Null if no pane is fullscreen. */
44
+ fullscreenPaneId?: string | null;
45
+ /** Callback triggered when a pane is toggled to/from fullscreen mode. Passes the active fullscreen paneId or null. */
46
+ onFullscreenChange?: (paneId: string | null) => void;
47
+ /** Callback triggered when a pane is removed from the dashboard layout tree. */
48
+ onRemove?: (paneId: string) => void;
49
+ /** Minimum pixel distance that a user must drag a pane handle before dragging triggers. Defaults to 8. */
50
+ dragActivationDistance?: number;
51
+ /** Threshold value in pixels for snapping layout resizing handles to adjacent edges. Defaults to 8. */
52
+ snapThreshold?: number;
53
+ /** Callback triggered when dragging starts for a pane. */
54
+ onDragStart?: (activeId: string) => void;
55
+ /** Callback triggered when dragging ends, providing details on target pane and drop action (split or swap). */
56
+ onDragEnd?: (activeId: string, overId: string | null, dropAction: {
57
+ type: 'split' | 'swap';
58
+ direction?: SplitDirection;
59
+ position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
60
+ } | null) => void;
61
+ /** Callback triggered when the user starts dragging a resizing handle between split panes. */
62
+ onResizeStart?: (currentNode: SplitNode) => void;
63
+ /** Callback triggered continuously while the user is dragging a resizing handle. Passes the new split percentage. */
64
+ onResize?: (currentNode: SplitNode, percentage: number) => void;
65
+ /** Callback triggered when the user stops dragging a resizing handle. Passes the final split percentage. */
66
+ onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
67
+ /** Minimum split percentage allowed when resizing split panes. Defaults to 5. */
68
+ minSplitPercentage?: number;
69
+ /** Maximum split percentage allowed when resizing split panes. Defaults to 95. */
70
+ maxSplitPercentage?: number;
71
+ /** Whether dragging a pane far enough outside the container triggers a drag-out/dismiss action. Defaults to false. */
72
+ enableDragToDismiss?: boolean;
73
+ /** The threshold in pixels beyond the container boundaries required to activate the drag-out/dismiss action. */
74
+ dismissThreshold?: number;
75
+ /** Callback triggered when the drag-out/dismiss intent changes (active pane ID or null when drag returns inside bounds). */
76
+ onDismissIntentChange?: (paneId: string | null) => void;
77
+ /** Child nodes nested inside the Zeugma context, usually containing a <PaneTree> or similar layout viewer. */
78
+ children: ReactNode;
79
+ }
26
80
  /**
27
81
  * State context — holds reactive values that change during runtime.
28
82
  * All consumers of this context will re-render when any of these values change.
29
83
  */
30
- interface DashboardStateValue {
84
+ interface ZeugmaStateValue {
85
+ /** The current active layout tree structure, or null if empty. */
31
86
  layout: TreeNode | null;
87
+ /** Callback to update the layout tree. */
32
88
  onLayoutChange: (newLayout: TreeNode | null) => void;
89
+ /** Renders the inner content of a pane given its unique ID. */
33
90
  renderPane: (paneId: string) => ReactNode;
91
+ /** The ID of the pane currently being dragged, or null. */
34
92
  activeId: string | null;
93
+ /** The ID of the pane currently targeted for dismiss/drag-out, or null. */
35
94
  dismissIntentId: string | null;
95
+ /** Ref setter to measure and track the dashboard root container element. */
36
96
  setContainerRef: (element: HTMLElement | null) => void;
97
+ /** The ID of the pane currently zoomed to fullscreen, or null. */
37
98
  fullscreenPaneId: string | null;
99
+ /** Normalized or overridden CSS classes for custom layout styling. */
38
100
  classNames: ZeugmaClassNames;
101
+ /** Callback triggered when a pane is closed/removed from the dashboard. */
39
102
  onRemove?: (paneId: string) => void;
103
+ /** Callback triggered to toggle fullscreen status for a pane. */
40
104
  onFullscreenChange?: (paneId: string | null) => void;
105
+ /** Threshold in pixels to snap layout resizers to adjacent edges. */
41
106
  snapThreshold?: number;
107
+ /** Callback triggered when a split pane starts being resized. */
42
108
  onResizeStart?: (currentNode: SplitNode) => void;
109
+ /** Callback triggered continuously during a split pane resize. */
43
110
  onResize?: (currentNode: SplitNode, percentage: number) => void;
111
+ /** Callback triggered when a split pane resize action is completed. */
44
112
  onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
113
+ /** Minimum split percentage allowed when resizing. */
45
114
  minSplitPercentage?: number;
115
+ /** Maximum split percentage allowed when resizing. */
46
116
  maxSplitPercentage?: number;
47
117
  }
48
118
  /**
49
119
  * Actions context — holds stable dispatch functions with permanent identity.
50
120
  * Consumers of only this context will never re-render from layout/drag state changes.
51
121
  */
52
- interface DashboardActionsValue {
122
+ interface ZeugmaActionsValue {
123
+ /** Removes the specified pane from the layout tree and collapses its parent split. */
53
124
  removePane: (paneId: string) => void;
125
+ /** Appends/inserts a pane at the bottom-rightmost leaf of the layout tree. */
54
126
  addPane: (paneId: string) => void;
127
+ /** Swaps the positions of two panes in the layout tree. */
55
128
  swapPanes: (paneIdA: string, paneIdB: string) => void;
129
+ /** Splits a target pane with a new pane in the specified direction and side. */
56
130
  splitPane: (targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string) => void;
131
+ /** Updates the split percentage of a specific split branch node. */
57
132
  updateSplitPercentage: (currentNode: SplitNode, percentage: number) => void;
133
+ /** Stable callback to update metadata for a specific pane. */
58
134
  updatePaneMetadata: (paneId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
59
135
  }
60
136
 
61
- /** Returns only reactive state. Use when you need layout, activeId, classNames, etc. */
62
- declare const useDashboardState: () => DashboardStateValue;
63
- /** Returns only stable action dispatchers. Consumers of this hook never re-render from state changes. */
64
- declare const useDashboardActions: () => DashboardActionsValue;
137
+ declare const useZeugmaState: () => ZeugmaStateValue;
138
+ declare const useZeugmaActions: () => ZeugmaActionsValue;
65
139
 
66
- interface DashboardProviderProps {
67
- layout: TreeNode | null;
68
- onChange: (newLayout: TreeNode | null) => void;
69
- renderPane: (paneId: string) => ReactNode;
70
- renderDragOverlay?: (activeId: string) => ReactNode;
71
- classNames?: ZeugmaClassNames;
72
- fullscreenPaneId?: string | null;
73
- onFullscreenChange?: (paneId: string | null) => void;
74
- onRemove?: (paneId: string) => void;
75
- dragActivationDistance?: number;
76
- snapThreshold?: number;
77
- onDragStart?: (activeId: string) => void;
78
- onDragEnd?: (activeId: string, overId: string | null, dropAction: {
79
- type: 'split' | 'swap';
80
- direction?: SplitDirection;
81
- position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
82
- } | null) => void;
83
- onResizeStart?: (currentNode: SplitNode) => void;
84
- onResize?: (currentNode: SplitNode, percentage: number) => void;
85
- onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
86
- minSplitPercentage?: number;
87
- maxSplitPercentage?: number;
88
- enableDragToDismiss?: boolean;
89
- dismissThreshold?: number;
90
- onDismissIntentChange?: (paneId: string | null) => void;
91
- children: ReactNode;
92
- }
93
- declare const DashboardProvider: React.FC<DashboardProviderProps>;
140
+ declare const Zeugma: React.FC<ZeugmaProps>;
94
141
 
95
142
  interface UseResizerProps {
96
143
  containerRef: React.RefObject<HTMLDivElement | null>;
@@ -108,10 +155,11 @@ interface UseResizerProps {
108
155
  declare function useResizer({ containerRef, isRow, direction, splitPercentage, resizerSize, snapThreshold, layout, currentNode, onLayoutChange, onResizeStart: localOnResizeStart, onResizeEnd: localOnResizeEnd, }: UseResizerProps): (e: React.PointerEvent<HTMLDivElement>) => void;
109
156
 
110
157
  interface PaneTreeProps {
158
+ /** The layout subtree node to render. If not specified, defaults to the root layout tree from the Zeugma context. */
111
159
  tree?: TreeNode | null;
112
- /** Size of the resizer in pixels (default 4) */
160
+ /** Size/thickness of the split handle resizer bars in pixels (default 4). */
113
161
  resizerSize?: number;
114
- /** Threshold in pixels to snap to adjacent resizer edges (default 8) */
162
+ /** Threshold distance in pixels to snap layout resizers to adjacent edges (default 8). */
115
163
  snapThreshold?: number;
116
164
  }
117
165
  declare const PaneTree: React.FC<PaneTreeProps>;
@@ -142,24 +190,36 @@ interface ResizableContainerProps {
142
190
  declare const ResizableContainer: React.FC<ResizableContainerProps>;
143
191
 
144
192
  interface PaneRenderProps {
193
+ /** True if the pane is actively being dragged. */
145
194
  isDragging: boolean;
195
+ /** True if the pane currently occupies the fullscreen view. */
146
196
  isFullscreen: boolean;
197
+ /** Toggles the pane to and from fullscreen/zoomed mode. */
147
198
  toggleFullscreen: () => void;
199
+ /** Closes and removes the pane from the layout tree. */
148
200
  remove: () => void;
201
+ /** The metadata values associated with this pane, or undefined. */
149
202
  metadata: Record<string, unknown> | undefined;
203
+ /** Updates the metadata of this pane using an updater function. */
150
204
  updateMetadata: (updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
151
205
  }
152
206
 
153
207
  interface PaneProps {
208
+ /** The unique ID of the pane, matching a `paneId` in the layout tree schema. */
154
209
  id: string;
210
+ /** Render prop function providing pane state (isDragging, isFullscreen, etc.) and handlers. */
155
211
  children: (props: PaneRenderProps) => React.ReactNode;
212
+ /** Optional inline CSS styles applied to the pane outer container. */
156
213
  style?: React.CSSProperties;
157
214
  }
158
215
  declare const Pane: React.FC<PaneProps>;
159
216
 
160
217
  interface DragHandleProps {
218
+ /** The children elements that will trigger dragging when held and dragged. */
161
219
  children: React.ReactNode;
220
+ /** Custom CSS class applied to the drag handle element. */
162
221
  className?: string;
222
+ /** Optional inline CSS styles applied to the drag handle. */
163
223
  style?: React.CSSProperties;
164
224
  }
165
225
  declare const DragHandle: React.FC<DragHandleProps>;
@@ -188,10 +248,6 @@ declare function addPane(tree: TreeNode | null, paneToAdd: string): TreeNode;
188
248
  * Tree Helper: Update split percentage recursively.
189
249
  */
190
250
  declare function updateSplitPercentage(tree: TreeNode | null, target: SplitNode, newPercentage: number): TreeNode | null;
191
- /**
192
- * Tree Helper: Split the entire tree at the root using a dragged pane.
193
- */
194
- declare function splitRoot(tree: TreeNode | null, draggingId: string, splitType: 'left' | 'right' | 'top' | 'bottom'): TreeNode | null;
195
251
  /**
196
252
  * Find a PaneNode by its paneId.
197
253
  */
@@ -226,4 +282,4 @@ interface DragSessionConfig {
226
282
  }
227
283
  declare function createDragSession({ cursor, resizerEl, onMove, onEnd }: DragSessionConfig): void;
228
284
 
229
- export { DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_RESIZER_SIZE, DEFAULT_SNAP_THRESHOLD, type DashboardActionsValue, DashboardProvider, type DashboardStateValue, DragHandle, type DragSessionConfig, Pane, type PaneNode, type PaneRenderProps, PaneTree, ResizableContainer, type ResizableContainerProps, type SplitDirection, type SplitNode, type TreeNode, type ZeugmaClassNames, addPane, createDragSession, findPane, removePane, splitPane, splitRoot, swapPanes, updatePaneMetadata, updateSplitPercentage, useDashboardActions, useDashboardState, useResizer };
285
+ export { DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_RESIZER_SIZE, DEFAULT_SNAP_THRESHOLD, DragHandle, type DragHandleProps, type DragSessionConfig, Pane, type PaneNode, type PaneProps, type PaneRenderProps, PaneTree, ResizableContainer, type ResizableContainerProps, type SplitDirection, type SplitNode, type TreeNode, Zeugma, type ZeugmaActionsValue, type ZeugmaClassNames, type ZeugmaProps, type ZeugmaStateValue, addPane, createDragSession, findPane, removePane, splitPane, swapPanes, updatePaneMetadata, updateSplitPercentage, useResizer, useZeugmaActions, useZeugmaState };
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 se=createContext(void 0),ae=createContext(void 0);var G=()=>{let e=useContext(se);if(!e)throw new Error("useDashboardState must be used within a DashboardProvider");return e},be=()=>{let e=useContext(ae);if(!e)throw new Error("useDashboardActions must be used within a DashboardProvider");return e};function Y(e,t){if(e===null)return null;if(e.type==="pane")return e.paneId===t?null:e;let n=Y(e.first,t),r=Y(e.second,t);return n===null?r:r===null?n:{...e,first:n,second:r}}function re(e,t,n,r,o){if(e===null)return typeof o=="string"?{type:"pane",paneId:o}:o;if(e.type==="pane"){if(e.paneId===t){let i=typeof o=="string"?{type:"pane",paneId:o}:o,d=r==="left"||r==="top";return {type:"split",direction:n,first:d?i:e,second:d?e:i,splitPercentage:50}}return e}return {...e,first:re(e.first,t,n,r,o)||e.first,second:re(e.second,t,n,r,o)||e.second}}function Pe(e,t,n){if(e===null)return null;let r=O(e,t),o=O(e,n);if(!r||!o)return e;function i(d){return d.type==="pane"?d.paneId===t?{...o}:d.paneId===n?{...r}:d:{...d,first:i(d.first),second:i(d.second)}}return i(e)}function Ze(e,t){if(e===null)return {type:"pane",paneId:t};function n(r,o){return r.type==="pane"?{type:"split",direction:o==="row"?"column":"row",splitPercentage:50,first:r,second:{type:"pane",paneId:t}}:{...r,second:n(r.second,r.direction)}}return n(e,null)}function Q(e,t,n){return e===null?null:e===t?{...e,splitPercentage:n}:e.type==="split"?{...e,first:Q(e.first,t,n)||e.first,second:Q(e.second,t,n)||e.second}:e}function _e(e,t,n){let r=O(e,t)??{type:"pane",paneId:t},o=Y(e,t);if(o===null)return {...r};let i=n==="left"||n==="right"?"row":"column",d=n==="left"||n==="top",c={...r};return {type:"split",direction:i,first:d?c:o,second:d?o:c,splitPercentage:50}}function O(e,t){return e===null?null:e.type==="pane"?e.paneId===t?e:null:O(e.first,t)??O(e.second,t)}function le(e,t,n){if(e===null)return null;if(e.type==="pane"){if(e.paneId===t){let r=n(e.metadata);if(r===void 0){let{metadata:o,...i}=e;return i}return {...e,metadata:r}}return e}return {...e,first:le(e.first,t,n)??e.first,second:le(e.second,t,n)??e.second}}var je=8,et=8,Xt=4;var at=({activeId:e,render:t,className:n})=>{let r=useRef(null);return useEffect(()=>{let o=i=>{r.current&&(r.current.style.transform=`translate(${i.clientX+12}px, ${i.clientY+12}px)`);};return document.addEventListener("pointermove",o),()=>document.removeEventListener("pointermove",o)},[]),jsx("div",{ref:r,className:n,style:{position:"fixed",top:0,left:0,zIndex:9999,pointerEvents:"none"},children:t(e)})},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")}]},lt=({layout:e,onChange:t,renderPane:n,renderDragOverlay:r,classNames:o={},fullscreenPaneId:i=null,onFullscreenChange:d,onRemove:c,dragActivationDistance:D=8,snapThreshold:P=8,onDragStart:y,onDragEnd:s,onResizeStart:x,onResize:g,onResizeEnd:N,minSplitPercentage:E=5,maxSplitPercentage:I=95,enableDragToDismiss:S=false,dismissThreshold:w=60,onDismissIntentChange:H,children:z})=>{let[u,m]=useState(e),[ee,te]=useState(e);e!==ee&&(te(e),m(e));let[b,T]=useState(null),[v,M]=useState(null),B=useRef(null),Z=useRef(null),h=useCallback(l=>{B.current=l;},[]),C=useCallback(l=>n(l),[n]),F=useMemo(()=>o,[o.pane,o.dropPreview,o.swapPreview,o.dragOverlay,o.resizer,o.dismissPreview]),_=useSensors(useSensor(Re,{activationConstraint:{distance:D}}),useSensor(De,{activationConstraint:{delay:250,tolerance:5}})),X=l=>{let f=l.active.id.toString();T(f),S&&B.current?Z.current=B.current.getBoundingClientRect():Z.current=null,y&&y(f);},K=l=>{if(!S)return;let f=l.active.id.toString(),a=Z.current;if(!a){v!==null&&(M(null),H?.(null));return}let p=l.activatorEvent,$=null,A=null;if(p instanceof MouseEvent||p instanceof PointerEvent)$=p.clientX+l.delta.x,A=p.clientY+l.delta.y;else if(typeof TouchEvent<"u"&&p instanceof TouchEvent){let R=p.touches[0]||p.changedTouches[0];R&&($=R.clientX+l.delta.x,A=R.clientY+l.delta.y);}let k=0;if($!==null&&A!==null){let R=0,L=0;$<a.left?R=a.left-$:$>a.right&&(R=$-a.right),A<a.top?L=a.top-A:A>a.bottom&&(L=A-a.bottom),k=Math.sqrt(R*R+L*L);}else {let R=l.active.rect.current.translated;if(R){let L=R.left+R.width/2,q=R.top+R.height/2,J=0,j=0;L<a.left?J=a.left-L:L>a.right&&(J=L-a.right),q<a.top?j=a.top-q:q>a.bottom&&(j=q-a.bottom),k=Math.sqrt(J*J+j*j);}}k>w?v!==f&&(M(f),H?.(f)):v!==null&&(M(null),H?.(null));},ne=l=>{T(null);let{active:f,over:a}=l,p=f.id.toString(),$=S&&v===p;if(M(null),H?.(null),Z.current=null,$){c?c(p):he(p),s&&s(p,null,null);return}if(!a){s&&s(p,null,null);return}let A=a.id.toString(),k=A.match(/^drop-root-(left|right|top|bottom)$/);if(k){let[,W]=k,oe=_e(u,p,W);m(oe),t(oe),s&&s(p,"root",{type:"split",direction:W==="left"||W==="right"?"row":"column",position:W});return}let ve=A.match(/^drop-center-(.+)$/);if(ve){let[,W]=ve;if(p!==W){let oe=Pe(u,p,W);m(oe),t(oe);}s&&s(p,W,{type:"swap",position:"center"});return}let R=A.match(/^drop-(left|right|top|bottom)-(.+)$/);if(!R){s&&s(p,null,null);return}let[,L,q]=R;if(p===q){s&&s(p,null,null);return}let J=L==="left"||L==="right"?"row":"column",j=O(u,p)??{type:"pane",paneId:p},Qe=Y(u,p),Fe=re(Qe,q,J,L,j);m(Fe),t(Fe),s&&s(p,q,{type:"split",direction:J,position:L});},Ie=useCallback(l=>{m(l),t(l);},[t]),he=useCallback(l=>{let f=Y(u,l);m(f),t(f);},[u,t]),ze=useCallback(l=>{let f=Ze(u,l);m(f),t(f);},[u,t]),Te=useCallback((l,f)=>{let a=Pe(u,l,f);m(a),t(a);},[u,t]),Ce=useCallback((l,f,a,p)=>{let $=O(u,p)??{type:"pane",paneId:p},A=Y(u,p),k=re(A,l,f,a,$);m(k),t(k);},[u,t]),Le=useCallback((l,f)=>{let a=Q(u,l,f);m(a),t(a);},[u,t]),Me=useCallback((l,f)=>{let a=le(u,l,f);m(a),t(a);},[u,t]),Ae=useCallback((l,f)=>{let a=Q(u,l,f);m(a),t(a),N&&N(l,f);},[u,t,N]),Ke=useMemo(()=>({layout:u,onLayoutChange:Ie,renderPane:C,activeId:b,dismissIntentId:v,setContainerRef:h,fullscreenPaneId:i,classNames:F,onRemove:c,onFullscreenChange:d,snapThreshold:P,onResizeStart:x,onResize:g,onResizeEnd:Ae,minSplitPercentage:E,maxSplitPercentage:I}),[u,b,v,h,i,F,c,d,P,x,g,E,I,Ie,C,Ae]),Je=useMemo(()=>({removePane:he,addPane:ze,swapPanes:Te,splitPane:Ce,updateSplitPercentage:Le,updatePaneMetadata:Me}),[he,ze,Te,Ce,Le,Me]);return jsx(ae.Provider,{value:Je,children:jsxs(se.Provider,{value:Ke,children:[jsx(DndContext,{id:"zeugma-dnd-context",sensors:_,collisionDetection:pointerWithin,onDragStart:X,onDragMove:K,onDragEnd:ne,children:z}),b&&r&&jsx(at,{activeId:b,render:r,className:`${o.dragOverlay||""} ${b===v?o.dismissPreview||"zeugma-dismiss-preview":""}`.trim()})]})})};var ut={top:{position:"absolute",top:0,left:0,right:0,height:"32px",zIndex:30,pointerEvents:"auto"},bottom:{position:"absolute",bottom:0,left:0,right:0,height:"32px",zIndex:30,pointerEvents:"auto"},left:{position:"absolute",top:0,bottom:0,left:0,width:"32px",zIndex:30,pointerEvents:"auto"},right:{position:"absolute",top:0,bottom:0,right:0,width:"32px",zIndex:30,pointerEvents:"auto"}},pt={top:{position:"absolute",top:0,left:0,right:0,height:"50%",zIndex:31,pointerEvents:"none",boxSizing:"border-box"},bottom:{position:"absolute",bottom:0,left:0,right:0,height:"50%",zIndex:31,pointerEvents:"none",boxSizing:"border-box"},left:{position:"absolute",top:0,bottom:0,left:0,width:"50%",zIndex:31,pointerEvents:"none",boxSizing:"border-box"},right:{position:"absolute",top:0,bottom:0,right:0,width:"50%",zIndex:31,pointerEvents:"none",boxSizing:"border-box"}},ft=({id:e,position:t,activeClassName:n})=>{let{setNodeRef:r,isOver:o}=useDroppable({id:e});return jsxs(Fragment,{children:[jsx("div",{ref:r,style:ut[t]}),o&&jsx("div",{className:n,style:pt[t]})]})},Ve=({activeId:e,hasOtherPanes:t,dropPreviewClassName:n})=>!e||!t?null:jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:30,pointerEvents:"none"},children:["top","bottom","left","right"].map(r=>jsx(ft,{id:`drop-root-${r}`,position:r,activeClassName:n},r))});function pe({cursor:e,resizerEl:t,onMove:n,onEnd:r}){document.body.classList.add("zeugma-resizing");let o=document.createElement("style");o.id="zeugma-global-cursor-style",o.textContent=`
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 re=createContext(void 0),ie=createContext(void 0);var B=()=>{let e=useContext(re);if(!e)throw new Error("useZeugmaState must be used within a Zeugma provider");return e},he=()=>{let e=useContext(ie);if(!e)throw new Error("useZeugmaActions must be used within a Zeugma provider");return e};function Q(e,t){if(e===null)return null;if(e.type==="pane")return e.paneId===t?null:e;let n=Q(e.first,t),r=Q(e.second,t);return n===null?r:r===null?n:{...e,first:n,second:r}}function ne(e,t,n,r,o){if(e===null)return typeof o=="string"?{type:"pane",paneId:o}:o;if(e.type==="pane"){if(e.paneId===t){let i=typeof o=="string"?{type:"pane",paneId:o}:o,u=r==="left"||r==="top";return {type:"split",direction:n,first:u?i:e,second:u?e:i,splitPercentage:50}}return e}return {...e,first:ne(e.first,t,n,r,o)||e.first,second:ne(e.second,t,n,r,o)||e.second}}function be(e,t,n){if(e===null)return null;let r=k(e,t),o=k(e,n);if(!r||!o)return e;function i(u){return u.type==="pane"?u.paneId===t?{...o}:u.paneId===n?{...r}:u:{...u,first:i(u.first),second:i(u.second)}}return i(e)}function He(e,t){if(e===null)return {type:"pane",paneId:t};function n(r,o){return r.type==="pane"?{type:"split",direction:o==="row"?"column":"row",splitPercentage:50,first:r,second:{type:"pane",paneId:t}}:{...r,second:n(r.second,r.direction)}}return n(e,null)}function G(e,t,n){return e===null?null:e===t?{...e,splitPercentage:n}:e.type==="split"?{...e,first:G(e.first,t,n)||e.first,second:G(e.second,t,n)||e.second}:e}function k(e,t){return e===null?null:e.type==="pane"?e.paneId===t?e:null:k(e.first,t)??k(e.second,t)}function se(e,t,n){if(e===null)return null;if(e.type==="pane"){if(e.paneId===t){let r=n(e.metadata);if(r===void 0){let{metadata:o,...i}=e;return i}return {...e,metadata:r}}return e}return {...e,first:se(e.first,t,n)??e.first,second:se(e.second,t,n)??e.second}}var Ge=8,Ke=8,Mt=4;var $e=({activeId:e,render:t,className:n})=>{let r=useRef(null);return useEffect(()=>{let o=i=>{r.current&&(r.current.style.transform=`translate(${i.clientX+12}px, ${i.clientY+12}px)`);};return document.addEventListener("pointermove",o),()=>document.removeEventListener("pointermove",o)},[]),jsx("div",{ref:r,className:n,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")}]},le=class extends TouchSensor{static activators=[{eventName:"onTouchStart",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]};var it=({layout:e,onChange:t,renderPane:n,renderDragOverlay:r,classNames:o={},fullscreenPaneId:i=null,onFullscreenChange:u,onRemove:p,dragActivationDistance:y=8,snapThreshold:S=8,onDragStart:E,onDragEnd:s,onResizeStart:b,onResize:P,onResizeEnd:L,minSplitPercentage:z=5,maxSplitPercentage:N=95,enableDragToDismiss:w=false,dismissThreshold:R=60,onDismissIntentChange:H,children:D})=>{let[c,m]=useState(e),[j,ee]=useState(e);e!==j&&(ee(e),m(e));let[h,T]=useState(null),[v,C]=useState(null),O=useRef(null),F=useRef(null),g=useCallback(l=>{O.current=l;},[]),I=useCallback(l=>n(l),[n]),Z=useMemo(()=>o,[o.pane,o.dropPreview,o.swapPreview,o.dragOverlay,o.resizer,o.dismissPreview]),_=useSensors(useSensor(ae,{activationConstraint:{distance:y}}),useSensor(le,{activationConstraint:{delay:250,tolerance:5}})),X=l=>{let f=l.active.id.toString();T(f),w&&O.current?F.current=O.current.getBoundingClientRect():F.current=null,E&&E(f);},q=l=>{if(!w)return;let f=l.active.id.toString(),a=F.current;if(!a){v!==null&&(C(null),H?.(null));return}let d=l.activatorEvent,$=null,A=null;if(d instanceof MouseEvent||d instanceof PointerEvent)$=d.clientX+l.delta.x,A=d.clientY+l.delta.y;else if(typeof TouchEvent<"u"&&d instanceof TouchEvent){let x=d.touches[0]||d.changedTouches[0];x&&($=x.clientX+l.delta.x,A=x.clientY+l.delta.y);}let Y=0;if($!==null&&A!==null){let x=0,M=0;$<a.left?x=a.left-$:$>a.right&&(x=$-a.right),A<a.top?M=a.top-A:A>a.bottom&&(M=A-a.bottom),Y=Math.sqrt(x*x+M*M);}else {let x=l.active.rect.current.translated;if(x){let M=x.left+x.width/2,W=x.top+x.height/2,K=0,J=0;M<a.left?K=a.left-M:M>a.right&&(K=M-a.right),W<a.top?J=a.top-W:W>a.bottom&&(J=W-a.bottom),Y=Math.sqrt(K*K+J*J);}}Y>R?v!==f&&(C(f),H?.(f)):v!==null&&(C(null),H?.(null));},te=l=>{T(null);let{active:f,over:a}=l,d=f.id.toString(),$=w&&v===d;if(C(null),H?.(null),F.current=null,$){p?p(d):me(d),s&&s(d,null,null);return}if(!a){s&&s(d,null,null);return}let A=a.id.toString(),Y=A.match(/^drop-center-(.+)$/);if(Y){let[,ve]=Y;if(d!==ve){let Me=be(c,d,ve);m(Me),t(Me);}s&&s(d,ve,{type:"swap",position:"center"});return}let ge=A.match(/^drop-(left|right|top|bottom)-(.+)$/);if(!ge){s&&s(d,null,null);return}let[,x,M]=ge;if(d===M){s&&s(d,null,null);return}let W=x==="left"||x==="right"?"row":"column",K=k(c,d)??{type:"pane",paneId:d},J=Q(c,d),Ce=ne(J,M,W,x,K);m(Ce),t(Ce),s&&s(d,M,{type:"split",direction:W,position:x});},Ee=useCallback(l=>{m(l),t(l);},[t]),me=useCallback(l=>{let f=Q(c,l);m(f),t(f);},[c,t]),Ne=useCallback(l=>{let f=He(c,l);m(f),t(f);},[c,t]),ze=useCallback((l,f)=>{let a=be(c,l,f);m(a),t(a);},[c,t]),De=useCallback((l,f,a,d)=>{let $=k(c,d)??{type:"pane",paneId:d},A=Q(c,d),Y=ne(A,l,f,a,$);m(Y),t(Y);},[c,t]),Te=useCallback((l,f)=>{let a=G(c,l,f);m(a),t(a);},[c,t]),Ie=useCallback((l,f)=>{let a=se(c,l,f);m(a),t(a);},[c,t]),Le=useCallback((l,f)=>{let a=G(c,l,f);m(a),t(a),L&&L(l,f);},[c,t,L]),qe=useMemo(()=>({layout:c,onLayoutChange:Ee,renderPane:I,activeId:h,dismissIntentId:v,setContainerRef:g,fullscreenPaneId:i,classNames:Z,onRemove:p,onFullscreenChange:u,snapThreshold:S,onResizeStart:b,onResize:P,onResizeEnd:Le,minSplitPercentage:z,maxSplitPercentage:N}),[c,h,v,g,i,Z,p,u,S,b,P,z,N,Ee,I,Le]),We=useMemo(()=>({removePane:me,addPane:Ne,swapPanes:ze,splitPane:De,updateSplitPercentage:Te,updatePaneMetadata:Ie}),[me,Ne,ze,De,Te,Ie]);return jsx(ie.Provider,{value:We,children:jsxs(re.Provider,{value:qe,children:[jsx(DndContext,{id:"zeugma-dnd-context",sensors:_,collisionDetection:pointerWithin,onDragStart:X,onDragMove:q,onDragEnd:te,children:D}),h&&r&&jsx($e,{activeId:h,render:r,className:`${o.dragOverlay||""} ${h===v?o.dismissPreview||"zeugma-dismiss-preview":""}`.trim()})]})})};function ue({cursor:e,resizerEl:t,onMove:n,onEnd:r}){document.body.classList.add("zeugma-resizing");let o=document.createElement("style");o.id="zeugma-global-cursor-style",o.textContent=`
2
2
  * {
3
3
  cursor: ${e} !important;
4
4
  user-select: none !important;
5
5
  }
6
- `,document.head.appendChild(o),t.setAttribute("data-resizing","true");let i=c=>{n(c);},d=()=>{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",d),r();};document.addEventListener("pointermove",i),document.addEventListener("pointerup",d);}function Ne({containerRef:e,isRow:t,direction:n,splitPercentage:r,resizerSize:o,snapThreshold:i,layout:d,currentNode:c,onLayoutChange:D,onResizeStart:P,onResizeEnd:y}){let{onResizeStart:s,onResize:x,onResizeEnd:g,minSplitPercentage:N=5,maxSplitPercentage:E=95}=G();return useCallback(I=>{I.preventDefault();let S=e.current;if(!S)return;P&&P(),s&&s(c);let w=S.getBoundingClientRect(),H=I.clientX,z=I.clientY,u=r,m=I.currentTarget,te=Array.from(document.querySelectorAll('div[role="separator"][data-direction]')).filter(T=>T!==m&&T.getAttribute("data-direction")===n).map(T=>{let v=T.getBoundingClientRect();return t?v.left+v.width/2:v.top+v.height/2}),b=u;pe({cursor:t?"col-resize":"row-resize",resizerEl:m,onMove:T=>{let v=t?(T.clientX-H)/w.width*100:(T.clientY-z)/w.height*100,M=u+v,B=t?w.left+(w.width-o)*(M/100)+o/2:w.top+(w.height-o)*(M/100)+o/2,Z=1/0,h=null;for(let K of te){let ne=Math.abs(B-K);ne<i&&ne<Z&&(Z=ne,h=K);}let C=M;h!==null&&(C=t?(h-o/2-w.left)/(w.width-o)*100:(h-o/2-w.top)/(w.height-o)*100);let F=Math.max(N,Math.min(E,C));b=F;let _=S.children[0],X=S.children[S.children.length-1];_&&X&&(_.style.flex=`${F} 1 0%`,X.style.flex=`${100-F} 1 0%`),x&&x(c,F);},onEnd:()=>{let T=Q(d,c,b);D(T),y&&y(),g&&g(c,b);}});},[e,t,n,r,o,i,d,c,D,P,y,s,x,g,N,E])}var xt=({currentNode:e,resizerSize:t,snapThreshold:n})=>{let{layout:r,onLayoutChange:o,classNames:i}=G(),[d,c]=useState(false),D=useRef(null),{direction:P,first:y,second:s,splitPercentage:x}=e,g=P==="row",N=Ne({containerRef:D,isRow:g,direction:P,splitPercentage:x,resizerSize:t,snapThreshold:n??8,layout:r,currentNode:e,onLayoutChange:o,onResizeStart:()=>c(true),onResizeEnd:()=>c(false)});return jsxs("div",{ref:D,style:{display:"flex",flexDirection:g?"row":"column",width:"100%",height:"100%",overflow:"hidden"},children:[jsx("div",{style:{flex:`${x} 1 0%`,overflow:"hidden"},children:jsx(we,{tree:y,resizerSize:t,snapThreshold:n})}),jsx("div",{className:`zeugma-resizer ${i.resizer||""}`.trim(),"data-direction":P,"data-resizing":d||void 0,style:{width:g?`${t}px`:"100%",height:g?"100%":`${t}px`,cursor:g?"col-resize":"row-resize",position:"relative",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box",flexShrink:0},onPointerDown:N,role:"separator","aria-valuenow":x,"aria-valuemin":5,"aria-valuemax":95}),jsx("div",{style:{flex:`${100-x} 1 0%`,overflow:"hidden"},children:jsx(we,{tree:s,resizerSize:t,snapThreshold:n})})]})},we=({tree:e,resizerSize:t=4,snapThreshold:n})=>{let{layout:r,renderPane:o,activeId:i,dismissIntentId:d,setContainerRef:c,classNames:D,fullscreenPaneId:P,snapThreshold:y}=G(),s=n!==void 0?n:y,x=useMemo(()=>e!==void 0||!i?false:Y(r,i)!==null,[e,r,i]);if(P&&!e)return jsx("div",{style:{width:"100%",height:"100%",position:"relative"},children:o(P)});let g=e!==void 0?e:r;if(!g)return null;let N=()=>g.type==="pane"?jsx("div",{style:{width:"100%",height:"100%",position:"relative"},children:o(g.paneId)}):jsx(xt,{currentNode:g,resizerSize:t,snapThreshold:s});return e===void 0?jsxs("div",{ref:c,className:`zeugma-dashboard-root ${i!==null&&i===d?"zeugma-dashboard-dismiss-active":""}`.trim(),style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:[N(),jsx(Ve,{activeId:i,hasOtherPanes:x,dropPreviewClassName:D.dropPreview})]}):N()};var Xe="zeugma-height:",Dt="default-pane";function Nt(e){try{let t=localStorage.getItem(Xe+e);if(t!==null){let n=Number(t);if(Number.isFinite(n)&&n>0)return n}}catch{}return null}function Be(e,t){try{localStorage.setItem(Xe+e,String(Math.round(t)));}catch{}}var qe=({children:e,active:t=true,height:n,onHeightChange:r,minHeight:o=100,maxHeight:i=1/0,persist:d,localStorageKey:c,resizerHeight:D=6,className:P,resizerClassName:y})=>{let s=d?c||Dt:null,x=()=>{let z=(s?Nt(s):null)??n??400;return fe(z,o,i)},[g,N]=useState(x),E=useRef(null),I=s?g:n??g,S=useRef(n);useEffect(()=>{if(n!==void 0&&n!==S.current){let z=fe(n,o,i);N(z),s&&Be(s,z);}S.current=n;},[n,o,i,s]);let w=useCallback(()=>i,[i]),H=useCallback(z=>{z.preventDefault();let u=z.clientY,m=I,ee=w(),te=z.currentTarget,b=We(E.current),T=b?b.scrollTop:0,v=u,M=null,B=(h,C)=>{let F=C-T,X=h-u+F,K=fe(m+X,o,ee);return E.current&&(E.current.style.height=`${K}px`),K},Z=()=>{if(!b)return;let h=b===document.documentElement||b===document.body?{top:0,bottom:window.innerHeight}:b.getBoundingClientRect(),C=40,F=10,_=0;v>h.bottom-C?_=Math.min(1,(v-(h.bottom-C))/C)*F:v<h.top+C&&(_=-Math.min(1,(h.top+C-v)/C)*F),_!==0&&(b.scrollTop+=_,B(v,b.scrollTop)),M=requestAnimationFrame(Z);};M=requestAnimationFrame(Z),pe({cursor:"row-resize",resizerEl:te,onMove:h=>{v=h.clientY,b&&B(v,b.scrollTop);},onEnd:()=>{M!==null&&cancelAnimationFrame(M);let h=m;E.current&&(h=E.current.getBoundingClientRect().height),h=fe(h,o,ee),N(h),r&&r(h),s&&Be(s,h);}});},[I,o,w,r,s]);return t?jsxs("div",{ref:E,className:`zeugma-resizable-container ${P||""}`.trim(),style:{height:`${I}px`,position:"relative",overflow:"hidden",boxSizing:"border-box"},children:[jsx("div",{style:{height:`calc(100% - ${D}px)`,overflow:"hidden"},children:e}),jsx("div",{className:`zeugma-resizable-handle ${y||""}`.trim(),style:{height:`${D}px`,cursor:"row-resize",position:"relative",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box",flexShrink:0},onPointerDown:H,role:"separator","aria-orientation":"horizontal","aria-valuenow":Math.round(I),"aria-valuemin":o,"aria-valuemax":i===1/0?void 0:i})]}):jsx("div",{className:`zeugma-resizable-container disabled ${P||""}`.trim(),style:{height:"100%",position:"relative",overflow:"hidden",boxSizing:"border-box"},children:jsx("div",{style:{height:"100%",overflow:"hidden"},children:e})})};function fe(e,t,n){return Math.max(t,Math.min(n,e))}function We(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:We(t)}var ge=createContext(null);var zt={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"}},Tt={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"}},Ge=({id:e,position:t,activeClassName:n})=>{let{setNodeRef:r,isOver:o}=useDroppable({id:e});return jsxs(Fragment,{children:[jsx("div",{ref:r,style:zt[t]}),o&&jsx("div",{className:n,style:Tt[t]})]})},Ct=({id:e,children:t,style:n})=>{let{layout:r,activeId:o,classNames:i,fullscreenPaneId:d,onRemove:c,onFullscreenChange:D}=G(),{removePane:P,updatePaneMetadata:y}=be(),s=o!==null&&o!==e,{attributes:x,listeners:g,setNodeRef:N,isDragging:E}=useDraggable({id:e}),I=o===e||E,S=d===e,H=useMemo(()=>O(r,e),[r,e])?.metadata,z=useMemo(()=>({isDragging:I,isFullscreen:S,toggleFullscreen:()=>D?.(S?null:e),remove:()=>{S&&D?.(null),c?c(e):P(e);},metadata:H,updateMetadata:m=>{y(e,m);}}),[I,S,D,e,c,P,H,y]),u=useMemo(()=>({...g,...x}),[g,x]);return jsx(ge.Provider,{value:u,children:jsxs("div",{ref:N,className:i.pane,style:{position:"relative",width:"100%",height:"100%",...n},children:[t(z),s&&jsxs("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:[["top","bottom","left","right"].map(m=>jsx(Ge,{id:`drop-${m}-${e}`,position:m,activeClassName:i.dropPreview},m)),jsx(Ge,{id:`drop-center-${e}`,position:"center",activeClassName:i.swapPreview})]})]})})};var At=({children:e,className:t,style:n})=>{let r=useContext(ge);if(!r)throw new Error("<DragHandle> must be used inside a <Pane>");return jsx("div",{className:t,style:{cursor:"grab",userSelect:"none",touchAction:"none",...n},...r,children:e})};export{et as DEFAULT_DRAG_ACTIVATION_DISTANCE,Xt as DEFAULT_RESIZER_SIZE,je as DEFAULT_SNAP_THRESHOLD,lt as DashboardProvider,At as DragHandle,Ct as Pane,we as PaneTree,qe as ResizableContainer,Ze as addPane,pe as createDragSession,O as findPane,Y as removePane,re as splitPane,_e as splitRoot,Pe as swapPanes,le as updatePaneMetadata,Q as updateSplitPercentage,be as useDashboardActions,G as useDashboardState,Ne as useResizer};//# sourceMappingURL=index.js.map
6
+ `,document.head.appendChild(o),t.setAttribute("data-resizing","true");let i=p=>{n(p);},u=()=>{document.body.classList.remove("zeugma-resizing"),t.removeAttribute("data-resizing");let p=document.getElementById("zeugma-global-cursor-style");p&&p.remove(),document.removeEventListener("pointermove",i),document.removeEventListener("pointerup",u),r();};document.addEventListener("pointermove",i),document.addEventListener("pointerup",u);}function Se({containerRef:e,isRow:t,direction:n,splitPercentage:r,resizerSize:o,snapThreshold:i,layout:u,currentNode:p,onLayoutChange:y,onResizeStart:S,onResizeEnd:E}){let{onResizeStart:s,onResize:b,onResizeEnd:P,minSplitPercentage:L=5,maxSplitPercentage:z=95}=B();return useCallback(N=>{N.preventDefault();let w=e.current;if(!w)return;S&&S(),s&&s(p);let R=w.getBoundingClientRect(),H=N.clientX,D=N.clientY,c=r,m=N.currentTarget,ee=Array.from(document.querySelectorAll('div[role="separator"][data-direction]')).filter(T=>T!==m&&T.getAttribute("data-direction")===n).map(T=>{let v=T.getBoundingClientRect();return t?v.left+v.width/2:v.top+v.height/2}),h=c;ue({cursor:t?"col-resize":"row-resize",resizerEl:m,onMove:T=>{let v=t?(T.clientX-H)/R.width*100:(T.clientY-D)/R.height*100,C=c+v,O=t?R.left+(R.width-o)*(C/100)+o/2:R.top+(R.height-o)*(C/100)+o/2,F=1/0,g=null;for(let q of ee){let te=Math.abs(O-q);te<i&&te<F&&(F=te,g=q);}let I=C;g!==null&&(I=t?(g-o/2-R.left)/(R.width-o)*100:(g-o/2-R.top)/(R.height-o)*100);let Z=Math.max(L,Math.min(z,I));h=Z;let _=w.children[0],X=w.children[w.children.length-1];_&&X&&(_.style.flex=`${Z} 1 0%`,X.style.flex=`${100-Z} 1 0%`),b&&b(p,Z);},onEnd:()=>{let T=G(u,p,h);y(T),E&&E(),P&&P(p,h);}});},[e,t,n,r,o,i,u,p,y,S,E,s,b,P,L,z])}var ut=({currentNode:e,resizerSize:t,snapThreshold:n})=>{let{layout:r,onLayoutChange:o,classNames:i}=B(),[u,p]=useState(false),y=useRef(null),{direction:S,first:E,second:s,splitPercentage:b}=e,P=S==="row",L=Se({containerRef:y,isRow:P,direction:S,splitPercentage:b,resizerSize:t,snapThreshold:n??8,layout:r,currentNode:e,onLayoutChange:o,onResizeStart:()=>p(true),onResizeEnd:()=>p(false)});return jsxs("div",{ref:y,style:{display:"flex",flexDirection:P?"row":"column",width:"100%",height:"100%",overflow:"hidden"},children:[jsx("div",{style:{flex:`${b} 1 0%`,overflow:"hidden"},children:jsx(ye,{tree:E,resizerSize:t,snapThreshold:n})}),jsx("div",{className:`zeugma-resizer ${i.resizer||""}`.trim(),"data-direction":S,"data-resizing":u||void 0,style:{width:P?`${t}px`:"100%",height:P?"100%":`${t}px`,cursor:P?"col-resize":"row-resize",position:"relative",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box",flexShrink:0},onPointerDown:L,role:"separator","aria-valuenow":b,"aria-valuemin":5,"aria-valuemax":95}),jsx("div",{style:{flex:`${100-b} 1 0%`,overflow:"hidden"},children:jsx(ye,{tree:s,resizerSize:t,snapThreshold:n})})]})},ye=({tree:e,resizerSize:t=4,snapThreshold:n})=>{let{layout:r,renderPane:o,activeId:i,dismissIntentId:u,setContainerRef:p,fullscreenPaneId:y,snapThreshold:S}=B(),E=n!==void 0?n:S;if(y&&!e)return jsx("div",{style:{width:"100%",height:"100%",position:"relative"},children:o(y)});let s=e!==void 0?e:r;if(!s)return null;let b=()=>s.type==="pane"?jsx("div",{style:{width:"100%",height:"100%",position:"relative"},children:o(s.paneId)}):jsx(ut,{currentNode:s,resizerSize:t,snapThreshold:E});return e===void 0?jsx("div",{ref:p,className:`zeugma-dashboard-root ${i!==null&&i===u?"zeugma-dashboard-dismiss-active":""}`.trim(),style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:b()}):b()};var Ue="zeugma-height:",mt="default-pane";function gt(e){try{let t=localStorage.getItem(Ue+e);if(t!==null){let n=Number(t);if(Number.isFinite(n)&&n>0)return n}}catch{}return null}function ke(e,t){try{localStorage.setItem(Ue+e,String(Math.round(t)));}catch{}}var Oe=({children:e,active:t=true,height:n,onHeightChange:r,minHeight:o=100,maxHeight:i=1/0,persist:u,localStorageKey:p,resizerHeight:y=6,className:S,resizerClassName:E})=>{let s=u?p||mt:null,b=()=>{let D=(s?gt(s):null)??n??400;return de(D,o,i)},[P,L]=useState(b),z=useRef(null),N=s?P:n??P,w=useRef(n);useEffect(()=>{if(n!==void 0&&n!==w.current){let D=de(n,o,i);L(D),s&&ke(s,D);}w.current=n;},[n,o,i,s]);let R=useCallback(()=>i,[i]),H=useCallback(D=>{D.preventDefault();let c=D.clientY,m=N,j=R(),ee=D.currentTarget,h=Xe(z.current),T=h?h.scrollTop:0,v=c,C=null,O=(g,I)=>{let Z=I-T,X=g-c+Z,q=de(m+X,o,j);return z.current&&(z.current.style.height=`${q}px`),q},F=()=>{if(!h)return;let g=h===document.documentElement||h===document.body?{top:0,bottom:window.innerHeight}:h.getBoundingClientRect(),I=40,Z=10,_=0;v>g.bottom-I?_=Math.min(1,(v-(g.bottom-I))/I)*Z:v<g.top+I&&(_=-Math.min(1,(g.top+I-v)/I)*Z),_!==0&&(h.scrollTop+=_,O(v,h.scrollTop)),C=requestAnimationFrame(F);};C=requestAnimationFrame(F),ue({cursor:"row-resize",resizerEl:ee,onMove:g=>{v=g.clientY,h&&O(v,h.scrollTop);},onEnd:()=>{C!==null&&cancelAnimationFrame(C);let g=m;z.current&&(g=z.current.getBoundingClientRect().height),g=de(g,o,j),L(g),r&&r(g),s&&ke(s,g);}});},[N,o,R,r,s]);return t?jsxs("div",{ref:z,className:`zeugma-resizable-container ${S||""}`.trim(),style:{height:`${N}px`,position:"relative",overflow:"hidden",boxSizing:"border-box"},children:[jsx("div",{style:{height:`calc(100% - ${y}px)`,overflow:"hidden"},children:e}),jsx("div",{className:`zeugma-resizable-handle ${E||""}`.trim(),style:{height:`${y}px`,cursor:"row-resize",position:"relative",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box",flexShrink:0},onPointerDown:H,role:"separator","aria-orientation":"horizontal","aria-valuenow":Math.round(N),"aria-valuemin":o,"aria-valuemax":i===1/0?void 0:i})]}):jsx("div",{className:`zeugma-resizable-container disabled ${S||""}`.trim(),style:{height:"100%",position:"relative",overflow:"hidden",boxSizing:"border-box"},children:jsx("div",{style:{height:"100%",overflow:"hidden"},children:e})})};function de(e,t,n){return Math.max(t,Math.min(n,e))}function Xe(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:Xe(t)}var fe=createContext(null);var xt={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"}},St={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"}},Be=({id:e,position:t,activeClassName:n})=>{let{setNodeRef:r,isOver:o}=useDroppable({id:e});return jsxs(Fragment,{children:[jsx("div",{ref:r,style:xt[t]}),o&&jsx("div",{className:n,style:St[t]})]})},yt=({id:e,children:t,style:n})=>{let{layout:r,activeId:o,classNames:i,fullscreenPaneId:u,onRemove:p,onFullscreenChange:y}=B(),{removePane:S,updatePaneMetadata:E}=he(),s=o!==null&&o!==e,{attributes:b,listeners:P,setNodeRef:L,isDragging:z}=useDraggable({id:e}),N=o===e||z,w=u===e,H=useMemo(()=>k(r,e),[r,e])?.metadata,D=useMemo(()=>({isDragging:N,isFullscreen:w,toggleFullscreen:()=>y?.(w?null:e),remove:()=>{w&&y?.(null),p?p(e):S(e);},metadata:H,updateMetadata:m=>{E(e,m);}}),[N,w,y,e,p,S,H,E]),c=useMemo(()=>({...P,...b}),[P,b]);return jsx(fe.Provider,{value:c,children:jsxs("div",{ref:L,className:i.pane,style:{position:"relative",width:"100%",height:"100%",...n},children:[t(D),s&&jsxs("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:[["top","bottom","left","right"].map(m=>jsx(Be,{id:`drop-${m}-${e}`,position:m,activeClassName:i.dropPreview},m)),jsx(Be,{id:`drop-center-${e}`,position:"center",activeClassName:i.swapPreview})]})]})})};var Et=({children:e,className:t,style:n})=>{let r=useContext(fe);if(!r)throw new Error("<DragHandle> must be used inside a <Pane>");return jsx("div",{className:t,style:{cursor:"grab",userSelect:"none",touchAction:"none",...n},...r,children:e})};export{Ke as DEFAULT_DRAG_ACTIVATION_DISTANCE,Mt as DEFAULT_RESIZER_SIZE,Ge as DEFAULT_SNAP_THRESHOLD,Et as DragHandle,yt as Pane,ye as PaneTree,Oe as ResizableContainer,it as Zeugma,He as addPane,ue as createDragSession,k as findPane,Q as removePane,ne as splitPane,be as swapPanes,se as updatePaneMetadata,G as updateSplitPercentage,Se as useResizer,he as useZeugmaActions,B as useZeugmaState};//# sourceMappingURL=index.js.map
7
7
  //# sourceMappingURL=index.js.map