@window-splitter/state 0.2.2 → 0.2.3--canary.823a479.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.
Files changed (43) hide show
  1. package/.tshy/commonjs.json +1 -0
  2. package/.tshy/esm.json +1 -0
  3. package/.tshy-build/esm/index.d.ts +327 -0
  4. package/.tshy-build/esm/index.d.ts.map +1 -0
  5. package/.tshy-build/esm/index.js +964 -0
  6. package/.tshy-build/esm/index.js.map +1 -0
  7. package/.tshy-build/esm/package.json +3 -0
  8. package/.turbo/turbo-build.log +1 -1
  9. package/.turbo/turbo-lint.log +1 -1
  10. package/.turbo/turbo-test.log +1023 -129
  11. package/coverage/clover.xml +358 -345
  12. package/coverage/coverage-final.json +1 -1
  13. package/coverage/index.html +18 -18
  14. package/coverage/index.ts.html +624 -402
  15. package/dist/commonjs/index.d.ts +22 -9
  16. package/dist/commonjs/index.d.ts.map +1 -1
  17. package/dist/commonjs/index.js +189 -134
  18. package/dist/commonjs/index.js.map +1 -1
  19. package/dist/esm/index.d.ts +22 -9
  20. package/dist/esm/index.d.ts.map +1 -1
  21. package/dist/esm/index.js +188 -114
  22. package/dist/esm/index.js.map +1 -1
  23. package/package.json +6 -6
  24. package/src/index.ts +279 -153
  25. package/src/machine.test.ts +174 -85
  26. package/src/package.json +3 -0
  27. package/src/utils.test.ts +22 -9
  28. package/dist/commonjs/machine.test.d.ts +0 -5
  29. package/dist/commonjs/machine.test.d.ts.map +0 -1
  30. package/dist/commonjs/machine.test.js +0 -1038
  31. package/dist/commonjs/machine.test.js.map +0 -1
  32. package/dist/commonjs/utils.test.d.ts +0 -2
  33. package/dist/commonjs/utils.test.d.ts.map +0 -1
  34. package/dist/commonjs/utils.test.js +0 -79
  35. package/dist/commonjs/utils.test.js.map +0 -1
  36. package/dist/esm/machine.test.d.ts +0 -5
  37. package/dist/esm/machine.test.d.ts.map +0 -1
  38. package/dist/esm/machine.test.js +0 -1036
  39. package/dist/esm/machine.test.js.map +0 -1
  40. package/dist/esm/utils.test.d.ts +0 -2
  41. package/dist/esm/utils.test.d.ts.map +0 -1
  42. package/dist/esm/utils.test.js +0 -77
  43. package/dist/esm/utils.test.js.map +0 -1
