react-resizable-panels 0.0.63 → 1.0.0-rc.2

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 (74) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/CHANGELOG.md +5 -0
  3. package/dist/declarations/src/Panel.d.ts +19 -34
  4. package/dist/declarations/src/PanelGroup.d.ts +9 -13
  5. package/dist/declarations/src/PanelResizeHandle.d.ts +5 -7
  6. package/dist/declarations/src/index.d.ts +2 -2
  7. package/dist/declarations/src/types.d.ts +0 -7
  8. package/dist/declarations/src/utils/assert.d.ts +1 -0
  9. package/dist/declarations/src/vendor/react.d.ts +2 -2
  10. package/dist/react-resizable-panels.browser.cjs.js +253 -518
  11. package/dist/react-resizable-panels.browser.cjs.mjs +2 -1
  12. package/dist/react-resizable-panels.browser.development.cjs.js +279 -574
  13. package/dist/react-resizable-panels.browser.development.cjs.mjs +2 -1
  14. package/dist/react-resizable-panels.browser.development.esm.js +279 -575
  15. package/dist/react-resizable-panels.browser.esm.js +253 -519
  16. package/dist/react-resizable-panels.cjs.d.ts +88 -1
  17. package/dist/react-resizable-panels.cjs.d.ts.map +1 -1
  18. package/dist/react-resizable-panels.cjs.js +1481 -1983
  19. package/dist/react-resizable-panels.cjs.js.map +1 -1
  20. package/dist/react-resizable-panels.cjs.mjs +2 -1
  21. package/dist/react-resizable-panels.development.cjs.js +281 -576
  22. package/dist/react-resizable-panels.development.cjs.mjs +2 -1
  23. package/dist/react-resizable-panels.development.esm.js +281 -577
  24. package/dist/react-resizable-panels.development.node.cjs.js +267 -502
  25. package/dist/react-resizable-panels.development.node.cjs.mjs +2 -1
  26. package/dist/react-resizable-panels.development.node.esm.js +267 -503
  27. package/dist/react-resizable-panels.esm.js +1476 -1959
  28. package/dist/react-resizable-panels.esm.js.map +1 -1
  29. package/dist/react-resizable-panels.node.cjs.js +239 -444
  30. package/dist/react-resizable-panels.node.cjs.mjs +2 -1
  31. package/dist/react-resizable-panels.node.esm.js +239 -445
  32. package/package.json +1 -1
  33. package/src/Panel.test.tsx +74 -73
  34. package/src/Panel.ts +44 -68
  35. package/src/PanelGroup.test.tsx +43 -42
  36. package/src/PanelGroup.ts +221 -411
  37. package/src/PanelGroupContext.ts +2 -3
  38. package/src/PanelResizeHandle.test.tsx +68 -0
  39. package/src/PanelResizeHandle.ts +31 -22
  40. package/src/hooks/useWindowSplitterBehavior.ts +2 -1
  41. package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +22 -33
  42. package/src/index.ts +4 -3
  43. package/src/types.ts +0 -9
  44. package/src/utils/adjustLayoutByDelta.test.ts +206 -336
  45. package/src/utils/adjustLayoutByDelta.ts +59 -51
  46. package/src/utils/assert.ts +1 -1
  47. package/src/utils/calculateAriaValues.test.ts +6 -11
  48. package/src/utils/calculateAriaValues.ts +7 -29
  49. package/src/utils/calculateDeltaPercentage.ts +8 -15
  50. package/src/utils/calculateDragOffsetPercentage.ts +11 -5
  51. package/src/utils/calculateUnsafeDefaultLayout.test.ts +4 -9
  52. package/src/utils/calculateUnsafeDefaultLayout.ts +13 -18
  53. package/src/utils/callPanelCallbacks.ts +11 -46
  54. package/src/utils/getResizeEventCursorPosition.ts +2 -0
  55. package/src/utils/resizePanel.test.ts +6 -52
  56. package/src/utils/resizePanel.ts +24 -46
  57. package/src/utils/test-utils.ts +6 -7
  58. package/src/utils/validatePanelConstraints.test.ts +12 -65
  59. package/src/utils/validatePanelConstraints.ts +26 -67
  60. package/src/utils/validatePanelGroupLayout.test.ts +27 -142
  61. package/src/utils/validatePanelGroupLayout.ts +17 -13
  62. package/src/vendor/react.ts +2 -0
  63. package/src/utils/computePercentagePanelConstraints.test.ts +0 -98
  64. package/src/utils/computePercentagePanelConstraints.ts +0 -56
  65. package/src/utils/convertPercentageToPixels.test.ts +0 -9
  66. package/src/utils/convertPercentageToPixels.ts +0 -6
  67. package/src/utils/convertPixelConstraintsToPercentages.test.ts +0 -47
  68. package/src/utils/convertPixelConstraintsToPercentages.ts +0 -72
  69. package/src/utils/convertPixelsToPercentage.test.ts +0 -9
  70. package/src/utils/convertPixelsToPercentage.ts +0 -6
  71. package/src/utils/getPercentageSizeFromMixedSizes.test.ts +0 -47
  72. package/src/utils/getPercentageSizeFromMixedSizes.ts +0 -15
  73. package/src/utils/shouldMonitorPixelBasedConstraints.test.ts +0 -23
  74. package/src/utils/shouldMonitorPixelBasedConstraints.ts +0 -13
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-resizable-panels",
3
- "version": "0.0.63",
3
+ "version": "1.0.0-rc.2",
4
4
  "description": "React components for resizable panel groups/layouts",
