@zag-js/splitter 0.2.5 → 0.2.7

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.js CHANGED
@@ -28,20 +28,15 @@ module.exports = __toCommonJS(src_exports);
28
28
 
29
29
  // src/splitter.anatomy.ts
30
30
  var import_anatomy = require("@zag-js/anatomy");
31
- var anatomy = (0, import_anatomy.createAnatomy)("splitter").parts(
32
- "root",
33
- "secondaryPane",
34
- "primaryPane",
35
- "toggleButton",
36
- "label",
37
- "splitter"
38
- );
31
+ var anatomy = (0, import_anatomy.createAnatomy)("splitter").parts("root", "panel", "toggleTrigger", "resizeTrigger");
39
32
  var parts = anatomy.build();
40
33
 
41
- // ../../utilities/dom/dist/index.mjs
34
+ // ../../utilities/dom/src/attrs.ts
42
35
  var dataAttr = (guard) => {
43
36
  return guard ? "" : void 0;
44
37
  };
38
+
39
+ // ../../utilities/core/src/functions.ts
45
40
  var runIfFn = (v, ...a) => {
46
41
  const res = typeof v === "function" ? v(...a) : v;
47
42
  return res != null ? res : void 0;
@@ -51,9 +46,22 @@ var callAll = (...fns) => (...a) => {
51
46
  fn == null ? void 0 : fn(...a);
52
47
  });
53
48
  };
49
+
50
+ // ../../utilities/core/src/guard.ts
54
51
  var isArray = (v) => Array.isArray(v);
55
52
  var isObject = (v) => !(v == null || typeof v !== "object" || isArray(v));
56
53
  var hasProp = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop);
54
+
55
+ // ../../utilities/core/src/object.ts
56
+ function compact(obj) {
57
+ if (obj === void 0)
58
+ return obj;
59
+ return Object.fromEntries(
60
+ Object.entries(obj).filter(([, value]) => value !== void 0).map(([key, value]) => [key, isObject(value) ? compact(value) : value])
61
+ );
62
+ }
63
+
64
+ // ../../utilities/dom/src/platform.ts
57
65
  var isDom = () => typeof window !== "undefined";
58
66
  function getPlatform() {
59
67
  var _a;
@@ -65,6 +73,8 @@ var isTouchDevice = () => isDom() && !!navigator.maxTouchPoints;
65
73
  var isMac = () => pt(/^Mac/) && !isTouchDevice;
66
74
  var isApple = () => pt(/mac|iphone|ipad|ipod/i);
67
75
  var isIos = () => isApple() && !isMac();
76
+
77
+ // ../../utilities/dom/src/query.ts
68
78
  function isDocument(el) {
69
79
  return el.nodeType === Node.DOCUMENT_NODE;
70
80
  }
@@ -91,37 +101,23 @@ function defineDomHelpers(helpers) {
91
101
  return (_a = dom2.getDoc(ctx).defaultView) != null ? _a : window;
92
102
  },
93
103
  getActiveElement: (ctx) => dom2.getDoc(ctx).activeElement,
94
- getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id),
95
- createEmitter: (ctx, target) => {
96
- const win = dom2.getWin(ctx);
97
- return function emit(evt, detail, options) {
98
- const { bubbles = true, cancelable, composed = true } = options != null ? options : {};
99
- const eventName = `zag:${evt}`;
100
- const init = { bubbles, cancelable, composed, detail };
101
- const event = new win.CustomEvent(eventName, init);
102
- target.dispatchEvent(event);
103
- };
104
- },
105
- createListener: (target) => {
106
- return function listen(evt, handler) {
107
- const eventName = `zag:${evt}`;
108
- const listener = (e) => handler(e);
109
- target.addEventListener(eventName, listener);
110
- return () => target.removeEventListener(eventName, listener);
111
- };
112
- }
104
+ getById: (ctx, id) => dom2.getRootNode(ctx).getElementById(id)
113
105
  };
114
106
  return {
115
107
  ...dom2,
116
108
  ...helpers
117
109
  };
118
110
  }
111
+
112
+ // ../../utilities/dom/src/event.ts
119
113
  var supportsPointerEvent = () => isDom() && window.onpointerdown === null;
120
114
  var supportsTouchEvent = () => isDom() && window.ontouchstart === null;
121
115
  var supportsMouseEvent = () => isDom() && window.onmousedown === null;
122
116
  var isMouseEvent = (v) => isObject(v) && hasProp(v, "button");
123
117
  var isTouchEvent = (v) => isObject(v) && hasProp(v, "touches");
124
118
  var isLeftClick = (v) => v.button === 0;
119
+
120
+ // ../../utilities/dom/src/get-element-offset.ts
125
121
  function getElementOffset(element) {
126
122
  let left = 0;
127
123
  let top = 0;
@@ -144,12 +140,32 @@ function getElementOffset(element) {
144
140
  left
145
141
  };
146
142
  }
143
+
144
+ // ../../utilities/dom/src/get-point-relative-to-element.ts
147
145
  function getPointRelativeToNode(point, element) {
148
146
  const offset = getElementOffset(element);
149
147
  const x = point.x - offset.left;
150
148
  const y = point.y - offset.top;
151
149
  return { x, y };
152
150
  }
