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/README.md CHANGED
@@ -41,7 +41,7 @@ Import the core components and configure the layout state inside your React appl
41
41
 
42
42
  ```tsx
43
43
  import { useState } from 'react'
44
- import { DashboardProvider, PaneTree, Pane, DragHandle, TreeNode } from 'react-zeugma'
44
+ import { Zeugma, PaneTree, Pane, DragHandle, TreeNode } from 'react-zeugma'
45
45
 
46
46
  const initialLayout: TreeNode = {
47
47
  type: 'split',
@@ -81,11 +81,11 @@ export default function Dashboard() {
81
81
  const [layout, setLayout] = useState<TreeNode | null>(initialLayout)
82
82
 
83
83
  return (
84
- <DashboardProvider layout={layout} onChange={setLayout} renderPane={(id) => <MyPane id={id} />}>
84
+ <Zeugma layout={layout} onChange={setLayout} renderPane={(id) => <MyPane id={id} />}>
85
85
  <div className="w-screen h-screen">
86
86
  <PaneTree />
87
87
  </div>
88
- </DashboardProvider>
88
+ </Zeugma>
89
89
  )
90
90
  }
91
91
  ```
@@ -94,35 +94,35 @@ export default function Dashboard() {
94
94
 
95
95
  ## API Reference
96
96
 
97
- ### `<DashboardProvider>`
97
+ ### `<Zeugma>`
98
98
 
99
99
  The context provider that sets up the drag-and-drop state machine, monitors active drags, and registers layout change notifications.
100
100
 
101
- | Prop | Type | Required | Description |
102
- | ------------------------ | --------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
103
- | `layout` | `TreeNode \| null` | Yes | The serializable tree layout schema. |
104
- | `onChange` | `(layout: TreeNode \| null) => void` | Yes | Fires when resizes, splits, swaps, or removes modify the tree. |
105
- | `renderPane` | `(paneId: string) => ReactNode` | Yes | Renderer function lookup that returns a `<Pane>` structure. |
106
- | `classNames` | `ZeugmaClassNames` | No | Custom classes for overriding pane, resizer, and drop preview overlays. |
107
- | `fullscreenPaneId` | `string \| null` | No | Active ID of the pane taking full viewport coverage. |
108
- | `renderDragOverlay` | `(activeId: string) => ReactNode` | No | Renders a custom cursor-following drag preview overlay. |
109
- | `onFullscreenChange` | `(paneId: string \| null) => void` | No | Callback triggered when a pane enters or leaves fullscreen. |
110
- | `onRemove` | `(paneId: string) => void` | No | Callback triggered when a pane is closed/removed from the layout tree. |
111
- | `dragActivationDistance` | `number` | No | Minimum pointer drag distance (in pixels) required to activate dragging. Defaults to `8`. |
112
- | `enableDragToDismiss` | `boolean` | No | If true, enables the drag-out-to-dismiss gesture where panes can be closed by dragging them outside. Defaults to `false`. |
113
- | `dragOutThreshold` | `number` | No | Distance in pixels outside the container bounds required to trigger drag-out mode. Defaults to `60`. |
114
- | `onDragOutChange` | `(activeId: string \| null) => void` | No | Callback triggered when the drag-out state changes. Receives the pane ID or `null`. |
115
- | `onDragStart` | `(activeId: string) => void` | No | Callback triggered when dragging starts on a pane. |
116
- | `onDragEnd` | `(activeId: string, overId: string \| null, dropAction: any) => void` | No | Callback triggered when dragging ends, providing swap or split details. The `overId` is set to `'root'` if dropped onto outer boundaries to split the entire dashboard root. |
117
- | `onResizeStart` | `(currentNode: SplitNode) => void` | No | Callback triggered when resizing starts on a split node. |
118
- | `onResize` | `(currentNode: SplitNode, percentage: number) => void` | No | Callback triggered continuously while resizing a split node. |
119
- | `onResizeEnd` | `(currentNode: SplitNode, percentage: number) => void` | No | Callback triggered when resizing ends on a split node. |
120
- | `minSplitPercentage` | `number` | No | Minimum resizing limit percentage. Defaults to `5`. |
121
- | `maxSplitPercentage` | `number` | No | Maximum resizing limit percentage. Defaults to `95`. |
101
+ | Prop | Type | Required | Description |
102
+ | ------------------------ | --------------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
103
+ | `layout` | `TreeNode \| null` | Yes | The serializable tree layout schema. |
104
+ | `onChange` | `(layout: TreeNode \| null) => void` | Yes | Fires when resizes, splits, swaps, or removes modify the tree. |
105
+ | `renderPane` | `(paneId: string) => ReactNode` | Yes | Renderer function lookup that returns a `<Pane>` structure. |
106
+ | `classNames` | `ZeugmaClassNames` | No | Custom classes for overriding pane, resizer, and drop preview overlays. |
107
+ | `fullscreenPaneId` | `string \| null` | No | Active ID of the pane taking full viewport coverage. |
108
+ | `renderDragOverlay` | `(activeId: string) => ReactNode` | No | Renders a custom cursor-following drag preview overlay. |
109
+ | `onFullscreenChange` | `(paneId: string \| null) => void` | No | Callback triggered when a pane enters or leaves fullscreen. |
110
+ | `onRemove` | `(paneId: string) => void` | No | Callback triggered when a pane is closed/removed from the layout tree. |
111
+ | `dragActivationDistance` | `number` | No | Minimum pointer drag distance (in pixels) required to activate dragging. Defaults to `8`. |
112
+ | `enableDragToDismiss` | `boolean` | No | If true, enables the drag-out-to-dismiss gesture where panes can be closed by dragging them outside. Defaults to `false`. |
113
+ | `dragOutThreshold` | `number` | No | Distance in pixels outside the container bounds required to trigger drag-out mode. Defaults to `60`. |
114
+ | `onDragOutChange` | `(activeId: string \| null) => void` | No | Callback triggered when the drag-out state changes. Receives the pane ID or `null`. |
115
+ | `onDragStart` | `(activeId: string) => void` | No | Callback triggered when dragging starts on a pane. |
116
+ | `onDragEnd` | `(activeId: string, overId: string \| null, dropAction: any) => void` | No | Callback triggered when dragging ends, providing swap or split details. |
117
+ | `onResizeStart` | `(currentNode: SplitNode) => void` | No | Callback triggered when resizing starts on a split node. |
118
+ | `onResize` | `(currentNode: SplitNode, percentage: number) => void` | No | Callback triggered continuously while resizing a split node. |
119
+ | `onResizeEnd` | `(currentNode: SplitNode, percentage: number) => void` | No | Callback triggered when resizing ends on a split node. |
120
+ | `minSplitPercentage` | `number` | No | Minimum resizing limit percentage. Defaults to `5`. |
121
+ | `maxSplitPercentage` | `number` | No | Maximum resizing limit percentage. Defaults to `95`. |
122
122
 
123
123
  ### `<PaneTree>`
124
124
 
125
- Recursively renders the split nodes and pane nodes. Must be placed inside `<DashboardProvider>`.
125
+ Recursively renders the split nodes and pane nodes. Must be placed inside `<Zeugma>`.
126
126
 
127
127
  | Prop | Type | Required | Description |
128
128
  | ------------- | ------------------ | -------- | ------------------------------------------------------------------- |
@@ -195,10 +195,6 @@ Swaps the positions of `idA` and `idB` nodes directly inside the tree structure.
195
195
 
196
196
  Splits the targeted `targetId` pane inside the tree with `direction` (_row_ / _column_) and type (_left_, _right_, _top_, _bottom_) to insert `paneToAdd`.
197
197
 
198
- #### `splitRoot(tree, draggingId, splitType)`
199
-
200
- Splits the entire dashboard tree at the root, placing the dragged `draggingId` pane on one half and the rest of the layout tree on the other.
201
-
202
198
  #### `findPane(tree: TreeNode | null, paneId: string): PaneNode | null`
203
199
 
204
200
  Recursively searches the layout tree and returns the target `PaneNode` if found, or `null` otherwise.
@@ -210,7 +206,7 @@ Recursively searches the layout tree and returns the target `PaneNode` if found,
210
206
  Use custom CSS or styling rules to style resizers, dragging states, drop previews, or active nodes by overriding `classNames` in the provider.
211
207
 
212
208
  ```tsx
213
- <DashboardProvider
209
+ <Zeugma
214
210
  layout={layout}
215
211
  onChange={setLayout}
216
212
  renderPane={renderPane}
@@ -225,7 +221,7 @@ Use custom CSS or styling rules to style resizers, dragging states, drop preview
225
221
  }}
226
222
  >
227
223
  <PaneTree />
228
- </DashboardProvider>
224
+ </Zeugma>
229
225
  ```
230
226
 
231
227
  ---
@@ -273,12 +269,12 @@ export interface PaneRenderProps {
273
269
  ) => void
274
270
  }
