@window-splitter/state 0.5.8 → 0.6.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,6 +1,4 @@
1
- import * as Cookies from "tiny-cookie";
2
1
  import { raf } from "@react-spring/rafz";
3
- import { createMachine, assign, enqueueActions, fromPromise, } from "xstate";
4
2
  import invariant from "tiny-invariant";
5
3
  import Big from "big.js";
6
4
  // #region Constants
@@ -71,9 +69,15 @@ export function getCursor(context) {
71
69
  }
72
70
  }
73
71
  export function prepareSnapshot(snapshot) {
74
- const snapshotContext = snapshot.context;
75
- snapshotContext.dragOvershoot = new Big(snapshotContext.dragOvershoot);
76
- for (const item of snapshotContext.items) {
72
+ // convert from old format
73
+ if ("context" in snapshot) {
74
+ snapshot = snapshot.context;
75
+ }
76
+ if (!("items" in snapshot)) {
77
+ return;
78
+ }
79
+ snapshot.dragOvershoot = new Big(snapshot.dragOvershoot || 0);
80
+ for (const item of snapshot.items) {
77
81
  if (isPanelData(item)) {
78
82
  item.currentValue.value = new Big(item.currentValue.value);
79
83
  item.collapsedSize.value = new Big(item.collapsedSize.value);
@@ -837,6 +841,9 @@ function handleOverflow(context) {
837
841
  function clearLastKnownSize(items) {
838
842
  return items.map((i) => ({ ...i, lastKnownSize: undefined }));
839
843
  }
844
+ function setCookie(name, jsonData) {
845
+ document.cookie = `${name}=${encodeURIComponent(`${jsonData}`)};path=/;max-age=31536000`;
846
+ }
840
847
  function getDeltaForEvent(context, event) {
841
848
  const panel = getPanelWithId(context, event.panelId);
842
849
  if (event.type === "expandPanel") {
@@ -845,193 +852,168 @@ function getDeltaForEvent(context, event) {
845
852
  const collapsedSize = getUnitPixelValue(context, panel.collapsedSize);
846
853
  return panel.currentValue.value.minus(collapsedSize);
847
854
  }
848
- const animationActor = fromPromise(({ input: { send, context, event } }) => new Promise((resolve) => {
855
+ function animationActor(context, event, send, abortController) {
849
856
  const panel = getPanelWithId(context, event.panelId);
850
857
  const handle = getHandleForPanelId(context, event.panelId);
851
858
  let direction = new Big(handle.direction);
852
859
  const fullDelta = getDeltaForEvent(context, event);
853
- if (event.type === "collapsePanel") {
854
- panel.sizeBeforeCollapse = panel.currentValue.value.toNumber();
855
- direction = direction.mul(new Big(-1));
856
- }
857
- const fps = 60;
858
- const { duration, ease } = getCollapseAnimation(panel);
859
- const totalFrames = Math.ceil(panel.collapseAnimation ? duration / (1000 / fps) : 1);
860
- let frame = 0;
861
- let appliedDelta = new Big(0);
862
- function renderFrame() {
863
- const progress = ++frame / totalFrames;
864
- const e = new Big(panel.collapseAnimation ? ease(progress) : 1);
865
- const delta = e.mul(fullDelta).sub(appliedDelta).mul(direction);
866
- send({
867
- type: "applyDelta",
868
- handleId: handle.item.id,
869
- delta: delta.toNumber(),
860
+ return new Promise((resolve, reject) => {
861
+ abortController.signal.addEventListener("abort", () => {
862
+ reject(new Error("Operation was canceled"));
870
863
  });
871
- appliedDelta = appliedDelta.add(delta
872
- .abs()
873
- .mul((delta.gt(0) && direction.lt(0)) ||
874
- (delta.lt(0) && direction.gt(0))
875
- ? -1
876
- : 1));
877
- if (e.eq(1)) {
878
- const action = event.type === "expandPanel" ? "expand" : "collapse";
879
- resolve({ panelId: panel.id, action });
880
- return false;
864
+ if (event.type === "collapsePanel") {
865
+ panel.sizeBeforeCollapse = panel.currentValue.value.toNumber();
866
+ direction = direction.mul(new Big(-1));
881
867
  }
882
- return true;
868
+ const fps = 60;
869
+ const { duration, ease } = getCollapseAnimation(panel);
870
+ const totalFrames = Math.ceil(panel.collapseAnimation ? duration / (1000 / fps) : 1);
871
+ let frame = 0;
872
+ let appliedDelta = new Big(0);
873
+ function renderFrame() {
874
+ const progress = ++frame / totalFrames;
875
+ const e = new Big(panel.collapseAnimation ? ease(progress) : 1);
876
+ const delta = e.mul(fullDelta).sub(appliedDelta).mul(direction);
877
+ send({
878
+ type: "applyDelta",
879
+ handleId: handle.item.id,
880
+ delta: delta.toNumber(),
881
+ });
882
+ appliedDelta = appliedDelta.add(delta
883
+ .abs()
884
+ .mul((delta.gt(0) && direction.lt(0)) || (delta.lt(0) && direction.gt(0))
885
+ ? -1
886
+ : 1));
887
+ if (e.eq(1)) {
888
+ const action = event.type === "expandPanel" ? "expand" : "collapse";
889
+ resolve({ panelId: panel.id, action });
890
+ return false;
891
+ }
892
+ return true;
893
+ }
894
+ raf(renderFrame);
895
+ });
896
+ }
897
+ function assign(target, source) {
898
+ for (const key in source) {
899
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
900
+ target[key] = source[key];
883
901
  }
884
- raf(renderFrame);
885
- }));
886
- export const groupMachine = createMachine({
887
- initial: "idle",
888
- types: {
889
- context: {},
890
- events: {},
891
- input: {},
892
- },
893
- context: ({ input }) => ({
902
+ }
903
+ let groupId = 0;
904
+ export function groupMachine(input, onUpdate) {
905
+ const abortController = new AbortController();
906
+ const state = {
907
+ current: "idle",
908
+ };
909
+ let locked = false;
910
+ const context = {
894
911
  size: { width: 0, height: 0 },
895
- items: input.initialItems || [],
912
+ items: input.items || [],
896
913
  orientation: input.orientation || "horizontal",
897
914
  dragOvershoot: new Big(0),
898
- groupId: input.groupId,
915
+ groupId: input.groupId || `group-${groupId++}`,
899
916
  autosaveStrategy: input.autosaveStrategy,
900
- }),
901
- states: {
902
- idle: {
903
- entry: ["onAutosave"],
904
- on: {
905
- dragHandleStart: {
906
- target: "dragging",
907
- actions: ["onDragHandleStart"],
908
- },
909
- setPanelPixelSize: {
910
- actions: [
911
- "prepare",
912
- "onClearLastKnownSize",
913
- "onSetPanelSize",
914
- "commit",
915
- "onResize",
916
- "onAutosave",
917
- ],
918
- },
919
- collapsePanel: [
920
- {
921
- actions: "notifyCollapseToggle",
922
- guard: "shouldNotifyCollapseToggle",
923
- },
924
- { target: "togglingCollapse" },
925
- ],
926
- expandPanel: [
927
- // This will match if we can't expand and the expansion won't happen
928
- { guard: "cannotExpandPanel" },
929
- {
930
- actions: "notifyCollapseToggle",
931
- guard: "shouldNotifyCollapseToggle",
932
- },
933
- { target: "togglingCollapse" },
934
- ],
935
- },
917
+ };
918
+ const actions = {
919
+ prepare: () => {
920
+ context.items = prepareItems(context);
936
921
  },
937
- dragging: {
938
- entry: ["prepare"],
939
- on: {
940
- dragHandle: {
941
- actions: ["onClearLastKnownSize", "onDragHandle", "onResize"],
942
- },
943
- dragHandleEnd: { target: "idle" },
944
- collapsePanel: {
945
- guard: "shouldCollapseToggle",
946
- actions: "runCollapseToggle",
947
- },
948
- expandPanel: {
949
- guard: "shouldCollapseToggle",
950
- actions: "runCollapseToggle",
951
- },
952
- },
953
- exit: ["commit", "clearDragHandle"],
922
+ clearLastKnownSize: () => {
923
+ context.items = clearLastKnownSize(context.items);
954
924
  },
955
- togglingCollapse: {
956
- entry: ["prepare", "onClearLastKnownSize"],
957
- invoke: {
958
- src: "animation",
959
- input: (i) => ({ ...i, send: i.self.send }),
960
- onDone: {
961
- target: "idle",
962
- actions: ["onToggleCollapseComplete", "commit"],
963
- },
964
- },
965
- on: {
966
- applyDelta: { actions: ["onApplyDelta", "onResize"] },
967
- },
925
+ commit: () => {
926
+ context.dragOvershoot = new Big(0);
927
+ context.items = commitLayout(context);
968
928
  },
969
- },
970
- on: {
971
- setActualItemsSize: { actions: ["recordActualItemSize", "onResize"] },
972
- registerPanel: { actions: ["assignPanelData"] },
973
- rebindPanelCallbacks: {
974
- actions: ["rebindPanelCallbacks"],
929
+ onResize: () => {
930
+ for (const item of context.items) {
931
+ if (isPanelData(item)) {
932
+ const pixel = item.lastKnownSize
933
+ ? new Big(context.orientation === "horizontal"
934
+ ? item.lastKnownSize.width
935
+ : item.lastKnownSize.height)
936
+ : clampUnit(context, item, getUnitPixelValue(context, item.currentValue));
937
+ const groupSize = getGroupSize(context);
938
+ item.onResize?.current?.({
939
+ pixel: pixel.toNumber(),
940
+ percentage: groupSize > 0 ? pixel.div(getGroupSize(context)).toNumber() : -1,
941
+ });
942
+ }
943
+ }
975
944
  },
976
- updateConstraints: {
977
- actions: [
978
- "prepare",
979
- "updateConstraints",
980
- "onClearLastKnownSize",
981
- "commit",
982
- "onResize",
983
- "onAutosave",
984
- ],
945
+ onAutosave: () => {
946
+ if (!context.autosaveStrategy || typeof window === "undefined") {
947
+ return;
948
+ }
949
+ const snapshot = { ...context };
950
+ snapshot.items = clearLastKnownSize(context.items);
951
+ snapshot.activeDragHandleId = context.activeDragHandleId;
952
+ const data = JSON.stringify(snapshot);
953
+ if (context.autosaveStrategy === "localStorage") {
954
+ localStorage.setItem(context.groupId, data);
955
+ }
956
+ else {
957
+ setCookie(context.groupId, data);
958
+ }
985
959
  },
986
- registerDynamicPanel: {
987
- actions: [
988
- "prepare",
989
- "onRegisterDynamicPanel",
990
- "onClearLastKnownSize",
991
- "commit",
992
- "onResize",
993
- "onAutosave",
994
- ],
960
+ removeItem: (id) => {
961
+ const itemIndex = context.items.findIndex((item) => item.id === id);
962
+ const item = context.items[itemIndex];
963
+ if (!item) {
964
+ return;
965
+ }
966
+ const newItems = context.items.filter((i) => i.id !== id);
967
+ const removedSize = isPanelData(item)
968
+ ? item.currentValue.value
969
+ : item.size.value;
970
+ applyDeltaInBothDirections(context, newItems, itemIndex, removedSize);
971
+ context.items = newItems;
995
972
  },
996
- unregisterPanel: {
997
- actions: [
998
- "prepare",
999
- "removeItem",
1000
- "onClearLastKnownSize",
1001
- "commit",
1002
- "onResize",
1003
- "onAutosave",
1004
- ],
973
+ notifyCollapseToggle: (event) => {
974
+ isEvent(event, ["collapsePanel", "expandPanel"]);
975
+ const panel = getPanelWithId(context, event.panelId);
976
+ panel.onCollapseChange?.current?.(!panel.collapsed);
1005
977
  },
1006
- registerPanelHandle: { actions: ["assignPanelHandleData"] },
1007
- unregisterPanelHandle: {
1008
- actions: [
1009
- "prepare",
1010
- "removeItem",
1011
- "onClearLastKnownSize",
1012
- "commit",
1013
- "onResize",
1014
- "onAutosave",
1015
- ],
978
+ runCollapseToggle: (event) => {
979
+ isEvent(event, ["collapsePanel", "expandPanel"]);
980
+ const handle = getHandleForPanelId(context, event.panelId);
981
+ // When collapsing a panel it will be in the opposite direction
982
+ // that handle assumes
983
+ const delta = event.type === "collapsePanel"
984
+ ? handle.direction * -1
985
+ : handle.direction;
986
+ const newContext = updateLayout(context, {
987
+ handleId: handle.item.id,
988
+ type: "dragHandle",
989
+ controlled: event.controlled,
990
+ value: dragHandlePayload({ delta, orientation: context.orientation }),
991
+ });
992
+ assign(context, newContext);
1016
993
  },
1017
- setSize: { actions: ["updateSize", "onResize"] },
1018
- setOrientation: {
1019
- actions: ["updateOrientation", "onClearLastKnownSize", "onResize"],
994
+ onAnimationEnd: (output) => {
995
+ invariant(output, "Expected output from animation actor");
996
+ const panel = getPanelWithId(context, output.panelId);
997
+ panel.collapsed = output.action === "collapse";
998
+ if (panel.collapsed) {
999
+ panel.currentValue = panel.collapsedSize;
1000
+ }
1001
+ actions.commit();
1020
1002
  },
1021
- },
1022
- }, {
1023
- guards: {
1024
- shouldNotifyCollapseToggle: ({ context, event }) => {
1003
+ };
1004
+ actions.onAutosave();
1005
+ const guards = {
1006
+ shouldNotifyCollapseToggle: (event) => {
1025
1007
  isEvent(event, ["collapsePanel", "expandPanel"]);
1026
1008
  const panel = getPanelWithId(context, event.panelId);
1027
1009
  return !event.controlled && panel.collapseIsControlled === true;
1028
1010
  },
1029
- shouldCollapseToggle: ({ context, event }) => {
1011
+ shouldCollapseToggle: (event) => {
1030
1012
  isEvent(event, ["collapsePanel", "expandPanel"]);
1031
1013
  const panel = getPanelWithId(context, event.panelId);
1032
1014
  return panel.collapseIsControlled === true;
1033
1015
  },
1034
- cannotExpandPanel: ({ context, event }) => {
1016
+ cannotExpandPanel: (event) => {
1035
1017
  isEvent(event, ["expandPanel"]);
1036
1018
  const delta = getDeltaForEvent(context, event);
1037
1019
  const handle = getHandleForPanelId(context, event.panelId);
@@ -1054,166 +1036,82 @@ export const groupMachine = createMachine({
1054
1036
  !updatedPanel.currentValue.value.eq(updatedPanel.collapsedSize.value);
1055
1037
  return totalSize.gt(getGroupSize(context)) || !didExpand;
1056
1038
  },
1057
- },
1058
- actors: {
1059
- animation: animationActor,
1060
- },
1061
- actions: {
1062
- onDragHandleStart: assign({
1063
- activeDragHandleId: ({ event }) => {
1064
- isEvent(event, ["dragHandleStart"]);
1065
- return event.handleId;
1066
- },
1067
- }),
1068
- clearDragHandle: assign({
1069
- activeDragHandleId: undefined,
1070
- }),
1071
- onAutosave: ({ context, self }) => {
1072
- if (!context.autosaveStrategy || typeof window === "undefined") {
1073
- return;
1074
- }
1075
- const snapshot = self.getPersistedSnapshot();
1076
- snapshot.context.items = clearLastKnownSize(context.items);
1077
- snapshot.context.activeDragHandleId = context.activeDragHandleId;
1078
- snapshot.value = "idle";
1079
- const data = JSON.stringify(snapshot);
1080
- if (context.autosaveStrategy === "localStorage") {
1081
- localStorage.setItem(context.groupId, data);
1082
- }
1083
- else {
1084
- Cookies.set(context.groupId, data, {
1085
- path: "/",
1086
- "max-age": 31536000,
1087
- });
1088
- }
1089
- },
1090
- notifyCollapseToggle: ({ context, event }) => {
1091
- isEvent(event, ["collapsePanel", "expandPanel"]);
1092
- const panel = getPanelWithId(context, event.panelId);
1093
- panel.onCollapseChange?.current?.(!panel.collapsed);
1094
- },
1095
- runCollapseToggle: enqueueActions(({ context, event, enqueue }) => {
1096
- isEvent(event, ["collapsePanel", "expandPanel"]);
1097
- const handle = getHandleForPanelId(context, event.panelId);
1098
- // When collapsing a panel it will be in the opposite direction
1099
- // that handle assumes
1100
- const delta = event.type === "collapsePanel"
1101
- ? handle.direction * -1
1102
- : handle.direction;
1103
- const newContext = updateLayout(context, {
1104
- handleId: handle.item.id,
1105
- type: "dragHandle",
1106
- controlled: event.controlled,
1107
- value: dragHandlePayload({ delta, orientation: context.orientation }),
1108
- });
1109
- enqueue.assign(newContext);
1110
- }),
1111
- onToggleCollapseComplete: assign({
1112
- items: ({ context, event: e }) => {
1113
- const { output } = e;
1114
- invariant(output, "Expected output from animation actor");
1115
- const panel = getPanelWithId(context, output.panelId);
1116
- panel.collapsed = output.action === "collapse";
1117
- if (panel.collapsed) {
1118
- panel.currentValue = panel.collapsedSize;
1119
- }
1120
- return context.items;
1121
- },
1122
- }),
1123
- updateSize: assign({
1124
- size: ({ event }) => {
1125
- isEvent(event, ["setSize"]);
1126
- return event.size;
1127
- },
1128
- }),
1129
- recordActualItemSize: assign({
1130
- items: ({ context, event }) => {
1131
- isEvent(event, ["setActualItemsSize"]);
1132
- const withLastKnownSize = context.items.map((i) => {
1133
- if (!isPanelData(i))
1134
- return i;
1135
- const lastKnownSize = event.childrenSizes[i.id] || i.lastKnownSize;
1136
- return { ...i, lastKnownSize };
1137
- });
1138
- let totalSize = 0;
1139
- for (const item of withLastKnownSize) {
1140
- if (isPanelData(item)) {
1141
- const size = item.lastKnownSize?.[context.orientation === "horizontal" ? "width" : "height"];
1142
- // If any size is 0 don't handle overflow
1143
- if (!size) {
1144
- return withLastKnownSize;
1145
- }
1146
- totalSize += size;
1147
- }
1148
- else {
1149
- totalSize += item.size.value.toNumber();
1150
- }
1151
- }
1152
- if (totalSize > getGroupSize(context)) {
1153
- return handleOverflow({
1154
- ...context,
1155
- items: prepareItems({ ...context, items: withLastKnownSize }),
1156
- }).items;
1157
- }
1158
- return withLastKnownSize;
1159
- },
1160
- }),
1161
- updateOrientation: assign({
1162
- orientation: ({ event }) => {
1163
- isEvent(event, ["setOrientation"]);
1164
- return event.orientation;
1165
- },
1166
- }),
1167
- onClearLastKnownSize: assign({
1168
- items: ({ context }) => clearLastKnownSize(context.items),
1169
- }),
1170
- assignPanelData: assign({
1171
- items: ({ context, event }) => {
1172
- isEvent(event, ["registerPanel"]);
1173
- return addDeDuplicatedItems(context.items, {
1039
+ };
1040
+ function transition(to) {
1041
+ // exit
1042
+ switch (state.current) {
1043
+ case "dragging":
1044
+ actions.commit();
1045
+ context.activeDragHandleId = undefined;
1046
+ break;
1047
+ }
1048
+ // enter
1049
+ switch (to) {
1050
+ case "idle":
1051
+ actions.onAutosave();
1052
+ break;
1053
+ case "dragging":
1054
+ actions.prepare();
1055
+ break;
1056
+ case "togglingCollapse":
1057
+ actions.prepare();
1058
+ actions.clearLastKnownSize();
1059
+ break;
1060
+ }
1061
+ state.current = to;
1062
+ }
1063
+ function send(event) {
1064
+ switch (event.type) {
1065
+ case "lockGroup":
1066
+ locked = true;
1067
+ break;
1068
+ case "unlockGroup":
1069
+ locked = false;
1070
+ break;
1071
+ }
1072
+ if (locked) {
1073
+ return;
1074
+ }
1075
+ switch (event.type) {
1076
+ case "registerPanel":
1077
+ context.items = addDeDuplicatedItems(context.items, {
1174
1078
  type: "panel",
1175
1079
  currentValue: makePixelUnit(-1),
1176
1080
  ...event.data,
1177
1081
  });
1178
- },
1179
- }),
1180
- rebindPanelCallbacks: assign({
1181
- items: ({ context, event }) => {
1182
- isEvent(event, ["rebindPanelCallbacks"]);
1183
- for (const item of context.items) {
1184
- if (isPanelData(item) && item.id === event.data.id) {
1185
- item.onCollapseChange = event.data.onCollapseChange;
1186
- item.onResize = event.data.onResize;
1187
- }
1188
- }
1189
- return context.items;
1190
- },
1191
- }),
1192
- updateConstraints: assign({
1193
- items: ({ context, event }) => {
1194
- isEvent(event, ["updateConstraints"]);
1195
- for (const item of context.items) {
1196
- if (isPanelData(item) && item.id === event.data.id) {
1197
- const panel = event.data;
1198
- item.min = panel.min;
1199
- item.max = panel.max;
1200
- item.default = panel.default;
1201
- item.collapsedSize = panel.collapsedSize;
1202
- item.isStaticAtRest = panel.isStaticAtRest;
1203
- item.collapseAnimation = panel.collapseAnimation;
1204
- item.collapsible = panel.collapsible;
1205
- }
1206
- else if (isPanelHandle(item) && item.id === event.data.id) {
1207
- const handle = event.data;
1208
- item.size = handle.size;
1209
- }
1210
- }
1211
- return context.items;
1212
- },
1213
- }),
1214
- onRegisterDynamicPanel: assign({
1215
- items: ({ context, event }) => {
1216
- isEvent(event, ["registerDynamicPanel"]);
1082
+ break;
1083
+ case "unregisterPanel":
1084
+ actions.prepare();
1085
+ actions.removeItem(event.id);
1086
+ actions.clearLastKnownSize();
1087
+ actions.commit();
1088
+ actions.onResize();
1089
+ actions.onAutosave();
1090
+ break;
1091
+ case "registerPanelHandle": {
1092
+ const unit = typeof event.data.size === "string"
1093
+ ? parseUnit(event.data.size)
1094
+ : event.data.size;
1095
+ context.items = addDeDuplicatedItems(context.items, {
1096
+ type: "handle",
1097
+ ...event.data,
1098
+ size: {
1099
+ type: "pixel",
1100
+ value: new Big(unit.value),
1101
+ },
1102
+ });
1103
+ break;
1104
+ }
1105
+ case "unregisterPanelHandle":
1106
+ actions.prepare();
1107
+ actions.removeItem(event.id);
1108
+ actions.clearLastKnownSize();
1109
+ actions.commit();
1110
+ actions.onResize();
1111
+ actions.onAutosave();
1112
+ break;
1113
+ case "registerDynamicPanel": {
1114
+ actions.prepare();
1217
1115
  let currentValue = makePixelUnit(0);
1218
1116
  if (event.data.collapsible &&
1219
1117
  event.data.collapsed &&
@@ -1242,100 +1140,196 @@ export const groupMachine = createMachine({
1242
1140
  }, new Big(0))
1243
1141
  .minus(getGroupSize(context));
1244
1142
  applyDeltaInBothDirections(newContext, newItems, itemIndex, currentValue.value.add(overflowDueToHandles).neg());
1245
- return newItems;
1246
- },
1247
- }),
1248
- assignPanelHandleData: assign({
1249
- items: ({ context, event }) => {
1250
- isEvent(event, ["registerPanelHandle"]);
1251
- const unit = typeof event.data.size === "string"
1252
- ? parseUnit(event.data.size)
1253
- : event.data.size;
1254
- return addDeDuplicatedItems(context.items, {
1255
- type: "handle",
1256
- ...event.data,
1257
- size: {
1258
- type: "pixel",
1259
- value: new Big(unit.value),
1260
- },
1143
+ context.items = newItems;
1144
+ actions.clearLastKnownSize();
1145
+ actions.commit();
1146
+ actions.onResize();
1147
+ actions.onAutosave();
1148
+ break;
1149
+ }
1150
+ case "rebindPanelCallbacks":
1151
+ for (const item of context.items) {
1152
+ if (isPanelData(item) && item.id === event.data.id) {
1153
+ item.onCollapseChange = event.data.onCollapseChange;
1154
+ item.onResize = event.data.onResize;
1155
+ }
1156
+ }
1157
+ break;
1158
+ case "updateConstraints":
1159
+ actions.prepare();
1160
+ for (const item of context.items) {
1161
+ if (isPanelData(item) && item.id === event.data.id) {
1162
+ const panel = event.data;
1163
+ item.min = panel.min;
1164
+ item.max = panel.max;
1165
+ item.default = panel.default;
1166
+ item.collapsedSize = panel.collapsedSize;
1167
+ item.isStaticAtRest = panel.isStaticAtRest;
1168
+ item.collapseAnimation = panel.collapseAnimation;
1169
+ item.collapsible = panel.collapsible;
1170
+ }
1171
+ else if (isPanelHandle(item) && item.id === event.data.id) {
1172
+ const handle = event.data;
1173
+ item.size = handle.size;
1174
+ }
1175
+ }
1176
+ actions.clearLastKnownSize();
1177
+ actions.commit();
1178
+ actions.onResize();
1179
+ actions.onAutosave();
1180
+ break;
1181
+ case "setActualItemsSize": {
1182
+ const withLastKnownSize = context.items.map((i) => {
1183
+ if (!isPanelData(i))
1184
+ return i;
1185
+ const lastKnownSize = event.childrenSizes[i.id] || i.lastKnownSize;
1186
+ return { ...i, lastKnownSize };
1261
1187
  });
1262
- },
1263
- }),
1264
- removeItem: assign({
1265
- items: ({ context, event }) => {
1266
- isEvent(event, ["unregisterPanel", "unregisterPanelHandle"]);
1267
- const itemIndex = context.items.findIndex((item) => item.id === event.id);
1268
- const item = context.items[itemIndex];
1269
- if (!item) {
1270
- return context.items;
1188
+ let totalSize = 0;
1189
+ let useLastKnownSize = false;
1190
+ for (const item of withLastKnownSize) {
1191
+ if (isPanelData(item)) {
1192
+ const size = item.lastKnownSize?.[context.orientation === "horizontal" ? "width" : "height"];
1193
+ // If any size is 0 don't handle overflow
1194
+ if (!size) {
1195
+ context.items = withLastKnownSize;
1196
+ useLastKnownSize = true;
1197
+ break;
1198
+ }
1199
+ totalSize += size;
1200
+ }
1201
+ else {
1202
+ totalSize += item.size.value.toNumber();
1203
+ }
1271
1204
  }
1272
- const newItems = context.items.filter((i) => i.id !== event.id);
1273
- const removedSize = isPanelData(item)
1274
- ? item.currentValue.value
1275
- : item.size.value;
1276
- applyDeltaInBothDirections(context, newItems, itemIndex, removedSize);
1277
- return newItems;
1278
- },
1279
- }),
1280
- prepare: assign({
1281
- items: ({ context }) => prepareItems(context),
1282
- }),
1283
- onDragHandle: enqueueActions(({ context, event, enqueue }) => {
1284
- isEvent(event, ["dragHandle"]);
1285
- enqueue.assign(updateLayout(context, event));
1286
- }),
1287
- commit: assign({
1288
- dragOvershoot: new Big(0),
1289
- items: ({ context }) => commitLayout(context),
1290
- }),
1291
- onApplyDelta: assign(({ context, event }) => {
1292
- isEvent(event, ["applyDelta"]);
1293
- return updateLayout(context, {
1294
- handleId: event.handleId,
1295
- type: "collapsePanel",
1296
- disregardCollapseBuffer: true,
1297
- value: dragHandlePayload({
1298
- delta: event.delta,
1299
- orientation: context.orientation,
1300
- }),
1301
- });
1302
- }),
1303
- onSetPanelSize: enqueueActions(({ context, event, enqueue }) => {
1304
- isEvent(event, ["setPanelPixelSize"]);
1305
- const panel = getPanelWithId(context, event.panelId);
1306
- const handle = getHandleForPanelId(context, event.panelId);
1307
- const current = panel.currentValue.value;
1308
- const newSize = clampUnit(context, panel, getUnitPixelValue(context, parseUnit(event.size)));
1309
- const isBigger = newSize > current;
1310
- const delta = isBigger
1311
- ? newSize.minus(current)
1312
- : current.minus(newSize);
1313
- enqueue.assign(iterativelyUpdateLayout({
1314
- context,
1315
- direction: (handle.direction * (isBigger ? 1 : -1)),
1316
- handleId: handle.item.id,
1317
- delta,
1318
- }));
1319
- }),
1320
- onResize: ({ context }) => {
1321
- for (const item of context.items) {
1322
- if (isPanelData(item)) {
1323
- const pixel = item.lastKnownSize
1324
- ? new Big(context.orientation === "horizontal"
1325
- ? item.lastKnownSize.width
1326
- : item.lastKnownSize.height)
1327
- : clampUnit(context, item, getUnitPixelValue(context, item.currentValue));
1328
- const groupSize = getGroupSize(context);
1329
- item.onResize?.current?.({
1330
- pixel: pixel.toNumber(),
1331
- percentage: groupSize > 0
1332
- ? pixel.div(getGroupSize(context)).toNumber()
1333
- : -1,
1334
- });
1205
+ if (useLastKnownSize) {
1206
+ context.items = withLastKnownSize;
1207
+ }
1208
+ else if (totalSize > getGroupSize(context)) {
1209
+ context.items = handleOverflow({
1210
+ ...context,
1211
+ items: prepareItems({ ...context, items: withLastKnownSize }),
1212
+ }).items;
1213
+ }
1214
+ else {
1215
+ context.items = withLastKnownSize;
1335
1216
  }
1217
+ actions.onResize();
1218
+ break;
1336
1219
  }
1337
- },
1338
- },
1339
- });
1220
+ case "setSize": {
1221
+ context.size = event.size;
1222
+ actions.onResize();
1223
+ break;
1224
+ }
1225
+ case "setOrientation":
1226
+ context.orientation = event.orientation;
1227
+ actions.clearLastKnownSize();
1228
+ actions.onResize();
1229
+ break;
1230
+ default:
1231
+ break;
1232
+ }
1233
+ if (state.current === "idle") {
1234
+ switch (event.type) {
1235
+ case "dragHandleStart":
1236
+ transition("dragging");
1237
+ context.activeDragHandleId = event.handleId;
1238
+ break;
1239
+ case "setPanelPixelSize": {
1240
+ actions.prepare();
1241
+ actions.clearLastKnownSize();
1242
+ const panel = getPanelWithId(context, event.panelId);
1243
+ const handle = getHandleForPanelId(context, event.panelId);
1244
+ const current = panel.currentValue.value;
1245
+ const newSize = clampUnit(context, panel, getUnitPixelValue(context, parseUnit(event.size)));
1246
+ const isBigger = newSize > current;
1247
+ const delta = isBigger
1248
+ ? newSize.minus(current)
1249
+ : current.minus(newSize);
1250
+ Object.assign(context, iterativelyUpdateLayout({
1251
+ context,
1252
+ direction: (handle.direction * (isBigger ? 1 : -1)),
1253
+ handleId: handle.item.id,
1254
+ delta,
1255
+ }));
1256
+ actions.commit();
1257
+ actions.onResize();
1258
+ actions.onAutosave();
1259
+ break;
1260
+ }
1261
+ case "collapsePanel":
1262
+ if (guards.shouldNotifyCollapseToggle(event)) {
1263
+ actions.notifyCollapseToggle(event);
1264
+ }
1265
+ else {
1266
+ transition("togglingCollapse");
1267
+ abortController.abort();
1268
+ animationActor(context, event, send, abortController).then((output) => {
1269
+ actions.onAnimationEnd(output);
1270
+ transition("idle");
1271
+ });
1272
+ }
1273
+ break;
1274
+ case "expandPanel":
1275
+ if (guards.cannotExpandPanel(event)) {
1276
+ break;
1277
+ }
1278
+ else {
1279
+ if (guards.shouldNotifyCollapseToggle(event)) {
1280
+ actions.notifyCollapseToggle(event);
1281
+ }
1282
+ else {
1283
+ transition("togglingCollapse");
1284
+ abortController.abort();
1285
+ animationActor(context, event, send, abortController).then((output) => {
1286
+ actions.onAnimationEnd(output);
1287
+ transition("idle");
1288
+ });
1289
+ }
1290
+ }
1291
+ break;
1292
+ default:
1293
+ break;
1294
+ }
1295
+ }
1296
+ else if (state.current === "dragging") {
1297
+ switch (event.type) {
1298
+ case "dragHandle":
1299
+ actions.clearLastKnownSize();
1300
+ assign(context, updateLayout(context, event));
1301
+ actions.onResize();
1302
+ break;
1303
+ case "dragHandleEnd":
1304
+ transition("idle");
1305
+ break;
1306
+ case "expandPanel":
1307
+ case "collapsePanel":
1308
+ if (guards.shouldCollapseToggle(event)) {
1309
+ actions.runCollapseToggle(event);
1310
+ }
1311
+ break;
1312
+ }
1313
+ }
1314
+ else if (state.current === "togglingCollapse") {
1315
+ switch (event.type) {
1316
+ case "applyDelta":
1317
+ assign(context, updateLayout(context, {
1318
+ handleId: event.handleId,
1319
+ type: "collapsePanel",
1320
+ disregardCollapseBuffer: true,
1321
+ value: dragHandlePayload({
1322
+ delta: event.delta,
1323
+ orientation: context.orientation,
1324
+ }),
1325
+ }));
1326
+ actions.onResize();
1327
+ break;
1328
+ }
1329
+ }
1330
+ onUpdate?.(context);
1331
+ }
1332
+ return [context, send, state];
1333
+ }
1340
1334
  // #endregion
1341
1335
  //# sourceMappingURL=index.js.map