react-resizable-panels 0.0.54 → 0.0.55

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.
Files changed (34) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/dist/declarations/src/Panel.d.ts +5 -4
  3. package/dist/declarations/src/PanelGroup.d.ts +7 -3
  4. package/dist/declarations/src/index.d.ts +3 -2
  5. package/dist/declarations/src/types.d.ts +2 -1
  6. package/dist/declarations/src/utils/group.d.ts +29 -0
  7. package/dist/react-resizable-panels.browser.cjs.js +385 -108
  8. package/dist/react-resizable-panels.browser.cjs.mjs +2 -1
  9. package/dist/react-resizable-panels.browser.development.cjs.js +417 -108
  10. package/dist/react-resizable-panels.browser.development.cjs.mjs +2 -1
  11. package/dist/react-resizable-panels.browser.development.esm.js +417 -109
  12. package/dist/react-resizable-panels.browser.esm.js +385 -109
  13. package/dist/react-resizable-panels.cjs.js +385 -108
  14. package/dist/react-resizable-panels.cjs.js.map +1 -0
  15. package/dist/react-resizable-panels.cjs.mjs +2 -1
  16. package/dist/react-resizable-panels.development.cjs.js +417 -108
  17. package/dist/react-resizable-panels.development.cjs.mjs +2 -1
  18. package/dist/react-resizable-panels.development.esm.js +417 -109
  19. package/dist/react-resizable-panels.development.node.cjs.js +282 -76
  20. package/dist/react-resizable-panels.development.node.cjs.mjs +2 -1
  21. package/dist/react-resizable-panels.development.node.esm.js +282 -77
  22. package/dist/react-resizable-panels.esm.js +385 -109
  23. package/dist/react-resizable-panels.esm.js.map +1 -0
  24. package/dist/react-resizable-panels.node.cjs.js +254 -76
  25. package/dist/react-resizable-panels.node.cjs.mjs +2 -1
  26. package/dist/react-resizable-panels.node.esm.js +254 -77
  27. package/package.json +1 -1
  28. package/src/Panel.ts +32 -32
  29. package/src/PanelContexts.ts +4 -2
  30. package/src/PanelGroup.ts +221 -111
  31. package/src/hooks/useWindowSplitterBehavior.ts +14 -11
  32. package/src/index.ts +11 -3
  33. package/src/types.ts +2 -1
  34. package/src/utils/group.ts +327 -28
package/src/PanelGroup.ts CHANGED
@@ -25,9 +25,9 @@ import {
25
25
  PanelGroupOnLayout,
26
26
  PanelGroupStorage,
27
27
  ResizeEvent,
28
+ Units,
28
29
  } from "./types";
29
30
  import { areEqual } from "./utils/arrays";
