@destyler/splitter 0.0.7-beta.7 → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs DELETED
@@ -1,648 +0,0 @@
1
- 'use strict';
2
-
3
- const anatomy$1 = require('@zag-js/anatomy');
4
- const domEvent = require('@zag-js/dom-event');
5
- const domQuery = require('@zag-js/dom-query');
6
- const core = require('@zag-js/core');
7
- const utils = require('@zag-js/utils');
8
- const types = require('@zag-js/types');
9
-
10
- const anatomy = anatomy$1.createAnatomy("splitter").parts("root", "panel", "resizeTrigger");
11
- const parts = anatomy.build();
12
-
13
- const dom = domQuery.createScope({
14
- getRootId: (ctx) => ctx.ids?.root ?? `splitter:${ctx.id}`,
15
- getResizeTriggerId: (ctx, id) => ctx.ids?.resizeTrigger?.(id) ?? `splitter:${ctx.id}:splitter:${id}`,
16
- getLabelId: (ctx) => ctx.ids?.label ?? `splitter:${ctx.id}:label`,
17
- getPanelId: (ctx, id) => ctx.ids?.panel?.(id) ?? `splitter:${ctx.id}:panel:${id}`,
18
- getGlobalCursorId: (ctx) => `splitter:${ctx.id}:global-cursor`,
19
- getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
20
- getResizeTriggerEl: (ctx, id) => dom.getById(ctx, dom.getResizeTriggerId(ctx, id)),
21
- getPanelEl: (ctx, id) => dom.getById(ctx, dom.getPanelId(ctx, id)),
22
- getCursor(ctx) {
23
- const x = ctx.isHorizontal;
24
- let cursor = x ? "col-resize" : "row-resize";
25
- if (ctx.activeResizeState.isAtMin)
26
- cursor = x ? "e-resize" : "s-resize";
27
- if (ctx.activeResizeState.isAtMax)
28
- cursor = x ? "w-resize" : "n-resize";
29
- return cursor;
30
- },
31
- getPanelStyle(ctx, id) {
32
- const flexGrow = ctx.panels.find((panel) => panel.id === id)?.size ?? "0";
33
- return {
34
- flexBasis: 0,
35
- flexGrow,
36
- flexShrink: 1,
37
- overflow: "hidden"
38
- };
39
- },
40
- getActiveHandleEl(ctx) {
41
- const activeId = ctx.activeResizeId;
42
- if (activeId == null)
43
- return;
44
- return dom.getById(ctx, dom.getResizeTriggerId(ctx, activeId));
45
- },
46
- getResizeTriggerEls(ctx) {
47
- const ownerId = CSS.escape(dom.getRootId(ctx));
48
- return domQuery.queryAll(dom.getRootEl(ctx), `[role=separator][data-ownedby='${ownerId}']`);
49
- },
50
- setupGlobalCursor(ctx) {
51
- const styleEl = dom.getById(ctx, dom.getGlobalCursorId(ctx));
52
- const textContent = `* { cursor: ${dom.getCursor(ctx)} !important; }`;
53
- if (styleEl) {
54
- styleEl.textContent = textContent;
55
- } else {
56
- const style = dom.getDoc(ctx).createElement("style");
57
- style.id = dom.getGlobalCursorId(ctx);
58
- style.textContent = textContent;
59
- dom.getDoc(ctx).head.appendChild(style);
60
- }
61
- },
62
- removeGlobalCursor(ctx) {
63
- dom.getById(ctx, dom.getGlobalCursorId(ctx))?.remove();
64
- }
65
- });
66
-
67
- function validateSize(key, size) {
68
- if (Math.floor(size) > 100) {
69
- throw new Error(`Total ${key} of panels cannot be greater than 100`);
70
- }
71
- }
72
- function getNormalizedPanels(ctx) {
73
- let numOfPanelsWithoutSize = 0;
74
- let totalSize = 0;
75
- let totalMinSize = 0;
76
- const panels = ctx.size.map((panel) => {
77
- const minSize = panel.minSize ?? 0;
78
- const maxSize = panel.maxSize ?? 100;
79
- totalMinSize += minSize;
80
- if (panel.size == null) {
81
- numOfPanelsWithoutSize++;
82
- } else {
83
- totalSize += panel.size;
84
- }
85
- return {
86
- ...panel,
87
- minSize,
88
- maxSize
89
- };
90
- });
91
- validateSize("minSize", totalMinSize);
92
- validateSize("size", totalSize);
93
- let end = 0;
94
- let remainingSize = 0;
95
- const result = panels.map((panel) => {
96
- const start = end;
97
- if (panel.size != null) {
98
- end += panel.size;
99
- remainingSize = panel.size - panel.minSize;
100
- return {
101
- ...panel,
102
- start,
103
- end,
104
- remainingSize
105
- };
106
- }
107
- const size = (100 - totalSize) / numOfPanelsWithoutSize;
108
- end += size;
109
- remainingSize = size - panel.minSize;
110
- return { ...panel, size, start, end, remainingSize };
111
- });
112
- return result;
113
- }
114
- function getHandlePanels(ctx, id = ctx.activeResizeId) {
115
- const [beforeId, afterId] = id?.split(":") ?? [];
116
- if (!beforeId || !afterId)
117
- return;
118
- const beforeIndex = ctx.previousPanels.findIndex((panel) => panel.id === beforeId);
119
- const afterIndex = ctx.previousPanels.findIndex((panel) => panel.id === afterId);
120
- if (beforeIndex === -1 || afterIndex === -1)
121
- return;
122
- const before = ctx.previousPanels[beforeIndex];
123
- const after = ctx.previousPanels[afterIndex];
124
- return {
125
- before: {
126
- ...before,
127
- index: beforeIndex
128
- },
129
- after: {
130
- ...after,
131
- index: afterIndex
132
- }
133
- };
134
- }
135
- function getHandleBounds(ctx, id = ctx.activeResizeId) {
136
- const panels = getHandlePanels(ctx, id);
137
- if (!panels)
138
- return;
139
- const { before, after } = panels;
140
- return {
141
- min: Math.max(before.start + before.minSize, after.end - after.maxSize),
142
- max: Math.min(after.end - after.minSize, before.maxSize + before.start)
143
- };
144
- }
145
- function getPanelBounds(ctx, id) {
146
- const bounds = getHandleBounds(ctx, id);
147
- const panels = getHandlePanels(ctx, id);
148
- if (!bounds || !panels)
149
- return;
150
- const { before, after } = panels;
151
- const beforeMin = Math.abs(before.start - bounds.min);
152
- const afterMin = after.size + (before.size - beforeMin);
153
- const beforeMax = Math.abs(before.start - bounds.max);
154
- const afterMax = after.size - (beforeMax - before.size);
155
- return {
156
- before: {
157
- index: before.index,
158
- min: beforeMin,
159
- max: beforeMax,
160
- isAtMin: beforeMin === before.size,
161
- isAtMax: beforeMax === before.size,
162
- up(step) {
163
- return Math.min(before.size + step, beforeMax);
164
- },
165
- down(step) {
166
- return Math.max(before.size - step, beforeMin);
167
- }
168
- },
169
- after: {
170
- index: after.index,
171
- min: afterMin,
172
- max: afterMax,
173
- isAtMin: afterMin === after.size,
174
- isAtMax: afterMax === after.size,
175
- up(step) {
176
- return Math.min(after.size + step, afterMin);
177
- },
178
- down(step) {
179
- return Math.max(after.size - step, afterMax);
180
- }
181
- }
182
- };
183
- }
184
- function clamp(value, min, max) {
185
- return Math.min(Math.max(value, min), max);
186
- }
187
-
188
- function connect(state, send, normalize) {
189
- const horizontal = state.context.isHorizontal;
190
- const focused = state.hasTag("focus");
191
- const dragging = state.matches("dragging");
192
- const panels = state.context.panels;
193
- function getResizeTriggerState(props) {
194
- const { id, disabled } = props;
195
- const ids = id.split(":");
196
- const panelIds = ids.map((id2) => dom.getPanelId(state.context, id2));
197
- const panels2 = getHandleBounds(state.context, id);
198
- return {
199
- disabled: !!disabled,
200
- focused: state.context.activeResizeId === id && focused,
201
- panelIds,
202
- min: panels2?.min,
203
- max: panels2?.max,
204
- value: 0
205
- };
206
- }
207
- return {
208
- focused,
209
- dragging,
210
- getResizeTriggerState,
211
- bounds: getHandleBounds(state.context),
212
- setToMinSize(id) {
213
- const panel = panels.find((panel2) => panel2.id === id);
214
- send({ type: "SET_PANEL_SIZE", id, size: panel?.minSize, src: "setToMinSize" });
215
- },
216
- setToMaxSize(id) {
217
- const panel = panels.find((panel2) => panel2.id === id);
218
- send({ type: "SET_PANEL_SIZE", id, size: panel?.maxSize, src: "setToMaxSize" });
219
- },
220
- setSize(id, size) {
221
- send({ type: "SET_PANEL_SIZE", id, size });
222
- },
223
- getRootProps() {
224
- return normalize.element({
225
- ...parts.root.attrs,
226
- "data-orientation": state.context.orientation,
227
- "id": dom.getRootId(state.context),
228
- "dir": state.context.dir,
229
- "style": {
230
- display: "flex",
231
- flexDirection: horizontal ? "row" : "column",
232
- height: "100%",
233
- width: "100%",
234
- overflow: "hidden"
235
- }
236
- });
237
- },
238
- getPanelProps(props) {
239
- const { id } = props;
240
- return normalize.element({
241
- ...parts.panel.attrs,
242
- "data-orientation": state.context.orientation,
243
- "dir": state.context.dir,
244
- "id": dom.getPanelId(state.context, id),
245
- "data-ownedby": dom.getRootId(state.context),
246
- "style": dom.getPanelStyle(state.context, id)
247
- });
248
- },
249
- getResizeTriggerProps(props) {
250
- const { id, disabled, step = 1 } = props;
251
- const triggerState = getResizeTriggerState(props);
252
- return normalize.element({
253
- ...parts.resizeTrigger.attrs,
254
- "dir": state.context.dir,
255
- "id": dom.getResizeTriggerId(state.context, id),
256
- "role": "separator",
257
- "data-ownedby": dom.getRootId(state.context),
258
- "tabIndex": disabled ? void 0 : 0,
259
- "aria-valuenow": triggerState.value,
260
- "aria-valuemin": triggerState.min,
261
- "aria-valuemax": triggerState.max,
262
- "data-orientation": state.context.orientation,
263
- "aria-orientation": state.context.orientation,
264
- "aria-controls": triggerState.panelIds.join(" "),
265
- "data-focus": domQuery.dataAttr(triggerState.focused),
266
- "data-disabled": domQuery.dataAttr(disabled),
267
- "style": {
268
- touchAction: "none",
269
- userSelect: "none",
270
- WebkitUserSelect: "none",
271
- flex: "0 0 auto",
272
- pointerEvents: dragging && !triggerState.focused ? "none" : void 0,
273
- cursor: horizontal ? "col-resize" : "row-resize",
274
- [horizontal ? "minHeight" : "minWidth"]: "0"
275
- },
276
- onPointerDown(event) {
277
- if (disabled) {
278
- event.preventDefault();
279
- return;
280
- }
281
- send({ type: "POINTER_DOWN", id });
282
- event.currentTarget.setPointerCapture(event.pointerId);
283
- event.preventDefault();
284
- event.stopPropagation();
285
- },
286
- onPointerUp(event) {
287
- if (disabled)
288
- return;
289
- if (event.currentTarget.hasPointerCapture(event.pointerId)) {
290
- event.currentTarget.releasePointerCapture(event.pointerId);
291
- }
292
- },
293
- onPointerOver() {
294
- if (disabled)
295
- return;
296
- send({ type: "POINTER_OVER", id });
297
- },
298
- onPointerLeave() {
299
- if (disabled)
300
- return;
301
- send({ type: "POINTER_LEAVE", id });
302
- },
303
- onBlur() {
304
- send("BLUR");
305
- },
306
- onFocus() {
307
- send({ type: "FOCUS", id });
308
- },
309
- onDoubleClick() {
310
- if (disabled)
311
- return;
312
- send({ type: "DOUBLE_CLICK", id });
313
- },
314
- onKeyDown(event) {
315
- if (event.defaultPrevented)
316
- return;
317
- if (disabled)
318
- return;
319
- const moveStep = domEvent.getEventStep(event) * step;
320
- const keyMap = {
321
- Enter() {
322
- send("ENTER");
323
- },
324
- ArrowUp() {
325
- send({ type: "ARROW_UP", step: moveStep });
326
- },
327
- ArrowDown() {
328
- send({ type: "ARROW_DOWN", step: moveStep });
329
- },
330
- ArrowLeft() {
331
- send({ type: "ARROW_LEFT", step: moveStep });
332
- },
333
- ArrowRight() {
334
- send({ type: "ARROW_RIGHT", step: moveStep });
335
- },
336
- Home() {
337
- send("HOME");
338
- },
339
- End() {
340
- send("END");
341
- }
342
- };
343
- const key = domEvent.getEventKey(event, state.context);
344
- const exec = keyMap[key];
345
- if (exec) {
346
- exec(event);
347
- event.preventDefault();
348
- }
349
- }
350
- });
351
- }
352
- };
353
- }
354
-
355
- function machine(userContext) {
356
- const ctx = utils.compact(userContext);
357
- return core.createMachine(
358
- {
359
- id: "splitter",
360
- initial: "idle",
361
- context: {
362
- orientation: "horizontal",
363
- activeResizeId: null,
364
- previousPanels: [],
365
- size: [],
366
- initialSize: [],
367
- activeResizeState: {
368
- isAtMin: false,
369
- isAtMax: false
370
- },
371
- ...ctx
372
- },
373
- created: ["setPreviousPanels", "setInitialSize"],
374
- watch: {
375
- size: ["setActiveResizeState"]
376
- },
377
- computed: {
378
- isHorizontal: (ctx2) => ctx2.orientation === "horizontal",
379
- panels: (ctx2) => getNormalizedPanels(ctx2)
380
- },
381
- on: {
382
- SET_PANEL_SIZE: {
383
- actions: "setPanelSize"
384
- }
385
- },
386
- states: {
387
- "idle": {
388
- entry: ["clearActiveHandleId"],
389
- on: {
390
- POINTER_OVER: {
391
- target: "hover:temp",
392
- actions: ["setActiveHandleId"]
393
- },
394
- FOCUS: {
395
- target: "focused",
396
- actions: ["setActiveHandleId"]
397
- },
398
- DOUBLE_CLICK: {
399
- actions: ["resetStartPanel", "setPreviousPanels"]
400
- }
401
- }
402
- },
403
- "hover:temp": {
404
- after: {
405
- HOVER_DELAY: "hover"
406
- },
407
- on: {
408
- POINTER_DOWN: {
409
- target: "dragging",
410
- actions: ["setActiveHandleId"]
411
- },
412
- POINTER_LEAVE: "idle"
413
- }
414
- },
415
- "hover": {
416
- tags: ["focus"],
417
- on: {
418
- POINTER_DOWN: "dragging",
419
- POINTER_LEAVE: "idle"
420
- }
421
- },
422
- "focused": {
423
- tags: ["focus"],
424
- on: {
425
- BLUR: "idle",
426
- POINTER_DOWN: {
427
- target: "dragging",
428
- actions: ["setActiveHandleId"]
429
- },
430
- ARROW_LEFT: {
431
- guard: "isHorizontal",
432
- actions: ["shrinkStartPanel", "setPreviousPanels"]
433
- },
434
- ARROW_RIGHT: {
435
- guard: "isHorizontal",
436
- actions: ["expandStartPanel", "setPreviousPanels"]
437
- },
438
- ARROW_UP: {
439
- guard: "isVertical",
440
- actions: ["shrinkStartPanel", "setPreviousPanels"]
441
- },
442
- ARROW_DOWN: {
443
- guard: "isVertical",
444
- actions: ["expandStartPanel", "setPreviousPanels"]
445
- },
446
- ENTER: [
447
- {
448
- guard: "isStartPanelAtMax",
449
- actions: ["setStartPanelToMin", "setPreviousPanels"]
450
- },
451
- { actions: ["setStartPanelToMax", "setPreviousPanels"] }
452
- ],
453
- HOME: {
454
- actions: ["setStartPanelToMin", "setPreviousPanels"]
455
- },
456
- END: {
457
- actions: ["setStartPanelToMax", "setPreviousPanels"]
458
- }
459
- }
460
- },
461
- "dragging": {
462
- tags: ["focus"],
463
- entry: "focusResizeHandle",
464
- activities: ["trackPointerMove"],
465
- on: {
466
- POINTER_MOVE: {
467
- actions: ["setPointerValue", "setGlobalCursor", "invokeOnResize"]
468
- },
469
- POINTER_UP: {
470
- target: "focused",
471
- actions: ["setPreviousPanels", "clearGlobalCursor", "blurResizeHandle", "invokeOnResizeEnd"]
472
- }
473
- }
474
- }
475
- }
476
- },
477
- {
478
- activities: {
479
- trackPointerMove: (ctx2, _evt, { send }) => {
480
- const doc = dom.getDoc(ctx2);
481
- return domEvent.trackPointerMove(doc, {
482
- onPointerMove(info) {
483
- send({ type: "POINTER_MOVE", point: info.point });
484
- },
485
- onPointerUp() {
486
- send("POINTER_UP");
487
- }
488
- });
489
- }
490
- },
491
- guards: {
492
- isStartPanelAtMin: (ctx2) => ctx2.activeResizeState.isAtMin,
493
- isStartPanelAtMax: (ctx2) => ctx2.activeResizeState.isAtMax,
494
- isHorizontal: (ctx2) => ctx2.isHorizontal,
495
- isVertical: (ctx2) => !ctx2.isHorizontal
496
- },
497
- delays: {
498
- HOVER_DELAY: 250
499
- },
500
- actions: {
501
- setGlobalCursor(ctx2) {
502
- dom.setupGlobalCursor(ctx2);
503
- },
504
- clearGlobalCursor(ctx2) {
505
- dom.removeGlobalCursor(ctx2);
506
- },
507
- invokeOnResize(ctx2) {
508
- ctx2.onSizeChange?.({ size: Array.from(ctx2.size), activeHandleId: ctx2.activeResizeId });
509
- },
510
- invokeOnResizeEnd(ctx2) {
511
- ctx2.onSizeChangeEnd?.({ size: Array.from(ctx2.size), activeHandleId: ctx2.activeResizeId });
512
- },
513
- setActiveHandleId(ctx2, evt) {
514
- ctx2.activeResizeId = evt.id;
515
- },
516
- clearActiveHandleId(ctx2) {
517
- ctx2.activeResizeId = null;
518
- },
519
- setInitialSize(ctx2) {
520
- ctx2.initialSize = ctx2.panels.slice().map((panel) => ({
521
- id: panel.id,
522
- size: panel.size
523
- }));
524
- },
525
- setPanelSize(ctx2, evt) {
526
- const { id, size } = evt;
527
- ctx2.size = ctx2.size.map((panel) => {
528
- const panelSize = clamp(size, panel.minSize ?? 0, panel.maxSize ?? 100);
529
- return panel.id === id ? { ...panel, size: panelSize } : panel;
530
- });
531
- },
532
- setStartPanelToMin(ctx2) {
533
- const bounds = getPanelBounds(ctx2);
534
- if (!bounds)
535
- return;
536
- const { before, after } = bounds;
537
- ctx2.size[before.index].size = before.min;
538
- ctx2.size[after.index].size = after.min;
539
- },
540
- setStartPanelToMax(ctx2) {
541
- const bounds = getPanelBounds(ctx2);
542
- if (!bounds)
543
- return;
544
- const { before, after } = bounds;
545
- ctx2.size[before.index].size = before.max;
546
- ctx2.size[after.index].size = after.max;
547
- },
548
- expandStartPanel(ctx2, evt) {
549
- const bounds = getPanelBounds(ctx2);
550
- if (!bounds)
551
- return;
552
- const { before, after } = bounds;
553
- ctx2.size[before.index].size = before.up(evt.step);
554
- ctx2.size[after.index].size = after.down(evt.step);
555
- },
556
- shrinkStartPanel(ctx2, evt) {
557
- const bounds = getPanelBounds(ctx2);
558
- if (!bounds)
559
- return;
560
- const { before, after } = bounds;
561
- ctx2.size[before.index].size = before.down(evt.step);
562
- ctx2.size[after.index].size = after.up(evt.step);
563
- },
564
- resetStartPanel(ctx2, evt) {
565
- const bounds = getPanelBounds(ctx2, evt.id);
566
- if (!bounds)
567
- return;
568
- const { before, after } = bounds;
569
- ctx2.size[before.index].size = ctx2.initialSize[before.index].size;
570
- ctx2.size[after.index].size = ctx2.initialSize[after.index].size;
571
- },
572
- focusResizeHandle(ctx2) {
573
- domQuery.raf(() => {
574
- dom.getActiveHandleEl(ctx2)?.focus({ preventScroll: true });
575
- });
576
- },
577
- blurResizeHandle(ctx2) {
578
- domQuery.raf(() => {
579
- dom.getActiveHandleEl(ctx2)?.blur();
580
- });
581
- },
582
- setPreviousPanels(ctx2) {
583
- ctx2.previousPanels = ctx2.panels.slice();
584
- },
585
- setActiveResizeState(ctx2) {
586
- const panels = getPanelBounds(ctx2);
587
- if (!panels)
588
- return;
589
- const { before } = panels;
590
- ctx2.activeResizeState = {
591
- isAtMin: before.isAtMin,
592
- isAtMax: before.isAtMax
593
- };
594
- },
595
- setPointerValue(ctx2, evt) {
596
- const panels = getHandlePanels(ctx2);
597
- const bounds = getHandleBounds(ctx2);
598
- if (!panels || !bounds)
599
- return;
600
- const rootEl = dom.getRootEl(ctx2);
601
- if (!rootEl)
602
- return;
603
- const relativePoint = domEvent.getRelativePoint(evt.point, rootEl);
604
- const percentValue = relativePoint.getPercentValue({
605
- dir: ctx2.dir,
606
- orientation: ctx2.orientation
607
- });
608
- let pointValue = percentValue * 100;
609
- ctx2.activeResizeState = {
610
- isAtMin: pointValue < bounds.min,
611
- isAtMax: pointValue > bounds.max
612
- };
613
- pointValue = clamp(pointValue, bounds.min, bounds.max);
614
- const { before, after } = panels;
615
- const offset = pointValue - before.end;
616
- ctx2.size[before.index].size = before.size + offset;
617
- ctx2.size[after.index].size = after.size - offset;
618
- }
619
- }
620
- }
621
- );
622
- }
623
-
624
- const props = types.createProps()([
625
- "dir",
626
- "getRootNode",
627
- "id",
628
- "ids",
629
- "onSizeChange",
630
- "onSizeChangeEnd",
631
- "orientation",
632
- "size"
633
- ]);
634
- const splitProps = utils.createSplitProps(props);
635
- const panelProps = types.createProps()(["id", "snapSize"]);
636
- const splitPanelProps = utils.createSplitProps(panelProps);
637
- const resizeTriggerProps = types.createProps()(["disabled", "id", "step"]);
638
- const splitResizeTriggerProps = utils.createSplitProps(resizeTriggerProps);
639
-
640
- exports.anatomy = anatomy;
641
- exports.connect = connect;
642
- exports.machine = machine;
643
- exports.panelProps = panelProps;
644
- exports.props = props;
645
- exports.resizeTriggerProps = resizeTriggerProps;
646
- exports.splitPanelProps = splitPanelProps;
647
- exports.splitProps = splitProps;
648
- exports.splitResizeTriggerProps = splitResizeTriggerProps;