@@ -1,1036 +0,0 @@
1
- /**
2
- * @vitest-environment jsdom
3
- */
4
- import { expect, test, describe, vi } from "vitest";
5
- import { buildTemplate, dragHandlePayload, groupMachine, initializePanel, isPanelHandle, } from "./index.js";
6
- import { createActor } from "xstate";
7
- // import { spring } from "framer-motion";
8
- function getTemplate(actor) {
9
- return buildTemplate(actor.getSnapshot().context);
10
- }
11
- const handleSize = {
12
- type: "pixel",
13
- value: 10,
14
- };
15
- function dragHandle(actor, options) {
16
- for (let i = 0; i < Math.abs(options.delta); i++) {
17
- actor.send({
18
- type: "dragHandle",
19
- handleId: options.id,
20
- value: dragHandlePayload({
21
- orientation: options.orientation || "horizontal",
22
- delta: options.delta > 0 ? 1 : -1,
23
- shiftKey: options.shiftKey,
24
- }),
25
- });
26
- }
27
- }
28
- function sendAll(actor, events) {
29
- for (const event of events) {
30
- actor.send(event);
31
- }
32
- }
33
- function capturePixelValues(actor, cb) {
34
- const firstHandle = actor
35
- .getSnapshot()
36
- .context.items.find((i) => isPanelHandle(i));
37
- if (firstHandle) {
38
- actor.send({ type: "dragHandleStart", handleId: firstHandle.id });
39
- }
40
- cb();
41
- if (firstHandle) {
42
- actor.send({ type: "dragHandleEnd", handleId: firstHandle.id });
43
- }
44
- }
45
- function waitForIdle(actor) {
46
- return new Promise((resolve) => {
47
- setInterval(() => {
48
- const snapshot = actor.getSnapshot();
49
- if (snapshot.value === "idle") {
50
- resolve();
51
- }
52
- }, 100);
53
- });
54
- }
55
- function initializeSizes(actor, options) {
56
- const context = actor.getSnapshot().context;
57
- const { orientation, items } = context;
58
- const template = buildTemplate(context);
59
- const div = document.createElement("div");
60
- div.style.width = `${options.width}px`;
61
- div.style.height = `${options.height}px`;
62
- div.style.display = "grid";
63
- div.id = "group";
64
- if (orientation === "horizontal") {
65
- div.style.gridTemplateColumns = template;
66
- }
67
- else {
68
- div.style.gridTemplateRows = template;
69
- }
70
- for (let i = 0; i < items.length; i++) {
71
- div.appendChild(document.createElement("div"));
72
- }
73
- document.body.appendChild(div);
74
- const childrenSizes = {};
75
- div.childNodes.forEach((node, index) => {
76
- const item = items[index];
77
- if (node instanceof HTMLElement && item) {
78
- const rect = node.getBoundingClientRect();
79
- childrenSizes[item.id] = {
80
- width: rect.width,
81
- height: rect.height,
82
- };
83
- }
84
- });
85
- actor.send({
86
- type: "setSize",
87
- size: { width: options.width, height: options.height },
88
- });
89
- actor.send({
90
- type: "setActualItemsSize",
91
- childrenSizes,
92
- });
93
- }
94
- describe("constraints", () => {
95
- test("works with 2 simple panels - horizontal", () => {
96
- const actor = createActor(groupMachine, {
97
- input: { groupId: "group" },
98
- }).start();
99
- sendAll(actor, [
100
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
101
- {
102
- type: "registerPanelHandle",
103
- data: { id: "resizer-1", size: handleSize },
104
- },
105
- { type: "registerPanel", data: initializePanel({ id: "panel-2" }) },
106
- ]);
107
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, 1fr) 10px minmax(0px, 1fr)"`);
108
- initializeSizes(actor, { width: 500, height: 200 });
109
- // Drag the resizer to the right
110
- capturePixelValues(actor, () => {
111
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
112
- dragHandle(actor, { id: "resizer-1", delta: 10 });
113
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"255px 10px 235px"`);
114
- });
115
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, min(calc(0.5204081632653061 * (100% - 10px)), 100%)) 10px minmax(0px, min(calc(0.47959183673469385 * (100% - 10px)), 100%))"`);
116
- // Drag the resizer to the left
117
- capturePixelValues(actor, () => {
118
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"255px 10px 235px"`);
119
- dragHandle(actor, { id: "resizer-1", delta: -20 });
120
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"235px 10px 255px"`);
121
- });
122
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, min(calc(0.47959183673469385 * (100% - 10px)), 100%)) 10px minmax(0px, min(calc(0.5204081632653061 * (100% - 10px)), 100%))"`);
123
- });
124
- test("works with 2 simple panels - vertical", () => {
125
- const actor = createActor(groupMachine, {
126
- input: { orientation: "vertical", groupId: "group" },
127
- }).start();
128
- sendAll(actor, [
129
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
130
- {
131
- type: "registerPanelHandle",
132
- data: { id: "resizer-1", size: handleSize },
133
- },
134
- { type: "registerPanel", data: initializePanel({ id: "panel-2" }) },
135
- ]);
136
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, 1fr) 10px minmax(0px, 1fr)"`);
137
- initializeSizes(actor, { width: 200, height: 500 });
138
- // Drag the resizer down
139
- capturePixelValues(actor, () => {
140
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
141
- dragHandle(actor, {
142
- id: "resizer-1",
143
- delta: 10,
144
- orientation: "vertical",
145
- });
146
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"255px 10px 235px"`);
147
- });
148
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, min(calc(0.5204081632653061 * (100% - 10px)), 100%)) 10px minmax(0px, min(calc(0.47959183673469385 * (100% - 10px)), 100%))"`);
149
- // Drag the resizer to the up
150
- capturePixelValues(actor, () => {
151
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"255px 10px 235px"`);
152
- dragHandle(actor, {
153
- id: "resizer-1",
154
- delta: -20,
155
- orientation: "vertical",
156
- });
157
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"235px 10px 255px"`);
158
- });
159
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, min(calc(0.47959183673469385 * (100% - 10px)), 100%)) 10px minmax(0px, min(calc(0.5204081632653061 * (100% - 10px)), 100%))"`);
160
- });
161
- test("doesn't register a panel with the same id twice", () => {
162
- const actor = createActor(groupMachine, {
163
- input: {
164
- groupId: "group",
165
- initialItems: [initializePanel({ id: "panel-1" })],
166
- },
167
- }).start();
168
- actor.send({
169
- type: "registerPanel",
170
- data: initializePanel({ id: "panel-1" }),
171
- });
172
- expect(actor.getSnapshot().context.items).toHaveLength(1);
173
- });
174
- test("works with 2 simple panels as input", () => {
175
- const actor = createActor(groupMachine, {
176
- input: {
177
- groupId: "group",
178
- initialItems: [
179
- initializePanel({ id: "panel-1" }),
180
- {
181
- type: "handle",
182
- id: "resizer-1",
183
- size: { type: "pixel", value: 10 },
184
- },
185
- initializePanel({ id: "panel-2" }),
186
- ],
187
- },
188
- }).start();
189
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, 1fr) 10px minmax(0px, 1fr)"`);
190
- initializeSizes(actor, { width: 500, height: 200 });
191
- capturePixelValues(actor, () => {
192
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
193
- });
194
- });
195
- test("no delta does nothing", () => {
196
- const actor = createActor(groupMachine, {
197
- input: {
198
- groupId: "group",
199
- initialItems: [
200
- initializePanel({ id: "panel-1" }),
201
- {
202
- type: "handle",
203
- id: "resizer-1",
204
- size: { type: "pixel", value: 10 },
205
- },
206
- initializePanel({ id: "panel-2" }),
207
- ],
208
- },
209
- }).start();
210
- initializeSizes(actor, { width: 500, height: 200 });
211
- capturePixelValues(actor, () => {
212
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
213
- actor.send({
214
- type: "dragHandle",
215
- handleId: "resizer-1",
216
- value: dragHandlePayload({ delta: 0, orientation: "horizontal" }),
217
- });
218
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
219
- });
220
- });
221
- test("shift key makes it drag more", () => {
222
- const actor = createActor(groupMachine, {
223
- input: {
224
- groupId: "group",
225
- initialItems: [
226
- initializePanel({ id: "panel-1" }),
227
- {
228
- type: "handle",
229
- id: "resizer-1",
230
- size: { type: "pixel", value: 10 },
231
- },
232
- initializePanel({ id: "panel-2" }),
233
- ],
234
- },
235
- }).start();
236
- initializeSizes(actor, { width: 500, height: 200 });
237
- capturePixelValues(actor, () => {
238
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
239
- dragHandle(actor, { id: "resizer-1", delta: -1, shiftKey: true });
240
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"230px 10px 260px"`);
241
- });
242
- });
243
- test("works with percentages", () => {
244
- const actor = createActor(groupMachine, {
245
- input: {
246
- groupId: "group",
247
- initialItems: [
248
- initializePanel({ id: "panel-1", min: "40%" }),
249
- {
250
- type: "handle",
251
- id: "resizer-1",
252
- size: { type: "pixel", value: 10 },
253
- },
254
- initializePanel({ id: "panel-2", min: "10%", default: "30%" }),
255
- ],
256
- },
257
- }).start();
258
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(40%, 1fr) 10px 30%"`);
259
- initializeSizes(actor, { width: 500, height: 200 });
260
- capturePixelValues(actor, () => {
261
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"340px 10px 150px"`);
262
- dragHandle(actor, { id: "resizer-1", delta: -200 });
263
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"200px 10px 290px"`);
264
- });
265
- });
266
- test("supports max", () => {
267
- const actor = createActor(groupMachine, {
268
- input: {
269
- groupId: "group",
270
- initialItems: [
271
- initializePanel({ id: "panel-1", max: "90%" }),
272
- {
273
- type: "handle",
274
- id: "resizer-1",
275
- size: { type: "pixel", value: 10 },
276
- },
277
- initializePanel({ id: "panel-2", default: "30%" }),
278
- ],
279
- },
280
- }).start();
281
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, 90%) 10px 30%"`);
282
- initializeSizes(actor, { width: 500, height: 200 });
283
- capturePixelValues(actor, () => {
284
- dragHandle(actor, { id: "resizer-1", delta: 400 });
285
- });
286
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, min(calc(0.9183673469387755 * (100% - 10px)), 90%)) 10px minmax(0px, min(calc(0.08163265306122448 * (100% - 10px)), 100%))"`);
287
- });
288
- test("panel can have a min", () => {
289
- const actor = createActor(groupMachine, {
290
- input: { groupId: "group" },
291
- }).start();
292
- sendAll(actor, [
293
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
294
- {
295
- type: "registerPanelHandle",
296
- data: { id: "resizer-1", size: handleSize },
297
- },
298
- {
299
- type: "registerPanel",
300
- data: initializePanel({ id: "panel-2", min: "100px" }),
301
- },
302
- ]);
303
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, 1fr) 10px minmax(100px, 1fr)"`);
304
- initializeSizes(actor, { width: 500, height: 200 });
305
- capturePixelValues(actor, () => {
306
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
307
- dragHandle(actor, { id: "resizer-1", delta: 200 });
308
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"390px 10px 100px"`);
309
- });
310
- });
311
- test("panel can have a max", () => {
312
- const actor = createActor(groupMachine, {
313
- input: { groupId: "group" },
314
- }).start();
315
- sendAll(actor, [
316
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
317
- {
318
- type: "registerPanelHandle",
319
- data: { id: "resizer-1", size: handleSize },
320
- },
321
- {
322
- type: "registerPanel",
323
- data: initializePanel({ id: "panel-2", max: "300px" }),
324
- },
325
- ]);
326
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, 1fr) 10px minmax(0px, 300px)"`);
327
- initializeSizes(actor, { width: 500, height: 200 });
328
- // Drag the resizer to the right
329
- capturePixelValues(actor, () => {
330
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"190px 10px 300px"`);
331
- dragHandle(actor, { id: "resizer-1", delta: -200 });
332
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"190px 10px 300px"`);
333
- });
334
- });
335
- test("panel can have a default size", () => {
336
- const actor = createActor(groupMachine, {
337
- input: { groupId: "group" },
338
- }).start();
339
- sendAll(actor, [
340
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
341
- {
342
- type: "registerPanelHandle",
343
- data: { id: "resizer-1", size: handleSize },
344
- },
345
- {
346
- type: "registerPanel",
347
- data: initializePanel({ id: "panel-2", default: "300px" }),
348
- },
349
- ]);
350
- initializeSizes(actor, { width: 500, height: 200 });
351
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, min(calc(1 * (100% - 310px)), 100%)) 10px minmax(0px, min(calc(1.5789473684210527 * (100% - 310px)), 100%))"`);
352
- capturePixelValues(actor, () => {
353
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"190px 10px 300px"`);
354
- });
355
- });
356
- test("dragging eats space from multiple panels in front of it", () => {
357
- const actor = createActor(groupMachine, {
358
- input: { groupId: "group" },
359
- }).start();
360
- sendAll(actor, [
361
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
362
- {
363
- type: "registerPanelHandle",
364
- data: { id: "resizer-1", size: handleSize },
365
- },
366
- {
367
- type: "registerPanel",
368
- data: initializePanel({
369
- id: "panel-2",
370
- min: "200px",
371
- default: "300px",
372
- }),
373
- },
374
- {
375
- type: "registerPanelHandle",
376
- data: { id: "resizer-2", size: handleSize },
377
- },
378
- {
379
- type: "registerPanel",
380
- data: initializePanel({ id: "panel-3", min: "100px" }),
381
- },
382
- ]);
383
- initializeSizes(actor, { width: 500, height: 200 });
384
- capturePixelValues(actor, () => {
385
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"80px 10px 300px 10px 100px"`);
386
- dragHandle(actor, { id: "resizer-1", delta: 160 });
387
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"180px 10px 200px 10px 100px"`);
388
- });
389
- });
390
- test("can set a panel's size", () => {
391
- const actor = createActor(groupMachine, {
392
- input: {
393
- groupId: "group",
394
- initialItems: [
395
- initializePanel({ id: "panel-1" }),
396
- {
397
- type: "handle",
398
- id: "resizer-1",
399
- size: { type: "pixel", value: 10 },
400
- },
401
- initializePanel({ id: "panel-2" }),
402
- ],
403
- },
404
- }).start();
405
- initializeSizes(actor, { width: 500, height: 200 });
406
- actor.send({
407
- type: "setPanelPixelSize",
408
- panelId: "panel-1",
409
- size: "100px",
410
- });
411
- capturePixelValues(actor, () => {
412
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"100px 10px 390px"`);
413
- });
414
- actor.send({
415
- type: "setPanelPixelSize",
416
- panelId: "panel-1",
417
- size: "25%",
418
- });
419
- capturePixelValues(actor, () => {
420
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"125px 10px 365px"`);
421
- });
422
- });
423
- test("can update orientation at runtime", () => {
424
- const actor = createActor(groupMachine, {
425
- input: { groupId: "group" },
426
- }).start();
427
- sendAll(actor, [
428
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
429
- {
430
- type: "registerPanelHandle",
431
- data: { id: "resizer-1", size: handleSize },
432
- },
433
- { type: "registerPanel", data: initializePanel({ id: "panel-2" }) },
434
- ]);
435
- initializeSizes(actor, { width: 500, height: 200 });
436
- capturePixelValues(actor, () => {
437
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
438
- });
439
- actor.send({ type: "setOrientation", orientation: "vertical" });
440
- capturePixelValues(actor, () => {
441
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"95px 10px 95px"`);
442
- });
443
- });
444
- });
445
- describe("collapsible panel", () => {
446
- // const springAnimation = spring({
447
- // keyframes: [0, 1],
448
- // velocity: 1,
449
- // stiffness: 100,
450
- // damping: 10,
451
- // mass: 1.0,
452
- // });
453
- // const springEasing = (t: number) => springAnimation.next(t * 1000).value;
454
- test.each([
455
- undefined,
456
- "ease-in-out",
457
- // The math is wrong, enable after Decimal128
458
- // { duration: 1000, easing: springEasing },
459
- ])("panel can be collapsible: %s", async (animation) => {
460
- const actor = createActor(groupMachine, {
461
- input: { groupId: "group" },
462
- }).start();
463
- sendAll(actor, [
464
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
465
- {
466
- type: "registerPanelHandle",
467
- data: { id: "resizer-1", size: handleSize },
468
- },
469
- {
470
- type: "registerPanel",
471
- data: initializePanel({
472
- id: "panel-2",
473
- collapsible: true,
474
- min: "100px",
475
- collapseAnimation: animation,
476
- }),
477
- },
478
- ]);
479
- expect(getTemplate(actor)).toBe("minmax(0px, 1fr) 10px minmax(100px, 1fr)");
480
- initializeSizes(actor, { width: 500, height: 200 });
481
- // Test dragging to collapse the panel
482
- capturePixelValues(actor, () => {
483
- expect(getTemplate(actor)).toBe("245px 10px 245px");
484
- // Drag into the drag buffer but not past it
485
- dragHandle(actor, { id: "resizer-1", delta: 160 });
486
- expect(getTemplate(actor)).toBe("390px 10px 100px");
487
- // Drag past the drag buffer and collapse the panel
488
- dragHandle(actor, { id: "resizer-1", delta: 100 });
489
- expect(getTemplate(actor)).toBe("490px 10px 0px");
490
- });
491
- expect(getTemplate(actor)).toBe("minmax(0px, min(calc(1 * (100% - 10px)), 100%)) 10px 0px");
492
- // Test dragging to expand the panel
493
- capturePixelValues(actor, () => {
494
- expect(getTemplate(actor)).toBe("490px 10px 0px");
495
- // Stays oollapsed in the buffer
496
- dragHandle(actor, { id: "resizer-1", delta: -30 });
497
- expect(getTemplate(actor)).toBe("490px 10px 0px");
498
- // Opens once the buffer is cleared
499
- dragHandle(actor, { id: "resizer-1", delta: -20 });
500
- expect(getTemplate(actor)).toBe("390px 10px 100px");
501
- });
502
- actor.send({ type: "collapsePanel", panelId: "panel-2" });
503
- await waitForIdle(actor);
504
- capturePixelValues(actor, () => {
505
- expect(getTemplate(actor)).toBe("490px 10px 0px");
506
- });
507
- });
508
- test("collapsible panel can have collapsed size - right", async () => {
509
- const actor = createActor(groupMachine, {
510
- input: { groupId: "group" },
511
- }).start();
512
- sendAll(actor, [
513
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
514
- {
515
- type: "registerPanelHandle",
516
- data: { id: "resizer-1", size: handleSize },
517
- },
518
- {
519
- type: "registerPanel",
520
- data: initializePanel({
521
- id: "panel-2",
522
- collapsible: true,
523
- defaultCollapsed: true,
524
- min: "200px",
525
- collapsedSize: "60px",
526
- }),
527
- },
528
- ]);
529
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, 1fr) 10px 60px"`);
530
- initializeSizes(actor, { width: 500, height: 200 });
531
- capturePixelValues(actor, () => {
532
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"430px 10px 60px"`);
533
- // Drag into the the panel
534
- dragHandle(actor, { id: "resizer-1", delta: 50 });
535
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"430px 10px 60px"`);
536
- // Drag into the start
537
- dragHandle(actor, { id: "resizer-1", delta: -50 });
538
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"430px 10px 60px"`);
539
- // Drag into the drag buffer but not past it
540
- dragHandle(actor, { id: "resizer-1", delta: -25 });
541
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"430px 10px 60px"`);
542
- // Drag past the buffer
543
- dragHandle(actor, { id: "resizer-1", delta: -25 });
544
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"290px 10px 200px"`);
545
- });
546
- });
547
- test("can expand default collapsed panel via event", async () => {
548
- const actor = createActor(groupMachine, {
549
- input: { groupId: "group" },
550
- }).start();
551
- sendAll(actor, [
552
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
553
- {
554
- type: "registerPanelHandle",
555
- data: { id: "resizer-1", size: handleSize },
556
- },
557
- {
558
- type: "registerPanel",
559
- data: initializePanel({
560
- id: "panel-2",
561
- collapsible: true,
562
- defaultCollapsed: true,
563
- min: "200px",
564
- collapsedSize: "60px",
565
- }),
566
- },
567
- ]);
568
- initializeSizes(actor, { width: 500, height: 200 });
569
- actor.send({ type: "expandPanel", panelId: "panel-2" });
570
- await waitForIdle(actor);
571
- capturePixelValues(actor, () => {
572
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"290px 10px 200px"`);
573
- });
574
- });
575
- test("collapsible panel can have collapsed size - left", async () => {
576
- const actor = createActor(groupMachine, {
577
- input: { groupId: "group" },
578
- }).start();
579
- sendAll(actor, [
580
- {
581
- type: "registerPanel",
582
- data: initializePanel({
583
- id: "panel-2",
584
- collapsible: true,
585
- defaultCollapsed: true,
586
- min: "200px",
587
- collapsedSize: "60px",
588
- }),
589
- },
590
- {
591
- type: "registerPanelHandle",
592
- data: { id: "resizer-1", size: handleSize },
593
- },
594
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
595
- ]);
596
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"60px 10px minmax(0px, 1fr)"`);
597
- initializeSizes(actor, { width: 500, height: 200 });
598
- capturePixelValues(actor, () => {
599
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"60px 10px 430px"`);
600
- // Drag into the the panel
601
- dragHandle(actor, { id: "resizer-1", delta: -50 });
602
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"60px 10px 430px"`);
603
- // Drag to the start
604
- dragHandle(actor, { id: "resizer-1", delta: 50 });
605
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"60px 10px 430px"`);
606
- // Drag into the drag buffer but not past it
607
- dragHandle(actor, { id: "resizer-1", delta: 25 });
608
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"60px 10px 430px"`);
609
- // Drag past the buffer
610
- dragHandle(actor, { id: "resizer-1", delta: 25 });
611
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"200px 10px 290px"`);
612
- });
613
- });
614
- test("collapsible remembers last position", async () => {
615
- const actor = createActor(groupMachine, {
616
- input: { groupId: "group" },
617
- }).start();
618
- sendAll(actor, [
619
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
620
- {
621
- type: "registerPanelHandle",
622
- data: { id: "resizer-1", size: handleSize },
623
- },
624
- {
625
- type: "registerPanel",
626
- data: initializePanel({
627
- id: "panel-2",
628
- collapsible: true,
629
- min: "200px",
630
- collapsedSize: "60px",
631
- }),
632
- },
633
- ]);
634
- initializeSizes(actor, { width: 500, height: 200 });
635
- capturePixelValues(actor, () => {
636
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
637
- dragHandle(actor, { id: "resizer-1", delta: -50 });
638
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"195px 10px 295px"`);
639
- });
640
- actor.send({ type: "collapsePanel", panelId: "panel-2" });
641
- await waitForIdle(actor);
642
- capturePixelValues(actor, () => {
643
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"430px 10px 60px"`);
644
- });
645
- actor.send({ type: "expandPanel", panelId: "panel-2" });
646
- await waitForIdle(actor);
647
- capturePixelValues(actor, () => {
648
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"195px 10px 295px"`);
649
- });
650
- });
651
- test("panel can collapse can subscribe to collapsed state", () => {
652
- const actor = createActor(groupMachine, {
653
- input: { groupId: "group" },
654
- }).start();
655
- const spy = vi.fn();
656
- sendAll(actor, [
657
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
658
- {
659
- type: "registerPanelHandle",
660
- data: { id: "resizer-1", size: handleSize },
661
- },
662
- {
663
- type: "registerPanel",
664
- data: initializePanel({
665
- id: "panel-2",
666
- collapsible: true,
667
- min: "100px",
668
- onCollapseChange: {
669
- current: spy,
670
- },
671
- }),
672
- },
673
- ]);
674
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, 1fr) 10px minmax(100px, 1fr)"`);
675
- initializeSizes(actor, { width: 500, height: 200 });
676
- // collapse the panel
677
- capturePixelValues(actor, () => {
678
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
679
- // Drag into the drag buffer but not past it
680
- dragHandle(actor, { id: "resizer-1", delta: 160 });
681
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"390px 10px 100px"`);
682
- // Drag past the drag buffer and collapse the panel
683
- dragHandle(actor, { id: "resizer-1", delta: 100 });
684
- expect(spy).toHaveBeenCalledWith(true);
685
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"490px 10px 0px"`);
686
- });
687
- spy.mockReset();
688
- // expand the panel
689
- capturePixelValues(actor, () => {
690
- // The panel doesn't actually expand yet
691
- dragHandle(actor, { id: "resizer-1", delta: -150 });
692
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"290px 10px 200px"`);
693
- expect(spy).toHaveBeenCalledWith(false);
694
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"290px 10px 200px"`);
695
- // Actually collapse the panel
696
- actor.send({
697
- type: "expandPanel",
698
- panelId: "panel-2",
699
- controlled: true,
700
- });
701
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"290px 10px 200px"`);
702
- });
703
- });
704
- test("should be able to trigger collapse/expand via event", async () => {
705
- const actor = createActor(groupMachine, {
706
- input: { groupId: "group" },
707
- }).start();
708
- sendAll(actor, [
709
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
710
- {
711
- type: "registerPanelHandle",
712
- data: { id: "resizer-1", size: handleSize },
713
- },
714
- {
715
- type: "registerPanel",
716
- data: initializePanel({
717
- id: "panel-2",
718
- collapsible: true,
719
- min: "100px",
720
- default: "100px",
721
- }),
722
- },
723
- ]);
724
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, 1fr) 10px 100px"`);
725
- initializeSizes(actor, { width: 500, height: 200 });
726
- capturePixelValues(actor, () => {
727
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"390px 10px 100px"`);
728
- });
729
- actor.send({ type: "collapsePanel", panelId: "panel-2" });
730
- await waitForIdle(actor);
731
- capturePixelValues(actor, () => {
732
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"490px 10px 0px"`);
733
- });
734
- actor.send({ type: "expandPanel", panelId: "panel-2" });
735
- await waitForIdle(actor);
736
- capturePixelValues(actor, () => {
737
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"390px 10px 100px"`);
738
- });
739
- });
740
- test("panel collapse can be controlled", async () => {
741
- const actor = createActor(groupMachine, {
742
- input: { groupId: "group" },
743
- }).start();
744
- const spy = vi.fn();
745
- sendAll(actor, [
746
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
747
- {
748
- type: "registerPanelHandle",
749
- data: { id: "resizer-1", size: handleSize },
750
- },
751
- {
752
- type: "registerPanel",
753
- data: initializePanel({
754
- id: "panel-2",
755
- collapsible: true,
756
- min: "100px",
757
- // This marks the collapse as controlled
758
- collapsed: false,
759
- collapsedSize: "20px",
760
- onCollapseChange: {
761
- current: spy,
762
- },
763
- }),
764
- },
765
- ]);
766
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"minmax(0px, 1fr) 10px minmax(100px, 1fr)"`);
767
- initializeSizes(actor, { width: 500, height: 200 });
768
- // collapse the panel via drag
769
- capturePixelValues(actor, () => {
770
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
771
- dragHandle(actor, { id: "resizer-1", delta: 160 });
772
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"390px 10px 100px"`);
773
- // The panel doesn't actually collapse yet
774
- dragHandle(actor, { id: "resizer-1", delta: 100 });
775
- expect(spy).toHaveBeenCalledWith(true);
776
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"390px 10px 100px"`);
777
- // Actually collapse the panel
778
- actor.send({
779
- type: "collapsePanel",
780
- panelId: "panel-2",
781
- controlled: true,
782
- });
783
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"470px 10px 20px"`);
784
- });
785
- spy.mockReset();
786
- // expand the panel via drag
787
- capturePixelValues(actor, () => {
788
- // The panel doesn't actually expand yet
789
- dragHandle(actor, { id: "resizer-1", delta: -150 });
790
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"470px 10px 20px"`);
791
- expect(spy).toHaveBeenCalledWith(false);
792
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"470px 10px 20px"`);
793
- // Actually collapse the panel
794
- actor.send({
795
- type: "expandPanel",
796
- panelId: "panel-2",
797
- controlled: true,
798
- });
799
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"319px 10px 171px"`);
800
- });
801
- spy.mockReset();
802
- actor.send({ type: "collapsePanel", panelId: "panel-2" });
803
- await waitForIdle(actor);
804
- // collapse the panel via drag
805
- capturePixelValues(actor, () => {
806
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"319px 10px 171px"`);
807
- });
808
- actor.send({ type: "expandPanel", panelId: "panel-2" });
809
- await waitForIdle(actor);
810
- // collapse the panel via drag
811
- capturePixelValues(actor, () => {
812
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"319px 10px 171px"`);
813
- });
814
- });
815
- });
816
- describe("conditional panel", () => {
817
- test("panel can be conditionally rendered", () => {
818
- const actor = createActor(groupMachine, {
819
- input: { groupId: "group" },
820
- }).start();
821
- sendAll(actor, [
822
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
823
- {
824
- type: "registerPanelHandle",
825
- data: { id: "resizer-1", size: handleSize },
826
- },
827
- { type: "registerPanel", data: initializePanel({ id: "panel-2" }) },
828
- ]);
829
- initializeSizes(actor, { width: 500, height: 200 });
830
- capturePixelValues(actor, () => {
831
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
832
- });
833
- sendAll(actor, [
834
- {
835
- type: "registerPanelHandle",
836
- data: { id: "resizer-2", size: handleSize },
837
- },
838
- {
839
- type: "registerDynamicPanel",
840
- data: initializePanel({ id: "panel-3", min: "100px" }),
841
- },
842
- ]);
843
- capturePixelValues(actor, () => {
844
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"240px 10px 140px 10px 100px"`);
845
- });
846
- sendAll(actor, [
847
- { type: "unregisterPanelHandle", id: "resizer-2" },
848
- { type: "unregisterPanel", id: "panel-3" },
849
- ]);
850
- capturePixelValues(actor, () => {
851
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"240px 10px 250px"`);
852
- });
853
- });
854
- test("collapsed panel can be conditionally rendered", () => {
855
- const actor = createActor(groupMachine, {
856
- input: { groupId: "group" },
857
- }).start();
858
- sendAll(actor, [
859
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
860
- {
861
- type: "registerPanelHandle",
862
- data: { id: "resizer-1", size: handleSize },
863
- },
864
- {
865
- type: "registerPanel",
866
- data: initializePanel({ id: "panel-2" }),
867
- },
868
- ]);
869
- initializeSizes(actor, { width: 500, height: 200 });
870
- capturePixelValues(actor, () => {
871
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
872
- });
873
- sendAll(actor, [
874
- {
875
- type: "registerPanelHandle",
876
- data: { id: "resizer-2", size: handleSize },
877
- },
878
- {
879
- type: "registerDynamicPanel",
880
- data: initializePanel({
881
- id: "panel-3",
882
- min: "100px",
883
- collapsible: true,
884
- defaultCollapsed: true,
885
- }),
886
- },
887
- ]);
888
- capturePixelValues(actor, () => {
889
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"240px 10px 240px 10px 0px"`);
890
- });
891
- sendAll(actor, [
892
- { type: "unregisterPanelHandle", id: "resizer-2" },
893
- { type: "unregisterPanel", id: "panel-3" },
894
- ]);
895
- capturePixelValues(actor, () => {
896
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"240px 10px 250px"`);
897
- });
898
- });
899
- test("panel can be conditionally rendered at default width", () => {
900
- const actor = createActor(groupMachine, {
901
- input: { groupId: "group" },
902
- }).start();
903
- sendAll(actor, [
904
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
905
- {
906
- type: "registerPanelHandle",
907
- data: { id: "resizer-1", size: handleSize },
908
- },
909
- {
910
- type: "registerPanel",
911
- data: initializePanel({ id: "panel-2" }),
912
- },
913
- ]);
914
- initializeSizes(actor, { width: 500, height: 200 });
915
- capturePixelValues(actor, () => {
916
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
917
- });
918
- sendAll(actor, [
919
- {
920
- type: "registerPanelHandle",
921
- data: { id: "resizer-2", size: handleSize },
922
- },
923
- {
924
- type: "registerDynamicPanel",
925
- data: initializePanel({
926
- id: "panel-3",
927
- default: "125px",
928
- }),
929
- },
930
- ]);
931
- capturePixelValues(actor, () => {
932
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"240px 10px 115px 10px 125px"`);
933
- });
934
- sendAll(actor, [
935
- { type: "unregisterPanelHandle", id: "resizer-2" },
936
- { type: "unregisterPanel", id: "panel-3" },
937
- ]);
938
- capturePixelValues(actor, () => {
939
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"240px 10px 250px"`);
940
- });
941
- });
942
- test("panel can be conditionally rendered w/order", () => {
943
- const actor = createActor(groupMachine, {
944
- input: { groupId: "group" },
945
- }).start();
946
- sendAll(actor, [
947
- { type: "registerPanel", data: initializePanel({ id: "panel-1" }) },
948
- {
949
- type: "registerPanelHandle",
950
- data: { id: "resizer-1", size: handleSize },
951
- },
952
- { type: "registerPanel", data: initializePanel({ id: "panel-2" }) },
953
- ]);
954
- initializeSizes(actor, { width: 500, height: 200 });
955
- capturePixelValues(actor, () => {
956
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
957
- });
958
- sendAll(actor, [
959
- {
960
- type: "registerPanelHandle",
961
- data: { id: "resizer-2", size: handleSize, order: 1 },
962
- },
963
- {
964
- type: "registerDynamicPanel",
965
- data: {
966
- ...initializePanel({ id: "panel-3", min: "100px" }),
967
- order: 2,
968
- },
969
- },
970
- ]);
971
- capturePixelValues(actor, () => {
972
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"240px 10px 100px 10px 140px"`);
973
- });
974
- sendAll(actor, [
975
- { type: "unregisterPanelHandle", id: "resizer-2" },
976
- { type: "unregisterPanel", id: "panel-3" },
977
- ]);
978
- capturePixelValues(actor, () => {
979
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"240px 10px 250px"`);
980
- });
981
- sendAll(actor, [
982
- { type: "unregisterPanelHandle", id: "resizer-2" },
983
- { type: "unregisterPanel", id: "panel-3" },
984
- ]);
985
- capturePixelValues(actor, () => {
986
- expect(getTemplate(actor)).toMatchInlineSnapshot(`"240px 10px 250px"`);
987
- });
988
- });
989
- });
990
- describe("errors", () => {
991
- test("throws for invalid units", () => {
992
- const actor = createActor(groupMachine, {
993
- input: { groupId: "group" },
994
- }).start();
995
- expect(() => actor.send({
996
- type: "registerPanel",
997
- // @ts-expect-error Testing the error
998
- data: initializePanel({ id: "panel-1", min: "40fr" }),
999
- })).toThrowErrorMatchingInlineSnapshot(`[Error: Invalid unit: 40fr]`);
1000
- });
1001
- test("throws when using invalid panel IDs", () => {
1002
- const spy = vi.fn();
1003
- const actor = createActor(groupMachine, {
1004
- input: { groupId: "group" },
1005
- }).start();
1006
- actor.subscribe({ error: spy });
1007
- actor.send({
1008
- type: "registerPanel",
1009
- data: initializePanel({ id: "panel-1" }),
1010
- });
1011
- actor.send({
1012
- type: "setPanelPixelSize",
1013
- panelId: "panel-2",
1014
- size: "100px",
1015
- });
1016
- expect(spy).toHaveBeenCalledWith(new Error("Expected panel with id: panel-2"));
1017
- });
1018
- test("throws when using invalid handle IDs", () => {
1019
- const spy = vi.fn();
1020
- const actor = createActor(groupMachine, {
1021
- input: { groupId: "group" },
1022
- }).start();
1023
- actor.subscribe({ error: spy });
1024
- sendAll(actor, [
1025
- { type: "registerPanel", data: initializePanel({ id: "handle-2" }) },
1026
- { type: "dragHandleStart", handleId: "handle-2" },
1027
- {
1028
- type: "dragHandle",
1029
- handleId: "handle-2",
1030
- value: dragHandlePayload({ delta: 100, orientation: "horizontal" }),
1031
- },
1032
- ]);
1033
- expect(spy).toHaveBeenCalledWith(new Error("Expected panel handle with id: handle-2"));
1034
- });
1035
- });
1036
- //# sourceMappingURL=machine.test.js.map