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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/CHANGELOG.md +5 -0
  3. package/dist/declarations/src/Panel.d.ts +19 -34
  4. package/dist/declarations/src/PanelGroup.d.ts +9 -13
  5. package/dist/declarations/src/PanelResizeHandle.d.ts +5 -7
  6. package/dist/declarations/src/index.d.ts +2 -2
  7. package/dist/declarations/src/types.d.ts +0 -7
  8. package/dist/declarations/src/utils/assert.d.ts +1 -0
  9. package/dist/declarations/src/vendor/react.d.ts +2 -2
  10. package/dist/react-resizable-panels.browser.cjs.js +253 -518
  11. package/dist/react-resizable-panels.browser.cjs.mjs +2 -1
  12. package/dist/react-resizable-panels.browser.development.cjs.js +279 -574
  13. package/dist/react-resizable-panels.browser.development.cjs.mjs +2 -1
  14. package/dist/react-resizable-panels.browser.development.esm.js +279 -575
  15. package/dist/react-resizable-panels.browser.esm.js +253 -519
  16. package/dist/react-resizable-panels.cjs.d.ts +88 -1
  17. package/dist/react-resizable-panels.cjs.d.ts.map +1 -1
  18. package/dist/react-resizable-panels.cjs.js +1481 -1983
  19. package/dist/react-resizable-panels.cjs.js.map +1 -1
  20. package/dist/react-resizable-panels.cjs.mjs +2 -1
  21. package/dist/react-resizable-panels.development.cjs.js +281 -576
  22. package/dist/react-resizable-panels.development.cjs.mjs +2 -1
  23. package/dist/react-resizable-panels.development.esm.js +281 -577
  24. package/dist/react-resizable-panels.development.node.cjs.js +267 -502
  25. package/dist/react-resizable-panels.development.node.cjs.mjs +2 -1
  26. package/dist/react-resizable-panels.development.node.esm.js +267 -503
  27. package/dist/react-resizable-panels.esm.js +1476 -1959
  28. package/dist/react-resizable-panels.esm.js.map +1 -1
  29. package/dist/react-resizable-panels.node.cjs.js +239 -444
  30. package/dist/react-resizable-panels.node.cjs.mjs +2 -1
  31. package/dist/react-resizable-panels.node.esm.js +239 -445
  32. package/package.json +1 -1
  33. package/src/Panel.test.tsx +74 -73
  34. package/src/Panel.ts +44 -68
  35. package/src/PanelGroup.test.tsx +43 -42
  36. package/src/PanelGroup.ts +221 -411
  37. package/src/PanelGroupContext.ts +2 -3
  38. package/src/PanelResizeHandle.test.tsx +68 -0
  39. package/src/PanelResizeHandle.ts +31 -22
  40. package/src/hooks/useWindowSplitterBehavior.ts +2 -1
  41. package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +22 -33
  42. package/src/index.ts +4 -3
  43. package/src/types.ts +0 -9
  44. package/src/utils/adjustLayoutByDelta.test.ts +206 -336
  45. package/src/utils/adjustLayoutByDelta.ts +59 -51
  46. package/src/utils/assert.ts +1 -1
  47. package/src/utils/calculateAriaValues.test.ts +6 -11
  48. package/src/utils/calculateAriaValues.ts +7 -29
  49. package/src/utils/calculateDeltaPercentage.ts +8 -15
  50. package/src/utils/calculateDragOffsetPercentage.ts +11 -5
  51. package/src/utils/calculateUnsafeDefaultLayout.test.ts +4 -9
  52. package/src/utils/calculateUnsafeDefaultLayout.ts +13 -18
  53. package/src/utils/callPanelCallbacks.ts +11 -46
  54. package/src/utils/getResizeEventCursorPosition.ts +2 -0
  55. package/src/utils/resizePanel.test.ts +6 -52
  56. package/src/utils/resizePanel.ts +24 -46
  57. package/src/utils/test-utils.ts +6 -7
  58. package/src/utils/validatePanelConstraints.test.ts +12 -65
  59. package/src/utils/validatePanelConstraints.ts +26 -67
  60. package/src/utils/validatePanelGroupLayout.test.ts +27 -142
  61. package/src/utils/validatePanelGroupLayout.ts +17 -13
  62. package/src/vendor/react.ts +2 -0
  63. package/src/utils/computePercentagePanelConstraints.test.ts +0 -98
  64. package/src/utils/computePercentagePanelConstraints.ts +0 -56
  65. package/src/utils/convertPercentageToPixels.test.ts +0 -9
  66. package/src/utils/convertPercentageToPixels.ts +0 -6
  67. package/src/utils/convertPixelConstraintsToPercentages.test.ts +0 -47
  68. package/src/utils/convertPixelConstraintsToPercentages.ts +0 -72
  69. package/src/utils/convertPixelsToPercentage.test.ts +0 -9
  70. package/src/utils/convertPixelsToPercentage.ts +0 -6
  71. package/src/utils/getPercentageSizeFromMixedSizes.test.ts +0 -47
  72. package/src/utils/getPercentageSizeFromMixedSizes.ts +0 -15
  73. package/src/utils/shouldMonitorPixelBasedConstraints.test.ts +0 -23
  74. package/src/utils/shouldMonitorPixelBasedConstraints.ts +0 -13
