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