@destyler/splitter 0.0.3 → 0.0.5

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 CHANGED
@@ -1,1822 +1,18 @@
1
1
  'use strict';
2
2
 
3
- const vue = require('vue');
4
- const primitive = require('@destyler/primitive');
5
- const shared = require('@destyler/shared');
6
- const composition = require('@destyler/composition');
7
- const directives = require('@destyler/directives');
8
- const nonSecure = require('nanoid/non-secure');
9
-
10
- function useUniqueId(idFromParams = null) {
11
- if (!shared.isBrowser && !idFromParams)
12
- console.warn("DestylerSplitter component required `id` for SSR. Or you can wrap the component with `<ClientOnly>`.");
13
- return idFromParams ?? nonSecure.nanoid(6);
14
- }
15
-
16
- function assert(expectedCondition, message = "Assertion failed!") {
17
- if (!expectedCondition) {
18
- console.error(message);
19
- throw new Error(message);
20
- }
21
- }
22
-
23
- function getPanelGroupElement(id, rootElement = document) {
24
- if (!shared.isBrowser)
25
- return null;
26
- if (rootElement instanceof HTMLElement && rootElement?.dataset?.panelGroupId === id)
27
- return rootElement;
28
- const element = rootElement.querySelector(
29
- `[data-panel-group][data-panel-group-id="${id}"]`
30
- );
31
- if (element)
32
- return element;
33
- return null;
34
- }
35
- function getResizeHandleElement(id, scope = document) {
36
- if (!shared.isBrowser)
37
- return null;
38
- const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
39
- if (element)
40
- return element;
41
- return null;
42
- }
43
- function getResizeHandleElementIndex(groupId, id, scope = document) {
44
- if (!shared.isBrowser)
45
- return null;
46
- const handles = getResizeHandleElementsForGroup(groupId, scope);
47
- const index = handles.findIndex(
48
- (handle) => handle.getAttribute("data-panel-resize-handle-id") === id
49
- );
50
- return index ?? null;
51
- }
52
- function getResizeHandleElementsForGroup(groupId, scope = document) {
53
- if (!shared.isBrowser)
54
- return [];
55
- return Array.from(
56
- scope.querySelectorAll(
57
- `[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`
58
- )
59
- );
60
- }
61
- function getResizeHandlePanelIds(groupId, handleId, panelsArray, scope = document) {
62
- const handle = getResizeHandleElement(handleId, scope);
63
- const handles = getResizeHandleElementsForGroup(groupId, scope);
64
- const index = handle ? handles.indexOf(handle) : -1;
65
- const idBefore = panelsArray[index]?.id ?? null;
66
- const idAfter = panelsArray[index + 1]?.id ?? null;
67
- return [idBefore, idAfter];
68
- }
69
-
70
- function useWindowSplitterResizeHandlerBehavior({
71
- disabled,
72
- handleId,
73
- resizeHandler,
74
- panelGroupElement
75
- }) {
76
- vue.watchEffect((onCleanup) => {
77
- const _panelGroupElement = panelGroupElement.value;
78
- if (disabled.value || resizeHandler.value === null || _panelGroupElement === null)
79
- return;
80
- const handleElement = getResizeHandleElement(handleId, _panelGroupElement);
81
- if (handleElement == null)
82
- return;
83
- const onKeyDown = (event) => {
84
- if (event.defaultPrevented)
85
- return;
86
- switch (event.key) {
87
- case "ArrowDown":
88
- case "ArrowLeft":
89
- case "ArrowRight":
90
- case "ArrowUp":
91
- case "End":
92
- case "Home": {
93
- event.preventDefault();
94
- resizeHandler.value?.(event);
95
- break;
96
- }
97
- case "F6": {
98
- event.preventDefault();
99
- const groupId = handleElement.getAttribute("data-panel-group-id");
100
- assert(groupId);
101
- const handles = getResizeHandleElementsForGroup(
102
- groupId,
103
- _panelGroupElement
104
- );
105
- const index = getResizeHandleElementIndex(
106
- groupId,
107
- handleId,
108
- _panelGroupElement
109
- );
110
- assert(index !== null);
111
- const nextIndex = event.shiftKey ? index > 0 ? index - 1 : handles.length - 1 : index + 1 < handles.length ? index + 1 : 0;
112
- const nextHandle = handles[nextIndex];
113
- nextHandle.focus();
114
- break;
115
- }
116
- }
117
- };
118
- handleElement.addEventListener("keydown", onKeyDown);
119
- onCleanup(() => {
120
- handleElement.removeEventListener("keydown", onKeyDown);
121
- });
122
- });
123
- }
124
-
125
- let currentCursorStyle = null;
126
- let styleElement = null;
127
- function getCursorStyle(state, constraintFlags) {
128
- if (constraintFlags) {
129
- const horizontalMin = (constraintFlags & EXCEEDED_HORIZONTAL_MIN) !== 0;
130
- const horizontalMax = (constraintFlags & EXCEEDED_HORIZONTAL_MAX) !== 0;
131
- const verticalMin = (constraintFlags & EXCEEDED_VERTICAL_MIN) !== 0;
132
- const verticalMax = (constraintFlags & EXCEEDED_VERTICAL_MAX) !== 0;
133
- if (horizontalMin) {
134
- if (verticalMin)
135
- return "se-resize";
136
- else if (verticalMax)
137
- return "ne-resize";
138
- else
139
- return "e-resize";
140
- } else if (horizontalMax) {
141
- if (verticalMin)
142
- return "sw-resize";
143
- else if (verticalMax)
144
- return "nw-resize";
145
- else
146
- return "w-resize";
147
- } else if (verticalMin) {
148
- return "s-resize";
149
- } else if (verticalMax) {
150
- return "n-resize";
151
- }
152
- }
153
- switch (state) {
154
- case "horizontal":
155
- return "ew-resize";
156
- case "intersection":
157
- return "move";
158
- case "vertical":
159
- return "ns-resize";
160
- }
161
- }
162
- function resetGlobalCursorStyle() {
163
- if (styleElement !== null) {
164
- document.head.removeChild(styleElement);
165
- currentCursorStyle = null;
166
- styleElement = null;
167
- }
168
- }
169
- function setGlobalCursorStyle(state, constraintFlags) {
170
- const style = getCursorStyle(state, constraintFlags);
171
- if (currentCursorStyle === style)
172
- return;
173
- currentCursorStyle = style;
174
- if (styleElement === null) {
175
- styleElement = document.createElement("style");
176
- document.head.appendChild(styleElement);
177
- }
178
- styleElement.innerHTML = `*{cursor: ${style}!important;}`;
179
- }
180
- function computePanelFlexBoxStyle({
181
- defaultSize,
182
- dragState,
183
- layout,
184
- panelData,
185
- panelIndex,
186
- precision = 3
187
- }) {
188
- const size = layout[panelIndex];
189
- let flexGrow;
190
- if (size == null) {
191
- flexGrow = defaultSize !== void 0 ? defaultSize.toPrecision(precision) : "1";
192
- } else if (panelData.length === 1) {
193
- flexGrow = "1";
194
- } else {
195
- flexGrow = size.toPrecision(precision);
196
- }
197
- return {
198
- flexBasis: 0,
199
- flexGrow,
200
- flexShrink: 1,
201
- // Without this, Panel sizes may be unintentionally overridden by their content
202
- overflow: "hidden",
203
- // Disable pointer events inside of a panel during resize
204
- // This avoid edge cases like nested iframes
205
- pointerEvents: dragState !== null ? "none" : void 0
206
- };
207
- }
208
-
209
- function isKeyDown(event) {
210
- return event.type === "keydown";
211
- }
212
- function isMouseEvent(event) {
213
- return event.type.startsWith("mouse");
214
- }
215
- function isTouchEvent(event) {
216
- return event.type.startsWith("touch");
217
- }
218
- function getResizeEventCoordinates(event) {
219
- if (isMouseEvent(event)) {
220
- return {
221
- x: event.clientX,
222
- y: event.clientY
223
- };
224
- } else if (isTouchEvent(event)) {
225
- const touch = event.touches[0];
226
- if (touch && touch.clientX && touch.clientY) {
227
- return {
228
- x: touch.clientX,
229
- y: touch.clientY
230
- };
231
- }
232
- }
233
- return {
234
- x: Number.POSITIVE_INFINITY,
235
- y: Number.POSITIVE_INFINITY
236
- };
237
- }
238
- function getResizeEventCursorPosition(direction, event) {
239
- const isHorizontal = direction === "horizontal";
240
- const { x, y } = getResizeEventCoordinates(event);
241
- return isHorizontal ? x : y;
242
- }
243
-
244
- function intersects(rectOne, rectTwo, strict) {
245
- if (strict) {
246
- return rectOne.x < rectTwo.x + rectTwo.width && rectOne.x + rectOne.width > rectTwo.x && rectOne.y < rectTwo.y + rectTwo.height && rectOne.y + rectOne.height > rectTwo.y;
247
- } else {
248
- return rectOne.x <= rectTwo.x + rectTwo.width && rectOne.x + rectOne.width >= rectTwo.x && rectOne.y <= rectTwo.y + rectTwo.height && rectOne.y + rectOne.height >= rectTwo.y;
249
- }
250
- }
251
-
252
- function compare(a, b) {
253
- if (a === b)
254
- throw new Error("Cannot compare node with itself");
255
- const ancestors = {
256
- a: getAncestors(a),
257
- b: getAncestors(b)
258
- };
259
- let common_ancestor;
260
- while (ancestors.a.at(-1) === ancestors.b.at(-1)) {
261
- a = ancestors.a.pop();
262
- b = ancestors.b.pop();
263
- common_ancestor = a;
264
- }
265
- assert(common_ancestor);
266
- const z_indexes = {
267
- a: getZIndex(findStackingContext(ancestors.a)),
268
- b: getZIndex(findStackingContext(ancestors.b))
269
- };
270
- if (z_indexes.a === z_indexes.b) {
271
- const children = common_ancestor.childNodes;
272
- const furthest_ancestors = {
273
- a: ancestors.a.at(-1),
274
- b: ancestors.b.at(-1)
275
- };
276
- let i = children.length;
277
- while (i--) {
278
- const child = children[i];
279
- if (child === furthest_ancestors.a)
280
- return 1;
281
- if (child === furthest_ancestors.b)
282
- return -1;
283
- }
284
- }
285
- return Math.sign(z_indexes.a - z_indexes.b);
286
- }
287
- const props = /\b(?:position|zIndex|opacity|transform|webkitTransform|mixBlendMode|filter|webkitFilter|isolation)\b/;
288
- function isFlexItem(node) {
289
- const display = getComputedStyle(getParent(node)).display;
290
- return display === "flex" || display === "inline-flex";
291
- }
292
- function createsStackingContext(node) {
293
- const style = getComputedStyle(node);
294
- if (style.position === "fixed")
295
- return true;
296
- if (style.zIndex !== "auto" && (style.position !== "static" || isFlexItem(node)))
297
- return true;
298
- if (+style.opacity < 1)
299
- return true;
300
- if ("transform" in style && style.transform !== "none")
301
- return true;
302
- if ("webkitTransform" in style && style.webkitTransform !== "none")
303
- return true;
304
- if ("mixBlendMode" in style && style.mixBlendMode !== "normal")
305
- return true;
306
- if ("filter" in style && style.filter !== "none")
307
- return true;
308
- if ("webkitFilter" in style && style.webkitFilter !== "none")
309
- return true;
310
- if ("isolation" in style && style.isolation === "isolate")
311
- return true;
312
- if (props.test(style.willChange))
313
- return true;
314
- if (style.webkitOverflowScrolling === "touch")
315
- return true;
316
- return false;
317
- }
318
- function findStackingContext(nodes) {
319
- let i = nodes.length;
320
- while (i--) {
321
- const node = nodes[i];
322
- assert(node);
323
- if (createsStackingContext(node))
324
- return node;
325
- }
326
- return null;
327
- }
328
- function getZIndex(node) {
329
- return node && Number(getComputedStyle(node).zIndex) || 0;
330
- }
331
- function getAncestors(node) {
332
- const ancestors = [];
333
- while (node) {
334
- ancestors.push(node);
335
- node = getParent(node);
336
- }
337
- return ancestors;
338
- }
339
- function getParent(node) {
340
- return node.parentNode?.host || node.parentNode;
341
- }
342
-
343
- const EXCEEDED_HORIZONTAL_MIN = 1;
344
- const EXCEEDED_HORIZONTAL_MAX = 2;
345
- const EXCEEDED_VERTICAL_MIN = 4;
346
- const EXCEEDED_VERTICAL_MAX = 8;
347
- function getInputType() {
348
- if (typeof matchMedia === "function")
349
- return matchMedia("(pointer:coarse)").matches ? "coarse" : "fine";
350
- }
351
- const isCoarsePointer = getInputType() === "coarse";
352
- const intersectingHandles = [];
353
- let isPointerDown = false;
354
- const ownerDocumentCounts = /* @__PURE__ */ new Map();
355
- const panelConstraintFlags = /* @__PURE__ */ new Map();
356
- const registeredResizeHandlers = /* @__PURE__ */ new Set();
357
- function registerResizeHandle(resizeHandleId, element, direction, hitAreaMargins, setResizeHandlerState) {
358
- const { ownerDocument } = element;
359
- const data = {
360
- direction,
361
- element,
362
- hitAreaMargins,
363
- setResizeHandlerState
364
- };
365
- const count = ownerDocumentCounts.get(ownerDocument) ?? 0;
366
- ownerDocumentCounts.set(ownerDocument, count + 1);
367
- registeredResizeHandlers.add(data);
368
- updateListeners();
369
- return function unregisterResizeHandle() {
370
- panelConstraintFlags.delete(resizeHandleId);
371
- registeredResizeHandlers.delete(data);
372
- const count2 = ownerDocumentCounts.get(ownerDocument) ?? 1;
373
- ownerDocumentCounts.set(ownerDocument, count2 - 1);
374
- updateListeners();
375
- if (count2 === 1)
376
- ownerDocumentCounts.delete(ownerDocument);
377
- };
378
- }
379
- function handlePointerDown(event) {
380
- const { target } = event;
381
- const { x, y } = getResizeEventCoordinates(event);
382
- isPointerDown = true;
383
- recalculateIntersectingHandles({ target, x, y });
384
- updateListeners();
385
- if (intersectingHandles.length > 0) {
386
- updateResizeHandlerStates("down", event);
387
- event.preventDefault();
388
- }
389
- }
390
- function handlePointerMove(event) {
391
- const { x, y } = getResizeEventCoordinates(event);
392
- if (!isPointerDown) {
393
- const { target } = event;
394
- recalculateIntersectingHandles({ target, x, y });
395
- }
396
- updateResizeHandlerStates("move", event);
397
- updateCursor();
398
- if (intersectingHandles.length > 0)
399
- event.preventDefault();
400
- }
401
- function handlePointerUp(event) {
402
- const { target } = event;
403
- const { x, y } = getResizeEventCoordinates(event);
404
- panelConstraintFlags.clear();
405
- isPointerDown = false;
406
- if (intersectingHandles.length > 0)
407
- event.preventDefault();
408
- updateResizeHandlerStates("up", event);
409
- recalculateIntersectingHandles({ target, x, y });
410
- updateCursor();
411
- updateListeners();
412
- }
413
- function recalculateIntersectingHandles({
414
- target,
415
- x,
416
- y
417
- }) {
418
- intersectingHandles.splice(0);
419
- let targetElement = null;
420
- if (target instanceof HTMLElement)
421
- targetElement = target;
422
- registeredResizeHandlers.forEach((data) => {
423
- const { element: dragHandleElement, hitAreaMargins } = data;
424
- const dragHandleRect = dragHandleElement.getBoundingClientRect();
425
- const { bottom, left, right, top } = dragHandleRect;
426
- const margin = isCoarsePointer ? hitAreaMargins.coarse : hitAreaMargins.fine;
427
- const eventIntersects = x >= left - margin && x <= right + margin && y >= top - margin && y <= bottom + margin;
428
- if (eventIntersects) {
429
- if (targetElement !== null && dragHandleElement !== targetElement && !dragHandleElement.contains(targetElement) && !targetElement.contains(dragHandleElement) && compare(targetElement, dragHandleElement) > 0) {
430
- let currentElement = targetElement;
431
- let didIntersect = false;
432
- while (currentElement) {
433
- if (currentElement.contains(dragHandleElement)) {
434
- break;
435
- } else if (intersects(
436
- currentElement.getBoundingClientRect(),
437
- dragHandleRect,
438
- true
439
- )) {
440
- didIntersect = true;
441
- break;
442
- }
443
- currentElement = currentElement.parentElement;
444
- }
445
- if (didIntersect)
446
- return;
447
- }
448
- intersectingHandles.push(data);
449
- }
450
- });
451
- }
452
- function reportConstraintsViolation(resizeHandleId, flag) {
453
- panelConstraintFlags.set(resizeHandleId, flag);
454
- }
455
- function updateCursor() {
456
- let intersectsHorizontal = false;
457
- let intersectsVertical = false;
458
- intersectingHandles.forEach((data) => {
459
- const { direction } = data;
460
- if (direction === "horizontal")
461
- intersectsHorizontal = true;
462
- else
463
- intersectsVertical = true;
464
- });
465
- let constraintFlags = 0;
466
- panelConstraintFlags.forEach((flag) => {
467
- constraintFlags |= flag;
468
- });
469
- if (intersectsHorizontal && intersectsVertical)
470
- setGlobalCursorStyle("intersection", constraintFlags);
471
- else if (intersectsHorizontal)
472
- setGlobalCursorStyle("horizontal", constraintFlags);
473
- else if (intersectsVertical)
474
- setGlobalCursorStyle("vertical", constraintFlags);
475
- else
476
- resetGlobalCursorStyle();
477
- }
478
- function updateListeners() {
479
- ownerDocumentCounts.forEach((_, ownerDocument) => {
480
- const { body } = ownerDocument;
481
- body.removeEventListener("contextmenu", handlePointerUp);
482
- body.removeEventListener("mousedown", handlePointerDown);
483
- body.removeEventListener("mouseleave", handlePointerMove);
484
- body.removeEventListener("mousemove", handlePointerMove);
485
- body.removeEventListener("touchmove", handlePointerMove);
486
- body.removeEventListener("touchstart", handlePointerDown);
487
- });
488
- window.removeEventListener("mouseup", handlePointerUp);
489
- window.removeEventListener("touchcancel", handlePointerUp);
490
- window.removeEventListener("touchend", handlePointerUp);
491
- if (registeredResizeHandlers.size > 0) {
492
- if (isPointerDown) {
493
- if (intersectingHandles.length > 0) {
494
- ownerDocumentCounts.forEach((count, ownerDocument) => {
495
- const { body } = ownerDocument;
496
- if (count > 0) {
497
- body.addEventListener("contextmenu", handlePointerUp);
498
- body.addEventListener("mouseleave", handlePointerMove);
499
- body.addEventListener("mousemove", handlePointerMove);
500
- body.addEventListener("touchmove", handlePointerMove, {
501
- passive: false
502
- });
503
- }
504
- });
505
- }
506
- window.addEventListener("mouseup", handlePointerUp);
507
- window.addEventListener("touchcancel", handlePointerUp);
508
- window.addEventListener("touchend", handlePointerUp);
509
- } else {
510
- ownerDocumentCounts.forEach((count, ownerDocument) => {
511
- const { body } = ownerDocument;
512
- if (count > 0) {
513
- body.addEventListener("mousedown", handlePointerDown);
514
- body.addEventListener("mousemove", handlePointerMove);
515
- body.addEventListener("touchmove", handlePointerMove, {
516
- passive: false
517
- });
518
- body.addEventListener("touchstart", handlePointerDown);
519
- }
520
- });
521
- }
522
- }
523
- }
524
- function updateResizeHandlerStates(action, event) {
525
- registeredResizeHandlers.forEach((data) => {
526
- const { setResizeHandlerState } = data;
527
- const isActive = intersectingHandles.includes(data);
528
- setResizeHandlerState(action, isActive, event);
529
- });
530
- }
531
-
532
- function debounce(callback, durationMs = 10) {
533
- let timeoutId = null;
534
- const callable = (...args) => {
535
- if (timeoutId !== null)
536
- clearTimeout(timeoutId);
537
- timeoutId = setTimeout(() => {
538
- callback(...args);
539
- }, durationMs);
540
- };
541
- return callable;
542
- }
543
-
544
- function determinePivotIndices(groupId, dragHandleId, panelGroupElement) {
545
- const index = getResizeHandleElementIndex(
546
- groupId,
547
- dragHandleId,
548
- panelGroupElement
549
- );
550
- return index != null ? [index, index + 1] : [-1, -1];
551
- }
552
-
553
- const PRECISION = 10;
554
-
555
- function fuzzyCompareNumbers(actual, expected, fractionDigits = PRECISION) {
556
- actual = Number.parseFloat(actual.toFixed(fractionDigits));
557
- expected = Number.parseFloat(expected.toFixed(fractionDigits));
558
- const delta = actual - expected;
559
- if (delta === 0)
560
- return 0;
561
- else
562
- return delta > 0 ? 1 : -1;
563
- }
564
- function fuzzyNumbersEqual(actual, expected, fractionDigits) {
565
- return fuzzyCompareNumbers(actual, expected, fractionDigits) === 0;
566
- }
567
-
568
- function resizePanel({
569
- panelConstraints: panelConstraintsArray,
570
- panelIndex,
571
- size
572
- }) {
573
- const panelConstraints = panelConstraintsArray[panelIndex];
574
- assert(panelConstraints != null);
575
- const { collapsedSize = 0, collapsible, maxSize = 100, minSize = 0 } = panelConstraints;
576
- if (fuzzyCompareNumbers(size, minSize) < 0) {
577
- if (collapsible) {
578
- const halfwayPoint = (collapsedSize + minSize) / 2;
579
- if (fuzzyCompareNumbers(size, halfwayPoint) < 0)
580
- size = collapsedSize;
581
- else
582
- size = minSize;
583
- } else {
584
- size = minSize;
585
- }
586
- }
587
- size = Math.min(maxSize, size);
588
- size = Number.parseFloat(size.toFixed(PRECISION));
589
- return size;
590
- }
591
-
592
- function validatePanelGroupLayout({
593
- layout: prevLayout,
594
- panelConstraints
595
- }) {
596
- const nextLayout = [...prevLayout];
597
- const nextLayoutTotalSize = nextLayout.reduce(
598
- (accumulated, current) => accumulated + current,
599
- 0
600
- );
601
- if (nextLayout.length !== panelConstraints.length) {
602
- throw new Error(
603
- `Invalid ${panelConstraints.length} panel layout: ${nextLayout.map((size) => `${size}%`).join(", ")}`
604
- );
605
- } else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
606
- {
607
- console.warn(
608
- `WARNING: Invalid layout total size: ${nextLayout.map((size) => `${size}%`).join(", ")}. Layout normalization will be applied.`
609
- );
610
- }
611
- for (let index = 0; index < panelConstraints.length; index++) {
612
- const unsafeSize = nextLayout[index];
613
- assert(unsafeSize != null);
614
- const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
615
- nextLayout[index] = safeSize;
616
- }
617
- }
618
- let remainingSize = 0;
619
- for (let index = 0; index < panelConstraints.length; index++) {
620
- const unsafeSize = nextLayout[index];
621
- assert(unsafeSize != null);
622
- const safeSize = resizePanel({
623
- panelConstraints,
624
- panelIndex: index,
625
- size: unsafeSize
626
- });
627
- if (unsafeSize !== safeSize) {
628
- remainingSize += unsafeSize - safeSize;
629
- nextLayout[index] = safeSize;
630
- }
631
- }
632
- if (!fuzzyNumbersEqual(remainingSize, 0)) {
633
- for (let index = 0; index < panelConstraints.length; index++) {
634
- const prevSize = nextLayout[index];
635
- assert(prevSize != null);
636
- const unsafeSize = prevSize + remainingSize;
637
- const safeSize = resizePanel({
638
- panelConstraints,
639
- panelIndex: index,
640
- size: unsafeSize
641
- });
642
- if (prevSize !== safeSize) {
643
- remainingSize -= safeSize - prevSize;
644
- nextLayout[index] = safeSize;
645
- if (fuzzyNumbersEqual(remainingSize, 0))
646
- break;
647
- }
648
- }
649
- }
650
- return nextLayout;
651
- }
652
-
653
- function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
654
- layout.forEach((size, index) => {
655
- const panelData = panelsArray[index];
656
- assert(panelData);
657
- const { callbacks, constraints, id: panelId } = panelData;
658
- const { collapsedSize = 0, collapsible } = constraints;
659
- const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
660
- if (lastNotifiedSize == null || size !== lastNotifiedSize) {
661
- panelIdToLastNotifiedSizeMap[panelId] = size;
662
- const { onCollapse, onExpand, onResize } = callbacks;
663
- if (onResize)
664
- onResize(size, lastNotifiedSize);
665
- if (collapsible && (onCollapse || onExpand)) {
666
- if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize)
667
- onExpand();
668
- if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize)
669
- onCollapse();
670
- }
671
- }
672
- });
673
- }
674
-
675
- function compareLayouts(a, b) {
676
- if (a.length !== b.length) {
677
- return false;
678
- } else {
679
- for (let index = 0; index < a.length; index++) {
680
- if (a[index] !== b[index])
681
- return false;
682
- }
683
- }
684
- return true;
685
- }
686
- function adjustLayoutByDelta({
687
- delta,
688
- layout: prevLayout,
689
- panelConstraints: panelConstraintsArray,
690
- pivotIndices,
691
- trigger
692
- }) {
693
- if (fuzzyNumbersEqual(delta, 0))
694
- return prevLayout;
695
- const nextLayout = [...prevLayout];
696
- const [firstPivotIndex, secondPivotIndex] = pivotIndices;
697
- assert(firstPivotIndex != null);
698
- assert(secondPivotIndex != null);
699
- let deltaApplied = 0;
700
- {
701
- if (trigger === "keyboard") {
702
- {
703
- const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
704
- const panelConstraints = panelConstraintsArray[index];
705
- assert(panelConstraints);
706
- if (panelConstraints.collapsible) {
707
- const prevSize = prevLayout[index];
708
- assert(prevSize != null);
709
- const panelConstraints2 = panelConstraintsArray[index];
710
- assert(panelConstraints2);
711
- const { collapsedSize = 0, minSize = 0 } = panelConstraints2;
712
- if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
713
- const localDelta = minSize - prevSize;
714
- if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0)
715
- delta = delta < 0 ? 0 - localDelta : localDelta;
716
- }
717
- }
718
- }
719
- {
720
- const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
721
- const panelConstraints = panelConstraintsArray[index];
722
- assert(panelConstraints);
723
- const { collapsible } = panelConstraints;
724
- if (collapsible) {
725
- const prevSize = prevLayout[index];
726
- assert(prevSize != null);
727
- const panelConstraints2 = panelConstraintsArray[index];
728
- assert(panelConstraints2);
729
- const { collapsedSize = 0, minSize = 0 } = panelConstraints2;
730
- if (fuzzyNumbersEqual(prevSize, minSize)) {
731
- const localDelta = prevSize - collapsedSize;
732
- if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0)
733
- delta = delta < 0 ? 0 - localDelta : localDelta;
734
- }
735
- }
736
- }
737
- }
738
- }
739
- {
740
- const increment = delta < 0 ? 1 : -1;
741
- let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
742
- let maxAvailableDelta = 0;
743
- while (true) {
744
- const prevSize = prevLayout[index];
745
- assert(prevSize != null);
746
- const maxSafeSize = resizePanel({
747
- panelConstraints: panelConstraintsArray,
748
- panelIndex: index,
749
- size: 100
750
- });
751
- const delta2 = maxSafeSize - prevSize;
752
- maxAvailableDelta += delta2;
753
- index += increment;
754
- if (index < 0 || index >= panelConstraintsArray.length)
755
- break;
756
- }
757
- const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
758
- delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
759
- }
760
- {
761
- const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
762
- let index = pivotIndex;
763
- while (index >= 0 && index < panelConstraintsArray.length) {
764
- const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
765
- const prevSize = prevLayout[index];
766
- assert(prevSize != null);
767
- const unsafeSize = prevSize - deltaRemaining;
768
- const safeSize = resizePanel({
769
- panelConstraints: panelConstraintsArray,
770
- panelIndex: index,
771
- size: unsafeSize
772
- });
773
- if (!fuzzyNumbersEqual(prevSize, safeSize)) {
774
- deltaApplied += prevSize - safeSize;
775
- nextLayout[index] = safeSize;
776
- if (deltaApplied.toPrecision(3).localeCompare(Math.abs(delta).toPrecision(3), void 0, {
777
- numeric: true
778
- }) >= 0)
779
- break;
780
- }
781
- if (delta < 0)
782
- index--;
783
- else
784
- index++;
785
- }
786
- }
787
- if (fuzzyNumbersEqual(deltaApplied, 0)) {
788
- return prevLayout;
789
- }
790
- {
791
- const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
792
- const prevSize = prevLayout[pivotIndex];
793
- assert(prevSize != null);
794
- const unsafeSize = prevSize + deltaApplied;
795
- const safeSize = resizePanel({
796
- panelConstraints: panelConstraintsArray,
797
- panelIndex: pivotIndex,
798
- size: unsafeSize
799
- });
800
- nextLayout[pivotIndex] = safeSize;
801
- if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
802
- let deltaRemaining = unsafeSize - safeSize;
803
- const pivotIndex2 = delta < 0 ? secondPivotIndex : firstPivotIndex;
804
- let index = pivotIndex2;
805
- while (index >= 0 && index < panelConstraintsArray.length) {
806
- const prevSize2 = nextLayout[index];
807
- assert(prevSize2 != null);
808
- const unsafeSize2 = prevSize2 + deltaRemaining;
809
- const safeSize2 = resizePanel({
810
- panelConstraints: panelConstraintsArray,
811
- panelIndex: index,
812
- size: unsafeSize2
813
- });
814
- if (!fuzzyNumbersEqual(prevSize2, safeSize2)) {
815
- deltaRemaining -= safeSize2 - prevSize2;
816
- nextLayout[index] = safeSize2;
817
- }
818
- if (fuzzyNumbersEqual(deltaRemaining, 0))
819
- break;
820
- if (delta > 0)
821
- index--;
822
- else
823
- index++;
824
- }
825
- }
826
- }
827
- const totalSize = nextLayout.reduce((total, size) => size + total, 0);
828
- if (!fuzzyNumbersEqual(totalSize, 100))
829
- return prevLayout;
830
- return nextLayout;
831
- }
832
-
833
- function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState, panelGroupElement) {
834
- const isHorizontal = direction === "horizontal";
835
- const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
836
- assert(handleElement);
837
- const groupId = handleElement.getAttribute("data-panel-group-id");
838
- assert(groupId);
839
- const { initialCursorPosition } = initialDragState;
840
- const cursorPosition = getResizeEventCursorPosition(direction, event);
841
- const groupElement = getPanelGroupElement(groupId, panelGroupElement);
842
- assert(groupElement);
843
- const groupRect = groupElement.getBoundingClientRect();
844
- const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
845
- const offsetPixels = cursorPosition - initialCursorPosition;
846
- const offsetPercentage = offsetPixels / groupSizeInPixels * 100;
847
- return offsetPercentage;
848
- }
849
- function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy, panelGroupElement) {
850
- if (isKeyDown(event)) {
851
- const isHorizontal = direction === "horizontal";
852
- let delta = 0;
853
- if (event.shiftKey)
854
- delta = 100;
855
- else
856
- delta = keyboardResizeBy ?? 10;
857
- let movement = 0;
858
- switch (event.key) {
859
- case "ArrowDown":
860
- movement = isHorizontal ? 0 : delta;
861
- break;
862
- case "ArrowLeft":
863
- movement = isHorizontal ? -delta : 0;
864
- break;
865
- case "ArrowRight":
866
- movement = isHorizontal ? delta : 0;
867
- break;
868
- case "ArrowUp":
869
- movement = isHorizontal ? 0 : -delta;
870
- break;
871
- case "End":
872
- movement = 100;
873
- break;
874
- case "Home":
875
- movement = -100;
876
- break;
877
- }
878
- return movement;
879
- } else {
880
- if (initialDragState == null)
881
- return 0;
882
- return calculateDragOffsetPercentage(
883
- event,
884
- dragHandleId,
885
- direction,
886
- initialDragState,
887
- panelGroupElement
888
- );
889
- }
890
- }
891
- function calculateAriaValues({
892
- layout,
893
- panelsArray,
894
- pivotIndices
895
- }) {
896
- let currentMinSize = 0;
897
- let currentMaxSize = 100;
898
- let totalMinSize = 0;
899
- let totalMaxSize = 0;
900
- const firstIndex = pivotIndices[0];
901
- assert(firstIndex != null);
902
- panelsArray.forEach((panelData, index) => {
903
- const { constraints } = panelData;
904
- const { maxSize = 100, minSize = 0 } = constraints;
905
- if (index === firstIndex) {
906
- currentMinSize = minSize;
907
- currentMaxSize = maxSize;
908
- } else {
909
- totalMinSize += minSize;
910
- totalMaxSize += maxSize;
911
- }
912
- });
913
- const valueMax = Math.min(currentMaxSize, 100 - totalMinSize);
914
- const valueMin = Math.max(currentMinSize, 100 - totalMaxSize);
915
- const valueNow = layout[firstIndex];
916
- return {
917
- valueMax,
918
- valueMin,
919
- valueNow
920
- };
921
- }
922
- function calculateUnsafeDefaultLayout({
923
- panelDataArray
924
- }) {
925
- const layout = Array(panelDataArray.length);
926
- const panelConstraintsArray = panelDataArray.map(
927
- (panelData) => panelData.constraints
928
- );
929
- let numPanelsWithSizes = 0;
930
- let remainingSize = 100;
931
- for (let index = 0; index < panelDataArray.length; index++) {
932
- const panelConstraints = panelConstraintsArray[index];
933
- assert(panelConstraints);
934
- const { defaultSize } = panelConstraints;
935
- if (defaultSize != null) {
936
- numPanelsWithSizes++;
937
- layout[index] = defaultSize;
938
- remainingSize -= defaultSize;
939
- }
940
- }
941
- for (let index = 0; index < panelDataArray.length; index++) {
942
- const panelConstraints = panelConstraintsArray[index];
943
- assert(panelConstraints);
944
- const { defaultSize } = panelConstraints;
945
- if (defaultSize != null)
946
- continue;
947
- const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
948
- const size = remainingSize / numRemainingPanels;
949
- numPanelsWithSizes++;
950
- layout[index] = size;
951
- remainingSize -= size;
952
- }
953
- return layout;
954
- }
955
-
956
- function initializeDefaultStorage(storageObject) {
957
- try {
958
- if (typeof localStorage !== "undefined") {
959
- storageObject.getItem = (name) => {
960
- return localStorage.getItem(name);
961
- };
962
- storageObject.setItem = (name, value) => {
963
- localStorage.setItem(name, value);
964
- };
965
- } else {
966
- throw new TypeError("localStorage not supported in this environment");
967
- }
968
- } catch (error) {
969
- console.error(error);
970
- storageObject.getItem = () => null;
971
- storageObject.setItem = () => {
972
- };
973
- }
974
- }
975
- function getPanelGroupKey(autoSaveId) {
976
- return `destyler:${autoSaveId}`;
977
- }
978
- function getPanelKey(panels) {
979
- return panels.map((panel) => {
980
- const { constraints, id, idIsFromProps, order } = panel;
981
- if (idIsFromProps) {
982
- return id;
983
- } else {
984
- return order ? `${order}:${JSON.stringify(constraints)}` : JSON.stringify(constraints);
985
- }
986
- }).sort((a, b) => a.localeCompare(b)).join(",");
987
- }
988
- function loadSerializedPanelGroupState(autoSaveId, storage) {
989
- try {
990
- const panelGroupKey = getPanelGroupKey(autoSaveId);
991
- const serialized = storage.getItem(panelGroupKey);
992
- if (serialized) {
993
- const parsed = JSON.parse(serialized);
994
- if (typeof parsed === "object" && parsed != null)
995
- return parsed;
996
- }
997
- } catch (error) {
998
- }
999
- return null;
1000
- }
1001
- function loadPanelGroupState(autoSaveId, panels, storage) {
1002
- const state = loadSerializedPanelGroupState(autoSaveId, storage) ?? {};
1003
- const panelKey = getPanelKey(panels);
1004
- return state[panelKey] ?? null;
1005
- }
1006
- function savePanelGroupState(autoSaveId, panels, panelSizesBeforeCollapse, sizes, storage) {
1007
- const panelGroupKey = getPanelGroupKey(autoSaveId);
1008
- const panelKey = getPanelKey(panels);
1009
- const state = loadSerializedPanelGroupState(autoSaveId, storage) ?? {};
1010
- state[panelKey] = {
1011
- expandToSizes: Object.fromEntries(panelSizesBeforeCollapse.entries()),
1012
- layout: sizes
1013
- };
1014
- try {
1015
- storage.setItem(panelGroupKey, JSON.stringify(state));
1016
- } catch (error) {
1017
- console.error(error);
1018
- }
1019
- }
1020
-
1021
- function useWindowSplitterPanelGroupBehavior({
1022
- eagerValuesRef,
1023
- groupId,
1024
- layout,
1025
- panelDataArray,
1026
- panelGroupElement,
1027
- setLayout
1028
- }) {
1029
- vue.watchEffect((onCleanup) => {
1030
- const _panelGroupElement = panelGroupElement.value;
1031
- if (!_panelGroupElement)
1032
- return;
1033
- const resizeHandleElements = getResizeHandleElementsForGroup(
1034
- groupId,
1035
- _panelGroupElement
1036
- );
1037
- for (let index = 0; index < panelDataArray.length - 1; index++) {
1038
- const { valueMax, valueMin, valueNow } = calculateAriaValues({
1039
- layout: layout.value,
1040
- panelsArray: panelDataArray,
1041
- pivotIndices: [index, index + 1]
1042
- });
1043
- const resizeHandleElement = resizeHandleElements[index];
1044
- if (resizeHandleElement == null) {
1045
- if (undefined.DEV)
1046
- console.warn(`WARNING: Missing resize handle for PanelGroup "${groupId}"`);
1047
- } else {
1048
- const panelData = panelDataArray[index];
1049
- assert(panelData);
1050
- resizeHandleElement.setAttribute("aria-controls", panelData.id);
1051
- resizeHandleElement.setAttribute(
1052
- "aria-valuemax",
1053
- `${Math.round(valueMax)}`
1054
- );
1055
- resizeHandleElement.setAttribute(
1056
- "aria-valuemin",
1057
- `${Math.round(valueMin)}`
1058
- );
1059
- resizeHandleElement.setAttribute(
1060
- "aria-valuenow",
1061
- valueNow != null ? `${Math.round(valueNow)}` : ""
1062
- );
1063
- }
1064
- }
1065
- onCleanup(() => {
1066
- resizeHandleElements.forEach((resizeHandleElement) => {
1067
- resizeHandleElement.removeAttribute("aria-controls");
1068
- resizeHandleElement.removeAttribute("aria-valuemax");
1069
- resizeHandleElement.removeAttribute("aria-valuemin");
1070
- resizeHandleElement.removeAttribute("aria-valuenow");
1071
- });
1072
- });
1073
- });
1074
- vue.watchEffect((onCleanup) => {
1075
- const _panelGroupElement = panelGroupElement.value;
1076
- if (!_panelGroupElement)
1077
- return;
1078
- const eagerValues = eagerValuesRef.value;
1079
- assert(eagerValues);
1080
- const { panelDataArray: panelDataArray2 } = eagerValues;
1081
- const groupElement = getPanelGroupElement(groupId, _panelGroupElement);
1082
- assert(groupElement != null, `No group found for id "${groupId}"`);
1083
- const handles = getResizeHandleElementsForGroup(groupId, _panelGroupElement);
1084
- assert(handles);
1085
- const cleanupFunctions = handles.map((handle) => {
1086
- const handleId = handle.getAttribute("data-panel-resize-handle-id");
1087
- assert(handleId);
1088
- const [idBefore, idAfter] = getResizeHandlePanelIds(
1089
- groupId,
1090
- handleId,
1091
- panelDataArray2,
1092
- _panelGroupElement
1093
- );
1094
- if (idBefore == null || idAfter == null)
1095
- return () => {
1096
- };
1097
- const onKeyDown = (event) => {
1098
- if (event.defaultPrevented)
1099
- return;
1100
- switch (event.key) {
1101
- case "Enter": {
1102
- event.preventDefault();
1103
- const index = panelDataArray2.findIndex(
1104
- (panelData) => panelData.id === idBefore
1105
- );
1106
- if (index >= 0) {
1107
- const panelData = panelDataArray2[index];
1108
- assert(panelData);
1109
- const size = layout.value[index];
1110
- const {
1111
- collapsedSize = 0,
1112
- collapsible,
1113
- minSize = 0
1114
- } = panelData.constraints;
1115
- if (size != null && collapsible) {
1116
- const nextLayout = adjustLayoutByDelta({
1117
- delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
1118
- layout: layout.value,
1119
- panelConstraints: panelDataArray2.map(
1120
- (panelData2) => panelData2.constraints
1121
- ),
1122
- pivotIndices: determinePivotIndices(
1123
- groupId,
1124
- handleId,
1125
- _panelGroupElement
1126
- ),
1127
- trigger: "keyboard"
1128
- });
1129
- if (layout.value !== nextLayout)
1130
- setLayout(nextLayout);
1131
- }
1132
- }
1133
- break;
1134
- }
1135
- }
1136
- };
1137
- handle.addEventListener("keydown", onKeyDown);
1138
- return () => {
1139
- handle.removeEventListener("keydown", onKeyDown);
1140
- };
1141
- });
1142
- onCleanup(() => {
1143
- cleanupFunctions.forEach((cleanupFunction) => cleanupFunction());
1144
- });
1145
- });
1146
- }
1147
-
1148
- const defaultStorage = {
1149
- getItem: (name) => {
1150
- initializeDefaultStorage(defaultStorage);
1151
- return defaultStorage.getItem(name);
1152
- },
1153
- setItem: (name, value) => {
1154
- initializeDefaultStorage(defaultStorage);
1155
- defaultStorage.setItem(name, value);
1156
- }
1157
- };
1158
- const destylerSplitterGroupProps = {
1159
- as: {
1160
- type: [String, Object],
1161
- required: false,
1162
- default: "div"
1163
- },
1164
- asChild: {
1165
- type: Boolean,
1166
- required: false,
1167
- default: false
1168
- },
1169
- id: {
1170
- type: String,
1171
- required: false
1172
- },
1173
- autoSaveId: {
1174
- type: String,
1175
- required: false,
1176
- default: null
1177
- },
1178
- direction: {
1179
- type: String,
1180
- required: true
1181
- },
1182
- keyboardResizeBy: {
1183
- type: Number,
1184
- required: false,
1185
- default: 10
1186
- },
1187
- storage: {
1188
- type: Object,
1189
- required: false,
1190
- default: () => defaultStorage
1191
- }
1192
- };
1193
- const [injectPanelGroupContext, providePanelGroupContext] = shared.createContext("PanelGroup");
1194
- const DestylerSplitterGroup = vue.defineComponent({
1195
- name: "DestylerSplitterGroup",
1196
- props: destylerSplitterGroupProps,
1197
- emits: ["layout"],
1198
- setup(props, { emit }) {
1199
- const LOCAL_STORAGE_DEBOUNCE_INTERVAL = 100;
1200
- const debounceMap = {};
1201
- const groupId = useUniqueId(props.id);
1202
- const dir = composition.useDirection();
1203
- const { forwardRef, currentElement: panelGroupElementRef } = composition.useForwardExpose();
1204
- const dragState = vue.ref(null);
1205
- const layout = vue.ref([]);
1206
- const panelIdToLastNotifiedSizeMapRef = vue.ref({});
1207
- const panelSizeBeforeCollapseRef = vue.ref(/* @__PURE__ */ new Map());
1208
- const prevDeltaRef = vue.ref(0);
1209
- const committedValuesRef = vue.computed(() => ({
1210
- autoSaveId: props.autoSaveId,
1211
- direction: props.direction,
1212
- dragState: dragState.value,
1213
- id: groupId,
1214
- keyboardResizeBy: props.keyboardResizeBy,
1215
- storage: props.storage
1216
- }));
1217
- const eagerValuesRef = vue.ref({
1218
- layout: layout.value,
1219
- panelDataArray: [],
1220
- panelDataArrayChanged: false
1221
- });
1222
- const setLayout = (val) => layout.value = val;
1223
- useWindowSplitterPanelGroupBehavior({
1224
- eagerValuesRef,
1225
- groupId,
1226
- layout,
1227
- panelDataArray: eagerValuesRef.value.panelDataArray,
1228
- setLayout,
1229
- panelGroupElement: panelGroupElementRef
1230
- });
1231
- vue.watchEffect(() => {
1232
- const { panelDataArray } = eagerValuesRef.value;
1233
- const { autoSaveId } = props;
1234
- if (autoSaveId) {
1235
- if (layout.value.length === 0 || layout.value.length !== panelDataArray.length)
1236
- return;
1237
- let debouncedSave = debounceMap[autoSaveId];
1238
- if (!debouncedSave) {
1239
- debouncedSave = debounce(
1240
- savePanelGroupState,
1241
- LOCAL_STORAGE_DEBOUNCE_INTERVAL
1242
- );
1243
- debounceMap[autoSaveId] = debouncedSave;
1244
- }
1245
- const clonedPanelDataArray = [...panelDataArray];
1246
- const clonedPanelSizesBeforeCollapse = new Map(
1247
- panelSizeBeforeCollapseRef.value
1248
- );
1249
- debouncedSave(
1250
- autoSaveId,
1251
- clonedPanelDataArray,
1252
- clonedPanelSizesBeforeCollapse,
1253
- layout.value,
1254
- props.storage
1255
- );
1256
- }
1257
- });
1258
- function getPanelStyle(panelData, defaultSize) {
1259
- const { panelDataArray } = eagerValuesRef.value;
1260
- const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1261
- return computePanelFlexBoxStyle({
1262
- defaultSize,
1263
- dragState: dragState.value,
1264
- layout: layout.value,
1265
- panelData: panelDataArray,
1266
- panelIndex
1267
- });
1268
- }
1269
- function registerPanel(panelData) {
1270
- const { panelDataArray } = eagerValuesRef.value;
1271
- panelDataArray.push(panelData);
1272
- panelDataArray.sort((panelA, panelB) => {
1273
- const orderA = panelA.order;
1274
- const orderB = panelB.order;
1275
- if (orderA == null && orderB == null)
1276
- return 0;
1277
- else if (orderA == null)
1278
- return -1;
1279
- else if (orderB == null)
1280
- return 1;
1281
- else
1282
- return orderA - orderB;
1283
- });
1284
- eagerValuesRef.value.panelDataArrayChanged = true;
1285
- }
1286
- vue.watch(() => eagerValuesRef.value.panelDataArrayChanged, () => {
1287
- if (eagerValuesRef.value.panelDataArrayChanged) {
1288
- eagerValuesRef.value.panelDataArrayChanged = false;
1289
- const { autoSaveId, storage } = committedValuesRef.value;
1290
- const { layout: prevLayout, panelDataArray } = eagerValuesRef.value;
1291
- let unsafeLayout = null;
1292
- if (autoSaveId) {
1293
- const state = loadPanelGroupState(autoSaveId, panelDataArray, storage);
1294
- if (state) {
1295
- panelSizeBeforeCollapseRef.value = new Map(
1296
- Object.entries(state.expandToSizes)
1297
- );
1298
- unsafeLayout = state.layout;
1299
- }
1300
- }
1301
- if (unsafeLayout === null) {
1302
- unsafeLayout = calculateUnsafeDefaultLayout({
1303
- panelDataArray
1304
- });
1305
- }
1306
- const nextLayout = validatePanelGroupLayout({
1307
- layout: unsafeLayout,
1308
- panelConstraints: panelDataArray.map(
1309
- (panelData) => panelData.constraints
1310
- )
1311
- });
1312
- if (!shared.areEqual(prevLayout, nextLayout)) {
1313
- setLayout(nextLayout);
1314
- eagerValuesRef.value.layout = nextLayout;
1315
- emit("layout", nextLayout);
1316
- callPanelCallbacks(
1317
- panelDataArray,
1318
- nextLayout,
1319
- panelIdToLastNotifiedSizeMapRef.value
1320
- );
1321
- }
1322
- }
1323
- });
1324
- function registerResizeHandle(dragHandleId) {
1325
- return function resizeHandler(event) {
1326
- event.preventDefault();
1327
- const panelGroupElement = panelGroupElementRef.value;
1328
- if (!panelGroupElement)
1329
- return () => null;
1330
- const { direction, dragState: dragState2, id: groupId2, keyboardResizeBy } = committedValuesRef.value;
1331
- const { layout: prevLayout, panelDataArray } = eagerValuesRef.value;
1332
- const { initialLayout } = dragState2 ?? {};
1333
- const pivotIndices = determinePivotIndices(
1334
- groupId2,
1335
- dragHandleId,
1336
- panelGroupElement
1337
- );
1338
- let delta = calculateDeltaPercentage(
1339
- event,
1340
- dragHandleId,
1341
- direction,
1342
- dragState2,
1343
- keyboardResizeBy,
1344
- panelGroupElement
1345
- );
1346
- if (delta === 0)
1347
- return;
1348
- const isHorizontal = direction === "horizontal";
1349
- if (dir.value === "rtl" && isHorizontal)
1350
- delta = -delta;
1351
- const panelConstraints = panelDataArray.map((panelData) => panelData.constraints);
1352
- const nextLayout = adjustLayoutByDelta({
1353
- delta,
1354
- layout: initialLayout ?? prevLayout,
1355
- panelConstraints,
1356
- pivotIndices,
1357
- trigger: isKeyDown(event) ? "keyboard" : "mouse-or-touch"
1358
- });
1359
- const layoutChanged = !compareLayouts(prevLayout, nextLayout);
1360
- if (isMouseEvent(event) || isTouchEvent(event)) {
1361
- if (prevDeltaRef.value !== delta) {
1362
- prevDeltaRef.value = delta;
1363
- if (!layoutChanged) {
1364
- if (isHorizontal) {
1365
- reportConstraintsViolation(
1366
- dragHandleId,
1367
- delta < 0 ? EXCEEDED_HORIZONTAL_MIN : EXCEEDED_HORIZONTAL_MAX
1368
- );
1369
- } else {
1370
- reportConstraintsViolation(
1371
- dragHandleId,
1372
- delta < 0 ? EXCEEDED_VERTICAL_MIN : EXCEEDED_VERTICAL_MAX
1373
- );
1374
- }
1375
- } else {
1376
- reportConstraintsViolation(dragHandleId, 0);
1377
- }
1378
- }
1379
- }
1380
- if (layoutChanged) {
1381
- setLayout(nextLayout);
1382
- eagerValuesRef.value.layout = nextLayout;
1383
- emit("layout", nextLayout);
1384
- callPanelCallbacks(
1385
- panelDataArray,
1386
- nextLayout,
1387
- panelIdToLastNotifiedSizeMapRef.value
1388
- );
1389
- }
1390
- };
1391
- }
1392
- function resizePanel(panelData, unsafePanelSize) {
1393
- const { layout: prevLayout, panelDataArray } = eagerValuesRef.value;
1394
- const panelConstraintsArray = panelDataArray.map((panelData2) => panelData2.constraints);
1395
- const { panelSize, pivotIndices } = panelDataHelper(
1396
- panelDataArray,
1397
- panelData,
1398
- prevLayout
1399
- );
1400
- assert(panelSize != null);
1401
- const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
1402
- const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1403
- const nextLayout = adjustLayoutByDelta({
1404
- delta,
1405
- layout: prevLayout,
1406
- panelConstraints: panelConstraintsArray,
1407
- pivotIndices,
1408
- trigger: "imperative-api"
1409
- });
1410
- if (!compareLayouts(prevLayout, nextLayout)) {
1411
- setLayout(nextLayout);
1412
- eagerValuesRef.value.layout = nextLayout;
1413
- emit("layout", nextLayout);
1414
- callPanelCallbacks(
1415
- panelDataArray,
1416
- nextLayout,
1417
- panelIdToLastNotifiedSizeMapRef.value
1418
- );
1419
- }
1420
- }
1421
- function reevaluatePanelConstraints(panelData, prevConstraints) {
1422
- const { layout: layout2, panelDataArray } = eagerValuesRef.value;
1423
- const {
1424
- collapsedSize: prevCollapsedSize = 0,
1425
- collapsible: prevCollapsible
1426
- } = prevConstraints;
1427
- const {
1428
- collapsedSize: nextCollapsedSize = 0,
1429
- collapsible: nextCollapsible,
1430
- maxSize: nextMaxSize = 100,
1431
- minSize: nextMinSize = 0
1432
- } = panelData.constraints;
1433
- const { panelSize: prevPanelSize } = panelDataHelper(
1434
- panelDataArray,
1435
- panelData,
1436
- layout2
1437
- );
1438
- if (prevPanelSize === null) {
1439
- return;
1440
- }
1441
- if (prevCollapsible && nextCollapsible && prevPanelSize === prevCollapsedSize) {
1442
- if (prevCollapsedSize !== nextCollapsedSize) {
1443
- resizePanel(panelData, nextCollapsedSize);
1444
- }
1445
- } else if (prevPanelSize < nextMinSize) {
1446
- resizePanel(panelData, nextMinSize);
1447
- } else if (prevPanelSize > nextMaxSize) {
1448
- resizePanel(panelData, nextMaxSize);
1449
- }
1450
- }
1451
- function startDragging(dragHandleId, event) {
1452
- const { direction } = committedValuesRef.value;
1453
- const { layout: layout2 } = eagerValuesRef.value;
1454
- if (!panelGroupElementRef.value)
1455
- return;
1456
- const handleElement = getResizeHandleElement(
1457
- dragHandleId,
1458
- panelGroupElementRef.value
1459
- );
1460
- assert(handleElement);
1461
- const initialCursorPosition = getResizeEventCursorPosition(
1462
- direction,
1463
- event
1464
- );
1465
- dragState.value = {
1466
- dragHandleId,
1467
- dragHandleRect: handleElement.getBoundingClientRect(),
1468
- initialCursorPosition,
1469
- initialLayout: layout2
1470
- };
1471
- }
1472
- function stopDragging() {
1473
- dragState.value = null;
1474
- }
1475
- function unregisterPanel(panelData) {
1476
- const { panelDataArray } = eagerValuesRef.value;
1477
- const index = findPanelDataIndex(panelDataArray, panelData);
1478
- if (index >= 0) {
1479
- panelDataArray.splice(index, 1);
1480
- delete panelIdToLastNotifiedSizeMapRef.value[panelData.id];
1481
- eagerValuesRef.value.panelDataArrayChanged = true;
1482
- }
1483
- }
1484
- providePanelGroupContext({
1485
- direction: props.direction,
1486
- dragState: dragState.value,
1487
- getPanelStyle,
1488
- groupId,
1489
- reevaluatePanelConstraints,
1490
- registerPanel,
1491
- registerResizeHandle,
1492
- resizePanel,
1493
- startDragging,
1494
- stopDragging,
1495
- unregisterPanel,
1496
- panelGroupElement: panelGroupElementRef
1497
- });
1498
- function findPanelDataIndex(panelDataArray, panelData) {
1499
- return panelDataArray.findIndex(
1500
- (prevPanelData) => prevPanelData === panelData || prevPanelData.id === panelData.id
1501
- );
1502
- }
1503
- function panelDataHelper(panelDataArray, panelData, layout2) {
1504
- const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1505
- const isLastPanel = panelIndex === panelDataArray.length - 1;
1506
- const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
1507
- const panelSize = layout2[panelIndex];
1508
- return {
1509
- ...panelData.constraints,
1510
- panelSize,
1511
- pivotIndices
1512
- };
1513
- }
1514
- return {
1515
- forwardRef,
1516
- groupId
1517
- };
1518
- },
1519
- render() {
1520
- return vue.h(primitive.DestylerPrimitive, {
1521
- "as": this.$props.as,
1522
- "asChild": this.$props.asChild,
1523
- "ref": (el) => this.forwardRef(el),
1524
- "style": {
1525
- display: "flex",
1526
- flexDirection: this.$props.direction === "horizontal" ? "row" : "column",
1527
- height: "100%",
1528
- overflow: "hidden",
1529
- width: "100%"
1530
- },
1531
- "data-panel-group": "",
1532
- "data-orientation": this.$props.direction,
1533
- "data-panel-group-id": this.groupId
1534
- }, () => this.$slots.default?.());
1535
- }
1536
- });
1537
-
1538
- const destylerSplitterResizeHandleProps = {
1539
- as: {
1540
- type: [String, Object],
1541
- required: false,
1542
- default: "div"
1543
- },
1544
- asChild: {
1545
- type: Boolean,
1546
- required: false,
1547
- default: false
1548
- },
1549
- id: {
1550
- type: String,
1551
- required: false
1552
- },
1553
- hitAreaMargins: {
1554
- type: Object,
1555
- required: false
1556
- },
1557
- tabindex: {
1558
- type: Number,
1559
- required: false,
1560
- default: 0
1561
- },
1562
- disabled: {
1563
- type: Boolean,
1564
- required: false
1565
- }
1566
- };
1567
- const DestylerSplitterResizeHandle = vue.defineComponent({
1568
- name: "DestylerSplitterResizeHandle",
1569
- props: destylerSplitterResizeHandleProps,
1570
- emits: ["dragging"],
1571
- setup(props, { emit }) {
1572
- const { forwardRef, currentElement } = composition.useForwardExpose();
1573
- const { disabled } = vue.toRefs(props);
1574
- const panelGroupContext = injectPanelGroupContext();
1575
- if (panelGroupContext === null) {
1576
- throw new Error(
1577
- "DestylerPanelResizeHandle components must be rendered within a PanelGroup container"
1578
- );
1579
- }
1580
- const {
1581
- direction,
1582
- groupId,
1583
- registerResizeHandle: registerResizeHandleWithParentGroup,
1584
- startDragging,
1585
- stopDragging,
1586
- panelGroupElement
1587
- } = panelGroupContext;
1588
- const resizeHandleId = useUniqueId(props.id);
1589
- const state = vue.ref("inactive");
1590
- const isFocused = vue.ref(false);
1591
- const resizeHandler = vue.ref(null);
1592
- vue.watch(disabled, () => {
1593
- if (!shared.isBrowser)
1594
- return;
1595
- if (disabled.value)
1596
- resizeHandler.value = null;
1597
- else
1598
- resizeHandler.value = registerResizeHandleWithParentGroup(resizeHandleId);
1599
- }, { immediate: true });
1600
- vue.watchEffect((onCleanup) => {
1601
- if (disabled.value || resizeHandler.value === null)
1602
- return;
1603
- const element = currentElement.value;
1604
- if (!element)
1605
- return;
1606
- assert(element);
1607
- const setResizeHandlerState = (action, isActive, event) => {
1608
- if (isActive) {
1609
- switch (action) {
1610
- case "down": {
1611
- state.value = "drag";
1612
- startDragging(resizeHandleId, event);
1613
- emit("dragging", true);
1614
- break;
1615
- }
1616
- case "move": {
1617
- if (state.value !== "drag")
1618
- state.value = "hover";
1619
- resizeHandler.value?.(event);
1620
- break;
1621
- }
1622
- case "up": {
1623
- state.value = "hover";
1624
- stopDragging();
1625
- emit("dragging", false);
1626
- break;
1627
- }
1628
- }
1629
- } else {
1630
- state.value = "inactive";
1631
- }
1632
- };
1633
- onCleanup(registerResizeHandle(
1634
- resizeHandleId,
1635
- element,
1636
- direction,
1637
- {
1638
- // Coarse inputs (e.g. finger/touch)
1639
- coarse: props.hitAreaMargins?.coarse ?? 15,
1640
- // Fine inputs (e.g. mouse)
1641
- fine: props.hitAreaMargins?.fine ?? 5
1642
- },
1643
- setResizeHandlerState
1644
- ));
1645
- });
1646
- useWindowSplitterResizeHandlerBehavior({
1647
- disabled,
1648
- resizeHandler,
1649
- handleId: resizeHandleId,
1650
- panelGroupElement
1651
- });
1652
- return {
1653
- resizeHandleId,
1654
- disabled,
1655
- state,
1656
- direction,
1657
- groupId,
1658
- isFocused,
1659
- forwardRef
1660
- };
1661
- },
1662
- render() {
1663
- return vue.withDirectives(vue.h(primitive.DestylerPrimitive, {
1664
- "ref": (el) => this.forwardRef(el),
1665
- "style": {
1666
- touchAction: "none",
1667
- userSelect: "none"
1668
- },
1669
- "role": "separator",
1670
- "data-resize-handle": "",
1671
- "tabindex": this.$props.tabindex,
1672
- "data-state": this.state,
1673
- "data-disabled": this.disabled ? "" : void 0,
1674
- "data-orientation": this.direction,
1675
- "data-panel-group-id": this.groupId,
1676
- "data-resize-handle-active": this.state === "drag" ? "pointer" : this.isFocused ? "keyboard" : void 0,
1677
- "data-resize-handle-state": this.state,
1678
- "data-panel-resize-handle-enabled": !this.disabled,
1679
- "data-panel-resize-handle-id": this.resizeHandleId,
1680
- "onBlur": () => {
1681
- this.isFocused = false;
1682
- },
1683
- "onFocus": () => {
1684
- this.isFocused = false;
1685
- }
1686
- }, () => this.$slots.default?.()), [
1687
- [directives.BindOnceDirective, { id: this.resizeHandleId }]
1688
- ]);
1689
- }
1690
- });
1691
-
1692
- const destylerSplitterPanelProps = {
1693
- as: {
1694
- type: [String, Object],
1695
- required: false,
1696
- default: "div"
1697
- },
1698
- asChild: {
1699
- type: Boolean,
1700
- required: false,
1701
- default: false
1702
- },
1703
- collapsedSize: {
1704
- type: Number,
1705
- required: false
1706
- },
1707
- collapsible: {
1708
- type: Boolean,
1709
- required: false
1710
- },
1711
- defaultSize: {
1712
- type: Number,
1713
- required: false
1714
- },
1715
- id: {
1716
- type: String,
1717
- required: false
1718
- },
1719
- maxSize: {
1720
- type: Number,
1721
- required: false
1722
- },
1723
- minSize: {
1724
- type: Number,
1725
- required: false
1726
- },
1727
- order: {
1728
- type: Number,
1729
- required: false
1730
- }
1731
- };
1732
- const DestylerSplitterPanel = vue.defineComponent({
1733
- name: "DestylerSplitterPanel",
1734
- props: destylerSplitterPanelProps,
1735
- emits: ["collapse", "expand", "resize"],
1736
- setup(props, { emit }) {
1737
- const panelGroupContext = injectPanelGroupContext();
1738
- if (panelGroupContext === null)
1739
- throw new Error("DestylerSplitterPanel components must be rendered within a SplitterGroup container");
1740
- const { getPanelStyle, groupId, reevaluatePanelConstraints, registerPanel, unregisterPanel } = panelGroupContext;
1741
- const panelId = useUniqueId(props.id);
1742
- const panelDataRef = vue.computed(() => ({
1743
- callbacks: {
1744
- onCollapse: () => emit("collapse"),
1745
- onExpand: () => emit("expand"),
1746
- onResize: (...args) => emit("resize", ...args)
1747
- },
1748
- constraints: {
1749
- collapsedSize: props.collapsedSize,
1750
- collapsible: props.collapsible,
1751
- defaultSize: props.defaultSize,
1752
- maxSize: props.maxSize,
1753
- minSize: props.minSize
1754
- },
1755
- id: panelId,
1756
- idIsFromProps: props.id !== void 0,
1757
- order: props.order
1758
- }));
1759
- vue.watch(() => panelDataRef.value.constraints, (prevConstraints, constraints) => {
1760
- if (prevConstraints.collapsedSize !== constraints.collapsedSize || prevConstraints.collapsible !== constraints.collapsible || prevConstraints.maxSize !== constraints.maxSize || prevConstraints.minSize !== constraints.minSize)
1761
- reevaluatePanelConstraints(panelDataRef.value, prevConstraints);
1762
- }, { deep: true });
1763
- vue.onMounted(() => {
1764
- const panelData = panelDataRef.value;
1765
- registerPanel(panelData);
1766
- vue.onUnmounted(() => {
1767
- unregisterPanel(panelData);
1768
- });
1769
- });
1770
- const style = vue.computed(() => getPanelStyle(panelDataRef.value, props.defaultSize));
1771
- return {
1772
- groupId,
1773
- panelId,
1774
- style
1775
- };
1776
- },
1777
- render() {
1778
- return vue.withDirectives(vue.h(primitive.DestylerPrimitive, {
1779
- "as": this.$props.as,
1780
- "asChild": this.$props.asChild,
1781
- "style": this.style,
1782
- "data-panel": "",
1783
- "data-panel-collapsible": this.$props.collapsible || void 0,
1784
- "data-panel-group-id": this.groupId,
1785
- "data-panel-id": this.panelId,
1786
- "data-panel-size": Number.parseFloat(`${this.style.flexGrow}`).toFixed(1)
1787
- }, () => this.$slots.default?.()), [
1788
- [directives.BindOnceDirective, { id: this.panelId }]
1789
- ]);
1790
- }
1791
- });
1792
-
1793
- const destylerSplitterRootProps = {
1794
- as: {
1795
- type: [String, Object],
1796
- required: false,
1797
- default: "div"
1798
- },
1799
- asChild: {
1800
- type: Boolean,
1801
- required: false,
1802
- default: false
1803
- }
1804
- };
1805
- const DestylerSplitterRoot = vue.defineComponent({
1806
- name: "DestylerSplitterRoot",
1807
- props: destylerSplitterRootProps,
1808
- setup(_) {
1809
- composition.useForwardExpose();
1810
- },
1811
- render() {
1812
- return vue.h(primitive.DestylerPrimitive, {
1813
- as: this.$props.as,
1814
- asChild: this.$props.asChild
1815
- }, () => this.$slots.default?.());
1816
- }
1817
- });
1818
-
1819
- exports.DestylerSplitterGroup = DestylerSplitterGroup;
1820
- exports.DestylerSplitterPanel = DestylerSplitterPanel;
1821
- exports.DestylerSplitterResizeHandle = DestylerSplitterResizeHandle;
1822
- exports.DestylerSplitterRoot = DestylerSplitterRoot;
3
+ const index = require('./component.cjs');
4
+ require('vue');
5
+ require('@destyler/primitive');
6
+ require('@destyler/shared');
7
+ require('@destyler/composition');
8
+
9
+
10
+
11
+ exports.SplitterGroup = index.SplitterGroup;
12
+ exports.SplitterPanel = index.SplitterPanel;
13
+ exports.SplitterResizeHandle = index.SplitterResizeHandle;
14
+ exports.SplitterRoot = index.SplitterRoot;
15
+ exports.splitterGroupProps = index.splitterGroupProps;
16
+ exports.splitterPanelProps = index.splitterPanelProps;
17
+ exports.splitterResizeHandleProps = index.splitterResizeHandleProps;
18
+ exports.splitterRootProps = index.splitterRootProps;