@@ -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
  }
@@ -1193,74 +1032,39 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
1193
1032
  }
1194
1033
  }
1195
1034
 
1196
- function shouldMonitorPixelBasedConstraints(constraints) {
1197
- return constraints.some(constraints => {
1198
- return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
1199
- });
1200
- }
1201
-
1202
1035
  function validatePanelConstraints({
1203
- groupSizePixels,
1204
- panelConstraints,
1036
+ panelConstraints: panelConstraintsArray,
1205
1037
  panelId,
1206
1038
  panelIndex
1207
1039
  }) {
1208
1040
  {
1209
1041
  const warnings = [];
1210
- {
1211
- const {
1212
- collapsedSizePercentage,
1213
- collapsedSizePixels,
1214
- defaultSizePercentage,
1215
- defaultSizePixels,
1216
- maxSizePercentage,
1217
- maxSizePixels,
1218
- minSizePercentage,
1219
- minSizePixels
1220
- } = panelConstraints[panelIndex];
1221
- const conflictingUnits = [];
1222
- if (collapsedSizePercentage != null && collapsedSizePixels != null) {
1223
- conflictingUnits.push("collapsed size");
1224
- }
1225
- if (defaultSizePercentage != null && defaultSizePixels != null) {
1226
- conflictingUnits.push("default size");
1227
- }
1228
- if (maxSizePercentage != null && maxSizePixels != null) {
1229
- conflictingUnits.push("max size");
1230
- }
1231
- if (minSizePercentage != null && minSizePixels != null) {
1232
- conflictingUnits.push("min size");
1233
- }
1234
- if (conflictingUnits.length > 0) {
1235
- warnings.push(`should not specify both percentage and pixel units for: ${conflictingUnits.join(", ")}`);
1236
- }
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}%)`);
1237
1052
  }
1238
- {
1239
- const {
1240
- collapsedSizePercentage,
1241
- defaultSizePercentage,
1242
- maxSizePercentage,
1243
- minSizePercentage
1244
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
1245
- if (minSizePercentage > maxSizePercentage) {
1246
- warnings.push(`min size (${minSizePercentage}%) should not be greater than max size (${maxSizePercentage}%)`);
1247
- }
1248
- if (defaultSizePercentage != null) {
1249
- if (defaultSizePercentage < 0) {
1250
- warnings.push("default size should not be less than 0");
1251
- } else if (defaultSizePercentage < minSizePercentage) {
1252
- warnings.push("default size should not be less than min size");
1253
- }
1254
- if (defaultSizePercentage > 100) {
1255
- warnings.push("default size should not be greater than 100");
1256
- } else if (defaultSizePercentage > maxSizePercentage) {
1257
- warnings.push("default size should not be greater than max size");
1258
- }
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");
1259
1058
  }
1260
- if (collapsedSizePercentage > minSizePercentage) {
1261
- 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");
1262
1063
  }
1263
1064
  }
1065
+ if (collapsedSize > minSize) {
1066
+ warnings.push("collapsed size should not be greater than min size");
1067
+ }
1264
1068
  if (warnings.length > 0) {
1265
1069
  const name = panelId != null ? `Panel "${panelId}"` : "Panel";
1266
1070
  console.warn(`${name} has an invalid configuration:\n\n${warnings.join("\n")}`);
@@ -1272,20 +1076,26 @@ function validatePanelConstraints({
1272
1076
 
1273
1077
  // All units must be in percentages; pixel values should be pre-converted
1274
1078
  function validatePanelGroupLayout({
1275
- groupSizePixels,
1276
1079
  layout: prevLayout,
1277
1080
  panelConstraints
1278
1081
  }) {
1279
1082
  const nextLayout = [...prevLayout];
1083
+ const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
1280
1084
 
1281
1085
  // Validate layout expectations
1282
1086
  if (nextLayout.length !== panelConstraints.length) {
1283
1087
  throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
1284
- } else if (!fuzzyNumbersEqual(nextLayout.reduce((accumulated, current) => accumulated + current, 0), 100)) {
1088
+ } else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
1285
1089
  // This is not ideal so we should warn about it, but it may be recoverable in some cases
1286
1090
  // (especially if the amount is small)
1287
1091
  {
1288
- 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;
1289
1099
  }
1290
1100
  }
1291
1101
  let remainingSize = 0;
@@ -1293,8 +1103,8 @@ function validatePanelGroupLayout({
1293
1103
  // First pass: Validate the proposed layout given each panel's constraints
1294
1104
  for (let index = 0; index < panelConstraints.length; index++) {
1295
1105
  const unsafeSize = nextLayout[index];
1106
+ assert(unsafeSize != null);
1296
1107
  const safeSize = resizePanel({
1297
- groupSizePixels,
1298
1108
  panelConstraints,
1299
1109
  panelIndex: index,
1300
1110
  size: unsafeSize
@@ -1310,9 +1120,9 @@ function validatePanelGroupLayout({
1310
1120
  if (!fuzzyNumbersEqual(remainingSize, 0)) {
1311
1121
  for (let index = 0; index < panelConstraints.length; index++) {
1312
1122
  const prevSize = nextLayout[index];
1123
+ assert(prevSize != null);
1313
1124
  const unsafeSize = prevSize + remainingSize;
1314
1125
  const safeSize = resizePanel({
1315
- groupSizePixels,
1316
1126
  panelConstraints,
1317
1127
  panelIndex: index,
1318
1128
  size: unsafeSize
@@ -1347,21 +1157,20 @@ function PanelGroupWithForwardedRef({
1347
1157
  autoSaveId = null,
1348
1158
  children,
1349
1159
  className: classNameFromProps = "",
1350
- dataAttributes,
1351
1160
  direction,
1352
1161
  forwardedRef,
1353
- id: idFromProps,
1162
+ id: idFromProps = null,
1354
1163
  onLayout = null,
1355
- keyboardResizeByPercentage = null,
1356
- keyboardResizeByPixels = null,
1164
+ keyboardResizeBy = null,
1357
1165
  storage = defaultStorage,
1358
1166
  style: styleFromProps,
1359
- tagName: Type = "div"
1167
+ tagName: Type = "div",
1168
+ ...rest
1360
1169
  }) {
1361
1170
  const groupId = useUniqueId(idFromProps);
1362
1171
  const [dragState, setDragState] = useState(null);
1363
1172
  const [layout, setLayout] = useState([]);
1364
- const panelIdToLastNotifiedMixedSizesMapRef = useRef({});
1173
+ const panelIdToLastNotifiedSizeMapRef = useRef({});
1365
1174
  const panelSizeBeforeCollapseRef = useRef(new Map());
1366
1175
  const prevDeltaRef = useRef(0);
1367
1176
  const committedValuesRef = useRef({
@@ -1369,8 +1178,7 @@ function PanelGroupWithForwardedRef({
1369
1178
  direction,
1370
1179
  dragState,
1371
1180
  id: groupId,
1372
- keyboardResizeByPercentage,
1373
- keyboardResizeByPixels,
1181
+ keyboardResizeBy,
1374
1182
  onLayout,
1375
1183
  storage
1376
1184
  });
@@ -1386,33 +1194,20 @@ function PanelGroupWithForwardedRef({
1386
1194
  useImperativeHandle(forwardedRef, () => ({
1387
1195
  getId: () => committedValuesRef.current.id,
1388
1196
  getLayout: () => {
1389
- const {
1390
- id: groupId
1391
- } = committedValuesRef.current;
1392
1197
  const {
1393
1198
  layout
1394
1199
  } = eagerValuesRef.current;
1395
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1396
- return layout.map(sizePercentage => {
1397
- return {
1398
- sizePercentage,
1399
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1400
- };
1401
- });
1200
+ return layout;
1402
1201
  },
1403
- setLayout: mixedSizes => {
1202
+ setLayout: unsafeLayout => {
1404
1203
  const {
1405
- id: groupId,
1406
1204
  onLayout
1407
1205
  } = committedValuesRef.current;
1408
1206
  const {
1409
1207
  layout: prevLayout,
1410
1208
  panelDataArray
1411
1209
  } = eagerValuesRef.current;
1412
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1413
- const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
1414
1210
  const safeLayout = validatePanelGroupLayout({
1415
- groupSizePixels,
1416
1211
  layout: unsafeLayout,
1417
1212
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1418
1213
  });
@@ -1420,12 +1215,9 @@ function PanelGroupWithForwardedRef({
1420
1215
  setLayout(safeLayout);
1421
1216
  eagerValuesRef.current.layout = safeLayout;
1422
1217
  if (onLayout) {
1423
- onLayout(safeLayout.map(sizePercentage => ({
1424
- sizePercentage,
1425
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1426
- })));
1218
+ onLayout(safeLayout);
1427
1219
  }
1428
- callPanelCallbacks(groupId, panelDataArray, safeLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1220
+ callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
1429
1221
  }
1430
1222
  }
1431
1223
  }), []);
@@ -1436,11 +1228,7 @@ function PanelGroupWithForwardedRef({
1436
1228
  committedValuesRef.current.id = groupId;
1437
1229
  committedValuesRef.current.onLayout = onLayout;
1438
1230
  committedValuesRef.current.storage = storage;
1439
-
1440
- // panelDataArray and layout are updated in-sync with scheduled state updates.
1441
- // TODO [217] Move these values into a separate ref
1442
1231
  });
1443
-
1444
1232
  useWindowSplitterPanelGroupBehavior({
1445
1233
  committedValuesRef,
1446
1234
  eagerValuesRef,
@@ -1459,57 +1247,16 @@ function PanelGroupWithForwardedRef({
1459
1247
  if (layout.length === 0 || layout.length !== panelDataArray.length) {
1460
1248
  return;
1461
1249
  }
1250
+ let debouncedSave = debounceMap[autoSaveId];
1462
1251
 
1463
1252
  // Limit the frequency of localStorage updates.
1464
- if (!debounceMap[autoSaveId]) {
1465
- debounceMap[autoSaveId] = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1253
+ if (debouncedSave == null) {
1254
+ debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1255
+ debounceMap[autoSaveId] = debouncedSave;
1466
1256
  }
1467
- debounceMap[autoSaveId](autoSaveId, panelDataArray, layout, storage);
1257
+ debouncedSave(autoSaveId, panelDataArray, layout, storage);
1468
1258
  }
1469
1259
  }, [autoSaveId, layout, storage]);
1470
- useIsomorphicLayoutEffect(() => {
1471
- const {
1472
- layout: prevLayout,
1473
- panelDataArray
1474
- } = eagerValuesRef.current;
1475
- const constraints = panelDataArray.map(({
1476
- constraints
1477
- }) => constraints);
1478
- if (!shouldMonitorPixelBasedConstraints(constraints)) {
1479
- // Avoid the overhead of ResizeObserver if no pixel constraints require monitoring
1480
- return;
1481
- }
1482
- if (typeof ResizeObserver === "undefined") {
1483
- console.warn(`WARNING: Pixel based constraints require ResizeObserver but it is not supported by the current browser.`);
1484
- } else {
1485
- const resizeObserver = new ResizeObserver(() => {
1486
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1487
- const {
1488
- onLayout
1489
- } = committedValuesRef.current;
1490
- const nextLayout = validatePanelGroupLayout({
1491
- groupSizePixels,
1492
- layout: prevLayout,
1493
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1494
- });
1495
- if (!areEqual(prevLayout, nextLayout)) {
1496
- setLayout(nextLayout);
1497
- eagerValuesRef.current.layout = nextLayout;
1498
- if (onLayout) {
1499
- onLayout(nextLayout.map(sizePercentage => ({
1500
- sizePercentage,
1501
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1502
- })));
1503
- }
1504
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1505
- }
1506
- });
1507
- resizeObserver.observe(getPanelGroupElement(groupId));
1508
- return () => {
1509
- resizeObserver.disconnect();
1510
- };
1511
- }
1512
- }, [groupId]);
1513
1260
 
1514
1261
  // DEV warnings
1515
1262
  useEffect(() => {
@@ -1540,12 +1287,12 @@ function PanelGroupWithForwardedRef({
1540
1287
  }
1541
1288
  if (!didLogPanelConstraintsWarning) {
1542
1289
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1543
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1544
1290
  for (let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++) {
1291
+ const panelData = panelDataArray[panelIndex];
1292
+ assert(panelData);
1545
1293
  const isValid = validatePanelConstraints({
1546
- groupSizePixels,
1547
1294
  panelConstraints,
1548
- panelId: panelDataArray[panelIndex].id,
1295
+ panelId: panelData.id,
1549
1296
  panelIndex
1550
1297
  });
1551
1298
  if (!isValid) {
@@ -1569,20 +1316,19 @@ function PanelGroupWithForwardedRef({
1569
1316
  if (panelData.constraints.collapsible) {
1570
1317
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1571
1318
  const {
1572
- collapsedSizePercentage,
1573
- panelSizePercentage,
1574
- pivotIndices,
1575
- groupSizePixels
1576
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1577
- if (panelSizePercentage !== collapsedSizePercentage) {
1319
+ collapsedSize = 0,
1320
+ panelSize,
1321
+ pivotIndices
1322
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1323
+ assert(panelSize != null);
1324
+ if (panelSize !== collapsedSize) {
1578
1325
  // Store size before collapse;
1579
1326
  // This is the size that gets restored if the expand() API is used.
1580
- panelSizeBeforeCollapseRef.current.set(panelData.id, panelSizePercentage);
1327
+ panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1581
1328
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1582
- const delta = isLastPanel ? panelSizePercentage - collapsedSizePercentage : collapsedSizePercentage - panelSizePercentage;
1329
+ const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1583
1330
  const nextLayout = adjustLayoutByDelta({
1584
1331
  delta,
1585
- groupSizePixels,
1586
1332
  layout: prevLayout,
1587
1333
  panelConstraints: panelConstraintsArray,
1588
1334
  pivotIndices,
@@ -1592,16 +1338,13 @@ function PanelGroupWithForwardedRef({
1592
1338
  setLayout(nextLayout);
1593
1339
  eagerValuesRef.current.layout = nextLayout;
1594
1340
  if (onLayout) {
1595
- onLayout(nextLayout.map(sizePercentage => ({
1596
- sizePercentage,
1597
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1598
- })));
1341
+ onLayout(nextLayout);
1599
1342
  }
1600
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1343
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1601
1344
  }
1602
1345
  }
1603
1346
  }
1604
- }, [groupId]);
1347
+ }, []);
1605
1348
 
1606
1349
  // External APIs are safe to memoize via committed values ref
1607
1350
  const expandPanel = useCallback(panelData => {
@@ -1615,21 +1358,19 @@ function PanelGroupWithForwardedRef({
1615
1358
  if (panelData.constraints.collapsible) {
1616
1359
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1617
1360
  const {
1618
- collapsedSizePercentage,
1619
- panelSizePercentage,
1620
- minSizePercentage,
1621
- pivotIndices,
1622
- groupSizePixels
1623
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1624
- if (panelSizePercentage === collapsedSizePercentage) {
1361
+ collapsedSize = 0,
1362
+ panelSize,
1363
+ minSize = 0,
1364
+ pivotIndices
1365
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1366
+ if (panelSize === collapsedSize) {
1625
1367
  // Restore this panel to the size it was before it was collapsed, if possible.
1626
- const prevPanelSizePercentage = panelSizeBeforeCollapseRef.current.get(panelData.id);
1627
- 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;
1628
1370
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1629
- const delta = isLastPanel ? panelSizePercentage - baseSizePercentage : baseSizePercentage - panelSizePercentage;
1371
+ const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1630
1372
  const nextLayout = adjustLayoutByDelta({
1631
1373
  delta,
1632
- groupSizePixels,
1633
1374
  layout: prevLayout,
1634
1375
  panelConstraints: panelConstraintsArray,
1635
1376
  pivotIndices,
@@ -1639,16 +1380,13 @@ function PanelGroupWithForwardedRef({
1639
1380
  setLayout(nextLayout);
1640
1381
  eagerValuesRef.current.layout = nextLayout;
1641
1382
  if (onLayout) {
1642
- onLayout(nextLayout.map(sizePercentage => ({
1643
- sizePercentage,
1644
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1645
- })));
1383
+ onLayout(nextLayout);
1646
1384
  }
1647
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1385
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1648
1386
  }
1649
1387
  }
1650
1388
  }
1651
- }, [groupId]);
1389
+ }, []);
1652
1390
 
1653
1391
  // External APIs are safe to memoize via committed values ref
1654
1392
  const getPanelSize = useCallback(panelData => {
@@ -1657,14 +1395,11 @@ function PanelGroupWithForwardedRef({
1657
1395
  panelDataArray
1658
1396
  } = eagerValuesRef.current;
1659
1397
  const {
1660
- panelSizePercentage,
1661
- panelSizePixels
1662
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1663
- return {
1664
- sizePercentage: panelSizePercentage,
1665
- sizePixels: panelSizePixels
1666
- };
1667
- }, [groupId]);
1398
+ panelSize
1399
+ } = panelDataHelper(panelDataArray, panelData, layout);
1400
+ assert(panelSize != null);
1401
+ return panelSize;
1402
+ }, []);
1668
1403
 
1669
1404
  // This API should never read from committedValuesRef
1670
1405
  const getPanelStyle = useCallback(panelData => {
@@ -1687,12 +1422,12 @@ function PanelGroupWithForwardedRef({
1687
1422
  panelDataArray
1688
1423
  } = eagerValuesRef.current;
1689
1424
  const {
1690
- collapsedSizePercentage,
1425
+ collapsedSize,
1691
1426
  collapsible,
1692
- panelSizePercentage
1693
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1694
- return collapsible === true && panelSizePercentage === collapsedSizePercentage;
1695
- }, [groupId]);
1427
+ panelSize
1428
+ } = panelDataHelper(panelDataArray, panelData, layout);
1429
+ return collapsible === true && panelSize === collapsedSize;
1430
+ }, []);
1696
1431
 
1697
1432
  // External APIs are safe to memoize via committed values ref
1698
1433
  const isPanelExpanded = useCallback(panelData => {
@@ -1701,12 +1436,13 @@ function PanelGroupWithForwardedRef({
1701
1436
  panelDataArray
1702
1437
  } = eagerValuesRef.current;
1703
1438
  const {
1704
- collapsedSizePercentage,
1439
+ collapsedSize = 0,
1705
1440
  collapsible,
1706
- panelSizePercentage
1707
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1708
- return !collapsible || panelSizePercentage > collapsedSizePercentage;
1709
- }, [groupId]);
1441
+ panelSize
1442
+ } = panelDataHelper(panelDataArray, panelData, layout);
1443
+ assert(panelSize != null);
1444
+ return !collapsible || panelSize > collapsedSize;
1445
+ }, []);
1710
1446
  const registerPanel = useCallback(panelData => {
1711
1447
  const {
1712
1448
  autoSaveId,
@@ -1746,18 +1482,8 @@ function PanelGroupWithForwardedRef({
1746
1482
  if (autoSaveId) {
1747
1483
  unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1748
1484
  }
1749
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1750
- if (groupSizePixels <= 0) {
1751
- if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
1752
- constraints
1753
- }) => constraints))) {
1754
- // Wait until the group has rendered a non-zero size before computing layout.
1755
- return;
1756
- }
1757
- }
1758
1485
  if (unsafeLayout == null) {
1759
1486
  unsafeLayout = calculateUnsafeDefaultLayout({
1760
- groupSizePixels,
1761
1487
  panelDataArray
1762
1488
  });
1763
1489
  }
@@ -1765,7 +1491,6 @@ function PanelGroupWithForwardedRef({
1765
1491
  // Validate even saved layouts in case something has changed since last render
1766
1492
  // e.g. for pixel groups, this could be the size of the window
1767
1493
  const nextLayout = validatePanelGroupLayout({
1768
- groupSizePixels,
1769
1494
  layout: unsafeLayout,
1770
1495
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1771
1496
  });
@@ -1777,12 +1502,9 @@ function PanelGroupWithForwardedRef({
1777
1502
  eagerValuesRef.current.layout = nextLayout;
1778
1503
  if (!areEqual(prevLayout, nextLayout)) {
1779
1504
  if (onLayout) {
1780
- onLayout(nextLayout.map(sizePercentage => ({
1781
- sizePercentage,
1782
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1783
- })));
1505
+ onLayout(nextLayout);
1784
1506
  }
1785
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1507
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1786
1508
  }
1787
1509
  }, []);
1788
1510
  const registerResizeHandle = useCallback(dragHandleId => {
@@ -1792,8 +1514,7 @@ function PanelGroupWithForwardedRef({
1792
1514
  direction,
1793
1515
  dragState,
1794
1516
  id: groupId,
1795
- keyboardResizeByPercentage,
1796
- keyboardResizeByPixels,
1517
+ keyboardResizeBy,
1797
1518
  onLayout
1798
1519
  } = committedValuesRef.current;
1799
1520
  const {
@@ -1804,10 +1525,7 @@ function PanelGroupWithForwardedRef({
1804
1525
  initialLayout
1805
1526
  } = dragState !== null && dragState !== void 0 ? dragState : {};
1806
1527
  const pivotIndices = determinePivotIndices(groupId, dragHandleId);
1807
- let delta = calculateDeltaPercentage(event, groupId, dragHandleId, direction, dragState, {
1808
- percentage: keyboardResizeByPercentage,
1809
- pixels: keyboardResizeByPixels
1810
- });
1528
+ let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
1811
1529
  if (delta === 0) {
1812
1530
  return;
1813
1531
  }
@@ -1817,11 +1535,9 @@ function PanelGroupWithForwardedRef({
1817
1535
  if (document.dir === "rtl" && isHorizontal) {
1818
1536
  delta = -delta;
1819
1537
  }
1820
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1821
1538
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1822
1539
  const nextLayout = adjustLayoutByDelta({
1823
1540
  delta,
1824
- groupSizePixels,
1825
1541
  layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
1826
1542
  panelConstraints,
1827
1543
  pivotIndices,
@@ -1857,18 +1573,15 @@ function PanelGroupWithForwardedRef({
1857
1573
  setLayout(nextLayout);
1858
1574
  eagerValuesRef.current.layout = nextLayout;
1859
1575
  if (onLayout) {
1860
- onLayout(nextLayout.map(sizePercentage => ({
1861
- sizePercentage,
1862
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1863
- })));
1576
+ onLayout(nextLayout);
1864
1577
  }
1865
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1578
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1866
1579
  }
1867
1580
  };
1868
1581
  }, []);
1869
1582
 
1870
1583
  // External APIs are safe to memoize via committed values ref
1871
- const resizePanel = useCallback((panelData, mixedSizes) => {
1584
+ const resizePanel = useCallback((panelData, unsafePanelSize) => {
1872
1585
  const {
1873
1586
  onLayout
1874
1587
  } = committedValuesRef.current;
@@ -1878,16 +1591,14 @@ function PanelGroupWithForwardedRef({
1878
1591
  } = eagerValuesRef.current;
1879
1592
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1880
1593
  const {
1881
- groupSizePixels,
1882
- panelSizePercentage,
1594
+ panelSize,
1883
1595
  pivotIndices
1884
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1885
- const sizePercentage = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
1596
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1597
+ assert(panelSize != null);
1886
1598
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1887
- const delta = isLastPanel ? panelSizePercentage - sizePercentage : sizePercentage - panelSizePercentage;
1599
+ const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1888
1600
  const nextLayout = adjustLayoutByDelta({
1889
1601
  delta,
1890
- groupSizePixels,
1891
1602
  layout: prevLayout,
1892
1603
  panelConstraints: panelConstraintsArray,
1893
1604
  pivotIndices,
@@ -1897,14 +1608,11 @@ function PanelGroupWithForwardedRef({
1897
1608
  setLayout(nextLayout);
1898
1609
  eagerValuesRef.current.layout = nextLayout;
1899
1610
  if (onLayout) {
1900
- onLayout(nextLayout.map(sizePercentage => ({
1901
- sizePercentage,
1902
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1903
- })));
1611
+ onLayout(nextLayout);
1904
1612
  }
1905
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1613
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1906
1614
  }
1907
- }, [groupId]);
1615
+ }, []);
1908
1616
  const startDragging = useCallback((dragHandleId, event) => {
1909
1617
  const {
1910
1618
  direction
@@ -1913,6 +1621,7 @@ function PanelGroupWithForwardedRef({
1913
1621
  layout
1914
1622
  } = eagerValuesRef.current;
1915
1623
  const handleElement = getResizeHandleElement(dragHandleId);
1624
+ assert(handleElement);
1916
1625
  const initialCursorPosition = getResizeEventCursorPosition(direction, event);
1917
1626
  setDragState({
1918
1627
  dragHandleId,
@@ -1931,7 +1640,6 @@ function PanelGroupWithForwardedRef({
1931
1640
  });
1932
1641
  const unregisterPanel = useCallback(panelData => {
1933
1642
  const {
1934
- id: groupId,
1935
1643
  onLayout
1936
1644
  } = committedValuesRef.current;
1937
1645
  const {
@@ -1954,7 +1662,7 @@ function PanelGroupWithForwardedRef({
1954
1662
  const {
1955
1663
  pendingPanelIds
1956
1664
  } = unregisterPanelRef.current;
1957
- const map = panelIdToLastNotifiedMixedSizesMapRef.current;
1665
+ const map = panelIdToLastNotifiedSizeMapRef.current;
1958
1666
 
1959
1667
  // TRICKY
1960
1668
  // Strict effects mode
@@ -1963,7 +1671,7 @@ function PanelGroupWithForwardedRef({
1963
1671
  pendingPanelIds.delete(panelId);
1964
1672
  if (panelDataArray.find(({
1965
1673
  id
1966
- }) => id === panelId) == null) {
1674
+ }) => id === panelId) != null) {
1967
1675
  unmountDueToStrictMode = true;
1968
1676
 
1969
1677
  // TRICKY
@@ -1980,16 +1688,13 @@ function PanelGroupWithForwardedRef({
1980
1688
  // The group is unmounting; skip layout calculation.
1981
1689
  return;
1982
1690
  }
1983
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1984
1691
  let unsafeLayout = calculateUnsafeDefaultLayout({
1985
- groupSizePixels,
1986
1692
  panelDataArray
1987
1693
  });
1988
1694
 
1989
1695
  // Validate even saved layouts in case something has changed since last render
1990
1696
  // e.g. for pixel groups, this could be the size of the window
1991
1697
  const nextLayout = validatePanelGroupLayout({
1992
- groupSizePixels,
1993
1698
  layout: unsafeLayout,
1994
1699
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1995
1700
  });
@@ -1997,12 +1702,9 @@ function PanelGroupWithForwardedRef({
1997
1702
  setLayout(nextLayout);
1998
1703
  eagerValuesRef.current.layout = nextLayout;
1999
1704
  if (onLayout) {
2000
- onLayout(nextLayout.map(sizePercentage => ({
2001
- sizePercentage,
2002
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
2003
- })));
1705
+ onLayout(nextLayout);
2004
1706
  }
2005
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1707
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
2006
1708
  }
2007
1709
  }, 0);
2008
1710
  }, []);
@@ -2033,13 +1735,13 @@ function PanelGroupWithForwardedRef({
2033
1735
  return createElement(PanelGroupContext.Provider, {
2034
1736
  value: context
2035
1737
  }, createElement(Type, {
1738
+ ...rest,
2036
1739
  children,
2037
1740
  className: classNameFromProps,
2038
1741
  style: {
2039
1742
  ...style,
2040
1743
  ...styleFromProps
2041
1744
  },
2042
- ...dataAttributes,
2043
1745
  // CSS selectors
2044
1746
  "data-panel-group": "",
2045
1747
  "data-panel-group-direction": direction,
@@ -2052,22 +1754,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
2052
1754
  }));
2053
1755
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
2054
1756
  PanelGroup.displayName = "forwardRef(PanelGroup)";
2055
- function panelDataHelper(groupId, panelDataArray, panelData, layout) {
1757
+ function panelDataHelper(panelDataArray, panelData, layout) {
2056
1758
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
2057
1759
  const panelIndex = panelDataArray.indexOf(panelData);
2058
1760
  const panelConstraints = panelConstraintsArray[panelIndex];
2059
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
2060
- const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
2061
1761
  const isLastPanel = panelIndex === panelDataArray.length - 1;
2062
1762
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
2063
- const panelSizePercentage = layout[panelIndex];
2064
- const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
1763
+ const panelSize = layout[panelIndex];
2065
1764
  return {
2066
- ...percentagePanelConstraints,
2067
- collapsible: panelConstraints.collapsible,
2068
- panelSizePercentage,
2069
- panelSizePixels,
2070
- groupSizePixels,
1765
+ ...panelConstraints,
1766
+ panelSize,
2071
1767
  pivotIndices
2072
1768
  };
2073
1769
  }
@@ -2107,6 +1803,7 @@ function useWindowSplitterResizeHandlerBehavior({
2107
1803
  {
2108
1804
  event.preventDefault();
2109
1805
  const groupId = handleElement.getAttribute("data-panel-group-id");
1806
+ assert(groupId);
2110
1807
  const handles = getResizeHandleElementsForGroup(groupId);
2111
1808
  const index = getResizeHandleElementIndex(groupId, handleId);
2112
1809
  assert(index !== null);
@@ -2127,12 +1824,13 @@ function useWindowSplitterResizeHandlerBehavior({
2127
1824
  function PanelResizeHandle({
2128
1825
  children = null,
2129
1826
  className: classNameFromProps = "",
2130
- dataAttributes,
2131
1827
  disabled = false,
2132
- id: idFromProps = null,
1828
+ id: idFromProps,
2133
1829
  onDragging,
2134
1830
  style: styleFromProps = {},
2135
- tagName: Type = "div"
1831
+ tabIndex = 0,
1832
+ tagName: Type = "div",
1833
+ ...rest
2136
1834
  }) {
2137
1835
  const divElementRef = useRef(null);
2138
1836
 
@@ -2162,8 +1860,9 @@ function PanelResizeHandle({
2162
1860
  const stopDraggingAndBlur = useCallback(() => {
2163
1861
  // Clicking on the drag handle shouldn't leave it focused;
2164
1862
  // That would cause the PanelGroup to think it was still active.
2165
- const div = divElementRef.current;
2166
- div.blur();
1863
+ const divElement = divElementRef.current;
1864
+ assert(divElement);
1865
+ divElement.blur();
2167
1866
  stopDragging();
2168
1867
  const {
2169
1868
  onDragging
@@ -2191,6 +1890,7 @@ function PanelResizeHandle({
2191
1890
  resizeHandler(event);
2192
1891
  };
2193
1892
  const divElement = divElementRef.current;
1893
+ assert(divElement);
2194
1894
  const targetDocument = divElement.ownerDocument;
2195
1895
  targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
2196
1896
  targetDocument.body.addEventListener("mousemove", onMove);
@@ -2218,15 +1918,18 @@ function PanelResizeHandle({
2218
1918
  userSelect: "none"
2219
1919
  };
2220
1920
  return createElement(Type, {
1921
+ ...rest,
2221
1922
  children,
2222
1923
  className: classNameFromProps,
2223
1924
  onBlur: () => setIsFocused(false),
2224
1925
  onFocus: () => setIsFocused(true),
2225
1926
  onMouseDown: event => {
2226
1927
  startDragging(resizeHandleId, event.nativeEvent);
1928
+ const callbacks = callbacksRef.current;
1929
+ assert(callbacks);
2227
1930
  const {
2228
1931
  onDragging
2229
- } = callbacksRef.current;
1932
+ } = callbacks;
2230
1933
  if (onDragging) {
2231
1934
  onDragging(true);
2232
1935
  }
@@ -2236,9 +1939,11 @@ function PanelResizeHandle({
2236
1939
  onTouchEnd: stopDraggingAndBlur,
2237
1940
  onTouchStart: event => {
2238
1941
  startDragging(resizeHandleId, event.nativeEvent);
1942
+ const callbacks = callbacksRef.current;
1943
+ assert(callbacks);
2239
1944
  const {
2240
1945
  onDragging
2241
- } = callbacksRef.current;
1946
+ } = callbacks;
2242
1947
  if (onDragging) {
2243
1948
  onDragging(true);
2244
1949
  }
@@ -2249,8 +1954,7 @@ function PanelResizeHandle({
2249
1954
  ...style,
2250
1955
  ...styleFromProps
2251
1956
  },
2252
- tabIndex: 0,
2253
- ...dataAttributes,
1957
+ tabIndex,
2254
1958
  // CSS selectors
2255
1959
  "data-panel-group-direction": direction,
2256
1960
  "data-panel-group-id": groupId,
@@ -2265,3 +1969,4 @@ PanelResizeHandle.displayName = "PanelResizeHandle";
2265
1969
  exports.Panel = Panel;
2266
1970
  exports.PanelGroup = PanelGroup;
2267
1971
  exports.PanelResizeHandle = PanelResizeHandle;
1972
+ exports.assert = assert;