react-resizable-panels 0.0.55 → 0.0.56

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 (93) hide show
  1. package/.eslintrc.cjs +26 -0
  2. package/CHANGELOG.md +234 -90
  3. package/README.md +55 -49
  4. package/dist/declarations/src/Panel.d.ts +75 -20
  5. package/dist/declarations/src/PanelGroup.d.ts +29 -25
  6. package/dist/declarations/src/PanelResizeHandle.d.ts +1 -1
  7. package/dist/declarations/src/index.d.ts +5 -6
  8. package/dist/declarations/src/types.d.ts +3 -26
  9. package/dist/declarations/src/vendor/react.d.ts +4 -4
  10. package/dist/react-resizable-panels.browser.cjs.js +1241 -1035
  11. package/dist/react-resizable-panels.browser.cjs.mjs +1 -2
  12. package/dist/react-resizable-panels.browser.development.cjs.js +1367 -1081
  13. package/dist/react-resizable-panels.browser.development.cjs.mjs +1 -2
  14. package/dist/react-resizable-panels.browser.development.esm.js +1368 -1081
  15. package/dist/react-resizable-panels.browser.esm.js +1242 -1035
  16. package/dist/react-resizable-panels.cjs.js +1241 -1035
  17. package/dist/react-resizable-panels.cjs.js.map +1 -1
  18. package/dist/react-resizable-panels.cjs.mjs +1 -2
  19. package/dist/react-resizable-panels.development.cjs.js +1370 -1084
  20. package/dist/react-resizable-panels.development.cjs.mjs +1 -2
  21. package/dist/react-resizable-panels.development.esm.js +1371 -1084
  22. package/dist/react-resizable-panels.development.node.cjs.js +1151 -940
  23. package/dist/react-resizable-panels.development.node.cjs.mjs +1 -2
  24. package/dist/react-resizable-panels.development.node.esm.js +1152 -940
  25. package/dist/react-resizable-panels.esm.js +1242 -1035
  26. package/dist/react-resizable-panels.esm.js.map +1 -1
  27. package/dist/react-resizable-panels.node.cjs.js +1049 -912
  28. package/dist/react-resizable-panels.node.cjs.mjs +1 -2
  29. package/dist/react-resizable-panels.node.esm.js +1050 -912
  30. package/jest.config.js +10 -0
  31. package/package.json +3 -1
  32. package/src/Panel.test.tsx +308 -0
  33. package/src/Panel.ts +175 -123
  34. package/src/PanelGroup.test.tsx +210 -0
  35. package/src/PanelGroup.ts +730 -669
  36. package/src/PanelGroupContext.ts +33 -0
  37. package/src/PanelResizeHandle.ts +13 -8
  38. package/src/hooks/useUniqueId.ts +1 -1
  39. package/src/hooks/useWindowSplitterBehavior.ts +9 -164
  40. package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +185 -0
  41. package/src/index.ts +19 -14
  42. package/src/types.ts +3 -30
  43. package/src/utils/adjustLayoutByDelta.test.ts +1808 -0
  44. package/src/utils/adjustLayoutByDelta.ts +211 -0
  45. package/src/utils/calculateAriaValues.test.ts +111 -0
  46. package/src/utils/calculateAriaValues.ts +67 -0
  47. package/src/utils/calculateDeltaPercentage.ts +68 -0
  48. package/src/utils/calculateDragOffsetPercentage.ts +30 -0
  49. package/src/utils/calculateUnsafeDefaultLayout.test.ts +92 -0
  50. package/src/utils/calculateUnsafeDefaultLayout.ts +55 -0
  51. package/src/utils/callPanelCallbacks.ts +81 -0
  52. package/src/utils/compareLayouts.test.ts +9 -0
  53. package/src/utils/compareLayouts.ts +12 -0
  54. package/src/utils/computePanelFlexBoxStyle.ts +44 -0
  55. package/src/utils/computePercentagePanelConstraints.test.ts +71 -0
  56. package/src/utils/computePercentagePanelConstraints.ts +56 -0
  57. package/src/utils/convertPercentageToPixels.test.ts +9 -0
  58. package/src/utils/convertPercentageToPixels.ts +6 -0
  59. package/src/utils/convertPixelConstraintsToPercentages.ts +55 -0
  60. package/src/utils/convertPixelsToPercentage.test.ts +9 -0
  61. package/src/utils/convertPixelsToPercentage.ts +6 -0
  62. package/src/utils/determinePivotIndices.ts +10 -0
  63. package/src/utils/dom/calculateAvailablePanelSizeInPixels.ts +29 -0
  64. package/src/utils/dom/getAvailableGroupSizePixels.ts +29 -0
  65. package/src/utils/dom/getPanelElement.ts +7 -0
  66. package/src/utils/dom/getPanelGroupElement.ts +7 -0
  67. package/src/utils/dom/getResizeHandleElement.ts +9 -0
  68. package/src/utils/dom/getResizeHandleElementIndex.ts +12 -0
  69. package/src/utils/dom/getResizeHandleElementsForGroup.ts +9 -0
  70. package/src/utils/dom/getResizeHandlePanelIds.ts +18 -0
  71. package/src/utils/events.ts +13 -0
  72. package/src/utils/getPercentageSizeFromMixedSizes.test.ts +47 -0
  73. package/src/utils/getPercentageSizeFromMixedSizes.ts +15 -0
  74. package/src/utils/getResizeEventCursorPosition.ts +19 -0
  75. package/src/utils/initializeDefaultStorage.ts +26 -0
  76. package/src/utils/numbers/fuzzyCompareNumbers.test.ts +16 -0
  77. package/src/utils/numbers/fuzzyCompareNumbers.ts +17 -0
  78. package/src/utils/numbers/fuzzyNumbersEqual.ts +9 -0
  79. package/src/utils/resizePanel.ts +41 -0
  80. package/src/utils/serialization.ts +9 -4
  81. package/src/utils/shouldMonitorPixelBasedConstraints.test.ts +23 -0
  82. package/src/utils/shouldMonitorPixelBasedConstraints.ts +13 -0
  83. package/src/utils/test-utils.ts +136 -0
  84. package/src/utils/validatePanelConstraints.test.ts +151 -0
  85. package/src/utils/validatePanelConstraints.ts +103 -0
  86. package/src/utils/validatePanelGroupLayout.test.ts +233 -0
  87. package/src/utils/validatePanelGroupLayout.ts +88 -0
  88. package/src/vendor/react.ts +4 -0
  89. package/.eslintrc.json +0 -22
  90. package/dist/declarations/src/utils/group.d.ts +0 -29
  91. package/src/PanelContexts.ts +0 -22
  92. package/src/utils/coordinates.ts +0 -149
  93. package/src/utils/group.ts +0 -614