5
5
  "author": "Brian Vaughn <brian.david.vaughn@gmail.com>",
6
6
  "license": "MIT",
@@ -1,12 +1,8 @@
1
1
  import { Root, createRoot } from "react-dom/client";
2
2
  import { act } from "react-dom/test-utils";
3
- import {
4
- ImperativePanelHandle,
5
- MixedSizes,
6
- Panel,
7
- PanelGroup,
8
- PanelResizeHandle,
9
- } from ".";
3
+ import { ImperativePanelHandle, Panel, PanelGroup, PanelResizeHandle } from ".";
4
+ import { assert } from "./utils/assert";
5
+ import { getPanelElement } from "./utils/dom/getPanelElement";
10
6
  import {
11
7
  mockPanelGroupOffsetWidthAndHeight,
12
8
  verifyExpandedPanelGroupLayout,
@@ -66,7 +62,7 @@ describe("PanelGroup", () => {
66
62
  let leftPanelRef = createRef<ImperativePanelHandle>();
67
63
  let rightPanelRef = createRef<ImperativePanelHandle>();
68
64
 
69
- let mostRecentLayout: MixedSizes[] | null;
65
+ let mostRecentLayout: number[] | null;
70
66
 
71
67
  beforeEach(() => {
72
68
  leftPanelRef = createRef<ImperativePanelHandle>();
@@ -74,67 +70,65 @@ describe("PanelGroup", () => {
74
70
 
75
71
  mostRecentLayout = null;
76
72
 
77
- const onLayout = (layout: MixedSizes[]) => {
73
+ const onLayout = (layout: number[]) => {
78
74
  mostRecentLayout = layout;
79
75
  };
80
76
 
81
77
  act(() => {
82
78
  root.render(
83
79
  <PanelGroup direction="horizontal" onLayout={onLayout}>
84
- <Panel
85
- collapsible
86
- defaultSizePercentage={50}
87
- ref={leftPanelRef}
88
- />
80
+ <Panel collapsible defaultSize={50} ref={leftPanelRef} />
89
81
  <PanelResizeHandle />
90
- <Panel
91
- collapsible
92
- defaultSizePercentage={50}
93
- ref={rightPanelRef}
94
- />
82
+ <Panel collapsible defaultSize={50} ref={rightPanelRef} />
95
83
  </PanelGroup>
96
84
  );
97
85
  });
98
86
  });
99
87
 
100
88
  it("should expand and collapse the first panel in a group", () => {
101
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [50, 50]);
89
+ assert(mostRecentLayout);
90
+
91
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [50, 50]);
102
92
  act(() => {
103
- leftPanelRef.current!.collapse();
93
+ leftPanelRef.current?.collapse();
104
94
  });
105
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [0, 100]);
95
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [0, 100]);
106
96
  act(() => {
107
- leftPanelRef.current!.expand();
97
+ leftPanelRef.current?.expand();
108
98
  });
109
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [50, 50]);
99
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [50, 50]);
110
100
  });
