@window-splitter/state 0.3.2 → 0.4.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/.turbo/turbo-build.log +1 -1
- package/.turbo/turbo-lint.log +1 -1
- package/CHANGELOG.md +27 -0
- package/coverage/coverage-final.json +1 -1
- package/coverage/coverage-summary.json +2 -2
- package/coverage/index.html +21 -21
- package/coverage/index.ts.html +1367 -893
- package/dist/commonjs/index.d.ts +11 -13
- package/dist/commonjs/index.d.ts.map +1 -1
- package/dist/commonjs/index.js +126 -29
- package/dist/commonjs/index.js.map +1 -1
- package/dist/esm/index.d.ts +11 -13
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js +126 -29
- package/dist/esm/index.js.map +1 -1
- package/package.json +3 -3
- package/src/index.ts +197 -48
- package/src/machine.test.ts +219 -0
package/src/index.ts
CHANGED
|
@@ -65,6 +65,13 @@ export interface Constraints<T extends ParsedUnit | Unit = ParsedUnit> {
|
|
|
65
65
|
defaultCollapsed?: boolean;
|
|
66
66
|
/** The size of the panel once collapsed */
|
|
67
67
|
collapsedSize?: T;
|
|
68
|
+
/**
|
|
69
|
+
* By default the layout will be stored in percentage values while at rest.
|
|
70
|
+
* This makes scaling the layout easier when the container is resized.
|
|
71
|
+
* However you might have a panel you want to stay at a static size when
|
|
72
|
+
* the container is resized.
|
|
73
|
+
*/
|
|
74
|
+
isStaticAtRest?: boolean;
|
|
68
75
|
}
|
|
69
76
|
|
|
70
77
|
interface Order {
|
|
@@ -228,6 +235,7 @@ interface SetSizeEvent {
|
|
|
228
235
|
/** Set the size of the whole group */
|
|
229
236
|
type: "setSize";
|
|
230
237
|
size: Rect;
|
|
238
|
+
handleOverflow?: boolean;
|
|
231
239
|
}
|
|
232
240
|
|
|
233
241
|
interface SetActualItemsSizeEvent {
|
|
@@ -406,23 +414,24 @@ type OnResizeSize = {
|
|
|
406
414
|
|
|
407
415
|
export type OnResizeCallback = (size: OnResizeSize) => void;
|
|
408
416
|
|
|
409
|
-
|
|
417
|
+
type InitializePanelOptions = {
|
|
410
418
|
min?: Unit;
|
|
411
419
|
max?: Unit;
|
|
412
420
|
default?: Unit;
|
|
413
|
-
collapsible?: boolean;
|
|
414
|
-
collapsed?: boolean;
|
|
415
421
|
collapsedSize?: Unit;
|
|
416
|
-
onCollapseChange?: {
|
|
417
|
-
current: ((isCollapsed: boolean) => void) | null | undefined;
|
|
418
|
-
};
|
|
419
|
-
onResize?: {
|
|
420
|
-
current: OnResizeCallback | null | undefined;
|
|
421
|
-
};
|
|
422
|
-
collapseAnimation?: PanelData["collapseAnimation"];
|
|
423
|
-
defaultCollapsed?: boolean;
|
|
424
422
|
id?: string;
|
|
425
|
-
}
|
|
423
|
+
} & Partial<
|
|
424
|
+
Pick<
|
|
425
|
+
PanelData,
|
|
426
|
+
| "isStaticAtRest"
|
|
427
|
+
| "collapseAnimation"
|
|
428
|
+
| "defaultCollapsed"
|
|
429
|
+
| "onResize"
|
|
430
|
+
| "collapsible"
|
|
431
|
+
| "collapsed"
|
|
432
|
+
| "onCollapseChange"
|
|
433
|
+
>
|
|
434
|
+
>;
|
|
426
435
|
|
|
427
436
|
type InitializePanelOptionsWithId = InitializePanelOptions & { id: string };
|
|
428
437
|
|
|
@@ -468,6 +477,7 @@ export function initializePanel(
|
|
|
468
477
|
id: item.id,
|
|
469
478
|
collapseAnimation: item.collapseAnimation,
|
|
470
479
|
default: item.default ? parseUnit(item.default) : undefined,
|
|
480
|
+
isStaticAtRest: item.isStaticAtRest,
|
|
471
481
|
} satisfies Omit<PanelData, "id" | "currentValue"> & { id?: string };
|
|
472
482
|
|
|
473
483
|
return { ...data, currentValue: makePixelUnit(-1) } satisfies Omit<
|
|
@@ -686,10 +696,7 @@ function panelHasSpace(
|
|
|
686
696
|
);
|
|
687
697
|
}
|
|
688
698
|
|
|
689
|
-
return (
|
|
690
|
-
item.currentValue.value.gt(getUnitPixelValue(context, item.min)) &&
|
|
691
|
-
item.currentValue.value.lte(getUnitPixelValue(context, item.max))
|
|
692
|
-
);
|
|
699
|
+
return item.currentValue.value.gt(getUnitPixelValue(context, item.min));
|
|
693
700
|
}
|
|
694
701
|
|
|
695
702
|
/** Search in a `direction` for a panel that still has space to expand. */
|
|
@@ -726,11 +733,9 @@ function getStaticWidth(context: GroupMachineContextValue) {
|
|
|
726
733
|
for (const item of context.items) {
|
|
727
734
|
if (isPanelHandle(item)) {
|
|
728
735
|
width = width.add(item.size.value);
|
|
729
|
-
} else if (
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
item.currentValue.type === "pixel"
|
|
733
|
-
) {
|
|
736
|
+
} else if (item.collapsed && item.currentValue.type === "pixel") {
|
|
737
|
+
width = width.add(item.currentValue.value);
|
|
738
|
+
} else if (item.isStaticAtRest) {
|
|
734
739
|
width = width.add(item.currentValue.value);
|
|
735
740
|
}
|
|
736
741
|
}
|
|
@@ -805,6 +810,11 @@ export function buildTemplate(context: GroupMachineContextValue) {
|
|
|
805
810
|
item.currentValue.type === "pixel" &&
|
|
806
811
|
item.currentValue.value.toNumber() !== -1
|
|
807
812
|
) {
|
|
813
|
+
if (item.isStaticAtRest) {
|
|
814
|
+
const max = item.max === "1fr" ? "100%" : formatUnit(item.max);
|
|
815
|
+
return `clamp(${min}, ${formatUnit(item.currentValue)}, ${max})`;
|
|
816
|
+
}
|
|
817
|
+
|
|
808
818
|
return formatUnit(item.currentValue);
|
|
809
819
|
} else if (item.currentValue.type === "percent") {
|
|
810
820
|
const max = item.max === "1fr" ? "100%" : formatUnit(item.max);
|
|
@@ -919,18 +929,18 @@ function createUnrestrainedPanel(_: GroupMachineContextValue, data: PanelData) {
|
|
|
919
929
|
*/
|
|
920
930
|
|
|
921
931
|
/** Converts the items to pixels */
|
|
922
|
-
export function prepareItems(context: GroupMachineContextValue) {
|
|
932
|
+
export function prepareItems(context: GroupMachineContextValue): Item[] {
|
|
923
933
|
const staticWidth = getStaticWidth(context);
|
|
924
934
|
const newItems = [];
|
|
925
935
|
|
|
926
936
|
for (const item of context.items) {
|
|
927
937
|
if (!item || !isPanelData(item)) {
|
|
928
|
-
newItems.push(item);
|
|
938
|
+
newItems.push({ ...item });
|
|
929
939
|
continue;
|
|
930
940
|
}
|
|
931
941
|
|
|
932
942
|
if (item.currentValue.type === "pixel") {
|
|
933
|
-
newItems.push(item);
|
|
943
|
+
newItems.push({ ...item });
|
|
934
944
|
continue;
|
|
935
945
|
}
|
|
936
946
|
|
|
@@ -1031,6 +1041,10 @@ function updateLayout(
|
|
|
1031
1041
|
|
|
1032
1042
|
const isInDragBugger =
|
|
1033
1043
|
newDragOvershoot.abs().lt(COLLAPSE_THRESHOLD) &&
|
|
1044
|
+
// Let the panel expand at it's min size
|
|
1045
|
+
!panelAfter.currentValue.value
|
|
1046
|
+
.add(newDragOvershoot.abs())
|
|
1047
|
+
.gte(panelAfter.min.value) &&
|
|
1034
1048
|
panelAfter.collapsible &&
|
|
1035
1049
|
panelAfter.collapsed &&
|
|
1036
1050
|
(isInLeftOvershoot || isInRightOvershoot);
|
|
@@ -1048,9 +1062,11 @@ function updateLayout(
|
|
|
1048
1062
|
|
|
1049
1063
|
// Don't let the panel collapse until the threshold is reached
|
|
1050
1064
|
if (
|
|
1065
|
+
!dragEvent.disregardCollapseBuffer &&
|
|
1051
1066
|
panelBefore.collapsible &&
|
|
1052
|
-
panelBefore.currentValue.value
|
|
1067
|
+
panelBefore.currentValue.value.eq(
|
|
1053
1068
|
getUnitPixelValue(context, panelBefore.min)
|
|
1069
|
+
)
|
|
1054
1070
|
) {
|
|
1055
1071
|
const potentialNewValue = panelBefore.currentValue.value.sub(
|
|
1056
1072
|
newDragOvershoot.abs()
|
|
@@ -1116,8 +1132,6 @@ function updateLayout(
|
|
|
1116
1132
|
.add(Math.abs(moveAmount))
|
|
1117
1133
|
);
|
|
1118
1134
|
|
|
1119
|
-
panelAfter.collapsed = false;
|
|
1120
|
-
|
|
1121
1135
|
if (extra.gt(0)) {
|
|
1122
1136
|
panelAfterNewValue = panelAfterNewValue.add(extra);
|
|
1123
1137
|
}
|
|
@@ -1131,6 +1145,13 @@ function updateLayout(
|
|
|
1131
1145
|
.minus(Math.abs(moveAmount))
|
|
1132
1146
|
);
|
|
1133
1147
|
|
|
1148
|
+
if (panelBeforeNewValue.lt(panelBefore.min.value)) {
|
|
1149
|
+
// TODO this should probably distribute the space between the panels?
|
|
1150
|
+
return { dragOvershoot: newDragOvershoot };
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
panelAfter.collapsed = false;
|
|
1154
|
+
|
|
1134
1155
|
if (
|
|
1135
1156
|
panelAfter.onCollapseChange?.current &&
|
|
1136
1157
|
!panelAfter.collapseIsControlled &&
|
|
@@ -1140,9 +1161,9 @@ function updateLayout(
|
|
|
1140
1161
|
}
|
|
1141
1162
|
}
|
|
1142
1163
|
|
|
1143
|
-
const panelBeforeIsAboutToCollapse =
|
|
1144
|
-
panelBefore.
|
|
1145
|
-
|
|
1164
|
+
const panelBeforeIsAboutToCollapse = panelBefore.currentValue.value.eq(
|
|
1165
|
+
getUnitPixelValue(context, panelBefore.min)
|
|
1166
|
+
);
|
|
1146
1167
|
|
|
1147
1168
|
// If the panel was expanded and now is at it's min size, collapse it
|
|
1148
1169
|
if (
|
|
@@ -1187,8 +1208,11 @@ function updateLayout(
|
|
|
1187
1208
|
);
|
|
1188
1209
|
|
|
1189
1210
|
if (!leftoverSpace.eq(0)) {
|
|
1190
|
-
panelBefore.currentValue.value =
|
|
1191
|
-
|
|
1211
|
+
panelBefore.currentValue.value = clampUnit(
|
|
1212
|
+
context,
|
|
1213
|
+
panelBefore,
|
|
1214
|
+
panelBefore.currentValue.value.add(leftoverSpace)
|
|
1215
|
+
);
|
|
1192
1216
|
}
|
|
1193
1217
|
|
|
1194
1218
|
return { items: newItems };
|
|
@@ -1215,7 +1239,7 @@ function commitLayout(context: GroupMachineContextValue) {
|
|
|
1215
1239
|
const staticWidth = getStaticWidth({ ...context, items: newItems });
|
|
1216
1240
|
|
|
1217
1241
|
newItems.forEach((item, index) => {
|
|
1218
|
-
if (item.type !== "panel" || item.collapsed) {
|
|
1242
|
+
if (item.type !== "panel" || item.collapsed || item.isStaticAtRest) {
|
|
1219
1243
|
return;
|
|
1220
1244
|
}
|
|
1221
1245
|
|
|
@@ -1334,6 +1358,81 @@ function applyDeltaInBothDirections(
|
|
|
1334
1358
|
}
|
|
1335
1359
|
}
|
|
1336
1360
|
|
|
1361
|
+
/**
|
|
1362
|
+
* A layout might overflow at small screen sizes.
|
|
1363
|
+
* This function tries to fix that by:
|
|
1364
|
+
*
|
|
1365
|
+
* 1. It will try to collapse a panel if it can.
|
|
1366
|
+
*/
|
|
1367
|
+
function handleOverflow(context: GroupMachineContextValue) {
|
|
1368
|
+
// If we haven't measured yet we can't do anything
|
|
1369
|
+
if (
|
|
1370
|
+
context.items.some((i) => isPanelData(i) && i.currentValue.value.eq(-1))
|
|
1371
|
+
) {
|
|
1372
|
+
return context;
|
|
1373
|
+
}
|
|
1374
|
+
|
|
1375
|
+
const groupSize = new Big(getGroupSize(context));
|
|
1376
|
+
const nonStaticWidth = groupSize.sub(getStaticWidth(context).toNumber());
|
|
1377
|
+
const pixelItems = context.items.map((i) => {
|
|
1378
|
+
if (isPanelHandle(i)) return i.size.value;
|
|
1379
|
+
if (i.collapsed) return getUnitPixelValue(context, i.currentValue);
|
|
1380
|
+
|
|
1381
|
+
const pixel =
|
|
1382
|
+
(i.currentValue.type === "pixel" && i.currentValue.value) ||
|
|
1383
|
+
i.currentValue.value.mul(nonStaticWidth);
|
|
1384
|
+
|
|
1385
|
+
return clampUnit(context, i, pixel);
|
|
1386
|
+
});
|
|
1387
|
+
const totalSize = pixelItems.reduce((acc, i) => acc.add(i), new Big(0));
|
|
1388
|
+
const overflow = totalSize.abs().sub(groupSize);
|
|
1389
|
+
|
|
1390
|
+
if (overflow.eq(0) || groupSize.eq(0)) {
|
|
1391
|
+
return context;
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
let newContext = { ...context, items: prepareItems(context) };
|
|
1395
|
+
|
|
1396
|
+
const collapsiblePanel = newContext.items.find((i): i is PanelData =>
|
|
1397
|
+
Boolean(isPanelData(i) && i.collapsible)
|
|
1398
|
+
);
|
|
1399
|
+
|
|
1400
|
+
if (collapsiblePanel) {
|
|
1401
|
+
const collapsiblePanelIndex = newContext.items.findIndex(
|
|
1402
|
+
(i) => i.id === collapsiblePanel.id
|
|
1403
|
+
);
|
|
1404
|
+
const handleId = getHandleForPanelId(newContext, collapsiblePanel.id);
|
|
1405
|
+
const sizeChange = collapsiblePanel.currentValue.value.sub(
|
|
1406
|
+
getUnitPixelValue(newContext, collapsiblePanel.collapsedSize)
|
|
1407
|
+
);
|
|
1408
|
+
|
|
1409
|
+
// Try to collapse the panel
|
|
1410
|
+
newContext = {
|
|
1411
|
+
...newContext,
|
|
1412
|
+
...iterativelyUpdateLayout({
|
|
1413
|
+
handleId: handleId.item.id,
|
|
1414
|
+
delta: sizeChange,
|
|
1415
|
+
direction: (handleId.direction * -1) as -1 | 1,
|
|
1416
|
+
context: {
|
|
1417
|
+
...newContext,
|
|
1418
|
+
// act like its the old size so the space is distributed correctly
|
|
1419
|
+
size: { width: totalSize.toNumber(), height: totalSize.toNumber() },
|
|
1420
|
+
},
|
|
1421
|
+
}),
|
|
1422
|
+
};
|
|
1423
|
+
|
|
1424
|
+
// Then remove all the overflow
|
|
1425
|
+
applyDeltaInBothDirections(
|
|
1426
|
+
newContext,
|
|
1427
|
+
newContext.items,
|
|
1428
|
+
collapsiblePanelIndex,
|
|
1429
|
+
overflow.neg()
|
|
1430
|
+
);
|
|
1431
|
+
}
|
|
1432
|
+
|
|
1433
|
+
return { ...newContext, items: commitLayout(newContext) };
|
|
1434
|
+
}
|
|
1435
|
+
|
|
1337
1436
|
// #endregion
|
|
1338
1437
|
|
|
1339
1438
|
// #region Machine
|
|
@@ -1349,6 +1448,22 @@ interface AnimationActorOutput {
|
|
|
1349
1448
|
action: "expand" | "collapse";
|
|
1350
1449
|
}
|
|
1351
1450
|
|
|
1451
|
+
function getDeltaForEvent(
|
|
1452
|
+
context: GroupMachineContextValue,
|
|
1453
|
+
event: CollapsePanelEvent | ExpandPanelEvent
|
|
1454
|
+
) {
|
|
1455
|
+
const panel = getPanelWithId(context, event.panelId);
|
|
1456
|
+
|
|
1457
|
+
if (event.type === "expandPanel") {
|
|
1458
|
+
return new Big(
|
|
1459
|
+
panel.sizeBeforeCollapse ?? getUnitPixelValue(context, panel.min)
|
|
1460
|
+
).minus(panel.currentValue.value);
|
|
1461
|
+
}
|
|
1462
|
+
|
|
1463
|
+
const collapsedSize = getUnitPixelValue(context, panel.collapsedSize);
|
|
1464
|
+
return panel.currentValue.value.minus(collapsedSize);
|
|
1465
|
+
}
|
|
1466
|
+
|
|
1352
1467
|
const animationActor = fromPromise<
|
|
1353
1468
|
AnimationActorOutput | undefined,
|
|
1354
1469
|
AnimationActorInput
|
|
@@ -1359,18 +1474,11 @@ const animationActor = fromPromise<
|
|
|
1359
1474
|
const handle = getHandleForPanelId(context, event.panelId);
|
|
1360
1475
|
|
|
1361
1476
|
let direction = new Big(handle.direction);
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
if (event.type === "expandPanel") {
|
|
1365
|
-
fullDelta = new Big(
|
|
1366
|
-
panel.sizeBeforeCollapse ?? getUnitPixelValue(context, panel.min)
|
|
1367
|
-
).minus(panel.currentValue.value);
|
|
1368
|
-
} else {
|
|
1369
|
-
const collapsedSize = getUnitPixelValue(context, panel.collapsedSize);
|
|
1477
|
+
const fullDelta = getDeltaForEvent(context, event);
|
|
1370
1478
|
|
|
1479
|
+
if (event.type === "collapsePanel") {
|
|
1371
1480
|
panel.sizeBeforeCollapse = panel.currentValue.value.toNumber();
|
|
1372
1481
|
direction = direction.mul(new Big(-1));
|
|
1373
|
-
fullDelta = panel.currentValue.value.minus(collapsedSize);
|
|
1374
1482
|
}
|
|
1375
1483
|
|
|
1376
1484
|
const fps = 60;
|
|
@@ -1457,6 +1565,8 @@ export const groupMachine = createMachine(
|
|
|
1457
1565
|
{ target: "togglingCollapse" },
|
|
1458
1566
|
],
|
|
1459
1567
|
expandPanel: [
|
|
1568
|
+
// This will match if we can't expand and the expansion won't happen
|
|
1569
|
+
{ guard: "cannotExpandPanel" },
|
|
1460
1570
|
{
|
|
1461
1571
|
actions: "notifyCollapseToggle",
|
|
1462
1572
|
guard: "shouldNotifyCollapseToggle",
|
|
@@ -1530,6 +1640,38 @@ export const groupMachine = createMachine(
|
|
|
1530
1640
|
const panel = getPanelWithId(context, event.panelId);
|
|
1531
1641
|
return panel.collapseIsControlled === true;
|
|
1532
1642
|
},
|
|
1643
|
+
cannotExpandPanel: ({ context, event }) => {
|
|
1644
|
+
isEvent(event, ["expandPanel"]);
|
|
1645
|
+
const delta = getDeltaForEvent(context, event);
|
|
1646
|
+
const handle = getHandleForPanelId(context, event.panelId);
|
|
1647
|
+
const pixelItems = prepareItems(context);
|
|
1648
|
+
|
|
1649
|
+
let interimContext = { ...context, items: pixelItems };
|
|
1650
|
+
interimContext = {
|
|
1651
|
+
...interimContext,
|
|
1652
|
+
...iterativelyUpdateLayout({
|
|
1653
|
+
context: interimContext,
|
|
1654
|
+
handleId: handle.item.id,
|
|
1655
|
+
controlled: event.controlled,
|
|
1656
|
+
delta: delta,
|
|
1657
|
+
direction: handle.direction,
|
|
1658
|
+
}),
|
|
1659
|
+
};
|
|
1660
|
+
const updatedPanel = interimContext.items.find(
|
|
1661
|
+
(i) => i.id === event.panelId
|
|
1662
|
+
);
|
|
1663
|
+
const totalSize = interimContext.items.reduce(
|
|
1664
|
+
(acc, i) =>
|
|
1665
|
+
acc.add(isPanelData(i) ? i.currentValue.value : i.size.value),
|
|
1666
|
+
new Big(0)
|
|
1667
|
+
);
|
|
1668
|
+
const didExpand =
|
|
1669
|
+
updatedPanel &&
|
|
1670
|
+
isPanelData(updatedPanel) &&
|
|
1671
|
+
!updatedPanel.currentValue.value.eq(updatedPanel.collapsedSize.value);
|
|
1672
|
+
|
|
1673
|
+
return totalSize.gt(getGroupSize(context)) || !didExpand;
|
|
1674
|
+
},
|
|
1533
1675
|
},
|
|
1534
1676
|
actors: {
|
|
1535
1677
|
animation: animationActor,
|
|
@@ -1575,11 +1717,14 @@ export const groupMachine = createMachine(
|
|
|
1575
1717
|
return context.items;
|
|
1576
1718
|
},
|
|
1577
1719
|
}),
|
|
1578
|
-
updateSize:
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1720
|
+
updateSize: enqueueActions(({ context, event, enqueue }) => {
|
|
1721
|
+
isEvent(event, ["setSize"]);
|
|
1722
|
+
|
|
1723
|
+
if (event.handleOverflow) {
|
|
1724
|
+
enqueue.assign(handleOverflow({ ...context, size: event.size }));
|
|
1725
|
+
} else {
|
|
1726
|
+
enqueue.assign({ size: event.size });
|
|
1727
|
+
}
|
|
1583
1728
|
}),
|
|
1584
1729
|
recordActualItemSize: assign({
|
|
1585
1730
|
items: ({ context, event }) => {
|
|
@@ -1763,10 +1908,14 @@ export const groupMachine = createMachine(
|
|
|
1763
1908
|
item,
|
|
1764
1909
|
getUnitPixelValue(context, item.currentValue)
|
|
1765
1910
|
);
|
|
1911
|
+
const groupSize = getGroupSize(context);
|
|
1766
1912
|
|
|
1767
1913
|
item.onResize?.current?.({
|
|
1768
1914
|
pixel: pixel.toNumber(),
|
|
1769
|
-
percentage:
|
|
1915
|
+
percentage:
|
|
1916
|
+
groupSize > 0
|
|
1917
|
+
? pixel.div(getGroupSize(context)).toNumber()
|
|
1918
|
+
: -1,
|
|
1770
1919
|
});
|
|
1771
1920
|
}
|
|
1772
1921
|
}
|
package/src/machine.test.ts
CHANGED
|
@@ -1301,6 +1301,189 @@ describe("collapsible panel", () => {
|
|
|
1301
1301
|
expect(getTemplate(actor)).toMatchInlineSnapshot(`"245px 10px 245px"`);
|
|
1302
1302
|
});
|
|
1303
1303
|
});
|
|
1304
|
+
|
|
1305
|
+
describe("constraints", () => {
|
|
1306
|
+
test("on render", async () => {
|
|
1307
|
+
const actor = createActor(groupMachine, {
|
|
1308
|
+
input: { groupId: "group" },
|
|
1309
|
+
}).start();
|
|
1310
|
+
|
|
1311
|
+
sendAll(actor, [
|
|
1312
|
+
{
|
|
1313
|
+
type: "registerPanel",
|
|
1314
|
+
data: initializePanel({ id: "panel-1", min: "200px" }),
|
|
1315
|
+
},
|
|
1316
|
+
{
|
|
1317
|
+
type: "registerPanelHandle",
|
|
1318
|
+
data: { id: "resizer-1", size: "10px" },
|
|
1319
|
+
},
|
|
1320
|
+
{
|
|
1321
|
+
type: "registerPanel",
|
|
1322
|
+
data: initializePanel({
|
|
1323
|
+
id: "panel-2",
|
|
1324
|
+
collapsible: true,
|
|
1325
|
+
min: "300px",
|
|
1326
|
+
collapsedSize: "60px",
|
|
1327
|
+
}),
|
|
1328
|
+
},
|
|
1329
|
+
]);
|
|
1330
|
+
|
|
1331
|
+
expect(getTemplate(actor)).toBe(
|
|
1332
|
+
"minmax(200px, 1fr) 10px minmax(300px, 1fr)"
|
|
1333
|
+
);
|
|
1334
|
+
initializeSizes(actor, { width: 400, height: 200 });
|
|
1335
|
+
actor.send({
|
|
1336
|
+
type: "setSize",
|
|
1337
|
+
size: { width: 400, height: 200 },
|
|
1338
|
+
handleOverflow: true,
|
|
1339
|
+
});
|
|
1340
|
+
// There wasn't enough space to render the panel so the last one is collapsed
|
|
1341
|
+
expect(getTemplate(actor)).toBe(
|
|
1342
|
+
"minmax(200px, min(calc(1 * (100% - 70px)), 100%)) 10px 60px"
|
|
1343
|
+
);
|
|
1344
|
+
});
|
|
1345
|
+
|
|
1346
|
+
test("on resize", async () => {
|
|
1347
|
+
const actor = createActor(groupMachine, {
|
|
1348
|
+
input: { groupId: "group" },
|
|
1349
|
+
}).start();
|
|
1350
|
+
|
|
1351
|
+
sendAll(actor, [
|
|
1352
|
+
{
|
|
1353
|
+
type: "registerPanel",
|
|
1354
|
+
data: initializePanel({ id: "panel-1", min: "200px" }),
|
|
1355
|
+
},
|
|
1356
|
+
{
|
|
1357
|
+
type: "registerPanelHandle",
|
|
1358
|
+
data: { id: "resizer-1", size: "10px" },
|
|
1359
|
+
},
|
|
1360
|
+
{
|
|
1361
|
+
type: "registerPanel",
|
|
1362
|
+
data: initializePanel({
|
|
1363
|
+
id: "panel-2",
|
|
1364
|
+
collapsible: true,
|
|
1365
|
+
min: "300px",
|
|
1366
|
+
collapsedSize: "60px",
|
|
1367
|
+
}),
|
|
1368
|
+
},
|
|
1369
|
+
]);
|
|
1370
|
+
|
|
1371
|
+
expect(getTemplate(actor)).toBe(
|
|
1372
|
+
"minmax(200px, 1fr) 10px minmax(300px, 1fr)"
|
|
1373
|
+
);
|
|
1374
|
+
initializeSizes(actor, { width: 500, height: 200 });
|
|
1375
|
+
expect(getTemplate(actor)).toBe(
|
|
1376
|
+
"minmax(200px, min(calc(0.40816326530612244898 * (100% - 10px)), 100%)) 10px minmax(300px, min(calc(0.61224489795918367347 * (100% - 10px)), 100%))"
|
|
1377
|
+
);
|
|
1378
|
+
|
|
1379
|
+
actor.send({
|
|
1380
|
+
type: "setSize",
|
|
1381
|
+
size: { width: 400, height: 200 },
|
|
1382
|
+
handleOverflow: true,
|
|
1383
|
+
});
|
|
1384
|
+
// There wasn't enough space to render the panel so the last one is collapsed
|
|
1385
|
+
expect(getTemplate(actor)).toBe(
|
|
1386
|
+
"minmax(200px, min(calc(1 * (100% - 70px)), 100%)) 10px 60px"
|
|
1387
|
+
);
|
|
1388
|
+
});
|
|
1389
|
+
|
|
1390
|
+
test("cannot expand panel via event", async () => {
|
|
1391
|
+
const actor = createActor(groupMachine, {
|
|
1392
|
+
input: { groupId: "group" },
|
|
1393
|
+
}).start();
|
|
1394
|
+
|
|
1395
|
+
sendAll(actor, [
|
|
1396
|
+
{
|
|
1397
|
+
type: "registerPanel",
|
|
1398
|
+
data: initializePanel({ id: "panel-1", min: "200px" }),
|
|
1399
|
+
},
|
|
1400
|
+
{
|
|
1401
|
+
type: "registerPanelHandle",
|
|
1402
|
+
data: { id: "resizer-1", size: "10px" },
|
|
1403
|
+
},
|
|
1404
|
+
{
|
|
1405
|
+
type: "registerPanel",
|
|
1406
|
+
data: initializePanel({
|
|
1407
|
+
id: "panel-2",
|
|
1408
|
+
collapsible: true,
|
|
1409
|
+
min: "300px",
|
|
1410
|
+
collapsedSize: "60px",
|
|
1411
|
+
}),
|
|
1412
|
+
},
|
|
1413
|
+
]);
|
|
1414
|
+
|
|
1415
|
+
expect(getTemplate(actor)).toBe(
|
|
1416
|
+
"minmax(200px, 1fr) 10px minmax(300px, 1fr)"
|
|
1417
|
+
);
|
|
1418
|
+
initializeSizes(actor, { width: 400, height: 200 });
|
|
1419
|
+
actor.send({
|
|
1420
|
+
type: "setSize",
|
|
1421
|
+
size: { width: 400, height: 200 },
|
|
1422
|
+
handleOverflow: true,
|
|
1423
|
+
});
|
|
1424
|
+
// There wasn't enough space to render the panel so the last one is collapsed
|
|
1425
|
+
expect(getTemplate(actor)).toBe(
|
|
1426
|
+
"minmax(200px, min(calc(1 * (100% - 70px)), 100%)) 10px 60px"
|
|
1427
|
+
);
|
|
1428
|
+
|
|
1429
|
+
actor.send({
|
|
1430
|
+
type: "expandPanel",
|
|
1431
|
+
panelId: "panel-2",
|
|
1432
|
+
});
|
|
1433
|
+
await waitForIdle(actor);
|
|
1434
|
+
|
|
1435
|
+
// There wasn't enough space to render the panel so the last one is collapsed
|
|
1436
|
+
expect(getTemplate(actor)).toBe(
|
|
1437
|
+
"minmax(200px, min(calc(1 * (100% - 70px)), 100%)) 10px 60px"
|
|
1438
|
+
);
|
|
1439
|
+
});
|
|
1440
|
+
|
|
1441
|
+
test("cannot expand panel via drag", async () => {
|
|
1442
|
+
const actor = createActor(groupMachine, {
|
|
1443
|
+
input: { groupId: "group" },
|
|
1444
|
+
}).start();
|
|
1445
|
+
|
|
1446
|
+
sendAll(actor, [
|
|
1447
|
+
{
|
|
1448
|
+
type: "registerPanel",
|
|
1449
|
+
data: initializePanel({ id: "panel-1", min: "200px" }),
|
|
1450
|
+
},
|
|
1451
|
+
{
|
|
1452
|
+
type: "registerPanelHandle",
|
|
1453
|
+
data: { id: "resizer-1", size: "10px" },
|
|
1454
|
+
},
|
|
1455
|
+
{
|
|
1456
|
+
type: "registerPanel",
|
|
1457
|
+
data: initializePanel({
|
|
1458
|
+
id: "panel-2",
|
|
1459
|
+
collapsible: true,
|
|
1460
|
+
min: "300px",
|
|
1461
|
+
collapsedSize: "60px",
|
|
1462
|
+
}),
|
|
1463
|
+
},
|
|
1464
|
+
]);
|
|
1465
|
+
|
|
1466
|
+
expect(getTemplate(actor)).toBe(
|
|
1467
|
+
"minmax(200px, 1fr) 10px minmax(300px, 1fr)"
|
|
1468
|
+
);
|
|
1469
|
+
initializeSizes(actor, { width: 400, height: 200 });
|
|
1470
|
+
actor.send({
|
|
1471
|
+
type: "setSize",
|
|
1472
|
+
size: { width: 400, height: 200 },
|
|
1473
|
+
handleOverflow: true,
|
|
1474
|
+
});
|
|
1475
|
+
// There wasn't enough space to render the panel so the last one is collapsed
|
|
1476
|
+
expect(getTemplate(actor)).toBe(
|
|
1477
|
+
"minmax(200px, min(calc(1 * (100% - 70px)), 100%)) 10px 60px"
|
|
1478
|
+
);
|
|
1479
|
+
|
|
1480
|
+
// Drag the resizer to the right
|
|
1481
|
+
capturePixelValues(actor, () => {
|
|
1482
|
+
dragHandle(actor, { id: "resizer-1", delta: -400 });
|
|
1483
|
+
expect(getTemplate(actor)).toBe("330px 10px 60px");
|
|
1484
|
+
});
|
|
1485
|
+
});
|
|
1486
|
+
});
|
|
1304
1487
|
});
|
|
1305
1488
|
|
|
1306
1489
|
describe("conditional panel", () => {
|
|
@@ -1749,3 +1932,39 @@ describe("utils", async () => {
|
|
|
1749
1932
|
expect(newSnapshot).toMatchSnapshot();
|
|
1750
1933
|
});
|
|
1751
1934
|
});
|
|
1935
|
+
|
|
1936
|
+
describe("static at rest", () => {
|
|
1937
|
+
test("a panel can be pixels when resting", async () => {
|
|
1938
|
+
const actor = createActor(groupMachine, {
|
|
1939
|
+
input: {
|
|
1940
|
+
groupId: "group",
|
|
1941
|
+
initialItems: [
|
|
1942
|
+
initializePanel({
|
|
1943
|
+
id: "panel-1",
|
|
1944
|
+
min: "20px",
|
|
1945
|
+
max: "200px",
|
|
1946
|
+
isStaticAtRest: true,
|
|
1947
|
+
}),
|
|
1948
|
+
initializePanelHandleData({ id: "resizer-1", size: "10px" }),
|
|
1949
|
+
initializePanel({ id: "panel-2", min: "50px" }),
|
|
1950
|
+
initializePanelHandleData({ id: "resizer-2", size: "10px" }),
|
|
1951
|
+
initializePanel({ id: "panel-3", min: "50px" }),
|
|
1952
|
+
],
|
|
1953
|
+
},
|
|
1954
|
+
}).start();
|
|
1955
|
+
|
|
1956
|
+
initializeSizes(actor, { width: 500, height: 200 });
|
|
1957
|
+
|
|
1958
|
+
expect(getTemplate(actor)).toMatchInlineSnapshot(
|
|
1959
|
+
`"clamp(20px, 200px, 200px) 10px minmax(50px, min(calc(0.5 * (100% - 220px)), 100%)) 10px minmax(50px, min(calc(0.5 * (100% - 220px)), 100%))"`
|
|
1960
|
+
);
|
|
1961
|
+
|
|
1962
|
+
capturePixelValues(actor, () => {
|
|
1963
|
+
dragHandle(actor, { id: "resizer-1", delta: -10 });
|
|
1964
|
+
});
|
|
1965
|
+
|
|
1966
|
+
expect(getTemplate(actor)).toMatchInlineSnapshot(
|
|
1967
|
+
`"clamp(20px, 190px, 200px) 10px minmax(50px, min(calc(0.51724137931034482759 * (100% - 210px)), 100%)) 10px minmax(50px, min(calc(0.48275862068965517241 * (100% - 210px)), 100%))"`
|
|
1968
|
+
);
|
|
1969
|
+
});
|
|
1970
|
+
});
|