react-resizable-panels 0.0.62 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/CHANGELOG.md +9 -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 +255 -519
  11. package/dist/react-resizable-panels.browser.cjs.mjs +2 -1
  12. package/dist/react-resizable-panels.browser.development.cjs.js +281 -575
  13. package/dist/react-resizable-panels.browser.development.cjs.mjs +2 -1
  14. package/dist/react-resizable-panels.browser.development.esm.js +281 -576
  15. package/dist/react-resizable-panels.browser.esm.js +255 -520
  16. package/dist/react-resizable-panels.cjs.js +255 -519
  17. package/dist/react-resizable-panels.cjs.js.map +1 -0
  18. package/dist/react-resizable-panels.cjs.mjs +2 -1
  19. package/dist/react-resizable-panels.development.cjs.js +283 -577
  20. package/dist/react-resizable-panels.development.cjs.mjs +2 -1
  21. package/dist/react-resizable-panels.development.esm.js +283 -578
  22. package/dist/react-resizable-panels.development.node.cjs.js +269 -503
  23. package/dist/react-resizable-panels.development.node.cjs.mjs +2 -1
  24. package/dist/react-resizable-panels.development.node.esm.js +269 -504
  25. package/dist/react-resizable-panels.esm.js +255 -520
  26. package/dist/react-resizable-panels.esm.js.map +1 -0
  27. package/dist/react-resizable-panels.node.cjs.js +241 -445
  28. package/dist/react-resizable-panels.node.cjs.mjs +2 -1
  29. package/dist/react-resizable-panels.node.esm.js +241 -446
  30. package/package.json +1 -1
  31. package/src/Panel.test.tsx +74 -73
  32. package/src/Panel.ts +44 -68
  33. package/src/PanelGroup.test.tsx +43 -42
  34. package/src/PanelGroup.ts +189 -403
  35. package/src/PanelGroupContext.ts +2 -3
  36. package/src/PanelResizeHandle.test.tsx +68 -0
  37. package/src/PanelResizeHandle.ts +31 -22
  38. package/src/hooks/useWindowSplitterBehavior.ts +2 -1
  39. package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +22 -33
  40. package/src/index.ts +4 -3
  41. package/src/types.ts +0 -9
  42. package/src/utils/adjustLayoutByDelta.test.ts +206 -336
  43. package/src/utils/adjustLayoutByDelta.ts +59 -51
  44. package/src/utils/assert.ts +1 -1
  45. package/src/utils/calculateAriaValues.test.ts +6 -11
  46. package/src/utils/calculateAriaValues.ts +7 -29
  47. package/src/utils/calculateDeltaPercentage.ts +8 -15
  48. package/src/utils/calculateDragOffsetPercentage.ts +11 -5
  49. package/src/utils/calculateUnsafeDefaultLayout.test.ts +4 -9
  50. package/src/utils/calculateUnsafeDefaultLayout.ts +13 -18
  51. package/src/utils/callPanelCallbacks.ts +11 -46
  52. package/src/utils/computePanelFlexBoxStyle.ts +3 -2
  53. package/src/utils/getResizeEventCursorPosition.ts +2 -0
  54. package/src/utils/resizePanel.test.ts +6 -52
  55. package/src/utils/resizePanel.ts +24 -46
  56. package/src/utils/test-utils.ts +6 -7
  57. package/src/utils/validatePanelConstraints.test.ts +12 -65
  58. package/src/utils/validatePanelConstraints.ts +26 -67
  59. package/src/utils/validatePanelGroupLayout.test.ts +27 -142
  60. package/src/utils/validatePanelGroupLayout.ts +17 -13
  61. package/src/vendor/react.ts +2 -0
  62. package/src/utils/computePercentagePanelConstraints.test.ts +0 -98
  63. package/src/utils/computePercentagePanelConstraints.ts +0 -56
  64. package/src/utils/convertPercentageToPixels.test.ts +0 -9
  65. package/src/utils/convertPercentageToPixels.ts +0 -6
  66. package/src/utils/convertPixelConstraintsToPercentages.test.ts +0 -47
  67. package/src/utils/convertPixelConstraintsToPercentages.ts +0 -72
  68. package/src/utils/convertPixelsToPercentage.test.ts +0 -9
  69. package/src/utils/convertPixelsToPercentage.ts +0 -6
  70. package/src/utils/getPercentageSizeFromMixedSizes.test.ts +0 -47
  71. package/src/utils/getPercentageSizeFromMixedSizes.ts +0 -15
  72. package/src/utils/shouldMonitorPixelBasedConstraints.test.ts +0 -23
  73. package/src/utils/shouldMonitorPixelBasedConstraints.ts +0 -13