275
271
 
276
- export interface DashboardStateValue {
272
+ export interface ZeugmaStateValue {
277
273
  layout: TreeNode | null
278
274
  onLayoutChange: (newLayout: TreeNode | null) => void
279
275
  renderPane: (paneId: string) => ReactNode
280
276
  activeId: string | null
281
- draggedOutId: string | null
277
+ dismissIntentId: string | null
282
278
  setContainerRef: (element: HTMLElement | null) => void
283
279
  fullscreenPaneId: string | null
284
280
  classNames: ZeugmaClassNames
@@ -292,7 +288,7 @@ export interface DashboardStateValue {
292
288
  maxSplitPercentage?: number
293
289
  }
294
290
 
295
- export interface DashboardActionsValue {
291
+ export interface ZeugmaActionsValue {
296
292
  removePane: (paneId: string) => void
297
293
  addPane: (paneId: string) => void
298
294
  swapPanes: (paneIdA: string, paneIdB: string) => void
@@ -361,7 +357,7 @@ export type TreeNode = SplitNode | PaneNode
361
357
 
362
358
  ## 2. Core Components
363
359
 
364
- ### `<DashboardProvider>`
360
+ ### `<Zeugma>`
365
361
 
366
362
  The root context provider. It handles the drag-and-drop event loop and coordinates the layout state.
367
363
 
@@ -380,7 +376,7 @@ The root context provider. It handles the drag-and-drop event loop and coordinat
380
376
  - `dragOutThreshold?: number` — (Optional) Distance in pixels outside the container boundaries required to activate drag-out mode. Defaults to `60`.
381
377
  - `onDragOutChange?: (activeId: string | null) => void` — (Optional) Callback triggered when the drag-out state changes.
382
378
  - `onDragStart?: (activeId: string) => void` — (Optional) Callback triggered when dragging starts on a pane.
383
- - `onDragEnd?: (activeId: string, overId: string | null, dropAction: any) => void` — (Optional) Callback triggered when dragging ends. The `overId` will be `'root'` if the pane was dropped onto the outer dashboard boundaries to split the root layout.
379
+ - `onDragEnd?: (activeId: string, overId: string | null, dropAction: any) => void` — (Optional) Callback triggered when dragging ends, providing swap or split details.
384
380
  - `onResizeStart?: (currentNode: SplitNode) => void` — (Optional) Callback triggered when resizing starts.
385
381
  - `onResize?: (currentNode: SplitNode, percentage: number) => void` — (Optional) Callback triggered during resizing.
386
382
  - `onResizeEnd?: (currentNode: SplitNode, percentage: number) => void` — (Optional) Callback triggered when resizing ends.
@@ -389,7 +385,7 @@ The root context provider. It handles the drag-and-drop event loop and coordinat
389
385
 
390
386
  ### `<PaneTree>`
391
387
 
392
- Recursively renders the split nodes and pane nodes. Must be placed inside `<DashboardProvider>`.
388
+ Recursively renders the split nodes and pane nodes. Must be placed inside `<Zeugma>`.
393
389
 
394
390
  #### Props
395
391
 
@@ -456,8 +452,6 @@ Import these helpers from `react-zeugma` to manipulate the tree layout programma
456
452
  Removes a pane from the tree and collapses the leftover sibling split node.
457
453
  - **`splitPane(tree: TreeNode | null, targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string): TreeNode | null`**
458
454
  Splits a specific target pane by nesting it under a new `SplitNode` along with a new pane.
459
- - **`splitRoot(tree: TreeNode | null, draggingId: string, splitType: 'left' | 'right' | 'top' | 'bottom'): TreeNode | null`**
460
- Splits the entire dashboard tree at the root, placing the dragged pane on one half and the remaining layout tree on the other.
461
455
  - **`swapPanes(tree: TreeNode | null, idA: string, idB: string): TreeNode | null`**
462
456
  Swaps the positions of two panes in the tree.
463
457
  - **`updatePaneMetadata(tree: TreeNode | null, paneId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined): TreeNode | null`**
@@ -467,10 +461,10 @@ Import these helpers from `react-zeugma` to manipulate the tree layout programma
467
461
 
468
462
  Alternatively, you can consume state and mutation helpers directly from the context hooks:
469
463
 
470
- - **`useDashboardState()`**: Returns the reactive state values (e.g., `layout`, `activeId`, `classNames`). Consumers of this hook will re-render whenever layout state updates.
471
- - **`useDashboardActions()`**: Returns the stable layout mutation actions (e.g., `removePane`, `splitPane`). Because these actions have a permanent identity, consumers of this hook **will not** re-render when layout state changes, providing a significant performance optimization.
464
+ - **`useZeugmaState()`**: Returns the reactive state values (e.g., `layout`, `activeId`, `classNames`). Consumers of this hook will re-render whenever layout state updates.
465
+ - **`useZeugmaActions()`**: Returns the stable layout mutation actions (e.g., `removePane`, `splitPane`). Because these actions have a permanent identity, consumers of this hook **will not** re-render when layout state changes, providing a significant performance optimization.
472
466
 
473
- The actions returned by `useDashboardActions()` are:
467
+ The actions returned by `useZeugmaActions()` are:
474
468
 
475
469
  - **`removePane(paneId: string) => void`**
476
470
  - **`addPane(paneId: string) => void`**
@@ -485,7 +479,7 @@ The actions returned by `useDashboardActions()` are:
485
479
 
486
480
  ```tsx
487
481
  import { useState } from 'react'
488
- import { DashboardProvider, PaneTree, Pane, DragHandle, TreeNode } from 'react-zeugma'
482
+ import { Zeugma, PaneTree, Pane, DragHandle, TreeNode } from 'react-zeugma'
489
483
 
490
484
  const initialLayout: TreeNode = {
491
485
  type: 'split',
@@ -526,7 +520,7 @@ export default function App() {
526
520
  }
527
521
 
528
522
  return (
529
- <DashboardProvider
523
+ <Zeugma
530
524
  layout={layout}
531
525
  onChange={setLayout}
532
526
  renderPane={(id) => <CustomPane id={id} />}
@@ -537,7 +531,7 @@ export default function App() {
537
531
  <div style={{ width: '100vw', height: '100vh' }}>
538
532
  <PaneTree />
539
533
  </div>
540
- </DashboardProvider>
534
+ </Zeugma>
541
535
  )
542
536
  }
543
537
  ```
@@ -546,7 +540,7 @@ export default function App() {
546
540
 
547
541
  ## 5. Styling Customization
548
542
 
549
- `react-zeugma` is style-agnostic and relies on class name configuration for visual states. Define classes in your styling framework and pass them via the `classNames` prop on `<DashboardProvider>`:
543
+ `react-zeugma` is style-agnostic and relies on class name configuration for visual states. Define classes in your styling framework and pass them via the `classNames` prop on `<Zeugma>`:
550
544
 
551
545
  ```ts
552
546
  interface ZeugmaClassNames {
package/dist/index.cjs CHANGED
@@ -1,7 +1,7 @@
1
- 'use strict';var react=require('react'),core=require('@dnd-kit/core'),jsxRuntime=require('react/jsx-runtime');var se=react.createContext(void 0),ae=react.createContext(void 0);var G=()=>{let e=react.useContext(se);if(!e)throw new Error("useDashboardState must be used within a DashboardProvider");return e},be=()=>{let e=react.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=react.useRef(null);return react.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)},[]),jsxRuntime.jsx("div",{ref:r,className:n,style:{position:"fixed",top:0,left:0,zIndex:9999,pointerEvents:"none"},children:t(e)})},Re=class extends core.PointerSensor{static activators=[{eventName:"onPointerDown",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]},De=class extends core.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]=react.useState(e),[ee,te]=react.useState(e);e!==ee&&(te(e),m(e));let[b,T]=react.useState(null),[v,M]=react.useState(null),B=react.useRef(null),Z=react.useRef(null),h=react.useCallback(l=>{B.current=l;},[]),C=react.useCallback(l=>n(l),[n]),F=react.useMemo(()=>o,[o.pane,o.dropPreview,o.swapPreview,o.dragOverlay,o.resizer,o.dismissPreview]),_=core.useSensors(core.useSensor(Re,{activationConstraint:{distance:D}}),core.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=react.useCallback(l=>{m(l),t(l);},[t]),he=react.useCallback(l=>{let f=Y(u,l);m(f),t(f);},[u,t]),ze=react.useCallback(l=>{let f=Ze(u,l);m(f),t(f);},[u,t]),Te=react.useCallback((l,f)=>{let a=Pe(u,l,f);m(a),t(a);},[u,t]),Ce=react.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=react.useCallback((l,f)=>{let a=Q(u,l,f);m(a),t(a);},[u,t]),Me=react.useCallback((l,f)=>{let a=le(u,l,f);m(a),t(a);},[u,t]),Ae=react.useCallback((l,f)=>{let a=Q(u,l,f);m(a),t(a),N&&N(l,f);},[u,t,N]),Ke=react.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=react.useMemo(()=>({removePane:he,addPane:ze,swapPanes:Te,splitPane:Ce,updateSplitPercentage:Le,updatePaneMetadata:Me}),[he,ze,Te,Ce,Le,Me]);return jsxRuntime.jsx(ae.Provider,{value:Je,children:jsxRuntime.jsxs(se.Provider,{value:Ke,children:[jsxRuntime.jsx(core.DndContext,{id:"zeugma-dnd-context",sensors:_,collisionDetection:core.pointerWithin,onDragStart:X,onDragMove:K,onDragEnd:ne,children:z}),b&&r&&jsxRuntime.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}=core.useDroppable({id:e});return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{ref:r,style:ut[t]}),o&&jsxRuntime.jsx("div",{className:n,style:pt[t]})]})},Ve=({activeId:e,hasOtherPanes:t,dropPreviewClassName:n})=>!e||!t?null:jsxRuntime.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:30,pointerEvents:"none"},children:["top","bottom","left","right"].map(r=>jsxRuntime.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
+ 'use strict';var react=require('react'),core=require('@dnd-kit/core'),jsxRuntime=require('react/jsx-runtime');var re=react.createContext(void 0),ie=react.createContext(void 0);var B=()=>{let e=react.useContext(re);if(!e)throw new Error("useZeugmaState must be used within a Zeugma provider");return e},he=()=>{let e=react.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=react.useRef(null);return react.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)},[]),jsxRuntime.jsx("div",{ref:r,className:n,style:{position:"fixed",top:0,left:0,zIndex:9999,pointerEvents:"none"},children:t(e)})};var ae=class extends core.PointerSensor{static activators=[{eventName:"onPointerDown",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]},le=class extends core.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]=react.useState(e),[j,ee]=react.useState(e);e!==j&&(ee(e),m(e));let[h,T]=react.useState(null),[v,C]=react.useState(null),O=react.useRef(null),F=react.useRef(null),g=react.useCallback(l=>{O.current=l;},[]),I=react.useCallback(l=>n(l),[n]),Z=react.useMemo(()=>o,[o.pane,o.dropPreview,o.swapPreview,o.dragOverlay,o.resizer,o.dismissPreview]),_=core.useSensors(core.useSensor(ae,{activationConstraint:{distance:y}}),core.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=react.useCallback(l=>{m(l),t(l);},[t]),me=react.useCallback(l=>{let f=Q(c,l);m(f),t(f);},[c,t]),Ne=react.useCallback(l=>{let f=He(c,l);m(f),t(f);},[c,t]),ze=react.useCallback((l,f)=>{let a=be(c,l,f);m(a),t(a);},[c,t]),De=react.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=react.useCallback((l,f)=>{let a=G(c,l,f);m(a),t(a);},[c,t]),Ie=react.useCallback((l,f)=>{let a=se(c,l,f);m(a),t(a);},[c,t]),Le=react.useCallback((l,f)=>{let a=G(c,l,f);m(a),t(a),L&&L(l,f);},[c,t,L]),qe=react.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=react.useMemo(()=>({removePane:me,addPane:Ne,swapPanes:ze,splitPane:De,updateSplitPercentage:Te,updatePaneMetadata:Ie}),[me,Ne,ze,De,Te,Ie]);return jsxRuntime.jsx(ie.Provider,{value:We,children:jsxRuntime.jsxs(re.Provider,{value:qe,children:[jsxRuntime.jsx(core.DndContext,{id:"zeugma-dnd-context",sensors:_,collisionDetection:core.pointerWithin,onDragStart:X,onDragMove:q,onDragEnd:te,children:D}),h&&r&&jsxRuntime.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 react.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]=react.useState(false),D=react.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 jsxRuntime.jsxs("div",{ref:D,style:{display:"flex",flexDirection:g?"row":"column",width:"100%",height:"100%",overflow:"hidden"},children:[jsxRuntime.jsx("div",{style:{flex:`${x} 1 0%`,overflow:"hidden"},children:jsxRuntime.jsx(we,{tree:y,resizerSize:t,snapThreshold:n})}),jsxRuntime.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}),jsxRuntime.jsx("div",{style:{flex:`${100-x} 1 0%`,overflow:"hidden"},children:jsxRuntime.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=react.useMemo(()=>e!==void 0||!i?false:Y(r,i)!==null,[e,r,i]);if(P&&!e)return jsxRuntime.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"?jsxRuntime.jsx("div",{style:{width:"100%",height:"100%",position:"relative"},children:o(g.paneId)}):jsxRuntime.jsx(xt,{currentNode:g,resizerSize:t,snapThreshold:s});return e===void 0?jsxRuntime.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(),jsxRuntime.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]=react.useState(x),E=react.useRef(null),I=s?g:n??g,S=react.useRef(n);react.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=react.useCallback(()=>i,[i]),H=react.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?jsxRuntime.jsxs("div",{ref:E,className:`zeugma-resizable-container ${P||""}`.trim(),style:{height:`${I}px`,position:"relative",overflow:"hidden",boxSizing:"border-box"},children:[jsxRuntime.jsx("div",{style:{height:`calc(100% - ${D}px)`,overflow:"hidden"},children:e}),jsxRuntime.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})]}):jsxRuntime.jsx("div",{className:`zeugma-resizable-container disabled ${P||""}`.trim(),style:{height:"100%",position:"relative",overflow:"hidden",boxSizing:"border-box"},children:jsxRuntime.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=react.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}=core.useDroppable({id:e});return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{ref:r,style:zt[t]}),o&&jsxRuntime.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}=core.useDraggable({id:e}),I=o===e||E,S=d===e,H=react.useMemo(()=>O(r,e),[r,e])?.metadata,z=react.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=react.useMemo(()=>({...g,...x}),[g,x]);return jsxRuntime.jsx(ge.Provider,{value:u,children:jsxRuntime.jsxs("div",{ref:N,className:i.pane,style:{position:"relative",width:"100%",height:"100%",...n},children:[t(z),s&&jsxRuntime.jsxs("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:[["top","bottom","left","right"].map(m=>jsxRuntime.jsx(Ge,{id:`drop-${m}-${e}`,position:m,activeClassName:i.dropPreview},m)),jsxRuntime.jsx(Ge,{id:`drop-center-${e}`,position:"center",activeClassName:i.swapPreview})]})]})})};var At=({children:e,className:t,style:n})=>{let r=react.useContext(ge);if(!r)throw new Error("<DragHandle> must be used inside a <Pane>");return jsxRuntime.jsx("div",{className:t,style:{cursor:"grab",userSelect:"none",touchAction:"none",...n},...r,children:e})};exports.DEFAULT_DRAG_ACTIVATION_DISTANCE=et;exports.DEFAULT_RESIZER_SIZE=Xt;exports.DEFAULT_SNAP_THRESHOLD=je;exports.DashboardProvider=lt;exports.DragHandle=At;exports.Pane=Ct;exports.PaneTree=we;exports.ResizableContainer=qe;exports.addPane=Ze;exports.createDragSession=pe;exports.findPane=O;exports.removePane=Y;exports.splitPane=re;exports.splitRoot=_e;exports.swapPanes=Pe;exports.updatePaneMetadata=le;exports.updateSplitPercentage=Q;exports.useDashboardActions=be;exports.useDashboardState=G;exports.useResizer=Ne;//# sourceMappingURL=index.cjs.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 react.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]=react.useState(false),y=react.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 jsxRuntime.jsxs("div",{ref:y,style:{display:"flex",flexDirection:P?"row":"column",width:"100%",height:"100%",overflow:"hidden"},children:[jsxRuntime.jsx("div",{style:{flex:`${b} 1 0%`,overflow:"hidden"},children:jsxRuntime.jsx(ye,{tree:E,resizerSize:t,snapThreshold:n})}),jsxRuntime.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}),jsxRuntime.jsx("div",{style:{flex:`${100-b} 1 0%`,overflow:"hidden"},children:jsxRuntime.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 jsxRuntime.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"?jsxRuntime.jsx("div",{style:{width:"100%",height:"100%",position:"relative"},children:o(s.paneId)}):jsxRuntime.jsx(ut,{currentNode:s,resizerSize:t,snapThreshold:E});return e===void 0?jsxRuntime.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]=react.useState(b),z=react.useRef(null),N=s?P:n??P,w=react.useRef(n);react.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=react.useCallback(()=>i,[i]),H=react.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?jsxRuntime.jsxs("div",{ref:z,className:`zeugma-resizable-container ${S||""}`.trim(),style:{height:`${N}px`,position:"relative",overflow:"hidden",boxSizing:"border-box"},children:[jsxRuntime.jsx("div",{style:{height:`calc(100% - ${y}px)`,overflow:"hidden"},children:e}),jsxRuntime.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})]}):jsxRuntime.jsx("div",{className:`zeugma-resizable-container disabled ${S||""}`.trim(),style:{height:"100%",position:"relative",overflow:"hidden",boxSizing:"border-box"},children:jsxRuntime.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=react.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}=core.useDroppable({id:e});return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{ref:r,style:xt[t]}),o&&jsxRuntime.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}=core.useDraggable({id:e}),N=o===e||z,w=u===e,H=react.useMemo(()=>k(r,e),[r,e])?.metadata,D=react.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=react.useMemo(()=>({...P,...b}),[P,b]);return jsxRuntime.jsx(fe.Provider,{value:c,children:jsxRuntime.jsxs("div",{ref:L,className:i.pane,style:{position:"relative",width:"100%",height:"100%",...n},children:[t(D),s&&jsxRuntime.jsxs("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:[["top","bottom","left","right"].map(m=>jsxRuntime.jsx(Be,{id:`drop-${m}-${e}`,position:m,activeClassName:i.dropPreview},m)),jsxRuntime.jsx(Be,{id:`drop-center-${e}`,position:"center",activeClassName:i.swapPreview})]})]})})};var Et=({children:e,className:t,style:n})=>{let r=react.useContext(fe);if(!r)throw new Error("<DragHandle> must be used inside a <Pane>");return jsxRuntime.jsx("div",{className:t,style:{cursor:"grab",userSelect:"none",touchAction:"none",...n},...r,children:e})};exports.DEFAULT_DRAG_ACTIVATION_DISTANCE=Ke;exports.DEFAULT_RESIZER_SIZE=Mt;exports.DEFAULT_SNAP_THRESHOLD=Ge;exports.DragHandle=Et;exports.Pane=yt;exports.PaneTree=ye;exports.ResizableContainer=Oe;exports.Zeugma=it;exports.addPane=He;exports.createDragSession=ue;exports.findPane=k;exports.removePane=Q;exports.splitPane=ne;exports.swapPanes=be;exports.updatePaneMetadata=se;exports.updateSplitPercentage=G;exports.useResizer=Se;exports.useZeugmaActions=he;exports.useZeugmaState=B;//# sourceMappingURL=index.cjs.map
7
7
  //# sourceMappingURL=index.cjs.map