react-zeugma 3.0.0 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts 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 {
@@ -18,47 +18,31 @@ interface PaneNode {
18
18
  }
19
19
  type TreeNode = SplitNode | PaneNode;
20
20
 
21
- interface ZeugmaClassNames {
22
- /** CSS class applied to the outer container div of each `<Pane>`. */
23
- pane?: string;
24
- /** CSS class applied to the pane container when locked. */
25
- paneLocked?: string;
26
- /** CSS class applied to drop zone indicators when hovering over layout edges to split a pane. */
27
- dropPreview?: string;
28
- /** CSS class applied to the drop zone indicator when hovering over the center of a pane to swap. */
29
- swapPreview?: string;
30
- /** CSS class applied to the custom cursor-following drag preview portal wrapper. */
31
- dragOverlay?: string;
32
- /** CSS class applied to the drag-to-resize split bar handles. */
33
- resizer?: string;
34
- /** CSS class applied to the background dismiss zone indicator during a drag-out dismiss gesture. */
35
- dismissPreview?: string;
36
- /** CSS class applied to root container when dashboard is globally locked. */
37
- dashboardLocked?: string;
38
- /** CSS class applied to drop zone indicator when hovering over a locked pane. */
39
- lockedPreview?: string;
40
- }
41
- interface ZeugmaProps {
42
- /** The layout tree model (TreeNode) defining pane organization and split percentages. Set to null for empty layout. */
43
- 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;
44
24
  /** Callback triggered when the layout changes via drag-and-drop actions, splits, swaps, or resizes. */
45
- onChange: (newLayout: TreeNode | null) => void;
46
- /** Render function mapping unique pane IDs to React elements. Usually renders a <Pane> wrapper. */
47
- renderPane: (paneId: string) => ReactNode;
48
- /** Custom overlay renderer function used to customize the cursor-following drag preview for an active pane or tab. */
49
- renderDragOverlay?: (activeId: string, type: 'pane' | 'tab') => ReactNode;
50
- /** Optional CSS class name mapping overrides for custom styles of components like panes, drop/swap previews, overlays, etc. */
51
- classNames?: ZeugmaClassNames;
25
+ onChange?: (newLayout: TreeNode | null) => void;
52
26
  /** The ID of the pane that is currently taking up the full dashboard area. Null if no pane is fullscreen. */
53
27
  fullscreenPaneId?: string | null;
54
28
  /** Callback triggered when a pane is toggled to/from fullscreen mode. Passes the active fullscreen paneId or null. */
55
29
  onFullscreenChange?: (paneId: string | null) => void;
56
- /** Callback triggered when a pane is removed from the dashboard layout tree. */
57
- onRemove?: (paneId: string) => void;
30
+ /** Whether the layout is locked. When locked, resizing, dragging, and dropping are disabled. */
31
+ locked?: boolean;
58
32
  /** Minimum pixel distance that a user must drag a pane handle before dragging triggers. Defaults to 8. */
59
33
  dragActivationDistance?: number;
60
34
  /** Threshold value in pixels for snapping layout resizing handles to adjacent edges. Defaults to 8. */
61
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;
62
46
  /** Callback triggered when dragging starts for a pane. */
63
47
  onDragStart?: (activeId: string) => void;
64
48
  /** Callback triggered when dragging ends, providing details on target pane and drop action (split or swap). */
@@ -73,94 +57,84 @@ interface ZeugmaProps {
73
57
  onResize?: (currentNode: SplitNode, percentage: number) => void;
74
58
  /** Callback triggered when the user stops dragging a resizing handle. Passes the final split percentage. */
75
59
  onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
76
- /** Minimum split percentage allowed when resizing split panes. Defaults to 5. */
77
- minSplitPercentage?: number;
78
- /** Maximum split percentage allowed when resizing split panes. Defaults to 95. */
79
- maxSplitPercentage?: number;
80
- /** Whether dragging a pane far enough outside the container triggers a drag-out/dismiss action. Defaults to false. */
81
- enableDragToDismiss?: boolean;
82
- /** The threshold in pixels beyond the container boundaries required to activate the drag-out/dismiss action. */
83
- dismissThreshold?: number;
84
- /** 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. */
85
61
  onDismissIntentChange?: (paneId: string | null) => void;
86
- /** Whether the layout is locked. When locked, resizing, dragging, and dropping are disabled. */
87
- locked?: boolean;
88
- /** Render function mapping tab IDs to React elements. Used to render tab widgets inside portals. */
89
- renderWidget?: (tabId: string) => ReactNode;
90
- /** Child nodes nested inside the Zeugma context, usually containing a <PaneTree> or similar layout viewer. */
91
- children: ReactNode;
92
62
  }
93
- /**
94
- * State context — holds reactive values that change during runtime.
95
- * All consumers of this context will re-render when any of these values change.
96
- */
97
- interface ZeugmaStateValue {
98
- /** The current active layout tree structure, or null if empty. */
63
+ interface ZeugmaController {
99
64
  layout: TreeNode | null;
100
- /** Callback to update the layout tree. */
101
- onLayoutChange: (newLayout: TreeNode | null, localOnly?: boolean) => void;
102
- /** Renders the inner content of a pane given its unique ID. */
103
- renderPane: (paneId: string) => ReactNode;
104
- /** The ID of the pane currently being dragged, or null. */
65
+ setLayout: Dispatch<SetStateAction<TreeNode | null>>;
66
+ fullscreenPaneId: string | null;
67
+ setFullscreenPaneId: (paneId: string | null) => void;
68
+ locked: boolean;
69
+ setLocked: Dispatch<SetStateAction<boolean>>;
105
70
  activeId: string | null;
106
- /** The ID of the pane currently targeted for dismiss/drag-out, or null. */
71
+ setActiveId: Dispatch<SetStateAction<string | null>>;
72
+ activeType: 'pane' | 'tab' | null;
73
+ setActiveType: Dispatch<SetStateAction<'pane' | 'tab' | null>>;
107
74
  dismissIntentId: string | null;
108
- /** Ref setter to measure and track the dashboard root container element. */
75
+ setDismissIntentId: Dispatch<SetStateAction<string | null>>;
76
+ containerRef: RefObject<HTMLElement | null>;
109
77
  setContainerRef: (element: HTMLElement | null) => void;
110
- /** The ID of the pane currently zoomed to fullscreen, or null. */
111
- fullscreenPaneId: string | null;
112
- /** Normalized or overridden CSS classes for custom layout styling. */
113
- classNames: ZeugmaClassNames;
114
- /** Callback triggered when a pane is closed/removed from the dashboard. */
78
+ dragActivationDistance: number;
79
+ snapThreshold: number;
80
+ minSplitPercentage: number;
81
+ maxSplitPercentage: number;
82
+ enableDragToDismiss: boolean;
83
+ dismissThreshold: number;
115
84
  onRemove?: (paneId: string) => void;
116
- /** Callback triggered to toggle fullscreen status for a pane. */
117
- onFullscreenChange?: (paneId: string | null) => void;
118
- /** Threshold in pixels to snap layout resizers to adjacent edges. */
119
- snapThreshold?: number;
120
- /** Callback triggered when a split pane starts being resized. */
85
+ onDragStart?: (activeId: string) => void;
86
+ onDragEnd?: (activeId: string, overId: string | null, dropAction: {
87
+ type: 'split' | 'swap';
88
+ direction?: SplitDirection;
89
+ position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
90
+ } | null) => void;
121
91
  onResizeStart?: (currentNode: SplitNode) => void;
122
- /** Callback triggered continuously during a split pane resize. */
123
92
  onResize?: (currentNode: SplitNode, percentage: number) => void;
124
- /** Callback triggered when a split pane resize action is completed. */
125
93
  onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
126
- /** Minimum split percentage allowed when resizing. */
127
- minSplitPercentage?: number;
128
- /** Maximum split percentage allowed when resizing. */
129
- maxSplitPercentage?: number;
130
- /** Whether the layout is globally locked. */
131
- locked: boolean;
132
- }
133
- /**
134
- * Actions context — holds stable dispatch functions with permanent identity.
135
- * Consumers of only this context will never re-render from layout/drag state changes.
136
- */
137
- interface ZeugmaActionsValue {
138
- /** Removes the specified pane from the layout tree and collapses its parent split. */
94
+ onDismissIntentChange?: (paneId: string | null) => void;
139
95
  removePane: (paneId: string) => void;
140
- /** Appends/inserts a pane at the bottom-rightmost leaf of the layout tree. */
141
96
  addPane: (paneId: string) => void;
142
- /** Swaps the positions of two panes in the layout tree. */
143
- swapPanes: (paneIdA: string, paneIdB: string) => void;
144
- /** Splits a target pane with a new pane in the specified direction and side. */
145
97
  splitPane: (targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string) => void;
146
- /** Updates the split percentage of a specific split branch node. */
147
98
  updateSplitPercentage: (currentNode: SplitNode, percentage: number) => void;
148
- /** Stable callback to update metadata for a specific tab. */
149
99
  updateTabMetadata: (tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
150
- /** Stable callback to update the locked status of a specific pane in the layout tree. */
151
100
  updatePaneLock: (paneId: string, locked: boolean) => void;
152
- /** Stable callback to activate a tab within a pane. */
153
101
  selectTab: (paneId: string, tabId: string) => void;
154
- /** Stable callback to merge a dragged tab/pane into another pane's tab list. */
155
102
  mergeTab: (draggedTabId: string, targetPaneId: string) => void;
156
- /** Stable callback to move/reorder a tab to another pane next to a target tab. */
157
103
  moveTab: (draggedTabId: string, targetTabId: string, position?: 'before' | 'after') => void;
158
- /** Stable callback to remove/close a specific tab from the layout. */
159
104
  removeTab: (tabId: string) => void;
160
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;
135
+ }
161
136
 
162
- declare const useZeugmaState: () => ZeugmaStateValue;
163
- declare const useZeugmaActions: () => ZeugmaActionsValue;
137
+ declare function useZeugma(options: UseZeugmaOptions): ZeugmaController;
164
138
 
165
139
  declare const Zeugma: React.FC<ZeugmaProps>;
166
140
 
@@ -293,6 +267,7 @@ declare const DEFAULT_SNAP_THRESHOLD = 8;
293
267
  declare const DEFAULT_DRAG_ACTIVATION_DISTANCE = 8;
294
268
  declare const DEFAULT_RESIZER_SIZE = 4;
295
269
 
270
+ declare function generateUniqueId(): string;
296
271
  /**
297
272
  * Tree Helper: Remove a pane container and consolidate the tree structure.
298
273
  */
@@ -305,10 +280,6 @@ declare function removeTab(tree: TreeNode | null, tabId: string): TreeNode | nul
305
280
  * Tree Helper: Insert a pane by splitting an existing target node.
306
281
  */
307
282
  declare function splitPane(tree: TreeNode | null, targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string | PaneNode): TreeNode | null;
308
- /**
309
- * Tree Helper: Swap the position of two panes in the tree structure.
310
- */
311
- declare function swapPanes(tree: TreeNode | null, idA: string, idB: string): TreeNode | null;
312
283
  /**
313
284
  * Tree Helper: Add a pane by recursively splitting the rightmost/bottommost pane in the tree.
314
285
  */
@@ -392,4 +363,4 @@ interface DragSessionConfig {
392
363
  }
393
364
  declare function createDragSession({ cursor, resizerEl, onMove, onEnd }: DragSessionConfig): void;
394
365
 
395
- 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, Zeugma, type ZeugmaActionsValue, type ZeugmaClassNames, type ZeugmaProps, type ZeugmaStateValue, addPane, computeLayout, createDragSession, findPane, mergeTab, moveTab, removePane, removeTab, selectTab, splitPane, swapPanes, updatePaneLock, updateSplitPercentage, updateTabMetadata, useResizer, useZeugmaActions, useZeugmaState };
366
+ export { type ComputedPane, type ComputedSplitter, DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_RESIZER_SIZE, DEFAULT_SNAP_THRESHOLD, DragHandle, type DragHandleProps, type DragSessionConfig, Pane, type PaneNode, type PaneProps, type PaneRenderProps, PaneTree, ResizableContainer, type ResizableContainerProps, type SplitDirection, type SplitNode, Tab, type TabProps, type TabRenderProps, type TreeNode, type UseZeugmaOptions, Zeugma, type ZeugmaClassNames, type ZeugmaController, type ZeugmaProps, addPane, computeLayout, createDragSession, findPane, generateUniqueId, mergeTab, moveTab, removePane, removeTab, selectTab, splitPane, updatePaneLock, updateSplitPercentage, updateTabMetadata, useResizer, useZeugma };
package/dist/index.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 {
@@ -18,47 +18,31 @@ interface PaneNode {
18
18
  }
19
19
  type TreeNode = SplitNode | PaneNode;
20
20
 
21
- interface ZeugmaClassNames {
22
- /** CSS class applied to the outer container div of each `<Pane>`. */
23
- pane?: string;
24
- /** CSS class applied to the pane container when locked. */
25
- paneLocked?: string;
26
- /** CSS class applied to drop zone indicators when hovering over layout edges to split a pane. */
27
- dropPreview?: string;
28
- /** CSS class applied to the drop zone indicator when hovering over the center of a pane to swap. */
29
- swapPreview?: string;
30
- /** CSS class applied to the custom cursor-following drag preview portal wrapper. */
31
- dragOverlay?: string;
32
- /** CSS class applied to the drag-to-resize split bar handles. */
33
- resizer?: string;
34
- /** CSS class applied to the background dismiss zone indicator during a drag-out dismiss gesture. */
35
- dismissPreview?: string;
36
- /** CSS class applied to root container when dashboard is globally locked. */
37
- dashboardLocked?: string;
38
- /** CSS class applied to drop zone indicator when hovering over a locked pane. */
39
- lockedPreview?: string;
40
- }
41
- interface ZeugmaProps {
42
- /** The layout tree model (TreeNode) defining pane organization and split percentages. Set to null for empty layout. */
43
- 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;
44
24
  /** Callback triggered when the layout changes via drag-and-drop actions, splits, swaps, or resizes. */
45
- onChange: (newLayout: TreeNode | null) => void;
46
- /** Render function mapping unique pane IDs to React elements. Usually renders a <Pane> wrapper. */
47
- renderPane: (paneId: string) => ReactNode;
48
- /** Custom overlay renderer function used to customize the cursor-following drag preview for an active pane or tab. */
49
- renderDragOverlay?: (activeId: string, type: 'pane' | 'tab') => ReactNode;
50
- /** Optional CSS class name mapping overrides for custom styles of components like panes, drop/swap previews, overlays, etc. */
51
- classNames?: ZeugmaClassNames;
25
+ onChange?: (newLayout: TreeNode | null) => void;
52
26
  /** The ID of the pane that is currently taking up the full dashboard area. Null if no pane is fullscreen. */
53
27
  fullscreenPaneId?: string | null;
54
28
  /** Callback triggered when a pane is toggled to/from fullscreen mode. Passes the active fullscreen paneId or null. */
55
29
  onFullscreenChange?: (paneId: string | null) => void;
56
- /** Callback triggered when a pane is removed from the dashboard layout tree. */
57
- onRemove?: (paneId: string) => void;
30
+ /** Whether the layout is locked. When locked, resizing, dragging, and dropping are disabled. */
31
+ locked?: boolean;
58
32
  /** Minimum pixel distance that a user must drag a pane handle before dragging triggers. Defaults to 8. */
59
33
  dragActivationDistance?: number;
60
34
  /** Threshold value in pixels for snapping layout resizing handles to adjacent edges. Defaults to 8. */
61
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;
62
46
  /** Callback triggered when dragging starts for a pane. */
63
47
  onDragStart?: (activeId: string) => void;
64
48
  /** Callback triggered when dragging ends, providing details on target pane and drop action (split or swap). */
@@ -73,94 +57,84 @@ interface ZeugmaProps {
73
57
  onResize?: (currentNode: SplitNode, percentage: number) => void;
74
58
  /** Callback triggered when the user stops dragging a resizing handle. Passes the final split percentage. */
75
59
  onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
76
- /** Minimum split percentage allowed when resizing split panes. Defaults to 5. */
77
- minSplitPercentage?: number;
78
- /** Maximum split percentage allowed when resizing split panes. Defaults to 95. */
79
- maxSplitPercentage?: number;
80
- /** Whether dragging a pane far enough outside the container triggers a drag-out/dismiss action. Defaults to false. */
81
- enableDragToDismiss?: boolean;
82
- /** The threshold in pixels beyond the container boundaries required to activate the drag-out/dismiss action. */
83
- dismissThreshold?: number;
84
- /** 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. */
85
61
  onDismissIntentChange?: (paneId: string | null) => void;
86
- /** Whether the layout is locked. When locked, resizing, dragging, and dropping are disabled. */
87
- locked?: boolean;
88
- /** Render function mapping tab IDs to React elements. Used to render tab widgets inside portals. */
89
- renderWidget?: (tabId: string) => ReactNode;
90
- /** Child nodes nested inside the Zeugma context, usually containing a <PaneTree> or similar layout viewer. */
91
- children: ReactNode;
92
62
  }
93
- /**
94
- * State context — holds reactive values that change during runtime.
95
- * All consumers of this context will re-render when any of these values change.
96
- */
97
- interface ZeugmaStateValue {
98
- /** The current active layout tree structure, or null if empty. */
63
+ interface ZeugmaController {
99
64
  layout: TreeNode | null;
100
- /** Callback to update the layout tree. */
101
- onLayoutChange: (newLayout: TreeNode | null, localOnly?: boolean) => void;
102
- /** Renders the inner content of a pane given its unique ID. */
103
- renderPane: (paneId: string) => ReactNode;
104
- /** The ID of the pane currently being dragged, or null. */
65
+ setLayout: Dispatch<SetStateAction<TreeNode | null>>;
66
+ fullscreenPaneId: string | null;
67
+ setFullscreenPaneId: (paneId: string | null) => void;
68
+ locked: boolean;
69
+ setLocked: Dispatch<SetStateAction<boolean>>;
105
70
  activeId: string | null;
106
- /** The ID of the pane currently targeted for dismiss/drag-out, or null. */
71
+ setActiveId: Dispatch<SetStateAction<string | null>>;
72
+ activeType: 'pane' | 'tab' | null;
73
+ setActiveType: Dispatch<SetStateAction<'pane' | 'tab' | null>>;
107
74
  dismissIntentId: string | null;
108
- /** Ref setter to measure and track the dashboard root container element. */
75
+ setDismissIntentId: Dispatch<SetStateAction<string | null>>;
76
+ containerRef: RefObject<HTMLElement | null>;
109
77
  setContainerRef: (element: HTMLElement | null) => void;
110
- /** The ID of the pane currently zoomed to fullscreen, or null. */
111
- fullscreenPaneId: string | null;
112
- /** Normalized or overridden CSS classes for custom layout styling. */
113
- classNames: ZeugmaClassNames;
114
- /** Callback triggered when a pane is closed/removed from the dashboard. */
78
+ dragActivationDistance: number;
79
+ snapThreshold: number;
80
+ minSplitPercentage: number;
81
+ maxSplitPercentage: number;
82
+ enableDragToDismiss: boolean;
83
+ dismissThreshold: number;
115
84
  onRemove?: (paneId: string) => void;
116
- /** Callback triggered to toggle fullscreen status for a pane. */
117
- onFullscreenChange?: (paneId: string | null) => void;
118
- /** Threshold in pixels to snap layout resizers to adjacent edges. */
119
- snapThreshold?: number;
120
- /** Callback triggered when a split pane starts being resized. */
85
+ onDragStart?: (activeId: string) => void;
86
+ onDragEnd?: (activeId: string, overId: string | null, dropAction: {
87
+ type: 'split' | 'swap';
88
+ direction?: SplitDirection;
89
+ position?: 'top' | 'bottom' | 'left' | 'right' | 'center';
90
+ } | null) => void;
121
91
  onResizeStart?: (currentNode: SplitNode) => void;
122
- /** Callback triggered continuously during a split pane resize. */
123
92
  onResize?: (currentNode: SplitNode, percentage: number) => void;
124
- /** Callback triggered when a split pane resize action is completed. */
125
93
  onResizeEnd?: (currentNode: SplitNode, percentage: number) => void;
126
- /** Minimum split percentage allowed when resizing. */
127
- minSplitPercentage?: number;
128
- /** Maximum split percentage allowed when resizing. */
129
- maxSplitPercentage?: number;
130
- /** Whether the layout is globally locked. */
131
- locked: boolean;
132
- }
133
- /**
134
- * Actions context — holds stable dispatch functions with permanent identity.
135
- * Consumers of only this context will never re-render from layout/drag state changes.
136
- */
137
- interface ZeugmaActionsValue {
138
- /** Removes the specified pane from the layout tree and collapses its parent split. */
94
+ onDismissIntentChange?: (paneId: string | null) => void;
139
95
  removePane: (paneId: string) => void;
140
- /** Appends/inserts a pane at the bottom-rightmost leaf of the layout tree. */
141
96
  addPane: (paneId: string) => void;
142
- /** Swaps the positions of two panes in the layout tree. */
143
- swapPanes: (paneIdA: string, paneIdB: string) => void;
144
- /** Splits a target pane with a new pane in the specified direction and side. */
145
97
  splitPane: (targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string) => void;
146
- /** Updates the split percentage of a specific split branch node. */
147
98
  updateSplitPercentage: (currentNode: SplitNode, percentage: number) => void;
148
- /** Stable callback to update metadata for a specific tab. */
149
99
  updateTabMetadata: (tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void;
150
- /** Stable callback to update the locked status of a specific pane in the layout tree. */
151
100
  updatePaneLock: (paneId: string, locked: boolean) => void;
152
- /** Stable callback to activate a tab within a pane. */
153
101
  selectTab: (paneId: string, tabId: string) => void;
154
- /** Stable callback to merge a dragged tab/pane into another pane's tab list. */
155
102
  mergeTab: (draggedTabId: string, targetPaneId: string) => void;
156
- /** Stable callback to move/reorder a tab to another pane next to a target tab. */
157
103
  moveTab: (draggedTabId: string, targetTabId: string, position?: 'before' | 'after') => void;
158
- /** Stable callback to remove/close a specific tab from the layout. */
159
104
  removeTab: (tabId: string) => void;
160
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;
135
+ }
161
136
 
162
- declare const useZeugmaState: () => ZeugmaStateValue;
163
- declare const useZeugmaActions: () => ZeugmaActionsValue;
137
+ declare function useZeugma(options: UseZeugmaOptions): ZeugmaController;
164
138
 
165
139
  declare const Zeugma: React.FC<ZeugmaProps>;
166
140
 
@@ -293,6 +267,7 @@ declare const DEFAULT_SNAP_THRESHOLD = 8;
293
267
  declare const DEFAULT_DRAG_ACTIVATION_DISTANCE = 8;
294
268
  declare const DEFAULT_RESIZER_SIZE = 4;
295
269
 
270
+ declare function generateUniqueId(): string;
296
271
  /**
297
272
  * Tree Helper: Remove a pane container and consolidate the tree structure.
298
273
  */
@@ -305,10 +280,6 @@ declare function removeTab(tree: TreeNode | null, tabId: string): TreeNode | nul
305
280
  * Tree Helper: Insert a pane by splitting an existing target node.
306
281
  */
307
282
  declare function splitPane(tree: TreeNode | null, targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string | PaneNode): TreeNode | null;
308
- /**
309
- * Tree Helper: Swap the position of two panes in the tree structure.
310
- */
311
- declare function swapPanes(tree: TreeNode | null, idA: string, idB: string): TreeNode | null;
312
283
  /**
313
284
  * Tree Helper: Add a pane by recursively splitting the rightmost/bottommost pane in the tree.
314
285
  */
@@ -392,4 +363,4 @@ interface DragSessionConfig {
392
363
  }
393
364
  declare function createDragSession({ cursor, resizerEl, onMove, onEnd }: DragSessionConfig): void;
394
365
 
395
- 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, Zeugma, type ZeugmaActionsValue, type ZeugmaClassNames, type ZeugmaProps, type ZeugmaStateValue, addPane, computeLayout, createDragSession, findPane, mergeTab, moveTab, removePane, removeTab, selectTab, splitPane, swapPanes, updatePaneLock, updateSplitPercentage, updateTabMetadata, useResizer, useZeugmaActions, useZeugmaState };
366
+ export { type ComputedPane, type ComputedSplitter, DEFAULT_DRAG_ACTIVATION_DISTANCE, DEFAULT_RESIZER_SIZE, DEFAULT_SNAP_THRESHOLD, DragHandle, type DragHandleProps, type DragSessionConfig, Pane, type PaneNode, type PaneProps, type PaneRenderProps, PaneTree, ResizableContainer, type ResizableContainerProps, type SplitDirection, type SplitNode, Tab, type TabProps, type TabRenderProps, type TreeNode, type UseZeugmaOptions, Zeugma, type ZeugmaClassNames, type ZeugmaController, type ZeugmaProps, addPane, computeLayout, createDragSession, findPane, generateUniqueId, mergeTab, moveTab, removePane, removeTab, selectTab, splitPane, updatePaneLock, updateSplitPercentage, updateTabMetadata, useResizer, useZeugma };