151
+ var clampPercent = (value) => Math.max(0, Math.min(100, value));
152
+ function getPointPercentRelativeToNode(point, element) {
153
+ const relativePoint = getPointRelativeToNode(point, element);
154
+ const x = relativePoint.x / element.offsetWidth * 100;
155
+ const y = relativePoint.y / element.offsetHeight * 100;
156
+ return { x: clampPercent(x), y: clampPercent(y) };
157
+ }
158
+ function normalizePointValue(point, options) {
159
+ const { dir = "ltr", orientation = "horizontal" } = options;
160
+ const { x, y } = point;
161
+ let result = { x, y };
162
+ if (orientation === "horizontal" && dir === "rtl") {
163
+ result = { x: 100 - x, y };
164
+ }
165
+ return orientation === "horizontal" ? result.x : result.y;
166
+ }
167
+
168
+ // ../../utilities/dom/src/keyboard-event.ts
153
169
  var rtlKeyMap = {
154
170
  ArrowLeft: "ArrowRight",
155
171
  ArrowRight: "ArrowLeft"
@@ -185,10 +201,12 @@ function getEventStep(event) {
185
201
  return isSkipKey ? 10 : 1;
186
202
  }
187
203
  }
204
+
205
+ // ../../utilities/dom/src/listener.ts
188
206
  var isRef = (v) => hasProp(v, "current");
189
- var fallback2 = { pageX: 0, pageY: 0, clientX: 0, clientY: 0 };
207
+ var fallback = { pageX: 0, pageY: 0, clientX: 0, clientY: 0 };
190
208
  function extractInfo(event, type = "page") {
191
- const point = isTouchEvent(event) ? event.touches[0] || event.changedTouches[0] || fallback2 : event;
209
+ const point = isTouchEvent(event) ? event.touches[0] || event.changedTouches[0] || fallback : event;
192
210
  return {
193
211
  point: {
194
212
  x: point[`${type}X`],
@@ -249,6 +267,8 @@ function getEventName(evt) {
249
267
  return mouseEventNames[evt];
250
268
  return evt;
251
269
  }
270
+
271
+ // ../../utilities/dom/src/next-tick.ts
252
272
  function nextTick(fn) {
253
273
  const set = /* @__PURE__ */ new Set();
254
274
  function raf2(fn2) {
@@ -268,6 +288,14 @@ function raf(fn) {
268
288
  globalThis.cancelAnimationFrame(id);
269
289
  };
270
290
  }
291
+
292
+ // ../../utilities/dom/src/nodelist.ts
293
+ function queryAll(root, selector) {
294
+ var _a;
295
+ return Array.from((_a = root == null ? void 0 : root.querySelectorAll(selector)) != null ? _a : []);
296
+ }
297
+
298
+ // ../../utilities/dom/src/text-selection.ts
271
299
  var state = "default";
272
300
  var savedUserSelect = "";
273
301
  var modifiedElementMap = /* @__PURE__ */ new WeakMap();
@@ -315,6 +343,8 @@ function restoreTextSelection({ target, doc } = {}) {
315
343
  }
316
344
  }
317
345
  }
346
+
347
+ // ../../utilities/dom/src/pointer-event.ts
318
348
  var THRESHOLD = 5;
319
349
  function trackPointerMove(doc, opts) {
320
350
  const { onPointerMove, onPointerUp } = opts;
@@ -340,273 +370,339 @@ function trackPointerMove(doc, opts) {
340
370
 
341
371
  // src/splitter.dom.ts
342
372
  var dom = defineDomHelpers({
343
- getRootId: (ctx) => {
344
- var _a, _b;
345
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.root) != null ? _b : `splitter:${ctx.id}`;
346
- },
347
- getSplitterId: (ctx) => {
348
- var _a, _b;
349
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.splitter) != null ? _b : `splitter:${ctx.id}:splitter`;
350
- },
351
- getToggleButtonId: (ctx) => {
352
- var _a, _b;
353
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.toggleBtn) != null ? _b : `splitter:${ctx.id}:toggle-btn`;
354
- },
355
- getLabelId: (ctx) => {
356
- var _a, _b;
357
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.label) != null ? _b : `splitter:${ctx.id}:label`;
358
- },
359
- getPrimaryPaneId: (ctx) => {
360
- var _a, _b;
361
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.primaryPane) != null ? _b : `splitter:${ctx.id}:primary`;
362
- },
363
- getSecondaryPaneId: (ctx) => {
364
- var _a, _b;
365
- return (_b = (_a = ctx.ids) == null ? void 0 : _a.secondaryPane) != null ? _b : `splitter:${ctx.id}:secondary`;
366
- },
367
- getSplitterEl: (ctx) => dom.getById(ctx, dom.getSplitterId(ctx)),
368
- getPrimaryPaneEl: (ctx) => dom.getById(ctx, dom.getPrimaryPaneId(ctx)),
373
+ getRootId: (ctx) => `splitter:${ctx.id}`,
374
+ getResizeTriggerId: (ctx, id) => `splitter:${ctx.id}:splitter:${id}`,
375
+ getToggleTriggerId: (ctx) => `splitter:${ctx.id}:toggle-btn`,
376
+ getLabelId: (ctx) => `splitter:${ctx.id}:label`,
377
+ getPanelId: (ctx, id) => `splitter:${ctx.id}:panel:${id}`,
378
+ globalCursorId: (ctx) => `splitter:${ctx.id}:global-cursor`,
379
+ getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
380
+ getResizeTriggerEl: (ctx, id) => dom.getById(ctx, dom.getResizeTriggerId(ctx, id)),
381
+ getPanelEl: (ctx, id) => dom.getById(ctx, dom.getPanelId(ctx, id)),
369
382
  getCursor(ctx) {
370
- if (ctx.disabled || ctx.fixed)
371
- return "default";
372
383
  const x = ctx.isHorizontal;
373
384
  let cursor = x ? "col-resize" : "row-resize";
374
- if (ctx.isAtMin)
385
+ if (ctx.activeResizeState.isAtMin)
375
386
  cursor = x ? "e-resize" : "s-resize";
376
- if (ctx.isAtMax)
387
+ if (ctx.activeResizeState.isAtMax)
377
388
  cursor = x ? "w-resize" : "n-resize";
378
389
  return cursor;
390
+ },
391
+ getPanelStyle(ctx, id) {
392
+ var _a, _b;
393
+ const flexGrow = (_b = (_a = ctx.panels.find((panel) => panel.id === id)) == null ? void 0 : _a.size) != null ? _b : "0";
394
+ return {
395
+ flexBasis: 0,
396
+ flexGrow,
397
+ flexShrink: 1,
398
+ overflow: "hidden"
399
+ };
400
+ },
401
+ getActiveHandleEl(ctx) {
402
+ const activeId = ctx.activeResizeId;
403
+ if (activeId == null)
404
+ return;
405
+ return dom.getById(ctx, dom.getResizeTriggerId(ctx, activeId));
406
+ },
407
+ getResizeTriggerEls(ctx) {
408
+ const ownerId = CSS.escape(dom.getRootId(ctx));
409
+ return queryAll(dom.getRootEl(ctx), `[role=separator][data-ownedby='${ownerId}']`);
410
+ },
411
+ setupGlobalCursor(ctx) {
412
+ const styleEl = dom.getById(ctx, dom.globalCursorId(ctx));
413
+ const textContent = `* { cursor: ${dom.getCursor(ctx)} !important; }`;
414
+ if (styleEl) {
415
+ styleEl.textContent = textContent;
416
+ } else {
417
+ const style = dom.getDoc(ctx).createElement("style");
418
+ style.id = dom.globalCursorId(ctx);
419
+ style.textContent = textContent;
420
+ dom.getDoc(ctx).head.appendChild(style);
421
+ }
422
+ },
423
+ removeGlobalCursor(ctx) {
424
+ var _a;
425
+ (_a = dom.getById(ctx, dom.globalCursorId(ctx))) == null ? void 0 : _a.remove();
379
426
  }
380
427
  });
