react-zeugma 2.3.0 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +91 -168
- package/dist/index.cjs +2 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +166 -110
- package/dist/index.d.ts +166 -110
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -12
package/README.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
### Core Features
|
|
16
16
|
|
|
17
17
|
- **Recursive Split Trees**: Nest rows and columns to any depth using a simple serialized JSON node structure.
|
|
18
|
-
- **
|
|
18
|
+
- **4-Zone Docking Previews**: Drag panels on the top, bottom, left, or right edges of another pane to split it.
|
|
19
19
|
- **Native Flexbox Resizers**: Fluid, non-blocking split handles built on pointer events.
|
|
20
20
|
- **Accessible Drag-and-Drop**: Built on top of the performant and accessible [`@dnd-kit`](https://dndkit.com) toolkit.
|
|
21
21
|
- **Fullscreen Zoom Toggle**: Programmatically expand any pane to cover the entire viewport and snap it back instantly.
|
|
@@ -37,23 +37,22 @@ npm install react-zeugma
|
|
|
37
37
|
|
|
38
38
|
## Quick Start
|
|
39
39
|
|
|
40
|
-
Import the core components and configure the layout state inside your React application.
|
|
40
|
+
Import the core components and configure the layout state inside your React application using the `useZeugma` hook.
|
|
41
41
|
|
|
42
42
|
```tsx
|
|
43
|
-
import {
|
|
44
|
-
import { Zeugma, PaneTree, Pane, DragHandle, TreeNode } from 'react-zeugma'
|
|
43
|
+
import { useZeugma, Zeugma, PaneTree, Pane, DragHandle, TreeNode } from 'react-zeugma'
|
|
45
44
|
|
|
46
45
|
const initialLayout: TreeNode = {
|
|
47
46
|
type: 'split',
|
|
48
47
|
direction: 'row',
|
|
49
48
|
splitPercentage: 20,
|
|
50
|
-
first: { type: 'pane',
|
|
49
|
+
first: { type: 'pane', id: 'explorer', tabs: ['explorer'], activeTabId: 'explorer' },
|
|
51
50
|
second: {
|
|
52
51
|
type: 'split',
|
|
53
52
|
direction: 'row',
|
|
54
53
|
splitPercentage: 50,
|
|
55
|
-
first: { type: 'pane',
|
|
56
|
-
second: { type: 'pane',
|
|
54
|
+
first: { type: 'pane', id: 'editor', tabs: ['editor'], activeTabId: 'editor' },
|
|
55
|
+
second: { type: 'pane', id: 'preview', tabs: ['preview'], activeTabId: 'preview' },
|
|
57
56
|
},
|
|
58
57
|
}
|
|
59
58
|
|
|
@@ -78,10 +77,10 @@ function MyPane({ id }: { id: string }) {
|
|
|
78
77
|
}
|
|
79
78
|
|
|
80
79
|
export default function Dashboard() {
|
|
81
|
-
const
|
|
80
|
+
const zeugma = useZeugma({ initialLayout })
|
|
82
81
|
|
|
83
82
|
return (
|
|
84
|
-
<Zeugma
|
|
83
|
+
<Zeugma {...zeugma} renderPane={(id) => <MyPane id={id} />}>
|
|
85
84
|
<div className="w-screen h-screen">
|
|
86
85
|
<PaneTree />
|
|
87
86
|
</div>
|
|
@@ -96,29 +95,37 @@ export default function Dashboard() {
|
|
|
96
95
|
|
|
97
96
|
### `<Zeugma>`
|
|
98
97
|
|
|
99
|
-
The context provider that sets up the drag-and-drop state machine, monitors active drags, and registers layout change notifications.
|
|
100
|
-
|
|
101
|
-
| Prop
|
|
102
|
-
|
|
|
103
|
-
| `
|
|
104
|
-
| `
|
|
105
|
-
| `
|
|
106
|
-
| `
|
|
107
|
-
| `
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
|
114
|
-
|
|
|
115
|
-
| `
|
|
116
|
-
| `
|
|
117
|
-
| `
|
|
118
|
-
| `
|
|
119
|
-
| `
|
|
120
|
-
| `
|
|
121
|
-
| `
|
|
98
|
+
The context provider that sets up the drag-and-drop state machine, monitors active drags, and registers layout change notifications. It extends `ZeugmaController` directly; you typically spread the controller object returned by `useZeugma` onto it.
|
|
99
|
+
|
|
100
|
+
| Prop | Type | Required | Description |
|
|
101
|
+
| -------------------- | -------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------- |
|
|
102
|
+
| `...controllerProps` | `ZeugmaController` | Yes | All properties returned by `useZeugma(options)`. Usually passed by spreading the controller object (e.g., `{...zeugma}`). |
|
|
103
|
+
| `renderPane` | `(paneId: string) => ReactNode` | Yes | Renderer function lookup that returns a `<Pane>` structure. |
|
|
104
|
+
| `classNames` | `ZeugmaClassNames` | No | Custom classes for overriding pane, resizer, and drop preview overlays. |
|
|
105
|
+
| `renderDragOverlay` | `(activeId: string, type: 'pane' \| 'tab') => ReactNode` | No | Renders a custom cursor-following drag preview overlay. |
|
|
106
|
+
| `renderWidget` | `(tabId: string) => ReactNode` | No | Render function mapping tab IDs to React elements. Used to render tab widgets inside portals. |
|
|
107
|
+
|
|
108
|
+
### `useZeugma(options)`
|
|
109
|
+
|
|
110
|
+
A custom state hook that initializes and manages the recursive layout tree and handles drag-and-drop actions.
|
|
111
|
+
|
|
112
|
+
| Option | Type | Default | Description |
|
|
113
|
+
| ------------------------ | --------------------------------------------------------------------- | ------- | -------------------------------------------------------------------------- |
|
|
114
|
+
| `initialLayout` | `TreeNode \| null` | Yes | Initial layout tree structure. |
|
|
115
|
+
| `locked` | `boolean` | `false` | If true, layout resizes and drags are disabled. |
|
|
116
|
+
| `dragActivationDistance` | `number` | `8` | Minimum pointer drag distance (in pixels) required to activate dragging. |
|
|
117
|
+
| `snapThreshold` | `number` | `8` | Threshold in pixels to snap layout resizers to adjacent edges. |
|
|
118
|
+
| `minSplitPercentage` | `number` | `5` | Minimum resizing limit percentage. |
|
|
119
|
+
| `maxSplitPercentage` | `number` | `95` | Maximum resizing limit percentage. |
|
|
120
|
+
| `enableDragToDismiss` | `boolean` | `false` | If true, enables the drag-out-to-dismiss gesture to close widgets. |
|
|
121
|
+
| `dismissThreshold` | `number` | `60` | Distance in pixels outside container bounds required to trigger dismissal. |
|
|
122
|
+
| `onRemove` | `(paneId: string) => void` | — | Callback triggered when a pane is removed. |
|
|
123
|
+
| `onDragStart` | `(activeId: string) => void` | — | Callback triggered when dragging starts. |
|
|
124
|
+
| `onDragEnd` | `(activeId: string, overId: string \| null, dropAction: any) => void` | — | Callback triggered when dragging ends. |
|
|
125
|
+
| `onResizeStart` | `(currentNode: SplitNode) => void` | — | Callback triggered when resizing starts. |
|
|
126
|
+
| `onResize` | `(currentNode: SplitNode, percentage: number) => void` | — | Callback triggered during resizing. |
|
|
127
|
+
| `onResizeEnd` | `(currentNode: SplitNode, percentage: number) => void` | — | Callback triggered when resizing ends. |
|
|
128
|
+
| `onDismissIntentChange` | `(paneId: string \| null) => void` | — | Callback triggered when drag-out intent changes. |
|
|
122
129
|
|
|
123
130
|
### `<PaneTree>`
|
|
124
131
|
|
|
@@ -140,12 +147,13 @@ Wraps the individual pane components inside the renderer. Utilizes a render prop
|
|
|
140
147
|
|
|
141
148
|
#### Render Props: `PaneRenderProps`
|
|
142
149
|
|
|
143
|
-
| Parameter | Type
|
|
144
|
-
| ------------------ |
|
|
145
|
-
| `isDragging` | `boolean`
|
|
146
|
-
| `isFullscreen` | `boolean`
|
|
147
|
-
| `toggleFullscreen` | `() => void`
|
|
148
|
-
| `remove` | `() => void`
|
|
150
|
+
| Parameter | Type | Description |
|
|
151
|
+
| ------------------ | ----------------- | -------------------------------------------------------------------------------- |
|
|
152
|
+
| `isDragging` | `boolean` | Returns `true` if the node wrapper is actively being dragged. |
|
|
153
|
+
| `isFullscreen` | `boolean` | Returns `true` if the pane is zoomed/fullscreen. |
|
|
154
|
+
| `toggleFullscreen` | `() => void` | Callback to toggle fullscreen viewport coverage. |
|
|
155
|
+
| `remove` | `() => void` | Triggers removal of this pane from the layout tree. |
|
|
156
|
+
| `renderActiveTab` | `() => ReactNode` | Renders the target placeholder element for the currently active tab in the pane. |
|
|
149
157
|
|
|
150
158
|
### `<DragHandle>`
|
|
151
159
|
|
|
@@ -187,10 +195,6 @@ Recursively scans the layout tree, removes the targeted pane node, and collapses
|
|
|
187
195
|
|
|
188
196
|
Recursively matches the bottommost/rightmost pane leaf in the tree, splits it, and inserts the target `paneToAdd`.
|
|
189
197
|
|
|
190
|
-
#### `swapPanes(tree: TreeNode | null, idA: string, idB: string): TreeNode | null`
|
|
191
|
-
|
|
192
|
-
Swaps the positions of `idA` and `idB` nodes directly inside the tree structure.
|
|
193
|
-
|
|
194
198
|
#### `splitPane(tree, targetId, direction, splitType, paneToAdd)`
|
|
195
199
|
|
|
196
200
|
Splits the targeted `targetId` pane inside the tree with `direction` (_row_ / _column_) and type (_left_, _right_, _top_, _bottom_) to insert `paneToAdd`.
|
|
@@ -207,17 +211,13 @@ Use custom CSS or styling rules to style resizers, dragging states, drop preview
|
|
|
207
211
|
|
|
208
212
|
```tsx
|
|
209
213
|
<Zeugma
|
|
210
|
-
|
|
211
|
-
onChange={setLayout}
|
|
212
|
-
renderPane={renderPane}
|
|
214
|
+
{...zeugma}
|
|
213
215
|
classNames={{
|
|
214
216
|
// resizer handles
|
|
215
217
|
resizer:
|
|
216
218
|
'bg-transparent hover:bg-indigo-500/50 active:bg-indigo-500 transition-colors duration-150',
|
|
217
219
|
// split previews
|
|
218
220
|
dropPreview: 'bg-indigo-500/10 border-2 border-dashed border-indigo-500/50 backdrop-blur-xs',
|
|
219
|
-
// swap previews
|
|
220
|
-
swapPreview: 'bg-amber-500/10 border-2 border-dashed border-amber-500/50 backdrop-blur-xs',
|
|
221
221
|
}}
|
|
222
222
|
>
|
|
223
223
|
<PaneTree />
|
|
@@ -248,62 +248,6 @@ export interface PaneNode {
|
|
|
248
248
|
}
|
|
249
249
|
|
|
250
250
|
export type TreeNode = SplitNode | PaneNode
|
|
251
|
-
|
|
252
|
-
export interface ZeugmaClassNames {
|
|
253
|
-
pane?: string
|
|
254
|
-
dropPreview?: string
|
|
255
|
-
swapPreview?: string
|
|
256
|
-
dragOverlay?: string
|
|
257
|
-
resizer?: string
|
|
258
|
-
dragOut?: string
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
export interface PaneRenderProps {
|
|
262
|
-
isDragging: boolean
|
|
263
|
-
isFullscreen: boolean
|
|
264
|
-
toggleFullscreen: () => void
|
|
265
|
-
remove: () => void
|
|
266
|
-
metadata: Record<string, unknown> | undefined
|
|
267
|
-
updateMetadata: (
|
|
268
|
-
updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined,
|
|
269
|
-
) => void
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
export interface ZeugmaStateValue {
|
|
273
|
-
layout: TreeNode | null
|
|
274
|
-
onLayoutChange: (newLayout: TreeNode | null) => void
|
|
275
|
-
renderPane: (paneId: string) => ReactNode
|
|
276
|
-
activeId: string | null
|
|
277
|
-
dismissIntentId: string | null
|
|
278
|
-
setContainerRef: (element: HTMLElement | null) => void
|
|
279
|
-
fullscreenPaneId: string | null
|
|
280
|
-
classNames: ZeugmaClassNames
|
|
281
|
-
onRemove?: (paneId: string) => void
|
|
282
|
-
onFullscreenChange?: (paneId: string | null) => void
|
|
283
|
-
snapThreshold?: number
|
|
284
|
-
onResizeStart?: (currentNode: SplitNode) => void
|
|
285
|
-
onResize?: (currentNode: SplitNode, percentage: number) => void
|
|
286
|
-
onResizeEnd?: (currentNode: SplitNode, percentage: number) => void
|
|
287
|
-
minSplitPercentage?: number
|
|
288
|
-
maxSplitPercentage?: number
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
export interface ZeugmaActionsValue {
|
|
292
|
-
removePane: (paneId: string) => void
|
|
293
|
-
addPane: (paneId: string) => void
|
|
294
|
-
swapPanes: (paneIdA: string, paneIdB: string) => void
|
|
295
|
-
splitPane: (
|
|
296
|
-
targetId: string,
|
|
297
|
-
direction: SplitDirection,
|
|
298
|
-
splitType: 'left' | 'right' | 'top' | 'bottom',
|
|
299
|
-
paneToAdd: string,
|
|
300
|
-
) => void
|
|
301
|
-
updateSplitPercentage: (currentNode: SplitNode, percentage: number) => void
|
|
302
|
-
updatePaneMetadata: (
|
|
303
|
-
paneId: string,
|
|
304
|
-
updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined,
|
|
305
|
-
) => void
|
|
306
|
-
}
|
|
307
251
|
```
|
|
308
252
|
|
|
309
253
|
---
|
|
@@ -363,25 +307,33 @@ The root context provider. It handles the drag-and-drop event loop and coordinat
|
|
|
363
307
|
|
|
364
308
|
#### Props
|
|
365
309
|
|
|
366
|
-
-
|
|
367
|
-
- `onChange: (newLayout: TreeNode | null) => void` — Callback triggered when the layout tree changes (resizing, dragging to split, dragging to swap).
|
|
310
|
+
- `...controllerProps: ZeugmaController` — The controller properties returned by the `useZeugma` hook (typically passed via `{...zeugma}`).
|
|
368
311
|
- `renderPane: (paneId: string) => ReactNode` — Callback to render the contents of a pane given its ID.
|
|
369
|
-
- `renderDragOverlay?: (activeId: string) => ReactNode` — (Optional) Renders a custom cursor-following drag preview.
|
|
312
|
+
- `renderDragOverlay?: (activeId: string, type: 'pane' | 'tab') => ReactNode` — (Optional) Renders a custom cursor-following drag preview.
|
|
370
313
|
- `classNames?: ZeugmaClassNames` — (Optional) CSS class overrides for styling various layout elements.
|
|
371
|
-
- `
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
- `
|
|
380
|
-
- `
|
|
381
|
-
- `
|
|
382
|
-
- `
|
|
383
|
-
- `minSplitPercentage?: number` —
|
|
384
|
-
- `maxSplitPercentage?: number` —
|
|
314
|
+
- `renderWidget?: (tabId: string) => ReactNode` — (Optional) Render function mapping tab IDs to React elements. Used to render tab widgets inside portals.
|
|
315
|
+
|
|
316
|
+
### `useZeugma(options)`
|
|
317
|
+
|
|
318
|
+
A custom hook to manage the dashboard layout state.
|
|
319
|
+
|
|
320
|
+
#### Options
|
|
321
|
+
|
|
322
|
+
- `initialLayout: TreeNode | null` — Initial layout tree.
|
|
323
|
+
- `locked?: boolean` — Whether the layout is globally locked.
|
|
324
|
+
- `dragActivationDistance?: number` — Minimum pointer drag distance (in pixels) required to activate dragging (defaults to `8`).
|
|
325
|
+
- `snapThreshold?: number` — Threshold in pixels to snap layout resizers to adjacent edges (defaults to `8`).
|
|
326
|
+
- `minSplitPercentage?: number` — Minimum resizing limit percentage (defaults to `5`).
|
|
327
|
+
- `maxSplitPercentage?: number` — Maximum resizing limit percentage (defaults to `95`).
|
|
328
|
+
- `enableDragToDismiss?: boolean` — Whether to enable drag-out-to-dismiss (defaults to `false`).
|
|
329
|
+
- `dismissThreshold?: number` — Distance in pixels outside container bounds required to trigger dismissal (defaults to `60`).
|
|
330
|
+
- `onRemove?: (paneId: string) => void` — Callback when a pane is removed.
|
|
331
|
+
- `onDragStart?: (activeId: string) => void` — Callback when dragging starts.
|
|
332
|
+
- `onDragEnd?: (activeId: string, overId: string | null, dropAction: any) => void` — Callback when dragging ends.
|
|
333
|
+
- `onResizeStart?: (currentNode: SplitNode) => void` — Callback when resizing starts.
|
|
334
|
+
- `onResize?: (currentNode: SplitNode, percentage: number) => void` — Callback during resizing.
|
|
335
|
+
- `onResizeEnd?: (currentNode: SplitNode, percentage: number) => void` — Callback when resizing ends.
|
|
336
|
+
- `onDismissIntentChange?: (paneId: string | null) => void` — Callback when drag-out intent changes.
|
|
385
337
|
|
|
386
338
|
### `<PaneTree>`
|
|
387
339
|
|
|
@@ -413,6 +365,16 @@ interface PaneRenderProps {
|
|
|
413
365
|
updateMetadata: (
|
|
414
366
|
updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined,
|
|
415
367
|
) => void
|
|
368
|
+
tabs: string[]
|
|
369
|
+
activeTabId: string
|
|
370
|
+
selectTab: (tabId: string) => void
|
|
371
|
+
removeTab: (tabId: string) => void
|
|
372
|
+
tabsMetadata: Record<string, Record<string, unknown>> | undefined
|
|
373
|
+
updateTabMetadata: (
|
|
374
|
+
tabId: string,
|
|
375
|
+
updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined,
|
|
376
|
+
) => void
|
|
377
|
+
renderActiveTab: () => ReactNode
|
|
416
378
|
}
|
|
417
379
|
```
|
|
418
380
|
|
|
@@ -452,41 +414,24 @@ Import these helpers from `react-zeugma` to manipulate the tree layout programma
|
|
|
452
414
|
Removes a pane from the tree and collapses the leftover sibling split node.
|
|
453
415
|
- **`splitPane(tree: TreeNode | null, targetId: string, direction: SplitDirection, splitType: 'left' | 'right' | 'top' | 'bottom', paneToAdd: string): TreeNode | null`**
|
|
454
416
|
Splits a specific target pane by nesting it under a new `SplitNode` along with a new pane.
|
|
455
|
-
- **`
|
|
456
|
-
|
|
457
|
-
- **`updatePaneMetadata(tree: TreeNode | null, paneId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined): TreeNode | null`**
|
|
458
|
-
Updates the metadata of a specific pane.
|
|
417
|
+
- **`updateTabMetadata(tree: TreeNode | null, tabId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined): TreeNode | null`**
|
|
418
|
+
Updates the metadata of a specific tab.
|
|
459
419
|
- **`findPane(tree: TreeNode | null, paneId: string): PaneNode | null`**
|
|
460
420
|
Recursively searches the layout tree and returns the target `PaneNode` if found, or `null` otherwise.
|
|
461
421
|
|
|
462
|
-
Alternatively, you can consume state and mutation helpers directly from the context hooks:
|
|
463
|
-
|
|
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.
|
|
466
|
-
|
|
467
|
-
The actions returned by `useZeugmaActions()` are:
|
|
468
|
-
|
|
469
|
-
- **`removePane(paneId: string) => void`**
|
|
470
|
-
- **`addPane(paneId: string) => void`**
|
|
471
|
-
- **`swapPanes(paneIdA: string, paneIdB: string) => void`**
|
|
472
|
-
- **`splitPane(targetId: string, direction: SplitDirection, splitType: string, paneToAdd: string) => void`**
|
|
473
|
-
- **`updateSplitPercentage(currentNode: SplitNode, percentage: number) => void`**
|
|
474
|
-
- **`updatePaneMetadata(paneId: string, updater: (current: Record<string, unknown> | undefined) => Record<string, unknown> | undefined) => void`**
|
|
475
|
-
|
|
476
422
|
---
|
|
477
423
|
|
|
478
424
|
## 4. Basic Integration Recipe
|
|
479
425
|
|
|
480
426
|
```tsx
|
|
481
|
-
import {
|
|
482
|
-
import { Zeugma, PaneTree, Pane, DragHandle, TreeNode } from 'react-zeugma'
|
|
427
|
+
import { useZeugma, Zeugma, PaneTree, Pane, DragHandle, TreeNode } from 'react-zeugma'
|
|
483
428
|
|
|
484
429
|
const initialLayout: TreeNode = {
|
|
485
430
|
type: 'split',
|
|
486
431
|
direction: 'row',
|
|
487
432
|
splitPercentage: 50,
|
|
488
|
-
first: { type: 'pane',
|
|
489
|
-
second: { type: 'pane',
|
|
433
|
+
first: { type: 'pane', id: 'sidebar', tabs: ['sidebar'], activeTabId: 'sidebar' },
|
|
434
|
+
second: { type: 'pane', id: 'main', tabs: ['main'], activeTabId: 'main' },
|
|
490
435
|
}
|
|
491
436
|
|
|
492
437
|
function CustomPane({ id }: { id: string }) {
|
|
@@ -511,23 +456,12 @@ function CustomPane({ id }: { id: string }) {
|
|
|
511
456
|
}
|
|
512
457
|
|
|
513
458
|
export default function App() {
|
|
514
|
-
const
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
const handleRemove = (paneId: string) => {
|
|
518
|
-
// Remove the pane and update layout
|
|
519
|
-
setLayout((prev) => removePane(prev, paneId))
|
|
520
|
-
}
|
|
459
|
+
const zeugma = useZeugma({
|
|
460
|
+
initialLayout,
|
|
461
|
+
})
|
|
521
462
|
|
|
522
463
|
return (
|
|
523
|
-
<Zeugma
|
|
524
|
-
layout={layout}
|
|
525
|
-
onChange={setLayout}
|
|
526
|
-
renderPane={(id) => <CustomPane id={id} />}
|
|
527
|
-
fullscreenPaneId={fullscreenId}
|
|
528
|
-
onFullscreenChange={setFullscreenId}
|
|
529
|
-
onRemove={handleRemove}
|
|
530
|
-
>
|
|
464
|
+
<Zeugma {...zeugma} renderPane={(id) => <CustomPane id={id} />}>
|
|
531
465
|
<div style={{ width: '100vw', height: '100vh' }}>
|
|
532
466
|
<PaneTree />
|
|
533
467
|
</div>
|
|
@@ -546,7 +480,6 @@ export default function App() {
|
|
|
546
480
|
interface ZeugmaClassNames {
|
|
547
481
|
pane?: string // Applied to the outer wrapper of <Pane>
|
|
548
482
|
dropPreview?: string // Applied to the preview box when hovering over edge dropzones
|
|
549
|
-
swapPreview?: string // Applied to the preview box when hovering over center dropzone
|
|
550
483
|
dragOverlay?: string // Applied to the cursor-following drag preview portal
|
|
551
484
|
resizer?: string // Applied to the drag-to-resize split bar
|
|
552
485
|
}
|
|
@@ -565,16 +498,6 @@ interface ZeugmaClassNames {
|
|
|
565
498
|
}
|
|
566
499
|
|
|
567
500
|
/* Edge drop previews */
|
|
568
|
-
.my-drop-preview {
|
|
569
|
-
background-color: rgba(59, 130, 246, 0.2);
|
|
570
|
-
border: 2px dashed #3b82f6;
|
|
571
|
-
}
|
|
572
|
-
|
|
573
|
-
/* Center swap preview */
|
|
574
|
-
.my-swap-preview {
|
|
575
|
-
background-color: rgba(16, 185, 129, 0.25);
|
|
576
|
-
border: 2px solid #10b981;
|
|
577
|
-
}
|
|
578
501
|
```
|
|
579
502
|
````
|
|
580
503
|
|
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 ve=react.createContext(void 0),be=react.createContext(void 0);var G=()=>{let e=react.useContext(ve);if(!e)throw new Error("useZeugmaState must be used within a Zeugma provider");return e},Te=()=>{let e=react.useContext(be);if(!e)throw new Error("useZeugmaActions must be used within a Zeugma provider");return e};function Ue(e){let t=react.useRef(null);return react.useEffect(()=>{if(!e){t.current=null;return}let o=n=>{t.current={x:n.clientX,y:n.clientY};},r=n=>{let i=n.touches[0]||n.changedTouches[0];i&&(t.current={x:i.clientX,y:i.clientY});};return window.addEventListener("pointermove",o,{passive:true}),window.addEventListener("touchmove",r,{passive:true}),()=>{window.removeEventListener("pointermove",o),window.removeEventListener("touchmove",r);}},[e]),t}function We(e){react.useEffect(()=>(e?document.body.style.setProperty("cursor","not-allowed","important"):document.body.style.removeProperty("cursor"),()=>{document.body.style.removeProperty("cursor");}),[e]);}function ae(e,t){if(e===null)return null;if(e.type==="pane")return e.paneId===t?null:e;let o=ae(e.first,t),r=ae(e.second,t);return o===null?r:r===null?o:{...e,first:o,second:r}}function ue(e,t,o,r,n){if(e===null)return typeof n=="string"?{type:"pane",paneId:n}:n;if(e.type==="pane"){if(e.paneId===t){let i=typeof n=="string"?{type:"pane",paneId:n}:n,s=r==="left"||r==="top";return {type:"split",direction:o,first:s?i:e,second:s?e:i,splitPercentage:50}}return e}return {...e,first:ue(e.first,t,o,r,n)||e.first,second:ue(e.second,t,o,r,n)||e.second}}function ze(e,t,o){if(e===null)return null;let r=B(e,t),n=B(e,o);if(!r||!n)return e;function i(s){return s.type==="pane"?s.paneId===t?{...n}:s.paneId===o?{...r}:s:{...s,first:i(s.first),second:i(s.second)}}return i(e)}function Be(e,t){if(e===null)return {type:"pane",paneId:t};function o(r,n){return r.type==="pane"?{type:"split",direction:n==="row"?"column":"row",splitPercentage:50,first:r,second:{type:"pane",paneId:t}}:{...r,second:o(r.second,r.direction)}}return o(e,null)}function te(e,t,o){return e===null?null:e===t?{...e,splitPercentage:o}:e.type==="split"?{...e,first:te(e.first,t,o)||e.first,second:te(e.second,t,o)||e.second}:e}function B(e,t){return e===null?null:e.type==="pane"?e.paneId===t?e:null:B(e.first,t)??B(e.second,t)}function he(e,t,o){if(e===null)return null;if(e.type==="pane"){if(e.paneId===t){let r=o(e.metadata);if(r===void 0){let{metadata:n,...i}=e;return i}return {...e,metadata:r}}return e}return {...e,first:he(e.first,t,o)??e.first,second:he(e.second,t,o)??e.second}}function Pe(e,t,o){if(e===null)return null;if(e.type==="pane"){if(e.paneId===t){if(o===false){let{locked:r,...n}=e;return n}return {...e,locked:o}}return e}return {...e,first:Pe(e.first,t,o)??e.first,second:Pe(e.second,t,o)??e.second}}var st=8,at=8,Xt=4;var Xe=({activeId:e,render:t,className:o})=>{let r=react.useRef(null);return react.useEffect(()=>{let n=i=>{r.current&&(r.current.style.transform=`translate(${i.clientX+12}px, ${i.clientY+12}px)`);};return document.addEventListener("pointermove",n),()=>document.removeEventListener("pointermove",n)},[]),jsxRuntime.jsx("div",{ref:r,className:o,style:{position:"fixed",top:0,left:0,zIndex:9999,pointerEvents:"none"},children:t(e)})};var xe=class extends core.PointerSensor{static activators=[{eventName:"onPointerDown",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]},ye=class extends core.TouchSensor{static activators=[{eventName:"onTouchStart",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]};function Ke(e){if(e instanceof MouseEvent||e instanceof PointerEvent)return {x:e.clientX,y:e.clientY};if(typeof TouchEvent<"u"&&e instanceof TouchEvent){let t=e.touches[0]||e.changedTouches[0];if(t)return {x:t.clientX,y:t.clientY}}return null}var vt=({layout:e,onChange:t,renderPane:o,renderDragOverlay:r,classNames:n={},fullscreenPaneId:i=null,onFullscreenChange:s,onRemove:c,dragActivationDistance:x=8,snapThreshold:y=8,onDragStart:z,onDragEnd:a,onResizeStart:R,onResize:m,onResizeEnd:d,minSplitPercentage:E=5,maxSplitPercentage:L=95,enableDragToDismiss:S=false,dismissThreshold:f=60,onDismissIntentChange:v,locked:w=false,children:D})=>{let[u,b]=react.useState(e),[X,N]=react.useState(e);e!==X&&(N(e),b(e));let[k,Z]=react.useState(null),[I,C]=react.useState(null),Y=react.useRef(null),g=react.useRef(null),A=Ue(k),W=react.useCallback(l=>{Y.current=l;},[]),[O,M]=react.useState(false);We(O);let H=react.useCallback(l=>o(l),[o]),oe=react.useMemo(()=>n,[n.pane,n.paneLocked,n.dropPreview,n.swapPreview,n.dragOverlay,n.resizer,n.dismissPreview,n.dashboardLocked,n.lockedPreview]),Le=core.useSensors(core.useSensor(xe,{activationConstraint:{distance:x}}),core.useSensor(ye,{activationConstraint:{delay:250,tolerance:5}})),me=l=>{let p=l.active.id.toString();Z(p);let T=l.activatorEvent;A.current=Ke(T),S&&Y.current?g.current=Y.current.getBoundingClientRect():g.current=null,z&&z(p);},re=l=>{let{over:p}=l,P=(p?.id.toString()||"").startsWith("drop-locked-");if(M(P),!S)return;let K=l.active.id.toString(),h=g.current;if(!h){I!==null&&(C(null),v?.(null));return}let J=l.activatorEvent,U=null,F=null;if(A.current)U=A.current.x,F=A.current.y;else {let $=Ke(J);$&&(U=$.x+l.delta.x,F=$.y+l.delta.y);}let Q=0;if(U!==null&&F!==null){let $=0,V=0;U<h.left?$=h.left-U:U>h.right&&($=U-h.right),F<h.top?V=h.top-F:F>h.bottom&&(V=F-h.bottom),Q=Math.sqrt($*$+V*V);}else {let $=l.active.rect.current.translated;if($){let V=$.left+$.width/2,j=$.top+$.height/2,q=0,ee=0;V<h.left?q=h.left-V:V>h.right&&(q=V-h.right),j<h.top?ee=h.top-j:j>h.bottom&&(ee=j-h.bottom),Q=Math.sqrt(q*q+ee*ee);}}Q>f?I!==K&&(C(K),v?.(K)):I!==null&&(C(null),v?.(null));},ge=l=>{Z(null),M(false);let{active:p,over:T}=l,P=p.id.toString(),K=S&&I===P;if(C(null),v?.(null),g.current=null,K){c?c(P):le(P),a&&a(P,null,null);return}if(!T){a&&a(P,null,null);return}let h=T.id.toString();if(h.startsWith("drop-locked-")){a&&a(P,null,null);return}let J=h.match(/^drop-center-(.+)$/);if(J){let[,q]=J;if(P!==q){let ee=ze(u,P,q);b(ee),t(ee);}a&&a(P,q,{type:"swap",position:"center"});return}let U=h.match(/^drop-(left|right|top|bottom)-(.+)$/);if(!U){a&&a(P,null,null);return}let[,F,Q]=U;if(P===Q){a&&a(P,null,null);return}let Ne=F==="left"||F==="right"?"row":"column",$=B(u,P)??{type:"pane",paneId:P},V=ae(u,P),j=ue(V,Q,Ne,F,$);b(j),t(j),a&&a(P,Q,{type:"split",direction:Ne,position:F});},ie=react.useCallback((l,p=false)=>{b(l),p||t(l);},[t]),le=react.useCallback(l=>{let p=ae(u,l);b(p),t(p);},[u,t]),ce=react.useCallback(l=>{let p=Be(u,l);b(p),t(p);},[u,t]),se=react.useCallback((l,p)=>{let T=ze(u,l,p);b(T),t(T);},[u,t]),Ae=react.useCallback((l,p,T,P)=>{let K=B(u,P)??{type:"pane",paneId:P},h=ae(u,P),J=ue(h,l,p,T,K);b(J),t(J);},[u,t]),ke=react.useCallback((l,p)=>{let T=te(u,l,p);b(T),t(T);},[u,t]),He=react.useCallback((l,p)=>{let T=he(u,l,p);b(T),t(T);},[u,t]),Fe=react.useCallback((l,p)=>{let T=Pe(u,l,p);b(T),t(T);},[u,t]),Oe=react.useCallback((l,p)=>{d&&d(l,p);},[d]),ot=react.useMemo(()=>({layout:u,onLayoutChange:ie,renderPane:H,activeId:k,dismissIntentId:I,setContainerRef:W,fullscreenPaneId:i,classNames:oe,onRemove:c,onFullscreenChange:s,snapThreshold:y,onResizeStart:R,onResize:m,onResizeEnd:Oe,minSplitPercentage:E,maxSplitPercentage:L,locked:w}),[u,k,I,W,i,oe,c,s,y,R,m,E,L,ie,H,Oe,w]),rt=react.useMemo(()=>({removePane:le,addPane:ce,swapPanes:se,splitPane:Ae,updateSplitPercentage:ke,updatePaneMetadata:He,updatePaneLock:Fe}),[le,ce,se,Ae,ke,He,Fe]);return jsxRuntime.jsx(be.Provider,{value:rt,children:jsxRuntime.jsxs(ve.Provider,{value:ot,children:[jsxRuntime.jsx(core.DndContext,{id:"zeugma-dnd-context",sensors:Le,collisionDetection:core.pointerWithin,onDragStart:me,onDragMove:re,onDragEnd:ge,children:D}),k&&r&&jsxRuntime.jsx(Xe,{activeId:k,render:r,className:`${n.dragOverlay||""} ${k===I?n.dismissPreview||"zeugma-dismiss-preview":""}`.trim()})]})})};function Se({cursor:e,resizerEl:t,onMove:o,onEnd:r}){document.body.classList.add("zeugma-resizing");let n=document.createElement("style");n.id="zeugma-global-cursor-style",n.textContent=`
|
|
1
|
+
'use strict';var en=require('react'),reactDom=require('react-dom'),core=require('@dnd-kit/core'),jsxRuntime=require('react/jsx-runtime');function _interopDefault(e){return e&&e.__esModule?e:{default:e}}var en__default=/*#__PURE__*/_interopDefault(en);var ze=en.createContext(void 0),Ie=en.createContext(void 0);var oe=()=>{let e=en.useContext(ze);if(!e)throw new Error("useZeugmaState must be used within a Zeugma provider");return e},nt=()=>{let e=en.useContext(Ie);if(!e)throw new Error("useZeugmaActions must be used within a Zeugma provider");return e};function rt(e){let t=en.useRef(null);return en.useEffect(()=>{if(!e){t.current=null;return}let r=n=>{t.current={x:n.clientX,y:n.clientY};},o=n=>{let s=n.touches[0]||n.changedTouches[0];s&&(t.current={x:s.clientX,y:s.clientY});};return window.addEventListener("pointermove",r,{passive:true}),window.addEventListener("touchmove",o,{passive:true}),()=>{window.removeEventListener("pointermove",r),window.removeEventListener("touchmove",o);}},[e]),t}function ot(e){en.useEffect(()=>(e?document.body.style.setProperty("cursor","not-allowed","important"):document.body.style.removeProperty("cursor"),()=>{document.body.style.removeProperty("cursor");}),[e]);}function st(){let[e,t]=en.useState({}),r=en.useCallback((o,n)=>{t(s=>s[o]===n?s:{...s,[o]:n});},[]);return {portalTargets:e,registerPortalTarget:r}}var $e=en.createContext(void 0);var Ht=8,Zt=8,An=4;function ie(){return "pane-"+Math.random().toString(36).substring(2,11)}function be(e,t){if(e===null)return null;if(e.type==="pane")return e.id===t?null:e;let r=be(e.first,t),o=be(e.second,t);return r===null?o:o===null?r:{...e,first:r,second:o}}function de(e,t){if(e===null)return null;if(e.type==="pane"){if(e.tabs.includes(t)){let n=e.tabs.filter(a=>a!==t);if(n.length===0)return null;let s=e.activeTabId;e.activeTabId===t&&(s=n[0]);let i={...e.tabsMetadata};return delete i[t],{...e,tabs:n,activeTabId:s,tabsMetadata:Object.keys(i).length>0?i:void 0}}return e}let r=de(e.first,t),o=de(e.second,t);return r===null?o:o===null?r:{...e,first:r,second:o}}function ye(e,t,r,o,n){if(e===null)return typeof n=="string"?{type:"pane",id:ie(),tabs:[n],activeTabId:n}:n;if(e.type==="pane"){if(e.id===t||e.tabs.includes(t)){let s=typeof n=="string"?{type:"pane",id:ie(),tabs:[n],activeTabId:n}:n,i=o==="left"||o==="top";return {type:"split",direction:r,first:i?s:e,second:i?e:s,splitPercentage:50}}return e}return {...e,first:ye(e.first,t,r,o,n)||e.first,second:ye(e.second,t,r,o,n)||e.second}}function it(e,t){if(e===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t};function r(o,n){return o.type==="pane"?{type:"split",direction:n==="row"?"column":"row",splitPercentage:50,first:o,second:{type:"pane",id:ie(),tabs:[t],activeTabId:t}}:{...o,second:r(o.second,o.direction)}}return r(e,null)}function ve(e,t,r){return e===null?null:e===t?{...e,splitPercentage:r}:e.type==="split"?{...e,first:ve(e.first,t,r)||e.first,second:ve(e.second,t,r)||e.second}:e}function q(e,t){return e===null?null:e.type==="pane"?e.id===t||e.tabs.includes(t)?e:null:q(e.first,t)??q(e.second,t)}function ke(e,t,r){if(e===null)return null;if(e.type==="pane"){if(e.id===t||e.tabs.includes(t)){let o=e.tabsMetadata||{},n=o[t],s=r(n),i={...o};return s===void 0?delete i[t]:i[t]=s,{...e,tabsMetadata:Object.keys(i).length>0?i:void 0}}return e}return {...e,first:ke(e.first,t,r)??e.first,second:ke(e.second,t,r)??e.second}}function He(e,t,r){if(e===null)return null;if(e.type==="pane"){if(e.id===t||e.tabs.includes(t)){if(r===false){let{locked:o,...n}=e;return n}return {...e,locked:r}}return e}return {...e,first:He(e.first,t,r)??e.first,second:He(e.second,t,r)??e.second}}function Ze(e,t,r){return e===null?null:e.type==="pane"?e.id===t||e.tabs.includes(t)?{...e,activeTabId:r}:e:{...e,first:Ze(e.first,t,r)??e.first,second:Ze(e.second,t,r)??e.second}}function at(e,t,r){if(e===null)return null;let n=q(e,t)?.tabsMetadata?.[t],s=de(e,t);if(s===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t,tabsMetadata:n?{[t]:n}:void 0};function i(a){if(a.type==="pane"){if(a.id===r||a.tabs.includes(r)){let l=[...a.tabs];l.includes(t)||l.push(t);let y={...a.tabsMetadata};return n&&(y[t]=n),{...a,tabs:l,activeTabId:t,tabsMetadata:Object.keys(y).length>0?y:void 0}}return a}return {...a,first:i(a.first),second:i(a.second)}}return i(s)}function lt(e,t,r,o="before"){if(e===null)return null;let s=q(e,t)?.tabsMetadata?.[t],i=de(e,t);if(i===null)return {type:"pane",id:ie(),tabs:[t],activeTabId:t,tabsMetadata:s?{[t]:s}:void 0};function a(l){if(l.type==="pane"){if(l.id===r||l.tabs.includes(r)){let D=[...l.tabs].filter(T=>T!==t),c=D.indexOf(r);c<0&&(c=0),o==="after"&&(c+=1),D.splice(c,0,t);let x={...l.tabsMetadata};return s&&(x[t]=s),{...l,tabs:D,activeTabId:t,tabsMetadata:Object.keys(x).length>0?x:void 0}}return l}return {...l,first:a(l.first),second:a(l.second)}}return a(i)}function se(e,t=0,r=0,o=100,n=100,s="root"){if(e===null)return {panes:[],splitters:[]};if(e.type==="pane")return {panes:[{paneId:e.id,left:t,top:r,width:o,height:n,node:e}],splitters:[]};let{direction:i,splitPercentage:a,first:l,second:y}=e,c={id:`splitter-${s}-${i}`,currentNode:e,direction:i,left:i==="row"?t+o*(a/100):t,top:i==="column"?r+n*(a/100):r,width:i==="row"?0:o,height:i==="column"?0:n,parentLeft:t,parentTop:r,parentWidth:o,parentHeight:n},x={panes:[],splitters:[]},T={panes:[],splitters:[]};if(i==="row"){let v=o*(a/100);x=se(l,t,r,v,n,`${s}-L`),T=se(y,t+v,r,o-v,n,`${s}-R`);}else {let v=n*(a/100);x=se(l,t,r,o,v,`${s}-T`),T=se(y,t,r+v,o,n-v,`${s}-B`);}return {panes:[...x.panes,...T.panes],splitters:[c,...x.splitters,...T.splitters]}}function At(e){let{initialLayout:t,onChange:r,fullscreenPaneId:o,onFullscreenChange:n,locked:s=false,dragActivationDistance:i=8,snapThreshold:a=8,minSplitPercentage:l=5,maxSplitPercentage:y=95,enableDragToDismiss:D=false,dismissThreshold:c=60,onRemove:x,onDragStart:T,onDragEnd:v,onResizeStart:R,onResize:E,onResizeEnd:L,onDismissIntentChange:p}=e,[b,f]=en.useState(t),[z,A]=en.useState(o||null),[I,V]=en.useState(s),[w,K]=en.useState(null),[h,F]=en.useState(null),[Y,O]=en.useState(null),m=en.useRef(null),$=en.useCallback(u=>{m.current=u;},[]),_=en.useCallback(u=>{A(u),n?.(u);},[n]);en.useEffect(()=>{V(s);},[s]),en.useEffect(()=>{o!==void 0&&A(o);},[o]);let k=en.useRef(true);en.useEffect(()=>{if(k.current){k.current=false;return}r?.(b);},[b,r]);let N=en.useCallback(u=>{f(S=>be(S,u));},[]),d=en.useCallback(u=>{f(S=>it(S,u));},[]),B=en.useCallback((u,S,P,te)=>{f(Re=>{let _e=q(Re,te)??{type:"pane",id:te,tabs:[te],activeTabId:te},Ye=be(Re,te);return ye(Ye,u,S,P,_e)});},[]),ae=en.useCallback((u,S)=>{f(P=>ve(P,u,S));},[]),W=en.useCallback((u,S)=>{f(P=>ke(P,u,S));},[]),ee=en.useCallback((u,S)=>{f(P=>He(P,u,S));},[]),le=en.useCallback((u,S)=>{f(P=>Ze(P,u,S));},[]),fe=en.useCallback((u,S)=>{f(P=>at(P,u,S));},[]),me=en.useCallback((u,S,P)=>{f(te=>lt(te,u,S,P));},[]),j=en.useCallback(u=>{f(S=>de(S,u));},[]);return {layout:b,setLayout:f,fullscreenPaneId:z,setFullscreenPaneId:_,locked:I,setLocked:V,activeId:w,setActiveId:K,activeType:h,setActiveType:F,dismissIntentId:Y,setDismissIntentId:O,containerRef:m,setContainerRef:$,dragActivationDistance:i,snapThreshold:a,minSplitPercentage:l,maxSplitPercentage:y,enableDragToDismiss:D,dismissThreshold:c,onRemove:x,onDragStart:T,onDragEnd:v,onResizeStart:R,onResize:E,onResizeEnd:L,onDismissIntentChange:p,removePane:N,addPane:d,splitPane:B,updateSplitPercentage:ae,updateTabMetadata:W,updatePaneLock:ee,selectTab:le,mergeTab:fe,moveTab:me,removeTab:j}}var ut=({activeId:e,render:t,className:r})=>{let o=en.useRef(null);return en.useEffect(()=>{let n=s=>{o.current&&(o.current.style.transform=`translate(${s.clientX+12}px, ${s.clientY+12}px)`);};return document.addEventListener("pointermove",n),()=>document.removeEventListener("pointermove",n)},[]),jsxRuntime.jsx("div",{ref:o,className:r,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")}]},Fe=class extends core.TouchSensor{static activators=[{eventName:"onTouchStart",handler:({nativeEvent:t})=>!t.target?.closest(".drag-cancel")}]};function qe(e){if(e instanceof MouseEvent||e instanceof PointerEvent)return {x:e.clientX,y:e.clientY};if(typeof TouchEvent<"u"&&e instanceof TouchEvent){let t=e.touches[0]||e.changedTouches[0];if(t)return {x:t.clientX,y:t.clientY}}return null}var Kt=e=>{let{renderPane:t,renderWidget:r,renderDragOverlay:o,classNames:n={},children:s,layout:i,setLayout:a,fullscreenPaneId:l,setFullscreenPaneId:y,locked:D,activeId:c,setActiveId:x,activeType:T,setActiveType:v,dismissIntentId:R,setDismissIntentId:E,containerRef:L,setContainerRef:p,dragActivationDistance:b,snapThreshold:f,minSplitPercentage:z,maxSplitPercentage:A,enableDragToDismiss:I,dismissThreshold:V,onRemove:w,onDragStart:K,onDragEnd:h,onResizeStart:F,onResize:Y,onResizeEnd:O,onDismissIntentChange:m,removePane:$,addPane:_,splitPane:k,updateSplitPercentage:N,updateTabMetadata:d,updatePaneLock:B,selectTab:ae,mergeTab:W,moveTab:ee,removeTab:le}=e,{portalTargets:fe,registerPortalTarget:me}=st(),j=en.useRef(null),u=rt(c),[S,P]=en.useState(false);ot(S);let te=en.useCallback(g=>t(g),[t]),Re=en.useMemo(()=>n,[n.pane,n.paneLocked,n.dropPreview,n.dragOverlay,n.resizer,n.dismissPreview,n.dashboardLocked,n.lockedPreview]),_e=core.useSensors(core.useSensor(Ae,{activationConstraint:{distance:b}}),core.useSensor(Fe,{activationConstraint:{delay:250,tolerance:5}})),Ye=en.useCallback(g=>{let H=core.pointerWithin(g);if(H.length>0)return H;if(g.active.id.toString().startsWith("tab-header-")){let ne=g.droppableContainers.filter(J=>J.id.toString().startsWith("tab-drop-"));return core.closestCenter({...g,droppableContainers:ne})}return []},[]),Rt=g=>{let H=g.active.id.toString(),U=H.startsWith("tab-header-"),ne=U?H.substring(11):H;x(ne),v(U?"tab":"pane");let J=g.activatorEvent;u.current=qe(J),I&&L.current?j.current=L.current.getBoundingClientRect():j.current=null,K&&K(ne);},St=g=>{let{over:H}=g,ne=(H?.id.toString()||"").startsWith("drop-locked-");if(P(ne),!I)return;let J=g.active.id.toString(),Se=J.startsWith("tab-header-")?J.substring(11):J,M=j.current;if(!M){R!==null&&(E(null),m?.(null));return}let we=g.activatorEvent,re=null,X=null;if(u.current)re=u.current.x,X=u.current.y;else {let Z=qe(we);Z&&(re=Z.x+g.delta.x,X=Z.y+g.delta.y);}let ce=0;if(re!==null&&X!==null){let Z=0,Q=0;re<M.left?Z=M.left-re:re>M.right&&(Z=re-M.right),X<M.top?Q=M.top-X:X>M.bottom&&(Q=X-M.bottom),ce=Math.sqrt(Z*Z+Q*Q);}else {let Z=g.active.rect.current.translated;if(Z){let Q=Z.left+Z.width/2,ge=Z.top+Z.height/2,ue=0,Pe=0;Q<M.left?ue=M.left-Q:Q>M.right&&(ue=Q-M.right),ge<M.top?Pe=M.top-ge:ge>M.bottom&&(Pe=ge-M.bottom),ce=Math.sqrt(ue*ue+Pe*Pe);}}ce>V?R!==Se&&(E(Se),m?.(Se)):R!==null&&(E(null),m?.(null));},Dt=g=>{x(null),v(null),P(false);let{active:H,over:U}=g,ne=H.id.toString(),J=ne.startsWith("tab-header-"),C=J?ne.substring(11):ne,Se=I&&R===C;if(E(null),m?.(null),j.current=null,Se){w?w(C):le(C),h&&h(C,null,null);return}if(!U){h&&h(C,null,null);return}let M=U.id.toString();if(M.startsWith("drop-locked-")){h&&h(C,null,null);return}let we=M.match(/^tab-drop-(.+)$/);if(we){let[,Ne]=we;if(C!==Ne){let Ee="before",Je=U.rect,Lt=g.activatorEvent,Me=null;if(u.current)Me=u.current.x;else {let Le=qe(Lt);Le&&(Me=Le.x+g.delta.x);}if(Me!==null){let Le=Je.left+Je.width/2;Me>Le&&(Ee="after");}ee(C,Ne,Ee);}h&&h(C,Ne,{type:"swap",position:"center"});return}let re=M.match(/^drop-(left|right|top|bottom)-(.+)$/);if(!re){h&&h(C,null,null);return}let[,X,ce]=re,De=q(i,C),Z=De&&De.id===ce,Q=De&&De.tabs.length===1;if(C===ce||Z&&Q){h&&h(C,null,null);return}let ge=X==="left"||X==="right"?"row":"column",ue;if(J){let Ee=q(i,C)?.tabsMetadata?.[C];ue={type:"pane",id:ie(),tabs:[C],activeTabId:C,tabsMetadata:Ee?{[C]:Ee}:void 0};}else ue=q(i,C)??{type:"pane",id:ie(),tabs:[C],activeTabId:C};let Pe=J?de(i,C):be(i,C),Mt=ye(Pe,ce,ge,X,ue);a(Mt),h&&h(C,ce,{type:"split",direction:ge,position:X});},je=en.useCallback((g,H)=>{O&&O(g,H);},[O]),Et=en.useMemo(()=>({layout:i,onLayoutChange:g=>a(g),renderPane:te,activeId:c,dismissIntentId:R,setContainerRef:p,fullscreenPaneId:l,classNames:Re,onRemove:w,onFullscreenChange:y,snapThreshold:f,onResizeStart:F,onResize:Y,onResizeEnd:je,minSplitPercentage:z,maxSplitPercentage:A,locked:D}),[i,c,R,p,l,Re,w,y,f,F,Y,z,A,a,te,je,D]),Ct=en.useMemo(()=>({removePane:$,addPane:_,splitPane:k,updateSplitPercentage:N,updateTabMetadata:d,updatePaneLock:B,selectTab:ae,mergeTab:W,moveTab:ee,removeTab:le}),[$,_,k,N,d,B,ae,W,ee,le]),wt=en.useMemo(()=>{let g=[];function H(U){U&&(U.type==="pane"?g.push(...U.tabs):(H(U.first),H(U.second)));}return H(i),g},[i]),Nt=en.useMemo(()=>({registerPortalTarget:me}),[me]);return jsxRuntime.jsx(Ie.Provider,{value:Ct,children:jsxRuntime.jsx(ze.Provider,{value:Et,children:jsxRuntime.jsxs($e.Provider,{value:Nt,children:[jsxRuntime.jsx(core.DndContext,{id:"zeugma-dnd-context",sensors:_e,collisionDetection:Ye,onDragStart:Rt,onDragMove:St,onDragEnd:Dt,children:s}),c&&T&&o&&jsxRuntime.jsx(ut,{activeId:c,render:g=>o(g,T),className:`${n.dragOverlay||""} ${c===R?n.dismissPreview||"zeugma-dismiss-preview":""}`.trim()}),jsxRuntime.jsx("div",{id:"zeugma-portal-host",style:{display:"none"},children:wt.map(g=>jsxRuntime.jsx(jt,{tabId:g,target:fe[g]||null,renderWidget:r},g))})]})})})},jt=({tabId:e,target:t,renderWidget:r})=>{let o=en.useRef(null);!o.current&&typeof window<"u"&&(o.current=document.createElement("div"),o.current.className=`zeugma-portal-wrapper-${e}`,o.current.style.width="100%",o.current.style.height="100%");let n=o.current;return en.useEffect(()=>{if(n)if(t)t.appendChild(n);else {let s=document.getElementById("zeugma-hidden-portal-container");s||(s=document.createElement("div"),s.id="zeugma-hidden-portal-container",s.style.display="none",document.body.appendChild(s)),s.appendChild(n);}},[t,n]),en.useEffect(()=>()=>{o.current&&o.current.remove();},[]),!n||!r?null:reactDom.createPortal(r(e),n)};function Oe({cursor:e,resizerEl:t,onMove:r,onEnd:o}){document.body.classList.add("zeugma-resizing");let n=document.createElement("style");n.id="zeugma-global-cursor-style",n.textContent=`
|
|
2
2
|
* {
|
|
3
3
|
cursor: ${e} !important;
|
|
4
4
|
user-select: none !important;
|
|
5
5
|
}
|
|
6
|
-
`,document.head.appendChild(n),t.setAttribute("data-resizing","true");let i=c=>{o(c);},s=()=>{document.body.classList.remove("zeugma-resizing"),t.removeAttribute("data-resizing");let c=document.getElementById("zeugma-global-cursor-style");c&&c.remove(),document.removeEventListener("pointermove",i),document.removeEventListener("pointerup",s),r();};document.addEventListener("pointermove",i),document.addEventListener("pointerup",s);}function Ce({containerRef:e,isRow:t,direction:o,splitPercentage:r,resizerSize:n,snapThreshold:i,layout:s,currentNode:c,onLayoutChange:x,onResizeStart:y,onResizeEnd:z,parentLeft:a,parentTop:R,parentWidth:m,parentHeight:d}){let{onResizeStart:E,onResize:L,onResizeEnd:S,minSplitPercentage:f=5,maxSplitPercentage:v=95,locked:w=false}=G();return react.useCallback(D=>{if(w)return;D.preventDefault();let u=e.current;if(!u)return;y&&y(),E&&E(c);let b=u.getBoundingClientRect(),X=D.clientX,N=D.clientY,k=r,Z=D.currentTarget,I=b.left+b.width*(a/100),C=b.top+b.height*(R/100),Y=b.width*(m/100),g=b.height*(d/100),W=Array.from(document.querySelectorAll('div[role="separator"][data-direction]')).filter(M=>M!==Z&&M.getAttribute("data-direction")===o).map(M=>{let H=M.getBoundingClientRect();return t?H.left+H.width/2:H.top+H.height/2}),O=k;Se({cursor:t?"col-resize":"row-resize",resizerEl:Z,onMove:M=>{let H=t?(M.clientX-X)/Y*100:(M.clientY-N)/g*100,oe=k+H,Le=t?I+(Y-n)*(oe/100)+n/2:C+(g-n)*(oe/100)+n/2,me=1/0,re=null;for(let ce of W){let se=Math.abs(Le-ce);se<i&&se<me&&(me=se,re=ce);}let ge=oe;re!==null&&(ge=t?(re-n/2-I)/(Y-n)*100:(re-n/2-C)/(g-n)*100);let ie=Math.max(f,Math.min(v,ge));O=ie;let le=te(s,c,ie);x(le,true),L&&L(c,ie);},onEnd:()=>{let M=te(s,c,O);x(M),z&&z(),S&&S(c,O);}});},[e,t,o,r,n,i,s,c,x,y,z,E,L,S,f,v,a,R,m,d])}function pe(e,t=0,o=0,r=100,n=100,i="root"){if(e.type==="pane")return {panes:[{paneId:e.paneId,left:t,top:o,width:r,height:n,node:e}],splitters:[]};let{direction:s,splitPercentage:c,first:x,second:y}=e,a={id:`splitter-${i}-${s}`,currentNode:e,direction:s,left:s==="row"?t+r*(c/100):t,top:s==="column"?o+n*(c/100):o,width:s==="row"?0:r,height:s==="column"?0:n,parentLeft:t,parentTop:o,parentWidth:r,parentHeight:n},R={panes:[],splitters:[]},m={panes:[],splitters:[]};if(s==="row"){let d=r*(c/100);R=pe(x,t,o,d,n,`${i}-L`),m=pe(y,t+d,o,r-d,n,`${i}-R`);}else {let d=n*(c/100);R=pe(x,t,o,r,d,`${i}-T`),m=pe(y,t,o+d,r,n-d,`${i}-B`);}return {panes:[...R.panes,...m.panes],splitters:[a,...R.splitters,...m.splitters]}}var St=({splitter:e,resizerSize:t,snapThreshold:o,containerRef:r})=>{let{layout:n,onLayoutChange:i,classNames:s,locked:c}=G(),[x,y]=react.useState(false),{currentNode:z,direction:a,left:R,top:m,width:d,height:E,parentLeft:L,parentTop:S,parentWidth:f,parentHeight:v}=e,w=a==="row",D=Ce({containerRef:r,isRow:w,direction:a,splitPercentage:z.splitPercentage,resizerSize:t,snapThreshold:o,layout:n,currentNode:z,onLayoutChange:i,onResizeStart:()=>y(true),onResizeEnd:()=>y(false),parentLeft:L,parentTop:S,parentWidth:f,parentHeight:v}),u=w?{position:"absolute",left:`calc(${R}% - ${t/2}px)`,top:`${m}%`,width:`${t}px`,height:`${E}%`,cursor:c?"default":"col-resize",pointerEvents:c?"none":"auto",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box"}:{position:"absolute",left:`${R}%`,top:`calc(${m}% - ${t/2}px)`,width:`${d}%`,height:`${t}px`,cursor:c?"default":"row-resize",pointerEvents:c?"none":"auto",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box"};return jsxRuntime.jsx("div",{className:`zeugma-resizer ${s.resizer||""}`.trim(),"data-direction":a,"data-resizing":x||void 0,style:u,onPointerDown:D,role:"separator","aria-valuenow":z.splitPercentage,"aria-valuemin":5,"aria-valuemax":95})},wt=({tree:e,resizerSize:t=4,snapThreshold:o})=>{let{layout:r,renderPane:n,activeId:i,dismissIntentId:s,setContainerRef:c,fullscreenPaneId:x,snapThreshold:y,locked:z,classNames:a}=G(),R=o!==void 0?o:y??8,m=e!==void 0?e:r,d=react.useRef(null),{panes:E,splitters:L}=react.useMemo(()=>m?pe(m):{panes:[],splitters:[]},[m]);if(!m)return null;let S=()=>jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[E.map(f=>{let v=x===f.paneId;return jsxRuntime.jsx("div",{style:{position:"absolute",left:v?"0%":`${f.left}%`,top:v?"0%":`${f.top}%`,width:v?"100%":`${f.width}%`,height:v?"100%":`${f.height}%`,overflow:"hidden",zIndex:v?20:1,display:x&&!v?"none":"block",padding:v?"0px":`${t/2}px`,boxSizing:"border-box"},children:n(f.paneId)},f.paneId)}),!x&&L.map(f=>jsxRuntime.jsx(St,{splitter:f,resizerSize:t,snapThreshold:R,containerRef:d},f.id))]});if(e===void 0){let f=i!==null&&i===s,v=D=>{c(D),d.current=D;},w=`zeugma-dashboard-root ${f?"zeugma-dashboard-dismiss-active":""} ${z?a.dashboardLocked||"zeugma-dashboard-locked":""}`.trim();return jsxRuntime.jsx("div",{ref:v,className:w,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:S()})}return jsxRuntime.jsx("div",{ref:d,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:S()})};var et="zeugma-height:",Tt="default-pane";function zt(e){try{let t=localStorage.getItem(et+e);if(t!==null){let o=Number(t);if(Number.isFinite(o)&&o>0)return o}}catch{}return null}function je(e,t){try{localStorage.setItem(et+e,String(Math.round(t)));}catch{}}var tt=({children:e,active:t=true,height:o,onHeightChange:r,minHeight:n=100,maxHeight:i=1/0,persist:s,localStorageKey:c,resizerHeight:x=6,className:y,resizerClassName:z})=>{let a=s?c||Tt:null,R=()=>{let w=(a?zt(a):null)??o??400;return we(w,n,i)},[m,d]=react.useState(R),E=react.useRef(null),L=a?m:o??m,S=react.useRef(o);react.useEffect(()=>{if(o!==void 0&&o!==S.current){let w=we(o,n,i);d(w),a&&je(a,w);}S.current=o;},[o,n,i,a]);let f=react.useCallback(()=>i,[i]),v=react.useCallback(w=>{w.preventDefault();let D=w.clientY,u=L,b=f(),X=w.currentTarget,N=nt(E.current),k=N?N.scrollTop:0,Z=D,I=null,C=(g,A)=>{let W=A-k,M=g-D+W,H=we(u+M,n,b);return E.current&&(E.current.style.height=`${H}px`),H},Y=()=>{if(!N)return;let g=N===document.documentElement||N===document.body?{top:0,bottom:window.innerHeight}:N.getBoundingClientRect(),A=40,W=10,O=0;Z>g.bottom-A?O=Math.min(1,(Z-(g.bottom-A))/A)*W:Z<g.top+A&&(O=-Math.min(1,(g.top+A-Z)/A)*W),O!==0&&(N.scrollTop+=O,C(Z,N.scrollTop)),I=requestAnimationFrame(Y);};I=requestAnimationFrame(Y),Se({cursor:"row-resize",resizerEl:X,onMove:g=>{Z=g.clientY,N&&C(Z,N.scrollTop);},onEnd:()=>{I!==null&&cancelAnimationFrame(I);let g=u;E.current&&(g=E.current.getBoundingClientRect().height),g=we(g,n,b),d(g),r&&r(g),a&&je(a,g);}});},[L,n,f,r,a]);return t?jsxRuntime.jsxs("div",{ref:E,className:`zeugma-resizable-container ${y||""}`.trim(),style:{height:`${L}px`,position:"relative",overflow:"hidden",boxSizing:"border-box"},children:[jsxRuntime.jsx("div",{style:{height:`calc(100% - ${x}px)`,overflow:"hidden"},children:e}),jsxRuntime.jsx("div",{className:`zeugma-resizable-handle ${z||""}`.trim(),style:{height:`${x}px`,cursor:"row-resize",position:"relative",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box",flexShrink:0},onPointerDown:v,role:"separator","aria-orientation":"horizontal","aria-valuenow":Math.round(L),"aria-valuemin":n,"aria-valuemax":i===1/0?void 0:i})]}):jsxRuntime.jsx("div",{className:`zeugma-resizable-container disabled ${y||""}`.trim(),style:{height:"100%",position:"relative",overflow:"hidden",boxSizing:"border-box"},children:jsxRuntime.jsx("div",{style:{height:"100%",overflow:"hidden"},children:e})})};function we(e,t,o){return Math.max(t,Math.min(o,e))}function nt(e){if(typeof window>"u"||!e)return null;let t=e.parentElement;if(!t)return document.documentElement;let r=window.getComputedStyle(t).overflowY;return r==="auto"||r==="scroll"?t:nt(t)}var Ee=react.createContext(null);var $t={top:{position:"absolute",top:0,left:"25%",width:"50%",height:"25%",zIndex:20,pointerEvents:"auto"},bottom:{position:"absolute",bottom:0,left:"25%",width:"50%",height:"25%",zIndex:20,pointerEvents:"auto"},left:{position:"absolute",top:"25%",left:0,width:"25%",height:"50%",zIndex:20,pointerEvents:"auto"},right:{position:"absolute",top:"25%",right:0,width:"25%",height:"50%",zIndex:20,pointerEvents:"auto"},center:{position:"absolute",top:"25%",left:"25%",width:"50%",height:"50%",zIndex:20,pointerEvents:"auto"},full:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:20,pointerEvents:"auto",cursor:"not-allowed"}},Zt={top:{position:"absolute",top:0,left:0,right:0,height:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},bottom:{position:"absolute",bottom:0,left:0,right:0,height:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},left:{position:"absolute",top:0,bottom:0,left:0,width:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},right:{position:"absolute",top:0,bottom:0,right:0,width:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},center:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:21,pointerEvents:"none",boxSizing:"border-box"},full:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:21,pointerEvents:"none",boxSizing:"border-box"}},$e=({id:e,position:t,activeClassName:o})=>{let{setNodeRef:r,isOver:n}=core.useDroppable({id:e});return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{ref:r,style:$t[t]}),n&&jsxRuntime.jsx("div",{className:o,style:Zt[t]})]})},At=({id:e,children:t,style:o,locked:r=false})=>{let{layout:n,activeId:i,classNames:s,fullscreenPaneId:c,onRemove:x,onFullscreenChange:y,locked:z}=G(),{removePane:a,updatePaneMetadata:R}=Te(),m=react.useMemo(()=>B(n,e),[n,e]),d=m?.metadata,E=m?.locked??false,L=r||E,S=z||L,f=z||L,v=i!==null&&i!==e&&!f,{attributes:w,listeners:D,setNodeRef:u,isDragging:b}=core.useDraggable({id:e,disabled:S}),X=i===e||b,N=c===e,k=react.useMemo(()=>({isDragging:X,isFullscreen:N,toggleFullscreen:()=>y?.(N?null:e),remove:()=>{N&&y?.(null),x?x(e):a(e);},metadata:d,updateMetadata:C=>{R(e,C);},locked:S}),[X,N,y,e,x,a,d,R,S]),Z=react.useMemo(()=>S?{disabled:true}:{...D,...w},[D,w,S]),I=`${s.pane||""} ${L?s.paneLocked||"zeugma-pane-locked":""}`.trim();return jsxRuntime.jsx(Ee.Provider,{value:Z,children:jsxRuntime.jsxs("div",{ref:u,className:I,style:{position:"relative",width:"100%",height:"100%",...o},children:[t(k),v&&jsxRuntime.jsxs("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:[["top","bottom","left","right"].map(C=>jsxRuntime.jsx($e,{id:`drop-${C}-${e}`,position:C,activeClassName:s.dropPreview},C)),jsxRuntime.jsx($e,{id:`drop-center-${e}`,position:"center",activeClassName:s.swapPreview})]}),i!==null&&i!==e&&f&&jsxRuntime.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:jsxRuntime.jsx($e,{id:`drop-locked-${e}`,position:"full",activeClassName:s.lockedPreview||"zeugma-locked-preview"})})]})})};var Ft=({children:e,className:t,style:o})=>{let r=react.useContext(Ee);if(!r)throw new Error("<DragHandle> must be used inside a <Pane>");let{disabled:n,...i}=r;return jsxRuntime.jsx("div",{className:t,style:{cursor:n?"default":"grab",userSelect:n?"auto":"none",touchAction:n?"auto":"none",...o},...n?{}:i,children:e})};exports.DEFAULT_DRAG_ACTIVATION_DISTANCE=at;exports.DEFAULT_RESIZER_SIZE=Xt;exports.DEFAULT_SNAP_THRESHOLD=st;exports.DragHandle=Ft;exports.Pane=At;exports.PaneTree=wt;exports.ResizableContainer=tt;exports.Zeugma=vt;exports.addPane=Be;exports.createDragSession=Se;exports.findPane=B;exports.removePane=ae;exports.splitPane=ue;exports.swapPanes=ze;exports.updatePaneLock=Pe;exports.updatePaneMetadata=he;exports.updateSplitPercentage=te;exports.useResizer=Ce;exports.useZeugmaActions=Te;exports.useZeugmaState=G;//# sourceMappingURL=index.cjs.map
|
|
6
|
+
`,document.head.appendChild(n),t.setAttribute("data-resizing","true");let s=a=>{r(a);},i=()=>{document.body.classList.remove("zeugma-resizing"),t.removeAttribute("data-resizing");let a=document.getElementById("zeugma-global-cursor-style");a&&a.remove(),document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",i),o();};document.addEventListener("pointermove",s),document.addEventListener("pointerup",i);}function Ge({containerRef:e,isRow:t,direction:r,splitPercentage:o,resizerSize:n,snapThreshold:s,layout:i,currentNode:a,onLayoutChange:l,onResizeStart:y,onResizeEnd:D,parentLeft:c,parentTop:x,parentWidth:T,parentHeight:v}){let{onResizeStart:R,onResize:E,onResizeEnd:L,minSplitPercentage:p=5,maxSplitPercentage:b=95,locked:f=false}=oe();return en.useCallback(z=>{if(f)return;z.preventDefault();let A=e.current;if(!A)return;y&&y(),R&&R(a);let I=A.getBoundingClientRect(),V=z.clientX,w=z.clientY,K=o,h=z.currentTarget,F=I.left+I.width*(c/100),Y=I.top+I.height*(x/100),O=I.width*(T/100),m=I.height*(v/100),_=Array.from(document.querySelectorAll('div[role="separator"][data-direction]')).filter(N=>N!==h&&N.getAttribute("data-direction")===r).map(N=>{let d=N.getBoundingClientRect();return t?d.left+d.width/2:d.top+d.height/2}),k=K;Oe({cursor:t?"col-resize":"row-resize",resizerEl:h,onMove:N=>{let d=t?(N.clientX-V)/O*100:(N.clientY-w)/m*100,B=K+d,ae=t?F+(O-n)*(B/100)+n/2:Y+(m-n)*(B/100)+n/2,W=1/0,ee=null;for(let j of _){let u=Math.abs(ae-j);u<s&&u<W&&(W=u,ee=j);}let le=B;ee!==null&&(le=t?(ee-n/2-F)/(O-n)*100:(ee-n/2-Y)/(m-n)*100);let fe=Math.max(p,Math.min(b,le));k=fe;let me=ve(i,a,fe);if(me){let{panes:j,splitters:u}=se(me),S=e.current;if(S){for(let P of j)S.style.setProperty(`--pane-left-${P.paneId}`,`${P.left}%`),S.style.setProperty(`--pane-top-${P.paneId}`,`${P.top}%`),S.style.setProperty(`--pane-width-${P.paneId}`,`${P.width}%`),S.style.setProperty(`--pane-height-${P.paneId}`,`${P.height}%`);for(let P of u)S.style.setProperty(`--splitter-pos-${P.id}`,`${P.direction==="row"?P.left:P.top}%`);}}E&&E(a,fe);},onEnd:()=>{let N=ve(i,a,k),d=e.current;if(d){let{panes:B,splitters:ae}=se(N);for(let W of B)d.style.removeProperty(`--pane-left-${W.paneId}`),d.style.removeProperty(`--pane-top-${W.paneId}`),d.style.removeProperty(`--pane-width-${W.paneId}`),d.style.removeProperty(`--pane-height-${W.paneId}`);for(let W of ae)d.style.removeProperty(`--splitter-pos-${W.id}`);}l(N),D&&D(),L&&L(a,k);}});},[e,t,r,o,n,s,i,a,l,y,D,R,E,L,p,b,c,x,T,v])}var on=({splitter:e,resizerSize:t,snapThreshold:r,containerRef:o})=>{let{layout:n,onLayoutChange:s,classNames:i,locked:a}=oe(),[l,y]=en.useState(false),{currentNode:D,direction:c,left:x,top:T,width:v,height:R,parentLeft:E,parentTop:L,parentWidth:p,parentHeight:b}=e,f=c==="row",z=Ge({containerRef:o,isRow:f,direction:c,splitPercentage:D.splitPercentage,resizerSize:t,snapThreshold:r,layout:n,currentNode:D,onLayoutChange:s,onResizeStart:()=>y(true),onResizeEnd:()=>y(false),parentLeft:E,parentTop:L,parentWidth:p,parentHeight:b}),A=f?{position:"absolute",left:`calc(var(--splitter-pos-${e.id}, ${x}%) - ${t/2}px)`,top:`calc(${T}% + ${t/2}px)`,width:`${t}px`,height:`calc(${R}% - ${t}px)`,cursor:a?"default":"col-resize",pointerEvents:a?"none":"auto",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box"}:{position:"absolute",left:`calc(${x}% + ${t/2}px)`,top:`calc(var(--splitter-pos-${e.id}, ${T}%) - ${t/2}px)`,width:`calc(${v}% - ${t}px)`,height:`${t}px`,cursor:a?"default":"row-resize",pointerEvents:a?"none":"auto",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box"};return jsxRuntime.jsx("div",{className:`zeugma-resizer ${i.resizer||""}`.trim(),"data-direction":c,"data-resizing":l||void 0,style:A,onPointerDown:z,role:"separator","aria-valuenow":D.splitPercentage,"aria-valuemin":5,"aria-valuemax":95})},sn=en__default.default.memo(({paneId:e,renderPane:t})=>jsxRuntime.jsx(jsxRuntime.Fragment,{children:t(e)}),(e,t)=>e.paneId===t.paneId&&e.renderPane===t.renderPane),an=({tree:e,resizerSize:t=4,snapThreshold:r})=>{let{layout:o,renderPane:n,activeId:s,dismissIntentId:i,setContainerRef:a,fullscreenPaneId:l,snapThreshold:y,locked:D,classNames:c}=oe(),x=r!==void 0?r:y??8,T=e!==void 0?e:o,v=en.useRef(null),{panes:R,splitters:E}=en.useMemo(()=>T?se(T):{panes:[],splitters:[]},[T]);if(!T)return null;let L=()=>jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[R.map(p=>{let b=l===p.paneId;return jsxRuntime.jsx("div",{style:{position:"absolute",left:b?"0%":`var(--pane-left-${p.paneId}, ${p.left}%)`,top:b?"0%":`var(--pane-top-${p.paneId}, ${p.top}%)`,width:b?"100%":`var(--pane-width-${p.paneId}, ${p.width}%)`,height:b?"100%":`var(--pane-height-${p.paneId}, ${p.height}%)`,overflow:"hidden",zIndex:b?20:1,display:l&&!b?"none":"block",padding:b?"0px":`${t/2}px`,boxSizing:"border-box"},children:jsxRuntime.jsx(sn,{paneId:p.paneId,renderPane:n})},p.paneId)}),!l&&E.map(p=>jsxRuntime.jsx(on,{splitter:p,resizerSize:t,snapThreshold:x,containerRef:v},p.id))]});if(e===void 0){let p=s!==null&&s===i,b=z=>{a(z),v.current=z;},f=`zeugma-dashboard-root ${p?"zeugma-dashboard-dismiss-active":""} ${D?c.dashboardLocked||"zeugma-dashboard-locked":""}`.trim();return jsxRuntime.jsx("div",{ref:b,className:f,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:L()})}return jsxRuntime.jsx("div",{ref:v,style:{position:"relative",width:"100%",height:"100%",overflow:"hidden"},children:L()})};var ht="zeugma-height:",dn="default-pane";function pn(e){try{let t=localStorage.getItem(ht+e);if(t!==null){let r=Number(t);if(Number.isFinite(r)&&r>0)return r}}catch{}return null}function vt(e,t){try{localStorage.setItem(ht+e,String(Math.round(t)));}catch{}}var Pt=({children:e,active:t=true,height:r,onHeightChange:o,minHeight:n=100,maxHeight:s=1/0,persist:i,localStorageKey:a,resizerHeight:l=6,className:y,resizerClassName:D})=>{let c=i?a||dn:null,x=()=>{let f=(c?pn(c):null)??r??400;return Ve(f,n,s)},[T,v]=en.useState(x),R=en.useRef(null),E=c?T:r??T,L=en.useRef(r);en.useEffect(()=>{if(r!==void 0&&r!==L.current){let f=Ve(r,n,s);v(f),c&&vt(c,f);}L.current=r;},[r,n,s,c]);let p=en.useCallback(()=>s,[s]),b=en.useCallback(f=>{f.preventDefault();let z=f.clientY,A=E,I=p(),V=f.currentTarget,w=yt(R.current),K=w?w.scrollTop:0,h=z,F=null,Y=(m,$)=>{let _=$-K,N=m-z+_,d=Ve(A+N,n,I);return R.current&&(R.current.style.height=`${d}px`),d},O=()=>{if(!w)return;let m=w===document.documentElement||w===document.body?{top:0,bottom:window.innerHeight}:w.getBoundingClientRect(),$=40,_=10,k=0;h>m.bottom-$?k=Math.min(1,(h-(m.bottom-$))/$)*_:h<m.top+$&&(k=-Math.min(1,(m.top+$-h)/$)*_),k!==0&&(w.scrollTop+=k,Y(h,w.scrollTop)),F=requestAnimationFrame(O);};F=requestAnimationFrame(O),Oe({cursor:"row-resize",resizerEl:V,onMove:m=>{h=m.clientY,w&&Y(h,w.scrollTop);},onEnd:()=>{F!==null&&cancelAnimationFrame(F);let m=A;R.current&&(m=R.current.getBoundingClientRect().height),m=Ve(m,n,I),v(m),o&&o(m),c&&vt(c,m);}});},[E,n,p,o,c]);return t?jsxRuntime.jsxs("div",{ref:R,className:`zeugma-resizable-container ${y||""}`.trim(),style:{height:`${E}px`,position:"relative",overflow:"hidden",boxSizing:"border-box"},children:[jsxRuntime.jsx("div",{style:{height:`calc(100% - ${l}px)`,overflow:"hidden"},children:e}),jsxRuntime.jsx("div",{className:`zeugma-resizable-handle ${D||""}`.trim(),style:{height:`${l}px`,cursor:"row-resize",position:"relative",zIndex:10,userSelect:"none",touchAction:"none",boxSizing:"border-box",flexShrink:0},onPointerDown:b,role:"separator","aria-orientation":"horizontal","aria-valuenow":Math.round(E),"aria-valuemin":n,"aria-valuemax":s===1/0?void 0:s})]}):jsxRuntime.jsx("div",{className:`zeugma-resizable-container disabled ${y||""}`.trim(),style:{height:"100%",position:"relative",overflow:"hidden",boxSizing:"border-box"},children:jsxRuntime.jsx("div",{style:{height:"100%",overflow:"hidden"},children:e})})};function Ve(e,t,r){return Math.max(t,Math.min(r,e))}function yt(e){if(typeof window>"u"||!e)return null;let t=e.parentElement;if(!t)return document.documentElement;let o=window.getComputedStyle(t).overflowY;return o==="auto"||o==="scroll"?t:yt(t)}var Ue=en.createContext(null);var yn={top:{position:"absolute",top:0,left:"25%",width:"50%",height:"25%",zIndex:20,pointerEvents:"auto"},bottom:{position:"absolute",bottom:0,left:"25%",width:"50%",height:"25%",zIndex:20,pointerEvents:"auto"},left:{position:"absolute",top:"25%",left:0,width:"25%",height:"50%",zIndex:20,pointerEvents:"auto"},right:{position:"absolute",top:"25%",right:0,width:"25%",height:"50%",zIndex:20,pointerEvents:"auto"},full:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:20,pointerEvents:"auto",cursor:"not-allowed"}},Tn={top:{position:"absolute",top:0,left:0,right:0,height:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},bottom:{position:"absolute",bottom:0,left:0,right:0,height:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},left:{position:"absolute",top:0,bottom:0,left:0,width:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},right:{position:"absolute",top:0,bottom:0,right:0,width:"50%",zIndex:21,pointerEvents:"none",boxSizing:"border-box"},full:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:21,pointerEvents:"none",boxSizing:"border-box"}},Tt=({id:e,position:t,activeClassName:r})=>{let{setNodeRef:o,isOver:n}=core.useDroppable({id:e});return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx("div",{ref:o,style:yn[t]}),n&&jsxRuntime.jsx("div",{className:r,style:Tn[t]})]})},xn=({id:e,children:t,style:r,locked:o=false})=>{let{layout:n,activeId:s,classNames:i,fullscreenPaneId:a,onFullscreenChange:l,locked:y}=oe(),{removePane:D,updateTabMetadata:c,selectTab:x,removeTab:T}=nt(),v=en.useContext($e);if(!v)throw new Error("Pane must be used within a Zeugma provider");let{registerPortalTarget:R}=v,E=en.useMemo(()=>q(n,e),[n,e]),L=E?.id??e,p=E?.tabs??[e],b=E?.activeTabId??e,f=E?.tabsMetadata,z=f?.[e],A=E?.locked??false,I=o||A,V=y||I,w=y||I,K=s!==null&&s!==e&&(!p.includes(s)||p.length>1)&&!w,{attributes:h,listeners:F,setNodeRef:Y}=core.useDraggable({id:e,disabled:V}),O=s!==null&&p.includes(s),m=a===e,$=en.useCallback(()=>jsxRuntime.jsx("div",{id:`zeugma-tab-target-${b}`,className:"zeugma-tab-content-wrapper",style:{height:"100%",width:"100%"}}),[b]);en.useEffect(()=>{let d=document.getElementById(`zeugma-tab-target-${b}`);return R(b,d),()=>{R(b,null);}},[b,R]);let _=en.useMemo(()=>({isDragging:O,isFullscreen:m,toggleFullscreen:()=>l?.(m?null:e),remove:()=>{m&&l?.(null),D(L);},metadata:z,updateMetadata:d=>{c(e,d);},locked:V,tabs:p,activeTabId:b,selectTab:d=>x(L,d),removeTab:d=>{m&&d===b&&l?.(null),T(d);},tabsMetadata:f,updateTabMetadata:(d,B)=>{c(d,B);},renderActiveTab:$}),[O,m,l,e,T,z,c,V,p,b,x,L,f,$]),k=en.useMemo(()=>V?{disabled:true}:{...F,...h},[F,h,V]),N=`${i.pane||""} ${I?i.paneLocked||"zeugma-pane-locked":""}`.trim();return jsxRuntime.jsx(Ue.Provider,{value:k,children:jsxRuntime.jsxs("div",{ref:Y,className:N,style:{position:"relative",width:"100%",height:"100%",...r},children:[t(_),K&&jsxRuntime.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:["top","bottom","left","right"].map(d=>jsxRuntime.jsx(Tt,{id:`drop-${d}-${e}`,position:d,activeClassName:i.dropPreview},d))}),s!==null&&s!==e&&w&&jsxRuntime.jsx("div",{style:{position:"absolute",top:0,left:0,right:0,bottom:0,zIndex:15,pointerEvents:"none"},children:jsxRuntime.jsx(Tt,{id:`drop-locked-${e}`,position:"full",activeClassName:i.lockedPreview||"zeugma-locked-preview"})})]})})};var Dn=({children:e,className:t,style:r})=>{let o=en.useContext(Ue);if(!o)throw new Error("<DragHandle> must be used inside a <Pane>");let{disabled:n,...s}=o;return jsxRuntime.jsx("div",{className:t,style:{cursor:n?"default":"grab",userSelect:n?"auto":"none",touchAction:n?"auto":"none",...r},...n?{}:s,children:e})};var Nn=({id:e,locked:t=false,children:r,className:o,style:n})=>{let{locked:s}=oe(),i=t||s,{attributes:a,listeners:l,setNodeRef:y,isDragging:D}=core.useDraggable({id:`tab-header-${e}`,disabled:i}),{setNodeRef:c,isOver:x}=core.useDroppable({id:`tab-drop-${e}`,disabled:i});return jsxRuntime.jsx("div",{ref:v=>{y(v),c(v);},className:o,style:{display:"inline-flex",cursor:i?"default":"grab",...n},...i?{}:l,...i?{}:a,children:r({isDragging:D,isOver:x})})};exports.DEFAULT_DRAG_ACTIVATION_DISTANCE=Zt;exports.DEFAULT_RESIZER_SIZE=An;exports.DEFAULT_SNAP_THRESHOLD=Ht;exports.DragHandle=Dn;exports.Pane=xn;exports.PaneTree=an;exports.ResizableContainer=Pt;exports.Tab=Nn;exports.Zeugma=Kt;exports.addPane=it;exports.computeLayout=se;exports.createDragSession=Oe;exports.findPane=q;exports.generateUniqueId=ie;exports.mergeTab=at;exports.moveTab=lt;exports.removePane=be;exports.removeTab=de;exports.selectTab=Ze;exports.splitPane=ye;exports.updatePaneLock=He;exports.updateSplitPercentage=ve;exports.updateTabMetadata=ke;exports.useResizer=Ge;exports.useZeugma=At;//# sourceMappingURL=index.cjs.map
|
|
7
7
|
//# sourceMappingURL=index.cjs.map
|