@@ -39,24 +39,20 @@ function useUniqueId(idFromParams = null) {
39
39
  function PanelWithForwardedRef({
40
40
  children,
41
41
  className: classNameFromProps = "",
42
- collapsedSizePercentage,
43
- collapsedSizePixels,
42
+ collapsedSize,
44
43
  collapsible,
45
- dataAttributes,
46
- defaultSizePercentage,
47
- defaultSizePixels,
44
+ defaultSize,
48
45
  forwardedRef,
49
46
  id: idFromProps,
50
- maxSizePercentage,
51
- maxSizePixels,
52
- minSizePercentage,
53
- minSizePixels,
47
+ maxSize,
48
+ minSize,
54
49
  onCollapse,
55
50
  onExpand,
56
51
  onResize,
57
52
  order,
58
53
  style: styleFromProps,
59
- tagName: Type = "div"
54
+ tagName: Type = "div",
55
+ ...rest
60
56
  }) {
61
57
  const context = useContext(PanelGroupContext);
62
58
  if (context === null) {
@@ -81,15 +77,11 @@ function PanelWithForwardedRef({
81
77
  onResize
82
78
  },
83
79
  constraints: {
84
- collapsedSizePercentage,
85
- collapsedSizePixels,
80
+ collapsedSize,
86
81
  collapsible,
87
- defaultSizePercentage,
88
- defaultSizePixels,
89
- maxSizePercentage,
90
- maxSizePixels,
91
- minSizePercentage,
92
- minSizePixels
82
+ defaultSize,
83
+ maxSize,
84
+ minSize
93
85
  },
94
86
  id: panelId,
95
87
  idIsFromProps: idFromProps !== undefined,
@@ -103,9 +95,9 @@ function PanelWithForwardedRef({
103
95
  // but effects don't run on the server, so we can't do it there
104
96
  {
105
97
  if (!devWarningsRef.current.didLogMissingDefaultSizeWarning) {
106
- if (defaultSizePercentage == null && defaultSizePixels == null) {
98
+ if (defaultSize == null) {
107
99
  devWarningsRef.current.didLogMissingDefaultSizeWarning = true;
108
- console.warn(`WARNING: Panel defaultSizePercentage or defaultSizePixels prop recommended to avoid layout shift after server rendering`);
100
+ console.warn(`WARNING: Panel defaultSize prop recommended to avoid layout shift after server rendering`);
109
101
  }
110
102
  }
111
103
  }
@@ -128,19 +120,19 @@ function PanelWithForwardedRef({
128
120
  isExpanded() {
129
121
  return !isPanelCollapsed(panelDataRef.current);
130
122
  },
131
- resize: mixedSizes => {
132
- resizePanel(panelDataRef.current, mixedSizes);
123
+ resize: size => {
124
+ resizePanel(panelDataRef.current, size);
133
125
  }
134
126
  }), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
135
127
  const style = getPanelStyle(panelDataRef.current);
136
128
  return createElement(Type, {
129
+ ...rest,
137
130
  children,
138
131
  className: classNameFromProps,
139
132
  style: {
140
133
  ...style,
141
134
  ...styleFromProps
142
135
  },
143
- ...dataAttributes,
144
136
  // CSS selectors
145
137
  "data-panel": "",
146
138
  "data-panel-id": panelId,
@@ -157,81 +149,11 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
157
149
  PanelWithForwardedRef.displayName = "Panel";
158
150
  Panel.displayName = "forwardRef(Panel)";
159
151
 
160
- function convertPixelsToPercentage(pixels, groupSizePixels) {
161
- return pixels / groupSizePixels * 100;
162
- }
163
-
164
- function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels) {
165
- let {
166
- collapsedSizePercentage = 0,
167
- collapsedSizePixels,
168
- defaultSizePercentage,
169
- defaultSizePixels,
170
- maxSizePercentage = 100,
171
- maxSizePixels,
172
- minSizePercentage = 0,
173
- minSizePixels
174
- } = panelConstraints;
175
- const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
176
- if (hasPixelConstraints && groupSizePixels <= 0) {
177
- console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
178
- return {
179
- collapsedSizePercentage: 0,
180
- defaultSizePercentage,
181
- maxSizePercentage: 0,
182
- minSizePercentage: 0
183
- };
184
- }
185
- if (collapsedSizePixels != null) {
186
- collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
187
- }
188
- if (defaultSizePixels != null) {
189
- defaultSizePercentage = convertPixelsToPercentage(defaultSizePixels, groupSizePixels);
190
- }
191
- if (minSizePixels != null) {
192
- minSizePercentage = convertPixelsToPercentage(minSizePixels, groupSizePixels);
193
- }
194
- if (maxSizePixels != null) {
195
- maxSizePercentage = convertPixelsToPercentage(maxSizePixels, groupSizePixels);
196
- }
197
- return {
198
- collapsedSizePercentage,
199
- defaultSizePercentage,
200
- maxSizePercentage,
201
- minSizePercentage
202
- };
203
- }
204
-
205
- function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels) {
206
- // All panel constraints, excluding the current one
207
- let totalMinConstraints = 0;
208
- let totalMaxConstraints = 0;
209
- for (let index = 0; index < panelConstraintsArray.length; index++) {
210
- if (index !== panelIndex) {
211
- const {
212
- collapsible
213
- } = panelConstraintsArray[index];
214
- const {
215
- collapsedSizePercentage,
216
- maxSizePercentage,
217
- minSizePercentage
218
- } = convertPixelConstraintsToPercentages(panelConstraintsArray[index], groupSizePixels);
219
- totalMaxConstraints += maxSizePercentage;
220
- totalMinConstraints += collapsible ? collapsedSizePercentage : minSizePercentage;
221
- }
152
+ function assert(expectedCondition, message = "Assertion failed!") {
153
+ if (!expectedCondition) {
154
+ console.error(message);
155
+ throw Error(message);
222
156
  }
223
- const {
224
- collapsedSizePercentage,
225
- defaultSizePercentage,
226
- maxSizePercentage,
227
- minSizePercentage
228
- } = convertPixelConstraintsToPercentages(panelConstraintsArray[panelIndex], groupSizePixels);
229
- return {
230
- collapsedSizePercentage,
231
- defaultSizePercentage,
232
- maxSizePercentage: panelConstraintsArray.length > 1 ? Math.min(maxSizePercentage, 100 - totalMinConstraints) : maxSizePercentage,
233
- minSizePercentage: panelConstraintsArray.length > 1 ? Math.max(minSizePercentage, 100 - totalMaxConstraints) : minSizePercentage
234
- };
235
157
  }
236
158
 
237
159
  const PRECISION = 10;
@@ -253,56 +175,41 @@ function fuzzyNumbersEqual(actual, expected, fractionDigits) {
253
175
 
254
176
  // Panel size must be in percentages; pixel values should be pre-converted
255
177
  function resizePanel({
256
- groupSizePixels,
257
- panelConstraints,
178
+ panelConstraints: panelConstraintsArray,
258
179
  panelIndex,
259
180
  size
260
181
  }) {
261
- const hasPixelConstraints = panelConstraints.some(({
262
- collapsedSizePixels,
263
- defaultSizePixels,
264
- minSizePixels,
265
- maxSizePixels
266
- }) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
267
- if (hasPixelConstraints && groupSizePixels <= 0) {
268
- console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
269
- return 0;
270
- }
182
+ const panelConstraints = panelConstraintsArray[panelIndex];
183
+ assert(panelConstraints != null);
271
184
  let {
272
- collapsible
273
- } = panelConstraints[panelIndex];
274
- const {
275
- collapsedSizePercentage,
276
- maxSizePercentage,
277
- minSizePercentage
278
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
279
- if (minSizePercentage != null) {
280
- if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
281
- if (collapsible) {
282
- // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
283
- const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
284
- if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
285
- size = collapsedSizePercentage;
286
- } else {
287
- size = minSizePercentage;
288
- }
185
+ collapsedSize = 0,
186
+ collapsible,
187
+ maxSize = 100,
188
+ minSize = 0
189
+ } = panelConstraints;
190
+ if (fuzzyCompareNumbers(size, minSize) < 0) {
191
+ if (collapsible) {
192
+ // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
193
+ const halfwayPoint = (collapsedSize + minSize) / 2;
194
+ if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
195
+ size = collapsedSize;
289
196
  } else {
290
- size = minSizePercentage;
197
+ size = minSize;
291
198
  }
199
+ } else {
200
+ size = minSize;
292
201
  }
293
202
  }
294
- if (maxSizePercentage != null) {
295
- size = Math.min(maxSizePercentage, size);
296
- }
203
+ size = Math.min(maxSize, size);
204
+ size = parseFloat(size.toFixed(PRECISION));
297
205
  return size;
298
206
  }
299
207
 
300
208
  // All units must be in percentages; pixel values should be pre-converted
301
209
  function adjustLayoutByDelta({
302
210
  delta,
303
- groupSizePixels,
304
211
  layout: prevLayout,
305
- panelConstraints,
212
+ panelConstraints: panelConstraintsArray,
306
213
  pivotIndices,
307
214
  trigger
308
215
  }) {
@@ -310,6 +217,9 @@ function adjustLayoutByDelta({
310
217
  return prevLayout;
311
218
  }
312
219
  const nextLayout = [...prevLayout];
220
+ const [firstPivotIndex, secondPivotIndex] = pivotIndices;
221
+ assert(firstPivotIndex != null);
222
+ assert(secondPivotIndex != null);
313
223
  let deltaApplied = 0;
314
224
 
315
225
  //const DEBUG = [];
@@ -333,18 +243,23 @@ function adjustLayoutByDelta({
333
243
  if (trigger === "keyboard") {
334
244
  {
335
245
  // Check if we should expand a collapsed panel
336
- const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
337
- const constraints = panelConstraints[index];
246
+ const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
247
+ const panelConstraints = panelConstraintsArray[index];
248
+ assert(panelConstraints);
249
+
338
250
  //DEBUG.push(`edge case check 1: ${index}`);
339
251
  //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
340
- if (constraints.collapsible) {
252
+ if (panelConstraints.collapsible) {
341
253
  const prevSize = prevLayout[index];
254
+ assert(prevSize != null);
255
+ const panelConstraints = panelConstraintsArray[index];
256
+ assert(panelConstraints);
342
257
  const {
343
- collapsedSizePercentage,
344
- minSizePercentage
345
- } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
346
- if (fuzzyNumbersEqual(prevSize, collapsedSizePercentage)) {
347
- const localDelta = minSizePercentage - prevSize;
258
+ collapsedSize = 0,
259
+ minSize = 0
260
+ } = panelConstraints;
261
+ if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
262
+ const localDelta = minSize - prevSize;
348
263
  //DEBUG.push(` -> expand delta: ${localDelta}`);
349
264
 
350
265
  if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
@@ -357,18 +272,26 @@ function adjustLayoutByDelta({
357
272
 
358
273
  {
359
274
  // Check if we should collapse a panel at its minimum size
360
- const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
361
- const constraints = panelConstraints[index];
275
+ const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
276
+ const panelConstraints = panelConstraintsArray[index];
277
+ assert(panelConstraints);
278
+ const {
279
+ collapsible
280
+ } = panelConstraints;
281
+
362
282
  //DEBUG.push(`edge case check 2: ${index}`);
363
- //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
364
- if (constraints.collapsible) {
283
+ //DEBUG.push(` -> collapsible? ${collapsible}`);
284
+ if (collapsible) {
365
285
  const prevSize = prevLayout[index];
286
+ assert(prevSize != null);
287
+ const panelConstraints = panelConstraintsArray[index];
288
+ assert(panelConstraints);
366
289
  const {
367
- collapsedSizePercentage,
368
- minSizePercentage
369
- } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
370
- if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
371
- const localDelta = prevSize - collapsedSizePercentage;
290
+ collapsedSize = 0,
291
+ minSize = 0
292
+ } = panelConstraints;
293
+ if (fuzzyNumbersEqual(prevSize, minSize)) {
294
+ const localDelta = prevSize - collapsedSize;
372
295
  //DEBUG.push(` -> expand delta: ${localDelta}`);
373
296
 
374
297
  if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
@@ -390,15 +313,15 @@ function adjustLayoutByDelta({
390
313
  // as an expanding panel might change from collapsed to min size.
391
314
 
392
315
  const increment = delta < 0 ? 1 : -1;
393
- let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
316
+ let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
394
317
  let maxAvailableDelta = 0;
395
318
 
396
319
  //DEBUG.push("pre calc...");
397
320
  while (true) {
398
321
  const prevSize = prevLayout[index];
322
+ assert(prevSize != null);
399
323
  const maxSafeSize = resizePanel({
400
- groupSizePixels,
401
- panelConstraints,
324
+ panelConstraints: panelConstraintsArray,
402
325
  panelIndex: index,
403
326
  size: 100
404
327
  });
@@ -407,7 +330,7 @@ function adjustLayoutByDelta({
407
330
 
408
331
  maxAvailableDelta += delta;
409
332
  index += increment;
410
- if (index < 0 || index >= panelConstraints.length) {
333
+ if (index < 0 || index >= panelConstraintsArray.length) {
411
334
  break;
412
335
  }
413
336
  }
@@ -422,15 +345,15 @@ function adjustLayoutByDelta({
422
345
  {
423
346
  // Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
424
347
 
425
- const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
348
+ const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
426
349
  let index = pivotIndex;
427
- while (index >= 0 && index < panelConstraints.length) {
350
+ while (index >= 0 && index < panelConstraintsArray.length) {
428
351
  const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
429
352
  const prevSize = prevLayout[index];
353
+ assert(prevSize != null);
430
354
  const unsafeSize = prevSize - deltaRemaining;
431
355
  const safeSize = resizePanel({
432
- groupSizePixels,
433
- panelConstraints,
356
+ panelConstraints: panelConstraintsArray,
434
357
  panelIndex: index,
435
358
  size: unsafeSize
436
359
  });
@@ -462,11 +385,12 @@ function adjustLayoutByDelta({
462
385
  }
463
386
  {
464
387
  // Now distribute the applied delta to the panels in the other direction
465
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
466
- const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
388
+ const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
389
+ const prevSize = prevLayout[pivotIndex];
390
+ assert(prevSize != null);
391
+ const unsafeSize = prevSize + deltaApplied;
467
392
  const safeSize = resizePanel({
468
- groupSizePixels,
469
- panelConstraints,
393
+ panelConstraints: panelConstraintsArray,
470
394
  panelIndex: pivotIndex,
471
395
  size: unsafeSize
472
396
  });
@@ -477,14 +401,14 @@ function adjustLayoutByDelta({
477
401
  // Edge case where expanding or contracting one panel caused another one to change collapsed state
478
402
  if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
479
403
  let deltaRemaining = unsafeSize - safeSize;
480
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
404
+ const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
481
405
  let index = pivotIndex;
482
- while (index >= 0 && index < panelConstraints.length) {
406
+ while (index >= 0 && index < panelConstraintsArray.length) {
483
407
  const prevSize = nextLayout[index];
408
+ assert(prevSize != null);
484
409
  const unsafeSize = prevSize + deltaRemaining;
485
410
  const safeSize = resizePanel({
486
- groupSizePixels,
487
- panelConstraints,
411
+ panelConstraints: panelConstraintsArray,
488
412
  panelIndex: index,
489
413
  size: unsafeSize
490
414
  });
@@ -508,9 +432,7 @@ function adjustLayoutByDelta({
508
432
  //DEBUG.push("");
509
433
 
510
434
  const totalSize = nextLayout.reduce((total, size) => size + total, 0);
511
- deltaApplied = 100 - totalSize;
512
435
  //DEBUG.push(`total size: ${totalSize}`);
513
- //DEBUG.push(` deltaApplied: ${deltaApplied}`);
514
436
  //console.log(DEBUG.join("\n"));
515
437
 
516
438
  if (!fuzzyNumbersEqual(totalSize, 100)) {
@@ -519,25 +441,6 @@ function adjustLayoutByDelta({
519
441
  return nextLayout;
520
442
  }
521
443
 
522
- function assert(expectedCondition, message = "Assertion failed!") {
523
- if (!expectedCondition) {
524
- console.error(message);
525
- throw Error(message);
526
- }
527
- }
528
-
529
- function getPercentageSizeFromMixedSizes({
530
- sizePercentage,
531
- sizePixels
532
- }, groupSizePixels) {
533
- if (sizePercentage != null) {
534
- return sizePercentage;
535
- } else if (sizePixels != null) {
536
- return convertPixelsToPercentage(sizePixels, groupSizePixels);
537
- }
538
- return undefined;
539
- }
540
-
541
444
  function getResizeHandleElementsForGroup(groupId) {
542
445
  return Array.from(document.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
543
446
  }
@@ -561,42 +464,6 @@ function getPanelGroupElement(id) {
561
464
  return null;
562
465
  }
563
466
 
564
- function calculateAvailablePanelSizeInPixels(groupId) {
565
- const panelGroupElement = getPanelGroupElement(groupId);
566
- if (panelGroupElement == null) {
567
- return NaN;
568
- }
569
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
570
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
571
- if (direction === "horizontal") {
572
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
573
- return accumulated + handle.offsetWidth;
574
- }, 0);
575
- } else {
576
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
577
- return accumulated + handle.offsetHeight;
578
- }, 0);
579
- }
580
- }
581
-
582
- function getAvailableGroupSizePixels(groupId) {
583
- const panelGroupElement = getPanelGroupElement(groupId);
584
- if (panelGroupElement == null) {
585
- return NaN;
586
- }
587
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
588
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
589
- if (direction === "horizontal") {
590
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
591
- return accumulated + handle.offsetWidth;
592
- }, 0);
593
- } else {
594
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
595
- return accumulated + handle.offsetHeight;
596
- }, 0);
597
- }
598
- }
599
-
600
467
  function getResizeHandleElement(id) {
601
468
  const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
602
469
  if (element) {
@@ -629,14 +496,18 @@ function useWindowSplitterPanelGroupBehavior({
629
496
  didWarnAboutMissingResizeHandle: false
630
497
  });
631
498
  useEffect(() => {
499
+ const eagerValues = eagerValuesRef.current;
500
+ assert(eagerValues);
632
501
  const {
633
502
  panelDataArray
634
- } = eagerValuesRef.current;
503
+ } = eagerValues;
635
504
  const groupElement = getPanelGroupElement(groupId);
636
505
  assert(groupElement != null, `No group found for id "${groupId}"`);
637
506
  const handles = getResizeHandleElementsForGroup(groupId);
507
+ assert(handles);
638
508
  const cleanupFunctions = handles.map(handle => {
639
509
  const handleId = handle.getAttribute("data-panel-resize-handle-id");
510
+ assert(handleId);
640
511
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
641
512
  if (idBefore == null || idAfter == null) {
642
513
  return () => {};
@@ -652,21 +523,16 @@ function useWindowSplitterPanelGroupBehavior({
652
523
  const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
653
524
  if (index >= 0) {
654
525
  const panelData = panelDataArray[index];
526
+ assert(panelData);
655
527
  const size = layout[index];
656
- if (size != null && panelData.constraints.collapsible) {
657
- var _getPercentageSizeFro, _getPercentageSizeFro2;
658
- const groupSizePixels = getAvailableGroupSizePixels(groupId);
659
- const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
660
- sizePercentage: panelData.constraints.collapsedSizePercentage,
661
- sizePixels: panelData.constraints.collapsedSizePixels
662
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
663
- const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
664
- sizePercentage: panelData.constraints.minSizePercentage,
665
- sizePixels: panelData.constraints.minSizePixels
666
- }, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
528
+ const {
529
+ collapsedSize = 0,
530
+ collapsible,
531
+ minSize = 0
532
+ } = panelData.constraints;
533
+ if (size != null && collapsible) {
667
534
  const nextLayout = adjustLayoutByDelta({
668
535
  delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
669
- groupSizePixels,
670
536
  layout,
671
537
  panelConstraints: panelDataArray.map(panelData => panelData.constraints),
672
538
  pivotIndices: determinePivotIndices(groupId, handleId),
@@ -720,6 +586,7 @@ function getResizeEventCursorPosition(direction, event) {
720
586
  return isHorizontal ? event.clientX : event.clientY;
721
587
  } else if (isTouchEvent(event)) {
722
588
  const firstTouch = event.touches[0];
589
+ assert(firstTouch);
723
590
  return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
724
591
  } else {
725
592
  throw Error(`Unsupported event type "${event.type}"`);
@@ -729,12 +596,15 @@ function getResizeEventCursorPosition(direction, event) {
729
596
  function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
730
597
  const isHorizontal = direction === "horizontal";
731
598
  const handleElement = getResizeHandleElement(dragHandleId);
599
+ assert(handleElement);
732
600
  const groupId = handleElement.getAttribute("data-panel-group-id");
601
+ assert(groupId);
733
602
  let {
734
603
  initialCursorPosition
735
604
  } = initialDragState;
736
605
  const cursorPosition = getResizeEventCursorPosition(direction, event);
737
606
  const groupElement = getPanelGroupElement(groupId);
607
+ assert(groupElement);
738
608
  const groupRect = groupElement.getBoundingClientRect();
739
609
  const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
740
610
  const offsetPixels = cursorPosition - initialCursorPosition;
@@ -743,19 +613,14 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
743
613
  }
744
614
 
745
615
  // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
746
- function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initialDragState, keyboardResizeByOptions) {
616
+ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
747
617
  if (isKeyDown(event)) {
748
618
  const isHorizontal = direction === "horizontal";
749
- const groupElement = getPanelGroupElement(groupId);
750
- const rect = groupElement.getBoundingClientRect();
751
- const groupSizeInPixels = isHorizontal ? rect.width : rect.height;
752
619
  let delta = 0;
753
620
  if (event.shiftKey) {
754
621
  delta = 100;
755
- } else if (keyboardResizeByOptions.percentage != null) {
756
- delta = keyboardResizeByOptions.percentage;
757
- } else if (keyboardResizeByOptions.pixels != null) {
758
- delta = keyboardResizeByOptions.pixels / groupSizeInPixels;
622
+ } else if (keyboardResizeBy != null) {
623
+ delta = keyboardResizeBy;
759
624
  } else {
760
625
  delta = 10;
761
626
  }
@@ -782,37 +647,43 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
782
647
  }
783
648
  return movement;
784
649
  } else {
650
+ if (initialDragState == null) {
651
+ return 0;
652
+ }
785
653
  return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
786
654
  }
787
655
  }
788
656
 
789
657
  function calculateUnsafeDefaultLayout({
790
- groupSizePixels,
791
658
  panelDataArray
792
659
  }) {
793
660
  const layout = Array(panelDataArray.length);
794
- const panelDataConstraints = panelDataArray.map(panelData => panelData.constraints);
661
+ const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
795
662
  let numPanelsWithSizes = 0;
796
663
  let remainingSize = 100;
797
664
 
798
665
  // Distribute default sizes first
799
666
  for (let index = 0; index < panelDataArray.length; index++) {
667
+ const panelConstraints = panelConstraintsArray[index];
668
+ assert(panelConstraints);
800
669
  const {
801
- defaultSizePercentage
802
- } = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
803
- if (defaultSizePercentage != null) {
670
+ defaultSize
671
+ } = panelConstraints;
672
+ if (defaultSize != null) {
804
673
  numPanelsWithSizes++;
805
- layout[index] = defaultSizePercentage;
806
- remainingSize -= defaultSizePercentage;
674
+ layout[index] = defaultSize;
675
+ remainingSize -= defaultSize;
807
676
  }
808
677
  }
809
678
 
810
679
  // Remaining size should be distributed evenly between panels without default sizes
811
680
  for (let index = 0; index < panelDataArray.length; index++) {
681
+ const panelConstraints = panelConstraintsArray[index];
682
+ assert(panelConstraints);
812
683
  const {
813
- defaultSizePercentage
814
- } = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
815
- if (defaultSizePercentage != null) {
684
+ defaultSize
685
+ } = panelConstraints;
686
+ if (defaultSize != null) {
816
687
  continue;
817
688
  }
818
689
  const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
@@ -824,54 +695,36 @@ function calculateUnsafeDefaultLayout({
824
695
  return layout;
825
696
  }
826
697
 
827
- function convertPercentageToPixels(percentage, groupSizePixels) {
828
- return percentage / 100 * groupSizePixels;
829
- }
830
-
831
698
  // Layout should be pre-converted into percentages
832
- function callPanelCallbacks(groupId, panelsArray, layout, panelIdToLastNotifiedMixedSizesMap) {
833
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
834
- layout.forEach((sizePercentage, index) => {
699
+ function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
700
+ layout.forEach((size, index) => {
835
701
  const panelData = panelsArray[index];
836
- if (!panelData) {
837
- // Handle initial mount (when panels are registered too late to be in the panels array)
838
- // The subsequent render+effects will handle the resize notification
839
- return;
840
- }
702
+ assert(panelData);
841
703
  const {
842
704
  callbacks,
843
705
  constraints,
844
706
  id: panelId
845
707
  } = panelData;
846
708
  const {
709
+ collapsedSize = 0,
847
710
  collapsible
848
711
  } = constraints;
849
- const mixedSizes = {
850
- sizePercentage,
851
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
852
- };
853
- const lastNotifiedMixedSizes = panelIdToLastNotifiedMixedSizesMap[panelId];
854
- if (lastNotifiedMixedSizes == null || mixedSizes.sizePercentage !== lastNotifiedMixedSizes.sizePercentage || mixedSizes.sizePixels !== lastNotifiedMixedSizes.sizePixels) {
855
- panelIdToLastNotifiedMixedSizesMap[panelId] = mixedSizes;
712
+ const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
713
+ if (lastNotifiedSize == null || size !== lastNotifiedSize) {
714
+ panelIdToLastNotifiedSizeMap[panelId] = size;
856
715
  const {
857
716
  onCollapse,
858
717
  onExpand,
859
718
  onResize
860
719
  } = callbacks;
861
720
  if (onResize) {
862
- onResize(mixedSizes, lastNotifiedMixedSizes);
721
+ onResize(size, lastNotifiedSize);
863
722
  }
864
723
  if (collapsible && (onCollapse || onExpand)) {
865
- var _getPercentageSizeFro;
866
- const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
867
- sizePercentage: constraints.collapsedSizePercentage,
868
- sizePixels: constraints.collapsedSizePixels
869
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
870
- const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
871
- if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
724
+ if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
872
725
  onExpand();
873
726
  }
874
- if (onCollapse && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage !== collapsedSize) && size === collapsedSize) {
727
+ if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
875
728
  onCollapse();
876
729
  }
877
730
  }
@@ -905,9 +758,10 @@ function computePanelFlexBoxStyle({
905
758
  const size = layout[panelIndex];
906
759
  let flexGrow;
907
760
  if (panelData.length === 1) {
908
- flexGrow = "100";
761
+ flexGrow = "1";
909
762
  } else if (size == null) {
910
- flexGrow = "0";
763
+ // Initial render (before panels have registered themselves)
764
+ flexGrow = "1";
911
765
  } else {
912
766
  flexGrow = size.toPrecision(precision);
913
767
  }
@@ -1053,74 +907,39 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
1053
907
  }
1054
908
  }
1055
909
 
1056
- function shouldMonitorPixelBasedConstraints(constraints) {
1057
- return constraints.some(constraints => {
1058
- return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
1059
- });
1060
- }
1061
-
1062
910
  function validatePanelConstraints({
1063
- groupSizePixels,
1064
- panelConstraints,
911
+ panelConstraints: panelConstraintsArray,
1065
912
  panelId,
1066
913
  panelIndex
1067
914
  }) {
1068
915
  {
1069
916
  const warnings = [];
1070
- {
1071
- const {
1072
- collapsedSizePercentage,
1073
- collapsedSizePixels,
1074
- defaultSizePercentage,
1075
- defaultSizePixels,
1076
- maxSizePercentage,
1077
- maxSizePixels,
1078
- minSizePercentage,
1079
- minSizePixels
1080
- } = panelConstraints[panelIndex];
1081
- const conflictingUnits = [];
1082
- if (collapsedSizePercentage != null && collapsedSizePixels != null) {
1083
- conflictingUnits.push("collapsed size");
1084
- }
1085
- if (defaultSizePercentage != null && defaultSizePixels != null) {
1086
- conflictingUnits.push("default size");
1087
- }
1088
- if (maxSizePercentage != null && maxSizePixels != null) {
1089
- conflictingUnits.push("max size");
1090
- }
1091
- if (minSizePercentage != null && minSizePixels != null) {
1092
- conflictingUnits.push("min size");
1093
- }
1094
- if (conflictingUnits.length > 0) {
1095
- warnings.push(`should not specify both percentage and pixel units for: ${conflictingUnits.join(", ")}`);
1096
- }
917
+ const panelConstraints = panelConstraintsArray[panelIndex];
918
+ assert(panelConstraints);
919
+ const {
920
+ collapsedSize = 0,
921
+ defaultSize,
922
+ maxSize = 100,
923
+ minSize = 0
924
+ } = panelConstraints;
925
+ if (minSize > maxSize) {
926
+ warnings.push(`min size (${minSize}%) should not be greater than max size (${maxSize}%)`);
1097
927
  }
1098
- {
1099
- const {
1100
- collapsedSizePercentage,
1101
- defaultSizePercentage,
1102
- maxSizePercentage,
1103
- minSizePercentage
1104
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
1105
- if (minSizePercentage > maxSizePercentage) {
1106
- warnings.push(`min size (${minSizePercentage}%) should not be greater than max size (${maxSizePercentage}%)`);
1107
- }
1108
- if (defaultSizePercentage != null) {
1109
- if (defaultSizePercentage < 0) {
1110
- warnings.push("default size should not be less than 0");
1111
- } else if (defaultSizePercentage < minSizePercentage) {
1112
- warnings.push("default size should not be less than min size");
1113
- }
1114
- if (defaultSizePercentage > 100) {
1115
- warnings.push("default size should not be greater than 100");
1116
- } else if (defaultSizePercentage > maxSizePercentage) {
1117
- warnings.push("default size should not be greater than max size");
1118
- }
928
+ if (defaultSize != null) {
929
+ if (defaultSize < 0) {
930
+ warnings.push("default size should not be less than 0");
931
+ } else if (defaultSize < minSize) {
932
+ warnings.push("default size should not be less than min size");
1119
933
  }
1120
- if (collapsedSizePercentage > minSizePercentage) {
1121
- warnings.push("collapsed size should not be greater than min size");
934
+ if (defaultSize > 100) {
935
+ warnings.push("default size should not be greater than 100");
936
+ } else if (defaultSize > maxSize) {
937
+ warnings.push("default size should not be greater than max size");
1122
938
  }
1123
939
  }
940
+ if (collapsedSize > minSize) {
941
+ warnings.push("collapsed size should not be greater than min size");
942
+ }
1124
943
  if (warnings.length > 0) {
1125
944
  const name = panelId != null ? `Panel "${panelId}"` : "Panel";
1126
945
  console.warn(`${name} has an invalid configuration:\n\n${warnings.join("\n")}`);
@@ -1132,20 +951,26 @@ function validatePanelConstraints({
1132
951
 
1133
952
  // All units must be in percentages; pixel values should be pre-converted
1134
953
  function validatePanelGroupLayout({
1135
- groupSizePixels,
1136
954
  layout: prevLayout,
1137
955
  panelConstraints
1138
956
  }) {
1139
957
  const nextLayout = [...prevLayout];
958
+ const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
1140
959
 
1141
960
  // Validate layout expectations
1142
961
  if (nextLayout.length !== panelConstraints.length) {
1143
962
  throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
1144
- } else if (!fuzzyNumbersEqual(nextLayout.reduce((accumulated, current) => accumulated + current, 0), 100)) {
963
+ } else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
1145
964
  // This is not ideal so we should warn about it, but it may be recoverable in some cases
1146
965
  // (especially if the amount is small)
1147
966
  {
1148
- console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}`);
967
+ console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}. Layout normalization will be applied.`);
968
+ }
969
+ for (let index = 0; index < panelConstraints.length; index++) {
970
+ const unsafeSize = nextLayout[index];
971
+ assert(unsafeSize != null);
972
+ const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
973
+ nextLayout[index] = safeSize;
1149
974
  }
1150
975
  }
1151
976
  let remainingSize = 0;
@@ -1153,8 +978,8 @@ function validatePanelGroupLayout({
1153
978
  // First pass: Validate the proposed layout given each panel's constraints
1154
979
  for (let index = 0; index < panelConstraints.length; index++) {
1155
980
  const unsafeSize = nextLayout[index];
981
+ assert(unsafeSize != null);
1156
982
  const safeSize = resizePanel({
1157
- groupSizePixels,
1158
983
  panelConstraints,
1159
984
  panelIndex: index,
1160
985
  size: unsafeSize
@@ -1170,9 +995,9 @@ function validatePanelGroupLayout({
1170
995
  if (!fuzzyNumbersEqual(remainingSize, 0)) {
1171
996
  for (let index = 0; index < panelConstraints.length; index++) {
1172
997
  const prevSize = nextLayout[index];
998
+ assert(prevSize != null);
1173
999
  const unsafeSize = prevSize + remainingSize;
1174
1000
  const safeSize = resizePanel({
1175
- groupSizePixels,
1176
1001
  panelConstraints,
1177
1002
  panelIndex: index,
1178
1003
  size: unsafeSize
@@ -1207,21 +1032,20 @@ function PanelGroupWithForwardedRef({
1207
1032
  autoSaveId = null,
1208
1033
  children,
1209
1034
  className: classNameFromProps = "",
1210
- dataAttributes,
1211
1035
  direction,
1212
1036
  forwardedRef,
1213
- id: idFromProps,
1037
+ id: idFromProps = null,
1214
1038
  onLayout = null,
1215
- keyboardResizeByPercentage = null,
1216
- keyboardResizeByPixels = null,
1039
+ keyboardResizeBy = null,
1217
1040
  storage = defaultStorage,
1218
1041
  style: styleFromProps,
1219
- tagName: Type = "div"
1042
+ tagName: Type = "div",
1043
+ ...rest
1220
1044
  }) {
1221
1045
  const groupId = useUniqueId(idFromProps);
1222
1046
  const [dragState, setDragState] = useState(null);
1223
1047
  const [layout, setLayout] = useState([]);
1224
- const panelIdToLastNotifiedMixedSizesMapRef = useRef({});
1048
+ const panelIdToLastNotifiedSizeMapRef = useRef({});
1225
1049
  const panelSizeBeforeCollapseRef = useRef(new Map());
1226
1050
  const prevDeltaRef = useRef(0);
1227
1051
  const committedValuesRef = useRef({
@@ -1229,8 +1053,7 @@ function PanelGroupWithForwardedRef({
1229
1053
  direction,
1230
1054
  dragState,
1231
1055
  id: groupId,
1232
- keyboardResizeByPercentage,
1233
- keyboardResizeByPixels,
1056
+ keyboardResizeBy,
1234
1057
  onLayout,
1235
1058
  storage
1236
1059
  });
@@ -1246,33 +1069,20 @@ function PanelGroupWithForwardedRef({
1246
1069
  useImperativeHandle(forwardedRef, () => ({
1247
1070
  getId: () => committedValuesRef.current.id,
1248
1071
  getLayout: () => {
1249
- const {
1250
- id: groupId
1251
- } = committedValuesRef.current;
1252
1072
  const {
1253
1073
  layout
1254
1074
  } = eagerValuesRef.current;
1255
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1256
- return layout.map(sizePercentage => {
1257
- return {
1258
- sizePercentage,
1259
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1260
- };
1261
- });
1075
+ return layout;
1262
1076
  },
1263
- setLayout: mixedSizes => {
1077
+ setLayout: unsafeLayout => {
1264
1078
  const {
1265
- id: groupId,
1266
1079
  onLayout
1267
1080
  } = committedValuesRef.current;
1268
1081
  const {
1269
1082
  layout: prevLayout,
1270
1083
  panelDataArray
1271
1084
  } = eagerValuesRef.current;
1272
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1273
- const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
1274
1085
  const safeLayout = validatePanelGroupLayout({
1275
- groupSizePixels,
1276
1086
  layout: unsafeLayout,
1277
1087
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1278
1088
  });
@@ -1280,16 +1090,12 @@ function PanelGroupWithForwardedRef({
1280
1090
  setLayout(safeLayout);
1281
1091
  eagerValuesRef.current.layout = safeLayout;
1282
1092
  if (onLayout) {
1283
- onLayout(safeLayout.map(sizePercentage => ({
1284
- sizePercentage,
1285
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1286
- })));
1093
+ onLayout(safeLayout);
1287
1094
  }
1288
- callPanelCallbacks(groupId, panelDataArray, safeLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1095
+ callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
1289
1096
  }
1290
1097
  }
1291
1098
  }), []);
1292
-
1293
1099
  useWindowSplitterPanelGroupBehavior({
1294
1100
  committedValuesRef,
1295
1101
  eagerValuesRef,
@@ -1308,12 +1114,14 @@ function PanelGroupWithForwardedRef({
1308
1114
  if (layout.length === 0 || layout.length !== panelDataArray.length) {
1309
1115
  return;
1310
1116
  }
1117
+ let debouncedSave = debounceMap[autoSaveId];
1311
1118
 
1312
1119
  // Limit the frequency of localStorage updates.
1313
- if (!debounceMap[autoSaveId]) {
1314
- debounceMap[autoSaveId] = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1120
+ if (debouncedSave == null) {
1121
+ debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1122
+ debounceMap[autoSaveId] = debouncedSave;
1315
1123
  }
1316
- debounceMap[autoSaveId](autoSaveId, panelDataArray, layout, storage);
1124
+ debouncedSave(autoSaveId, panelDataArray, layout, storage);
1317
1125
  }
1318
1126
  }, [autoSaveId, layout, storage]);
1319
1127
 
@@ -1346,12 +1154,12 @@ function PanelGroupWithForwardedRef({
1346
1154
  }
1347
1155
  if (!didLogPanelConstraintsWarning) {
1348
1156
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1349
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1350
1157
  for (let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++) {
1158
+ const panelData = panelDataArray[panelIndex];
1159
+ assert(panelData);
1351
1160
  const isValid = validatePanelConstraints({
1352
- groupSizePixels,
1353
1161
  panelConstraints,
1354
- panelId: panelDataArray[panelIndex].id,
1162
+ panelId: panelData.id,
1355
1163
  panelIndex
1356
1164
  });
1357
1165
  if (!isValid) {
@@ -1375,20 +1183,19 @@ function PanelGroupWithForwardedRef({
1375
1183
  if (panelData.constraints.collapsible) {
1376
1184
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1377
1185
  const {
1378
- collapsedSizePercentage,
1379
- panelSizePercentage,
1380
- pivotIndices,
1381
- groupSizePixels
1382
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1383
- if (panelSizePercentage !== collapsedSizePercentage) {
1186
+ collapsedSize = 0,
1187
+ panelSize,
1188
+ pivotIndices
1189
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1190
+ assert(panelSize != null);
1191
+ if (panelSize !== collapsedSize) {
1384
1192
  // Store size before collapse;
1385
1193
  // This is the size that gets restored if the expand() API is used.
1386
- panelSizeBeforeCollapseRef.current.set(panelData.id, panelSizePercentage);
1194
+ panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1387
1195
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1388
- const delta = isLastPanel ? panelSizePercentage - collapsedSizePercentage : collapsedSizePercentage - panelSizePercentage;
1196
+ const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1389
1197
  const nextLayout = adjustLayoutByDelta({
1390
1198
  delta,
1391
- groupSizePixels,
1392
1199
  layout: prevLayout,
1393
1200
  panelConstraints: panelConstraintsArray,
1394
1201
  pivotIndices,
@@ -1398,16 +1205,13 @@ function PanelGroupWithForwardedRef({
1398
1205
  setLayout(nextLayout);
1399
1206
  eagerValuesRef.current.layout = nextLayout;
1400
1207
  if (onLayout) {
1401
- onLayout(nextLayout.map(sizePercentage => ({
1402
- sizePercentage,
1403
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1404
- })));
1208
+ onLayout(nextLayout);
1405
1209
  }
1406
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1210
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1407
1211
  }
1408
1212
  }
1409
1213
  }
1410
- }, [groupId]);
1214
+ }, []);
1411
1215
 
1412
1216
  // External APIs are safe to memoize via committed values ref
1413
1217
  const expandPanel = useCallback(panelData => {
@@ -1421,21 +1225,19 @@ function PanelGroupWithForwardedRef({
1421
1225
  if (panelData.constraints.collapsible) {
1422
1226
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1423
1227
  const {
1424
- collapsedSizePercentage,
1425
- panelSizePercentage,
1426
- minSizePercentage,
1427
- pivotIndices,
1428
- groupSizePixels
1429
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1430
- if (panelSizePercentage === collapsedSizePercentage) {
1228
+ collapsedSize = 0,
1229
+ panelSize,
1230
+ minSize = 0,
1231
+ pivotIndices
1232
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1233
+ if (panelSize === collapsedSize) {
1431
1234
  // Restore this panel to the size it was before it was collapsed, if possible.
1432
- const prevPanelSizePercentage = panelSizeBeforeCollapseRef.current.get(panelData.id);
1433
- const baseSizePercentage = prevPanelSizePercentage != null && prevPanelSizePercentage >= minSizePercentage ? prevPanelSizePercentage : minSizePercentage;
1235
+ const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1236
+ const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1434
1237
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1435
- const delta = isLastPanel ? panelSizePercentage - baseSizePercentage : baseSizePercentage - panelSizePercentage;
1238
+ const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1436
1239
  const nextLayout = adjustLayoutByDelta({
1437
1240
  delta,
1438
- groupSizePixels,
1439
1241
  layout: prevLayout,
1440
1242
  panelConstraints: panelConstraintsArray,
1441
1243
  pivotIndices,
@@ -1445,16 +1247,13 @@ function PanelGroupWithForwardedRef({
1445
1247
  setLayout(nextLayout);
1446
1248
  eagerValuesRef.current.layout = nextLayout;
1447
1249
  if (onLayout) {
1448
- onLayout(nextLayout.map(sizePercentage => ({
1449
- sizePercentage,
1450
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1451
- })));
1250
+ onLayout(nextLayout);
1452
1251
  }
1453
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1252
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1454
1253
  }
1455
1254
  }
1456
1255
  }
1457
- }, [groupId]);
1256
+ }, []);
1458
1257
 
1459
1258
  // External APIs are safe to memoize via committed values ref
1460
1259
  const getPanelSize = useCallback(panelData => {
@@ -1463,14 +1262,11 @@ function PanelGroupWithForwardedRef({
1463
1262
  panelDataArray
1464
1263
  } = eagerValuesRef.current;
1465
1264
  const {
1466
- panelSizePercentage,
1467
- panelSizePixels
1468
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1469
- return {
1470
- sizePercentage: panelSizePercentage,
1471
- sizePixels: panelSizePixels
1472
- };
1473
- }, [groupId]);
1265
+ panelSize
1266
+ } = panelDataHelper(panelDataArray, panelData, layout);
1267
+ assert(panelSize != null);
1268
+ return panelSize;
1269
+ }, []);
1474
1270
 
1475
1271
  // This API should never read from committedValuesRef
1476
1272
  const getPanelStyle = useCallback(panelData => {
@@ -1493,12 +1289,12 @@ function PanelGroupWithForwardedRef({
1493
1289
  panelDataArray
1494
1290
  } = eagerValuesRef.current;
1495
1291
  const {
1496
- collapsedSizePercentage,
1292
+ collapsedSize,
1497
1293
  collapsible,
1498
- panelSizePercentage
1499
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1500
- return collapsible === true && panelSizePercentage === collapsedSizePercentage;
1501
- }, [groupId]);
1294
+ panelSize
1295
+ } = panelDataHelper(panelDataArray, panelData, layout);
1296
+ return collapsible === true && panelSize === collapsedSize;
1297
+ }, []);
1502
1298
 
1503
1299
  // External APIs are safe to memoize via committed values ref
1504
1300
  const isPanelExpanded = useCallback(panelData => {
@@ -1507,12 +1303,13 @@ function PanelGroupWithForwardedRef({
1507
1303
  panelDataArray
1508
1304
  } = eagerValuesRef.current;
1509
1305
  const {
1510
- collapsedSizePercentage,
1306
+ collapsedSize = 0,
1511
1307
  collapsible,
1512
- panelSizePercentage
1513
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1514
- return !collapsible || panelSizePercentage > collapsedSizePercentage;
1515
- }, [groupId]);
1308
+ panelSize
1309
+ } = panelDataHelper(panelDataArray, panelData, layout);
1310
+ assert(panelSize != null);
1311
+ return !collapsible || panelSize > collapsedSize;
1312
+ }, []);
1516
1313
  const registerPanel = useCallback(panelData => {
1517
1314
  const {
1518
1315
  autoSaveId,
@@ -1552,18 +1349,8 @@ function PanelGroupWithForwardedRef({
1552
1349
  if (autoSaveId) {
1553
1350
  unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1554
1351
  }
1555
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1556
- if (groupSizePixels <= 0) {
1557
- if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
1558
- constraints
1559
- }) => constraints))) {
1560
- // Wait until the group has rendered a non-zero size before computing layout.
1561
- return;
1562
- }
1563
- }
1564
1352
  if (unsafeLayout == null) {
1565
1353
  unsafeLayout = calculateUnsafeDefaultLayout({
1566
- groupSizePixels,
1567
1354
  panelDataArray
1568
1355
  });
1569
1356
  }
@@ -1571,7 +1358,6 @@ function PanelGroupWithForwardedRef({
1571
1358
  // Validate even saved layouts in case something has changed since last render
1572
1359
  // e.g. for pixel groups, this could be the size of the window
1573
1360
  const nextLayout = validatePanelGroupLayout({
1574
- groupSizePixels,
1575
1361
  layout: unsafeLayout,
1576
1362
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1577
1363
  });
@@ -1583,12 +1369,9 @@ function PanelGroupWithForwardedRef({
1583
1369
  eagerValuesRef.current.layout = nextLayout;
1584
1370
  if (!areEqual(prevLayout, nextLayout)) {
1585
1371
  if (onLayout) {
1586
- onLayout(nextLayout.map(sizePercentage => ({
1587
- sizePercentage,
1588
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1589
- })));
1372
+ onLayout(nextLayout);
1590
1373
  }
1591
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1374
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1592
1375
  }
1593
1376
  }, []);
1594
1377
  const registerResizeHandle = useCallback(dragHandleId => {
@@ -1598,8 +1381,7 @@ function PanelGroupWithForwardedRef({
1598
1381
  direction,
1599
1382
  dragState,
1600
1383
  id: groupId,
1601
- keyboardResizeByPercentage,
1602
- keyboardResizeByPixels,
1384
+ keyboardResizeBy,
1603
1385
  onLayout
1604
1386
  } = committedValuesRef.current;
1605
1387
  const {
@@ -1610,10 +1392,7 @@ function PanelGroupWithForwardedRef({
1610
1392
  initialLayout
1611
1393
  } = dragState !== null && dragState !== void 0 ? dragState : {};
1612
1394
  const pivotIndices = determinePivotIndices(groupId, dragHandleId);
1613
- let delta = calculateDeltaPercentage(event, groupId, dragHandleId, direction, dragState, {
1614
- percentage: keyboardResizeByPercentage,
1615
- pixels: keyboardResizeByPixels
1616
- });
1395
+ let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
1617
1396
  if (delta === 0) {
1618
1397
  return;
1619
1398
  }
@@ -1623,11 +1402,9 @@ function PanelGroupWithForwardedRef({
1623
1402
  if (document.dir === "rtl" && isHorizontal) {
1624
1403
  delta = -delta;
1625
1404
  }
1626
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1627
1405
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1628
1406
  const nextLayout = adjustLayoutByDelta({
1629
1407
  delta,
1630
- groupSizePixels,
1631
1408
  layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
1632
1409
  panelConstraints,
1633
1410
  pivotIndices,
@@ -1663,18 +1440,15 @@ function PanelGroupWithForwardedRef({
1663
1440
  setLayout(nextLayout);
1664
1441
  eagerValuesRef.current.layout = nextLayout;
1665
1442
  if (onLayout) {
1666
- onLayout(nextLayout.map(sizePercentage => ({
1667
- sizePercentage,
1668
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1669
- })));
1443
+ onLayout(nextLayout);
1670
1444
  }
1671
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1445
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1672
1446
  }
1673
1447
  };
1674
1448
  }, []);
1675
1449
 
1676
1450
  // External APIs are safe to memoize via committed values ref
1677
- const resizePanel = useCallback((panelData, mixedSizes) => {
1451
+ const resizePanel = useCallback((panelData, unsafePanelSize) => {
1678
1452
  const {
1679
1453
  onLayout
1680
1454
  } = committedValuesRef.current;
@@ -1684,16 +1458,14 @@ function PanelGroupWithForwardedRef({
1684
1458
  } = eagerValuesRef.current;
1685
1459
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1686
1460
  const {
1687
- groupSizePixels,
1688
- panelSizePercentage,
1461
+ panelSize,
1689
1462
  pivotIndices
1690
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1691
- const sizePercentage = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
1463
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1464
+ assert(panelSize != null);
1692
1465
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1693
- const delta = isLastPanel ? panelSizePercentage - sizePercentage : sizePercentage - panelSizePercentage;
1466
+ const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1694
1467
  const nextLayout = adjustLayoutByDelta({
1695
1468
  delta,
1696
- groupSizePixels,
1697
1469
  layout: prevLayout,
1698
1470
  panelConstraints: panelConstraintsArray,
1699
1471
  pivotIndices,
@@ -1703,14 +1475,11 @@ function PanelGroupWithForwardedRef({
1703
1475
  setLayout(nextLayout);
1704
1476
  eagerValuesRef.current.layout = nextLayout;
1705
1477
  if (onLayout) {
1706
- onLayout(nextLayout.map(sizePercentage => ({
1707
- sizePercentage,
1708
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1709
- })));
1478
+ onLayout(nextLayout);
1710
1479
  }
1711
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1480
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1712
1481
  }
1713
- }, [groupId]);
1482
+ }, []);
1714
1483
  const startDragging = useCallback((dragHandleId, event) => {
1715
1484
  const {
1716
1485
  direction
@@ -1719,6 +1488,7 @@ function PanelGroupWithForwardedRef({
1719
1488
  layout
1720
1489
  } = eagerValuesRef.current;
1721
1490
  const handleElement = getResizeHandleElement(dragHandleId);
1491
+ assert(handleElement);
1722
1492
  const initialCursorPosition = getResizeEventCursorPosition(direction, event);
1723
1493
  setDragState({
1724
1494
  dragHandleId,
@@ -1737,7 +1507,6 @@ function PanelGroupWithForwardedRef({
1737
1507
  });
1738
1508
  const unregisterPanel = useCallback(panelData => {
1739
1509
  const {
1740
- id: groupId,
1741
1510
  onLayout
1742
1511
  } = committedValuesRef.current;
1743
1512
  const {
@@ -1760,7 +1529,7 @@ function PanelGroupWithForwardedRef({
1760
1529
  const {
1761
1530
  pendingPanelIds
1762
1531
  } = unregisterPanelRef.current;
1763
- const map = panelIdToLastNotifiedMixedSizesMapRef.current;
1532
+ const map = panelIdToLastNotifiedSizeMapRef.current;
1764
1533
 
1765
1534
  // TRICKY
1766
1535
  // Strict effects mode
@@ -1786,16 +1555,13 @@ function PanelGroupWithForwardedRef({
1786
1555
  // The group is unmounting; skip layout calculation.
1787
1556
  return;
1788
1557
  }
1789
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1790
1558
  let unsafeLayout = calculateUnsafeDefaultLayout({
1791
- groupSizePixels,
1792
1559
  panelDataArray
1793
1560
  });
1794
1561
 
1795
1562
  // Validate even saved layouts in case something has changed since last render
1796
1563
  // e.g. for pixel groups, this could be the size of the window
1797
1564
  const nextLayout = validatePanelGroupLayout({
1798
- groupSizePixels,
1799
1565
  layout: unsafeLayout,
1800
1566
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1801
1567
  });
@@ -1803,12 +1569,9 @@ function PanelGroupWithForwardedRef({
1803
1569
  setLayout(nextLayout);
1804
1570
  eagerValuesRef.current.layout = nextLayout;
1805
1571
  if (onLayout) {
1806
- onLayout(nextLayout.map(sizePercentage => ({
1807
- sizePercentage,
1808
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1809
- })));
1572
+ onLayout(nextLayout);
1810
1573
  }
1811
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1574
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1812
1575
  }
1813
1576
  }, 0);
1814
1577
  }, []);
@@ -1839,13 +1602,13 @@ function PanelGroupWithForwardedRef({
1839
1602
  return createElement(PanelGroupContext.Provider, {
1840
1603
  value: context
1841
1604
  }, createElement(Type, {
1605
+ ...rest,
1842
1606
  children,
1843
1607
  className: classNameFromProps,
1844
1608
  style: {
1845
1609
  ...style,
1846
1610
  ...styleFromProps
1847
1611
  },
1848
- ...dataAttributes,
1849
1612
  // CSS selectors
1850
1613
  "data-panel-group": "",
1851
1614
  "data-panel-group-direction": direction,
@@ -1858,22 +1621,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1858
1621
  }));
1859
1622
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1860
1623
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1861
- function panelDataHelper(groupId, panelDataArray, panelData, layout) {
1624
+ function panelDataHelper(panelDataArray, panelData, layout) {
1862
1625
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1863
1626
  const panelIndex = panelDataArray.indexOf(panelData);
1864
1627
  const panelConstraints = panelConstraintsArray[panelIndex];
1865
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1866
- const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
1867
1628
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1868
1629
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
1869
- const panelSizePercentage = layout[panelIndex];
1870
- const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
1630
+ const panelSize = layout[panelIndex];
1871
1631
  return {
1872
- ...percentagePanelConstraints,
1873
- collapsible: panelConstraints.collapsible,
1874
- panelSizePercentage,
1875
- panelSizePixels,
1876
- groupSizePixels,
1632
+ ...panelConstraints,
1633
+ panelSize,
1877
1634
  pivotIndices
1878
1635
  };
1879
1636
  }
@@ -1913,6 +1670,7 @@ function useWindowSplitterResizeHandlerBehavior({
1913
1670
  {
1914
1671
  event.preventDefault();
1915
1672
  const groupId = handleElement.getAttribute("data-panel-group-id");
1673
+ assert(groupId);
1916
1674
  const handles = getResizeHandleElementsForGroup(groupId);
1917
1675
  const index = getResizeHandleElementIndex(groupId, handleId);
1918
1676
  assert(index !== null);
@@ -1933,12 +1691,13 @@ function useWindowSplitterResizeHandlerBehavior({
1933
1691
  function PanelResizeHandle({
1934
1692
  children = null,
1935
1693
  className: classNameFromProps = "",
1936
- dataAttributes,
1937
1694
  disabled = false,
1938
- id: idFromProps = null,
1695
+ id: idFromProps,
1939
1696
  onDragging,
1940
1697
  style: styleFromProps = {},
1941
- tagName: Type = "div"
1698
+ tabIndex = 0,
1699
+ tagName: Type = "div",
1700
+ ...rest
1942
1701
  }) {
1943
1702
  const divElementRef = useRef(null);
1944
1703
 
@@ -1968,8 +1727,9 @@ function PanelResizeHandle({
1968
1727
  const stopDraggingAndBlur = useCallback(() => {
1969
1728
  // Clicking on the drag handle shouldn't leave it focused;
1970
1729
  // That would cause the PanelGroup to think it was still active.
1971
- const div = divElementRef.current;
1972
- div.blur();
1730
+ const divElement = divElementRef.current;
1731
+ assert(divElement);
1732
+ divElement.blur();
1973
1733
  stopDragging();
1974
1734
  const {
1975
1735
  onDragging
@@ -1997,6 +1757,7 @@ function PanelResizeHandle({
1997
1757
  resizeHandler(event);
1998
1758
  };
1999
1759
  const divElement = divElementRef.current;
1760
+ assert(divElement);
2000
1761
  const targetDocument = divElement.ownerDocument;
2001
1762
  targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
2002
1763
  targetDocument.body.addEventListener("mousemove", onMove);
@@ -2024,15 +1785,18 @@ function PanelResizeHandle({
2024
1785
  userSelect: "none"
2025
1786
  };
2026
1787
  return createElement(Type, {
1788
+ ...rest,
2027
1789
  children,
2028
1790
  className: classNameFromProps,
2029
1791
  onBlur: () => setIsFocused(false),
2030
1792
  onFocus: () => setIsFocused(true),
2031
1793
  onMouseDown: event => {
2032
1794
  startDragging(resizeHandleId, event.nativeEvent);
1795
+ const callbacks = callbacksRef.current;
1796
+ assert(callbacks);
2033
1797
  const {
2034
1798
  onDragging
2035
- } = callbacksRef.current;
1799
+ } = callbacks;
2036
1800
  if (onDragging) {
2037
1801
  onDragging(true);
2038
1802
  }
@@ -2042,9 +1806,11 @@ function PanelResizeHandle({
2042
1806
  onTouchEnd: stopDraggingAndBlur,
2043
1807
  onTouchStart: event => {
2044
1808
  startDragging(resizeHandleId, event.nativeEvent);
1809
+ const callbacks = callbacksRef.current;
1810
+ assert(callbacks);
2045
1811
  const {
2046
1812
  onDragging
2047
- } = callbacksRef.current;
1813
+ } = callbacks;
2048
1814
  if (onDragging) {
2049
1815
  onDragging(true);
2050
1816
  }
@@ -2055,8 +1821,7 @@ function PanelResizeHandle({
2055
1821
  ...style,
2056
1822
  ...styleFromProps
2057
1823
  },
2058
- tabIndex: 0,
2059
- ...dataAttributes,
1824
+ tabIndex,
2060
1825
  // CSS selectors
2061
1826
  "data-panel-group-direction": direction,
2062
1827
  "data-panel-group-id": groupId,
@@ -2068,4 +1833,4 @@ function PanelResizeHandle({
2068
1833
  }
2069
1834
  PanelResizeHandle.displayName = "PanelResizeHandle";
2070
1835
 
2071
- export { Panel, PanelGroup, PanelResizeHandle };
1836
+ export { Panel, PanelGroup, PanelResizeHandle, assert };