111
101
 
112
102
  it("should expand and collapse the last panel in a group", () => {
113
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [50, 50]);
103
+ assert(mostRecentLayout);
104
+
105
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [50, 50]);
114
106
  act(() => {
115
- rightPanelRef.current!.collapse();
107
+ rightPanelRef.current?.collapse();
116
108
  });
117
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [100, 0]);
109
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [100, 0]);
118
110
  act(() => {
119
- rightPanelRef.current!.expand();
111
+ rightPanelRef.current?.expand();
120
112
  });
121
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [50, 50]);
113
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [50, 50]);
122
114
  });
123
115
 
124
116
  it("should re-expand to the most recent size before collapsing", () => {
125
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [50, 50]);
117
+ assert(mostRecentLayout);
118
+
119
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [50, 50]);
126
120
  act(() => {
127
- leftPanelRef.current!.resize({ sizePercentage: 30 });
121
+ leftPanelRef.current?.resize(30);
128
122
  });
129
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [30, 70]);
123
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [30, 70]);
130
124
  act(() => {
131
- leftPanelRef.current!.collapse();
125
+ leftPanelRef.current?.collapse();
132
126
  });
133
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [0, 100]);
127
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [0, 100]);
134
128
  act(() => {
135
- leftPanelRef.current!.expand();
129
+ leftPanelRef.current?.expand();
136
130
  });
137
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [30, 70]);
131
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [30, 70]);
138
132
  });
139
133
  });
140
134
 
@@ -143,7 +137,7 @@ describe("PanelGroup", () => {
143
137
  let middlePanelRef = createRef<ImperativePanelHandle>();
144
138
  let rightPanelRef = createRef<ImperativePanelHandle>();
145
139
 
146
- let mostRecentLayout: MixedSizes[] | null;
140
+ let mostRecentLayout: number[] | null;
147
141
 
148
142
  beforeEach(() => {
149
143
  leftPanelRef = createRef<ImperativePanelHandle>();
@@ -152,45 +146,51 @@ describe("PanelGroup", () => {
152
146
 
153
147
  mostRecentLayout = null;
154
148
 
155
- const onLayout = (layout: MixedSizes[]) => {
149
+ const onLayout = (layout: number[]) => {
156
150
  mostRecentLayout = layout;
157
151
  };
158
152
 
159
153
  act(() => {
160
154
  root.render(
161
155
  <PanelGroup direction="horizontal" onLayout={onLayout}>
162
- <Panel defaultSizePercentage={20} ref={leftPanelRef} />
156
+ <Panel defaultSize={20} ref={leftPanelRef} />
163
157
  <PanelResizeHandle />
164
- <Panel defaultSizePercentage={60} ref={middlePanelRef} />
158
+ <Panel defaultSize={60} ref={middlePanelRef} />
165
159
  <PanelResizeHandle />
166
- <Panel defaultSizePercentage={20} ref={rightPanelRef} />
160
+ <Panel defaultSize={20} ref={rightPanelRef} />
167
161
  </PanelGroup>
168
162
  );
169
163
  });
170
164
  });
171
165
 
172
166
  it("should resize the first panel in a group", () => {
173
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [20, 60, 20]);
167
+ assert(mostRecentLayout);
168
+
169
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [20, 60, 20]);
174
170
  act(() => {
175
- leftPanelRef.current!.resize({ sizePercentage: 40 });
171
+ leftPanelRef.current?.resize(40);
176
172
  });
177
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [40, 40, 20]);
173
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [40, 40, 20]);
178
174
  });
179
175
 
180
176
  it("should resize the middle panel in a group", () => {
181
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [20, 60, 20]);
177
+ assert(mostRecentLayout);
178
+
179
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [20, 60, 20]);
182
180
  act(() => {
183
- middlePanelRef.current!.resize({ sizePercentage: 40 });
181
+ middlePanelRef.current?.resize(40);
184
182
  });
185
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [20, 40, 40]);
183
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [20, 40, 40]);
186
184
  });