@@ -0,0 +1,33 @@
1
+ import { PanelData } from "./Panel";
2
+ import { MixedSizes } from "./types";
3
+ import { CSSProperties, createContext } from "./vendor/react";
4
+
5
+ export type ResizeEvent = KeyboardEvent | MouseEvent | TouchEvent;
6
+ export type ResizeHandler = (event: ResizeEvent) => void;
7
+
8
+ export type DragState = {
9
+ dragHandleId: string;
10
+ dragHandleRect: DOMRect;
11
+ initialCursorPosition: number;
12
+ initialLayout: number[];
13
+ };
14
+
15
+ export const PanelGroupContext = createContext<{
16
+ collapsePanel: (panelData: PanelData) => void;
17
+ direction: "horizontal" | "vertical";
18
+ dragState: DragState | null;
19
+ expandPanel: (panelData: PanelData) => void;
20
+ getPanelSize: (panelData: PanelData) => MixedSizes;
21
+ getPanelStyle: (panelData: PanelData) => CSSProperties;
22
+ groupId: string;
23
+ isPanelCollapsed: (panelData: PanelData) => boolean;
24
+ isPanelExpanded: (panelData: PanelData) => boolean;
25
+ registerPanel: (panelData: PanelData) => void;
26
+ registerResizeHandle: (dragHandleId: string) => ResizeHandler;
27
+ resizePanel: (panelData: PanelData, mixedSizes: Partial<MixedSizes>) => void;
28
+ startDragging: (dragHandleId: string, event: ResizeEvent) => void;
29
+ stopDragging: () => void;
30
+ unregisterPanel: (panelData: PanelData) => void;
31
+ } | null>(null);
32
+
33
+ PanelGroupContext.displayName = "PanelGroupContext";
@@ -1,3 +1,4 @@
1
+ import useUniqueId from "./hooks/useUniqueId";
1
2
  import {
2
3
  createElement,
3
4
  CSSProperties,
@@ -11,17 +12,17 @@ import {
11
12
  useRef,
12
13
  useState,
13
14
  } from "./vendor/react";
14
- import useUniqueId from "./hooks/useUniqueId";
15
15
 
16
16
  import { useWindowSplitterResizeHandlerBehavior } from "./hooks/useWindowSplitterBehavior";
17
- import { PanelGroupContext } from "./PanelContexts";
18
- import type {
19
- ResizeHandler,
17
+ import {
18
+ PanelGroupContext,
20
19
  ResizeEvent,
21
- PanelResizeHandleOnDragging,
22
- } from "./types";
20
+ ResizeHandler,
21
+ } from "./PanelGroupContext";
23
22
  import { getCursorStyle } from "./utils/cursor";
24
23
 
24
+ export type PanelResizeHandleOnDragging = (isDragging: boolean) => void;
25
+
25
26
  export type PanelResizeHandleProps = {
26
27
  children?: ReactNode;
27
28
  className?: string;
@@ -59,8 +60,8 @@ export function PanelResizeHandle({
59
60
  }
60
61
 
61
62
  const {
62
- activeHandleId,
63
63
  direction,
64
+ dragState,
64
65
  groupId,
65
66
  registerResizeHandle,
66
67
  startDragging,
@@ -68,7 +69,7 @@ export function PanelResizeHandle({
68
69
  } = panelGroupContext;
69
70
 
70
71
  const resizeHandleId = useUniqueId(idFromProps);
71
- const isDragging = activeHandleId === resizeHandleId;
72
+ const isDragging = dragState?.dragHandleId === resizeHandleId;
72
73
 
73
74
  const [isFocused, setIsFocused] = useState(false);
74
75
 
@@ -150,6 +151,10 @@ export function PanelResizeHandle({
150
151
  return createElement(Type, {
151
152
  children,
152
153
  className: classNameFromProps,
154
+
155
+ // CSS selectors
156
+ "data-resize-handle": "",
157
+
153
158
  "data-resize-handle-active": isDragging
154
159
  ? "pointer"
155
160
  : isFocused
@@ -15,5 +15,5 @@ export default function useUniqueId(
15
15
  idRef.current = "" + counter++;
16
16
  }
17
17
 
18
- return idRef.current;
18
+ return idFromParams ?? idRef.current;
19
19
  }
@@ -1,169 +1,12 @@
1
- import { RefObject, useEffect } from "../vendor/react";
2
- import { PRECISION } from "../constants";
3
-
4
- import { CommittedValues, PanelDataMap } from "../PanelGroup";
5
1
  import { ResizeHandler } from "../types";
6
- import {
7
- adjustByDelta,
8
- getPanel,
9
- getPanelGroup,
10
- getResizeHandle,
11
- getResizeHandleIndex,
12
- getResizeHandlePanelIds,
13
- getResizeHandles,
14
- getResizeHandlesForGroup,
15
- getFlexGrow,
16
- panelsMapToSortedArray,
17
- } from "../utils/group";
18
2
  import { assert } from "../utils/assert";
3
+ import { getResizeHandleElement } from "../utils/dom/getResizeHandleElement";
4
+ import { getResizeHandleElementIndex } from "../utils/dom/getResizeHandleElementIndex";
5
+ import { getResizeHandleElementsForGroup } from "../utils/dom/getResizeHandleElementsForGroup";
6
+ import { useEffect } from "../vendor/react";
19
7
 
20
8
  // https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/
21
9
 
22
- export function useWindowSplitterPanelGroupBehavior({
23
- committedValuesRef,
24
- groupId,
25
- panels,
26
- setSizes,
27
- sizes,
28
- panelSizeBeforeCollapse,
29
- }: {
30
- committedValuesRef: RefObject<CommittedValues>;
31
- groupId: string;
32
- panels: PanelDataMap;
33
- setSizes: (sizes: number[]) => void;
34
- sizes: number[];
35
- panelSizeBeforeCollapse: RefObject<Map<string, number>>;
36
- }): void {
37
- useEffect(() => {
38
- const { direction, panels } = committedValuesRef.current!;
39
-
40
- const groupElement = getPanelGroup(groupId);
41
- assert(groupElement != null, `No group found for id "${groupId}"`);
42
-
43
- const { height, width } = groupElement.getBoundingClientRect();
44
-
45
- const handles = getResizeHandlesForGroup(groupId);
46
- const cleanupFunctions = handles.map((handle) => {
47
- const handleId = handle.getAttribute("data-panel-resize-handle-id")!;
48
- const panelsArray = panelsMapToSortedArray(panels);
49
-
50
- const [idBefore, idAfter] = getResizeHandlePanelIds(
51
- groupId,
52
- handleId,
53
- panelsArray
54
- );
55
- if (idBefore == null || idAfter == null) {
56
- return () => {};
57
- }
58
-
59
- let currentMinSize = 0;
60
- let currentMaxSize = 100;
61
- let totalMinSize = 0;
62
- let totalMaxSize = 0;
63
-
64
- // A panel's effective min/max sizes also need to account for other panel's sizes.
65
- panelsArray.forEach((panelData) => {
66
- const { id, maxSize, minSize } = panelData.current;
67
- if (id === idBefore) {
68
- currentMinSize = minSize;
69
- currentMaxSize = maxSize != null ? maxSize : 100;
70
- } else {
71
- totalMinSize += minSize;
72
- totalMaxSize += maxSize != null ? maxSize : 100;
73
- }
74
- });
75
-
76
- const ariaValueMax = Math.min(currentMaxSize, 100 - totalMinSize);
77
- const ariaValueMin = Math.max(
78
- currentMinSize,
79
- (panelsArray.length - 1) * 100 - totalMaxSize
80
- );
81
-
82
- const flexGrow = getFlexGrow(panels, idBefore, sizes);
83
-
84
- handle.setAttribute("aria-valuemax", "" + Math.round(ariaValueMax));
85
- handle.setAttribute("aria-valuemin", "" + Math.round(ariaValueMin));
86
- handle.setAttribute("aria-valuenow", "" + Math.round(parseInt(flexGrow)));
87
-
88
- const onKeyDown = (event: KeyboardEvent) => {
89
- if (event.defaultPrevented) {
90
- return;
91
- }
92
-
93
- switch (event.key) {
94
- case "Enter": {
95
- event.preventDefault();
96
-
97
- const index = panelsArray.findIndex(
98
- (panel) => panel.current.id === idBefore
99
- );
100
- if (index >= 0) {
101
- const panelData = panelsArray[index];
102
- const size = sizes[index];
103
- if (size != null) {
104
- let delta = 0;
105
- if (
106
- size.toPrecision(PRECISION) <=
107
- panelData.current.minSize.toPrecision(PRECISION)
108
- ) {
109
- delta = direction === "horizontal" ? width : height;
110
- } else {
111
- delta = -(direction === "horizontal" ? width : height);
112
- }
113
-
114
- const nextSizes = adjustByDelta(
115
- event,
116
- committedValuesRef.current!,
117
- idBefore,
118
- idAfter,
119
- delta,
120
- sizes,
121
- panelSizeBeforeCollapse.current!,
122
- null
123
- );
124
- if (sizes !== nextSizes) {
125
- setSizes(nextSizes);
126
- }
127
- }
128
- }
129
- break;
130
- }
131
- }
132
- };
133
-
134
- handle.addEventListener("keydown", onKeyDown);
135
-
136
- const panelBefore = getPanel(idBefore);
137
- if (panelBefore != null) {
138
- handle.setAttribute("aria-controls", panelBefore.id);
139
- }
140
-
141
- return () => {
142
- handle.removeAttribute("aria-valuemax");
143
- handle.removeAttribute("aria-valuemin");
144
- handle.removeAttribute("aria-valuenow");
145
-
146
- handle.removeEventListener("keydown", onKeyDown);
147
-
148
- if (panelBefore != null) {
149
- handle.removeAttribute("aria-controls");
150
- }
151
- };
152
- });
153
-
154
- return () => {
155
- cleanupFunctions.forEach((cleanupFunction) => cleanupFunction());
156
- };
157
- }, [
158
- committedValuesRef,
159
- groupId,
160
- panels,
161
- panelSizeBeforeCollapse,
162
- setSizes,
163
- sizes,
164
- ]);
165
- }
166
-
167
10
  export function useWindowSplitterResizeHandlerBehavior({
168
11
  disabled,
169
12
  handleId,
@@ -178,7 +21,7 @@ export function useWindowSplitterResizeHandlerBehavior({
178
21
  return;
179
22
  }
180
23
 
181
- const handleElement = getResizeHandle(handleId);
24
+ const handleElement = getResizeHandleElement(handleId);
182
25
  if (handleElement == null) {
183
26
  return;
184
27
  }
@@ -203,8 +46,10 @@ export function useWindowSplitterResizeHandlerBehavior({
203
46
  case "F6": {
204
47
  event.preventDefault();
205
48
 
206
- const handles = getResizeHandles();
207
- const index = getResizeHandleIndex(handleId);
49
+ const groupId = handleElement.getAttribute("data-panel-group-id")!;
50
+
51
+ const handles = getResizeHandleElementsForGroup(groupId);
52
+ const index = getResizeHandleElementIndex(groupId, handleId);
208
53
 
209
54
  assert(index !== null);
210
55
 
@@ -0,0 +1,185 @@
1
+ import { isDevelopment } from "#is-development";
2
+ import { PanelData } from "../Panel";
3
+ import { PRECISION } from "../constants";
4
+ import { Direction } from "../types";
5
+ import { adjustLayoutByDelta } from "../utils/adjustLayoutByDelta";
6
+ import { assert } from "../utils/assert";
7
+ import { calculateAriaValues } from "../utils/calculateAriaValues";
8
+ import { determinePivotIndices } from "../utils/determinePivotIndices";
9
+ import { calculateAvailablePanelSizeInPixels } from "../utils/dom/calculateAvailablePanelSizeInPixels";
10
+ import { getAvailableGroupSizePixels } from "../utils/dom/getAvailableGroupSizePixels";
11
+ import { getPanelGroupElement } from "../utils/dom/getPanelGroupElement";
12
+ import { getResizeHandleElementsForGroup } from "../utils/dom/getResizeHandleElementsForGroup";
13
+ import { getResizeHandlePanelIds } from "../utils/dom/getResizeHandlePanelIds";
14
+ import { getPercentageSizeFromMixedSizes } from "../utils/getPercentageSizeFromMixedSizes";
15
+ import { RefObject, useEffect, useRef } from "../vendor/react";
16
+ import useIsomorphicLayoutEffect from "./useIsomorphicEffect";
17
+
18
+ // https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/
19
+
20
+ export function useWindowSplitterPanelGroupBehavior({
21
+ committedValuesRef,
22
+ groupId,
23
+ layout,
24
+ panelDataArray,
25
+ setLayout,
26
+ }: {
27
+ committedValuesRef: RefObject<{
28
+ direction: Direction;
29
+ panelDataArray: PanelData[];
30
+ }>;
31
+ groupId: string;
32
+ layout: number[];
33
+ panelDataArray: PanelData[];
34
+ setLayout: (sizes: number[]) => void;
35
+ }): void {
36
+ const devWarningsRef = useRef<{
37
+ didWarnAboutMissingResizeHandle: boolean;
38
+ }>({
39
+ didWarnAboutMissingResizeHandle: false,
40
+ });
41
+
42
+ useIsomorphicLayoutEffect(() => {
43
+ const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
44
+ const resizeHandleElements = getResizeHandleElementsForGroup(groupId);
45
+
46
+ for (let index = 0; index < panelDataArray.length - 1; index++) {
47
+ const { valueMax, valueMin, valueNow } = calculateAriaValues({
48
+ groupSizePixels,
49
+ layout,
50
+ panelsArray: panelDataArray,
51
+ pivotIndices: [index, index + 1],
52
+ });
53
+
54
+ const resizeHandleElement = resizeHandleElements[index];
55
+ if (resizeHandleElement == null) {
56
+ if (isDevelopment) {
57
+ const { didWarnAboutMissingResizeHandle } = devWarningsRef.current;
58
+
59
+ if (!didWarnAboutMissingResizeHandle) {
60
+ devWarningsRef.current.didWarnAboutMissingResizeHandle = true;
61
+
62
+ console.warn(
63
+ `WARNING: Missing resize handle for PanelGroup "${groupId}"`
64
+ );
65
+ }
66
+ }
67
+ } else {
68
+ resizeHandleElement.setAttribute(
69
+ "aria-controls",
70
+ panelDataArray[index].id
71
+ );
72
+ resizeHandleElement.setAttribute(
73
+ "aria-valuemax",
74
+ "" + Math.round(valueMax)
75
+ );
76
+ resizeHandleElement.setAttribute(
77
+ "aria-valuemin",
78
+ "" + Math.round(valueMin)
79
+ );
80
+ resizeHandleElement.setAttribute(
81
+ "aria-valuenow",
82
+ "" + Math.round(valueNow)
83
+ );
84
+ }
85
+ }
86
+
87
+ return () => {
88
+ resizeHandleElements.forEach((resizeHandleElement, index) => {
89
+ resizeHandleElement.removeAttribute("aria-controls");
90
+ resizeHandleElement.removeAttribute("aria-valuemax");
91
+ resizeHandleElement.removeAttribute("aria-valuemin");
92
+ resizeHandleElement.removeAttribute("aria-valuenow");
93
+ });
94
+ };
95
+ }, [groupId, layout, panelDataArray]);
96
+
97
+ useEffect(() => {
98
+ const { direction, panelDataArray } = committedValuesRef.current!;
99
+
100
+ const groupElement = getPanelGroupElement(groupId);
101
+ assert(groupElement != null, `No group found for id "${groupId}"`);
102
+
103
+ const { height, width } = groupElement.getBoundingClientRect();
104
+
105
+ const handles = getResizeHandleElementsForGroup(groupId);
106
+ const cleanupFunctions = handles.map((handle) => {
107
+ const handleId = handle.getAttribute("data-panel-resize-handle-id")!;
108
+
109
+ const [idBefore, idAfter] = getResizeHandlePanelIds(
110
+ groupId,
111
+ handleId,
112
+ panelDataArray
113
+ );
114
+ if (idBefore == null || idAfter == null) {
115
+ return () => {};
116
+ }
117
+
118
+ const onKeyDown = (event: KeyboardEvent) => {
119
+ if (event.defaultPrevented) {
120
+ return;
121
+ }
122
+
123
+ switch (event.key) {
124
+ case "Enter": {
125
+ event.preventDefault();
126
+
127
+ const index = panelDataArray.findIndex(
128
+ (panelData) => panelData.id === idBefore
129
+ );
130
+ if (index >= 0) {
131
+ const panelData = panelDataArray[index];
132
+ const size = layout[index];
133
+ if (size != null) {
134
+ const groupSizePixels = getAvailableGroupSizePixels(groupId);
135
+
136
+ const minSize =
137
+ getPercentageSizeFromMixedSizes(
138
+ {
139
+ sizePercentage: panelData.constraints.minSizePercentage,
140
+ sizePixels: panelData.constraints.minSizePixels,
141
+ },
142
+ groupSizePixels
143
+ ) ?? 0;
144
+
145
+ let delta = 0;
146
+ if (
147
+ size.toPrecision(PRECISION) <= minSize.toPrecision(PRECISION)
148
+ ) {
149
+ delta = direction === "horizontal" ? width : height;
150
+ } else {
151
+ delta = -(direction === "horizontal" ? width : height);
152
+ }
153
+
154
+ const nextLayout = adjustLayoutByDelta({
155
+ delta,
156
+ groupSizePixels,
157
+ layout,
158
+ panelConstraints: panelDataArray.map(
159
+ (panelData) => panelData.constraints
160
+ ),
161
+ pivotIndices: determinePivotIndices(groupId, handleId),
162
+ trigger: "keyboard",
163
+ });
164
+ if (layout !== nextLayout) {
165
+ setLayout(nextLayout);
166
+ }
167
+ }
168
+ }
169
+ break;
170
+ }
171
+ }
172
+ };
173
+
174
+ handle.addEventListener("keydown", onKeyDown);
175
+
176
+ return () => {
177
+ handle.removeEventListener("keydown", onKeyDown);
178
+ };
179
+ });
180
+
181
+ return () => {
182
+ cleanupFunctions.forEach((cleanupFunction) => cleanupFunction());
183
+ };
184
+ }, [committedValuesRef, groupId, layout, panelDataArray, setLayout]);
185
+ }
package/src/index.ts CHANGED
@@ -2,38 +2,43 @@ import { Panel } from "./Panel";
2
2
  import { PanelGroup } from "./PanelGroup";
3
3
  import { PanelResizeHandle } from "./PanelResizeHandle";
4
4
 
5
- import type { ImperativePanelHandle, PanelProps } from "./Panel";
6
- import type { ImperativePanelGroupHandle, PanelGroupProps } from "./PanelGroup";
7
- import type { PanelResizeHandleProps } from "./PanelResizeHandle";
8
- import { getAvailableGroupSizePixels } from "./utils/group";
5
+ import type { MixedSizes } from "./types";
6
+
9
7
  import type {
10
- PanelGroupOnLayout,
11
- PanelGroupStorage,
8
+ ImperativePanelHandle,
12
9
  PanelOnCollapse,
10
+ PanelOnExpand,
13
11
  PanelOnResize,
12
+ PanelProps,
13
+ } from "./Panel";
14
+ import type {
15
+ ImperativePanelGroupHandle,
16
+ PanelGroupOnLayout,
17
+ PanelGroupProps,
18
+ PanelGroupStorage,
19
+ } from "./PanelGroup";
20
+ import type {
14
21
  PanelResizeHandleOnDragging,
15
- Units,
16
- } from "./types";
22
+ PanelResizeHandleProps,
23
+ } from "./PanelResizeHandle";
17
24
 
18
25
  export {
19
26
  // TypeScript types
20
27
  ImperativePanelGroupHandle,
21
28
  ImperativePanelHandle,
22
- PanelOnCollapse,
23
- PanelOnResize,
29
+ MixedSizes,
24
30
  PanelGroupOnLayout,
25
31
  PanelGroupProps,
26
32
  PanelGroupStorage,
33
+ PanelOnCollapse,
34
+ PanelOnExpand,
35
+ PanelOnResize,
27
36
  PanelProps,
28
37
  PanelResizeHandleOnDragging,
29
38
  PanelResizeHandleProps,
30
- Units,
31
39
 
32
40
  // React components
33
41
  Panel,
34
42
  PanelGroup,
35
43
  PanelResizeHandle,
36
-
37
- // Utility methods
38
- getAvailableGroupSizePixels,
39
44
  };
package/src/types.ts CHANGED
@@ -1,35 +1,8 @@
1
- import { RefObject } from "./vendor/react";
2
-
3
1
  export type Direction = "horizontal" | "vertical";
4
- export type Units = "percentages" | "pixels";
5
-
6
- export type PanelGroupStorage = {
7
- getItem(name: string): string | null;
8
- setItem(name: string, value: string): void;
9
- };
10
-
11
- export type PanelGroupOnLayout = (sizes: number[]) => void;
12
- export type PanelOnCollapse = (collapsed: boolean) => void;
13
- export type PanelOnResize = (size: number, prevSize: number) => void;
14
- export type PanelResizeHandleOnDragging = (isDragging: boolean) => void;
15
-
16
- export type PanelCallbackRef = RefObject<{
17
- onCollapse: PanelOnCollapse | null;
18
- onResize: PanelOnResize | null;
19
- }>;
20
2
 
21
- export type PanelData = {
22
- current: {
23
- callbacksRef: PanelCallbackRef;
24
- collapsedSize: number;
25
- collapsible: boolean;
26
- defaultSize: number | null;
27
- id: string;
28
- idWasAutoGenerated: boolean;
29
- maxSize: number | null;
30
- minSize: number;
31
- order: number | null;
32
- };
3
+ export type MixedSizes = {
4
+ sizePercentage: number;
5
+ sizePixels: number;
33
6
  };
34
7
 
35
8
  export type ResizeEvent = KeyboardEvent | MouseEvent | TouchEvent;