react-resizable-panels 0.0.63 → 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 (72) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/CHANGELOG.md +5 -0
  3. package/dist/declarations/src/Panel.d.ts +19 -34
  4. package/dist/declarations/src/PanelGroup.d.ts +9 -13
  5. package/dist/declarations/src/PanelResizeHandle.d.ts +5 -7
  6. package/dist/declarations/src/index.d.ts +2 -2
  7. package/dist/declarations/src/types.d.ts +0 -7
  8. package/dist/declarations/src/utils/assert.d.ts +1 -0
  9. package/dist/declarations/src/vendor/react.d.ts +2 -2
  10. package/dist/react-resizable-panels.browser.cjs.js +252 -517
  11. package/dist/react-resizable-panels.browser.cjs.mjs +2 -1
  12. package/dist/react-resizable-panels.browser.development.cjs.js +278 -573
  13. package/dist/react-resizable-panels.browser.development.cjs.mjs +2 -1
  14. package/dist/react-resizable-panels.browser.development.esm.js +278 -574
  15. package/dist/react-resizable-panels.browser.esm.js +252 -518
  16. package/dist/react-resizable-panels.cjs.js +252 -517
  17. package/dist/react-resizable-panels.cjs.js.map +1 -1
  18. package/dist/react-resizable-panels.cjs.mjs +2 -1
  19. package/dist/react-resizable-panels.development.cjs.js +280 -575
  20. package/dist/react-resizable-panels.development.cjs.mjs +2 -1
  21. package/dist/react-resizable-panels.development.esm.js +280 -576
  22. package/dist/react-resizable-panels.development.node.cjs.js +266 -501
  23. package/dist/react-resizable-panels.development.node.cjs.mjs +2 -1
  24. package/dist/react-resizable-panels.development.node.esm.js +266 -502
  25. package/dist/react-resizable-panels.esm.js +252 -518
  26. package/dist/react-resizable-panels.esm.js.map +1 -1
  27. package/dist/react-resizable-panels.node.cjs.js +238 -443
  28. package/dist/react-resizable-panels.node.cjs.mjs +2 -1
  29. package/dist/react-resizable-panels.node.esm.js +238 -444
  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/getResizeEventCursorPosition.ts +2 -0
  53. package/src/utils/resizePanel.test.ts +6 -52
  54. package/src/utils/resizePanel.ts +24 -46
  55. package/src/utils/test-utils.ts +6 -7
  56. package/src/utils/validatePanelConstraints.test.ts +12 -65
  57. package/src/utils/validatePanelConstraints.ts +26 -67
  58. package/src/utils/validatePanelGroupLayout.test.ts +27 -142
  59. package/src/utils/validatePanelGroupLayout.ts +17 -13
  60. package/src/vendor/react.ts +2 -0
  61. package/src/utils/computePercentagePanelConstraints.test.ts +0 -98
  62. package/src/utils/computePercentagePanelConstraints.ts +0 -56
  63. package/src/utils/convertPercentageToPixels.test.ts +0 -9
  64. package/src/utils/convertPercentageToPixels.ts +0 -6
  65. package/src/utils/convertPixelConstraintsToPercentages.test.ts +0 -47
  66. package/src/utils/convertPixelConstraintsToPercentages.ts +0 -72
  67. package/src/utils/convertPixelsToPercentage.test.ts +0 -9
  68. package/src/utils/convertPixelsToPercentage.ts +0 -6
  69. package/src/utils/getPercentageSizeFromMixedSizes.test.ts +0 -47
  70. package/src/utils/getPercentageSizeFromMixedSizes.ts +0 -15
  71. package/src/utils/shouldMonitorPixelBasedConstraints.test.ts +0 -23
  72. package/src/utils/shouldMonitorPixelBasedConstraints.ts +0 -13