30
- import { assert } from "./utils/assert";
31
31
  import {
32
32
  getDragOffset,
33
33
  getMovement,
@@ -38,13 +38,17 @@ import { resetGlobalCursorStyle, setGlobalCursorStyle } from "./utils/cursor";
38
38
  import debounce from "./utils/debounce";
39
39
  import {
40
40
  adjustByDelta,
41
+ calculateDefaultLayout,
41
42
  callPanelCallbacks,
43
+ getAvailableGroupSizePixels,
42
44
  getBeforeAndAfterIds,
43
45
  getFlexGrow,
44
46
  getPanelGroup,
45
47
  getResizeHandle,
46
48
  getResizeHandlePanelIds,
47
49
  panelsMapToSortedArray,
50
+ validatePanelGroupLayout,
51
+ validatePanelProps,
48
52
  } from "./utils/group";
49
53
  import { loadPanelLayout, savePanelGroupLayout } from "./utils/serialization";
50
54
 
@@ -95,8 +99,10 @@ const defaultStorage: PanelGroupStorage = {
95
99
 
96
100
  export type CommittedValues = {
97
101
  direction: Direction;
102
+ id: string;
98
103
  panels: Map<string, PanelData>;
99
104
  sizes: number[];
105
+ units: Units;
100
106
  };
101
107
 
102
108
  export type PanelDataMap = Map<string, PanelData>;
@@ -114,10 +120,6 @@ export type InitialDragState = {
114
120
  sizes: number[];
115
121
  };
116
122
 
117
- // TODO
118
- // Within an active drag, remember original positions to refine more easily on expand.
119
- // Look at what the Chrome devtools Sources does.
120
-
121
123
  export type PanelGroupProps = {
122
124
  autoSaveId?: string;
123
125
  children?: ReactNode;
@@ -129,11 +131,13 @@ export type PanelGroupProps = {
129
131
  storage?: PanelGroupStorage;
130
132
  style?: CSSProperties;
131
133
  tagName?: ElementType;
134
+ units?: Units;
132
135
  };
133
136
 
134
137
  export type ImperativePanelGroupHandle = {
135
- getLayout: () => number[];
136
- setLayout: (panelSizes: number[]) => void;
138
+ getId: () => string;
139
+ getLayout: (units?: Units) => number[];
140
+ setLayout: (panelSizes: number[], units?: Units) => void;
137
141
  };
138
142
 
139
143
  function PanelGroupWithForwardedRef({
@@ -148,6 +152,7 @@ function PanelGroupWithForwardedRef({
148
152
  storage = defaultStorage,
149
153
  style: styleFromProps = {},
150
154
  tagName: Type = "div",
155
+ units = "percentages",
151
156
  }: PanelGroupProps & {
152
157
  forwardedRef: ForwardedRef<ImperativePanelGroupHandle>;
153
158
  }) {
@@ -164,10 +169,12 @@ function PanelGroupWithForwardedRef({
164
169
  const devWarningsRef = useRef<{
165
170
  didLogDefaultSizeWarning: boolean;
166
171
  didLogIdAndOrderWarning: boolean;
172
+ didLogInvalidLayoutWarning: boolean;
167
173
  prevPanelIds: string[];
168
174
  }>({
169
175
  didLogDefaultSizeWarning: false,
170
176
  didLogIdAndOrderWarning: false,
177
+ didLogInvalidLayoutWarning: false,
171
178
  prevPanelIds: [],
172
179
  });
173
180
 
@@ -192,42 +199,71 @@ function PanelGroupWithForwardedRef({
192
199
  // Store committed values to avoid unnecessarily re-running memoization/effects functions.
193
200
  const committedValuesRef = useRef<CommittedValues>({
194
201
  direction,
202
+ id: groupId,
195
203
  panels,
196
204
  sizes,
205
+ units,
197
206
  });
198
207
 
199
208
  useImperativeHandle(
200
209
  forwardedRef,
201
210
  () => ({
202
- getLayout: () => {
203
- const { sizes } = committedValuesRef.current;
204
- return sizes;
211
+ getId: () => groupId,
212
+ getLayout: (unitsFromParams?: Units) => {
213
+ const { sizes, units: unitsFromProps } = committedValuesRef.current;
214
+
215
+ const units = unitsFromParams ?? unitsFromProps;
216
+ if (units === "pixels") {
217
+ const groupSizePixels = getAvailableGroupSizePixels(groupId);
218
+ return sizes.map((size) => (size / 100) * groupSizePixels);
219
+ } else {
220
+ return sizes;
221
+ }
205
222
  },
206
- setLayout: (sizes: number[]) => {
207
- const total = sizes.reduce(
208
- (accumulated, current) => accumulated + current,
209
- 0
210
- );
223
+ setLayout: (sizes: number[], unitsFromParams?: Units) => {
224
+ const {
225
+ id: groupId,
226
+ panels,
227
+ sizes: prevSizes,
228
+ units,
229
+ } = committedValuesRef.current;
211
230
 
212
- assert(total === 100, "Panel sizes must add up to 100%");
231
+ if ((unitsFromParams || units) === "pixels") {
232
+ const groupSizePixels = getAvailableGroupSizePixels(groupId);
233
+ sizes = sizes.map((size) => (size / groupSizePixels) * 100);
234
+ }
213
235
 
214
- const { panels } = committedValuesRef.current;
215
236
  const panelIdToLastNotifiedSizeMap =
216
237
  panelIdToLastNotifiedSizeMapRef.current;
217
238
  const panelsArray = panelsMapToSortedArray(panels);
218
239
 
219
- setSizes(sizes);
240
+ const nextSizes = validatePanelGroupLayout({
241
+ groupId,
242
+ panels,
243
+ nextSizes: sizes,
244
+ prevSizes,
245
+ units,
246
+ });
247
+ if (!areEqual(prevSizes, nextSizes)) {
248
+ setSizes(nextSizes);
220
249
 
221
- callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap);
250
+ callPanelCallbacks(
251
+ panelsArray,
252
+ nextSizes,
253
+ panelIdToLastNotifiedSizeMap
254
+ );
255
+ }
222
256
  },
223
257
  }),
224
- []
258
+ [groupId]
225
259
  );
226
260
 
227
261
  useIsomorphicLayoutEffect(() => {
228
262
  committedValuesRef.current.direction = direction;
263
+ committedValuesRef.current.id = groupId;
229
264
  committedValuesRef.current.panels = panels;
230
265
  committedValuesRef.current.sizes = sizes;
266
+ committedValuesRef.current.units = units;
231
267
  });
232
268
 
233
269
  useWindowSplitterPanelGroupBehavior({
@@ -267,7 +303,7 @@ function PanelGroupWithForwardedRef({
267
303
  // Compute the initial sizes based on default weights.
268
304
  // This assumes that panels register during initial mount (no conditional rendering)!
269
305
  useIsomorphicLayoutEffect(() => {
270
- const sizes = committedValuesRef.current.sizes;
306
+ const { id: groupId, sizes, units } = committedValuesRef.current;
271
307
  if (sizes.length === panels.size) {
272
308
  // Only compute (or restore) default sizes once per panel configuration.
273
309
  return;
@@ -282,50 +318,25 @@ function PanelGroupWithForwardedRef({
282
318
  }
283
319
 
284
320
  if (defaultSizes != null) {
285
- setSizes(defaultSizes);
286
- } else {
287
- const panelsArray = panelsMapToSortedArray(panels);
288
-
289
- let panelsWithNullDefaultSize = 0;
290
- let totalDefaultSize = 0;
291
- let totalMinSize = 0;
292
-
293
- // TODO
294
- // Implicit default size calculations below do not account for inferred min/max size values.
295
- // e.g. if Panel A has a maxSize of 40 then Panels A and B can't both have an implicit default size of 50.
296
- // For now, these logic edge cases are left to the user to handle via props.
297
-
298
- panelsArray.forEach((panel) => {
299
- totalMinSize += panel.current.minSize;
300
-
301
- if (panel.current.defaultSize === null) {
302
- panelsWithNullDefaultSize++;
303
- } else {
304
- totalDefaultSize += panel.current.defaultSize;
305
- }
321
+ // Validate saved sizes in case something has changed since last render
322
+ // e.g. for pixel groups, this could be the size of the window
323
+ const validatedSizes = validatePanelGroupLayout({
324
+ groupId,
325
+ panels,
326
+ nextSizes: defaultSizes,
327
+ prevSizes: defaultSizes,
328
+ units,
306
329
  });
307
330
 
308
- if (totalDefaultSize > 100) {
309
- throw new Error(`Default panel sizes cannot exceed 100%`);
310
- } else if (
311
- panelsArray.length > 1 &&
312
- panelsWithNullDefaultSize === 0 &&
313
- totalDefaultSize !== 100
314
- ) {
315
- throw new Error(`Invalid default sizes specified for panels`);
316
- } else if (totalMinSize > 100) {
317
- throw new Error(`Minimum panel sizes cannot exceed 100%`);
318
- }
319
-
320
- setSizes(
321
- panelsArray.map((panel) => {
322
- if (panel.current.defaultSize === null) {
323
- return (100 - totalDefaultSize) / panelsWithNullDefaultSize;
324
- }
331
+ setSizes(validatedSizes);
332
+ } else {
333
+ const sizes = calculateDefaultLayout({
334
+ groupId,
335
+ panels,
336
+ units,
337
+ });
325
338
 
326
- return panel.current.defaultSize;
327
- })
328
- );
339
+ setSizes(sizes);
329
340
  }
330
341
  }, [autoSaveId, panels, storage]);
331
342
 
@@ -374,6 +385,53 @@ function PanelGroupWithForwardedRef({
374
385
  }
375
386
  }, [autoSaveId, panels, sizes, storage]);
376
387
 
388
+ useIsomorphicLayoutEffect(() => {
389
+ // Pixel panel constraints need to be reassessed after a group resize
390
+ // We can avoid the ResizeObserver overhead for relative layouts
391
+ if (units === "pixels") {
392
+ const resizeObserver = new ResizeObserver(() => {
393
+ const { panels, sizes: prevSizes } = committedValuesRef.current;
394
+
395
+ const nextSizes = validatePanelGroupLayout({
396
+ groupId,
397
+ panels,
398
+ nextSizes: prevSizes,
399
+ prevSizes,
400
+ units,
401
+ });
402
+ if (!areEqual(prevSizes, nextSizes)) {
403
+ setSizes(nextSizes);
404
+ }
405
+ });
406
+
407
+ resizeObserver.observe(getPanelGroup(groupId)!);
408
+
409
+ return () => {
410
+ resizeObserver.disconnect();
411
+ };
412
+ }
413
+ }, [groupId, units]);
414
+
415
+ const getPanelSize = useCallback(
416
+ (id: string, unitsFromParams?: Units) => {
417
+ const { panels, units: unitsFromProps } = committedValuesRef.current;
418
+
419
+ const panelsArray = panelsMapToSortedArray(panels);
420
+
421
+ const index = panelsArray.findIndex((panel) => panel.current.id === id);
422
+ const size = sizes[index];
423
+
424
+ const units = unitsFromParams ?? unitsFromProps;
425
+ if (units === "pixels") {
426
+ const groupSizePixels = getAvailableGroupSizePixels(groupId);
427
+ return (size / 100) * groupSizePixels;
428
+ } else {
429
+ return size;
430
+ }
431
+ },
432
+ [groupId, sizes]
433
+ );
434
+
377
435
  const getPanelStyle = useCallback(
378
436
  (id: string, defaultSize: number | null): CSSProperties => {
379
437
  const { panels } = committedValuesRef.current;
@@ -425,6 +483,10 @@ function PanelGroupWithForwardedRef({
425
483
  );
426
484
 
427
485
  const registerPanel = useCallback((id: string, panelRef: PanelData) => {
486
+ const { units } = committedValuesRef.current;
487
+
488
+ validatePanelProps(units, panelRef);
489
+
428
490
  setPanels((prevPanels) => {
429
491
  if (prevPanels.has(id)) {
430
492
  return prevPanels;
@@ -484,9 +546,11 @@ function PanelGroupWithForwardedRef({
484
546
  const size = isHorizontal ? rect.width : rect.height;
485
547
  const delta = (movement / size) * 100;
486
548
 
549
+ // If a validateLayout method has been provided
550
+ // it's important to use it before updating the mouse cursor
487
551
  const nextSizes = adjustByDelta(
488
552
  event,
489
- panels,
553
+ committedValuesRef.current,
490
554
  idBefore,
491
555
  idAfter,
492
556
  delta,
@@ -528,6 +592,7 @@ function PanelGroupWithForwardedRef({
528
592
  const panelIdToLastNotifiedSizeMap =
529
593
  panelIdToLastNotifiedSizeMapRef.current;
530
594
 
595
+ // It's okay to bypass in this case because we already validated above
531
596
  setSizes(nextSizes);
532
597
 
533
598
  // If resize change handlers have been declared, this is the time to call them.
@@ -598,7 +663,7 @@ function PanelGroupWithForwardedRef({
598
663
 
599
664
  const nextSizes = adjustByDelta(
600
665
  null,
601
- panels,
666
+ committedValuesRef.current,
602
667
  idBefore,
603
668
  idAfter,
604
669
  delta,
@@ -659,7 +724,7 @@ function PanelGroupWithForwardedRef({
659
724
 
660
725
  const nextSizes = adjustByDelta(
661
726
  null,
662
- panels,
727
+ committedValuesRef.current,
663
728
  idBefore,
664
729
  idAfter,
665
730
  delta,
@@ -679,63 +744,103 @@ function PanelGroupWithForwardedRef({
679
744
  }
680
745
  }, []);
681
746
 
682
- const resizePanel = useCallback((id: string, nextSize: number) => {
683
- const { panels, sizes: prevSizes } = committedValuesRef.current;
747
+ const resizePanel = useCallback(
748
+ (id: string, nextSize: number, unitsFromParams?: Units) => {
749
+ const {
750
+ id: groupId,
751
+ panels,
752
+ sizes: prevSizes,
753
+ units,
754
+ } = committedValuesRef.current;
755
+
756
+ if ((unitsFromParams || units) === "pixels") {
757
+ const groupSizePixels = getAvailableGroupSizePixels(groupId);
758
+ nextSize = (nextSize / groupSizePixels) * 100;
759
+ }
684
760
 
685
- const panel = panels.get(id);
686
- if (panel == null) {
687
- return;
688
- }
761
+ const panel = panels.get(id);
762
+ if (panel == null) {
763
+ return;
764
+ }
689
765
 
690
- const { collapsedSize, collapsible, maxSize, minSize } = panel.current;
766
+ let { collapsedSize, collapsible, maxSize, minSize } = panel.current;
691
767
 
692
- const panelsArray = panelsMapToSortedArray(panels);
768
+ if (units === "pixels") {
769
+ const groupSizePixels = getAvailableGroupSizePixels(groupId);
770
+ minSize = (minSize / groupSizePixels) * 100;
771
+ if (maxSize != null) {
772
+ maxSize = (maxSize / groupSizePixels) * 100;
773
+ }
774
+ }
693
775
 
694
- const index = panelsArray.indexOf(panel);
695
- if (index < 0) {
696
- return;
697
- }
776
+ const panelsArray = panelsMapToSortedArray(panels);
698
777
 
699
- const currentSize = prevSizes[index];
700
- if (currentSize === nextSize) {
701
- return;
702
- }
778
+ const index = panelsArray.indexOf(panel);
779
+ if (index < 0) {
780
+ return;
781
+ }
703
782
 
704
- if (collapsible && nextSize === collapsedSize) {
705
- // This is a valid resize state.
706
- } else {
707
- nextSize = Math.min(maxSize, Math.max(minSize, nextSize));
708
- }
783
+ const currentSize = prevSizes[index];
784
+ if (currentSize === nextSize) {
785
+ return;
786
+ }
709
787
 
710
- const [idBefore, idAfter] = getBeforeAndAfterIds(id, panelsArray);
711
- if (idBefore == null || idAfter == null) {
712
- return;
713
- }
788
+ if (collapsible && nextSize === collapsedSize) {
789
+ // This is a valid resize state.
790
+ } else {
791
+ const unsafeNextSize = nextSize;
714
792
 
715
- const isLastPanel = index === panelsArray.length - 1;
716
- const delta = isLastPanel ? currentSize - nextSize : nextSize - currentSize;
793
+ nextSize = Math.min(
794
+ maxSize != null ? maxSize : 100,
795
+ Math.max(minSize, nextSize)
796
+ );
717
797
 
718
- const nextSizes = adjustByDelta(
719
- null,
720
- panels,
721
- idBefore,
722
- idAfter,
723
- delta,
724
- prevSizes,
725
- panelSizeBeforeCollapse.current,
726
- null
727
- );
728
- if (prevSizes !== nextSizes) {
729
- const panelIdToLastNotifiedSizeMap =
730
- panelIdToLastNotifiedSizeMapRef.current;
798
+ if (isDevelopment) {
799
+ if (unsafeNextSize !== nextSize) {
800
+ console.error(
801
+ `Invalid size (${unsafeNextSize}) specified for Panel "${panel.current.id}" given the panel's min/max size constraints`
802
+ );
803
+ }
804
+ }
805
+ }
731
806
 
732
- setSizes(nextSizes);
807
+ const [idBefore, idAfter] = getBeforeAndAfterIds(id, panelsArray);
808
+ if (idBefore == null || idAfter == null) {
809
+ return;
810
+ }
733
811
 
734
- // If resize change handlers have been declared, this is the time to call them.
735
- // Trigger user callbacks after updating state, so that user code can override the sizes.
736
- callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
737
- }
738
- }, []);
812
+ const isLastPanel = index === panelsArray.length - 1;
813
+ const delta = isLastPanel
814
+ ? currentSize - nextSize
815
+ : nextSize - currentSize;
816
+
817
+ const nextSizes = adjustByDelta(
818
+ null,
819
+ committedValuesRef.current,
820
+ idBefore,
821
+ idAfter,
822
+ delta,
823
+ prevSizes,
824
+ panelSizeBeforeCollapse.current,
825
+ null
826
+ );
827
+ if (prevSizes !== nextSizes) {
828
+ const panelIdToLastNotifiedSizeMap =
829
+ panelIdToLastNotifiedSizeMapRef.current;
830
+
831
+ setSizes(nextSizes);
832
+
833
+ // If resize change handlers have been declared, this is the time to call them.
834
+ // Trigger user callbacks after updating state, so that user code can override the sizes.
835
+ callPanelCallbacks(
836
+ panelsArray,
837
+ nextSizes,
838
+ panelIdToLastNotifiedSizeMap
839
+ );
840
+ }
841
+ },
842
+ []
843
+ );
739
844
 
740
845
  const context = useMemo(
741
846
  () => ({
@@ -743,6 +848,7 @@ function PanelGroupWithForwardedRef({
743
848
  collapsePanel,
744
849
  direction,
745
850
  expandPanel,
851
+ getPanelSize,
746
852
  getPanelStyle,
747
853
  groupId,
748
854
  registerPanel,
@@ -767,6 +873,7 @@ function PanelGroupWithForwardedRef({
767
873
 
768
874
  initialDragStateRef.current = null;
769
875
  },
876
+ units,
770
877
  unregisterPanel,
771
878
  }),
772
879
  [
@@ -774,11 +881,13 @@ function PanelGroupWithForwardedRef({
774
881
  collapsePanel,
775
882
  direction,
776
883
  expandPanel,
884
+ getPanelSize,
777
885
  getPanelStyle,
778
886
  groupId,
779
887
  registerPanel,
780
888
  registerResizeHandle,
781
889
  resizePanel,
890
+ units,
782
891
  unregisterPanel,
783
892
  ]
784
893
  );
@@ -798,6 +907,7 @@ function PanelGroupWithForwardedRef({
798
907
  "data-panel-group": "",
799
908
  "data-panel-group-direction": direction,
800
909
  "data-panel-group-id": groupId,
910
+ "data-panel-group-units": units,
801
911
  style: { ...style, ...styleFromProps },
802
912
  }),
803
913
  value: context,
@@ -37,7 +37,9 @@ export function useWindowSplitterPanelGroupBehavior({
37
37
  useEffect(() => {
38
38
  const { direction, panels } = committedValuesRef.current!;
39
39
 
40
- const groupElement = getPanelGroup(groupId)!;
40
+ const groupElement = getPanelGroup(groupId);
41
+ assert(groupElement != null, `No group found for id "${groupId}"`);
42
+
41
43
  const { height, width } = groupElement.getBoundingClientRect();
42
44
 
43
45
  const handles = getResizeHandlesForGroup(groupId);
@@ -54,25 +56,26 @@ export function useWindowSplitterPanelGroupBehavior({
54
56
  return () => {};
55
57
  }
56
58
 
57
- let minSize = 0;
58
- let maxSize = 100;
59
+ let currentMinSize = 0;
60
+ let currentMaxSize = 100;
59
61
  let totalMinSize = 0;
60
62
  let totalMaxSize = 0;
61
63
 
62
64
  // A panel's effective min/max sizes also need to account for other panel's sizes.
63
65
  panelsArray.forEach((panelData) => {
64
- if (panelData.current.id === idBefore) {
65
- maxSize = panelData.current.maxSize;
66
- minSize = panelData.current.minSize;
66
+ const { id, maxSize, minSize } = panelData.current;
67
+ if (id === idBefore) {
68
+ currentMinSize = minSize;
69
+ currentMaxSize = maxSize != null ? maxSize : 100;
67
70
  } else {
68
- totalMinSize += panelData.current.minSize;
69
- totalMaxSize += panelData.current.maxSize;
71
+ totalMinSize += minSize;
72
+ totalMaxSize += maxSize != null ? maxSize : 100;
70
73
  }
71
74
  });
72
75
 
73
- const ariaValueMax = Math.min(maxSize, 100 - totalMinSize);
76
+ const ariaValueMax = Math.min(currentMaxSize, 100 - totalMinSize);
74
77
  const ariaValueMin = Math.max(
75
- minSize,
78
+ currentMinSize,
76
79
  (panelsArray.length - 1) * 100 - totalMaxSize
77
80
  );
78
81
 
@@ -110,7 +113,7 @@ export function useWindowSplitterPanelGroupBehavior({
110
113
 
111
114
  const nextSizes = adjustByDelta(
112
115
  event,
113
- panels,
116
+ committedValuesRef.current!,
114
117
  idBefore,
115
118
  idAfter,
116
119
  delta,
package/src/index.ts CHANGED
@@ -5,27 +5,35 @@ import { PanelResizeHandle } from "./PanelResizeHandle";
5
5
  import type { ImperativePanelHandle, PanelProps } from "./Panel";
6
6
  import type { ImperativePanelGroupHandle, PanelGroupProps } from "./PanelGroup";
7
7
  import type { PanelResizeHandleProps } from "./PanelResizeHandle";
8
+ import { getAvailableGroupSizePixels } from "./utils/group";
8
9
  import type {
9
10
  PanelGroupOnLayout,
10
11
  PanelGroupStorage,
11
12
  PanelOnCollapse,
12
13
  PanelOnResize,
13
14
  PanelResizeHandleOnDragging,
15
+ Units,
14
16
  } from "./types";
15
17
 
16
18
  export {
17
19
  // TypeScript types
18
20
  ImperativePanelGroupHandle,
19
21
  ImperativePanelHandle,
20
- Panel,
21
22
  PanelOnCollapse,
22
23
  PanelOnResize,
23
- PanelGroup,
24
24
  PanelGroupOnLayout,
25
25
  PanelGroupProps,
26
26
  PanelGroupStorage,
27
27
  PanelProps,
28
- PanelResizeHandle,
29
28
  PanelResizeHandleOnDragging,
30
29
  PanelResizeHandleProps,
30
+ Units,
31
+
32
+ // React components
33
+ Panel,
34
+ PanelGroup,
35
+ PanelResizeHandle,
36
+
37
+ // Utility methods
38
+ getAvailableGroupSizePixels,
31
39
  };
package/src/types.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  import { RefObject } from "./vendor/react";
2
2
 
3
3
  export type Direction = "horizontal" | "vertical";
4
+ export type Units = "percentages" | "pixels";
4
5
 
5
6
  export type PanelGroupStorage = {
6
7
  getItem(name: string): string | null;
@@ -25,7 +26,7 @@ export type PanelData = {
25
26
  defaultSize: number | null;
26
27
  id: string;
27
28
  idWasAutoGenerated: boolean;
28
- maxSize: number;
29
+ maxSize: number | null;
29
30
  minSize: number;
30
31
  order: number | null;
31
32
  };