187
185
 
188
186
  it("should resize the last panel in a group", () => {
189
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [20, 60, 20]);
187
+ assert(mostRecentLayout);
188
+
189
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [20, 60, 20]);
190
190
  act(() => {
191
- rightPanelRef.current!.resize({ sizePercentage: 40 });
191
+ rightPanelRef.current?.resize(40);
192
192
  });
193
- verifyExpandedPanelGroupLayout(mostRecentLayout!, [20, 40, 40]);
193
+ verifyExpandedPanelGroupLayout(mostRecentLayout, [20, 40, 40]);
194
194
  });
195
195
  });
196
196
  });
@@ -207,7 +207,7 @@ describe("PanelGroup", () => {
207
207
  act(() => {
208
208
  root.render(
209
209
  <PanelGroup direction="horizontal">
210
- <Panel defaultSizePercentage={-1} />
210
+ <Panel defaultSize={-1} />
211
211
  </PanelGroup>
212
212
  );
213
213
  });
@@ -217,7 +217,7 @@ describe("PanelGroup", () => {
217
217
  act(() => {
218
218
  root.render(
219
219
  <PanelGroup direction="horizontal">
220
- <Panel defaultSizePercentage={101} />
220
+ <Panel defaultSize={101} />
221
221
  </PanelGroup>
222
222
  );
223
223
  });
@@ -235,6 +235,24 @@ describe("PanelGroup", () => {
235
235
  });
236
236
  });
237
237
 
238
+ it("should support ...rest attributes", () => {
239
+ act(() => {
240
+ root.render(
241
+ <PanelGroup direction="horizontal">
242
+ <Panel data-test-name="foo" id="panel" tabIndex={123} title="bar" />
243
+ <PanelResizeHandle />
244
+ <Panel />
245
+ </PanelGroup>
246
+ );
247
+ });
248
+
249
+ const element = getPanelElement("panel");
250
+ assert(element);
251
+ expect(element.tabIndex).toBe(123);
252
+ expect(element.getAttribute("data-test-name")).toBe("foo");
253
+ expect(element.title).toBe("bar");
254
+ });
255
+
238
256
  describe("DEV warnings", () => {
239
257
  it("should warn about server rendered panels with no default size", () => {
240
258
  jest.resetModules();
@@ -254,15 +272,15 @@ describe("PanelGroup", () => {
254
272
  // No warning expected if default sizes provided
255
273
  renderToStaticMarkup(
256
274
  <PanelGroup direction="horizontal">
257
- <Panel defaultSizePercentage={100} />
275
+ <Panel defaultSize={100} />
258
276
  <PanelResizeHandle />
259
- <Panel defaultSizePixels={1_000} />
277
+ <Panel defaultSize={1_000} />
260
278
  </PanelGroup>
261
279
  );
262
280
  });
263
281
 
264
282
  expectWarning(
265
- "Panel defaultSizePercentage or defaultSizePixels prop recommended to avoid layout shift after server rendering"
283
+ "Panel defaultSize prop recommended to avoid layout shift after server rendering"
266
284
  );
267
285
 
268
286
  act(() => {
@@ -274,30 +292,13 @@ describe("PanelGroup", () => {
274
292
  });
275
293
  });
276
294
 
277
- it("should warn if both pixel and percentage units are specified", () => {
278
- // We just spot check this here; validatePanelConstraints() has its own in-depth tests
279
- expectWarning(
280
- "should not specify both percentage and pixel units for: min size"
281
- );
282
-
283
- expectWarning("Pixel based constraints require ResizeObserver");
284
-
285
- act(() => {
286
- root.render(
287
- <PanelGroup direction="horizontal" key="minSize">
288
- <Panel minSizePercentage={100} minSizePixels={1_000} />
289
- </PanelGroup>
290
- );
291
- });
292
- });
293
-
294
295
  it("should warn if invalid sizes are specified declaratively", () => {
295
296
  expectWarning("default size should not be less than 0");
296
297
 
297
298
  act(() => {
298
299
  root.render(
299
300
  <PanelGroup direction="horizontal" key="collapsedSize">
300
- <Panel defaultSizePercentage={-1} />
301
+ <Panel defaultSize={-1} />
301
302
  <PanelResizeHandle />
302
303
  <Panel />
303
304
  </PanelGroup>
package/src/Panel.ts CHANGED
@@ -3,10 +3,10 @@ import { isDevelopment } from "#is-development";
3
3
  import { PanelGroupContext } from "./PanelGroupContext";
4
4
  import useIsomorphicLayoutEffect from "./hooks/useIsomorphicEffect";
5
5
  import useUniqueId from "./hooks/useUniqueId";
6
- import { DataAttributes, MixedSizes } from "./types";
7
6
  import {
8
7
  ElementType,
9
8
  ForwardedRef,
9
+ HTMLAttributes,
10
10
  PropsWithChildren,
11
11
  createElement,
12
12
  forwardRef,
@@ -18,8 +18,8 @@ import {
18
18
  export type PanelOnCollapse = () => void;
19
19
  export type PanelOnExpand = () => void;
20
20
  export type PanelOnResize = (
21
- mixedSizes: MixedSizes,
22
- prevMixedSizes: MixedSizes | undefined
21
+ size: number,
22
+ prevSize: number | undefined
23
23
  ) => void;
24
24
 
25
25
  export type PanelCallbacks = {
@@ -29,15 +29,11 @@ export type PanelCallbacks = {
29
29
  };
30
30
 
31
31
  export type PanelConstraints = {
32
- collapsedSizePercentage?: number | undefined;
33
- collapsedSizePixels?: number | undefined;
32
+ collapsedSize?: number | undefined;
34
33
  collapsible?: boolean | undefined;
35
- defaultSizePercentage?: number | undefined;
36
- defaultSizePixels?: number | undefined;
37
- maxSizePercentage?: number | undefined;
38
- maxSizePixels?: number | undefined;
39
- minSizePercentage?: number | undefined;
40
- minSizePixels?: number | undefined;
34
+ defaultSize?: number | undefined;
35
+ maxSize?: number | undefined;
36
+ minSize?: number | undefined;
41
37
  };
42
38
 
43
39
  export type PanelData = {
@@ -52,54 +48,46 @@ export type ImperativePanelHandle = {
52
48
  collapse: () => void;
53
49
  expand: () => void;
54
50
  getId(): string;
55
- getSize(): MixedSizes;
51
+ getSize(): number;
56
52
  isCollapsed: () => boolean;
57
53
  isExpanded: () => boolean;
58
- resize: (size: Partial<MixedSizes>) => void;
54
+ resize: (size: number) => void;
59
55
  };
60
56
 
61
- export type PanelProps = PropsWithChildren<{
62
- className?: string;
63
- collapsedSizePercentage?: number | undefined;
64
- collapsedSizePixels?: number | undefined;
65
- collapsible?: boolean | undefined;
66
- dataAttributes?: DataAttributes;
67
- defaultSizePercentage?: number | undefined;
68
- defaultSizePixels?: number | undefined;
69
- id?: string;
70
- maxSizePercentage?: number | undefined;
71
- maxSizePixels?: number | undefined;
72
- minSizePercentage?: number | undefined;
73
- minSizePixels?: number | undefined;
74
- onCollapse?: PanelOnCollapse;
75
- onExpand?: PanelOnExpand;
76
- onResize?: PanelOnResize;
77
- order?: number;
78
- style?: object;
79
- tagName?: ElementType;
80
- }>;
57
+ export type PanelProps = Omit<HTMLAttributes<ElementType>, "id" | "onResize"> &
58
+ PropsWithChildren<{
59
+ className?: string;
60
+ collapsedSize?: number | undefined;
61
+ collapsible?: boolean | undefined;
62
+ defaultSize?: number | undefined;
63
+ id?: string;
64
+ maxSize?: number | undefined;
65
+ minSize?: number | undefined;
66
+ onCollapse?: PanelOnCollapse;
67
+ onExpand?: PanelOnExpand;
68
+ onResize?: PanelOnResize;
69
+ order?: number;
70
+ style?: object;
71
+ tagName?: ElementType;
72
+ }>;
81
73
 
82
74
  export function PanelWithForwardedRef({
83
75
  children,
84
76
  className: classNameFromProps = "",
85
- collapsedSizePercentage,
86
- collapsedSizePixels,
77
+ collapsedSize,
87
78
  collapsible,
88
- dataAttributes,
89
- defaultSizePercentage,
90
- defaultSizePixels,
79
+ defaultSize,
91
80
  forwardedRef,
92
81
  id: idFromProps,
93
- maxSizePercentage,
94
- maxSizePixels,
95
- minSizePercentage,
96
- minSizePixels,
82
+ maxSize,
83
+ minSize,
97
84
  onCollapse,
98
85
  onExpand,
99
86
  onResize,
100
87
  order,
101
88
  style: styleFromProps,
102
89
  tagName: Type = "div",
90
+ ...rest
103
91
  }: PanelProps & {
104
92
  forwardedRef: ForwardedRef<ImperativePanelHandle>;
105
93
  }) {
@@ -131,15 +119,11 @@ export function PanelWithForwardedRef({
131
119
  onResize,
132
120
  },
133
121
  constraints: {
134
- collapsedSizePercentage,
135
- collapsedSizePixels,
122
+ collapsedSize,
136
123
  collapsible,
137
- defaultSizePercentage,
138
- defaultSizePixels,
139
- maxSizePercentage,
140
- maxSizePixels,
141
- minSizePercentage,
142
- minSizePixels,
124
+ defaultSize,
125
+ maxSize,
126
+ minSize,
143
127
  },
144
128
  id: panelId,
145
129
  idIsFromProps: idFromProps !== undefined,
@@ -156,14 +140,10 @@ export function PanelWithForwardedRef({
156
140
  // but effects don't run on the server, so we can't do it there
157
141
  if (isDevelopment) {
158
142
  if (!devWarningsRef.current.didLogMissingDefaultSizeWarning) {
159
- if (
160
- !isBrowser &&
161
- defaultSizePercentage == null &&
162
- defaultSizePixels == null
163
- ) {
143
+ if (!isBrowser && defaultSize == null) {
164
144
  devWarningsRef.current.didLogMissingDefaultSizeWarning = true;
165
145
  console.warn(
166
- `WARNING: Panel defaultSizePercentage or defaultSizePixels prop recommended to avoid layout shift after server rendering`
146
+ `WARNING: Panel defaultSize prop recommended to avoid layout shift after server rendering`
167
147
  );
168
148
  }
169
149
  }
@@ -180,15 +160,11 @@ export function PanelWithForwardedRef({
180
160
  callbacks.onExpand = onExpand;
181
161
  callbacks.onResize = onResize;
182
162
 
183
- constraints.collapsedSizePercentage = collapsedSizePercentage;
184
- constraints.collapsedSizePixels = collapsedSizePixels;
163
+ constraints.collapsedSize = collapsedSize;
185
164
  constraints.collapsible = collapsible;
186
- constraints.defaultSizePercentage = defaultSizePercentage;
187
- constraints.defaultSizePixels = defaultSizePixels;
188
- constraints.maxSizePercentage = maxSizePercentage;
189
- constraints.maxSizePixels = maxSizePixels;
190
- constraints.minSizePercentage = minSizePercentage;
191
- constraints.minSizePixels = minSizePixels;
165
+ constraints.defaultSize = defaultSize;
166
+ constraints.maxSize = maxSize;
167
+ constraints.minSize = minSize;
192
168
  });
193
169
 
194
170
  useIsomorphicLayoutEffect(() => {
@@ -222,8 +198,8 @@ export function PanelWithForwardedRef({
222
198
  isExpanded() {
223
199
  return !isPanelCollapsed(panelDataRef.current);
224
200
  },
225
- resize: (mixedSizes: Partial<MixedSizes>) => {
226
- resizePanel(panelDataRef.current, mixedSizes);
201
+ resize: (size: number) => {
202
+ resizePanel(panelDataRef.current, size);
227
203
  },
228
204
  }),
229
205
  [
@@ -239,6 +215,8 @@ export function PanelWithForwardedRef({
239
215
  const style = getPanelStyle(panelDataRef.current);
240
216
 
241
217
  return createElement(Type, {
218
+ ...rest,
219
+
242
220
  children,
243
221
  className: classNameFromProps,
244
222
  style: {
@@ -246,8 +224,6 @@ export function PanelWithForwardedRef({
246
224
  ...styleFromProps,
247
225
  },
248
226
 
249
- ...dataAttributes,
250
-
251
227
  // CSS selectors
252
228
  "data-panel": "",
253
229
  "data-panel-id": panelId,
@@ -2,11 +2,12 @@ import { Root, createRoot } from "react-dom/client";
2
2
  import { act } from "react-dom/test-utils";
3
3
  import {
4
4
  ImperativePanelGroupHandle,
5
- MixedSizes,
6
5
  Panel,
7
6
  PanelGroup,
8
7
  PanelResizeHandle,
9
8
  } from ".";
9
+ import { assert } from "./utils/assert";
10
+ import { getPanelGroupElement } from "./utils/dom/getPanelGroupElement";
10
11
  import { mockPanelGroupOffsetWidthAndHeight } from "./utils/test-utils";
11
12
  import { createRef } from "./vendor/react";
12
13
 
@@ -67,71 +68,74 @@ describe("PanelGroup", () => {
67
68
  root.render(<PanelGroup direction="horizontal" id="one" ref={ref} />);
68
69
  });
69
70
 
70
- expect(ref.current!.getId()).toBe("one");
71
+ expect(ref.current?.getId()).toBe("one");
71
72
 
72
73
  act(() => {
73
74
  root.render(<PanelGroup direction="horizontal" id="two" ref={ref} />);
74
75
  });
75
76
 
76
- expect(ref.current!.getId()).toBe("two");
77
+ expect(ref.current?.getId()).toBe("two");
77
78
  });
78
79
 
79
80
  it("should get and set layouts", () => {
80
81
  const ref = createRef<ImperativePanelGroupHandle>();
81
82
 
82
- let mostRecentLayout: MixedSizes[] | null = null;
83
+ let mostRecentLayout: number[] | null = null;
83
84
 
84
- const onLayout = (layout: MixedSizes[]) => {
85
+ const onLayout = (layout: number[]) => {
85
86
  mostRecentLayout = layout;
86
87
  };
87
88
 
88
89
  act(() => {
89
90
  root.render(
90
91
  <PanelGroup direction="horizontal" onLayout={onLayout} ref={ref}>
91
- <Panel defaultSizePercentage={50} id="a" />
92
+ <Panel defaultSize={50} id="a" />
92
93
  <PanelResizeHandle />
93
- <Panel defaultSizePercentage={50} id="b" />
94
+ <Panel defaultSize={50} id="b" />
94
95
  </PanelGroup>
95
96
  );
96
97
  });
97
98
 
98
- expect(mostRecentLayout).toEqual([
99
- {
100
- sizePercentage: 50,
101
- sizePixels: 500,
102
- },
103
- {
104
- sizePercentage: 50,
105
- sizePixels: 500,
106
- },
107
- ]);
99
+ expect(mostRecentLayout).toEqual([50, 50]);
108
100
 
109
101
  act(() => {
110
- ref.current!.setLayout([
111
- { sizePercentage: 25 },
112
- { sizePercentage: 75 },
113
- ]);
102
+ ref.current?.setLayout([25, 75]);
114
103
  });
115
104
 
116
- expect(mostRecentLayout).toEqual([
117
- {
118
- sizePercentage: 25,
119
- sizePixels: 250,
120
- },
121
- {
122
- sizePercentage: 75,
123
- sizePixels: 750,
124
- },
125
- ]);
105
+ expect(mostRecentLayout).toEqual([25, 75]);
126
106
  });
127
107
  });
128
108
 
109
+ it("should support ...rest attributes", () => {
110
+ act(() => {
111
+ root.render(
112
+ <PanelGroup
113
+ data-test-name="foo"
114
+ direction="horizontal"
115
+ id="group"
116
+ tabIndex={123}
117
+ title="bar"
118
+ >
119
+ <Panel />
120
+ <PanelResizeHandle />
121
+ <Panel />
122
+ </PanelGroup>
123
+ );
124
+ });
125
+
126
+ const element = getPanelGroupElement("group");
127
+ assert(element);
128
+ expect(element.tabIndex).toBe(123);
129
+ expect(element.getAttribute("data-test-name")).toBe("foo");
130
+ expect(element.title).toBe("bar");
131
+ });
132
+
129
133
  describe("DEV warnings", () => {
130
134
  it("should warn about unstable layouts without id and order props", () => {
131
135
  act(() => {
132
136
  root.render(
133
137
  <PanelGroup direction="horizontal">
134
- <Panel defaultSizePercentage={100} id="a" />
138
+ <Panel defaultSize={100} id="a" />
135
139
  </PanelGroup>
136
140
  );
137
141
  });
@@ -143,9 +147,9 @@ describe("PanelGroup", () => {
143
147
  act(() => {
144
148
  root.render(
145
149
  <PanelGroup direction="horizontal">
146
- <Panel defaultSizePercentage={50} id="a" />
150
+ <Panel defaultSize={50} id="a" />
147
151
  <PanelResizeHandle />
148
- <Panel defaultSizePercentage={50} id="b" />
152
+ <Panel defaultSize={50} id="b" />
149
153
  </PanelGroup>
150
154
  );
151
155
  });
@@ -172,9 +176,9 @@ describe("PanelGroup", () => {
172
176
  act(() => {
173
177
  root.render(
174
178
  <PanelGroup direction="horizontal" id="group-without-handle">
175
- <Panel defaultSizePercentage={60} />
179
+ <Panel defaultSize={60} />
176
180
  <PanelResizeHandle />
177
- <Panel defaultSizePercentage={80} />
181
+ <Panel defaultSize={80} />
178
182
  </PanelGroup>
179
183
  );
180
184
  });
@@ -190,9 +194,9 @@ describe("PanelGroup", () => {
190
194
  id="group-without-handle"
191
195
  ref={ref}
192
196
  >
193
- <Panel defaultSizePercentage={30} />
197
+ <Panel defaultSize={30} />
194
198
  <PanelResizeHandle />
195
- <Panel defaultSizePercentage={70} />
199
+ <Panel defaultSize={70} />
196
200
  </PanelGroup>
197
201
  );
198
202
  });
@@ -200,10 +204,7 @@ describe("PanelGroup", () => {
200
204
  expectWarning("Invalid layout total size: 60%, 80%");
201
205
 
202
206
  act(() => {
203
- ref.current!.setLayout([
204
- { sizePercentage: 60 },
205
- { sizePercentage: 80 },
206
- ]);
207
+ ref.current?.setLayout([60, 80]);
207
208
  });
208
209
  });
209
210
  });