381
428
 
429
+ // src/splitter.utils.ts
430
+ function validateSize(key, size) {
431
+ if (Math.floor(size) > 100) {
432
+ throw new Error(`Total ${key} of panels cannot be greater than 100`);
433
+ }
434
+ }
435
+ function getNormalizedPanels(ctx) {
436
+ let numOfPanelsWithoutSize = 0;
437
+ let totalSize = 0;
438
+ let totalMinSize = 0;
439
+ const panels = ctx.size.map((panel) => {
440
+ var _a, _b;
441
+ const minSize = (_a = panel.minSize) != null ? _a : 10;
442
+ const maxSize = (_b = panel.maxSize) != null ? _b : 100;
443
+ totalMinSize += minSize;
444
+ if (panel.size == null) {
445
+ numOfPanelsWithoutSize++;
446
+ } else {
447
+ totalSize += panel.size;
448
+ }
449
+ return {
450
+ ...panel,
451
+ minSize,
452
+ maxSize
453
+ };
454
+ });
455
+ validateSize("minSize", totalMinSize);
456
+ validateSize("size", totalSize);
457
+ let end = 0;
458
+ let remainingSize = 0;
459
+ const result = panels.map((panel) => {
460
+ let start = end;
461
+ if (panel.size != null) {
462
+ end += panel.size;
463
+ remainingSize = panel.size - panel.minSize;
464
+ return {
465
+ ...panel,
466
+ start,
467
+ end,
468
+ remainingSize
469
+ };
470
+ }
471
+ const size = (100 - totalSize) / numOfPanelsWithoutSize;
472
+ end += size;
473
+ remainingSize = size - panel.minSize;
474
+ return { ...panel, size, start, end, remainingSize };
475
+ });
476
+ return result;
477
+ }
478
+ function getHandlePanels(ctx, id = ctx.activeResizeId) {
479
+ var _a;
480
+ const [beforeId, afterId] = (_a = id == null ? void 0 : id.split(":")) != null ? _a : [];
481
+ if (!beforeId || !afterId)
482
+ return;
483
+ const beforeIndex = ctx.previousPanels.findIndex((panel) => panel.id === beforeId);
484
+ const afterIndex = ctx.previousPanels.findIndex((panel) => panel.id === afterId);
485
+ if (beforeIndex === -1 || afterIndex === -1)
486
+ return;
487
+ const before = ctx.previousPanels[beforeIndex];
488
+ const after = ctx.previousPanels[afterIndex];
489
+ return {
490
+ before: {
491
+ ...before,
492
+ index: beforeIndex
493
+ },
494
+ after: {
495
+ ...after,
496
+ index: afterIndex
497
+ }
498
+ };
499
+ }
500
+ function getHandleBounds(ctx, id = ctx.activeResizeId) {
501
+ const panels = getHandlePanels(ctx, id);
502
+ if (!panels)
503
+ return;
504
+ const { before, after } = panels;
505
+ return {
506
+ min: Math.max(before.start + before.minSize, after.end - after.maxSize),
507
+ max: Math.min(after.end - after.minSize, before.maxSize + before.start)
508
+ };
509
+ }
510
+ function getPanelBounds(ctx, id) {
511
+ const bounds = getHandleBounds(ctx, id);
512
+ const panels = getHandlePanels(ctx, id);
513
+ if (!bounds || !panels)
514
+ return;
515
+ const { before, after } = panels;
516
+ const beforeMin = Math.abs(before.start - bounds.min);
517
+ const afterMin = after.size + (before.size - beforeMin);
518
+ const beforeMax = Math.abs(before.start - bounds.max);
519
+ const afterMax = after.size - (beforeMax - before.size);
520
+ return {
521
+ before: {
522
+ index: before.index,
523
+ min: beforeMin,
524
+ max: beforeMax,
525
+ isAtMin: beforeMin === before.size,
526
+ isAtMax: beforeMax === before.size,
527
+ up(step) {
528
+ return Math.min(before.size + step, beforeMax);
529
+ },
530
+ down(step) {
531
+ return Math.max(before.size - step, beforeMin);
532
+ }
533
+ },
534
+ after: {
535
+ index: after.index,
536
+ min: afterMin,
537
+ max: afterMax,
538
+ isAtMin: afterMin === after.size,
539
+ isAtMax: afterMax === after.size,
540
+ up(step) {
541
+ return Math.min(after.size + step, afterMin);
542
+ },
543
+ down(step) {
544
+ return Math.max(after.size - step, afterMax);
545
+ }
546
+ }
547
+ };
548
+ }
549
+ function clamp(value, min, max) {
550
+ return Math.min(Math.max(value, min), max);
551
+ }
552
+
382
553
  // src/splitter.connect.ts
