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
@@ -63,24 +63,20 @@ function useUniqueId(idFromParams = null) {
63
63
  function PanelWithForwardedRef({
64
64
  children,
65
65
  className: classNameFromProps = "",
66
- collapsedSizePercentage,
67
- collapsedSizePixels,
66
+ collapsedSize,
68
67
  collapsible,
69
- dataAttributes,
70
- defaultSizePercentage,
71
- defaultSizePixels,
68
+ defaultSize,
72
69
  forwardedRef,
73
70
  id: idFromProps,
74
- maxSizePercentage,
75
- maxSizePixels,
76
- minSizePercentage,
77
- minSizePixels,
71
+ maxSize,
72
+ minSize,
78
73
  onCollapse,
79
74
  onExpand,
80
75
  onResize,
81
76
  order,
82
77
  style: styleFromProps,
83
- tagName: Type = "div"
78
+ tagName: Type = "div",
79
+ ...rest
84
80
  }) {
85
81
  const context = useContext(PanelGroupContext);
86
82
  if (context === null) {
@@ -105,15 +101,11 @@ function PanelWithForwardedRef({
105
101
  onResize
106
102
  },
107
103
  constraints: {
108
- collapsedSizePercentage,
109
- collapsedSizePixels,
104
+ collapsedSize,
110
105
  collapsible,
111
- defaultSizePercentage,
112
- defaultSizePixels,
113
- maxSizePercentage,
114
- maxSizePixels,
115
- minSizePercentage,
116
- minSizePixels
106
+ defaultSize,
107
+ maxSize,
108
+ minSize
117
109
  },
118
110
  id: panelId,
119
111
  idIsFromProps: idFromProps !== undefined,
@@ -127,9 +119,9 @@ function PanelWithForwardedRef({
127
119
  // but effects don't run on the server, so we can't do it there
128
120
  {
129
121
  if (!devWarningsRef.current.didLogMissingDefaultSizeWarning) {
130
- if (defaultSizePercentage == null && defaultSizePixels == null) {
122
+ if (defaultSize == null) {
131
123
  devWarningsRef.current.didLogMissingDefaultSizeWarning = true;
132
- console.warn(`WARNING: Panel defaultSizePercentage or defaultSizePixels prop recommended to avoid layout shift after server rendering`);
124
+ console.warn(`WARNING: Panel defaultSize prop recommended to avoid layout shift after server rendering`);
133
125
  }
134
126
  }
135
127
  }
@@ -152,19 +144,19 @@ function PanelWithForwardedRef({
152
144
  isExpanded() {
153
145
  return !isPanelCollapsed(panelDataRef.current);
154
146
  },
155
- resize: mixedSizes => {
156
- resizePanel(panelDataRef.current, mixedSizes);
147
+ resize: size => {
148
+ resizePanel(panelDataRef.current, size);
157
149
  }
158
150
  }), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
159
151
  const style = getPanelStyle(panelDataRef.current);
160
152
  return createElement(Type, {
153
+ ...rest,
161
154
  children,
162
155
  className: classNameFromProps,
163
156
  style: {
164
157
  ...style,
165
158
  ...styleFromProps
166
159
  },
167
- ...dataAttributes,
168
160
  // CSS selectors
169
161
  "data-panel": "",
170
162
  "data-panel-id": panelId,
@@ -181,81 +173,11 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
181
173
  PanelWithForwardedRef.displayName = "Panel";
182
174
  Panel.displayName = "forwardRef(Panel)";
183
175
 
184
- function convertPixelsToPercentage(pixels, groupSizePixels) {
185
- return pixels / groupSizePixels * 100;
186
- }
187
-
188
- function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels) {
189
- let {
190
- collapsedSizePercentage = 0,
191
- collapsedSizePixels,
192
- defaultSizePercentage,
193
- defaultSizePixels,
194
- maxSizePercentage = 100,
195
- maxSizePixels,
196
- minSizePercentage = 0,
197
- minSizePixels
198
- } = panelConstraints;
199
- const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
200
- if (hasPixelConstraints && groupSizePixels <= 0) {
201
- console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
202
- return {
203
- collapsedSizePercentage: 0,
204
- defaultSizePercentage,
205
- maxSizePercentage: 0,
206
- minSizePercentage: 0
207
- };
208
- }
209
- if (collapsedSizePixels != null) {
210
- collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
211
- }
212
- if (defaultSizePixels != null) {
213
- defaultSizePercentage = convertPixelsToPercentage(defaultSizePixels, groupSizePixels);
214
- }
215
- if (minSizePixels != null) {
216
- minSizePercentage = convertPixelsToPercentage(minSizePixels, groupSizePixels);
217
- }
218
- if (maxSizePixels != null) {
219
- maxSizePercentage = convertPixelsToPercentage(maxSizePixels, groupSizePixels);
220
- }
221
- return {
222
- collapsedSizePercentage,
223
- defaultSizePercentage,
224
- maxSizePercentage,
225
- minSizePercentage
226
- };
227
- }
228
-
229
- function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels) {
230
- // All panel constraints, excluding the current one
231
- let totalMinConstraints = 0;
232
- let totalMaxConstraints = 0;
233
- for (let index = 0; index < panelConstraintsArray.length; index++) {
234
- if (index !== panelIndex) {
235
- const {
236
- collapsible
237
- } = panelConstraintsArray[index];
238
- const {
239
- collapsedSizePercentage,
240
- maxSizePercentage,
241
- minSizePercentage
242
- } = convertPixelConstraintsToPercentages(panelConstraintsArray[index], groupSizePixels);
243
- totalMaxConstraints += maxSizePercentage;
244
- totalMinConstraints += collapsible ? collapsedSizePercentage : minSizePercentage;
245
- }
176
+ function assert(expectedCondition, message = "Assertion failed!") {
177
+ if (!expectedCondition) {
178
+ console.error(message);
179
+ throw Error(message);
246
180
  }
247
- const {
248
- collapsedSizePercentage,
249
- defaultSizePercentage,
250
- maxSizePercentage,
251
- minSizePercentage
252
- } = convertPixelConstraintsToPercentages(panelConstraintsArray[panelIndex], groupSizePixels);
253
- return {
254
- collapsedSizePercentage,
255
- defaultSizePercentage,
256
- maxSizePercentage: panelConstraintsArray.length > 1 ? Math.min(maxSizePercentage, 100 - totalMinConstraints) : maxSizePercentage,
257
- minSizePercentage: panelConstraintsArray.length > 1 ? Math.max(minSizePercentage, 100 - totalMaxConstraints) : minSizePercentage
258
- };
259
181
  }
260
182
 
261
183
  const PRECISION = 10;
@@ -277,56 +199,41 @@ function fuzzyNumbersEqual(actual, expected, fractionDigits) {
277
199
 
278
200
  // Panel size must be in percentages; pixel values should be pre-converted
279
201
  function resizePanel({
280
- groupSizePixels,
281
- panelConstraints,
202
+ panelConstraints: panelConstraintsArray,
282
203
  panelIndex,
283
204
  size
284
205
  }) {
285
- const hasPixelConstraints = panelConstraints.some(({
286
- collapsedSizePixels,
287
- defaultSizePixels,
288
- minSizePixels,
289
- maxSizePixels
290
- }) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
291
- if (hasPixelConstraints && groupSizePixels <= 0) {
292
- console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
293
- return 0;
294
- }
206
+ const panelConstraints = panelConstraintsArray[panelIndex];
207
+ assert(panelConstraints != null);
295
208
  let {
296
- collapsible
297
- } = panelConstraints[panelIndex];
298
- const {
299
- collapsedSizePercentage,
300
- maxSizePercentage,
301
- minSizePercentage
302
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
303
- if (minSizePercentage != null) {
304
- if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
305
- if (collapsible) {
306
- // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
307
- const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
308
- if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
309
- size = collapsedSizePercentage;
310
- } else {
311
- size = minSizePercentage;
312
- }
209
+ collapsedSize = 0,
210
+ collapsible,
211
+ maxSize = 100,
212
+ minSize = 0
213
+ } = panelConstraints;
214
+ if (fuzzyCompareNumbers(size, minSize) < 0) {
215
+ if (collapsible) {
216
+ // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
217
+ const halfwayPoint = (collapsedSize + minSize) / 2;
218
+ if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
219
+ size = collapsedSize;
313
220
  } else {
314
- size = minSizePercentage;
221
+ size = minSize;
315
222
  }
223
+ } else {
224
+ size = minSize;
316
225
  }
317
226
  }
318
- if (maxSizePercentage != null) {
319
- size = Math.min(maxSizePercentage, size);
320
- }
227
+ size = Math.min(maxSize, size);
228
+ size = parseFloat(size.toFixed(PRECISION));
321
229
  return size;
322
230
  }
323
231
 
324
232
  // All units must be in percentages; pixel values should be pre-converted
325
233
  function adjustLayoutByDelta({
326
234
  delta,
327
- groupSizePixels,
328
235
  layout: prevLayout,
329
- panelConstraints,
236
+ panelConstraints: panelConstraintsArray,
330
237
  pivotIndices,
331
238
  trigger
332
239
  }) {
@@ -334,6 +241,9 @@ function adjustLayoutByDelta({
334
241
  return prevLayout;
335
242
  }
336
243
  const nextLayout = [...prevLayout];
244
+ const [firstPivotIndex, secondPivotIndex] = pivotIndices;
245
+ assert(firstPivotIndex != null);
246
+ assert(secondPivotIndex != null);
337
247
  let deltaApplied = 0;
338
248
 
339
249
  //const DEBUG = [];
@@ -357,18 +267,23 @@ function adjustLayoutByDelta({
357
267
  if (trigger === "keyboard") {
358
268
  {
359
269
  // Check if we should expand a collapsed panel
360
- const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
361
- const constraints = panelConstraints[index];
270
+ const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
271
+ const panelConstraints = panelConstraintsArray[index];
272
+ assert(panelConstraints);
273
+
362
274
  //DEBUG.push(`edge case check 1: ${index}`);
363
275
  //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
364
- if (constraints.collapsible) {
276
+ if (panelConstraints.collapsible) {
365
277
  const prevSize = prevLayout[index];
278
+ assert(prevSize != null);
279
+ const panelConstraints = panelConstraintsArray[index];
280
+ assert(panelConstraints);
366
281
  const {
367
- collapsedSizePercentage,
368
- minSizePercentage
369
- } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
370
- if (fuzzyNumbersEqual(prevSize, collapsedSizePercentage)) {
371
- const localDelta = minSizePercentage - prevSize;
282
+ collapsedSize = 0,
283
+ minSize = 0
284
+ } = panelConstraints;
285
+ if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
286
+ const localDelta = minSize - prevSize;
372
287
  //DEBUG.push(` -> expand delta: ${localDelta}`);
373
288
 
374
289
  if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
@@ -381,18 +296,26 @@ function adjustLayoutByDelta({
381
296
 
382
297
  {
383
298
  // Check if we should collapse a panel at its minimum size
384
- const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
385
- const constraints = panelConstraints[index];
299
+ const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
300
+ const panelConstraints = panelConstraintsArray[index];
301
+ assert(panelConstraints);
302
+ const {
303
+ collapsible
304
+ } = panelConstraints;
305
+
386
306
  //DEBUG.push(`edge case check 2: ${index}`);
387
- //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
388
- if (constraints.collapsible) {
307
+ //DEBUG.push(` -> collapsible? ${collapsible}`);
308
+ if (collapsible) {
389
309
  const prevSize = prevLayout[index];
310
+ assert(prevSize != null);
311
+ const panelConstraints = panelConstraintsArray[index];
312
+ assert(panelConstraints);
390
313
  const {
391
- collapsedSizePercentage,
392
- minSizePercentage
393
- } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
394
- if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
395
- const localDelta = prevSize - collapsedSizePercentage;
314
+ collapsedSize = 0,
315
+ minSize = 0
316
+ } = panelConstraints;
317
+ if (fuzzyNumbersEqual(prevSize, minSize)) {
318
+ const localDelta = prevSize - collapsedSize;
396
319
  //DEBUG.push(` -> expand delta: ${localDelta}`);
397
320
 
398
321
  if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
@@ -414,15 +337,15 @@ function adjustLayoutByDelta({
414
337
  // as an expanding panel might change from collapsed to min size.
415
338
 
416
339
  const increment = delta < 0 ? 1 : -1;
417
- let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
340
+ let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
418
341
  let maxAvailableDelta = 0;
419
342
 
420
343
  //DEBUG.push("pre calc...");
421
344
  while (true) {
422
345
  const prevSize = prevLayout[index];
346
+ assert(prevSize != null);
423
347
  const maxSafeSize = resizePanel({
424
- groupSizePixels,
425
- panelConstraints,
348
+ panelConstraints: panelConstraintsArray,
426
349
  panelIndex: index,
427
350
  size: 100
428
351
  });
@@ -431,7 +354,7 @@ function adjustLayoutByDelta({
431
354
 
432
355
  maxAvailableDelta += delta;
433
356
  index += increment;
434
- if (index < 0 || index >= panelConstraints.length) {
357
+ if (index < 0 || index >= panelConstraintsArray.length) {
435
358
  break;
436
359
  }
437
360
  }
@@ -446,15 +369,15 @@ function adjustLayoutByDelta({
446
369
  {
447
370
  // Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
448
371
 
449
- const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
372
+ const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
450
373
  let index = pivotIndex;
451
- while (index >= 0 && index < panelConstraints.length) {
374
+ while (index >= 0 && index < panelConstraintsArray.length) {
452
375
  const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
453
376
  const prevSize = prevLayout[index];
377
+ assert(prevSize != null);
454
378
  const unsafeSize = prevSize - deltaRemaining;
455
379
  const safeSize = resizePanel({
456
- groupSizePixels,
457
- panelConstraints,
380
+ panelConstraints: panelConstraintsArray,
458
381
  panelIndex: index,
459
382
  size: unsafeSize
460
383
  });
@@ -486,11 +409,12 @@ function adjustLayoutByDelta({
486
409
  }
487
410
  {
488
411
  // Now distribute the applied delta to the panels in the other direction
489
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
490
- const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
412
+ const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
413
+ const prevSize = prevLayout[pivotIndex];
414
+ assert(prevSize != null);
415
+ const unsafeSize = prevSize + deltaApplied;
491
416
  const safeSize = resizePanel({
492
- groupSizePixels,
493
- panelConstraints,
417
+ panelConstraints: panelConstraintsArray,
494
418
  panelIndex: pivotIndex,
495
419
  size: unsafeSize
496
420
  });
@@ -501,14 +425,14 @@ function adjustLayoutByDelta({
501
425
  // Edge case where expanding or contracting one panel caused another one to change collapsed state
502
426
  if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
503
427
  let deltaRemaining = unsafeSize - safeSize;
504
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
428
+ const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
505
429
  let index = pivotIndex;
506
- while (index >= 0 && index < panelConstraints.length) {
430
+ while (index >= 0 && index < panelConstraintsArray.length) {
507
431
  const prevSize = nextLayout[index];
432
+ assert(prevSize != null);
508
433
  const unsafeSize = prevSize + deltaRemaining;
509
434
  const safeSize = resizePanel({
510
- groupSizePixels,
511
- panelConstraints,
435
+ panelConstraints: panelConstraintsArray,
512
436
  panelIndex: index,
513
437
  size: unsafeSize
514
438
  });
@@ -532,9 +456,7 @@ function adjustLayoutByDelta({
532
456
  //DEBUG.push("");
533
457
 
534
458
  const totalSize = nextLayout.reduce((total, size) => size + total, 0);
535
- deltaApplied = 100 - totalSize;
536
459
  //DEBUG.push(`total size: ${totalSize}`);
537
- //DEBUG.push(` deltaApplied: ${deltaApplied}`);
538
460
  //console.log(DEBUG.join("\n"));
539
461
 
540
462
  if (!fuzzyNumbersEqual(totalSize, 100)) {
@@ -543,25 +465,6 @@ function adjustLayoutByDelta({
543
465
  return nextLayout;
544
466
  }
545
467
 
546
- function assert(expectedCondition, message = "Assertion failed!") {
547
- if (!expectedCondition) {
548
- console.error(message);
549
- throw Error(message);
550
- }
551
- }
552
-
553
- function getPercentageSizeFromMixedSizes({
554
- sizePercentage,
555
- sizePixels
556
- }, groupSizePixels) {
557
- if (sizePercentage != null) {
558
- return sizePercentage;
559
- } else if (sizePixels != null) {
560
- return convertPixelsToPercentage(sizePixels, groupSizePixels);
561
- }
562
- return undefined;
563
- }
564
-
565
468
  function getResizeHandleElementsForGroup(groupId) {
566
469
  return Array.from(document.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
567
470
  }
@@ -585,42 +488,6 @@ function getPanelGroupElement(id) {
585
488
  return null;
586
489
  }
587
490
 
588
- function calculateAvailablePanelSizeInPixels(groupId) {
589
- const panelGroupElement = getPanelGroupElement(groupId);
590
- if (panelGroupElement == null) {
591
- return NaN;
592
- }
593
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
594
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
595
- if (direction === "horizontal") {
596
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
597
- return accumulated + handle.offsetWidth;
598
- }, 0);
599
- } else {
600
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
601
- return accumulated + handle.offsetHeight;
602
- }, 0);
603
- }
604
- }
605
-
606
- function getAvailableGroupSizePixels(groupId) {
607
- const panelGroupElement = getPanelGroupElement(groupId);
608
- if (panelGroupElement == null) {
609
- return NaN;
610
- }
611
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
612
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
613
- if (direction === "horizontal") {
614
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
615
- return accumulated + handle.offsetWidth;
616
- }, 0);
617
- } else {
618
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
619
- return accumulated + handle.offsetHeight;
620
- }, 0);
621
- }
622
- }
623
-
624
491
  function getResizeHandleElement(id) {
625
492
  const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
626
493
  if (element) {
@@ -653,14 +520,18 @@ function useWindowSplitterPanelGroupBehavior({
653
520
  didWarnAboutMissingResizeHandle: false
654
521
  });
655
522
  useEffect(() => {
523
+ const eagerValues = eagerValuesRef.current;
524
+ assert(eagerValues);
656
525
  const {
657
526
  panelDataArray
658
- } = eagerValuesRef.current;
527
+ } = eagerValues;
659
528
  const groupElement = getPanelGroupElement(groupId);
660
529
  assert(groupElement != null, `No group found for id "${groupId}"`);
661
530
  const handles = getResizeHandleElementsForGroup(groupId);
531
+ assert(handles);
662
532
  const cleanupFunctions = handles.map(handle => {
663
533
  const handleId = handle.getAttribute("data-panel-resize-handle-id");
534
+ assert(handleId);
664
535
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
665
536
  if (idBefore == null || idAfter == null) {
666
537
  return () => {};
@@ -676,21 +547,16 @@ function useWindowSplitterPanelGroupBehavior({
676
547
  const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
677
548
  if (index >= 0) {
678
549
  const panelData = panelDataArray[index];
550
+ assert(panelData);
679
551
  const size = layout[index];
680
- if (size != null && panelData.constraints.collapsible) {
681
- var _getPercentageSizeFro, _getPercentageSizeFro2;
682
- const groupSizePixels = getAvailableGroupSizePixels(groupId);
683
- const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
684
- sizePercentage: panelData.constraints.collapsedSizePercentage,
685
- sizePixels: panelData.constraints.collapsedSizePixels
686
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
687
- const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
688
- sizePercentage: panelData.constraints.minSizePercentage,
689
- sizePixels: panelData.constraints.minSizePixels
690
- }, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
552
+ const {
553
+ collapsedSize = 0,
554
+ collapsible,
555
+ minSize = 0
556
+ } = panelData.constraints;
557
+ if (size != null && collapsible) {
691
558
  const nextLayout = adjustLayoutByDelta({
692
559
  delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
693
- groupSizePixels,
694
560
  layout,
695
561
  panelConstraints: panelDataArray.map(panelData => panelData.constraints),
696
562
  pivotIndices: determinePivotIndices(groupId, handleId),
@@ -744,6 +610,7 @@ function getResizeEventCursorPosition(direction, event) {
744
610
  return isHorizontal ? event.clientX : event.clientY;
745
611
  } else if (isTouchEvent(event)) {
746
612
  const firstTouch = event.touches[0];
613
+ assert(firstTouch);
747
614
  return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
748
615
  } else {
749
616
  throw Error(`Unsupported event type "${event.type}"`);
@@ -753,12 +620,15 @@ function getResizeEventCursorPosition(direction, event) {
753
620
  function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
754
621
  const isHorizontal = direction === "horizontal";
755
622
  const handleElement = getResizeHandleElement(dragHandleId);
623
+ assert(handleElement);
756
624
  const groupId = handleElement.getAttribute("data-panel-group-id");
625
+ assert(groupId);
757
626
  let {
758
627
  initialCursorPosition
759
628
  } = initialDragState;
760
629
  const cursorPosition = getResizeEventCursorPosition(direction, event);
761
630
  const groupElement = getPanelGroupElement(groupId);
631
+ assert(groupElement);
762
632
  const groupRect = groupElement.getBoundingClientRect();
763
633
  const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
764
634
  const offsetPixels = cursorPosition - initialCursorPosition;
@@ -767,19 +637,14 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
767
637
  }
768
638
 
769
639
  // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
770
- function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initialDragState, keyboardResizeByOptions) {
640
+ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
771
641
  if (isKeyDown(event)) {
772
642
  const isHorizontal = direction === "horizontal";
773
- const groupElement = getPanelGroupElement(groupId);
774
- const rect = groupElement.getBoundingClientRect();
775
- const groupSizeInPixels = isHorizontal ? rect.width : rect.height;
776
643
  let delta = 0;
777
644
  if (event.shiftKey) {
778
645
  delta = 100;
779
- } else if (keyboardResizeByOptions.percentage != null) {
780
- delta = keyboardResizeByOptions.percentage;
781
- } else if (keyboardResizeByOptions.pixels != null) {
782
- delta = keyboardResizeByOptions.pixels / groupSizeInPixels;
646
+ } else if (keyboardResizeBy != null) {
647
+ delta = keyboardResizeBy;
783
648
  } else {
784
649
  delta = 10;
785
650
  }
@@ -806,37 +671,43 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
806
671
  }
807
672
  return movement;
808
673
  } else {
674
+ if (initialDragState == null) {
675
+ return 0;
676
+ }
809
677
  return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
810
678
  }
811
679
  }
812
680
 
813
681
  function calculateUnsafeDefaultLayout({
814
- groupSizePixels,
815
682
  panelDataArray
816
683
  }) {
817
684
  const layout = Array(panelDataArray.length);
818
- const panelDataConstraints = panelDataArray.map(panelData => panelData.constraints);
685
+ const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
819
686
  let numPanelsWithSizes = 0;
820
687
  let remainingSize = 100;
821
688
 
822
689
  // Distribute default sizes first
823
690
  for (let index = 0; index < panelDataArray.length; index++) {
691
+ const panelConstraints = panelConstraintsArray[index];
692
+ assert(panelConstraints);
824
693
  const {
825
- defaultSizePercentage
826
- } = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
827
- if (defaultSizePercentage != null) {
694
+ defaultSize
695
+ } = panelConstraints;
696
+ if (defaultSize != null) {
828
697
  numPanelsWithSizes++;
829
- layout[index] = defaultSizePercentage;
830
- remainingSize -= defaultSizePercentage;
698
+ layout[index] = defaultSize;
699
+ remainingSize -= defaultSize;
831
700
  }
832
701
  }
833
702
 
834
703
  // Remaining size should be distributed evenly between panels without default sizes
835
704
  for (let index = 0; index < panelDataArray.length; index++) {
705
+ const panelConstraints = panelConstraintsArray[index];
706
+ assert(panelConstraints);
836
707
  const {
837
- defaultSizePercentage
838
- } = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
839
- if (defaultSizePercentage != null) {
708
+ defaultSize
709
+ } = panelConstraints;
710
+ if (defaultSize != null) {
840
711
  continue;
841
712
  }
842
713
  const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
@@ -848,54 +719,36 @@ function calculateUnsafeDefaultLayout({
848
719
  return layout;
849
720
  }
850
721
 
851
- function convertPercentageToPixels(percentage, groupSizePixels) {
852
- return percentage / 100 * groupSizePixels;
853
- }
854
-
855
722
  // Layout should be pre-converted into percentages
856
- function callPanelCallbacks(groupId, panelsArray, layout, panelIdToLastNotifiedMixedSizesMap) {
857
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
858
- layout.forEach((sizePercentage, index) => {
723
+ function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
724
+ layout.forEach((size, index) => {
859
725
  const panelData = panelsArray[index];
860
- if (!panelData) {
861
- // Handle initial mount (when panels are registered too late to be in the panels array)
862
- // The subsequent render+effects will handle the resize notification
863
- return;
864
- }
726
+ assert(panelData);
865
727
  const {
866
728
  callbacks,
867
729
  constraints,
868
730
  id: panelId
869
731
  } = panelData;
870
732
  const {
733
+ collapsedSize = 0,
871
734
  collapsible
872
735
  } = constraints;
873
- const mixedSizes = {
874
- sizePercentage,
875
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
876
- };
877
- const lastNotifiedMixedSizes = panelIdToLastNotifiedMixedSizesMap[panelId];
878
- if (lastNotifiedMixedSizes == null || mixedSizes.sizePercentage !== lastNotifiedMixedSizes.sizePercentage || mixedSizes.sizePixels !== lastNotifiedMixedSizes.sizePixels) {
879
- panelIdToLastNotifiedMixedSizesMap[panelId] = mixedSizes;
736
+ const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
737
+ if (lastNotifiedSize == null || size !== lastNotifiedSize) {
738
+ panelIdToLastNotifiedSizeMap[panelId] = size;
880
739
  const {
881
740
  onCollapse,
882
741
  onExpand,
883
742
  onResize
884
743
  } = callbacks;
885
744
  if (onResize) {
886
- onResize(mixedSizes, lastNotifiedMixedSizes);
745
+ onResize(size, lastNotifiedSize);
887
746
  }
888
747
  if (collapsible && (onCollapse || onExpand)) {
889
- var _getPercentageSizeFro;
890
- const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
891
- sizePercentage: constraints.collapsedSizePercentage,
892
- sizePixels: constraints.collapsedSizePixels
893
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
894
- const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
895
- if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
748
+ if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
896
749
  onExpand();
897
750
  }
898
- if (onCollapse && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage !== collapsedSize) && size === collapsedSize) {
751
+ if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
899
752
  onCollapse();
900
753
  }
901
754
  }
@@ -929,9 +782,10 @@ function computePanelFlexBoxStyle({
929
782
  const size = layout[panelIndex];
930
783
  let flexGrow;
931
784
  if (panelData.length === 1) {
932
- flexGrow = "100";
785
+ flexGrow = "1";
933
786
  } else if (size == null) {
934
- flexGrow = "0";
787
+ // Initial render (before panels have registered themselves)
788
+ flexGrow = "1";
935
789
  } else {
936
790
  flexGrow = size.toPrecision(precision);
937
791
  }
@@ -1077,74 +931,39 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
1077
931
  }
1078
932
  }
1079
933
 
1080
- function shouldMonitorPixelBasedConstraints(constraints) {
1081
- return constraints.some(constraints => {
1082
- return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
1083
- });
1084
- }
1085
-
1086
934
  function validatePanelConstraints({
1087
- groupSizePixels,
1088
- panelConstraints,
935
+ panelConstraints: panelConstraintsArray,
1089
936
  panelId,
1090
937
  panelIndex
1091
938
  }) {
1092
939
  {
1093
940
  const warnings = [];
1094
- {
1095
- const {
1096
- collapsedSizePercentage,
1097
- collapsedSizePixels,
1098
- defaultSizePercentage,
1099
- defaultSizePixels,
1100
- maxSizePercentage,
1101
- maxSizePixels,
1102
- minSizePercentage,
1103
- minSizePixels
1104
- } = panelConstraints[panelIndex];
1105
- const conflictingUnits = [];
1106
- if (collapsedSizePercentage != null && collapsedSizePixels != null) {
1107
- conflictingUnits.push("collapsed size");
1108
- }
1109
- if (defaultSizePercentage != null && defaultSizePixels != null) {
1110
- conflictingUnits.push("default size");
1111
- }
1112
- if (maxSizePercentage != null && maxSizePixels != null) {
1113
- conflictingUnits.push("max size");
1114
- }
1115
- if (minSizePercentage != null && minSizePixels != null) {
1116
- conflictingUnits.push("min size");
1117
- }
1118
- if (conflictingUnits.length > 0) {
1119
- warnings.push(`should not specify both percentage and pixel units for: ${conflictingUnits.join(", ")}`);
1120
- }
941
+ const panelConstraints = panelConstraintsArray[panelIndex];
942
+ assert(panelConstraints);
943
+ const {
944
+ collapsedSize = 0,
945
+ defaultSize,
946
+ maxSize = 100,
947
+ minSize = 0
948
+ } = panelConstraints;
949
+ if (minSize > maxSize) {
950
+ warnings.push(`min size (${minSize}%) should not be greater than max size (${maxSize}%)`);
1121
951
  }
1122
- {
1123
- const {
1124
- collapsedSizePercentage,
1125
- defaultSizePercentage,
1126
- maxSizePercentage,
1127
- minSizePercentage
1128
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
1129
- if (minSizePercentage > maxSizePercentage) {
1130
- warnings.push(`min size (${minSizePercentage}%) should not be greater than max size (${maxSizePercentage}%)`);
1131
- }
1132
- if (defaultSizePercentage != null) {
1133
- if (defaultSizePercentage < 0) {
1134
- warnings.push("default size should not be less than 0");
1135
- } else if (defaultSizePercentage < minSizePercentage) {
1136
- warnings.push("default size should not be less than min size");
1137
- }
1138
- if (defaultSizePercentage > 100) {
1139
- warnings.push("default size should not be greater than 100");
1140
- } else if (defaultSizePercentage > maxSizePercentage) {
1141
- warnings.push("default size should not be greater than max size");
1142
- }
952
+ if (defaultSize != null) {
953
+ if (defaultSize < 0) {
954
+ warnings.push("default size should not be less than 0");
955
+ } else if (defaultSize < minSize) {
956
+ warnings.push("default size should not be less than min size");
1143
957
  }
1144
- if (collapsedSizePercentage > minSizePercentage) {
1145
- warnings.push("collapsed size should not be greater than min size");
958
+ if (defaultSize > 100) {
959
+ warnings.push("default size should not be greater than 100");
960
+ } else if (defaultSize > maxSize) {
961
+ warnings.push("default size should not be greater than max size");
1146
962
  }
1147
963
  }
964
+ if (collapsedSize > minSize) {
965
+ warnings.push("collapsed size should not be greater than min size");
966
+ }
1148
967
  if (warnings.length > 0) {
1149
968
  const name = panelId != null ? `Panel "${panelId}"` : "Panel";
1150
969
  console.warn(`${name} has an invalid configuration:\n\n${warnings.join("\n")}`);
@@ -1156,20 +975,26 @@ function validatePanelConstraints({
1156
975
 
1157
976
  // All units must be in percentages; pixel values should be pre-converted
1158
977
  function validatePanelGroupLayout({
1159
- groupSizePixels,
1160
978
  layout: prevLayout,
1161
979
  panelConstraints
1162
980
  }) {
1163
981
  const nextLayout = [...prevLayout];
982
+ const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
1164
983
 
1165
984
  // Validate layout expectations
1166
985
  if (nextLayout.length !== panelConstraints.length) {
1167
986
  throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
1168
- } else if (!fuzzyNumbersEqual(nextLayout.reduce((accumulated, current) => accumulated + current, 0), 100)) {
987
+ } else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
1169
988
  // This is not ideal so we should warn about it, but it may be recoverable in some cases
1170
989
  // (especially if the amount is small)
1171
990
  {
1172
- console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}`);
991
+ console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}. Layout normalization will be applied.`);
992
+ }
993
+ for (let index = 0; index < panelConstraints.length; index++) {
994
+ const unsafeSize = nextLayout[index];
995
+ assert(unsafeSize != null);
996
+ const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
997
+ nextLayout[index] = safeSize;
1173
998
  }
1174
999
  }
1175
1000
  let remainingSize = 0;
@@ -1177,8 +1002,8 @@ function validatePanelGroupLayout({
1177
1002
  // First pass: Validate the proposed layout given each panel's constraints
1178
1003
  for (let index = 0; index < panelConstraints.length; index++) {
1179
1004
  const unsafeSize = nextLayout[index];
1005
+ assert(unsafeSize != null);
1180
1006
  const safeSize = resizePanel({
1181
- groupSizePixels,
1182
1007
  panelConstraints,
1183
1008
  panelIndex: index,
1184
1009
  size: unsafeSize
@@ -1194,9 +1019,9 @@ function validatePanelGroupLayout({
1194
1019
  if (!fuzzyNumbersEqual(remainingSize, 0)) {
1195
1020
  for (let index = 0; index < panelConstraints.length; index++) {
1196
1021
  const prevSize = nextLayout[index];
1022
+ assert(prevSize != null);
1197
1023
  const unsafeSize = prevSize + remainingSize;
1198
1024
  const safeSize = resizePanel({
1199
- groupSizePixels,
1200
1025
  panelConstraints,
1201
1026
  panelIndex: index,
1202
1027
  size: unsafeSize
@@ -1231,21 +1056,20 @@ function PanelGroupWithForwardedRef({
1231
1056
  autoSaveId = null,
1232
1057
  children,
1233
1058
  className: classNameFromProps = "",
1234
- dataAttributes,
1235
1059
  direction,
1236
1060
  forwardedRef,
1237
- id: idFromProps,
1061
+ id: idFromProps = null,
1238
1062
  onLayout = null,
1239
- keyboardResizeByPercentage = null,
1240
- keyboardResizeByPixels = null,
1063
+ keyboardResizeBy = null,
1241
1064
  storage = defaultStorage,
1242
1065
  style: styleFromProps,
1243
- tagName: Type = "div"
1066
+ tagName: Type = "div",
1067
+ ...rest
1244
1068
  }) {
1245
1069
  const groupId = useUniqueId(idFromProps);
1246
1070
  const [dragState, setDragState] = useState(null);
1247
1071
  const [layout, setLayout] = useState([]);
1248
- const panelIdToLastNotifiedMixedSizesMapRef = useRef({});
1072
+ const panelIdToLastNotifiedSizeMapRef = useRef({});
1249
1073
  const panelSizeBeforeCollapseRef = useRef(new Map());
1250
1074
  const prevDeltaRef = useRef(0);
1251
1075
  const committedValuesRef = useRef({
@@ -1253,8 +1077,7 @@ function PanelGroupWithForwardedRef({
1253
1077
  direction,
1254
1078
  dragState,
1255
1079
  id: groupId,
1256
- keyboardResizeByPercentage,
1257
- keyboardResizeByPixels,
1080
+ keyboardResizeBy,
1258
1081
  onLayout,
1259
1082
  storage
1260
1083
  });
@@ -1270,33 +1093,20 @@ function PanelGroupWithForwardedRef({
1270
1093
  useImperativeHandle(forwardedRef, () => ({
1271
1094
  getId: () => committedValuesRef.current.id,
1272
1095
  getLayout: () => {
1273
- const {
1274
- id: groupId
1275
- } = committedValuesRef.current;
1276
1096
  const {
1277
1097
  layout
1278
1098
  } = eagerValuesRef.current;
1279
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1280
- return layout.map(sizePercentage => {
1281
- return {
1282
- sizePercentage,
1283
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1284
- };
1285
- });
1099
+ return layout;
1286
1100
  },
1287
- setLayout: mixedSizes => {
1101
+ setLayout: unsafeLayout => {
1288
1102
  const {
1289
- id: groupId,
1290
1103
  onLayout
1291
1104
  } = committedValuesRef.current;
1292
1105
  const {
1293
1106
  layout: prevLayout,
1294
1107
  panelDataArray
1295
1108
  } = eagerValuesRef.current;
1296
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1297
- const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
1298
1109
  const safeLayout = validatePanelGroupLayout({
1299
- groupSizePixels,
1300
1110
  layout: unsafeLayout,
1301
1111
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1302
1112
  });
@@ -1304,16 +1114,12 @@ function PanelGroupWithForwardedRef({
1304
1114
  setLayout(safeLayout);
1305
1115
  eagerValuesRef.current.layout = safeLayout;
1306
1116
  if (onLayout) {
1307
- onLayout(safeLayout.map(sizePercentage => ({
1308
- sizePercentage,
1309
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1310
- })));
1117
+ onLayout(safeLayout);
1311
1118
  }
1312
- callPanelCallbacks(groupId, panelDataArray, safeLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1119
+ callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
1313
1120
  }
1314
1121
  }
1315
1122
  }), []);
1316
-
1317
1123
  useWindowSplitterPanelGroupBehavior({
1318
1124
  committedValuesRef,
1319
1125
  eagerValuesRef,
@@ -1332,12 +1138,14 @@ function PanelGroupWithForwardedRef({
1332
1138
  if (layout.length === 0 || layout.length !== panelDataArray.length) {
1333
1139
  return;
1334
1140
  }
1141
+ let debouncedSave = debounceMap[autoSaveId];
1335
1142
 
1336
1143
  // Limit the frequency of localStorage updates.
1337
- if (!debounceMap[autoSaveId]) {
1338
- debounceMap[autoSaveId] = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1144
+ if (debouncedSave == null) {
1145
+ debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1146
+ debounceMap[autoSaveId] = debouncedSave;
1339
1147
  }
1340
- debounceMap[autoSaveId](autoSaveId, panelDataArray, layout, storage);
1148
+ debouncedSave(autoSaveId, panelDataArray, layout, storage);
1341
1149
  }
1342
1150
  }, [autoSaveId, layout, storage]);
1343
1151
 
@@ -1370,12 +1178,12 @@ function PanelGroupWithForwardedRef({
1370
1178
  }
1371
1179
  if (!didLogPanelConstraintsWarning) {
1372
1180
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1373
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1374
1181
  for (let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++) {
1182
+ const panelData = panelDataArray[panelIndex];
1183
+ assert(panelData);
1375
1184
  const isValid = validatePanelConstraints({
1376
- groupSizePixels,
1377
1185
  panelConstraints,
1378
- panelId: panelDataArray[panelIndex].id,
1186
+ panelId: panelData.id,
1379
1187
  panelIndex
1380
1188
  });
1381
1189
  if (!isValid) {
@@ -1399,20 +1207,19 @@ function PanelGroupWithForwardedRef({
1399
1207
  if (panelData.constraints.collapsible) {
1400
1208
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1401
1209
  const {
1402
- collapsedSizePercentage,
1403
- panelSizePercentage,
1404
- pivotIndices,
1405
- groupSizePixels
1406
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1407
- if (panelSizePercentage !== collapsedSizePercentage) {
1210
+ collapsedSize = 0,
1211
+ panelSize,
1212
+ pivotIndices
1213
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1214
+ assert(panelSize != null);
1215
+ if (panelSize !== collapsedSize) {
1408
1216
  // Store size before collapse;
1409
1217
  // This is the size that gets restored if the expand() API is used.
1410
- panelSizeBeforeCollapseRef.current.set(panelData.id, panelSizePercentage);
1218
+ panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1411
1219
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1412
- const delta = isLastPanel ? panelSizePercentage - collapsedSizePercentage : collapsedSizePercentage - panelSizePercentage;
1220
+ const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1413
1221
  const nextLayout = adjustLayoutByDelta({
1414
1222
  delta,
1415
- groupSizePixels,
1416
1223
  layout: prevLayout,
1417
1224
  panelConstraints: panelConstraintsArray,
1418
1225
  pivotIndices,
@@ -1422,16 +1229,13 @@ function PanelGroupWithForwardedRef({
1422
1229
  setLayout(nextLayout);
1423
1230
  eagerValuesRef.current.layout = nextLayout;
1424
1231
  if (onLayout) {
1425
- onLayout(nextLayout.map(sizePercentage => ({
1426
- sizePercentage,
1427
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1428
- })));
1232
+ onLayout(nextLayout);
1429
1233
  }
1430
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1234
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1431
1235
  }
1432
1236
  }
1433
1237
  }
1434
- }, [groupId]);
1238
+ }, []);
1435
1239
 
1436
1240
  // External APIs are safe to memoize via committed values ref
1437
1241
  const expandPanel = useCallback(panelData => {
@@ -1445,21 +1249,19 @@ function PanelGroupWithForwardedRef({
1445
1249
  if (panelData.constraints.collapsible) {
1446
1250
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1447
1251
  const {
1448
- collapsedSizePercentage,
1449
- panelSizePercentage,
1450
- minSizePercentage,
1451
- pivotIndices,
1452
- groupSizePixels
1453
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1454
- if (panelSizePercentage === collapsedSizePercentage) {
1252
+ collapsedSize = 0,
1253
+ panelSize,
1254
+ minSize = 0,
1255
+ pivotIndices
1256
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1257
+ if (panelSize === collapsedSize) {
1455
1258
  // Restore this panel to the size it was before it was collapsed, if possible.
1456
- const prevPanelSizePercentage = panelSizeBeforeCollapseRef.current.get(panelData.id);
1457
- const baseSizePercentage = prevPanelSizePercentage != null && prevPanelSizePercentage >= minSizePercentage ? prevPanelSizePercentage : minSizePercentage;
1259
+ const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1260
+ const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1458
1261
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1459
- const delta = isLastPanel ? panelSizePercentage - baseSizePercentage : baseSizePercentage - panelSizePercentage;
1262
+ const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1460
1263
  const nextLayout = adjustLayoutByDelta({
1461
1264
  delta,
1462
- groupSizePixels,
1463
1265
  layout: prevLayout,
1464
1266
  panelConstraints: panelConstraintsArray,
1465
1267
  pivotIndices,
@@ -1469,16 +1271,13 @@ function PanelGroupWithForwardedRef({
1469
1271
  setLayout(nextLayout);
1470
1272
  eagerValuesRef.current.layout = nextLayout;
1471
1273
  if (onLayout) {
1472
- onLayout(nextLayout.map(sizePercentage => ({
1473
- sizePercentage,
1474
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1475
- })));
1274
+ onLayout(nextLayout);
1476
1275
  }
1477
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1276
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1478
1277
  }
1479
1278
  }
1480
1279
  }
1481
- }, [groupId]);
1280
+ }, []);
1482
1281
 
1483
1282
  // External APIs are safe to memoize via committed values ref
1484
1283
  const getPanelSize = useCallback(panelData => {
@@ -1487,14 +1286,11 @@ function PanelGroupWithForwardedRef({
1487
1286
  panelDataArray
1488
1287
  } = eagerValuesRef.current;
1489
1288
  const {
1490
- panelSizePercentage,
1491
- panelSizePixels
1492
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1493
- return {
1494
- sizePercentage: panelSizePercentage,
1495
- sizePixels: panelSizePixels
1496
- };
1497
- }, [groupId]);
1289
+ panelSize
1290
+ } = panelDataHelper(panelDataArray, panelData, layout);
1291
+ assert(panelSize != null);
1292
+ return panelSize;
1293
+ }, []);
1498
1294
 
1499
1295
  // This API should never read from committedValuesRef
1500
1296
  const getPanelStyle = useCallback(panelData => {
@@ -1517,12 +1313,12 @@ function PanelGroupWithForwardedRef({
1517
1313
  panelDataArray
1518
1314
  } = eagerValuesRef.current;
1519
1315
  const {
1520
- collapsedSizePercentage,
1316
+ collapsedSize,
1521
1317
  collapsible,
1522
- panelSizePercentage
1523
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1524
- return collapsible === true && panelSizePercentage === collapsedSizePercentage;
1525
- }, [groupId]);
1318
+ panelSize
1319
+ } = panelDataHelper(panelDataArray, panelData, layout);
1320
+ return collapsible === true && panelSize === collapsedSize;
1321
+ }, []);
1526
1322
 
1527
1323
  // External APIs are safe to memoize via committed values ref
1528
1324
  const isPanelExpanded = useCallback(panelData => {
@@ -1531,12 +1327,13 @@ function PanelGroupWithForwardedRef({
1531
1327
  panelDataArray
1532
1328
  } = eagerValuesRef.current;
1533
1329
  const {
1534
- collapsedSizePercentage,
1330
+ collapsedSize = 0,
1535
1331
  collapsible,
1536
- panelSizePercentage
1537
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1538
- return !collapsible || panelSizePercentage > collapsedSizePercentage;
1539
- }, [groupId]);
1332
+ panelSize
1333
+ } = panelDataHelper(panelDataArray, panelData, layout);
1334
+ assert(panelSize != null);
1335
+ return !collapsible || panelSize > collapsedSize;
1336
+ }, []);
1540
1337
  const registerPanel = useCallback(panelData => {
1541
1338
  const {
1542
1339
  autoSaveId,
@@ -1576,18 +1373,8 @@ function PanelGroupWithForwardedRef({
1576
1373
  if (autoSaveId) {
1577
1374
  unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1578
1375
  }
1579
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1580
- if (groupSizePixels <= 0) {
1581
- if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
1582
- constraints
1583
- }) => constraints))) {
1584
- // Wait until the group has rendered a non-zero size before computing layout.
1585
- return;
1586
- }
1587
- }
1588
1376
  if (unsafeLayout == null) {
1589
1377
  unsafeLayout = calculateUnsafeDefaultLayout({
1590
- groupSizePixels,
1591
1378
  panelDataArray
1592
1379
  });
1593
1380
  }
@@ -1595,7 +1382,6 @@ function PanelGroupWithForwardedRef({
1595
1382
  // Validate even saved layouts in case something has changed since last render
1596
1383
  // e.g. for pixel groups, this could be the size of the window
1597
1384
  const nextLayout = validatePanelGroupLayout({
1598
- groupSizePixels,
1599
1385
  layout: unsafeLayout,
1600
1386
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1601
1387
  });
@@ -1607,12 +1393,9 @@ function PanelGroupWithForwardedRef({
1607
1393
  eagerValuesRef.current.layout = nextLayout;
1608
1394
  if (!areEqual(prevLayout, nextLayout)) {
1609
1395
  if (onLayout) {
1610
- onLayout(nextLayout.map(sizePercentage => ({
1611
- sizePercentage,
1612
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1613
- })));
1396
+ onLayout(nextLayout);
1614
1397
  }
1615
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1398
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1616
1399
  }
1617
1400
  }, []);
1618
1401
  const registerResizeHandle = useCallback(dragHandleId => {
@@ -1622,8 +1405,7 @@ function PanelGroupWithForwardedRef({
1622
1405
  direction,
1623
1406
  dragState,
1624
1407
  id: groupId,
1625
- keyboardResizeByPercentage,
1626
- keyboardResizeByPixels,
1408
+ keyboardResizeBy,
1627
1409
  onLayout
1628
1410
  } = committedValuesRef.current;
1629
1411
  const {
@@ -1634,10 +1416,7 @@ function PanelGroupWithForwardedRef({
1634
1416
  initialLayout
1635
1417
  } = dragState !== null && dragState !== void 0 ? dragState : {};
1636
1418
  const pivotIndices = determinePivotIndices(groupId, dragHandleId);
1637
- let delta = calculateDeltaPercentage(event, groupId, dragHandleId, direction, dragState, {
1638
- percentage: keyboardResizeByPercentage,
1639
- pixels: keyboardResizeByPixels
1640
- });
1419
+ let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
1641
1420
  if (delta === 0) {
1642
1421
  return;
1643
1422
  }
@@ -1647,11 +1426,9 @@ function PanelGroupWithForwardedRef({
1647
1426
  if (document.dir === "rtl" && isHorizontal) {
1648
1427
  delta = -delta;
1649
1428
  }
1650
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1651
1429
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1652
1430
  const nextLayout = adjustLayoutByDelta({
1653
1431
  delta,
1654
- groupSizePixels,
1655
1432
  layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
1656
1433
  panelConstraints,
1657
1434
  pivotIndices,
@@ -1687,18 +1464,15 @@ function PanelGroupWithForwardedRef({
1687
1464
  setLayout(nextLayout);
1688
1465
  eagerValuesRef.current.layout = nextLayout;
1689
1466
  if (onLayout) {
1690
- onLayout(nextLayout.map(sizePercentage => ({
1691
- sizePercentage,
1692
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1693
- })));
1467
+ onLayout(nextLayout);
1694
1468
  }
1695
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1469
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1696
1470
  }
1697
1471
  };
1698
1472
  }, []);
1699
1473
 
1700
1474
  // External APIs are safe to memoize via committed values ref
1701
- const resizePanel = useCallback((panelData, mixedSizes) => {
1475
+ const resizePanel = useCallback((panelData, unsafePanelSize) => {
1702
1476
  const {
1703
1477
  onLayout
1704
1478
  } = committedValuesRef.current;
@@ -1708,16 +1482,14 @@ function PanelGroupWithForwardedRef({
1708
1482
  } = eagerValuesRef.current;
1709
1483
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1710
1484
  const {
1711
- groupSizePixels,
1712
- panelSizePercentage,
1485
+ panelSize,
1713
1486
  pivotIndices
1714
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1715
- const sizePercentage = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
1487
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1488
+ assert(panelSize != null);
1716
1489
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1717
- const delta = isLastPanel ? panelSizePercentage - sizePercentage : sizePercentage - panelSizePercentage;
1490
+ const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1718
1491
  const nextLayout = adjustLayoutByDelta({
1719
1492
  delta,
1720
- groupSizePixels,
1721
1493
  layout: prevLayout,
1722
1494
  panelConstraints: panelConstraintsArray,
1723
1495
  pivotIndices,
@@ -1727,14 +1499,11 @@ function PanelGroupWithForwardedRef({
1727
1499
  setLayout(nextLayout);
1728
1500
  eagerValuesRef.current.layout = nextLayout;
1729
1501
  if (onLayout) {
1730
- onLayout(nextLayout.map(sizePercentage => ({
1731
- sizePercentage,
1732
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1733
- })));
1502
+ onLayout(nextLayout);
1734
1503
  }
1735
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1504
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1736
1505
  }
1737
- }, [groupId]);
1506
+ }, []);
1738
1507
  const startDragging = useCallback((dragHandleId, event) => {
1739
1508
  const {
1740
1509
  direction
@@ -1743,6 +1512,7 @@ function PanelGroupWithForwardedRef({
1743
1512
  layout
1744
1513
  } = eagerValuesRef.current;
1745
1514
  const handleElement = getResizeHandleElement(dragHandleId);
1515
+ assert(handleElement);
1746
1516
  const initialCursorPosition = getResizeEventCursorPosition(direction, event);
1747
1517
  setDragState({
1748
1518
  dragHandleId,
@@ -1761,7 +1531,6 @@ function PanelGroupWithForwardedRef({
1761
1531
  });
1762
1532
  const unregisterPanel = useCallback(panelData => {
1763
1533
  const {
1764
- id: groupId,
1765
1534
  onLayout
1766
1535
  } = committedValuesRef.current;
1767
1536
  const {
@@ -1784,7 +1553,7 @@ function PanelGroupWithForwardedRef({
1784
1553
  const {
1785
1554
  pendingPanelIds
1786
1555
  } = unregisterPanelRef.current;
1787
- const map = panelIdToLastNotifiedMixedSizesMapRef.current;
1556
+ const map = panelIdToLastNotifiedSizeMapRef.current;
1788
1557
 
1789
1558
  // TRICKY
1790
1559
  // Strict effects mode
@@ -1810,16 +1579,13 @@ function PanelGroupWithForwardedRef({
1810
1579
  // The group is unmounting; skip layout calculation.
1811
1580
  return;
1812
1581
  }
1813
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1814
1582
  let unsafeLayout = calculateUnsafeDefaultLayout({
1815
- groupSizePixels,
1816
1583
  panelDataArray
1817
1584
  });
1818
1585
 
1819
1586
  // Validate even saved layouts in case something has changed since last render
1820
1587
  // e.g. for pixel groups, this could be the size of the window
1821
1588
  const nextLayout = validatePanelGroupLayout({
1822
- groupSizePixels,
1823
1589
  layout: unsafeLayout,
1824
1590
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1825
1591
  });
@@ -1827,12 +1593,9 @@ function PanelGroupWithForwardedRef({
1827
1593
  setLayout(nextLayout);
1828
1594
  eagerValuesRef.current.layout = nextLayout;
1829
1595
  if (onLayout) {
1830
- onLayout(nextLayout.map(sizePercentage => ({
1831
- sizePercentage,
1832
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1833
- })));
1596
+ onLayout(nextLayout);
1834
1597
  }
1835
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1598
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1836
1599
  }
1837
1600
  }, 0);
1838
1601
  }, []);
@@ -1863,13 +1626,13 @@ function PanelGroupWithForwardedRef({
1863
1626
  return createElement(PanelGroupContext.Provider, {
1864
1627
  value: context
1865
1628
  }, createElement(Type, {
1629
+ ...rest,
1866
1630
  children,
1867
1631
  className: classNameFromProps,
1868
1632
  style: {
1869
1633
  ...style,
1870
1634
  ...styleFromProps
1871
1635
  },
1872
- ...dataAttributes,
1873
1636
  // CSS selectors
1874
1637
  "data-panel-group": "",
1875
1638
  "data-panel-group-direction": direction,
@@ -1882,22 +1645,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1882
1645
  }));
1883
1646
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1884
1647
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1885
- function panelDataHelper(groupId, panelDataArray, panelData, layout) {
1648
+ function panelDataHelper(panelDataArray, panelData, layout) {
1886
1649
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1887
1650
  const panelIndex = panelDataArray.indexOf(panelData);
1888
1651
  const panelConstraints = panelConstraintsArray[panelIndex];
1889
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1890
- const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
1891
1652
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1892
1653
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
1893
- const panelSizePercentage = layout[panelIndex];
1894
- const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
1654
+ const panelSize = layout[panelIndex];
1895
1655
  return {
1896
- ...percentagePanelConstraints,
1897
- collapsible: panelConstraints.collapsible,
1898
- panelSizePercentage,
1899
- panelSizePixels,
1900
- groupSizePixels,
1656
+ ...panelConstraints,
1657
+ panelSize,
1901
1658
  pivotIndices
1902
1659
  };
1903
1660
  }
@@ -1937,6 +1694,7 @@ function useWindowSplitterResizeHandlerBehavior({
1937
1694
  {
1938
1695
  event.preventDefault();
1939
1696
  const groupId = handleElement.getAttribute("data-panel-group-id");
1697
+ assert(groupId);
1940
1698
  const handles = getResizeHandleElementsForGroup(groupId);
1941
1699
  const index = getResizeHandleElementIndex(groupId, handleId);
1942
1700
  assert(index !== null);
@@ -1957,12 +1715,13 @@ function useWindowSplitterResizeHandlerBehavior({
1957
1715
  function PanelResizeHandle({
1958
1716
  children = null,
1959
1717
  className: classNameFromProps = "",
1960
- dataAttributes,
1961
1718
  disabled = false,
1962
- id: idFromProps = null,
1719
+ id: idFromProps,
1963
1720
  onDragging,
1964
1721
  style: styleFromProps = {},
1965
- tagName: Type = "div"
1722
+ tabIndex = 0,
1723
+ tagName: Type = "div",
1724
+ ...rest
1966
1725
  }) {
1967
1726
  const divElementRef = useRef(null);
1968
1727
 
@@ -1992,8 +1751,9 @@ function PanelResizeHandle({
1992
1751
  const stopDraggingAndBlur = useCallback(() => {
1993
1752
  // Clicking on the drag handle shouldn't leave it focused;
1994
1753
  // That would cause the PanelGroup to think it was still active.
1995
- const div = divElementRef.current;
1996
- div.blur();
1754
+ const divElement = divElementRef.current;
1755
+ assert(divElement);
1756
+ divElement.blur();
1997
1757
  stopDragging();
1998
1758
  const {
1999
1759
  onDragging
@@ -2021,6 +1781,7 @@ function PanelResizeHandle({
2021
1781
  resizeHandler(event);
2022
1782
  };
2023
1783
  const divElement = divElementRef.current;
1784
+ assert(divElement);
2024
1785
  const targetDocument = divElement.ownerDocument;
2025
1786
  targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
2026
1787
  targetDocument.body.addEventListener("mousemove", onMove);
@@ -2048,15 +1809,18 @@ function PanelResizeHandle({
2048
1809
  userSelect: "none"
2049
1810
  };
2050
1811
  return createElement(Type, {
1812
+ ...rest,
2051
1813
  children,
2052
1814
  className: classNameFromProps,
2053
1815
  onBlur: () => setIsFocused(false),
2054
1816
  onFocus: () => setIsFocused(true),
2055
1817
  onMouseDown: event => {
2056
1818
  startDragging(resizeHandleId, event.nativeEvent);
1819
+ const callbacks = callbacksRef.current;
1820
+ assert(callbacks);
2057
1821
  const {
2058
1822
  onDragging
2059
- } = callbacksRef.current;
1823
+ } = callbacks;
2060
1824
  if (onDragging) {
2061
1825
  onDragging(true);
2062
1826
  }
@@ -2066,9 +1830,11 @@ function PanelResizeHandle({
2066
1830
  onTouchEnd: stopDraggingAndBlur,
2067
1831
  onTouchStart: event => {
2068
1832
  startDragging(resizeHandleId, event.nativeEvent);
1833
+ const callbacks = callbacksRef.current;
1834
+ assert(callbacks);
2069
1835
  const {
2070
1836
  onDragging
2071
- } = callbacksRef.current;
1837
+ } = callbacks;
2072
1838
  if (onDragging) {
2073
1839
  onDragging(true);
2074
1840
  }
@@ -2079,8 +1845,7 @@ function PanelResizeHandle({
2079
1845
  ...style,
2080
1846
  ...styleFromProps
2081
1847
  },
2082
- tabIndex: 0,
2083
- ...dataAttributes,
1848
+ tabIndex,
2084
1849
  // CSS selectors
2085
1850
  "data-panel-group-direction": direction,
2086
1851
  "data-panel-group-id": groupId,
@@ -2095,3 +1860,4 @@ PanelResizeHandle.displayName = "PanelResizeHandle";
2095
1860
  exports.Panel = Panel;
2096
1861
  exports.PanelGroup = PanelGroup;
2097
1862
  exports.PanelResizeHandle = PanelResizeHandle;
1863
+ exports.assert = assert;