@window-splitter/state 1.1.0 → 1.1.1--canary.9d2f98a.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/src/index.ts CHANGED
@@ -257,6 +257,7 @@ interface ApplyDeltaEvent {
257
257
  type: "applyDelta";
258
258
  delta: number;
259
259
  handleId: string;
260
+ panelId: string;
260
261
  }
261
262
 
262
263
  interface SetOrientationEvent {
@@ -278,6 +279,7 @@ interface CollapsePanelEvent extends ControlledCollapseToggle {
278
279
  type: "collapsePanel";
279
280
  /** The panel to collapse */
280
281
  panelId: string;
282
+ resolve?: () => void;
281
283
  }
282
284
 
283
285
  interface ExpandPanelEvent extends ControlledCollapseToggle {
@@ -285,6 +287,7 @@ interface ExpandPanelEvent extends ControlledCollapseToggle {
285
287
  type: "expandPanel";
286
288
  /** The panel to expand */
287
289
  panelId: string;
290
+ resolve?: () => void;
288
291
  }
289
292
 
290
293
  interface SetPanelPixelSizeEvent {
@@ -740,6 +743,25 @@ function getHandleForPanelId(
740
743
  ) {
741
744
  const panelIndex = context.items.findIndex((item) => item.id === panelId);
742
745
 
746
+ // When in controlled collapse mode we defer to the controlled state to know if we need to update.
747
+ // The confirmation comes along as an expand/collapse event.
748
+ // The default behavior is to find the closes handle and use that to collapse, if we're dragging some other
749
+ // handle though we want to use that instead. This will results in a smoother visual experience.
750
+ if (context.activeDragHandleId) {
751
+ const handleIndex = getPanelHandleIndex(
752
+ context,
753
+ context.activeDragHandleId
754
+ );
755
+ const item = context.items[handleIndex];
756
+
757
+ if (item && isPanelHandle(item)) {
758
+ return {
759
+ item,
760
+ direction: handleIndex > panelIndex ? (1 as const) : (-1 as const),
761
+ };
762
+ }
763
+ }
764
+
743
765
  invariant(panelIndex !== -1, `Expected panel before: ${panelId}`);
744
766
 
745
767
  let item = context.items[panelIndex + 1];
@@ -757,6 +779,37 @@ function getHandleForPanelId(
757
779
  throw new Error(`Cant find handle for panel: ${panelId}`);
758
780
  }
759
781
 
782
+ function getHandleForPanelIdWithAvailableSpace(
783
+ context: GroupMachineContextValue,
784
+ panelId: string
785
+ ) {
786
+ const panelIndex = context.items.findIndex((item) => item.id === panelId);
787
+
788
+ invariant(panelIndex !== -1, `Expected panel before: ${panelId}`);
789
+
790
+ let item = context.items[panelIndex + 1];
791
+
792
+ if (
793
+ item &&
794
+ isPanelHandle(item) &&
795
+ findPanelWithSpace(context, context.items, panelIndex + 1, 1, "add")
796
+ ) {
797
+ return { item, direction: 1 as const };
798
+ }
799
+
800
+ item = context.items[panelIndex - 1];
801
+
802
+ if (
803
+ item &&
804
+ isPanelHandle(item) &&
805
+ findPanelWithSpace(context, context.items, panelIndex - 1, -1, "add")
806
+ ) {
807
+ return { item, direction: -1 as const };
808
+ }
809
+
810
+ return getHandleForPanelId(context, panelId);
811
+ }
812
+
760
813
  /** Given the specified order props and default order of the items, order the items */
761
814
  function sortWithOrder(items: Array<Item>) {
762
815
  const defaultPlacement: Record<string, number> = {};
@@ -804,8 +857,8 @@ function panelHasSpace(
804
857
  `panelHasSpace only works with number values: ${item.id} ${item.currentValue}`
805
858
  );
806
859
 
807
- if (item.collapsible && !item.collapsed) {
808
- return true;
860
+ if (item.collapsible) {
861
+ return !item.collapsed;
809
862
  }
810
863
 
811
864
  if (adjustment === "add") {
@@ -1103,6 +1156,7 @@ function updateLayout(
1103
1156
  | (DragHandleEvent & {
1104
1157
  controlled?: boolean;
1105
1158
  disregardCollapseBuffer?: never;
1159
+ panelId?: string;
1106
1160
  isVirtual?: boolean;
1107
1161
  })
1108
1162
  | {
@@ -1110,6 +1164,7 @@ function updateLayout(
1110
1164
  value: MoveMoveEvent;
1111
1165
  handleId: string;
1112
1166
  controlled?: boolean;
1167
+ panelId: string;
1113
1168
  disregardCollapseBuffer?: boolean;
1114
1169
  isVirtual?: boolean;
1115
1170
  }
@@ -1152,7 +1207,26 @@ function updateLayout(
1152
1207
 
1153
1208
  invariant(isPanelData(panelBefore), `Expected panel before: ${handle.id}`);
1154
1209
 
1155
- const panelAfter = newItems[handleIndex - moveDirection];
1210
+ /** The panel that gets bigger */
1211
+ const panelAfter =
1212
+ dragEvent.type === "collapsePanel"
1213
+ ? // If we have the panel id just use that
1214
+ newItems.find(
1215
+ (item) =>
1216
+ item.id === dragEvent.panelId &&
1217
+ panelBefore.id !== dragEvent.panelId
1218
+ ) ||
1219
+ // otherwise fallback to the next panel with space
1220
+ findPanelWithSpace(
1221
+ context,
1222
+ newItems,
1223
+ handleIndex - moveDirection,
1224
+ moveDirection * -1,
1225
+ "add",
1226
+ dragEvent.disregardCollapseBuffer
1227
+ ) ||
1228
+ newItems[handleIndex - moveDirection]
1229
+ : newItems[handleIndex - moveDirection];
1156
1230
 
1157
1231
  invariant(
1158
1232
  panelAfter && isPanelData(panelAfter),
@@ -1170,7 +1244,7 @@ function updateLayout(
1170
1244
  const newDragOvershoot = context.dragOvershoot.add(moveAmount);
1171
1245
 
1172
1246
  // Don't let the panel expand until the threshold is reached
1173
- if (!dragEvent.disregardCollapseBuffer) {
1247
+ if (!dragEvent.disregardCollapseBuffer && !dragEvent.controlled) {
1174
1248
  const isInLeftBuffer = newDragOvershoot.lt(0) && moveDirection > 0;
1175
1249
  const isInLeftOvershoot = newDragOvershoot.gt(0) && moveDirection > 0;
1176
1250
  const isInRightBuffer = newDragOvershoot.gt(0) && moveDirection < 0;
@@ -1204,6 +1278,7 @@ function updateLayout(
1204
1278
  // Don't let the panel collapse until the threshold is reached
1205
1279
  if (
1206
1280
  !dragEvent.disregardCollapseBuffer &&
1281
+ !dragEvent.controlled &&
1207
1282
  panelBefore.collapsible &&
1208
1283
  panelBefore.currentValue.value.eq(
1209
1284
  getUnitPixelValue(context, panelBefore.min)
@@ -1287,7 +1362,10 @@ function updateLayout(
1287
1362
  .minus(Math.abs(moveAmount))
1288
1363
  );
1289
1364
 
1290
- if (panelBeforeNewValue.lt(panelBefore.min.value)) {
1365
+ if (
1366
+ panelBeforeNewValue.lt(panelBefore.min.value) &&
1367
+ !panelBefore.collapsible
1368
+ ) {
1291
1369
  // TODO this should probably distribute the space between the panels?
1292
1370
  return { dragOvershoot: newDragOvershoot };
1293
1371
  }
@@ -1328,7 +1406,7 @@ function updateLayout(
1328
1406
  panelBefore.collapsed = true;
1329
1407
  panelBeforeNewValue = getUnitPixelValue(context, panelBefore.collapsedSize);
1330
1408
  // Add the extra space created to the before panel
1331
- panelAfterNewValue = panelAfterNewValue.add(
1409
+ panelAfterNewValue = panelAfter.currentValue.value.add(
1332
1410
  panelBeforePreviousValue.minus(panelBeforeNewValue)
1333
1411
  );
1334
1412
 
@@ -1432,6 +1510,7 @@ function iterativelyUpdateLayout({
1432
1510
  controlled,
1433
1511
  disregardCollapseBuffer,
1434
1512
  isVirtual,
1513
+ panelId,
1435
1514
  }: {
1436
1515
  context: GroupMachineContextValue;
1437
1516
  handleId: string;
@@ -1444,6 +1523,7 @@ function iterativelyUpdateLayout({
1444
1523
  * no on* callbacks will be called
1445
1524
  */
1446
1525
  isVirtual?: boolean;
1526
+ panelId: string;
1447
1527
  }) {
1448
1528
  let newContext: Partial<GroupMachineContextValue> = context;
1449
1529
 
@@ -1459,6 +1539,7 @@ function iterativelyUpdateLayout({
1459
1539
  controlled,
1460
1540
  disregardCollapseBuffer,
1461
1541
  isVirtual,
1542
+ panelId,
1462
1543
  value: dragHandlePayload({
1463
1544
  delta: direction,
1464
1545
  orientation: context.orientation,
@@ -1565,6 +1646,7 @@ function handleOverflow(context: GroupMachineContextValue) {
1565
1646
  handleId: handleId.item.id,
1566
1647
  delta: sizeChange,
1567
1648
  direction: (handleId.direction * -1) as -1 | 1,
1649
+ panelId: collapsiblePanel.id,
1568
1650
  context: {
1569
1651
  ...newContext,
1570
1652
  // act like its the old size so the space is distributed correctly
@@ -1600,6 +1682,7 @@ function setCookie(name: string, jsonData: unknown) {
1600
1682
  interface AnimationActorOutput {
1601
1683
  panelId: string;
1602
1684
  action: "expand" | "collapse";
1685
+ resolve?: () => void;
1603
1686
  }
1604
1687
 
1605
1688
  function getDeltaForEvent(
@@ -1625,11 +1708,20 @@ function animationActor(
1625
1708
  abortController: AbortController
1626
1709
  ) {
1627
1710
  const panel = getPanelWithId(context, event.panelId);
1628
- const handle = getHandleForPanelId(context, event.panelId);
1629
-
1711
+ const handle = getHandleForPanelIdWithAvailableSpace(context, event.panelId);
1630
1712
  let direction = new Big(handle.direction);
1631
1713
  const fullDelta = getDeltaForEvent(context, event);
1632
1714
 
1715
+ const contextCopy = { ...context, items: prepareItems(context) };
1716
+ const finalLayout = iterativelyUpdateLayout({
1717
+ context: contextCopy,
1718
+ panelId: event.panelId,
1719
+ handleId: handle.item.id,
1720
+ delta: fullDelta,
1721
+ direction: handle.direction,
1722
+ isVirtual: true,
1723
+ });
1724
+
1633
1725
  return new Promise<AnimationActorOutput | undefined>((resolve, reject) => {
1634
1726
  abortController.signal.addEventListener("abort", () => {
1635
1727
  reject(new Error("Operation was canceled"));
@@ -1657,6 +1749,7 @@ function animationActor(
1657
1749
  type: "applyDelta",
1658
1750
  handleId: handle.item.id,
1659
1751
  delta: delta.toNumber(),
1752
+ panelId: panel.id,
1660
1753
  });
1661
1754
 
1662
1755
  appliedDelta = appliedDelta.add(
@@ -1670,8 +1763,21 @@ function animationActor(
1670
1763
  );
1671
1764
 
1672
1765
  if (e.eq(1)) {
1766
+ // If we're controlled expanding to a value that breaks the layout we might get negative values
1767
+ // In this case we need to use a valid layout like `iterativelyUpdateLayout`'s return value
1768
+ // Ideally we figure out some way to not do this but disregardCollapseBuffer is needed for animations
1769
+ if (
1770
+ context.items.find(
1771
+ (i) =>
1772
+ isPanelData(i) &&
1773
+ i.currentValue.value.round(undefined, Big.roundHalfEven).lt(0)
1774
+ )
1775
+ ) {
1776
+ assign(context, finalLayout);
1777
+ }
1778
+
1673
1779
  const action = event.type === "expandPanel" ? "expand" : "collapse";
1674
- resolve({ panelId: panel.id, action });
1780
+ resolve({ panelId: panel.id, action, resolve: event.resolve });
1675
1781
  return false;
1676
1782
  }
1677
1783
 
@@ -1806,6 +1912,7 @@ export function groupMachine(
1806
1912
  : handle.direction;
1807
1913
 
1808
1914
  const newContext = updateLayout(context, {
1915
+ panelId: event.panelId,
1809
1916
  handleId: handle.item.id,
1810
1917
  type: "dragHandle",
1811
1918
  controlled: event.controlled,
@@ -1850,15 +1957,20 @@ export function groupMachine(
1850
1957
  },
1851
1958
  cannotExpandPanel: (event: GroupMachineEvent) => {
1852
1959
  isEvent(event, ["expandPanel"]);
1853
- const delta = getDeltaForEvent(context, event);
1854
- const handle = getHandleForPanelId(context, event.panelId);
1855
1960
  const pixelItems = prepareItems(context);
1856
-
1857
1961
  let interimContext = { ...context, items: pixelItems };
1962
+
1963
+ const delta = getDeltaForEvent(context, event);
1964
+ const handle = getHandleForPanelIdWithAvailableSpace(
1965
+ interimContext,
1966
+ event.panelId
1967
+ );
1968
+
1858
1969
  interimContext = {
1859
1970
  ...interimContext,
1860
1971
  ...iterativelyUpdateLayout({
1861
1972
  context: interimContext,
1973
+ panelId: event.panelId,
1862
1974
  handleId: handle.item.id,
1863
1975
  controlled: event.controlled,
1864
1976
  delta: delta,
@@ -1907,6 +2019,8 @@ export function groupMachine(
1907
2019
  }
1908
2020
 
1909
2021
  state.current = to;
2022
+
2023
+ onUpdate?.(context);
1910
2024
  }
1911
2025
 
1912
2026
  function send(event: GroupMachineEvent) {
@@ -2117,11 +2231,13 @@ export function groupMachine(
2117
2231
  const delta = isBigger
2118
2232
  ? newSize.minus(current)
2119
2233
  : current.minus(newSize);
2234
+ panel.sizeBeforeCollapse = newSize.toNumber();
2120
2235
 
2121
2236
  Object.assign(
2122
2237
  context,
2123
2238
  iterativelyUpdateLayout({
2124
2239
  context,
2240
+ panelId: event.panelId,
2125
2241
  direction: (handle.direction * (isBigger ? 1 : -1)) as -1 | 1,
2126
2242
  handleId: handle.item.id,
2127
2243
  delta,
@@ -2146,6 +2262,9 @@ export function groupMachine(
2146
2262
  (output) => {
2147
2263
  actions.onAnimationEnd(output);
2148
2264
  transition("idle");
2265
+ if (event.resolve) {
2266
+ requestAnimationFrame(event.resolve);
2267
+ }
2149
2268
  }
2150
2269
  );
2151
2270
  }
@@ -2166,6 +2285,9 @@ export function groupMachine(
2166
2285
  (output) => {
2167
2286
  actions.onAnimationEnd(output);
2168
2287
  transition("idle");
2288
+ if (event.resolve) {
2289
+ requestAnimationFrame(event.resolve);
2290
+ }
2169
2291
  }
2170
2292
  );
2171
2293
  }
@@ -2198,6 +2320,7 @@ export function groupMachine(
2198
2320
  assign(
2199
2321
  context,
2200
2322
  updateLayout(context, {
2323
+ panelId: event.panelId,
2201
2324
  handleId: event.handleId,
2202
2325
  type: "collapsePanel",
2203
2326
  disregardCollapseBuffer: true,
@@ -485,6 +485,283 @@ describe("constraints", () => {
485
485
  );
486
486
  });
487
487
 
488
+ test("sibling collapsible panels work", async () => {
489
+ const onCollapseChange = (isCollapsed: boolean) => {
490
+ if (isCollapsed) {
491
+ actor.send({
492
+ type: "collapsePanel",
493
+ panelId: "panel-1",
494
+ controlled: true,
495
+ });
496
+ } else {
497
+ actor.send({
498
+ type: "expandPanel",
499
+ panelId: "panel-1",
500
+ controlled: true,
501
+ });
502
+ }
503
+ };
504
+
505
+ const actor = createActor({
506
+ groupId: "group",
507
+ items: [
508
+ initializePanel({
509
+ id: "panel-1",
510
+ default: "200px",
511
+ min: "100px",
512
+ collapsible: true,
513
+ collapsed: false,
514
+ onCollapseChange: { current: onCollapseChange },
515
+ }),
516
+ initializePanelHandleData({ id: "resizer-1", size: "10px" }),
517
+ initializePanel({
518
+ id: "panel-2",
519
+ default: "200px",
520
+ min: "100px",
521
+ collapsible: true,
522
+ }),
523
+ initializePanelHandleData({ id: "resizer-2", size: "10px" }),
524
+ initializePanel({
525
+ id: "panel-3",
526
+ min: "200px",
527
+ collapsible: true,
528
+ collapsedSize: "60px",
529
+ }),
530
+ ],
531
+ });
532
+
533
+ initializeSizes(actor, { width: 800, height: 200 });
534
+
535
+ capturePixelValues(actor, () => {
536
+ // First collapse both panels
537
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
538
+ `"200px 10px 200px 10px 380px"`
539
+ );
540
+ dragHandle(actor, { id: "resizer-2", delta: -410 });
541
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
542
+ `"0px 10px 0px 10px 780px"`
543
+ );
544
+ });
545
+
546
+ actor.send({
547
+ type: "expandPanel",
548
+ panelId: "panel-1",
549
+ controlled: true,
550
+ });
551
+ await waitForIdle(actor);
552
+
553
+ capturePixelValues(actor, () => {
554
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
555
+ `"100px 10px 0px 10px 680px"`
556
+ );
557
+ });
558
+ });
559
+
560
+ test("controlled collapse complex drags", async () => {
561
+ const onCollapseChange = (panelId: string) => (isCollapsed: boolean) => {
562
+ if (isCollapsed) {
563
+ actor.send({
564
+ type: "collapsePanel",
565
+ panelId,
566
+ controlled: true,
567
+ });
568
+ } else {
569
+ actor.send({ type: "expandPanel", panelId, controlled: true });
570
+ }
571
+ };
572
+
573
+ const onChange1 = onCollapseChange("panel-1");
574
+ const onChange2 = onCollapseChange("panel-2");
575
+ const onChange3 = onCollapseChange("panel-3");
576
+
577
+ const actor = createActor({
578
+ groupId: "group",
579
+ items: [
580
+ initializePanel({
581
+ id: "panel-1",
582
+ default: "200px",
583
+ min: "100px",
584
+ collapsible: true,
585
+ collapsed: false,
586
+ onCollapseChange: { current: onChange1 },
587
+ }),
588
+ initializePanelHandleData({ id: "resizer-1", size: "10px" }),
589
+ initializePanel({
590
+ id: "panel-2",
591
+ default: "200px",
592
+ min: "100px",
593
+ collapsible: true,
594
+ onCollapseChange: { current: onChange2 },
595
+ }),
596
+ initializePanelHandleData({ id: "resizer-2", size: "10px" }),
597
+ initializePanel({
598
+ id: "panel-3",
599
+ min: "100px",
600
+ collapsible: true,
601
+ onCollapseChange: { current: onChange3 },
602
+ }),
603
+ ],
604
+ });
605
+
606
+ initializeSizes(actor, { width: 800, height: 200 });
607
+
608
+ // Collapse middle panel from the left
609
+ capturePixelValues(actor, () => {
610
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
611
+ `"200px 10px 200px 10px 380px"`
612
+ );
613
+ dragHandle(actor, { id: "resizer-1", delta: 200 });
614
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
615
+ `"450px 10px 0px 10px 330px"`
616
+ );
617
+ dragHandle(actor, { id: "resizer-1", delta: -200 });
618
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
619
+ `"249px 10px 201px 10px 330px"`
620
+ );
621
+ });
622
+
623
+ // Collapse middle panel from the right
624
+ capturePixelValues(actor, () => {
625
+ dragHandle(actor, { id: "resizer-2", delta: -200 });
626
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
627
+ `"200px 10px 0px 10px 580px"`
628
+ );
629
+ dragHandle(actor, { id: "resizer-2", delta: 200 });
630
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
631
+ `"200px 10px 201px 10px 379px"`
632
+ );
633
+ });
634
+
635
+ // Collapse the left panel
636
+ capturePixelValues(actor, () => {
637
+ dragHandle(actor, { id: "resizer-1", delta: -200 });
638
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
639
+ `"0px 10px 401px 10px 379px"`
640
+ );
641
+ dragHandle(actor, { id: "resizer-1", delta: 200 });
642
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
643
+ `"150px 10px 251px 10px 379px"`
644
+ );
645
+ });
646
+
647
+ // Collapse the right panel
648
+ capturePixelValues(actor, () => {
649
+ dragHandle(actor, { id: "resizer-2", delta: 600 });
650
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
651
+ `"150px 10px 630px 10px 0px"`
652
+ );
653
+ dragHandle(actor, { id: "resizer-2", delta: -600 });
654
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
655
+ `"150px 10px 300px 10px 330px"`
656
+ );
657
+ });
658
+
659
+ // Sweep the left handle to the right
660
+ capturePixelValues(actor, () => {
661
+ dragHandle(actor, { id: "resizer-1", delta: 1000 });
662
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
663
+ `"780px 10px 0px 10px 0px"`
664
+ );
665
+ });
666
+
667
+ // Sweep the right handle to the left
668
+ capturePixelValues(actor, () => {
669
+ dragHandle(actor, { id: "resizer-2", delta: -1000 });
670
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
671
+ `"0px 10px 0px 10px 780px"`
672
+ );
673
+ });
674
+ });
675
+
676
+ test("controlled collapse events", async () => {
677
+ const onCollapseChange = (panelId: string) => (isCollapsed: boolean) => {
678
+ if (isCollapsed) {
679
+ actor.send({
680
+ type: "collapsePanel",
681
+ panelId,
682
+ controlled: true,
683
+ });
684
+ } else {
685
+ actor.send({ type: "expandPanel", panelId, controlled: true });
686
+ }
687
+ };
688
+
689
+ const onChange1 = onCollapseChange("panel-1");
690
+ const onChange2 = onCollapseChange("panel-2");
691
+ const onChange3 = onCollapseChange("panel-3");
692
+
693
+ const actor = createActor({
694
+ groupId: "group",
695
+ items: [
696
+ initializePanel({
697
+ id: "panel-1",
698
+ default: "200px",
699
+ min: "100px",
700
+ collapsible: true,
701
+ collapsed: false,
702
+ onCollapseChange: { current: onChange1 },
703
+ }),
704
+ initializePanelHandleData({ id: "resizer-1", size: "10px" }),
705
+ initializePanel({
706
+ id: "panel-2",
707
+ default: "200px",
708
+ min: "100px",
709
+ collapsible: true,
710
+ collapsed: false,
711
+ onCollapseChange: { current: onChange2 },
712
+ }),
713
+ initializePanelHandleData({ id: "resizer-2", size: "10px" }),
714
+ initializePanel({
715
+ id: "panel-3",
716
+ min: "100px",
717
+ collapsible: true,
718
+ collapsed: false,
719
+ onCollapseChange: { current: onChange3 },
720
+ }),
721
+ ],
722
+ });
723
+
724
+ initializeSizes(actor, { width: 800, height: 200 });
725
+
726
+ capturePixelValues(actor, () => {
727
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
728
+ `"200px 10px 200px 10px 380px"`
729
+ );
730
+ });
731
+
732
+ actor.send({ type: "collapsePanel", panelId: "panel-2", controlled: true });
733
+ await waitForIdle(actor);
734
+ capturePixelValues(actor, () => {
735
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
736
+ `"200px 10px 0px 10px 580px"`
737
+ );
738
+ });
739
+
740
+ actor.send({ type: "collapsePanel", panelId: "panel-3", controlled: true });
741
+ await waitForIdle(actor);
742
+ capturePixelValues(actor, () => {
743
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
744
+ `"780px 10px 0px 10px 0px"`
745
+ );
746
+ });
747
+
748
+ actor.send({ type: "expandPanel", panelId: "panel-2", controlled: true });
749
+ await waitForIdle(actor);
750
+ capturePixelValues(actor, () => {
751
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
752
+ `"580px 10px 200px 10px 0px"`
753
+ );
754
+ });
755
+
756
+ actor.send({ type: "expandPanel", panelId: "panel-3", controlled: true });
757
+ await waitForIdle(actor);
758
+ capturePixelValues(actor, () => {
759
+ expect(buildTemplate(actor.value)).toMatchInlineSnapshot(
760
+ `"100px 10px 0px 10px 680px"`
761
+ );
762
+ });
763
+ });
764
+
488
765
  test("panel can have a min", () => {
489
766
  const actor = createActor({ groupId: "group" });
490
767