@zag-js/splitter 1.39.1 → 1.41.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.mts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/splitter.connect.js +61 -29
- package/dist/splitter.connect.mjs +61 -29
- package/dist/splitter.dom.d.mts +4 -3
- package/dist/splitter.dom.d.ts +4 -3
- package/dist/splitter.dom.js +31 -2
- package/dist/splitter.dom.mjs +31 -3
- package/dist/splitter.machine.js +168 -59
- package/dist/splitter.machine.mjs +169 -61
- package/dist/splitter.types.d.mts +27 -8
- package/dist/splitter.types.d.ts +27 -8
- package/dist/utils/aria.d.mts +9 -3
- package/dist/utils/aria.d.ts +9 -3
- package/dist/utils/aria.js +9 -0
- package/dist/utils/aria.mjs +9 -0
- package/dist/utils/panel.d.mts +13 -12
- package/dist/utils/panel.d.ts +13 -12
- package/dist/utils/panel.js +41 -7
- package/dist/utils/panel.mjs +41 -7
- package/dist/utils/preserve-fixed-panel-sizes.d.mts +18 -0
- package/dist/utils/preserve-fixed-panel-sizes.d.ts +18 -0
- package/dist/utils/preserve-fixed-panel-sizes.js +91 -0
- package/dist/utils/preserve-fixed-panel-sizes.mjs +68 -0
- package/dist/utils/registry.js +1 -1
- package/dist/utils/registry.mjs +2 -2
- package/dist/utils/resize-by-delta.d.mts +2 -2
- package/dist/utils/resize-by-delta.d.ts +2 -2
- package/dist/utils/resize-panel.d.mts +2 -2
- package/dist/utils/resize-panel.d.ts +2 -2
- package/dist/utils/size.d.mts +17 -0
- package/dist/utils/size.d.ts +17 -0
- package/dist/utils/size.js +138 -0
- package/dist/utils/size.mjs +111 -0
- package/dist/utils/validate-sizes.d.mts +2 -2
- package/dist/utils/validate-sizes.d.ts +2 -2
- package/package.json +6 -6
|
@@ -2,7 +2,7 @@ import "./chunk-QZ7TP4HQ.mjs";
|
|
|
2
2
|
|
|
3
3
|
// src/splitter.machine.ts
|
|
4
4
|
import { createMachine } from "@zag-js/core";
|
|
5
|
-
import { observeChildren, trackPointerMove } from "@zag-js/dom-query";
|
|
5
|
+
import { observeChildren, resizeObserverBorderBox, trackPointerMove } from "@zag-js/dom-query";
|
|
6
6
|
import { ensure, ensureProps, isEqual, next, prev, setRafTimeout } from "@zag-js/utils";
|
|
7
7
|
import * as dom from "./splitter.dom.mjs";
|
|
8
8
|
import { getAriaValue } from "./utils/aria.mjs";
|
|
@@ -11,12 +11,13 @@ import {
|
|
|
11
11
|
findPanelDataIndex,
|
|
12
12
|
getPanelById,
|
|
13
13
|
getPanelLayout,
|
|
14
|
-
getUnsafeDefaultSize,
|
|
15
14
|
panelDataHelper,
|
|
16
15
|
serializePanels,
|
|
17
16
|
sortPanels
|
|
18
17
|
} from "./utils/panel.mjs";
|
|
18
|
+
import { preserveFixedPanelSizes } from "./utils/preserve-fixed-panel-sizes.mjs";
|
|
19
19
|
import { resizeByDelta } from "./utils/resize-by-delta.mjs";
|
|
20
|
+
import { getGroupSize, normalizePanels, resolvePanelSizes } from "./utils/size.mjs";
|
|
20
21
|
import { validateSizes } from "./utils/validate-sizes.mjs";
|
|
21
22
|
var machine = createMachine({
|
|
22
23
|
props({ props }) {
|
|
@@ -34,15 +35,18 @@ var machine = createMachine({
|
|
|
34
35
|
},
|
|
35
36
|
context({ prop, bindable, getContext, getRefs }) {
|
|
36
37
|
return {
|
|
38
|
+
panels: bindable(() => ({
|
|
39
|
+
defaultValue: normalizePanels(prop("panels"), null, prop("orientation"))
|
|
40
|
+
})),
|
|
37
41
|
size: bindable(() => ({
|
|
38
|
-
|
|
39
|
-
defaultValue: prop("defaultSize"),
|
|
42
|
+
defaultValue: [],
|
|
40
43
|
isEqual(a, b) {
|
|
41
44
|
return b != null && fuzzySizeEqual(a, b);
|
|
42
45
|
},
|
|
43
46
|
onChange(value) {
|
|
44
47
|
const ctx = getContext();
|
|
45
48
|
const refs = getRefs();
|
|
49
|
+
if (refs.get("suppressOnResize")) return;
|
|
46
50
|
const sizesBeforeCollapse = refs.get("panelSizeBeforeCollapse");
|
|
47
51
|
const expandToSizes = Object.fromEntries(sizesBeforeCollapse.entries());
|
|
48
52
|
const resizeTriggerId = ctx.get("dragState")?.resizeTriggerId ?? null;
|
|
@@ -64,15 +68,27 @@ var machine = createMachine({
|
|
|
64
68
|
};
|
|
65
69
|
},
|
|
66
70
|
watch({ track, action, prop }) {
|
|
67
|
-
track(
|
|
68
|
-
|
|
69
|
-
|
|
71
|
+
track(
|
|
72
|
+
[
|
|
73
|
+
() => serializePanels(prop("panels")),
|
|
74
|
+
() => JSON.stringify(prop("size") ?? []),
|
|
75
|
+
() => JSON.stringify(prop("defaultSize") ?? [])
|
|
76
|
+
],
|
|
77
|
+
() => {
|
|
78
|
+
action(["syncSize"]);
|
|
79
|
+
}
|
|
80
|
+
);
|
|
70
81
|
},
|
|
71
82
|
refs() {
|
|
72
83
|
return {
|
|
73
84
|
panelSizeBeforeCollapse: /* @__PURE__ */ new Map(),
|
|
74
85
|
prevDelta: 0,
|
|
75
|
-
panelIdToLastNotifiedSizeMap: /* @__PURE__ */ new Map()
|
|
86
|
+
panelIdToLastNotifiedSizeMap: /* @__PURE__ */ new Map(),
|
|
87
|
+
initialSize: null,
|
|
88
|
+
prevInitialLayout: null,
|
|
89
|
+
prevGroupSize: null,
|
|
90
|
+
lastRequestedSize: null,
|
|
91
|
+
suppressOnResize: false
|
|
76
92
|
};
|
|
77
93
|
},
|
|
78
94
|
computed: {
|
|
@@ -84,6 +100,9 @@ var machine = createMachine({
|
|
|
84
100
|
"SIZE.SET": {
|
|
85
101
|
actions: ["setSize"]
|
|
86
102
|
},
|
|
103
|
+
"SIZE.RESET": {
|
|
104
|
+
actions: ["resetSize"]
|
|
105
|
+
},
|
|
87
106
|
"PANEL.COLLAPSE": {
|
|
88
107
|
actions: ["collapsePanel"]
|
|
89
108
|
},
|
|
@@ -92,11 +111,14 @@ var machine = createMachine({
|
|
|
92
111
|
},
|
|
93
112
|
"PANEL.RESIZE": {
|
|
94
113
|
actions: ["resizePanel"]
|
|
114
|
+
},
|
|
115
|
+
"ROOT.RESIZE": {
|
|
116
|
+
actions: ["syncSize"]
|
|
95
117
|
}
|
|
96
118
|
},
|
|
97
119
|
entry: ["syncSize"],
|
|
98
120
|
exit: ["clearGlobalCursor"],
|
|
99
|
-
effects: ["trackResizeHandles"],
|
|
121
|
+
effects: ["trackResizeHandles", "trackRootResize"],
|
|
100
122
|
states: {
|
|
101
123
|
idle: {
|
|
102
124
|
entry: ["clearDraggingState", "clearKeyboardState"],
|
|
@@ -171,14 +193,27 @@ var machine = createMachine({
|
|
|
171
193
|
POINTER_MOVE: {
|
|
172
194
|
actions: ["setPointerValue", "setGlobalCursor"]
|
|
173
195
|
},
|
|
174
|
-
POINTER_UP:
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
196
|
+
POINTER_UP: [
|
|
197
|
+
{
|
|
198
|
+
guard: "isResizeTriggerFocused",
|
|
199
|
+
target: "focused",
|
|
200
|
+
actions: ["invokeOnResizeEnd", "setKeyboardState", "clearDraggingState", "clearGlobalCursor"]
|
|
201
|
+
},
|
|
202
|
+
{
|
|
203
|
+
target: "idle",
|
|
204
|
+
actions: ["invokeOnResizeEnd", "clearGlobalCursor"]
|
|
205
|
+
}
|
|
206
|
+
]
|
|
178
207
|
}
|
|
179
208
|
}
|
|
180
209
|
},
|
|
181
210
|
implementations: {
|
|
211
|
+
guards: {
|
|
212
|
+
isResizeTriggerFocused({ context, scope }) {
|
|
213
|
+
const dragState = context.get("dragState");
|
|
214
|
+
return scope.isActiveElement(dom.getResizeTriggerEl(scope, dragState?.resizeTriggerId));
|
|
215
|
+
}
|
|
216
|
+
},
|
|
182
217
|
effects: {
|
|
183
218
|
trackResizeHandles: ({ prop, scope, send }) => {
|
|
184
219
|
const registry = prop("registry");
|
|
@@ -211,6 +246,13 @@ var machine = createMachine({
|
|
|
211
246
|
observeCleanup?.();
|
|
212
247
|
};
|
|
213
248
|
},
|
|
249
|
+
trackRootResize: ({ scope, send }) => {
|
|
250
|
+
const rootEl = dom.getRootEl(scope);
|
|
251
|
+
if (!rootEl) return;
|
|
252
|
+
return resizeObserverBorderBox.observe(rootEl, () => {
|
|
253
|
+
send({ type: "ROOT.RESIZE" });
|
|
254
|
+
});
|
|
255
|
+
},
|
|
214
256
|
waitForHoverDelay: ({ send }) => {
|
|
215
257
|
return setRafTimeout(() => {
|
|
216
258
|
send({ type: "HOVER_DELAY" });
|
|
@@ -230,40 +272,85 @@ var machine = createMachine({
|
|
|
230
272
|
},
|
|
231
273
|
actions: {
|
|
232
274
|
setSize(params) {
|
|
233
|
-
const { context, event, prop } = params;
|
|
275
|
+
const { context, event, prop, scope } = params;
|
|
234
276
|
const unsafeSize = event.size;
|
|
235
277
|
const prevSize = context.get("size");
|
|
236
|
-
const panels =
|
|
278
|
+
const panels = context.get("panels");
|
|
237
279
|
const safeSize = validateSizes({
|
|
238
|
-
size:
|
|
280
|
+
size: resolvePanelSizes({
|
|
281
|
+
sizes: unsafeSize,
|
|
282
|
+
panels: prop("panels"),
|
|
283
|
+
rootEl: dom.getRootEl(scope),
|
|
284
|
+
orientation: prop("orientation")
|
|
285
|
+
}),
|
|
239
286
|
panels
|
|
240
287
|
});
|
|
241
288
|
if (!isEqual(prevSize, safeSize)) {
|
|
242
289
|
setSize(params, safeSize);
|
|
243
290
|
}
|
|
244
291
|
},
|
|
245
|
-
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
panels,
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
292
|
+
resetSize(params) {
|
|
293
|
+
const { refs, context, prop, scope } = params;
|
|
294
|
+
const initialSize = refs.get("initialSize");
|
|
295
|
+
const nextSize = initialSize ?? validateSizes({
|
|
296
|
+
size: resolvePanelSizes({
|
|
297
|
+
sizes: prop("size") ?? prop("defaultSize"),
|
|
298
|
+
panels: prop("panels"),
|
|
299
|
+
rootEl: dom.getRootEl(scope),
|
|
300
|
+
orientation: prop("orientation")
|
|
301
|
+
}),
|
|
302
|
+
panels: context.get("panels")
|
|
303
|
+
});
|
|
304
|
+
setSize(params, nextSize);
|
|
305
|
+
},
|
|
306
|
+
syncSize(params) {
|
|
307
|
+
const { context, scope, prop, refs } = params;
|
|
308
|
+
const rootEl = dom.getRootEl(scope);
|
|
309
|
+
if (!rootEl) return;
|
|
310
|
+
const orientation = prop("orientation");
|
|
311
|
+
const nextGroupSize = getGroupSize(rootEl, orientation);
|
|
312
|
+
if (nextGroupSize <= 0) return;
|
|
313
|
+
const panels = normalizePanels(prop("panels"), rootEl, prop("orientation"));
|
|
314
|
+
context.set("panels", panels);
|
|
315
|
+
const sizeSpec = prop("size") ?? prop("defaultSize");
|
|
316
|
+
const initialLayout = `${getPanelLayout(prop("panels"))}:${JSON.stringify(prop("size") ?? [])}:${JSON.stringify(prop("defaultSize") ?? [])}`;
|
|
317
|
+
const prevGroupSize = refs.get("prevGroupSize");
|
|
318
|
+
const currentSize = context.get("size");
|
|
319
|
+
const nextResolvedSize = resolvePanelSizes({
|
|
320
|
+
sizes: sizeSpec,
|
|
321
|
+
panels: prop("panels"),
|
|
322
|
+
rootEl,
|
|
323
|
+
orientation
|
|
324
|
+
});
|
|
325
|
+
const canPreserveLayout = prevGroupSize != null && prevGroupSize !== nextGroupSize && currentSize.length === panels.length;
|
|
326
|
+
const nextSize = canPreserveLayout ? preserveFixedPanelSizes({
|
|
327
|
+
panels,
|
|
328
|
+
prevLayout: currentSize,
|
|
329
|
+
prevGroupSize,
|
|
330
|
+
nextGroupSize
|
|
331
|
+
}) : nextResolvedSize;
|
|
332
|
+
const safeSize = validateSizes({
|
|
333
|
+
size: nextSize,
|
|
257
334
|
panels
|
|
258
335
|
});
|
|
259
|
-
if (
|
|
260
|
-
|
|
336
|
+
if (refs.get("prevInitialLayout") !== initialLayout) {
|
|
337
|
+
refs.set("initialSize", safeSize);
|
|
338
|
+
refs.set("prevInitialLayout", initialLayout);
|
|
339
|
+
}
|
|
340
|
+
const prevSize = context.get("size");
|
|
341
|
+
if (!isEqual(prevSize, safeSize)) {
|
|
342
|
+
refs.set("suppressOnResize", prop("size") != null || prevSize.length === 0);
|
|
343
|
+
context.set("size", safeSize);
|
|
344
|
+
refs.set("suppressOnResize", false);
|
|
261
345
|
}
|
|
346
|
+
refs.set("prevGroupSize", nextGroupSize);
|
|
262
347
|
},
|
|
263
348
|
setDraggingState({ context, event, prop, scope }) {
|
|
264
349
|
const orientation = prop("orientation");
|
|
265
350
|
const size = context.get("size");
|
|
266
351
|
const resizeTriggerId = event.id;
|
|
352
|
+
const resolvedResizeTriggerId = dom.resolveResizeTriggerId(scope, resizeTriggerId);
|
|
353
|
+
if (!resolvedResizeTriggerId) return;
|
|
267
354
|
const panelGroupEl = dom.getRootEl(scope);
|
|
268
355
|
if (!panelGroupEl) return;
|
|
269
356
|
const handleElement = dom.getResizeTriggerEl(scope, resizeTriggerId);
|
|
@@ -271,6 +358,7 @@ var machine = createMachine({
|
|
|
271
358
|
const initialCursorPosition = orientation === "horizontal" ? event.point.x : event.point.y;
|
|
272
359
|
context.set("dragState", {
|
|
273
360
|
resizeTriggerId: event.id,
|
|
361
|
+
resolvedResizeTriggerId,
|
|
274
362
|
resizeTriggerRect: handleElement.getBoundingClientRect(),
|
|
275
363
|
initialCursorPosition,
|
|
276
364
|
initialSize: size
|
|
@@ -279,23 +367,26 @@ var machine = createMachine({
|
|
|
279
367
|
clearDraggingState({ context }) {
|
|
280
368
|
context.set("dragState", null);
|
|
281
369
|
},
|
|
282
|
-
setKeyboardState({ context, event }) {
|
|
370
|
+
setKeyboardState({ context, event, scope }) {
|
|
371
|
+
const id = event.id ?? context.get("dragState")?.resizeTriggerId;
|
|
372
|
+
if (id == null) return;
|
|
283
373
|
context.set("keyboardState", {
|
|
284
|
-
resizeTriggerId:
|
|
374
|
+
resizeTriggerId: id,
|
|
375
|
+
resolvedResizeTriggerId: dom.resolveResizeTriggerId(scope, id)
|
|
285
376
|
});
|
|
286
377
|
},
|
|
287
378
|
clearKeyboardState({ context }) {
|
|
288
379
|
context.set("keyboardState", null);
|
|
289
380
|
},
|
|
290
381
|
collapsePanel(params) {
|
|
291
|
-
const { context,
|
|
382
|
+
const { context, event, refs } = params;
|
|
292
383
|
const prevSize = context.get("size");
|
|
293
|
-
const panels =
|
|
384
|
+
const panels = context.get("panels");
|
|
294
385
|
const panel = panels.find((panel2) => panel2.id === event.id);
|
|
295
386
|
ensure(panel, () => `Panel data not found for id "${event.id}"`);
|
|
296
387
|
if (panel.collapsible) {
|
|
297
388
|
const { collapsedSize = 0, panelSize, pivotIndices } = panelDataHelper(panels, panel, prevSize);
|
|
298
|
-
ensure(panelSize, () => `Panel size not found for panel "${panel.id}"`);
|
|
389
|
+
ensure(panelSize != null, () => `Panel size not found for panel "${panel.id}"`);
|
|
299
390
|
if (!fuzzyNumbersEqual(panelSize, collapsedSize)) {
|
|
300
391
|
refs.get("panelSizeBeforeCollapse").set(panel.id, panelSize);
|
|
301
392
|
const isLastPanel = findPanelDataIndex(panels, panel) === panels.length - 1;
|
|
@@ -315,8 +406,8 @@ var machine = createMachine({
|
|
|
315
406
|
}
|
|
316
407
|
},
|
|
317
408
|
expandPanel(params) {
|
|
318
|
-
const { context,
|
|
319
|
-
const panels =
|
|
409
|
+
const { context, event, refs } = params;
|
|
410
|
+
const panels = context.get("panels");
|
|
320
411
|
const prevSize = context.get("size");
|
|
321
412
|
const panel = panels.find((panel2) => panel2.id === event.id);
|
|
322
413
|
ensure(panel, () => `Panel data not found for id "${event.id}"`);
|
|
@@ -348,13 +439,13 @@ var machine = createMachine({
|
|
|
348
439
|
}
|
|
349
440
|
},
|
|
350
441
|
resizePanel(params) {
|
|
351
|
-
const { context,
|
|
442
|
+
const { context, event } = params;
|
|
352
443
|
const prevSize = context.get("size");
|
|
353
|
-
const panels =
|
|
444
|
+
const panels = context.get("panels");
|
|
354
445
|
const panel = getPanelById(panels, event.id);
|
|
355
446
|
const unsafePanelSize = event.size;
|
|
356
447
|
const { panelSize, pivotIndices } = panelDataHelper(panels, panel, prevSize);
|
|
357
|
-
ensure(panelSize, () => `Panel size not found for panel "${panel.id}"`);
|
|
448
|
+
ensure(panelSize != null, () => `Panel size not found for panel "${panel.id}"`);
|
|
358
449
|
const isLastPanel = findPanelDataIndex(panels, panel) === panels.length - 1;
|
|
359
450
|
const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
|
|
360
451
|
const nextSize = resizeByDelta({
|
|
@@ -373,11 +464,11 @@ var machine = createMachine({
|
|
|
373
464
|
const { context, event, prop, scope } = params;
|
|
374
465
|
const dragState = context.get("dragState");
|
|
375
466
|
if (!dragState) return;
|
|
376
|
-
const {
|
|
377
|
-
const panels =
|
|
467
|
+
const { resolvedResizeTriggerId, initialSize, initialCursorPosition } = dragState;
|
|
468
|
+
const panels = context.get("panels");
|
|
378
469
|
const panelGroupElement = dom.getRootEl(scope);
|
|
379
470
|
ensure(panelGroupElement, () => `Panel group element not found`);
|
|
380
|
-
const pivotIndices =
|
|
471
|
+
const pivotIndices = resolvedResizeTriggerId.split(":").map((id) => panels.findIndex((panel) => panel.id === id));
|
|
381
472
|
const horizontal = prop("orientation") === "horizontal";
|
|
382
473
|
const cursorPosition = horizontal ? event.point.x : event.point.y;
|
|
383
474
|
const groupRect = panelGroupElement.getBoundingClientRect();
|
|
@@ -398,9 +489,10 @@ var machine = createMachine({
|
|
|
398
489
|
}
|
|
399
490
|
},
|
|
400
491
|
setKeyboardValue(params) {
|
|
401
|
-
const { context, event
|
|
402
|
-
const panelDataArray =
|
|
403
|
-
const resizeTriggerId = event.id;
|
|
492
|
+
const { context, event } = params;
|
|
493
|
+
const panelDataArray = context.get("panels");
|
|
494
|
+
const resizeTriggerId = dom.resolveResizeTriggerId(params.scope, event.id);
|
|
495
|
+
if (!resizeTriggerId) return;
|
|
404
496
|
const delta = event.delta;
|
|
405
497
|
const pivotIndices = resizeTriggerId.split(":").map((id) => panelDataArray.findIndex((panelData) => panelData.id === id));
|
|
406
498
|
const prevSize = context.get("size");
|
|
@@ -416,11 +508,11 @@ var machine = createMachine({
|
|
|
416
508
|
setSize(params, nextSize);
|
|
417
509
|
}
|
|
418
510
|
},
|
|
419
|
-
invokeOnResizeEnd({ context, prop }) {
|
|
511
|
+
invokeOnResizeEnd({ context, prop, refs }) {
|
|
420
512
|
queueMicrotask(() => {
|
|
421
513
|
const dragState = context.get("dragState");
|
|
422
514
|
prop("onResizeEnd")?.({
|
|
423
|
-
size: context.get("size"),
|
|
515
|
+
size: refs.get("lastRequestedSize") ?? context.get("size"),
|
|
424
516
|
resizeTriggerId: dragState?.resizeTriggerId ?? null
|
|
425
517
|
});
|
|
426
518
|
});
|
|
@@ -431,10 +523,10 @@ var machine = createMachine({
|
|
|
431
523
|
});
|
|
432
524
|
},
|
|
433
525
|
collapseOrExpandPanel(params) {
|
|
434
|
-
const { context,
|
|
435
|
-
const panelDataArray =
|
|
526
|
+
const { context, refs } = params;
|
|
527
|
+
const panelDataArray = context.get("panels");
|
|
436
528
|
const sizes = context.get("size");
|
|
437
|
-
const resizeTriggerId = context.get("keyboardState")?.
|
|
529
|
+
const resizeTriggerId = context.get("keyboardState")?.resolvedResizeTriggerId;
|
|
438
530
|
const [idBefore, idAfter] = resizeTriggerId?.split(":") ?? [];
|
|
439
531
|
const index = panelDataArray.findIndex((panelData2) => panelData2.id === idBefore);
|
|
440
532
|
if (index === -1) return;
|
|
@@ -448,7 +540,7 @@ var machine = createMachine({
|
|
|
448
540
|
);
|
|
449
541
|
const nextSize = resizeByDelta({
|
|
450
542
|
delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
|
|
451
|
-
initialSize:
|
|
543
|
+
initialSize: refs.get("initialSize") ?? sizes,
|
|
452
544
|
panels: panelDataArray,
|
|
453
545
|
pivotIndices,
|
|
454
546
|
prevSize: sizes,
|
|
@@ -459,18 +551,19 @@ var machine = createMachine({
|
|
|
459
551
|
}
|
|
460
552
|
}
|
|
461
553
|
},
|
|
462
|
-
setGlobalCursor(
|
|
554
|
+
setGlobalCursor(params) {
|
|
555
|
+
const { context, scope, prop } = params;
|
|
463
556
|
const registry = prop("registry");
|
|
464
557
|
if (registry) return;
|
|
465
558
|
const dragState = context.get("dragState");
|
|
466
559
|
if (!dragState) return;
|
|
467
|
-
const panels =
|
|
560
|
+
const panels = context.get("panels");
|
|
468
561
|
const horizontal = prop("orientation") === "horizontal";
|
|
469
|
-
const [idBefore] = dragState.
|
|
562
|
+
const [idBefore] = dragState.resolvedResizeTriggerId.split(":");
|
|
470
563
|
const indexBefore = panels.findIndex((panel2) => panel2.id === idBefore);
|
|
471
564
|
const panel = panels[indexBefore];
|
|
472
565
|
const size = context.get("size");
|
|
473
|
-
const aria = getAriaValue(size, panels, dragState.
|
|
566
|
+
const aria = getAriaValue(size, panels, dragState.resolvedResizeTriggerId);
|
|
474
567
|
const isAtMin = fuzzyNumbersEqual(aria.valueNow, aria.valueMin) || fuzzyNumbersEqual(aria.valueNow, panel.collapsedSize);
|
|
475
568
|
const isAtMax = fuzzyNumbersEqual(aria.valueNow, aria.valueMax);
|
|
476
569
|
const cursorState = { isAtMin, isAtMax };
|
|
@@ -490,21 +583,36 @@ var machine = createMachine({
|
|
|
490
583
|
});
|
|
491
584
|
function setSize(params, sizes) {
|
|
492
585
|
const { refs, prop, context } = params;
|
|
493
|
-
const panelsArray =
|
|
586
|
+
const panelsArray = context.get("panels");
|
|
494
587
|
const onCollapse = prop("onCollapse");
|
|
495
588
|
const onExpand = prop("onExpand");
|
|
589
|
+
const onResize = prop("onResize");
|
|
496
590
|
const onResizeStart = prop("onResizeStart");
|
|
497
591
|
const onResizeEnd = prop("onResizeEnd");
|
|
498
592
|
const panelIdToLastNotifiedSizeMap = refs.get("panelIdToLastNotifiedSizeMap");
|
|
499
593
|
const dragState = context.get("dragState");
|
|
500
594
|
const keyboardState = context.get("keyboardState");
|
|
501
595
|
const isProgrammatic = dragState === null && keyboardState === null;
|
|
596
|
+
refs.set("lastRequestedSize", sizes);
|
|
502
597
|
if (isProgrammatic && onResizeStart) {
|
|
503
598
|
queueMicrotask(() => {
|
|
504
599
|
onResizeStart();
|
|
505
600
|
});
|
|
506
601
|
}
|
|
507
|
-
|
|
602
|
+
if (prop("size") == null) {
|
|
603
|
+
context.set("size", sizes);
|
|
604
|
+
} else if (onResize) {
|
|
605
|
+
const sizesBeforeCollapse = refs.get("panelSizeBeforeCollapse");
|
|
606
|
+
const expandToSizes = Object.fromEntries(sizesBeforeCollapse.entries());
|
|
607
|
+
const resizeTriggerId = dragState?.resizeTriggerId ?? null;
|
|
608
|
+
const layout = getPanelLayout(prop("panels"));
|
|
609
|
+
onResize({
|
|
610
|
+
size: sizes,
|
|
611
|
+
layout,
|
|
612
|
+
resizeTriggerId,
|
|
613
|
+
expandToSizes
|
|
614
|
+
});
|
|
615
|
+
}
|
|
508
616
|
sizes.forEach((size, index) => {
|
|
509
617
|
const panelData = panelsArray[index];
|
|
510
618
|
ensure(panelData, () => `Panel data not found for index ${index}`);
|
|
@@ -512,11 +620,11 @@ function setSize(params, sizes) {
|
|
|
512
620
|
const lastNotifiedSize = panelIdToLastNotifiedSizeMap.get(panelId);
|
|
513
621
|
if (lastNotifiedSize == null || size !== lastNotifiedSize) {
|
|
514
622
|
panelIdToLastNotifiedSizeMap.set(panelId, size);
|
|
515
|
-
if (collapsible && (onCollapse || onExpand)) {
|
|
516
|
-
if (
|
|
623
|
+
if (collapsible && lastNotifiedSize != null && (onCollapse || onExpand)) {
|
|
624
|
+
if (fuzzyNumbersEqual(lastNotifiedSize, collapsedSize) && !fuzzyNumbersEqual(size, collapsedSize)) {
|
|
517
625
|
onExpand?.({ panelId, size });
|
|
518
626
|
}
|
|
519
|
-
if (
|
|
627
|
+
if (!fuzzyNumbersEqual(lastNotifiedSize, collapsedSize) && fuzzyNumbersEqual(size, collapsedSize)) {
|
|
520
628
|
onCollapse?.({ panelId, size });
|
|
521
629
|
}
|
|
522
630
|
}
|
|
@@ -4,7 +4,9 @@ import { SplitterRegistry } from './utils/registry.mjs';
|
|
|
4
4
|
|
|
5
5
|
type ResizeEvent = PointerEvent | KeyboardEvent;
|
|
6
6
|
type PanelId = string;
|
|
7
|
-
type ResizeTriggerId = `${PanelId}:${PanelId}`;
|
|
7
|
+
type ResizeTriggerId = `${PanelId}:${PanelId}` | `${PanelId}:` | `:${PanelId}`;
|
|
8
|
+
type PanelSize = number | string;
|
|
9
|
+
type PanelResizeBehavior = "preserve-relative-size" | "preserve-pixel-size";
|
|
8
10
|
interface PanelData {
|
|
9
11
|
/**
|
|
10
12
|
* The id of the panel.
|
|
@@ -17,20 +19,29 @@ interface PanelData {
|
|
|
17
19
|
/**
|
|
18
20
|
* The minimum size of the panel.
|
|
19
21
|
*/
|
|
20
|
-
minSize?:
|
|
22
|
+
minSize?: PanelSize | undefined;
|
|
21
23
|
/**
|
|
22
24
|
* The maximum size of the panel.
|
|
23
25
|
*/
|
|
24
|
-
maxSize?:
|
|
26
|
+
maxSize?: PanelSize | undefined;
|
|
25
27
|
/**
|
|
26
28
|
* Whether the panel is collapsible.
|
|
27
29
|
*/
|
|
28
30
|
collapsible?: boolean | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* How the panel should behave when the parent group is resized.
|
|
33
|
+
*/
|
|
34
|
+
resizeBehavior?: PanelResizeBehavior | undefined;
|
|
29
35
|
/**
|
|
30
36
|
* The size of the panel when collapsed.
|
|
31
37
|
*/
|
|
32
|
-
collapsedSize?:
|
|
38
|
+
collapsedSize?: PanelSize | undefined;
|
|
33
39
|
}
|
|
40
|
+
type NormalizedPanelData = Omit<PanelData, "minSize" | "maxSize" | "collapsedSize"> & {
|
|
41
|
+
minSize?: number | undefined;
|
|
42
|
+
maxSize?: number | undefined;
|
|
43
|
+
collapsedSize?: number | undefined;
|
|
44
|
+
};
|
|
34
45
|
interface CursorState {
|
|
35
46
|
isAtMin: boolean;
|
|
36
47
|
isAtMax: boolean;
|
|
@@ -64,12 +75,12 @@ interface SplitterProps extends DirectionProperty, CommonProperties {
|
|
|
64
75
|
/**
|
|
65
76
|
* The controlled size data of the panels
|
|
66
77
|
*/
|
|
67
|
-
size?:
|
|
78
|
+
size?: PanelSize[] | undefined;
|
|
68
79
|
/**
|
|
69
80
|
* The initial size of the panels when rendered.
|
|
70
81
|
* Use when you don't need to control the size of the panels.
|
|
71
82
|
*/
|
|
72
|
-
defaultSize?:
|
|
83
|
+
defaultSize?: PanelSize[] | undefined;
|
|
73
84
|
/**
|
|
74
85
|
* The size constraints of the panels.
|
|
75
86
|
*/
|
|
@@ -115,22 +126,30 @@ interface SplitterProps extends DirectionProperty, CommonProperties {
|
|
|
115
126
|
type PropsWithDefault = "orientation" | "panels";
|
|
116
127
|
interface DragState {
|
|
117
128
|
resizeTriggerId: string;
|
|
129
|
+
resolvedResizeTriggerId: `${PanelId}:${PanelId}`;
|
|
118
130
|
resizeTriggerRect: DOMRect;
|
|
119
131
|
initialCursorPosition: number;
|
|
120
132
|
initialSize: number[];
|
|
121
133
|
}
|
|
122
134
|
interface KeyboardState {
|
|
123
135
|
resizeTriggerId: string;
|
|
136
|
+
resolvedResizeTriggerId: `${PanelId}:${PanelId}` | null;
|
|
124
137
|
}
|
|
125
138
|
interface Context {
|
|
126
139
|
dragState: DragState | null;
|
|
127
140
|
keyboardState: KeyboardState | null;
|
|
128
141
|
size: number[];
|
|
142
|
+
panels: NormalizedPanelData[];
|
|
129
143
|
}
|
|
130
144
|
interface Refs {
|
|
131
145
|
panelSizeBeforeCollapse: Map<string, number>;
|
|
132
146
|
panelIdToLastNotifiedSizeMap: Map<string, number>;
|
|
133
147
|
prevDelta: number;
|
|
148
|
+
initialSize: number[] | null;
|
|
149
|
+
prevInitialLayout: string | null;
|
|
150
|
+
prevGroupSize: number | null;
|
|
151
|
+
lastRequestedSize: number[] | null;
|
|
152
|
+
suppressOnResize: boolean;
|
|
134
153
|
}
|
|
135
154
|
interface SplitterSchema {
|
|
136
155
|
state: "idle" | "hover:temp" | "hover" | "dragging" | "focused";
|
|
@@ -185,7 +204,7 @@ interface SplitterApi<T extends PropTypes = PropTypes> {
|
|
|
185
204
|
/**
|
|
186
205
|
* Sets the sizes of the panels.
|
|
187
206
|
*/
|
|
188
|
-
setSizes: (size:
|
|
207
|
+
setSizes: (size: PanelSize[]) => void;
|
|
189
208
|
/**
|
|
190
209
|
* Returns the items of the splitter.
|
|
191
210
|
*/
|
|
@@ -240,4 +259,4 @@ interface SplitterApi<T extends PropTypes = PropTypes> {
|
|
|
240
259
|
getResizeTriggerIndicator: (props: ResizeTriggerProps) => T["element"];
|
|
241
260
|
}
|
|
242
261
|
|
|
243
|
-
export type { CursorState, DragState, ElementIds, ExpandCollapseDetails, KeyboardState, PanelData, PanelId, PanelItem, PanelProps, ResizeDetails, ResizeEndDetails, ResizeEvent, ResizeTriggerId, ResizeTriggerItem, ResizeTriggerProps, ResizeTriggerState, SplitterApi, SplitterItem, SplitterMachine, SplitterProps, SplitterSchema, SplitterService };
|
|
262
|
+
export type { CursorState, DragState, ElementIds, ExpandCollapseDetails, KeyboardState, NormalizedPanelData, PanelData, PanelId, PanelItem, PanelProps, PanelResizeBehavior, PanelSize, ResizeDetails, ResizeEndDetails, ResizeEvent, ResizeTriggerId, ResizeTriggerItem, ResizeTriggerProps, ResizeTriggerState, SplitterApi, SplitterItem, SplitterMachine, SplitterProps, SplitterSchema, SplitterService };
|
package/dist/splitter.types.d.ts
CHANGED
|
@@ -4,7 +4,9 @@ import { SplitterRegistry } from './utils/registry.js';
|
|
|
4
4
|
|
|
5
5
|
type ResizeEvent = PointerEvent | KeyboardEvent;
|
|
6
6
|
type PanelId = string;
|
|
7
|
-
type ResizeTriggerId = `${PanelId}:${PanelId}`;
|
|
7
|
+
type ResizeTriggerId = `${PanelId}:${PanelId}` | `${PanelId}:` | `:${PanelId}`;
|
|
8
|
+
type PanelSize = number | string;
|
|
9
|
+
type PanelResizeBehavior = "preserve-relative-size" | "preserve-pixel-size";
|
|
8
10
|
interface PanelData {
|
|
9
11
|
/**
|
|
10
12
|
* The id of the panel.
|
|
@@ -17,20 +19,29 @@ interface PanelData {
|
|
|
17
19
|
/**
|
|
18
20
|
* The minimum size of the panel.
|
|
19
21
|
*/
|
|
20
|
-
minSize?:
|
|
22
|
+
minSize?: PanelSize | undefined;
|
|
21
23
|
/**
|
|
22
24
|
* The maximum size of the panel.
|
|
23
25
|
*/
|
|
24
|
-
maxSize?:
|
|
26
|
+
maxSize?: PanelSize | undefined;
|
|
25
27
|
/**
|
|
26
28
|
* Whether the panel is collapsible.
|
|
27
29
|
*/
|
|
28
30
|
collapsible?: boolean | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* How the panel should behave when the parent group is resized.
|
|
33
|
+
*/
|
|
34
|
+
resizeBehavior?: PanelResizeBehavior | undefined;
|
|
29
35
|
/**
|
|
30
36
|
* The size of the panel when collapsed.
|
|
31
37
|
*/
|
|
32
|
-
collapsedSize?:
|
|
38
|
+
collapsedSize?: PanelSize | undefined;
|
|
33
39
|
}
|
|
40
|
+
type NormalizedPanelData = Omit<PanelData, "minSize" | "maxSize" | "collapsedSize"> & {
|
|
41
|
+
minSize?: number | undefined;
|
|
42
|
+
maxSize?: number | undefined;
|
|
43
|
+
collapsedSize?: number | undefined;
|
|
44
|
+
};
|
|
34
45
|
interface CursorState {
|
|
35
46
|
isAtMin: boolean;
|
|
36
47
|
isAtMax: boolean;
|
|
@@ -64,12 +75,12 @@ interface SplitterProps extends DirectionProperty, CommonProperties {
|
|
|
64
75
|
/**
|
|
65
76
|
* The controlled size data of the panels
|
|
66
77
|
*/
|
|
67
|
-
size?:
|
|
78
|
+
size?: PanelSize[] | undefined;
|
|
68
79
|
/**
|
|
69
80
|
* The initial size of the panels when rendered.
|
|
70
81
|
* Use when you don't need to control the size of the panels.
|
|
71
82
|
*/
|
|
72
|
-
defaultSize?:
|
|
83
|
+
defaultSize?: PanelSize[] | undefined;
|
|
73
84
|
/**
|
|
74
85
|
* The size constraints of the panels.
|
|
75
86
|
*/
|
|
@@ -115,22 +126,30 @@ interface SplitterProps extends DirectionProperty, CommonProperties {
|
|
|
115
126
|
type PropsWithDefault = "orientation" | "panels";
|
|
116
127
|
interface DragState {
|
|
117
128
|
resizeTriggerId: string;
|
|
129
|
+
resolvedResizeTriggerId: `${PanelId}:${PanelId}`;
|
|
118
130
|
resizeTriggerRect: DOMRect;
|
|
119
131
|
initialCursorPosition: number;
|
|
120
132
|
initialSize: number[];
|
|
121
133
|
}
|
|
122
134
|
interface KeyboardState {
|
|
123
135
|
resizeTriggerId: string;
|
|
136
|
+
resolvedResizeTriggerId: `${PanelId}:${PanelId}` | null;
|
|
124
137
|
}
|
|
125
138
|
interface Context {
|
|
126
139
|
dragState: DragState | null;
|
|
127
140
|
keyboardState: KeyboardState | null;
|
|
128
141
|
size: number[];
|
|
142
|
+
panels: NormalizedPanelData[];
|
|
129
143
|
}
|
|
130
144
|
interface Refs {
|
|
131
145
|
panelSizeBeforeCollapse: Map<string, number>;
|
|
132
146
|
panelIdToLastNotifiedSizeMap: Map<string, number>;
|
|
133
147
|
prevDelta: number;
|
|
148
|
+
initialSize: number[] | null;
|
|
149
|
+
prevInitialLayout: string | null;
|
|
150
|
+
prevGroupSize: number | null;
|
|
151
|
+
lastRequestedSize: number[] | null;
|
|
152
|
+
suppressOnResize: boolean;
|
|
134
153
|
}
|
|
135
154
|
interface SplitterSchema {
|
|
136
155
|
state: "idle" | "hover:temp" | "hover" | "dragging" | "focused";
|
|
@@ -185,7 +204,7 @@ interface SplitterApi<T extends PropTypes = PropTypes> {
|
|
|
185
204
|
/**
|
|
186
205
|
* Sets the sizes of the panels.
|
|
187
206
|
*/
|
|
188
|
-
setSizes: (size:
|
|
207
|
+
setSizes: (size: PanelSize[]) => void;
|
|
189
208
|
/**
|
|
190
209
|
* Returns the items of the splitter.
|
|
191
210
|
*/
|
|
@@ -240,4 +259,4 @@ interface SplitterApi<T extends PropTypes = PropTypes> {
|
|
|
240
259
|
getResizeTriggerIndicator: (props: ResizeTriggerProps) => T["element"];
|
|
241
260
|
}
|
|
242
261
|
|
|
243
|
-
export type { CursorState, DragState, ElementIds, ExpandCollapseDetails, KeyboardState, PanelData, PanelId, PanelItem, PanelProps, ResizeDetails, ResizeEndDetails, ResizeEvent, ResizeTriggerId, ResizeTriggerItem, ResizeTriggerProps, ResizeTriggerState, SplitterApi, SplitterItem, SplitterMachine, SplitterProps, SplitterSchema, SplitterService };
|
|
262
|
+
export type { CursorState, DragState, ElementIds, ExpandCollapseDetails, KeyboardState, NormalizedPanelData, PanelData, PanelId, PanelItem, PanelProps, PanelResizeBehavior, PanelSize, ResizeDetails, ResizeEndDetails, ResizeEvent, ResizeTriggerId, ResizeTriggerItem, ResizeTriggerProps, ResizeTriggerState, SplitterApi, SplitterItem, SplitterMachine, SplitterProps, SplitterSchema, SplitterService };
|