@window-splitter/state 0.4.0 → 0.4.1

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/esm/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import Cookies from "universal-cookie";
1
2
  import { raf } from "@react-spring/rafz";
2
3
  import { createMachine, assign, enqueueActions, fromPromise, } from "xstate";
3
4
  import invariant from "invariant";
@@ -70,9 +71,7 @@ export function getCursor(context) {
70
71
  }
71
72
  }
72
73
  export function prepareSnapshot(snapshot) {
73
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
74
- const snapshotContext = snapshot
75
- .context;
74
+ const snapshotContext = snapshot.context;
76
75
  snapshotContext.dragOvershoot = new Big(snapshotContext.dragOvershoot);
77
76
  for (const item of snapshotContext.items) {
78
77
  if (isPanelData(item)) {
@@ -349,6 +348,7 @@ export function getPanelPercentageSize(context, panelId) {
349
348
  /** Build the grid template from the item values. */
350
349
  export function buildTemplate(context) {
351
350
  const staticWidth = getStaticWidth(context);
351
+ let hasSeenFillPanel = false;
352
352
  return context.items
353
353
  .map((item) => {
354
354
  if (item.type === "panel") {
@@ -362,6 +362,12 @@ export function buildTemplate(context) {
362
362
  return formatUnit(item.currentValue);
363
363
  }
364
364
  else if (item.currentValue.type === "percent") {
365
+ if (!hasSeenFillPanel &&
366
+ (item.max === "1fr" ||
367
+ (item.max.type === "percent" && item.max.value.eq(100)))) {
368
+ hasSeenFillPanel = true;
369
+ return `minmax(${min}, 1fr)`;
370
+ }
365
371
  const max = item.max === "1fr" ? "100%" : formatUnit(item.max);
366
372
  return `minmax(${min}, min(calc(${item.currentValue.value} * (100% - ${staticWidth}px)), ${max}))`;
367
373
  }
@@ -467,6 +473,13 @@ export function prepareItems(context) {
467
473
  newItems.push({ ...item });
468
474
  continue;
469
475
  }
476
+ if (item.lastKnownSize) {
477
+ const lastSize = makePixelUnit(context.orientation === "horizontal"
478
+ ? item.lastKnownSize.width
479
+ : item.lastKnownSize.height);
480
+ newItems.push({ ...item, currentValue: lastSize });
481
+ continue;
482
+ }
470
483
  if (item.currentValue.type === "pixel") {
471
484
  newItems.push({ ...item });
472
485
  continue;
@@ -776,6 +789,9 @@ function handleOverflow(context) {
776
789
  }
777
790
  return { ...newContext, items: commitLayout(newContext) };
778
791
  }
792
+ function clearLastKnownSize(items) {
793
+ return items.map((i) => ({ ...i, lastKnownSize: undefined }));
794
+ }
779
795
  function getDeltaForEvent(context, event) {
780
796
  const panel = getPanelWithId(context, event.panelId);
781
797
  if (event.type === "expandPanel") {
@@ -835,15 +851,17 @@ export const groupMachine = createMachine({
835
851
  orientation: input.orientation || "horizontal",
836
852
  dragOvershoot: new Big(0),
837
853
  groupId: input.groupId,
854
+ autosaveStrategy: input.autosaveStrategy,
838
855
  }),
839
856
  states: {
840
857
  idle: {
858
+ entry: ["onAutosave"],
841
859
  on: {
842
- setActualItemsSize: { actions: ["recordActualItemSize", "onResize"] },
843
860
  dragHandleStart: { target: "dragging" },
844
861
  setPanelPixelSize: {
845
862
  actions: [
846
863
  "prepare",
864
+ "onClearLastKnownSize",
847
865
  "onSetPanelSize",
848
866
  "commit",
849
867
  "onResize",
@@ -871,7 +889,9 @@ export const groupMachine = createMachine({
871
889
  dragging: {
872
890
  entry: ["prepare"],
873
891
  on: {
874
- dragHandle: { actions: ["onDragHandle", "onResize"] },
892
+ dragHandle: {
893
+ actions: ["onClearLastKnownSize", "onDragHandle", "onResize"],
894
+ },
875
895
  dragHandleEnd: { target: "idle" },
876
896
  collapsePanel: {
877
897
  guard: "shouldCollapseToggle",
@@ -882,16 +902,16 @@ export const groupMachine = createMachine({
882
902
  actions: "runCollapseToggle",
883
903
  },
884
904
  },
885
- exit: ["commit", "onAutosave"],
905
+ exit: ["commit"],
886
906
  },
887
907
  togglingCollapse: {
888
- entry: ["prepare"],
908
+ entry: ["prepare", "onClearLastKnownSize"],
889
909
  invoke: {
890
910
  src: "animation",
891
911
  input: (i) => ({ ...i, send: i.self.send }),
892
912
  onDone: {
893
913
  target: "idle",
894
- actions: ["onToggleCollapseComplete", "commit", "onAutosave"],
914
+ actions: ["onToggleCollapseComplete", "commit"],
895
915
  },
896
916
  },
897
917
  on: {
@@ -900,25 +920,43 @@ export const groupMachine = createMachine({
900
920
  },
901
921
  },
902
922
  on: {
923
+ setActualItemsSize: { actions: ["recordActualItemSize", "onResize"] },
903
924
  registerPanel: { actions: ["assignPanelData"] },
904
925
  registerDynamicPanel: {
905
926
  actions: [
906
927
  "prepare",
907
928
  "onRegisterDynamicPanel",
929
+ "onClearLastKnownSize",
908
930
  "commit",
909
931
  "onResize",
910
932
  "onAutosave",
911
933
  ],
912
934
  },
913
935
  unregisterPanel: {
914
- actions: ["prepare", "removeItem", "commit", "onResize", "onAutosave"],
936
+ actions: [
937
+ "prepare",
938
+ "removeItem",
939
+ "onClearLastKnownSize",
940
+ "commit",
941
+ "onResize",
942
+ "onAutosave",
943
+ ],
915
944
  },
916
945
  registerPanelHandle: { actions: ["assignPanelHandleData"] },
917
946
  unregisterPanelHandle: {
918
- actions: ["prepare", "removeItem", "commit", "onResize", "onAutosave"],
947
+ actions: [
948
+ "prepare",
949
+ "removeItem",
950
+ "onClearLastKnownSize",
951
+ "commit",
952
+ "onResize",
953
+ "onAutosave",
954
+ ],
919
955
  },
920
956
  setSize: { actions: ["updateSize", "onResize"] },
921
- setOrientation: { actions: ["updateOrientation", "onResize"] },
957
+ setOrientation: {
958
+ actions: ["updateOrientation", "onClearLastKnownSize", "onResize"],
959
+ },
922
960
  },
923
961
  }, {
924
962
  guards: {
@@ -960,6 +998,24 @@ export const groupMachine = createMachine({
960
998
  animation: animationActor,
961
999
  },
962
1000
  actions: {
1001
+ onAutosave: ({ context, self }) => {
1002
+ if (!context.autosaveStrategy || typeof window === "undefined") {
1003
+ return;
1004
+ }
1005
+ const snapshot = self.getPersistedSnapshot();
1006
+ snapshot.context.items = clearLastKnownSize(context.items);
1007
+ snapshot.value = "idle";
1008
+ const data = JSON.stringify(snapshot);
1009
+ if (context.autosaveStrategy === "localStorage") {
1010
+ localStorage.setItem(context.groupId, data);
1011
+ }
1012
+ else {
1013
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
1014
+ const ActualClass = Cookies.default || Cookies;
1015
+ const cookies = new ActualClass(null, { path: "/" });
1016
+ cookies.set(context.groupId, data, { path: "/", maxAge: 31536000 });
1017
+ }
1018
+ },
963
1019
  notifyCollapseToggle: ({ context, event }) => {
964
1020
  isEvent(event, ["collapsePanel", "expandPanel"]);
965
1021
  const panel = getPanelWithId(context, event.panelId);
@@ -983,8 +1039,7 @@ export const groupMachine = createMachine({
983
1039
  }),
984
1040
  onToggleCollapseComplete: assign({
985
1041
  items: ({ context, event: e }) => {
986
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
987
- const output = e.output;
1042
+ const { output } = e;
988
1043
  invariant(output, "Expected output from animation actor");
989
1044
  const panel = getPanelWithId(context, output.panelId);
990
1045
  panel.collapsed = output.action === "collapse";
@@ -994,27 +1049,42 @@ export const groupMachine = createMachine({
994
1049
  return context.items;
995
1050
  },
996
1051
  }),
997
- updateSize: enqueueActions(({ context, event, enqueue }) => {
998
- isEvent(event, ["setSize"]);
999
- if (event.handleOverflow) {
1000
- enqueue.assign(handleOverflow({ ...context, size: event.size }));
1001
- }
1002
- else {
1003
- enqueue.assign({ size: event.size });
1004
- }
1052
+ updateSize: assign({
1053
+ size: ({ event }) => {
1054
+ isEvent(event, ["setSize"]);
1055
+ return event.size;
1056
+ },
1005
1057
  }),
1006
1058
  recordActualItemSize: assign({
1007
1059
  items: ({ context, event }) => {
1008
1060
  isEvent(event, ["setActualItemsSize"]);
1009
- const orientation = context.orientation;
1010
- for (const [id, size] of Object.entries(event.childrenSizes)) {
1011
- const item = context.items.find((i) => i.id === id);
1012
- if (!isPanelData(item)) {
1013
- continue;
1061
+ const withLastKnownSize = context.items.map((i) => {
1062
+ if (!isPanelData(i))
1063
+ return i;
1064
+ const lastKnownSize = event.childrenSizes[i.id] || i.lastKnownSize;
1065
+ return { ...i, lastKnownSize };
1066
+ });
1067
+ let totalSize = 0;
1068
+ for (const item of withLastKnownSize) {
1069
+ if (isPanelData(item)) {
1070
+ const size = item.lastKnownSize?.[context.orientation === "horizontal" ? "width" : "height"];
1071
+ // If any size is 0 don't handle overflow
1072
+ if (!size) {
1073
+ return withLastKnownSize;
1074
+ }
1075
+ totalSize += size;
1076
+ }
1077
+ else {
1078
+ totalSize += item.size.value.toNumber();
1014
1079
  }
1015
- item.currentValue = makePixelUnit(orientation === "horizontal" ? size.width : size.height);
1016
1080
  }
1017
- return commitLayout(context);
1081
+ if (totalSize > getGroupSize(context)) {
1082
+ return handleOverflow({
1083
+ ...context,
1084
+ items: prepareItems({ ...context, items: withLastKnownSize }),
1085
+ }).items;
1086
+ }
1087
+ return withLastKnownSize;
1018
1088
  },
1019
1089
  }),
1020
1090
  updateOrientation: assign({
@@ -1023,6 +1093,9 @@ export const groupMachine = createMachine({
1023
1093
  return event.orientation;
1024
1094
  },
1025
1095
  }),
1096
+ onClearLastKnownSize: assign({
1097
+ items: ({ context }) => clearLastKnownSize(context.items),
1098
+ }),
1026
1099
  assignPanelData: assign({
1027
1100
  items: ({ context, event }) => {
1028
1101
  isEvent(event, ["registerPanel"]);
@@ -1142,7 +1215,11 @@ export const groupMachine = createMachine({
1142
1215
  onResize: ({ context }) => {
1143
1216
  for (const item of context.items) {
1144
1217
  if (isPanelData(item)) {
1145
- const pixel = clampUnit(context, item, getUnitPixelValue(context, item.currentValue));
1218
+ const pixel = item.lastKnownSize
1219
+ ? new Big(context.orientation === "horizontal"
1220
+ ? item.lastKnownSize.width
1221
+ : item.lastKnownSize.height)
1222
+ : clampUnit(context, item, getUnitPixelValue(context, item.currentValue));
1146
1223
  const groupSize = getGroupSize(context);
1147
1224
  item.onResize?.current?.({
1148
1225
  pixel: pixel.toNumber(),