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
@@ -65,24 +65,20 @@ function useUniqueId(idFromParams = null) {
65
65
  function PanelWithForwardedRef({
66
66
  children,
67
67
  className: classNameFromProps = "",
68
- collapsedSizePercentage,
69
- collapsedSizePixels,
68
+ collapsedSize,
70
69
  collapsible,
71
- dataAttributes,
72
- defaultSizePercentage,
73
- defaultSizePixels,
70
+ defaultSize,
74
71
  forwardedRef,
75
72
  id: idFromProps,
76
- maxSizePercentage,
77
- maxSizePixels,
78
- minSizePercentage,
79
- minSizePixels,
73
+ maxSize,
74
+ minSize,
80
75
  onCollapse,
81
76
  onExpand,
82
77
  onResize,
83
78
  order,
84
79
  style: styleFromProps,
85
- tagName: Type = "div"
80
+ tagName: Type = "div",
81
+ ...rest
86
82
  }) {
87
83
  const context = useContext(PanelGroupContext);
88
84
  if (context === null) {
@@ -107,15 +103,11 @@ function PanelWithForwardedRef({
107
103
  onResize
108
104
  },
109
105
  constraints: {
110
- collapsedSizePercentage,
111
- collapsedSizePixels,
106
+ collapsedSize,
112
107
  collapsible,
113
- defaultSizePercentage,
114
- defaultSizePixels,
115
- maxSizePercentage,
116
- maxSizePixels,
117
- minSizePercentage,
118
- minSizePixels
108
+ defaultSize,
109
+ maxSize,
110
+ minSize
119
111
  },
120
112
  id: panelId,
121
113
  idIsFromProps: idFromProps !== undefined,
@@ -141,15 +133,11 @@ function PanelWithForwardedRef({
141
133
  callbacks.onCollapse = onCollapse;
142
134
  callbacks.onExpand = onExpand;
143
135
  callbacks.onResize = onResize;
144
- constraints.collapsedSizePercentage = collapsedSizePercentage;
145
- constraints.collapsedSizePixels = collapsedSizePixels;
136
+ constraints.collapsedSize = collapsedSize;
146
137
  constraints.collapsible = collapsible;
147
- constraints.defaultSizePercentage = defaultSizePercentage;
148
- constraints.defaultSizePixels = defaultSizePixels;
149
- constraints.maxSizePercentage = maxSizePercentage;
150
- constraints.maxSizePixels = maxSizePixels;
151
- constraints.minSizePercentage = minSizePercentage;
152
- constraints.minSizePixels = minSizePixels;
138
+ constraints.defaultSize = defaultSize;
139
+ constraints.maxSize = maxSize;
140
+ constraints.minSize = minSize;
153
141
  });
154
142
  useIsomorphicLayoutEffect(() => {
155
143
  const panelData = panelDataRef.current;
@@ -177,19 +165,19 @@ function PanelWithForwardedRef({
177
165
  isExpanded() {
178
166
  return !isPanelCollapsed(panelDataRef.current);
179
167
  },
180
- resize: mixedSizes => {
181
- resizePanel(panelDataRef.current, mixedSizes);
168
+ resize: size => {
169
+ resizePanel(panelDataRef.current, size);
182
170
  }
183
171
  }), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
184
172
  const style = getPanelStyle(panelDataRef.current);
185
173
  return createElement(Type, {
174
+ ...rest,
186
175
  children,
187
176
  className: classNameFromProps,
188
177
  style: {
189
178
  ...style,
190
179
  ...styleFromProps
191
180
  },
192
- ...dataAttributes,
193
181
  // CSS selectors
194
182
  "data-panel": "",
195
183
  "data-panel-id": panelId,
@@ -206,81 +194,11 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
206
194
  PanelWithForwardedRef.displayName = "Panel";
207
195
  Panel.displayName = "forwardRef(Panel)";
208
196
 
209
- function convertPixelsToPercentage(pixels, groupSizePixels) {
210
- return pixels / groupSizePixels * 100;
211
- }
212
-
213
- function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels) {
214
- let {
215
- collapsedSizePercentage = 0,
216
- collapsedSizePixels,
217
- defaultSizePercentage,
218
- defaultSizePixels,
219
- maxSizePercentage = 100,
220
- maxSizePixels,
221
- minSizePercentage = 0,
222
- minSizePixels
223
- } = panelConstraints;
224
- const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
225
- if (hasPixelConstraints && groupSizePixels <= 0) {
226
- console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
227
- return {
228
- collapsedSizePercentage: 0,
229
- defaultSizePercentage,
230
- maxSizePercentage: 0,
231
- minSizePercentage: 0
232
- };
233
- }
234
- if (collapsedSizePixels != null) {
235
- collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
236
- }
237
- if (defaultSizePixels != null) {
238
- defaultSizePercentage = convertPixelsToPercentage(defaultSizePixels, groupSizePixels);
239
- }
240
- if (minSizePixels != null) {
241
- minSizePercentage = convertPixelsToPercentage(minSizePixels, groupSizePixels);
242
- }
243
- if (maxSizePixels != null) {
244
- maxSizePercentage = convertPixelsToPercentage(maxSizePixels, groupSizePixels);
245
- }
246
- return {
247
- collapsedSizePercentage,
248
- defaultSizePercentage,
249
- maxSizePercentage,
250
- minSizePercentage
251
- };
252
- }
253
-
254
- function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels) {
255
- // All panel constraints, excluding the current one
256
- let totalMinConstraints = 0;
257
- let totalMaxConstraints = 0;
258
- for (let index = 0; index < panelConstraintsArray.length; index++) {
259
- if (index !== panelIndex) {
260
- const {
261
- collapsible
262
- } = panelConstraintsArray[index];
263
- const {
264
- collapsedSizePercentage,
265
- maxSizePercentage,
266
- minSizePercentage
267
- } = convertPixelConstraintsToPercentages(panelConstraintsArray[index], groupSizePixels);
268
- totalMaxConstraints += maxSizePercentage;
269
- totalMinConstraints += collapsible ? collapsedSizePercentage : minSizePercentage;
270
- }
197
+ function assert(expectedCondition, message = "Assertion failed!") {
198
+ if (!expectedCondition) {
199
+ console.error(message);
200
+ throw Error(message);
271
201
  }
272
- const {
273
- collapsedSizePercentage,
274
- defaultSizePercentage,
275
- maxSizePercentage,
276
- minSizePercentage
277
- } = convertPixelConstraintsToPercentages(panelConstraintsArray[panelIndex], groupSizePixels);
278
- return {
279
- collapsedSizePercentage,
280
- defaultSizePercentage,
281
- maxSizePercentage: panelConstraintsArray.length > 1 ? Math.min(maxSizePercentage, 100 - totalMinConstraints) : maxSizePercentage,
282
- minSizePercentage: panelConstraintsArray.length > 1 ? Math.max(minSizePercentage, 100 - totalMaxConstraints) : minSizePercentage
283
- };
284
202
  }
285
203
 
286
204
  const PRECISION = 10;
@@ -302,56 +220,41 @@ function fuzzyNumbersEqual(actual, expected, fractionDigits) {
302
220
 
303
221
  // Panel size must be in percentages; pixel values should be pre-converted
304
222
  function resizePanel({
305
- groupSizePixels,
306
- panelConstraints,
223
+ panelConstraints: panelConstraintsArray,
307
224
  panelIndex,
308
225
  size
309
226
  }) {
310
- const hasPixelConstraints = panelConstraints.some(({
311
- collapsedSizePixels,
312
- defaultSizePixels,
313
- minSizePixels,
314
- maxSizePixels
315
- }) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
316
- if (hasPixelConstraints && groupSizePixels <= 0) {
317
- console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
318
- return 0;
319
- }
227
+ const panelConstraints = panelConstraintsArray[panelIndex];
228
+ assert(panelConstraints != null);
320
229
  let {
321
- collapsible
322
- } = panelConstraints[panelIndex];
323
- const {
324
- collapsedSizePercentage,
325
- maxSizePercentage,
326
- minSizePercentage
327
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
328
- if (minSizePercentage != null) {
329
- if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
330
- if (collapsible) {
331
- // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
332
- const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
333
- if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
334
- size = collapsedSizePercentage;
335
- } else {
336
- size = minSizePercentage;
337
- }
230
+ collapsedSize = 0,
231
+ collapsible,
232
+ maxSize = 100,
233
+ minSize = 0
234
+ } = panelConstraints;
235
+ if (fuzzyCompareNumbers(size, minSize) < 0) {
236
+ if (collapsible) {
237
+ // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
238
+ const halfwayPoint = (collapsedSize + minSize) / 2;
239
+ if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
240
+ size = collapsedSize;
338
241
  } else {
339
- size = minSizePercentage;
242
+ size = minSize;
340
243
  }
244
+ } else {
245
+ size = minSize;
341
246
  }
342
247
  }
343
- if (maxSizePercentage != null) {
344
- size = Math.min(maxSizePercentage, size);
345
- }
248
+ size = Math.min(maxSize, size);
249
+ size = parseFloat(size.toFixed(PRECISION));
346
250
  return size;
347
251
  }
348
252
 
349
253
  // All units must be in percentages; pixel values should be pre-converted
350
254
  function adjustLayoutByDelta({
351
255
  delta,
352
- groupSizePixels,
353
256
  layout: prevLayout,
354
- panelConstraints,
257
+ panelConstraints: panelConstraintsArray,
355
258
  pivotIndices,
356
259
  trigger
357
260
  }) {
@@ -359,6 +262,9 @@ function adjustLayoutByDelta({
359
262
  return prevLayout;
360
263
  }
361
264
  const nextLayout = [...prevLayout];
265
+ const [firstPivotIndex, secondPivotIndex] = pivotIndices;
266
+ assert(firstPivotIndex != null);
267
+ assert(secondPivotIndex != null);
362
268
  let deltaApplied = 0;
363
269
 
364
270
  //const DEBUG = [];
@@ -382,18 +288,23 @@ function adjustLayoutByDelta({
382
288
  if (trigger === "keyboard") {
383
289
  {
384
290
  // Check if we should expand a collapsed panel
385
- const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
386
- const constraints = panelConstraints[index];
291
+ const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
292
+ const panelConstraints = panelConstraintsArray[index];
293
+ assert(panelConstraints);
294
+
387
295
  //DEBUG.push(`edge case check 1: ${index}`);
388
296
  //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
389
- if (constraints.collapsible) {
297
+ if (panelConstraints.collapsible) {
390
298
  const prevSize = prevLayout[index];
299
+ assert(prevSize != null);
300
+ const panelConstraints = panelConstraintsArray[index];
301
+ assert(panelConstraints);
391
302
  const {
392
- collapsedSizePercentage,
393
- minSizePercentage
394
- } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
395
- if (fuzzyNumbersEqual(prevSize, collapsedSizePercentage)) {
396
- const localDelta = minSizePercentage - prevSize;
303
+ collapsedSize = 0,
304
+ minSize = 0
305
+ } = panelConstraints;
306
+ if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
307
+ const localDelta = minSize - prevSize;
397
308
  //DEBUG.push(` -> expand delta: ${localDelta}`);
398
309
 
399
310
  if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
@@ -406,18 +317,26 @@ function adjustLayoutByDelta({
406
317
 
407
318
  {
408
319
  // Check if we should collapse a panel at its minimum size
409
- const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
410
- const constraints = panelConstraints[index];
320
+ const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
321
+ const panelConstraints = panelConstraintsArray[index];
322
+ assert(panelConstraints);
323
+ const {
324
+ collapsible
325
+ } = panelConstraints;
326
+
411
327
  //DEBUG.push(`edge case check 2: ${index}`);
412
- //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
413
- if (constraints.collapsible) {
328
+ //DEBUG.push(` -> collapsible? ${collapsible}`);
329
+ if (collapsible) {
414
330
  const prevSize = prevLayout[index];
331
+ assert(prevSize != null);
332
+ const panelConstraints = panelConstraintsArray[index];
333
+ assert(panelConstraints);
415
334
  const {
416
- collapsedSizePercentage,
417
- minSizePercentage
418
- } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
419
- if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
420
- const localDelta = prevSize - collapsedSizePercentage;
335
+ collapsedSize = 0,
336
+ minSize = 0
337
+ } = panelConstraints;
338
+ if (fuzzyNumbersEqual(prevSize, minSize)) {
339
+ const localDelta = prevSize - collapsedSize;
421
340
  //DEBUG.push(` -> expand delta: ${localDelta}`);
422
341
 
423
342
  if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
@@ -439,15 +358,15 @@ function adjustLayoutByDelta({
439
358
  // as an expanding panel might change from collapsed to min size.
440
359
 
441
360
  const increment = delta < 0 ? 1 : -1;
442
- let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
361
+ let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
443
362
  let maxAvailableDelta = 0;
444
363
 
445
364
  //DEBUG.push("pre calc...");
446
365
  while (true) {
447
366
  const prevSize = prevLayout[index];
367
+ assert(prevSize != null);
448
368
  const maxSafeSize = resizePanel({
449
- groupSizePixels,
450
- panelConstraints,
369
+ panelConstraints: panelConstraintsArray,
451
370
  panelIndex: index,
452
371
  size: 100
453
372
  });
@@ -456,7 +375,7 @@ function adjustLayoutByDelta({
456
375
 
457
376
  maxAvailableDelta += delta;
458
377
  index += increment;
459
- if (index < 0 || index >= panelConstraints.length) {
378
+ if (index < 0 || index >= panelConstraintsArray.length) {
460
379
  break;
461
380
  }
462
381
  }
@@ -471,15 +390,15 @@ function adjustLayoutByDelta({
471
390
  {
472
391
  // Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
473
392
 
474
- const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
393
+ const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
475
394
  let index = pivotIndex;
476
- while (index >= 0 && index < panelConstraints.length) {
395
+ while (index >= 0 && index < panelConstraintsArray.length) {
477
396
  const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
478
397
  const prevSize = prevLayout[index];
398
+ assert(prevSize != null);
479
399
  const unsafeSize = prevSize - deltaRemaining;
480
400
  const safeSize = resizePanel({
481
- groupSizePixels,
482
- panelConstraints,
401
+ panelConstraints: panelConstraintsArray,
483
402
  panelIndex: index,
484
403
  size: unsafeSize
485
404
  });
@@ -511,11 +430,12 @@ function adjustLayoutByDelta({
511
430
  }
512
431
  {
513
432
  // Now distribute the applied delta to the panels in the other direction
514
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
515
- const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
433
+ const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
434
+ const prevSize = prevLayout[pivotIndex];
435
+ assert(prevSize != null);
436
+ const unsafeSize = prevSize + deltaApplied;
516
437
  const safeSize = resizePanel({
517
- groupSizePixels,
518
- panelConstraints,
438
+ panelConstraints: panelConstraintsArray,
519
439
  panelIndex: pivotIndex,
520
440
  size: unsafeSize
521
441
  });
@@ -526,14 +446,14 @@ function adjustLayoutByDelta({
526
446
  // Edge case where expanding or contracting one panel caused another one to change collapsed state
527
447
  if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
528
448
  let deltaRemaining = unsafeSize - safeSize;
529
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
449
+ const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
530
450
  let index = pivotIndex;
531
- while (index >= 0 && index < panelConstraints.length) {
451
+ while (index >= 0 && index < panelConstraintsArray.length) {
532
452
  const prevSize = nextLayout[index];
453
+ assert(prevSize != null);
533
454
  const unsafeSize = prevSize + deltaRemaining;
534
455
  const safeSize = resizePanel({
535
- groupSizePixels,
536
- panelConstraints,
456
+ panelConstraints: panelConstraintsArray,
537
457
  panelIndex: index,
538
458
  size: unsafeSize
539
459
  });
@@ -557,9 +477,7 @@ function adjustLayoutByDelta({
557
477
  //DEBUG.push("");
558
478
 
559
479
  const totalSize = nextLayout.reduce((total, size) => size + total, 0);
560
- deltaApplied = 100 - totalSize;
561
480
  //DEBUG.push(`total size: ${totalSize}`);
562
- //DEBUG.push(` deltaApplied: ${deltaApplied}`);
563
481
  //console.log(DEBUG.join("\n"));
564
482
 
565
483
  if (!fuzzyNumbersEqual(totalSize, 100)) {
@@ -568,27 +486,7 @@ function adjustLayoutByDelta({
568
486
  return nextLayout;
569
487
  }
570
488
 
571
- function assert(expectedCondition, message = "Assertion failed!") {
572
- if (!expectedCondition) {
573
- console.error(message);
574
- throw Error(message);
575
- }
576
- }
577
-
578
- function getPercentageSizeFromMixedSizes({
579
- sizePercentage,
580
- sizePixels
581
- }, groupSizePixels) {
582
- if (sizePercentage != null) {
583
- return sizePercentage;
584
- } else if (sizePixels != null) {
585
- return convertPixelsToPercentage(sizePixels, groupSizePixels);
586
- }
587
- return undefined;
588
- }
589
-
590
489
  function calculateAriaValues({
591
- groupSizePixels,
592
490
  layout,
593
491
  panelsArray,
594
492
  pivotIndices
@@ -597,28 +495,19 @@ function calculateAriaValues({
597
495
  let currentMaxSize = 100;
598
496
  let totalMinSize = 0;
599
497
  let totalMaxSize = 0;
498
+ const firstIndex = pivotIndices[0];
499
+ assert(firstIndex != null);
600
500
 
601
501
  // A panel's effective min/max sizes also need to account for other panel's sizes.
602
502
  panelsArray.forEach((panelData, index) => {
603
- var _getPercentageSizeFro, _getPercentageSizeFro2;
604
503
  const {
605
504
  constraints
606
505
  } = panelData;
607
506
  const {
608
- maxSizePercentage,
609
- maxSizePixels,
610
- minSizePercentage,
611
- minSizePixels
507
+ maxSize = 100,
508
+ minSize = 0
612
509
  } = constraints;
613
- const minSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
614
- sizePercentage: minSizePercentage,
615
- sizePixels: minSizePixels
616
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
617
- const maxSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
618
- sizePercentage: maxSizePercentage,
619
- sizePixels: maxSizePixels
620
- }, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 100;
621
- if (index === pivotIndices[0]) {
510
+ if (index === firstIndex) {
622
511
  currentMinSize = minSize;
623
512
  currentMaxSize = maxSize;
624
513
  } else {
@@ -628,7 +517,7 @@ function calculateAriaValues({
628
517
  });
629
518
  const valueMax = Math.min(currentMaxSize, 100 - totalMinSize);
630
519
  const valueMin = Math.max(currentMinSize, 100 - totalMaxSize);
631
- const valueNow = layout[pivotIndices[0]];
520
+ const valueNow = layout[firstIndex];
632
521
  return {
633
522
  valueMax,
634
523
  valueMin,
@@ -659,42 +548,6 @@ function getPanelGroupElement(id) {
659
548
  return null;
660
549
  }
661
550
 
662
- function calculateAvailablePanelSizeInPixels(groupId) {
663
- const panelGroupElement = getPanelGroupElement(groupId);
664
- if (panelGroupElement == null) {
665
- return NaN;
666
- }
667
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
668
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
669
- if (direction === "horizontal") {
670
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
671
- return accumulated + handle.offsetWidth;
672
- }, 0);
673
- } else {
674
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
675
- return accumulated + handle.offsetHeight;
676
- }, 0);
677
- }
678
- }
679
-
680
- function getAvailableGroupSizePixels(groupId) {
681
- const panelGroupElement = getPanelGroupElement(groupId);
682
- if (panelGroupElement == null) {
683
- return NaN;
684
- }
685
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
686
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
687
- if (direction === "horizontal") {
688
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
689
- return accumulated + handle.offsetWidth;
690
- }, 0);
691
- } else {
692
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
693
- return accumulated + handle.offsetHeight;
694
- }, 0);
695
- }
696
- }
697
-
698
551
  function getResizeHandleElement(id) {
699
552
  const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
700
553
  if (element) {
@@ -727,7 +580,6 @@ function useWindowSplitterPanelGroupBehavior({
727
580
  didWarnAboutMissingResizeHandle: false
728
581
  });
729
582
  useIsomorphicLayoutEffect(() => {
730
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
731
583
  const resizeHandleElements = getResizeHandleElementsForGroup(groupId);
732
584
  for (let index = 0; index < panelDataArray.length - 1; index++) {
733
585
  const {
@@ -735,7 +587,6 @@ function useWindowSplitterPanelGroupBehavior({
735
587
  valueMin,
736
588
  valueNow
737
589
  } = calculateAriaValues({
738
- groupSizePixels,
739
590
  layout,
740
591
  panelsArray: panelDataArray,
741
592
  pivotIndices: [index, index + 1]
@@ -752,10 +603,12 @@ function useWindowSplitterPanelGroupBehavior({
752
603
  }
753
604
  }
754
605
  } else {
755
- resizeHandleElement.setAttribute("aria-controls", panelDataArray[index].id);
606
+ const panelData = panelDataArray[index];
607
+ assert(panelData);
608
+ resizeHandleElement.setAttribute("aria-controls", panelData.id);
756
609
  resizeHandleElement.setAttribute("aria-valuemax", "" + Math.round(valueMax));
757
610
  resizeHandleElement.setAttribute("aria-valuemin", "" + Math.round(valueMin));
758
- resizeHandleElement.setAttribute("aria-valuenow", "" + Math.round(valueNow));
611
+ resizeHandleElement.setAttribute("aria-valuenow", valueNow != null ? "" + Math.round(valueNow) : "");
759
612
  }
760
613
  }
761
614
  return () => {
@@ -768,14 +621,18 @@ function useWindowSplitterPanelGroupBehavior({
768
621
  };
769
622
  }, [groupId, layout, panelDataArray]);
770
623
  useEffect(() => {
624
+ const eagerValues = eagerValuesRef.current;
625
+ assert(eagerValues);
771
626
  const {
772
627
  panelDataArray
773
- } = eagerValuesRef.current;
628
+ } = eagerValues;
774
629
  const groupElement = getPanelGroupElement(groupId);
775
630
  assert(groupElement != null, `No group found for id "${groupId}"`);
776
631
  const handles = getResizeHandleElementsForGroup(groupId);
632
+ assert(handles);
777
633
  const cleanupFunctions = handles.map(handle => {
778
634
  const handleId = handle.getAttribute("data-panel-resize-handle-id");
635
+ assert(handleId);
779
636
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
780
637
  if (idBefore == null || idAfter == null) {
781
638
  return () => {};
@@ -791,21 +648,16 @@ function useWindowSplitterPanelGroupBehavior({
791
648
  const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
792
649
  if (index >= 0) {
793
650
  const panelData = panelDataArray[index];
651
+ assert(panelData);
794
652
  const size = layout[index];
795
- if (size != null && panelData.constraints.collapsible) {
796
- var _getPercentageSizeFro, _getPercentageSizeFro2;
797
- const groupSizePixels = getAvailableGroupSizePixels(groupId);
798
- const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
799
- sizePercentage: panelData.constraints.collapsedSizePercentage,
800
- sizePixels: panelData.constraints.collapsedSizePixels
801
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
802
- const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
803
- sizePercentage: panelData.constraints.minSizePercentage,
804
- sizePixels: panelData.constraints.minSizePixels
805
- }, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
653
+ const {
654
+ collapsedSize = 0,
655
+ collapsible,
656
+ minSize = 0
657
+ } = panelData.constraints;
658
+ if (size != null && collapsible) {
806
659
  const nextLayout = adjustLayoutByDelta({
807
660
  delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
808
- groupSizePixels,
809
661
  layout,
810
662
  panelConstraints: panelDataArray.map(panelData => panelData.constraints),
811
663
  pivotIndices: determinePivotIndices(groupId, handleId),
@@ -859,6 +711,7 @@ function getResizeEventCursorPosition(direction, event) {
859
711
  return isHorizontal ? event.clientX : event.clientY;
860
712
  } else if (isTouchEvent(event)) {
861
713
  const firstTouch = event.touches[0];
714
+ assert(firstTouch);
862
715
  return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
863
716
  } else {
864
717
  throw Error(`Unsupported event type "${event.type}"`);
@@ -868,12 +721,15 @@ function getResizeEventCursorPosition(direction, event) {
868
721
  function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
869
722
  const isHorizontal = direction === "horizontal";
870
723
  const handleElement = getResizeHandleElement(dragHandleId);
724
+ assert(handleElement);
871
725
  const groupId = handleElement.getAttribute("data-panel-group-id");
726
+ assert(groupId);
872
727
  let {
873
728
  initialCursorPosition
874
729
  } = initialDragState;
875
730
  const cursorPosition = getResizeEventCursorPosition(direction, event);
876
731
  const groupElement = getPanelGroupElement(groupId);
732
+ assert(groupElement);
877
733
  const groupRect = groupElement.getBoundingClientRect();
878
734
  const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
879
735
  const offsetPixels = cursorPosition - initialCursorPosition;
@@ -882,19 +738,14 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
882
738
  }
883
739
 
884
740
  // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
885
- function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initialDragState, keyboardResizeByOptions) {
741
+ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
886
742
  if (isKeyDown(event)) {
887
743
  const isHorizontal = direction === "horizontal";
888
- const groupElement = getPanelGroupElement(groupId);
889
- const rect = groupElement.getBoundingClientRect();
890
- const groupSizeInPixels = isHorizontal ? rect.width : rect.height;
891
744
  let delta = 0;
892
745
  if (event.shiftKey) {
893
746
  delta = 100;
894
- } else if (keyboardResizeByOptions.percentage != null) {
895
- delta = keyboardResizeByOptions.percentage;
896
- } else if (keyboardResizeByOptions.pixels != null) {
897
- delta = keyboardResizeByOptions.pixels / groupSizeInPixels;
747
+ } else if (keyboardResizeBy != null) {
748
+ delta = keyboardResizeBy;
898
749
  } else {
899
750
  delta = 10;
900
751
  }
@@ -921,37 +772,43 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
921
772
  }
922
773
  return movement;
923
774
  } else {
775
+ if (initialDragState == null) {
776
+ return 0;
777
+ }
924
778
  return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
925
779
  }
926
780
  }
927
781
 
928
782
  function calculateUnsafeDefaultLayout({
929
- groupSizePixels,
930
783
  panelDataArray
931
784
  }) {
932
785
  const layout = Array(panelDataArray.length);
933
- const panelDataConstraints = panelDataArray.map(panelData => panelData.constraints);
786
+ const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
934
787
  let numPanelsWithSizes = 0;
935
788
  let remainingSize = 100;
936
789
 
937
790
  // Distribute default sizes first
938
791
  for (let index = 0; index < panelDataArray.length; index++) {
792
+ const panelConstraints = panelConstraintsArray[index];
793
+ assert(panelConstraints);
939
794
  const {
940
- defaultSizePercentage
941
- } = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
942
- if (defaultSizePercentage != null) {
795
+ defaultSize
796
+ } = panelConstraints;
797
+ if (defaultSize != null) {
943
798
  numPanelsWithSizes++;
944
- layout[index] = defaultSizePercentage;
945
- remainingSize -= defaultSizePercentage;
799
+ layout[index] = defaultSize;
800
+ remainingSize -= defaultSize;
946
801
  }
947
802
  }
948
803
 
949
804
  // Remaining size should be distributed evenly between panels without default sizes
950
805
  for (let index = 0; index < panelDataArray.length; index++) {
806
+ const panelConstraints = panelConstraintsArray[index];
807
+ assert(panelConstraints);
951
808
  const {
952
- defaultSizePercentage
953
- } = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
954
- if (defaultSizePercentage != null) {
809
+ defaultSize
810
+ } = panelConstraints;
811
+ if (defaultSize != null) {
955
812
  continue;
956
813
  }
957
814
  const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
@@ -963,54 +820,36 @@ function calculateUnsafeDefaultLayout({
963
820
  return layout;
964
821
  }
965
822
 
966
- function convertPercentageToPixels(percentage, groupSizePixels) {
967
- return percentage / 100 * groupSizePixels;
968
- }
969
-
970
823
  // Layout should be pre-converted into percentages
971
- function callPanelCallbacks(groupId, panelsArray, layout, panelIdToLastNotifiedMixedSizesMap) {
972
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
973
- layout.forEach((sizePercentage, index) => {
824
+ function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
825
+ layout.forEach((size, index) => {
974
826
  const panelData = panelsArray[index];
975
- if (!panelData) {
976
- // Handle initial mount (when panels are registered too late to be in the panels array)
977
- // The subsequent render+effects will handle the resize notification
978
- return;
979
- }
827
+ assert(panelData);
980
828
  const {
981
829
  callbacks,
982
830
  constraints,
983
831
  id: panelId
984
832
  } = panelData;
985
833
  const {
834
+ collapsedSize = 0,
986
835
  collapsible
987
836
  } = constraints;
988
- const mixedSizes = {
989
- sizePercentage,
990
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
991
- };
992
- const lastNotifiedMixedSizes = panelIdToLastNotifiedMixedSizesMap[panelId];
993
- if (lastNotifiedMixedSizes == null || mixedSizes.sizePercentage !== lastNotifiedMixedSizes.sizePercentage || mixedSizes.sizePixels !== lastNotifiedMixedSizes.sizePixels) {
994
- panelIdToLastNotifiedMixedSizesMap[panelId] = mixedSizes;
837
+ const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
838
+ if (lastNotifiedSize == null || size !== lastNotifiedSize) {
839
+ panelIdToLastNotifiedSizeMap[panelId] = size;
995
840
  const {
996
841
  onCollapse,
997
842
  onExpand,
998
843
  onResize
999
844
  } = callbacks;
1000
845
  if (onResize) {
1001
- onResize(mixedSizes, lastNotifiedMixedSizes);
846
+ onResize(size, lastNotifiedSize);
1002
847
  }
1003
848
  if (collapsible && (onCollapse || onExpand)) {
1004
- var _getPercentageSizeFro;
1005
- const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
1006
- sizePercentage: constraints.collapsedSizePercentage,
1007
- sizePixels: constraints.collapsedSizePixels
1008
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
1009
- const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
1010
- if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
849
+ if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
1011
850
  onExpand();
1012
851
  }
1013
- if (onCollapse && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage !== collapsedSize) && size === collapsedSize) {
852
+ if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
1014
853
  onCollapse();
1015
854
  }
1016
855
  }
@@ -1044,9 +883,10 @@ function computePanelFlexBoxStyle({
1044
883
  const size = layout[panelIndex];
1045
884
  let flexGrow;
1046
885
  if (panelData.length === 1) {
1047
- flexGrow = "100";
886
+ flexGrow = "1";
1048
887
  } else if (size == null) {
1049
- flexGrow = "0";
888
+ // Initial render (before panels have registered themselves)
889
+ flexGrow = "1";
1050
890
  } else {
1051
891
  flexGrow = size.toPrecision(precision);
1052
892
  }
@@ -1192,74 +1032,39 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
1192
1032
  }
1193
1033
  }
1194
1034
 
1195
- function shouldMonitorPixelBasedConstraints(constraints) {
1196
- return constraints.some(constraints => {
1197
- return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
1198
- });
1199
- }
1200
-
1201
1035
  function validatePanelConstraints({
1202
- groupSizePixels,
1203
- panelConstraints,
1036
+ panelConstraints: panelConstraintsArray,
1204
1037
  panelId,
1205
1038
  panelIndex
1206
1039
  }) {
1207
1040
  {
1208
1041
  const warnings = [];
1209
- {
1210
- const {
1211
- collapsedSizePercentage,
1212
- collapsedSizePixels,
1213
- defaultSizePercentage,
1214
- defaultSizePixels,
1215
- maxSizePercentage,
1216
- maxSizePixels,
1217
- minSizePercentage,
1218
- minSizePixels
1219
- } = panelConstraints[panelIndex];
1220
- const conflictingUnits = [];
1221
- if (collapsedSizePercentage != null && collapsedSizePixels != null) {
1222
- conflictingUnits.push("collapsed size");
1223
- }
1224
- if (defaultSizePercentage != null && defaultSizePixels != null) {
1225
- conflictingUnits.push("default size");
1226
- }
1227
- if (maxSizePercentage != null && maxSizePixels != null) {
1228
- conflictingUnits.push("max size");
1229
- }
1230
- if (minSizePercentage != null && minSizePixels != null) {
1231
- conflictingUnits.push("min size");
1232
- }
1233
- if (conflictingUnits.length > 0) {
1234
- warnings.push(`should not specify both percentage and pixel units for: ${conflictingUnits.join(", ")}`);
1235
- }
1042
+ const panelConstraints = panelConstraintsArray[panelIndex];
1043
+ assert(panelConstraints);
1044
+ const {
1045
+ collapsedSize = 0,
1046
+ defaultSize,
1047
+ maxSize = 100,
1048
+ minSize = 0
1049
+ } = panelConstraints;
1050
+ if (minSize > maxSize) {
1051
+ warnings.push(`min size (${minSize}%) should not be greater than max size (${maxSize}%)`);
1236
1052
  }
1237
- {
1238
- const {
1239
- collapsedSizePercentage,
1240
- defaultSizePercentage,
1241
- maxSizePercentage,
1242
- minSizePercentage
1243
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
1244
- if (minSizePercentage > maxSizePercentage) {
1245
- warnings.push(`min size (${minSizePercentage}%) should not be greater than max size (${maxSizePercentage}%)`);
1246
- }
1247
- if (defaultSizePercentage != null) {
1248
- if (defaultSizePercentage < 0) {
1249
- warnings.push("default size should not be less than 0");
1250
- } else if (defaultSizePercentage < minSizePercentage) {
1251
- warnings.push("default size should not be less than min size");
1252
- }
1253
- if (defaultSizePercentage > 100) {
1254
- warnings.push("default size should not be greater than 100");
1255
- } else if (defaultSizePercentage > maxSizePercentage) {
1256
- warnings.push("default size should not be greater than max size");
1257
- }
1053
+ if (defaultSize != null) {
1054
+ if (defaultSize < 0) {
1055
+ warnings.push("default size should not be less than 0");
1056
+ } else if (defaultSize < minSize) {
1057
+ warnings.push("default size should not be less than min size");
1258
1058
  }
1259
- if (collapsedSizePercentage > minSizePercentage) {
1260
- warnings.push("collapsed size should not be greater than min size");
1059
+ if (defaultSize > 100) {
1060
+ warnings.push("default size should not be greater than 100");
1061
+ } else if (defaultSize > maxSize) {
1062
+ warnings.push("default size should not be greater than max size");
1261
1063
  }
1262
1064
  }
1065
+ if (collapsedSize > minSize) {
1066
+ warnings.push("collapsed size should not be greater than min size");
1067
+ }
1263
1068
  if (warnings.length > 0) {
1264
1069
  const name = panelId != null ? `Panel "${panelId}"` : "Panel";
1265
1070
  console.warn(`${name} has an invalid configuration:\n\n${warnings.join("\n")}`);
@@ -1271,20 +1076,26 @@ function validatePanelConstraints({
1271
1076
 
1272
1077
  // All units must be in percentages; pixel values should be pre-converted
1273
1078
  function validatePanelGroupLayout({
1274
- groupSizePixels,
1275
1079
  layout: prevLayout,
1276
1080
  panelConstraints
1277
1081
  }) {
1278
1082
  const nextLayout = [...prevLayout];
1083
+ const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
1279
1084
 
1280
1085
  // Validate layout expectations
1281
1086
  if (nextLayout.length !== panelConstraints.length) {
1282
1087
  throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
1283
- } else if (!fuzzyNumbersEqual(nextLayout.reduce((accumulated, current) => accumulated + current, 0), 100)) {
1088
+ } else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
1284
1089
  // This is not ideal so we should warn about it, but it may be recoverable in some cases
1285
1090
  // (especially if the amount is small)
1286
1091
  {
1287
- console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}`);
1092
+ console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}. Layout normalization will be applied.`);
1093
+ }
1094
+ for (let index = 0; index < panelConstraints.length; index++) {
1095
+ const unsafeSize = nextLayout[index];
1096
+ assert(unsafeSize != null);
1097
+ const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
1098
+ nextLayout[index] = safeSize;
1288
1099
  }
1289
1100
  }
1290
1101
  let remainingSize = 0;
@@ -1292,8 +1103,8 @@ function validatePanelGroupLayout({
1292
1103
  // First pass: Validate the proposed layout given each panel's constraints
1293
1104
  for (let index = 0; index < panelConstraints.length; index++) {
1294
1105
  const unsafeSize = nextLayout[index];
1106
+ assert(unsafeSize != null);
1295
1107
  const safeSize = resizePanel({
1296
- groupSizePixels,
1297
1108
  panelConstraints,
1298
1109
  panelIndex: index,
1299
1110
  size: unsafeSize
@@ -1309,9 +1120,9 @@ function validatePanelGroupLayout({
1309
1120
  if (!fuzzyNumbersEqual(remainingSize, 0)) {
1310
1121
  for (let index = 0; index < panelConstraints.length; index++) {
1311
1122
  const prevSize = nextLayout[index];
1123
+ assert(prevSize != null);
1312
1124
  const unsafeSize = prevSize + remainingSize;
1313
1125
  const safeSize = resizePanel({
1314
- groupSizePixels,
1315
1126
  panelConstraints,
1316
1127
  panelIndex: index,
1317
1128
  size: unsafeSize
@@ -1346,21 +1157,20 @@ function PanelGroupWithForwardedRef({
1346
1157
  autoSaveId = null,
1347
1158
  children,
1348
1159
  className: classNameFromProps = "",
1349
- dataAttributes,
1350
1160
  direction,
1351
1161
  forwardedRef,
1352
- id: idFromProps,
1162
+ id: idFromProps = null,
1353
1163
  onLayout = null,
1354
- keyboardResizeByPercentage = null,
1355
- keyboardResizeByPixels = null,
1164
+ keyboardResizeBy = null,
1356
1165
  storage = defaultStorage,
1357
1166
  style: styleFromProps,
1358
- tagName: Type = "div"
1167
+ tagName: Type = "div",
1168
+ ...rest
1359
1169
  }) {
1360
1170
  const groupId = useUniqueId(idFromProps);
1361
1171
  const [dragState, setDragState] = useState(null);
1362
1172
  const [layout, setLayout] = useState([]);
1363
- const panelIdToLastNotifiedMixedSizesMapRef = useRef({});
1173
+ const panelIdToLastNotifiedSizeMapRef = useRef({});
1364
1174
  const panelSizeBeforeCollapseRef = useRef(new Map());
1365
1175
  const prevDeltaRef = useRef(0);
1366
1176
  const committedValuesRef = useRef({
@@ -1368,8 +1178,7 @@ function PanelGroupWithForwardedRef({
1368
1178
  direction,
1369
1179
  dragState,
1370
1180
  id: groupId,
1371
- keyboardResizeByPercentage,
1372
- keyboardResizeByPixels,
1181
+ keyboardResizeBy,
1373
1182
  onLayout,
1374
1183
  storage
1375
1184
  });
@@ -1385,33 +1194,20 @@ function PanelGroupWithForwardedRef({
1385
1194
  useImperativeHandle(forwardedRef, () => ({
1386
1195
  getId: () => committedValuesRef.current.id,
1387
1196
  getLayout: () => {
1388
- const {
1389
- id: groupId
1390
- } = committedValuesRef.current;
1391
1197
  const {
1392
1198
  layout
1393
1199
  } = eagerValuesRef.current;
1394
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1395
- return layout.map(sizePercentage => {
1396
- return {
1397
- sizePercentage,
1398
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1399
- };
1400
- });
1200
+ return layout;
1401
1201
  },
1402
- setLayout: mixedSizes => {
1202
+ setLayout: unsafeLayout => {
1403
1203
  const {
1404
- id: groupId,
1405
1204
  onLayout
1406
1205
  } = committedValuesRef.current;
1407
1206
  const {
1408
1207
  layout: prevLayout,
1409
1208
  panelDataArray
1410
1209
  } = eagerValuesRef.current;
1411
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1412
- const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
1413
1210
  const safeLayout = validatePanelGroupLayout({
1414
- groupSizePixels,
1415
1211
  layout: unsafeLayout,
1416
1212
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1417
1213
  });
@@ -1419,12 +1215,9 @@ function PanelGroupWithForwardedRef({
1419
1215
  setLayout(safeLayout);
1420
1216
  eagerValuesRef.current.layout = safeLayout;
1421
1217
  if (onLayout) {
1422
- onLayout(safeLayout.map(sizePercentage => ({
1423
- sizePercentage,
1424
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1425
- })));
1218
+ onLayout(safeLayout);
1426
1219
  }
1427
- callPanelCallbacks(groupId, panelDataArray, safeLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1220
+ callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
1428
1221
  }
1429
1222
  }
1430
1223
  }), []);
@@ -1435,11 +1228,7 @@ function PanelGroupWithForwardedRef({
1435
1228
  committedValuesRef.current.id = groupId;
1436
1229
  committedValuesRef.current.onLayout = onLayout;
1437
1230
  committedValuesRef.current.storage = storage;
1438
-
1439
- // panelDataArray and layout are updated in-sync with scheduled state updates.
1440
- // TODO [217] Move these values into a separate ref
1441
1231
  });
1442
-
1443
1232
  useWindowSplitterPanelGroupBehavior({
1444
1233
  committedValuesRef,
1445
1234
  eagerValuesRef,
@@ -1458,57 +1247,16 @@ function PanelGroupWithForwardedRef({
1458
1247
  if (layout.length === 0 || layout.length !== panelDataArray.length) {
1459
1248
  return;
1460
1249
  }
1250
+ let debouncedSave = debounceMap[autoSaveId];
1461
1251
 
1462
1252
  // Limit the frequency of localStorage updates.
1463
- if (!debounceMap[autoSaveId]) {
1464
- debounceMap[autoSaveId] = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1253
+ if (debouncedSave == null) {
1254
+ debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1255
+ debounceMap[autoSaveId] = debouncedSave;
1465
1256
  }
1466
- debounceMap[autoSaveId](autoSaveId, panelDataArray, layout, storage);
1257
+ debouncedSave(autoSaveId, panelDataArray, layout, storage);
1467
1258
  }
1468
1259
  }, [autoSaveId, layout, storage]);
1469
- useIsomorphicLayoutEffect(() => {
1470
- const {
1471
- layout: prevLayout,
1472
- panelDataArray
1473
- } = eagerValuesRef.current;
1474
- const constraints = panelDataArray.map(({
1475
- constraints
1476
- }) => constraints);
1477
- if (!shouldMonitorPixelBasedConstraints(constraints)) {
1478
- // Avoid the overhead of ResizeObserver if no pixel constraints require monitoring
1479
- return;
1480
- }
1481
- if (typeof ResizeObserver === "undefined") {
1482
- console.warn(`WARNING: Pixel based constraints require ResizeObserver but it is not supported by the current browser.`);
1483
- } else {
1484
- const resizeObserver = new ResizeObserver(() => {
1485
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1486
- const {
1487
- onLayout
1488
- } = committedValuesRef.current;
1489
- const nextLayout = validatePanelGroupLayout({
1490
- groupSizePixels,
1491
- layout: prevLayout,
1492
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1493
- });
1494
- if (!areEqual(prevLayout, nextLayout)) {
1495
- setLayout(nextLayout);
1496
- eagerValuesRef.current.layout = nextLayout;
1497
- if (onLayout) {
1498
- onLayout(nextLayout.map(sizePercentage => ({
1499
- sizePercentage,
1500
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1501
- })));
1502
- }
1503
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1504
- }
1505
- });
1506
- resizeObserver.observe(getPanelGroupElement(groupId));
1507
- return () => {
1508
- resizeObserver.disconnect();
1509
- };
1510
- }
1511
- }, [groupId]);
1512
1260
 
1513
1261
  // DEV warnings
1514
1262
  useEffect(() => {
@@ -1539,12 +1287,12 @@ function PanelGroupWithForwardedRef({
1539
1287
  }
1540
1288
  if (!didLogPanelConstraintsWarning) {
1541
1289
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1542
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1543
1290
  for (let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++) {
1291
+ const panelData = panelDataArray[panelIndex];
1292
+ assert(panelData);
1544
1293
  const isValid = validatePanelConstraints({
1545
- groupSizePixels,
1546
1294
  panelConstraints,
1547
- panelId: panelDataArray[panelIndex].id,
1295
+ panelId: panelData.id,
1548
1296
  panelIndex
1549
1297
  });
1550
1298
  if (!isValid) {
@@ -1568,20 +1316,19 @@ function PanelGroupWithForwardedRef({
1568
1316
  if (panelData.constraints.collapsible) {
1569
1317
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1570
1318
  const {
1571
- collapsedSizePercentage,
1572
- panelSizePercentage,
1573
- pivotIndices,
1574
- groupSizePixels
1575
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1576
- if (panelSizePercentage !== collapsedSizePercentage) {
1319
+ collapsedSize = 0,
1320
+ panelSize,
1321
+ pivotIndices
1322
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1323
+ assert(panelSize != null);
1324
+ if (panelSize !== collapsedSize) {
1577
1325
  // Store size before collapse;
1578
1326
  // This is the size that gets restored if the expand() API is used.
1579
- panelSizeBeforeCollapseRef.current.set(panelData.id, panelSizePercentage);
1327
+ panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1580
1328
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1581
- const delta = isLastPanel ? panelSizePercentage - collapsedSizePercentage : collapsedSizePercentage - panelSizePercentage;
1329
+ const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1582
1330
  const nextLayout = adjustLayoutByDelta({
1583
1331
  delta,
1584
- groupSizePixels,
1585
1332
  layout: prevLayout,
1586
1333
  panelConstraints: panelConstraintsArray,
1587
1334
  pivotIndices,
@@ -1591,16 +1338,13 @@ function PanelGroupWithForwardedRef({
1591
1338
  setLayout(nextLayout);
1592
1339
  eagerValuesRef.current.layout = nextLayout;
1593
1340
  if (onLayout) {
1594
- onLayout(nextLayout.map(sizePercentage => ({
1595
- sizePercentage,
1596
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1597
- })));
1341
+ onLayout(nextLayout);
1598
1342
  }
1599
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1343
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1600
1344
  }
1601
1345
  }
1602
1346
  }
1603
- }, [groupId]);
1347
+ }, []);
1604
1348
 
1605
1349
  // External APIs are safe to memoize via committed values ref
1606
1350
  const expandPanel = useCallback(panelData => {
@@ -1614,21 +1358,19 @@ function PanelGroupWithForwardedRef({
1614
1358
  if (panelData.constraints.collapsible) {
1615
1359
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1616
1360
  const {
1617
- collapsedSizePercentage,
1618
- panelSizePercentage,
1619
- minSizePercentage,
1620
- pivotIndices,
1621
- groupSizePixels
1622
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1623
- if (panelSizePercentage === collapsedSizePercentage) {
1361
+ collapsedSize = 0,
1362
+ panelSize,
1363
+ minSize = 0,
1364
+ pivotIndices
1365
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1366
+ if (panelSize === collapsedSize) {
1624
1367
  // Restore this panel to the size it was before it was collapsed, if possible.
1625
- const prevPanelSizePercentage = panelSizeBeforeCollapseRef.current.get(panelData.id);
1626
- const baseSizePercentage = prevPanelSizePercentage != null && prevPanelSizePercentage >= minSizePercentage ? prevPanelSizePercentage : minSizePercentage;
1368
+ const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1369
+ const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1627
1370
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1628
- const delta = isLastPanel ? panelSizePercentage - baseSizePercentage : baseSizePercentage - panelSizePercentage;
1371
+ const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1629
1372
  const nextLayout = adjustLayoutByDelta({
1630
1373
  delta,
1631
- groupSizePixels,
1632
1374
  layout: prevLayout,
1633
1375
  panelConstraints: panelConstraintsArray,
1634
1376
  pivotIndices,
@@ -1638,16 +1380,13 @@ function PanelGroupWithForwardedRef({
1638
1380
  setLayout(nextLayout);
1639
1381
  eagerValuesRef.current.layout = nextLayout;
1640
1382
  if (onLayout) {
1641
- onLayout(nextLayout.map(sizePercentage => ({
1642
- sizePercentage,
1643
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1644
- })));
1383
+ onLayout(nextLayout);
1645
1384
  }
1646
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1385
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1647
1386
  }
1648
1387
  }
1649
1388
  }
1650
- }, [groupId]);
1389
+ }, []);
1651
1390
 
1652
1391
  // External APIs are safe to memoize via committed values ref
1653
1392
  const getPanelSize = useCallback(panelData => {
@@ -1656,14 +1395,11 @@ function PanelGroupWithForwardedRef({
1656
1395
  panelDataArray
1657
1396
  } = eagerValuesRef.current;
1658
1397
  const {
1659
- panelSizePercentage,
1660
- panelSizePixels
1661
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1662
- return {
1663
- sizePercentage: panelSizePercentage,
1664
- sizePixels: panelSizePixels
1665
- };
1666
- }, [groupId]);
1398
+ panelSize
1399
+ } = panelDataHelper(panelDataArray, panelData, layout);
1400
+ assert(panelSize != null);
1401
+ return panelSize;
1402
+ }, []);
1667
1403
 
1668
1404
  // This API should never read from committedValuesRef
1669
1405
  const getPanelStyle = useCallback(panelData => {
@@ -1686,12 +1422,12 @@ function PanelGroupWithForwardedRef({
1686
1422
  panelDataArray
1687
1423
  } = eagerValuesRef.current;
1688
1424
  const {
1689
- collapsedSizePercentage,
1425
+ collapsedSize,
1690
1426
  collapsible,
1691
- panelSizePercentage
1692
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1693
- return collapsible === true && panelSizePercentage === collapsedSizePercentage;
1694
- }, [groupId]);
1427
+ panelSize
1428
+ } = panelDataHelper(panelDataArray, panelData, layout);
1429
+ return collapsible === true && panelSize === collapsedSize;
1430
+ }, []);
1695
1431
 
1696
1432
  // External APIs are safe to memoize via committed values ref
1697
1433
  const isPanelExpanded = useCallback(panelData => {
@@ -1700,12 +1436,13 @@ function PanelGroupWithForwardedRef({
1700
1436
  panelDataArray
1701
1437
  } = eagerValuesRef.current;
1702
1438
  const {
1703
- collapsedSizePercentage,
1439
+ collapsedSize = 0,
1704
1440
  collapsible,
1705
- panelSizePercentage
1706
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1707
- return !collapsible || panelSizePercentage > collapsedSizePercentage;
1708
- }, [groupId]);
1441
+ panelSize
1442
+ } = panelDataHelper(panelDataArray, panelData, layout);
1443
+ assert(panelSize != null);
1444
+ return !collapsible || panelSize > collapsedSize;
1445
+ }, []);
1709
1446
  const registerPanel = useCallback(panelData => {
1710
1447
  const {
1711
1448
  autoSaveId,
@@ -1745,18 +1482,8 @@ function PanelGroupWithForwardedRef({
1745
1482
  if (autoSaveId) {
1746
1483
  unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1747
1484
  }
1748
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1749
- if (groupSizePixels <= 0) {
1750
- if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
1751
- constraints
1752
- }) => constraints))) {
1753
- // Wait until the group has rendered a non-zero size before computing layout.
1754
- return;
1755
- }
1756
- }
1757
1485
  if (unsafeLayout == null) {
1758
1486
  unsafeLayout = calculateUnsafeDefaultLayout({
1759
- groupSizePixels,
1760
1487
  panelDataArray
1761
1488
  });
1762
1489
  }
@@ -1764,7 +1491,6 @@ function PanelGroupWithForwardedRef({
1764
1491
  // Validate even saved layouts in case something has changed since last render
1765
1492
  // e.g. for pixel groups, this could be the size of the window
1766
1493
  const nextLayout = validatePanelGroupLayout({
1767
- groupSizePixels,
1768
1494
  layout: unsafeLayout,
1769
1495
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1770
1496
  });
@@ -1776,12 +1502,9 @@ function PanelGroupWithForwardedRef({
1776
1502
  eagerValuesRef.current.layout = nextLayout;
1777
1503
  if (!areEqual(prevLayout, nextLayout)) {
1778
1504
  if (onLayout) {
1779
- onLayout(nextLayout.map(sizePercentage => ({
1780
- sizePercentage,
1781
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1782
- })));
1505
+ onLayout(nextLayout);
1783
1506
  }
1784
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1507
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1785
1508
  }
1786
1509
  }, []);
1787
1510
  const registerResizeHandle = useCallback(dragHandleId => {
@@ -1791,8 +1514,7 @@ function PanelGroupWithForwardedRef({
1791
1514
  direction,
1792
1515
  dragState,
1793
1516
  id: groupId,
1794
- keyboardResizeByPercentage,
1795
- keyboardResizeByPixels,
1517
+ keyboardResizeBy,
1796
1518
  onLayout
1797
1519
  } = committedValuesRef.current;
1798
1520
  const {
@@ -1803,10 +1525,7 @@ function PanelGroupWithForwardedRef({
1803
1525
  initialLayout
1804
1526
  } = dragState !== null && dragState !== void 0 ? dragState : {};
1805
1527
  const pivotIndices = determinePivotIndices(groupId, dragHandleId);
1806
- let delta = calculateDeltaPercentage(event, groupId, dragHandleId, direction, dragState, {
1807
- percentage: keyboardResizeByPercentage,
1808
- pixels: keyboardResizeByPixels
1809
- });
1528
+ let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
1810
1529
  if (delta === 0) {
1811
1530
  return;
1812
1531
  }
@@ -1816,11 +1535,9 @@ function PanelGroupWithForwardedRef({
1816
1535
  if (document.dir === "rtl" && isHorizontal) {
1817
1536
  delta = -delta;
1818
1537
  }
1819
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1820
1538
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1821
1539
  const nextLayout = adjustLayoutByDelta({
1822
1540
  delta,
1823
- groupSizePixels,
1824
1541
  layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
1825
1542
  panelConstraints,
1826
1543
  pivotIndices,
@@ -1856,18 +1573,15 @@ function PanelGroupWithForwardedRef({
1856
1573
  setLayout(nextLayout);
1857
1574
  eagerValuesRef.current.layout = nextLayout;
1858
1575
  if (onLayout) {
1859
- onLayout(nextLayout.map(sizePercentage => ({
1860
- sizePercentage,
1861
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1862
- })));
1576
+ onLayout(nextLayout);
1863
1577
  }
1864
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1578
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1865
1579
  }
1866
1580
  };
1867
1581
  }, []);
1868
1582
 
1869
1583
  // External APIs are safe to memoize via committed values ref
1870
- const resizePanel = useCallback((panelData, mixedSizes) => {
1584
+ const resizePanel = useCallback((panelData, unsafePanelSize) => {
1871
1585
  const {
1872
1586
  onLayout
1873
1587
  } = committedValuesRef.current;
@@ -1877,16 +1591,14 @@ function PanelGroupWithForwardedRef({
1877
1591
  } = eagerValuesRef.current;
1878
1592
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1879
1593
  const {
1880
- groupSizePixels,
1881
- panelSizePercentage,
1594
+ panelSize,
1882
1595
  pivotIndices
1883
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1884
- const sizePercentage = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
1596
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1597
+ assert(panelSize != null);
1885
1598
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1886
- const delta = isLastPanel ? panelSizePercentage - sizePercentage : sizePercentage - panelSizePercentage;
1599
+ const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1887
1600
  const nextLayout = adjustLayoutByDelta({
1888
1601
  delta,
1889
- groupSizePixels,
1890
1602
  layout: prevLayout,
1891
1603
  panelConstraints: panelConstraintsArray,
1892
1604
  pivotIndices,
@@ -1896,14 +1608,11 @@ function PanelGroupWithForwardedRef({
1896
1608
  setLayout(nextLayout);
1897
1609
  eagerValuesRef.current.layout = nextLayout;
1898
1610
  if (onLayout) {
1899
- onLayout(nextLayout.map(sizePercentage => ({
1900
- sizePercentage,
1901
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1902
- })));
1611
+ onLayout(nextLayout);
1903
1612
  }
1904
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1613
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1905
1614
  }
1906
- }, [groupId]);
1615
+ }, []);
1907
1616
  const startDragging = useCallback((dragHandleId, event) => {
1908
1617
  const {
1909
1618
  direction
@@ -1912,6 +1621,7 @@ function PanelGroupWithForwardedRef({
1912
1621
  layout
1913
1622
  } = eagerValuesRef.current;
1914
1623
  const handleElement = getResizeHandleElement(dragHandleId);
1624
+ assert(handleElement);
1915
1625
  const initialCursorPosition = getResizeEventCursorPosition(direction, event);
1916
1626
  setDragState({
1917
1627
  dragHandleId,
@@ -1930,7 +1640,6 @@ function PanelGroupWithForwardedRef({
1930
1640
  });
1931
1641
  const unregisterPanel = useCallback(panelData => {
1932
1642
  const {
1933
- id: groupId,
1934
1643
  onLayout
1935
1644
  } = committedValuesRef.current;
1936
1645
  const {
@@ -1953,7 +1662,7 @@ function PanelGroupWithForwardedRef({
1953
1662
  const {
1954
1663
  pendingPanelIds
1955
1664
  } = unregisterPanelRef.current;
1956
- const map = panelIdToLastNotifiedMixedSizesMapRef.current;
1665
+ const map = panelIdToLastNotifiedSizeMapRef.current;
1957
1666
 
1958
1667
  // TRICKY
1959
1668
  // Strict effects mode
@@ -1979,16 +1688,13 @@ function PanelGroupWithForwardedRef({
1979
1688
  // The group is unmounting; skip layout calculation.
1980
1689
  return;
1981
1690
  }
1982
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1983
1691
  let unsafeLayout = calculateUnsafeDefaultLayout({
1984
- groupSizePixels,
1985
1692
  panelDataArray
1986
1693
  });
1987
1694
 
1988
1695
  // Validate even saved layouts in case something has changed since last render
1989
1696
  // e.g. for pixel groups, this could be the size of the window
1990
1697
  const nextLayout = validatePanelGroupLayout({
1991
- groupSizePixels,
1992
1698
  layout: unsafeLayout,
1993
1699
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1994
1700
  });
@@ -1996,12 +1702,9 @@ function PanelGroupWithForwardedRef({
1996
1702
  setLayout(nextLayout);
1997
1703
  eagerValuesRef.current.layout = nextLayout;
1998
1704
  if (onLayout) {
1999
- onLayout(nextLayout.map(sizePercentage => ({
2000
- sizePercentage,
2001
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
2002
- })));
1705
+ onLayout(nextLayout);
2003
1706
  }
2004
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1707
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
2005
1708
  }
2006
1709
  }, 0);
2007
1710
  }, []);
@@ -2032,13 +1735,13 @@ function PanelGroupWithForwardedRef({
2032
1735
  return createElement(PanelGroupContext.Provider, {
2033
1736
  value: context
2034
1737
  }, createElement(Type, {
1738
+ ...rest,
2035
1739
  children,
2036
1740
  className: classNameFromProps,
2037
1741
  style: {
2038
1742
  ...style,
2039
1743
  ...styleFromProps
2040
1744
  },
2041
- ...dataAttributes,
2042
1745
  // CSS selectors
2043
1746
  "data-panel-group": "",
2044
1747
  "data-panel-group-direction": direction,
@@ -2051,22 +1754,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
2051
1754
  }));
2052
1755
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
2053
1756
  PanelGroup.displayName = "forwardRef(PanelGroup)";
2054
- function panelDataHelper(groupId, panelDataArray, panelData, layout) {
1757
+ function panelDataHelper(panelDataArray, panelData, layout) {
2055
1758
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
2056
1759
  const panelIndex = panelDataArray.indexOf(panelData);
2057
1760
  const panelConstraints = panelConstraintsArray[panelIndex];
2058
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
2059
- const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
2060
1761
  const isLastPanel = panelIndex === panelDataArray.length - 1;
2061
1762
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
2062
- const panelSizePercentage = layout[panelIndex];
2063
- const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
1763
+ const panelSize = layout[panelIndex];
2064
1764
  return {
2065
- ...percentagePanelConstraints,
2066
- collapsible: panelConstraints.collapsible,
2067
- panelSizePercentage,
2068
- panelSizePixels,
2069
- groupSizePixels,
1765
+ ...panelConstraints,
1766
+ panelSize,
2070
1767
  pivotIndices
2071
1768
  };
2072
1769
  }
@@ -2106,6 +1803,7 @@ function useWindowSplitterResizeHandlerBehavior({
2106
1803
  {
2107
1804
  event.preventDefault();
2108
1805
  const groupId = handleElement.getAttribute("data-panel-group-id");
1806
+ assert(groupId);
2109
1807
  const handles = getResizeHandleElementsForGroup(groupId);
2110
1808
  const index = getResizeHandleElementIndex(groupId, handleId);
2111
1809
  assert(index !== null);
@@ -2126,12 +1824,13 @@ function useWindowSplitterResizeHandlerBehavior({
2126
1824
  function PanelResizeHandle({
2127
1825
  children = null,
2128
1826
  className: classNameFromProps = "",
2129
- dataAttributes,
2130
1827
  disabled = false,
2131
- id: idFromProps = null,
1828
+ id: idFromProps,
2132
1829
  onDragging,
2133
1830
  style: styleFromProps = {},
2134
- tagName: Type = "div"
1831
+ tabIndex = 0,
1832
+ tagName: Type = "div",
1833
+ ...rest
2135
1834
  }) {
2136
1835
  const divElementRef = useRef(null);
2137
1836
 
@@ -2161,8 +1860,9 @@ function PanelResizeHandle({
2161
1860
  const stopDraggingAndBlur = useCallback(() => {
2162
1861
  // Clicking on the drag handle shouldn't leave it focused;
2163
1862
  // That would cause the PanelGroup to think it was still active.
2164
- const div = divElementRef.current;
2165
- div.blur();
1863
+ const divElement = divElementRef.current;
1864
+ assert(divElement);
1865
+ divElement.blur();
2166
1866
  stopDragging();
2167
1867
  const {
2168
1868
  onDragging
@@ -2190,6 +1890,7 @@ function PanelResizeHandle({
2190
1890
  resizeHandler(event);
2191
1891
  };
2192
1892
  const divElement = divElementRef.current;
1893
+ assert(divElement);
2193
1894
  const targetDocument = divElement.ownerDocument;
2194
1895
  targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
2195
1896
  targetDocument.body.addEventListener("mousemove", onMove);
@@ -2217,15 +1918,18 @@ function PanelResizeHandle({
2217
1918
  userSelect: "none"
2218
1919
  };
2219
1920
  return createElement(Type, {
1921
+ ...rest,
2220
1922
  children,
2221
1923
  className: classNameFromProps,
2222
1924
  onBlur: () => setIsFocused(false),
2223
1925
  onFocus: () => setIsFocused(true),
2224
1926
  onMouseDown: event => {
2225
1927
  startDragging(resizeHandleId, event.nativeEvent);
1928
+ const callbacks = callbacksRef.current;
1929
+ assert(callbacks);
2226
1930
  const {
2227
1931
  onDragging
2228
- } = callbacksRef.current;
1932
+ } = callbacks;
2229
1933
  if (onDragging) {
2230
1934
  onDragging(true);
2231
1935
  }
@@ -2235,9 +1939,11 @@ function PanelResizeHandle({
2235
1939
  onTouchEnd: stopDraggingAndBlur,
2236
1940
  onTouchStart: event => {
2237
1941
  startDragging(resizeHandleId, event.nativeEvent);
1942
+ const callbacks = callbacksRef.current;
1943
+ assert(callbacks);
2238
1944
  const {
2239
1945
  onDragging
2240
- } = callbacksRef.current;
1946
+ } = callbacks;
2241
1947
  if (onDragging) {
2242
1948
  onDragging(true);
2243
1949
  }
@@ -2248,8 +1954,7 @@ function PanelResizeHandle({
2248
1954
  ...style,
2249
1955
  ...styleFromProps
2250
1956
  },
2251
- tabIndex: 0,
2252
- ...dataAttributes,
1957
+ tabIndex,
2253
1958
  // CSS selectors
2254
1959
  "data-panel-group-direction": direction,
2255
1960
  "data-panel-group-id": groupId,
@@ -2264,3 +1969,4 @@ PanelResizeHandle.displayName = "PanelResizeHandle";
2264
1969
  exports.Panel = Panel;
2265
1970
  exports.PanelGroup = PanelGroup;
2266
1971
  exports.PanelResizeHandle = PanelResizeHandle;
1972
+ exports.assert = assert;