383
554
  function connect(state2, send, normalize) {
384
555
  const isHorizontal = state2.context.isHorizontal;
385
- const isDisabled = state2.context.disabled;
386
556
  const isFocused = state2.hasTag("focus");
387
557
  const isDragging = state2.matches("dragging");
388
- const isAtMin = state2.context.isAtMin;
389
- const isAtMax = state2.context.isAtMax;
390
- const min = state2.context.min;
391
- const max = state2.context.max;
392
- const value = state2.context.value;
393
558
  return {
394
- isCollapsed: isAtMin,
395
- isExpanded: isAtMax,
396
559
  isFocused,
397
560
  isDragging,
398
- value,
399
- collapse() {
400
- send("COLLAPSE");
561
+ bounds: getHandleBounds(state2.context),
562
+ collapse(id) {
563
+ send({ type: "COLLAPSE", id });
401
564
  },
402
- expand() {
403
- send("EXPAND");
565
+ expand(id) {
566
+ send({ type: "EXPAND", id });
404
567
  },
405
- toggle() {
406
- send("TOGGLE");
568
+ toggle(id) {
569
+ send({ type: "TOGGLE", id });
407
570
  },
408
- setSize(size) {
409
- send({ type: "SET_SIZE", size });
571
+ setSize(id, size) {
572
+ send({ type: "SET_SIZE", id, size });
410
573
  },
411
574
  rootProps: normalize.element({
412
575
  ...parts.root.attrs,
413
576
  "data-orientation": state2.context.orientation,
414
- "data-disabled": dataAttr(isDisabled),
415
577
  id: dom.getRootId(state2.context),
578
+ dir: state2.context.dir,
416
579
  style: {
417
580
  display: "flex",
418
- flex: "1 1 0%",
419
- flexDirection: isHorizontal ? "row" : "column"
420
- }
421
- }),
422
- secondaryPaneProps: normalize.element({
423
- ...parts.secondaryPane.attrs,
424
- "data-disabled": dataAttr(isDisabled),
425
- id: dom.getSecondaryPaneId(state2.context),
426
- style: {
427
- height: isHorizontal ? "100%" : "auto",
428
- width: isHorizontal ? "auto" : "100%",
429
- flex: "1 1 auto",
430
- position: "relative"
581
+ flexDirection: isHorizontal ? "row" : "column",
582
+ height: "100%",
583
+ width: "100%",
584
+ overflow: "hidden"
431
585
  }
432
586
  }),
433
- primaryPaneProps: normalize.element({
434
- ...parts.primaryPane.attrs,
435
- id: dom.getPrimaryPaneId(state2.context),
436
- "data-disabled": dataAttr(isDisabled),
437
- "data-state": isAtMax ? "at-max" : isAtMin ? "at-min" : "between",
438
- style: {
439
- visibility: "visible",
440
- flex: `0 0 ${value}px`,
441
- position: "relative",
442
- userSelect: isDragging ? "none" : "auto",
443
- ...isHorizontal ? { minWidth: `${min}px`, maxWidth: `${max}px` } : { minHeight: `${min}px`, maxHeight: `${max}px` }
444
- }
445
- }),
446
- toggleButtonProps: normalize.element({
447
- ...parts.toggleButton.attrs,
448
- id: dom.getToggleButtonId(state2.context),
449
- "aria-label": state2.context.isAtMin ? "Expand Primary Pane" : "Collapse Primary Pane",
450
- onClick() {
451
- send("TOGGLE");
452
- }
453
- }),
454
- labelProps: normalize.element({
455
- ...parts.label.attrs,
456
- id: dom.getLabelId(state2.context)
457
- }),
458
- splitterProps: normalize.element({
459
- ...parts.splitter.attrs,
460
- id: dom.getSplitterId(state2.context),
461
- role: "separator",
462
- tabIndex: isDisabled ? void 0 : 0,
463
- "aria-valuenow": value,
464
- "aria-valuemin": min,
465
- "aria-valuemax": max,
466
- "aria-orientation": state2.context.orientation,
467
- "aria-labelledby": dom.getLabelId(state2.context),
468
- "aria-controls": dom.getPrimaryPaneId(state2.context),
469
- "data-orientation": state2.context.orientation,
470
- "data-focus": dataAttr(isFocused),
471
- "data-disabled": dataAttr(isDisabled),
472
- style: {
473
- touchAction: "none",
474
- userSelect: "none",
475
- WebkitUserSelect: "none",
476
- msUserSelect: "none",
477
- flex: "0 0 auto",
478
- cursor: dom.getCursor(state2.context),
479
- minHeight: isHorizontal ? "0px" : void 0,
480
- minWidth: isHorizontal ? void 0 : "0px"
481
- },
482
- onPointerDown(event) {
483
- if (isDisabled) {
484
- event.preventDefault();
485
- return;
486
- }
487
- send("POINTER_DOWN");
488
- event.preventDefault();
489
- event.stopPropagation();
490
- },
491
- onPointerOver() {
492
- if (isDisabled)
493
- return;
494
- send("POINTER_OVER");
495
- },
496
- onPointerLeave() {
497
- if (isDisabled)
498
- return;
499
- send("POINTER_LEAVE");
500
- },
501
- onBlur() {
502
- send("BLUR");
503
- },
504
- onFocus() {
505
- send("FOCUS");
506
- },
507
- onDoubleClick() {
508
- if (isDisabled)
509
- return;
510
- send("DOUBLE_CLICK");
511
- },
512
- onKeyDown(event) {
513
- if (isDisabled)
514
- return;
515
- const step = getEventStep(event) * state2.context.step;
516
- const keyMap = {
517
- ArrowUp() {
518
- send({ type: "ARROW_UP", step });
519
- },
520
- ArrowDown() {
521
- send({ type: "ARROW_DOWN", step });
522
- },
523
- ArrowLeft() {
524
- send({ type: "ARROW_LEFT", step });
525
- },
526
- ArrowRight() {
527
- send({ type: "ARROW_RIGHT", step });
528
- },
529
- Home() {
530
- send("HOME");
531
- },
532
- End() {
533
- send("END");
587
+ getPanelProps(props) {
588
+ const { id } = props;
589
+ return normalize.element({
590
+ ...parts.panel.attrs,
591
+ dir: state2.context.dir,
592
+ id: dom.getPanelId(state2.context, id),
593
+ "data-ownedby": dom.getRootId(state2.context),
594
+ style: dom.getPanelStyle(state2.context, id)
595
+ });
596
+ },
597
+ getResizeTriggerState(id) {
598
+ const ids = id.split(":");
599
+ const panelIds = ids.map((id2) => dom.getPanelId(state2.context, id2));
600
+ const panels = getHandleBounds(state2.context, id);
601
+ return {
602
+ isFocused: state2.context.activeResizeId === id && isFocused,
603
+ panelIds,
604
+ min: panels == null ? void 0 : panels.min,
605
+ max: panels == null ? void 0 : panels.max,
606
+ value: 0
607
+ };
608
+ },
609
+ getResizeTriggerProps(props) {
610
+ const { id, disabled, step = 1 } = props;
611
+ const triggerState = this.getResizeTriggerState(id);
612
+ return normalize.element({
613
+ ...parts.resizeTrigger.attrs,
614
+ dir: state2.context.dir,
615
+ id: dom.getResizeTriggerId(state2.context, id),
616
+ role: "separator",
617
+ "data-ownedby": dom.getRootId(state2.context),
618
+ tabIndex: disabled ? void 0 : 0,
619
+ "aria-valuenow": triggerState.value,
620
+ "aria-valuemin": triggerState.min,
621
+ "aria-valuemax": triggerState.max,
622
+ "data-orientation": state2.context.orientation,
623
+ "aria-orientation": state2.context.orientation,
624
+ "aria-controls": triggerState.panelIds.join(" "),
625
+ "data-focus": dataAttr(triggerState.isFocused),
626
+ "data-disabled": dataAttr(disabled),
627
+ style: {
628
+ touchAction: "none",
629
+ userSelect: "none",
630
+ flex: "0 0 auto",
631
+ pointerEvents: isDragging && !triggerState.isFocused ? "none" : void 0,
632
+ cursor: isHorizontal ? "col-resize" : "row-resize",
633
+ [isHorizontal ? "minHeight" : "minWidth"]: "0"
634
+ },
635
+ onPointerDown(event) {
636
+ if (disabled) {
637
+ event.preventDefault();
638
+ return;
534
639
  }
535
- };
536
- const key = getEventKey(event, state2.context);
537
- const exec = keyMap[key];
538
- if (exec) {
539
- exec(event);
640
+ send({ type: "POINTER_DOWN", id });
540
641
  event.preventDefault();
642
+ event.stopPropagation();
643
+ },
644
+ onPointerOver() {
645
+ if (disabled)
646
+ return;
647
+ send({ type: "POINTER_OVER", id });
648
+ },
649
+ onPointerLeave() {
650
+ if (disabled)
651
+ return;
652
+ send({ type: "POINTER_LEAVE", id });
653
+ },
654
+ onBlur() {
655
+ send("BLUR");
656
+ },
657
+ onFocus() {
658
+ send({ type: "FOCUS", id });
659
+ },
660
+ onDoubleClick() {
661
+ if (disabled)
662
+ return;
663
+ send({ type: "DOUBLE_CLICK", id });
664
+ },
665
+ onKeyDown(event) {
666
+ if (disabled)
667
+ return;
668
+ const moveStep = getEventStep(event) * step;
669
+ const keyMap = {
670
+ Enter() {
671
+ send("ENTER");
672
+ },
673
+ ArrowUp() {
674
+ send({ type: "ARROW_UP", step: moveStep });
675
+ },
676
+ ArrowDown() {
677
+ send({ type: "ARROW_DOWN", step: moveStep });
678
+ },
679
+ ArrowLeft() {
680
+ send({ type: "ARROW_LEFT", step: moveStep });
681
+ },
682
+ ArrowRight() {
683
+ send({ type: "ARROW_RIGHT", step: moveStep });
684
+ },
685
+ Home() {
686
+ send("HOME");
687
+ },
688
+ End() {
689
+ send("END");
690
+ }
691
+ };
692
+ const key = getEventKey(event, state2.context);
693
+ const exec = keyMap[key];
694
+ if (exec) {
695
+ exec(event);
696
+ event.preventDefault();
697
+ }
541
698
  }
542
- }
543
- })
699
+ });
700
+ }
544
701
  };
545
702
  }
546
703
 
547
704
  // src/splitter.machine.ts
548
705
  var import_core = require("@zag-js/core");
549
-
550
- // ../../utilities/number/dist/index.mjs
551
- function round(v, t) {
552
- let num = valueOf(v);
553
- const p = 10 ** (t != null ? t : 10);
554
- num = Math.round(num * p) / p;
555
- return t ? num.toFixed(t) : v.toString();
556
- }
557
- function clamp(v, o) {
558
- return Math.min(Math.max(valueOf(v), o.min), o.max);
559
- }
560
- function countDecimals(value) {
561
- if (!Number.isFinite(value))
562
- return 0;
563
- let e = 1, p = 0;
564
- while (Math.round(value * e) / e !== value) {
565
- e *= 10;
566
- p += 1;
567
- }
568
- return p;
569
- }
570
- var increment = (v, s) => decimalOperation(valueOf(v), "+", s);
571
- var decrement = (v, s) => decimalOperation(valueOf(v), "-", s);
572
- function snapToStep(value, step) {
573
- const num = valueOf(value);
574
- const p = countDecimals(step);
575
- const v = Math.round(num / step) * step;
576
- return round(v, p);
577
- }
578
- function valueOf(v) {
579
- if (typeof v === "number")
580
- return v;
581
- const num = parseFloat(v.toString().replace(/[^\w.-]+/g, ""));
582
- return !Number.isNaN(num) ? num : 0;
583
- }
584
- function decimalOperation(a, op, b) {
585
- let result = op === "+" ? a + b : a - b;
586
- if (a % 1 !== 0 || b % 1 !== 0) {
587
- const multiplier = 10 ** Math.max(countDecimals(a), countDecimals(b));
588
- a = Math.round(a * multiplier);
589
- b = Math.round(b * multiplier);
590
- result = op === "+" ? a + b : a - b;
591
- result /= multiplier;
592
- }
593
- return result;
594
- }
595
- var nf = new Intl.NumberFormat("en-US", { style: "decimal", maximumFractionDigits: 20 });
596
-
597
- // ../../utilities/core/dist/index.mjs
598
- var isArray2 = (v) => Array.isArray(v);
599
- var isObject2 = (v) => !(v == null || typeof v !== "object" || isArray2(v));
600
- function compact(obj) {
601
- if (obj === void 0)
602
- return obj;
603
- return Object.fromEntries(
604
- Object.entries(obj).filter(([, value]) => value !== void 0).map(([key, value]) => [key, isObject2(value) ? compact(value) : value])
605
- );
606
- }
607
-
608
- // src/splitter.machine.ts
609
- var { not } = import_core.guards;
610
706
  function machine(userContext) {
611
707
  const ctx = compact(userContext);
612
708
  return (0, import_core.createMachine)(
@@ -615,32 +711,38 @@ function machine(userContext) {
615
711
  initial: "unknown",
616
712
  context: {
617
713
  orientation: "horizontal",
618
- min: 224,
619
- max: 340,
620
- step: 1,
621
- value: 256,
622
- snapOffset: 0,
714
+ activeResizeId: null,
715
+ previousPanels: [],
716
+ size: [],
717
+ initialSize: [],
718
+ activeResizeState: {
719
+ isAtMin: false,
720
+ isAtMax: false
721
+ },
623
722
  ...ctx
624
723
  },
724
+ created: ["setPreviousPanels", "setInitialSize"],
725
+ watch: {
726
+ size: ["setActiveResizeState"]
727
+ },
625
728
  computed: {
626
729
  isHorizontal: (ctx2) => ctx2.orientation === "horizontal",
627
- isAtMin: (ctx2) => ctx2.value === ctx2.min,
628
- isAtMax: (ctx2) => ctx2.value === ctx2.max
730
+ panels: (ctx2) => getNormalizedPanels(ctx2)
629
731
  },
630
732
  on: {
631
733
  COLLAPSE: {
632
- actions: "setToMin"
734
+ actions: "setStartPanelToMin"
633
735
  },
634
736
  EXPAND: {
635
- actions: "setToMax"
737
+ actions: "setStartPanelToMax"
636
738
  },
637
739
  TOGGLE: [
638
740
  {
639
- guard: "isCollapsed",
640
- actions: "setToMax"
741
+ guard: "isStartPanelAtMin",
742
+ actions: "setStartPanelToMax"
641
743
  },
642
744
  {
643
- actions: "setToMin"
745
+ actions: "setStartPanelToMin"
644
746
  }
645
747
  ]
646
748
  },
@@ -651,13 +753,19 @@ function machine(userContext) {
651
753
  }
652
754
  },
653
755
  idle: {
756
+ entry: ["clearActiveHandleId"],
654
757
  on: {
655
758
  POINTER_OVER: {
656
- guard: not("isFixed"),
657
- target: "hover:temp"
759
+ target: "hover:temp",
760
+ actions: ["setActiveHandleId"]
761
+ },
762
+ FOCUS: {
763
+ target: "focused",
764
+ actions: ["setActiveHandleId"]
658
765
  },
659
- POINTER_LEAVE: "idle",
660
- FOCUS: "focused"
766
+ DOUBLE_CLICK: {
767
+ actions: ["resetStartPanel", "setPreviousPanels"]
768
+ }
661
769
  }
662
770
  },
663
771
  "hover:temp": {
@@ -667,7 +775,7 @@ function machine(userContext) {
667
775
  on: {
668
776
  POINTER_DOWN: {
669
777
  target: "dragging",
670
- actions: ["invokeOnChangeStart"]
778
+ actions: ["setActiveHandleId", "invokeOnResizeStart"]
671
779
  },
672
780
  POINTER_LEAVE: "idle"
673
781
  }
@@ -677,7 +785,7 @@ function machine(userContext) {
677
785
  on: {
678
786
  POINTER_DOWN: {
679
787
  target: "dragging",
680
- actions: ["invokeOnChangeStart"]
788
+ actions: ["invokeOnResizeStart"]
681
789
  },
682
790
  POINTER_LEAVE: "idle"
683
791
  }
@@ -688,57 +796,50 @@ function machine(userContext) {
688
796
  BLUR: "idle",
689
797
  POINTER_DOWN: {
690
798
  target: "dragging",
691
- actions: ["invokeOnChangeStart"]
799
+ actions: ["setActiveHandleId", "invokeOnResizeStart"]
692
800
  },
693
801
  ARROW_LEFT: {
694
802
  guard: "isHorizontal",
695
- actions: "decrement"
803
+ actions: ["shrinkStartPanel", "setPreviousPanels"]
696
804
  },
697
805
  ARROW_RIGHT: {
698
806
  guard: "isHorizontal",
699
- actions: "increment"
807
+ actions: ["expandStartPanel", "setPreviousPanels"]
700
808
  },
701
809
  ARROW_UP: {
702
810
  guard: "isVertical",
703
- actions: "increment"
811
+ actions: ["shrinkStartPanel", "setPreviousPanels"]
704
812
  },
705
813
  ARROW_DOWN: {
706
814
  guard: "isVertical",
707
- actions: "decrement"
815
+ actions: ["expandStartPanel", "setPreviousPanels"]
708
816
  },
709
817
  ENTER: [
710
818
  {
711
- guard: "isCollapsed",
712
- actions: "setToMin"
819
+ guard: "isStartPanelAtMax",
820
+ actions: ["setStartPanelToMin", "setPreviousPanels"]
713
821
  },
714
- { actions: "setToMin" }
822
+ { actions: ["setStartPanelToMax", "setPreviousPanels"] }
715
823
  ],
716
824
  HOME: {
717
- actions: "setToMin"
825
+ actions: ["setStartPanelToMin", "setPreviousPanels"]
718
826
  },
719
827
  END: {
720
- actions: "setToMax"
721
- },
722
- DOUBLE_CLICK: [
723
- {
724
- guard: "isCollapsed",
725
- actions: "setToMax"
726
- },
727
- { actions: "setToMin" }
728
- ]
828
+ actions: ["setStartPanelToMax", "setPreviousPanels"]
829
+ }
729
830
  }
730
831
  },
731
832
  dragging: {
732
833
  tags: ["focus"],
733
- entry: "focusSplitter",
734
- activities: "trackPointerMove",
834
+ entry: "focusResizeHandle",
835
+ activities: ["trackPointerMove"],
735
836
  on: {
837
+ POINTER_MOVE: {
838
+ actions: ["setPointerValue", "setGlobalCursor"]
839
+ },
736
840
  POINTER_UP: {
737
841
  target: "focused",
738
- actions: ["invokeOnChangeEnd"]
739
- },
740
- POINTER_MOVE: {
741
- actions: "setPointerValue"
842
+ actions: ["invokeOnResizeEnd", "setPreviousPanels", "clearGlobalCursor", "blurResizeHandle"]
742
843
  }
743
844
  }
744
845
  }
@@ -751,70 +852,135 @@ function machine(userContext) {
751
852
  return trackPointerMove(doc, {
752
853
  onPointerMove(info) {
753
854
  send({ type: "POINTER_MOVE", point: info.point });
754
- doc.documentElement.style.cursor = dom.getCursor(ctx2);
755
855
  },
756
856
  onPointerUp() {
757
857
  send("POINTER_UP");
758
- doc.documentElement.style.cursor = "";
759
858
  }
760
859
  });
761
860
  }
762
861
  },
763
862
  guards: {
764
- isCollapsed: (ctx2) => ctx2.isAtMin,
863
+ isStartPanelAtMin: (ctx2) => ctx2.activeResizeState.isAtMin,
864
+ isStartPanelAtMax: (ctx2) => ctx2.activeResizeState.isAtMax,
765
865
  isHorizontal: (ctx2) => ctx2.isHorizontal,
766
- isVertical: (ctx2) => !ctx2.isHorizontal,
767
- isFixed: (ctx2) => !!ctx2.fixed
866
+ isVertical: (ctx2) => !ctx2.isHorizontal
768
867
  },
769
868
  delays: {
770
869
  HOVER_DELAY: 250
771
870
  },
772
871
  actions: {
773
- invokeOnChange(ctx2, evt) {
872
+ setGlobalCursor(ctx2) {
873
+ dom.setupGlobalCursor(ctx2);
874
+ },
875
+ clearGlobalCursor(ctx2) {
876
+ dom.removeGlobalCursor(ctx2);
877
+ },
878
+ invokeOnResize(ctx2) {
774
879
  var _a;
775
- if (evt.type !== "SETUP") {
776
- (_a = ctx2.onChange) == null ? void 0 : _a.call(ctx2, { value: ctx2.value });
777
- }
880
+ (_a = ctx2.onResize) == null ? void 0 : _a.call(ctx2, { size: ctx2.size, activeHandleId: ctx2.activeResizeId });
778
881
  },
779
- invokeOnChangeStart(ctx2) {
882
+ invokeOnResizeStart(ctx2) {
780
883
  var _a;
781
- (_a = ctx2.onChangeStart) == null ? void 0 : _a.call(ctx2, { value: ctx2.value });
884
+ (_a = ctx2.onResizeStart) == null ? void 0 : _a.call(ctx2, { size: ctx2.size, activeHandleId: ctx2.activeResizeId });
782
885
  },
783
- invokeOnChangeEnd(ctx2) {
886
+ invokeOnResizeEnd(ctx2) {
784
887
  var _a;
785
- (_a = ctx2.onChangeEnd) == null ? void 0 : _a.call(ctx2, { value: ctx2.value });
888
+ (_a = ctx2.onResizeEnd) == null ? void 0 : _a.call(ctx2, { size: ctx2.size, activeHandleId: ctx2.activeResizeId });
889
+ },
890
+ setActiveHandleId(ctx2, evt) {
891
+ ctx2.activeResizeId = evt.id;
892
+ },
893
+ clearActiveHandleId(ctx2) {
894
+ ctx2.activeResizeId = null;
895
+ },
896
+ setInitialSize(ctx2) {
897
+ ctx2.initialSize = ctx2.panels.slice().map((panel) => ({
898
+ id: panel.id,
899
+ size: panel.size
900
+ }));
901
+ },
902
+ setStartPanelToMin(ctx2) {
903
+ const bounds = getPanelBounds(ctx2);
904
+ if (!bounds)
905
+ return;
906
+ const { before, after } = bounds;
907
+ ctx2.size[before.index].size = before.min;
908
+ ctx2.size[after.index].size = after.min;
909
+ },
910
+ setStartPanelToMax(ctx2) {
911
+ const bounds = getPanelBounds(ctx2);
912
+ if (!bounds)
913
+ return;
914
+ const { before, after } = bounds;
915
+ ctx2.size[before.index].size = before.max;
916
+ ctx2.size[after.index].size = after.max;
786
917
  },
787
- setToMin(ctx2) {
788
- ctx2.value = ctx2.min;
918
+ expandStartPanel(ctx2, evt) {
919
+ const bounds = getPanelBounds(ctx2);
920
+ if (!bounds)
921
+ return;
922
+ const { before, after } = bounds;
923
+ ctx2.size[before.index].size = before.up(evt.step);
924
+ ctx2.size[after.index].size = after.down(evt.step);
789
925
  },
790
- setToMax(ctx2) {
791
- ctx2.value = ctx2.max;
926
+ shrinkStartPanel(ctx2, evt) {
927
+ const bounds = getPanelBounds(ctx2);
928
+ if (!bounds)
929
+ return;
930
+ const { before, after } = bounds;
931
+ ctx2.size[before.index].size = before.down(evt.step);
932
+ ctx2.size[after.index].size = after.up(evt.step);
792
933
  },
793
- increment(ctx2, evt) {
794
- ctx2.value = clamp(increment(ctx2.value, evt.step), ctx2);
934
+ resetStartPanel(ctx2, evt) {
935
+ const bounds = getPanelBounds(ctx2, evt.id);
936
+ if (!bounds)
937
+ return;
938
+ const { before, after } = bounds;
939
+ ctx2.size[before.index].size = ctx2.initialSize[before.index].size;
940
+ ctx2.size[after.index].size = ctx2.initialSize[after.index].size;
795
941
  },
796
- decrement(ctx2, evt) {
797
- ctx2.value = clamp(decrement(ctx2.value, evt.step), ctx2);
942
+ focusResizeHandle(ctx2) {
943
+ raf(() => {
944
+ var _a;
945
+ (_a = dom.getActiveHandleEl(ctx2)) == null ? void 0 : _a.focus();
946
+ });
798
947
  },
799
- focusSplitter(ctx2) {
948
+ blurResizeHandle(ctx2) {
800
949
  raf(() => {
801
950
  var _a;
802
- return (_a = dom.getSplitterEl(ctx2)) == null ? void 0 : _a.focus();
951
+ (_a = dom.getActiveHandleEl(ctx2)) == null ? void 0 : _a.blur();
803
952
  });
804
953
  },
954
+ setPreviousPanels(ctx2) {
955
+ ctx2.previousPanels = ctx2.panels.slice();
956
+ },
957
+ setActiveResizeState(ctx2) {
958
+ const panels = getPanelBounds(ctx2);
959
+ if (!panels)
960
+ return;
961
+ const { before } = panels;
962
+ ctx2.activeResizeState = {
963
+ isAtMin: before.isAtMin,
964
+ isAtMax: before.isAtMax
965
+ };
966
+ },
805
967
  setPointerValue(ctx2, evt) {
806
- const el = dom.getPrimaryPaneEl(ctx2);
807
- if (!el)
968
+ const panels = getHandlePanels(ctx2);
969
+ const bounds = getHandleBounds(ctx2);
970
+ const rootEl = dom.getRootEl(ctx2);
971
+ if (!panels || !rootEl || !bounds)
808
972
  return;
809
- const relativePoint = getPointRelativeToNode(evt.point, el);
810
- let currentPoint = ctx2.isHorizontal ? relativePoint.x : relativePoint.y;
811
- let value = parseFloat(snapToStep(clamp(currentPoint, ctx2), ctx2.step));
812
- if (Math.abs(value - ctx2.min) <= ctx2.snapOffset) {
813
- value = ctx2.min;
814
- } else if (Math.abs(value - ctx2.max) <= ctx2.snapOffset) {
815
- value = ctx2.max;
816
- }
817
- ctx2.value = value;
973
+ const percent = getPointPercentRelativeToNode(evt.point, rootEl);
974
+ let pointValue = normalizePointValue(percent, ctx2);
975
+ ctx2.activeResizeState = {
976
+ isAtMin: pointValue < bounds.min,
977
+ isAtMax: pointValue > bounds.max
978
+ };
979
+ pointValue = clamp(pointValue, bounds.min, bounds.max);
980
+ const { before, after } = panels;
981
+ const offset = pointValue - before.end;
982
+ ctx2.size[before.index].size = before.size + offset;
983
+ ctx2.size[after.index].size = after.size - offset;
818
984
  }
819
985
  }
820
986
  }