@@ -43,24 +43,20 @@ function useUniqueId(idFromParams = null) {
43
43
  function PanelWithForwardedRef({
44
44
  children,
45
45
  className: classNameFromProps = "",
46
- collapsedSizePercentage,
47
- collapsedSizePixels,
46
+ collapsedSize,
48
47
  collapsible,
49
- dataAttributes,
50
- defaultSizePercentage,
51
- defaultSizePixels,
48
+ defaultSize,
52
49
  forwardedRef,
53
50
  id: idFromProps,
54
- maxSizePercentage,
55
- maxSizePixels,
56
- minSizePercentage,
57
- minSizePixels,
51
+ maxSize,
52
+ minSize,
58
53
  onCollapse,
59
54
  onExpand,
60
55
  onResize,
61
56
  order,
62
57
  style: styleFromProps,
63
- tagName: Type = "div"
58
+ tagName: Type = "div",
59
+ ...rest
64
60
  }) {
65
61
  const context = useContext(PanelGroupContext);
66
62
  if (context === null) {
@@ -85,15 +81,11 @@ function PanelWithForwardedRef({
85
81
  onResize
86
82
  },
87
83
  constraints: {
88
- collapsedSizePercentage,
89
- collapsedSizePixels,
84
+ collapsedSize,
90
85
  collapsible,
91
- defaultSizePercentage,
92
- defaultSizePixels,
93
- maxSizePercentage,
94
- maxSizePixels,
95
- minSizePercentage,
96
- minSizePixels
86
+ defaultSize,
87
+ maxSize,
88
+ minSize
97
89
  },
98
90
  id: panelId,
99
91
  idIsFromProps: idFromProps !== undefined,
@@ -113,15 +105,11 @@ function PanelWithForwardedRef({
113
105
  callbacks.onCollapse = onCollapse;
114
106
  callbacks.onExpand = onExpand;
115
107
  callbacks.onResize = onResize;
116
- constraints.collapsedSizePercentage = collapsedSizePercentage;
117
- constraints.collapsedSizePixels = collapsedSizePixels;
108
+ constraints.collapsedSize = collapsedSize;
118
109
  constraints.collapsible = collapsible;
119
- constraints.defaultSizePercentage = defaultSizePercentage;
120
- constraints.defaultSizePixels = defaultSizePixels;
121
- constraints.maxSizePercentage = maxSizePercentage;
122
- constraints.maxSizePixels = maxSizePixels;
123
- constraints.minSizePercentage = minSizePercentage;
124
- constraints.minSizePixels = minSizePixels;
110
+ constraints.defaultSize = defaultSize;
111
+ constraints.maxSize = maxSize;
112
+ constraints.minSize = minSize;
125
113
  });
126
114
  useIsomorphicLayoutEffect(() => {
127
115
  const panelData = panelDataRef.current;
@@ -149,19 +137,19 @@ function PanelWithForwardedRef({
149
137
  isExpanded() {
150
138
  return !isPanelCollapsed(panelDataRef.current);
151
139
  },
152
- resize: mixedSizes => {
153
- resizePanel(panelDataRef.current, mixedSizes);
140
+ resize: size => {
141
+ resizePanel(panelDataRef.current, size);
154
142
  }
155
143
  }), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
156
144
  const style = getPanelStyle(panelDataRef.current);
157
145
  return createElement(Type, {
146
+ ...rest,
158
147
  children,
159
148
  className: classNameFromProps,
160
149
  style: {
161
150
  ...style,
162
151
  ...styleFromProps
163
152
  },
164
- ...dataAttributes,
165
153
  // CSS selectors
166
154
  "data-panel": "",
167
155
  "data-panel-id": panelId,
@@ -178,81 +166,11 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
178
166
  PanelWithForwardedRef.displayName = "Panel";
179
167
  Panel.displayName = "forwardRef(Panel)";
180
168
 
181
- function convertPixelsToPercentage(pixels, groupSizePixels) {
182
- return pixels / groupSizePixels * 100;
183
- }
184
-
185
- function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels) {
186
- let {
187
- collapsedSizePercentage = 0,
188
- collapsedSizePixels,
189
- defaultSizePercentage,
190
- defaultSizePixels,
191
- maxSizePercentage = 100,
192
- maxSizePixels,
193
- minSizePercentage = 0,
194
- minSizePixels
195
- } = panelConstraints;
196
- const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
197
- if (hasPixelConstraints && groupSizePixels <= 0) {
198
- console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
199
- return {
200
- collapsedSizePercentage: 0,
201
- defaultSizePercentage,
202
- maxSizePercentage: 0,
203
- minSizePercentage: 0
204
- };
205
- }
206
- if (collapsedSizePixels != null) {
207
- collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
208
- }
209
- if (defaultSizePixels != null) {
210
- defaultSizePercentage = convertPixelsToPercentage(defaultSizePixels, groupSizePixels);
211
- }
212
- if (minSizePixels != null) {
213
- minSizePercentage = convertPixelsToPercentage(minSizePixels, groupSizePixels);
214
- }
215
- if (maxSizePixels != null) {
216
- maxSizePercentage = convertPixelsToPercentage(maxSizePixels, groupSizePixels);
217
- }
218
- return {
219
- collapsedSizePercentage,
220
- defaultSizePercentage,
221
- maxSizePercentage,
222
- minSizePercentage
223
- };
224
- }
225
-
226
- function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels) {
227
- // All panel constraints, excluding the current one
228
- let totalMinConstraints = 0;
229
- let totalMaxConstraints = 0;
230
- for (let index = 0; index < panelConstraintsArray.length; index++) {
231
- if (index !== panelIndex) {
232
- const {
233
- collapsible
234
- } = panelConstraintsArray[index];
235
- const {
236
- collapsedSizePercentage,
237
- maxSizePercentage,
238
- minSizePercentage
239
- } = convertPixelConstraintsToPercentages(panelConstraintsArray[index], groupSizePixels);
240
- totalMaxConstraints += maxSizePercentage;
241
- totalMinConstraints += collapsible ? collapsedSizePercentage : minSizePercentage;
242
- }
169
+ function assert(expectedCondition, message = "Assertion failed!") {
170
+ if (!expectedCondition) {
171
+ console.error(message);
172
+ throw Error(message);
243
173
  }
244
- const {
245
- collapsedSizePercentage,
246
- defaultSizePercentage,
247
- maxSizePercentage,
248
- minSizePercentage
249
- } = convertPixelConstraintsToPercentages(panelConstraintsArray[panelIndex], groupSizePixels);
250
- return {
251
- collapsedSizePercentage,
252
- defaultSizePercentage,
253
- maxSizePercentage: panelConstraintsArray.length > 1 ? Math.min(maxSizePercentage, 100 - totalMinConstraints) : maxSizePercentage,
254
- minSizePercentage: panelConstraintsArray.length > 1 ? Math.max(minSizePercentage, 100 - totalMaxConstraints) : minSizePercentage
255
- };
256
174
  }
257
175
 
258
176
  const PRECISION = 10;
@@ -274,56 +192,41 @@ function fuzzyNumbersEqual(actual, expected, fractionDigits) {
274
192
 
275
193
  // Panel size must be in percentages; pixel values should be pre-converted
276
194
  function resizePanel({
277
- groupSizePixels,
278
- panelConstraints,
195
+ panelConstraints: panelConstraintsArray,
279
196
  panelIndex,
280
197
  size
281
198
  }) {
282
- const hasPixelConstraints = panelConstraints.some(({
283
- collapsedSizePixels,
284
- defaultSizePixels,
285
- minSizePixels,
286
- maxSizePixels
287
- }) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
288
- if (hasPixelConstraints && groupSizePixels <= 0) {
289
- console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
290
- return 0;
291
- }
199
+ const panelConstraints = panelConstraintsArray[panelIndex];
200
+ assert(panelConstraints != null);
292
201
  let {
293
- collapsible
294
- } = panelConstraints[panelIndex];
295
- const {
296
- collapsedSizePercentage,
297
- maxSizePercentage,
298
- minSizePercentage
299
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
300
- if (minSizePercentage != null) {
301
- if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
302
- if (collapsible) {
303
- // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
304
- const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
305
- if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
306
- size = collapsedSizePercentage;
307
- } else {
308
- size = minSizePercentage;
309
- }
202
+ collapsedSize = 0,
203
+ collapsible,
204
+ maxSize = 100,
205
+ minSize = 0
206
+ } = panelConstraints;
207
+ if (fuzzyCompareNumbers(size, minSize) < 0) {
208
+ if (collapsible) {
209
+ // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
210
+ const halfwayPoint = (collapsedSize + minSize) / 2;
211
+ if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
212
+ size = collapsedSize;
310
213
  } else {
311
- size = minSizePercentage;
214
+ size = minSize;
312
215
  }
216
+ } else {
217
+ size = minSize;
313
218
  }
314
219
  }
315
- if (maxSizePercentage != null) {
316
- size = Math.min(maxSizePercentage, size);
317
- }
220
+ size = Math.min(maxSize, size);
221
+ size = parseFloat(size.toFixed(PRECISION));
318
222
  return size;
319
223
  }
320
224
 
321
225
  // All units must be in percentages; pixel values should be pre-converted
322
226
  function adjustLayoutByDelta({
323
227
  delta,
324
- groupSizePixels,
325
228
  layout: prevLayout,
326
- panelConstraints,
229
+ panelConstraints: panelConstraintsArray,
327
230
  pivotIndices,
328
231
  trigger
329
232
  }) {
@@ -331,6 +234,9 @@ function adjustLayoutByDelta({
331
234
  return prevLayout;
332
235
  }
333
236
  const nextLayout = [...prevLayout];
237
+ const [firstPivotIndex, secondPivotIndex] = pivotIndices;
238
+ assert(firstPivotIndex != null);
239
+ assert(secondPivotIndex != null);
334
240
  let deltaApplied = 0;
335
241
 
336
242
  //const DEBUG = [];
@@ -354,18 +260,23 @@ function adjustLayoutByDelta({
354
260
  if (trigger === "keyboard") {
355
261
  {
356
262
  // Check if we should expand a collapsed panel
357
- const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
358
- const constraints = panelConstraints[index];
263
+ const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
264
+ const panelConstraints = panelConstraintsArray[index];
265
+ assert(panelConstraints);
266
+
359
267
  //DEBUG.push(`edge case check 1: ${index}`);
360
268
  //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
361
- if (constraints.collapsible) {
269
+ if (panelConstraints.collapsible) {
362
270
  const prevSize = prevLayout[index];
271
+ assert(prevSize != null);
272
+ const panelConstraints = panelConstraintsArray[index];
273
+ assert(panelConstraints);
363
274
  const {
364
- collapsedSizePercentage,
365
- minSizePercentage
366
- } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
367
- if (fuzzyNumbersEqual(prevSize, collapsedSizePercentage)) {
368
- const localDelta = minSizePercentage - prevSize;
275
+ collapsedSize = 0,
276
+ minSize = 0
277
+ } = panelConstraints;
278
+ if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
279
+ const localDelta = minSize - prevSize;
369
280
  //DEBUG.push(` -> expand delta: ${localDelta}`);
370
281
 
371
282
  if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
@@ -378,18 +289,26 @@ function adjustLayoutByDelta({
378
289
 
379
290
  {
380
291
  // Check if we should collapse a panel at its minimum size
381
- const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
382
- const constraints = panelConstraints[index];
292
+ const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
293
+ const panelConstraints = panelConstraintsArray[index];
294
+ assert(panelConstraints);
295
+ const {
296
+ collapsible
297
+ } = panelConstraints;
298
+
383
299
  //DEBUG.push(`edge case check 2: ${index}`);
384
- //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
385
- if (constraints.collapsible) {
300
+ //DEBUG.push(` -> collapsible? ${collapsible}`);
301
+ if (collapsible) {
386
302
  const prevSize = prevLayout[index];
303
+ assert(prevSize != null);
304
+ const panelConstraints = panelConstraintsArray[index];
305
+ assert(panelConstraints);
387
306
  const {
388
- collapsedSizePercentage,
389
- minSizePercentage
390
- } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
391
- if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
392
- const localDelta = prevSize - collapsedSizePercentage;
307
+ collapsedSize = 0,
308
+ minSize = 0
309
+ } = panelConstraints;
310
+ if (fuzzyNumbersEqual(prevSize, minSize)) {
311
+ const localDelta = prevSize - collapsedSize;
393
312
  //DEBUG.push(` -> expand delta: ${localDelta}`);
394
313
 
395
314
  if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
@@ -411,15 +330,15 @@ function adjustLayoutByDelta({
411
330
  // as an expanding panel might change from collapsed to min size.
412
331
 
413
332
  const increment = delta < 0 ? 1 : -1;
414
- let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
333
+ let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
415
334
  let maxAvailableDelta = 0;
416
335
 
417
336
  //DEBUG.push("pre calc...");
418
337
  while (true) {
419
338
  const prevSize = prevLayout[index];
339
+ assert(prevSize != null);
420
340
  const maxSafeSize = resizePanel({
421
- groupSizePixels,
422
- panelConstraints,
341
+ panelConstraints: panelConstraintsArray,
423
342
  panelIndex: index,
424
343
  size: 100
425
344
  });
@@ -428,7 +347,7 @@ function adjustLayoutByDelta({
428
347
 
429
348
  maxAvailableDelta += delta;
430
349
  index += increment;
431
- if (index < 0 || index >= panelConstraints.length) {
350
+ if (index < 0 || index >= panelConstraintsArray.length) {
432
351
  break;
433
352
  }
434
353
  }
@@ -443,15 +362,15 @@ function adjustLayoutByDelta({
443
362
  {
444
363
  // Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
445
364
 
446
- const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
365
+ const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
447
366
  let index = pivotIndex;
448
- while (index >= 0 && index < panelConstraints.length) {
367
+ while (index >= 0 && index < panelConstraintsArray.length) {
449
368
  const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
450
369
  const prevSize = prevLayout[index];
370
+ assert(prevSize != null);
451
371
  const unsafeSize = prevSize - deltaRemaining;
452
372
  const safeSize = resizePanel({
453
- groupSizePixels,
454
- panelConstraints,
373
+ panelConstraints: panelConstraintsArray,
455
374
  panelIndex: index,
456
375
  size: unsafeSize
457
376
  });
@@ -483,11 +402,12 @@ function adjustLayoutByDelta({
483
402
  }
484
403
  {
485
404
  // Now distribute the applied delta to the panels in the other direction
486
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
487
- const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
405
+ const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
406
+ const prevSize = prevLayout[pivotIndex];
407
+ assert(prevSize != null);
408
+ const unsafeSize = prevSize + deltaApplied;
488
409
  const safeSize = resizePanel({
489
- groupSizePixels,
490
- panelConstraints,
410
+ panelConstraints: panelConstraintsArray,
491
411
  panelIndex: pivotIndex,
492
412
  size: unsafeSize
493
413
  });
@@ -498,14 +418,14 @@ function adjustLayoutByDelta({
498
418
  // Edge case where expanding or contracting one panel caused another one to change collapsed state
499
419
  if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
500
420
  let deltaRemaining = unsafeSize - safeSize;
501
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
421
+ const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
502
422
  let index = pivotIndex;
503
- while (index >= 0 && index < panelConstraints.length) {
423
+ while (index >= 0 && index < panelConstraintsArray.length) {
504
424
  const prevSize = nextLayout[index];
425
+ assert(prevSize != null);
505
426
  const unsafeSize = prevSize + deltaRemaining;
506
427
  const safeSize = resizePanel({
507
- groupSizePixels,
508
- panelConstraints,
428
+ panelConstraints: panelConstraintsArray,
509
429
  panelIndex: index,
510
430
  size: unsafeSize
511
431
  });
@@ -529,9 +449,7 @@ function adjustLayoutByDelta({
529
449
  //DEBUG.push("");
530
450
 
531
451
  const totalSize = nextLayout.reduce((total, size) => size + total, 0);
532
- deltaApplied = 100 - totalSize;
533
452
  //DEBUG.push(`total size: ${totalSize}`);
534
- //DEBUG.push(` deltaApplied: ${deltaApplied}`);
535
453
  //console.log(DEBUG.join("\n"));
536
454
 
537
455
  if (!fuzzyNumbersEqual(totalSize, 100)) {
@@ -540,27 +458,7 @@ function adjustLayoutByDelta({
540
458
  return nextLayout;
541
459
  }
542
460
 
543
- function assert(expectedCondition, message = "Assertion failed!") {
544
- if (!expectedCondition) {
545
- console.error(message);
546
- throw Error(message);
547
- }
548
- }
549
-
550
- function getPercentageSizeFromMixedSizes({
551
- sizePercentage,
552
- sizePixels
553
- }, groupSizePixels) {
554
- if (sizePercentage != null) {
555
- return sizePercentage;
556
- } else if (sizePixels != null) {
557
- return convertPixelsToPercentage(sizePixels, groupSizePixels);
558
- }
559
- return undefined;
560
- }
561
-
562
461
  function calculateAriaValues({
563
- groupSizePixels,
564
462
  layout,
565
463
  panelsArray,
566
464
  pivotIndices
@@ -569,28 +467,19 @@ function calculateAriaValues({
569
467
  let currentMaxSize = 100;
570
468
  let totalMinSize = 0;
571
469
  let totalMaxSize = 0;
470
+ const firstIndex = pivotIndices[0];
471
+ assert(firstIndex != null);
572
472
 
573
473
  // A panel's effective min/max sizes also need to account for other panel's sizes.
574
474
  panelsArray.forEach((panelData, index) => {
575
- var _getPercentageSizeFro, _getPercentageSizeFro2;
576
475
  const {
577
476
  constraints
578
477
  } = panelData;
579
478
  const {
580
- maxSizePercentage,
581
- maxSizePixels,
582
- minSizePercentage,
583
- minSizePixels
479
+ maxSize = 100,
480
+ minSize = 0
584
481
  } = constraints;
585
- const minSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
586
- sizePercentage: minSizePercentage,
587
- sizePixels: minSizePixels
588
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
589
- const maxSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
590
- sizePercentage: maxSizePercentage,
591
- sizePixels: maxSizePixels
592
- }, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 100;
593
- if (index === pivotIndices[0]) {
482
+ if (index === firstIndex) {
594
483
  currentMinSize = minSize;
595
484
  currentMaxSize = maxSize;
596
485
  } else {
@@ -600,7 +489,7 @@ function calculateAriaValues({
600
489
  });
601
490
  const valueMax = Math.min(currentMaxSize, 100 - totalMinSize);
602
491
  const valueMin = Math.max(currentMinSize, 100 - totalMaxSize);
603
- const valueNow = layout[pivotIndices[0]];
492
+ const valueNow = layout[firstIndex];
604
493
  return {
605
494
  valueMax,
606
495
  valueMin,
@@ -631,42 +520,6 @@ function getPanelGroupElement(id) {
631
520
  return null;
632
521
  }
633
522
 
634
- function calculateAvailablePanelSizeInPixels(groupId) {
635
- const panelGroupElement = getPanelGroupElement(groupId);
636
- if (panelGroupElement == null) {
637
- return NaN;
638
- }
639
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
640
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
641
- if (direction === "horizontal") {
642
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
643
- return accumulated + handle.offsetWidth;
644
- }, 0);
645
- } else {
646
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
647
- return accumulated + handle.offsetHeight;
648
- }, 0);
649
- }
650
- }
651
-
652
- function getAvailableGroupSizePixels(groupId) {
653
- const panelGroupElement = getPanelGroupElement(groupId);
654
- if (panelGroupElement == null) {
655
- return NaN;
656
- }
657
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
658
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
659
- if (direction === "horizontal") {
660
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
661
- return accumulated + handle.offsetWidth;
662
- }, 0);
663
- } else {
664
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
665
- return accumulated + handle.offsetHeight;
666
- }, 0);
667
- }
668
- }
669
-
670
523
  function getResizeHandleElement(id) {
671
524
  const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
672
525
  if (element) {
@@ -699,7 +552,6 @@ function useWindowSplitterPanelGroupBehavior({
699
552
  didWarnAboutMissingResizeHandle: false
700
553
  });
701
554
  useIsomorphicLayoutEffect(() => {
702
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
703
555
  const resizeHandleElements = getResizeHandleElementsForGroup(groupId);
704
556
  for (let index = 0; index < panelDataArray.length - 1; index++) {
705
557
  const {
@@ -707,17 +559,18 @@ function useWindowSplitterPanelGroupBehavior({
707
559
  valueMin,
708
560
  valueNow
709
561
  } = calculateAriaValues({
710
- groupSizePixels,
711
562
  layout,
712
563
  panelsArray: panelDataArray,
713
564
  pivotIndices: [index, index + 1]
714
565
  });
715
566
  const resizeHandleElement = resizeHandleElements[index];
716
567
  if (resizeHandleElement == null) ; else {
717
- resizeHandleElement.setAttribute("aria-controls", panelDataArray[index].id);
568
+ const panelData = panelDataArray[index];
569
+ assert(panelData);
570
+ resizeHandleElement.setAttribute("aria-controls", panelData.id);
718
571
  resizeHandleElement.setAttribute("aria-valuemax", "" + Math.round(valueMax));
719
572
  resizeHandleElement.setAttribute("aria-valuemin", "" + Math.round(valueMin));
720
- resizeHandleElement.setAttribute("aria-valuenow", "" + Math.round(valueNow));
573
+ resizeHandleElement.setAttribute("aria-valuenow", valueNow != null ? "" + Math.round(valueNow) : "");
721
574
  }
722
575
  }
723
576
  return () => {
@@ -730,14 +583,18 @@ function useWindowSplitterPanelGroupBehavior({
730
583
  };
731
584
  }, [groupId, layout, panelDataArray]);
732
585
  useEffect(() => {
586
+ const eagerValues = eagerValuesRef.current;
587
+ assert(eagerValues);
733
588
  const {
734
589
  panelDataArray
735
- } = eagerValuesRef.current;
590
+ } = eagerValues;
736
591
  const groupElement = getPanelGroupElement(groupId);
737
592
  assert(groupElement != null, `No group found for id "${groupId}"`);
738
593
  const handles = getResizeHandleElementsForGroup(groupId);
594
+ assert(handles);
739
595
  const cleanupFunctions = handles.map(handle => {
740
596
  const handleId = handle.getAttribute("data-panel-resize-handle-id");
597
+ assert(handleId);
741
598
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
742
599
  if (idBefore == null || idAfter == null) {
743
600
  return () => {};
@@ -753,21 +610,16 @@ function useWindowSplitterPanelGroupBehavior({
753
610
  const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
754
611
  if (index >= 0) {
755
612
  const panelData = panelDataArray[index];
613
+ assert(panelData);
756
614
  const size = layout[index];
757
- if (size != null && panelData.constraints.collapsible) {
758
- var _getPercentageSizeFro, _getPercentageSizeFro2;
759
- const groupSizePixels = getAvailableGroupSizePixels(groupId);
760
- const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
761
- sizePercentage: panelData.constraints.collapsedSizePercentage,
762
- sizePixels: panelData.constraints.collapsedSizePixels
763
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
764
- const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
765
- sizePercentage: panelData.constraints.minSizePercentage,
766
- sizePixels: panelData.constraints.minSizePixels
767
- }, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
615
+ const {
616
+ collapsedSize = 0,
617
+ collapsible,
618
+ minSize = 0
619
+ } = panelData.constraints;
620
+ if (size != null && collapsible) {
768
621
  const nextLayout = adjustLayoutByDelta({
769
622
  delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
770
- groupSizePixels,
771
623
  layout,
772
624
  panelConstraints: panelDataArray.map(panelData => panelData.constraints),
773
625
  pivotIndices: determinePivotIndices(groupId, handleId),
@@ -821,6 +673,7 @@ function getResizeEventCursorPosition(direction, event) {
821
673
  return isHorizontal ? event.clientX : event.clientY;
822
674
  } else if (isTouchEvent(event)) {
823
675
  const firstTouch = event.touches[0];
676
+ assert(firstTouch);
824
677
  return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
825
678
  } else {
826
679
  throw Error(`Unsupported event type "${event.type}"`);
@@ -830,12 +683,15 @@ function getResizeEventCursorPosition(direction, event) {
830
683
  function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
831
684
  const isHorizontal = direction === "horizontal";
832
685
  const handleElement = getResizeHandleElement(dragHandleId);
686
+ assert(handleElement);
833
687
  const groupId = handleElement.getAttribute("data-panel-group-id");
688
+ assert(groupId);
834
689
  let {
835
690
  initialCursorPosition
836
691
  } = initialDragState;
837
692
  const cursorPosition = getResizeEventCursorPosition(direction, event);
838
693
  const groupElement = getPanelGroupElement(groupId);
694
+ assert(groupElement);
839
695
  const groupRect = groupElement.getBoundingClientRect();
840
696
  const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
841
697
  const offsetPixels = cursorPosition - initialCursorPosition;
@@ -844,19 +700,14 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
844
700
  }
845
701
 
846
702
  // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
847
- function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initialDragState, keyboardResizeByOptions) {
703
+ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
848
704
  if (isKeyDown(event)) {
849
705
  const isHorizontal = direction === "horizontal";
850
- const groupElement = getPanelGroupElement(groupId);
851
- const rect = groupElement.getBoundingClientRect();
852
- const groupSizeInPixels = isHorizontal ? rect.width : rect.height;
853
706
  let delta = 0;
854
707
  if (event.shiftKey) {
855
708
  delta = 100;
856
- } else if (keyboardResizeByOptions.percentage != null) {
857
- delta = keyboardResizeByOptions.percentage;
858
- } else if (keyboardResizeByOptions.pixels != null) {
859
- delta = keyboardResizeByOptions.pixels / groupSizeInPixels;
709
+ } else if (keyboardResizeBy != null) {
710
+ delta = keyboardResizeBy;
860
711
  } else {
861
712
  delta = 10;
862
713
  }
@@ -883,37 +734,43 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
883
734
  }
884
735
  return movement;
885
736
  } else {
737
+ if (initialDragState == null) {
738
+ return 0;
739
+ }
886
740
  return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
887
741
  }
888
742
  }
889
743
 
890
744
  function calculateUnsafeDefaultLayout({
891
- groupSizePixels,
892
745
  panelDataArray
893
746
  }) {
894
747
  const layout = Array(panelDataArray.length);
895
- const panelDataConstraints = panelDataArray.map(panelData => panelData.constraints);
748
+ const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
896
749
  let numPanelsWithSizes = 0;
897
750
  let remainingSize = 100;
898
751
 
899
752
  // Distribute default sizes first
900
753
  for (let index = 0; index < panelDataArray.length; index++) {
754
+ const panelConstraints = panelConstraintsArray[index];
755
+ assert(panelConstraints);
901
756
  const {
902
- defaultSizePercentage
903
- } = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
904
- if (defaultSizePercentage != null) {
757
+ defaultSize
758
+ } = panelConstraints;
759
+ if (defaultSize != null) {
905
760
  numPanelsWithSizes++;
906
- layout[index] = defaultSizePercentage;
907
- remainingSize -= defaultSizePercentage;
761
+ layout[index] = defaultSize;
762
+ remainingSize -= defaultSize;
908
763
  }
909
764
  }
910
765
 
911
766
  // Remaining size should be distributed evenly between panels without default sizes
912
767
  for (let index = 0; index < panelDataArray.length; index++) {
768
+ const panelConstraints = panelConstraintsArray[index];
769
+ assert(panelConstraints);
913
770
  const {
914
- defaultSizePercentage
915
- } = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
916
- if (defaultSizePercentage != null) {
771
+ defaultSize
772
+ } = panelConstraints;
773
+ if (defaultSize != null) {
917
774
  continue;
918
775
  }
919
776
  const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
@@ -925,54 +782,36 @@ function calculateUnsafeDefaultLayout({
925
782
  return layout;
926
783
  }
927
784
 
928
- function convertPercentageToPixels(percentage, groupSizePixels) {
929
- return percentage / 100 * groupSizePixels;
930
- }
931
-
932
785
  // Layout should be pre-converted into percentages
933
- function callPanelCallbacks(groupId, panelsArray, layout, panelIdToLastNotifiedMixedSizesMap) {
934
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
935
- layout.forEach((sizePercentage, index) => {
786
+ function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
787
+ layout.forEach((size, index) => {
936
788
  const panelData = panelsArray[index];
937
- if (!panelData) {
938
- // Handle initial mount (when panels are registered too late to be in the panels array)
939
- // The subsequent render+effects will handle the resize notification
940
- return;
941
- }
789
+ assert(panelData);
942
790
  const {
943
791
  callbacks,
944
792
  constraints,
945
793
  id: panelId
946
794
  } = panelData;
947
795
  const {
796
+ collapsedSize = 0,
948
797
  collapsible
949
798
  } = constraints;
950
- const mixedSizes = {
951
- sizePercentage,
952
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
953
- };
954
- const lastNotifiedMixedSizes = panelIdToLastNotifiedMixedSizesMap[panelId];
955
- if (lastNotifiedMixedSizes == null || mixedSizes.sizePercentage !== lastNotifiedMixedSizes.sizePercentage || mixedSizes.sizePixels !== lastNotifiedMixedSizes.sizePixels) {
956
- panelIdToLastNotifiedMixedSizesMap[panelId] = mixedSizes;
799
+ const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
800
+ if (lastNotifiedSize == null || size !== lastNotifiedSize) {
801
+ panelIdToLastNotifiedSizeMap[panelId] = size;
957
802
  const {
958
803
  onCollapse,
959
804
  onExpand,
960
805
  onResize
961
806
  } = callbacks;
962
807
  if (onResize) {
963
- onResize(mixedSizes, lastNotifiedMixedSizes);
808
+ onResize(size, lastNotifiedSize);
964
809
  }
965
810
  if (collapsible && (onCollapse || onExpand)) {
966
- var _getPercentageSizeFro;
967
- const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
968
- sizePercentage: constraints.collapsedSizePercentage,
969
- sizePixels: constraints.collapsedSizePixels
970
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
971
- const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
972
- if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
811
+ if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
973
812
  onExpand();
974
813
  }
975
- if (onCollapse && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage !== collapsedSize) && size === collapsedSize) {
814
+ if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
976
815
  onCollapse();
977
816
  }
978
817
  }
@@ -1155,31 +994,32 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
1155
994
  }
1156
995
  }
1157
996
 
1158
- function shouldMonitorPixelBasedConstraints(constraints) {
1159
- return constraints.some(constraints => {
1160
- return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
1161
- });
1162
- }
1163
-
1164
997
  // All units must be in percentages; pixel values should be pre-converted
1165
998
  function validatePanelGroupLayout({
1166
- groupSizePixels,
1167
999
  layout: prevLayout,
1168
1000
  panelConstraints
1169
1001
  }) {
1170
1002
  const nextLayout = [...prevLayout];
1003
+ const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
1171
1004
 
1172
1005
  // Validate layout expectations
1173
1006
  if (nextLayout.length !== panelConstraints.length) {
1174
1007
  throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
1175
- } else if (!fuzzyNumbersEqual(nextLayout.reduce((accumulated, current) => accumulated + current, 0), 100)) ;
1008
+ } else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
1009
+ for (let index = 0; index < panelConstraints.length; index++) {
1010
+ const unsafeSize = nextLayout[index];
1011
+ assert(unsafeSize != null);
1012
+ const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
1013
+ nextLayout[index] = safeSize;
1014
+ }
1015
+ }
1176
1016
  let remainingSize = 0;
1177
1017
 
1178
1018
  // First pass: Validate the proposed layout given each panel's constraints
1179
1019
  for (let index = 0; index < panelConstraints.length; index++) {
1180
1020
  const unsafeSize = nextLayout[index];
1021
+ assert(unsafeSize != null);
1181
1022
  const safeSize = resizePanel({
1182
- groupSizePixels,
1183
1023
  panelConstraints,
1184
1024
  panelIndex: index,
1185
1025
  size: unsafeSize
@@ -1195,9 +1035,9 @@ function validatePanelGroupLayout({
1195
1035
  if (!fuzzyNumbersEqual(remainingSize, 0)) {
1196
1036
  for (let index = 0; index < panelConstraints.length; index++) {
1197
1037
  const prevSize = nextLayout[index];
1038
+ assert(prevSize != null);
1198
1039
  const unsafeSize = prevSize + remainingSize;
1199
1040
  const safeSize = resizePanel({
1200
- groupSizePixels,
1201
1041
  panelConstraints,
1202
1042
  panelIndex: index,
1203
1043
  size: unsafeSize
@@ -1232,21 +1072,20 @@ function PanelGroupWithForwardedRef({
1232
1072
  autoSaveId = null,
1233
1073
  children,
1234
1074
  className: classNameFromProps = "",
1235
- dataAttributes,
1236
1075
  direction,
1237
1076
  forwardedRef,
1238
- id: idFromProps,
1077
+ id: idFromProps = null,
1239
1078
  onLayout = null,
1240
- keyboardResizeByPercentage = null,
1241
- keyboardResizeByPixels = null,
1079
+ keyboardResizeBy = null,
1242
1080
  storage = defaultStorage,
1243
1081
  style: styleFromProps,
1244
- tagName: Type = "div"
1082
+ tagName: Type = "div",
1083
+ ...rest
1245
1084
  }) {
1246
1085
  const groupId = useUniqueId(idFromProps);
1247
1086
  const [dragState, setDragState] = useState(null);
1248
1087
  const [layout, setLayout] = useState([]);
1249
- const panelIdToLastNotifiedMixedSizesMapRef = useRef({});
1088
+ const panelIdToLastNotifiedSizeMapRef = useRef({});
1250
1089
  const panelSizeBeforeCollapseRef = useRef(new Map());
1251
1090
  const prevDeltaRef = useRef(0);
1252
1091
  const committedValuesRef = useRef({
@@ -1254,8 +1093,7 @@ function PanelGroupWithForwardedRef({
1254
1093
  direction,
1255
1094
  dragState,
1256
1095
  id: groupId,
1257
- keyboardResizeByPercentage,
1258
- keyboardResizeByPixels,
1096
+ keyboardResizeBy,
1259
1097
  onLayout,
1260
1098
  storage
1261
1099
  });
@@ -1271,33 +1109,20 @@ function PanelGroupWithForwardedRef({
1271
1109
  useImperativeHandle(forwardedRef, () => ({
1272
1110
  getId: () => committedValuesRef.current.id,
1273
1111
  getLayout: () => {
1274
- const {
1275
- id: groupId
1276
- } = committedValuesRef.current;
1277
1112
  const {
1278
1113
  layout
1279
1114
  } = eagerValuesRef.current;
1280
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1281
- return layout.map(sizePercentage => {
1282
- return {
1283
- sizePercentage,
1284
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1285
- };
1286
- });
1115
+ return layout;
1287
1116
  },
1288
- setLayout: mixedSizes => {
1117
+ setLayout: unsafeLayout => {
1289
1118
  const {
1290
- id: groupId,
1291
1119
  onLayout
1292
1120
  } = committedValuesRef.current;
1293
1121
  const {
1294
1122
  layout: prevLayout,
1295
1123
  panelDataArray
1296
1124
  } = eagerValuesRef.current;
1297
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1298
- const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
1299
1125
  const safeLayout = validatePanelGroupLayout({
1300
- groupSizePixels,
1301
1126
  layout: unsafeLayout,
1302
1127
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1303
1128
  });
@@ -1305,12 +1130,9 @@ function PanelGroupWithForwardedRef({
1305
1130
  setLayout(safeLayout);
1306
1131
  eagerValuesRef.current.layout = safeLayout;
1307
1132
  if (onLayout) {
1308
- onLayout(safeLayout.map(sizePercentage => ({
1309
- sizePercentage,
1310
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1311
- })));
1133
+ onLayout(safeLayout);
1312
1134
  }
1313
- callPanelCallbacks(groupId, panelDataArray, safeLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1135
+ callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
1314
1136
  }
1315
1137
  }
1316
1138
  }), []);
@@ -1321,11 +1143,7 @@ function PanelGroupWithForwardedRef({
1321
1143
  committedValuesRef.current.id = groupId;
1322
1144
  committedValuesRef.current.onLayout = onLayout;
1323
1145
  committedValuesRef.current.storage = storage;
1324
-
1325
- // panelDataArray and layout are updated in-sync with scheduled state updates.
1326
- // TODO [217] Move these values into a separate ref
1327
1146
  });
1328
-
1329
1147
  useWindowSplitterPanelGroupBehavior({
1330
1148
  committedValuesRef,
1331
1149
  eagerValuesRef,
@@ -1344,57 +1162,16 @@ function PanelGroupWithForwardedRef({
1344
1162
  if (layout.length === 0 || layout.length !== panelDataArray.length) {
1345
1163
  return;
1346
1164
  }
1165
+ let debouncedSave = debounceMap[autoSaveId];
1347
1166
 
1348
1167
  // Limit the frequency of localStorage updates.
1349
- if (!debounceMap[autoSaveId]) {
1350
- debounceMap[autoSaveId] = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1168
+ if (debouncedSave == null) {
1169
+ debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1170
+ debounceMap[autoSaveId] = debouncedSave;
1351
1171
  }
1352
- debounceMap[autoSaveId](autoSaveId, panelDataArray, layout, storage);
1172
+ debouncedSave(autoSaveId, panelDataArray, layout, storage);
1353
1173
  }
1354
1174
  }, [autoSaveId, layout, storage]);
1355
- useIsomorphicLayoutEffect(() => {
1356
- const {
1357
- layout: prevLayout,
1358
- panelDataArray
1359
- } = eagerValuesRef.current;
1360
- const constraints = panelDataArray.map(({
1361
- constraints
1362
- }) => constraints);
1363
- if (!shouldMonitorPixelBasedConstraints(constraints)) {
1364
- // Avoid the overhead of ResizeObserver if no pixel constraints require monitoring
1365
- return;
1366
- }
1367
- if (typeof ResizeObserver === "undefined") {
1368
- console.warn(`WARNING: Pixel based constraints require ResizeObserver but it is not supported by the current browser.`);
1369
- } else {
1370
- const resizeObserver = new ResizeObserver(() => {
1371
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1372
- const {
1373
- onLayout
1374
- } = committedValuesRef.current;
1375
- const nextLayout = validatePanelGroupLayout({
1376
- groupSizePixels,
1377
- layout: prevLayout,
1378
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1379
- });
1380
- if (!areEqual(prevLayout, nextLayout)) {
1381
- setLayout(nextLayout);
1382
- eagerValuesRef.current.layout = nextLayout;
1383
- if (onLayout) {
1384
- onLayout(nextLayout.map(sizePercentage => ({
1385
- sizePercentage,
1386
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1387
- })));
1388
- }
1389
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1390
- }
1391
- });
1392
- resizeObserver.observe(getPanelGroupElement(groupId));
1393
- return () => {
1394
- resizeObserver.disconnect();
1395
- };
1396
- }
1397
- }, [groupId]);
1398
1175
 
1399
1176
  // DEV warnings
1400
1177
  useEffect(() => {
@@ -1412,20 +1189,19 @@ function PanelGroupWithForwardedRef({
1412
1189
  if (panelData.constraints.collapsible) {
1413
1190
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1414
1191
  const {
1415
- collapsedSizePercentage,
1416
- panelSizePercentage,
1417
- pivotIndices,
1418
- groupSizePixels
1419
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1420
- if (panelSizePercentage !== collapsedSizePercentage) {
1192
+ collapsedSize = 0,
1193
+ panelSize,
1194
+ pivotIndices
1195
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1196
+ assert(panelSize != null);
1197
+ if (panelSize !== collapsedSize) {
1421
1198
  // Store size before collapse;
1422
1199
  // This is the size that gets restored if the expand() API is used.
1423
- panelSizeBeforeCollapseRef.current.set(panelData.id, panelSizePercentage);
1200
+ panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1424
1201
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1425
- const delta = isLastPanel ? panelSizePercentage - collapsedSizePercentage : collapsedSizePercentage - panelSizePercentage;
1202
+ const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1426
1203
  const nextLayout = adjustLayoutByDelta({
1427
1204
  delta,
1428
- groupSizePixels,
1429
1205
  layout: prevLayout,
1430
1206
  panelConstraints: panelConstraintsArray,
1431
1207
  pivotIndices,
@@ -1435,16 +1211,13 @@ function PanelGroupWithForwardedRef({
1435
1211
  setLayout(nextLayout);
1436
1212
  eagerValuesRef.current.layout = nextLayout;
1437
1213
  if (onLayout) {
1438
- onLayout(nextLayout.map(sizePercentage => ({
1439
- sizePercentage,
1440
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1441
- })));
1214
+ onLayout(nextLayout);
1442
1215
  }
1443
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1216
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1444
1217
  }
1445
1218
  }
1446
1219
  }
1447
- }, [groupId]);
1220
+ }, []);
1448
1221
 
1449
1222
  // External APIs are safe to memoize via committed values ref
1450
1223
  const expandPanel = useCallback(panelData => {
@@ -1458,21 +1231,19 @@ function PanelGroupWithForwardedRef({
1458
1231
  if (panelData.constraints.collapsible) {
1459
1232
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1460
1233
  const {
1461
- collapsedSizePercentage,
1462
- panelSizePercentage,
1463
- minSizePercentage,
1464
- pivotIndices,
1465
- groupSizePixels
1466
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1467
- if (panelSizePercentage === collapsedSizePercentage) {
1234
+ collapsedSize = 0,
1235
+ panelSize,
1236
+ minSize = 0,
1237
+ pivotIndices
1238
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1239
+ if (panelSize === collapsedSize) {
1468
1240
  // Restore this panel to the size it was before it was collapsed, if possible.
1469
- const prevPanelSizePercentage = panelSizeBeforeCollapseRef.current.get(panelData.id);
1470
- const baseSizePercentage = prevPanelSizePercentage != null && prevPanelSizePercentage >= minSizePercentage ? prevPanelSizePercentage : minSizePercentage;
1241
+ const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1242
+ const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1471
1243
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1472
- const delta = isLastPanel ? panelSizePercentage - baseSizePercentage : baseSizePercentage - panelSizePercentage;
1244
+ const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1473
1245
  const nextLayout = adjustLayoutByDelta({
1474
1246
  delta,
1475
- groupSizePixels,
1476
1247
  layout: prevLayout,
1477
1248
  panelConstraints: panelConstraintsArray,
1478
1249
  pivotIndices,
@@ -1482,16 +1253,13 @@ function PanelGroupWithForwardedRef({
1482
1253
  setLayout(nextLayout);
1483
1254
  eagerValuesRef.current.layout = nextLayout;
1484
1255
  if (onLayout) {
1485
- onLayout(nextLayout.map(sizePercentage => ({
1486
- sizePercentage,
1487
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1488
- })));
1256
+ onLayout(nextLayout);
1489
1257
  }
1490
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1258
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1491
1259
  }
1492
1260
  }
1493
1261
  }
1494
- }, [groupId]);
1262
+ }, []);
1495
1263
 
1496
1264
  // External APIs are safe to memoize via committed values ref
1497
1265
  const getPanelSize = useCallback(panelData => {
@@ -1500,14 +1268,11 @@ function PanelGroupWithForwardedRef({
1500
1268
  panelDataArray
1501
1269
  } = eagerValuesRef.current;
1502
1270
  const {
1503
- panelSizePercentage,
1504
- panelSizePixels
1505
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1506
- return {
1507
- sizePercentage: panelSizePercentage,
1508
- sizePixels: panelSizePixels
1509
- };
1510
- }, [groupId]);
1271
+ panelSize
1272
+ } = panelDataHelper(panelDataArray, panelData, layout);
1273
+ assert(panelSize != null);
1274
+ return panelSize;
1275
+ }, []);
1511
1276
 
1512
1277
  // This API should never read from committedValuesRef
1513
1278
  const getPanelStyle = useCallback(panelData => {
@@ -1530,12 +1295,12 @@ function PanelGroupWithForwardedRef({
1530
1295
  panelDataArray
1531
1296
  } = eagerValuesRef.current;
1532
1297
  const {
1533
- collapsedSizePercentage,
1298
+ collapsedSize,
1534
1299
  collapsible,
1535
- panelSizePercentage
1536
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1537
- return collapsible === true && panelSizePercentage === collapsedSizePercentage;
1538
- }, [groupId]);
1300
+ panelSize
1301
+ } = panelDataHelper(panelDataArray, panelData, layout);
1302
+ return collapsible === true && panelSize === collapsedSize;
1303
+ }, []);
1539
1304
 
1540
1305
  // External APIs are safe to memoize via committed values ref
1541
1306
  const isPanelExpanded = useCallback(panelData => {
@@ -1544,12 +1309,13 @@ function PanelGroupWithForwardedRef({
1544
1309
  panelDataArray
1545
1310
  } = eagerValuesRef.current;
1546
1311
  const {
1547
- collapsedSizePercentage,
1312
+ collapsedSize = 0,
1548
1313
  collapsible,
1549
- panelSizePercentage
1550
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1551
- return !collapsible || panelSizePercentage > collapsedSizePercentage;
1552
- }, [groupId]);
1314
+ panelSize
1315
+ } = panelDataHelper(panelDataArray, panelData, layout);
1316
+ assert(panelSize != null);
1317
+ return !collapsible || panelSize > collapsedSize;
1318
+ }, []);
1553
1319
  const registerPanel = useCallback(panelData => {
1554
1320
  const {
1555
1321
  autoSaveId,
@@ -1589,18 +1355,8 @@ function PanelGroupWithForwardedRef({
1589
1355
  if (autoSaveId) {
1590
1356
  unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1591
1357
  }
1592
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1593
- if (groupSizePixels <= 0) {
1594
- if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
1595
- constraints
1596
- }) => constraints))) {
1597
- // Wait until the group has rendered a non-zero size before computing layout.
1598
- return;
1599
- }
1600
- }
1601
1358
  if (unsafeLayout == null) {
1602
1359
  unsafeLayout = calculateUnsafeDefaultLayout({
1603
- groupSizePixels,
1604
1360
  panelDataArray
1605
1361
  });
1606
1362
  }
@@ -1608,7 +1364,6 @@ function PanelGroupWithForwardedRef({
1608
1364
  // Validate even saved layouts in case something has changed since last render
1609
1365
  // e.g. for pixel groups, this could be the size of the window
1610
1366
  const nextLayout = validatePanelGroupLayout({
1611
- groupSizePixels,
1612
1367
  layout: unsafeLayout,
1613
1368
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1614
1369
  });
@@ -1620,12 +1375,9 @@ function PanelGroupWithForwardedRef({
1620
1375
  eagerValuesRef.current.layout = nextLayout;
1621
1376
  if (!areEqual(prevLayout, nextLayout)) {
1622
1377
  if (onLayout) {
1623
- onLayout(nextLayout.map(sizePercentage => ({
1624
- sizePercentage,
1625
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1626
- })));
1378
+ onLayout(nextLayout);
1627
1379
  }
1628
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1380
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1629
1381
  }
1630
1382
  }, []);
1631
1383
  const registerResizeHandle = useCallback(dragHandleId => {
@@ -1635,8 +1387,7 @@ function PanelGroupWithForwardedRef({
1635
1387
  direction,
1636
1388
  dragState,
1637
1389
  id: groupId,
1638
- keyboardResizeByPercentage,
1639
- keyboardResizeByPixels,
1390
+ keyboardResizeBy,
1640
1391
  onLayout
1641
1392
  } = committedValuesRef.current;
1642
1393
  const {
@@ -1647,10 +1398,7 @@ function PanelGroupWithForwardedRef({
1647
1398
  initialLayout
1648
1399
  } = dragState !== null && dragState !== void 0 ? dragState : {};
1649
1400
  const pivotIndices = determinePivotIndices(groupId, dragHandleId);
1650
- let delta = calculateDeltaPercentage(event, groupId, dragHandleId, direction, dragState, {
1651
- percentage: keyboardResizeByPercentage,
1652
- pixels: keyboardResizeByPixels
1653
- });
1401
+ let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
1654
1402
  if (delta === 0) {
1655
1403
  return;
1656
1404
  }
@@ -1660,11 +1408,9 @@ function PanelGroupWithForwardedRef({
1660
1408
  if (document.dir === "rtl" && isHorizontal) {
1661
1409
  delta = -delta;
1662
1410
  }
1663
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1664
1411
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1665
1412
  const nextLayout = adjustLayoutByDelta({
1666
1413
  delta,
1667
- groupSizePixels,
1668
1414
  layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
1669
1415
  panelConstraints,
1670
1416
  pivotIndices,
@@ -1700,18 +1446,15 @@ function PanelGroupWithForwardedRef({
1700
1446
  setLayout(nextLayout);
1701
1447
  eagerValuesRef.current.layout = nextLayout;
1702
1448
  if (onLayout) {
1703
- onLayout(nextLayout.map(sizePercentage => ({
1704
- sizePercentage,
1705
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1706
- })));
1449
+ onLayout(nextLayout);
1707
1450
  }
1708
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1451
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1709
1452
  }
1710
1453
  };
1711
1454
  }, []);
1712
1455
 
1713
1456
  // External APIs are safe to memoize via committed values ref
1714
- const resizePanel = useCallback((panelData, mixedSizes) => {
1457
+ const resizePanel = useCallback((panelData, unsafePanelSize) => {
1715
1458
  const {
1716
1459
  onLayout
1717
1460
  } = committedValuesRef.current;
@@ -1721,16 +1464,14 @@ function PanelGroupWithForwardedRef({
1721
1464
  } = eagerValuesRef.current;
1722
1465
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1723
1466
  const {
1724
- groupSizePixels,
1725
- panelSizePercentage,
1467
+ panelSize,
1726
1468
  pivotIndices
1727
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1728
- const sizePercentage = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
1469
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1470
+ assert(panelSize != null);
1729
1471
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1730
- const delta = isLastPanel ? panelSizePercentage - sizePercentage : sizePercentage - panelSizePercentage;
1472
+ const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1731
1473
  const nextLayout = adjustLayoutByDelta({
1732
1474
  delta,
1733
- groupSizePixels,
1734
1475
  layout: prevLayout,
1735
1476
  panelConstraints: panelConstraintsArray,
1736
1477
  pivotIndices,
@@ -1740,14 +1481,11 @@ function PanelGroupWithForwardedRef({
1740
1481
  setLayout(nextLayout);
1741
1482
  eagerValuesRef.current.layout = nextLayout;
1742
1483
  if (onLayout) {
1743
- onLayout(nextLayout.map(sizePercentage => ({
1744
- sizePercentage,
1745
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1746
- })));
1484
+ onLayout(nextLayout);
1747
1485
  }
1748
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1486
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1749
1487
  }
1750
- }, [groupId]);
1488
+ }, []);
1751
1489
  const startDragging = useCallback((dragHandleId, event) => {
1752
1490
  const {
1753
1491
  direction
@@ -1756,6 +1494,7 @@ function PanelGroupWithForwardedRef({
1756
1494
  layout
1757
1495
  } = eagerValuesRef.current;
1758
1496
  const handleElement = getResizeHandleElement(dragHandleId);
1497
+ assert(handleElement);
1759
1498
  const initialCursorPosition = getResizeEventCursorPosition(direction, event);
1760
1499
  setDragState({
1761
1500
  dragHandleId,
@@ -1774,7 +1513,6 @@ function PanelGroupWithForwardedRef({
1774
1513
  });
1775
1514
  const unregisterPanel = useCallback(panelData => {
1776
1515
  const {
1777
- id: groupId,
1778
1516
  onLayout
1779
1517
  } = committedValuesRef.current;
1780
1518
  const {
@@ -1797,7 +1535,7 @@ function PanelGroupWithForwardedRef({
1797
1535
  const {
1798
1536
  pendingPanelIds
1799
1537
  } = unregisterPanelRef.current;
1800
- const map = panelIdToLastNotifiedMixedSizesMapRef.current;
1538
+ const map = panelIdToLastNotifiedSizeMapRef.current;
1801
1539
 
1802
1540
  // TRICKY
1803
1541
  // Strict effects mode
@@ -1823,16 +1561,13 @@ function PanelGroupWithForwardedRef({
1823
1561
  // The group is unmounting; skip layout calculation.
1824
1562
  return;
1825
1563
  }
1826
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1827
1564
  let unsafeLayout = calculateUnsafeDefaultLayout({
1828
- groupSizePixels,
1829
1565
  panelDataArray
1830
1566
  });
1831
1567
 
1832
1568
  // Validate even saved layouts in case something has changed since last render
1833
1569
  // e.g. for pixel groups, this could be the size of the window
1834
1570
  const nextLayout = validatePanelGroupLayout({
1835
- groupSizePixels,
1836
1571
  layout: unsafeLayout,
1837
1572
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1838
1573
  });
@@ -1840,12 +1575,9 @@ function PanelGroupWithForwardedRef({
1840
1575
  setLayout(nextLayout);
1841
1576
  eagerValuesRef.current.layout = nextLayout;
1842
1577
  if (onLayout) {
1843
- onLayout(nextLayout.map(sizePercentage => ({
1844
- sizePercentage,
1845
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1846
- })));
1578
+ onLayout(nextLayout);
1847
1579
  }
1848
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1580
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1849
1581
  }
1850
1582
  }, 0);
1851
1583
  }, []);
@@ -1876,13 +1608,13 @@ function PanelGroupWithForwardedRef({
1876
1608
  return createElement(PanelGroupContext.Provider, {
1877
1609
  value: context
1878
1610
  }, createElement(Type, {
1611
+ ...rest,
1879
1612
  children,
1880
1613
  className: classNameFromProps,
1881
1614
  style: {
1882
1615
  ...style,
1883
1616
  ...styleFromProps
1884
1617
  },
1885
- ...dataAttributes,
1886
1618
  // CSS selectors
1887
1619
  "data-panel-group": "",
1888
1620
  "data-panel-group-direction": direction,
@@ -1895,22 +1627,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
1895
1627
  }));
1896
1628
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
1897
1629
  PanelGroup.displayName = "forwardRef(PanelGroup)";
1898
- function panelDataHelper(groupId, panelDataArray, panelData, layout) {
1630
+ function panelDataHelper(panelDataArray, panelData, layout) {
1899
1631
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1900
1632
  const panelIndex = panelDataArray.indexOf(panelData);
1901
1633
  const panelConstraints = panelConstraintsArray[panelIndex];
1902
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1903
- const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
1904
1634
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1905
1635
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
1906
- const panelSizePercentage = layout[panelIndex];
1907
- const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
1636
+ const panelSize = layout[panelIndex];
1908
1637
  return {
1909
- ...percentagePanelConstraints,
1910
- collapsible: panelConstraints.collapsible,
1911
- panelSizePercentage,
1912
- panelSizePixels,
1913
- groupSizePixels,
1638
+ ...panelConstraints,
1639
+ panelSize,
1914
1640
  pivotIndices
1915
1641
  };
1916
1642
  }
@@ -1950,6 +1676,7 @@ function useWindowSplitterResizeHandlerBehavior({
1950
1676
  {
1951
1677
  event.preventDefault();
1952
1678
  const groupId = handleElement.getAttribute("data-panel-group-id");
1679
+ assert(groupId);
1953
1680
  const handles = getResizeHandleElementsForGroup(groupId);
1954
1681
  const index = getResizeHandleElementIndex(groupId, handleId);
1955
1682
  assert(index !== null);
@@ -1970,12 +1697,13 @@ function useWindowSplitterResizeHandlerBehavior({
1970
1697
  function PanelResizeHandle({
1971
1698
  children = null,
1972
1699
  className: classNameFromProps = "",
1973
- dataAttributes,
1974
1700
  disabled = false,
1975
- id: idFromProps = null,
1701
+ id: idFromProps,
1976
1702
  onDragging,
1977
1703
  style: styleFromProps = {},
1978
- tagName: Type = "div"
1704
+ tabIndex = 0,
1705
+ tagName: Type = "div",
1706
+ ...rest
1979
1707
  }) {
1980
1708
  const divElementRef = useRef(null);
1981
1709
 
@@ -2005,8 +1733,9 @@ function PanelResizeHandle({
2005
1733
  const stopDraggingAndBlur = useCallback(() => {
2006
1734
  // Clicking on the drag handle shouldn't leave it focused;
2007
1735
  // That would cause the PanelGroup to think it was still active.
2008
- const div = divElementRef.current;
2009
- div.blur();
1736
+ const divElement = divElementRef.current;
1737
+ assert(divElement);
1738
+ divElement.blur();
2010
1739
  stopDragging();
2011
1740
  const {
2012
1741
  onDragging
@@ -2034,6 +1763,7 @@ function PanelResizeHandle({
2034
1763
  resizeHandler(event);
2035
1764
  };
2036
1765
  const divElement = divElementRef.current;
1766
+ assert(divElement);
2037
1767
  const targetDocument = divElement.ownerDocument;
2038
1768
  targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
2039
1769
  targetDocument.body.addEventListener("mousemove", onMove);
@@ -2061,15 +1791,18 @@ function PanelResizeHandle({
2061
1791
  userSelect: "none"
2062
1792
  };
2063
1793
  return createElement(Type, {
1794
+ ...rest,
2064
1795
  children,
2065
1796
  className: classNameFromProps,
2066
1797
  onBlur: () => setIsFocused(false),
2067
1798
  onFocus: () => setIsFocused(true),
2068
1799
  onMouseDown: event => {
2069
1800
  startDragging(resizeHandleId, event.nativeEvent);
1801
+ const callbacks = callbacksRef.current;
1802
+ assert(callbacks);
2070
1803
  const {
2071
1804
  onDragging
2072
- } = callbacksRef.current;
1805
+ } = callbacks;
2073
1806
  if (onDragging) {
2074
1807
  onDragging(true);
2075
1808
  }
@@ -2079,9 +1812,11 @@ function PanelResizeHandle({
2079
1812
  onTouchEnd: stopDraggingAndBlur,
2080
1813
  onTouchStart: event => {
2081
1814
  startDragging(resizeHandleId, event.nativeEvent);
1815
+ const callbacks = callbacksRef.current;
1816
+ assert(callbacks);
2082
1817
  const {
2083
1818
  onDragging
2084
- } = callbacksRef.current;
1819
+ } = callbacks;
2085
1820
  if (onDragging) {
2086
1821
  onDragging(true);
2087
1822
  }
@@ -2092,8 +1827,7 @@ function PanelResizeHandle({
2092
1827
  ...style,
2093
1828
  ...styleFromProps
2094
1829
  },
2095
- tabIndex: 0,
2096
- ...dataAttributes,
1830
+ tabIndex,
2097
1831
  // CSS selectors
2098
1832
  "data-panel-group-direction": direction,
2099
1833
  "data-panel-group-id": groupId,
@@ -2105,4 +1839,4 @@ function PanelResizeHandle({
2105
1839
  }
2106
1840
  PanelResizeHandle.displayName = "PanelResizeHandle";
2107
1841
 
2108
- export { Panel, PanelGroup, PanelResizeHandle };
1842
+ export { Panel, PanelGroup, PanelResizeHandle, assert };