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
@@ -41,24 +41,20 @@ function useUniqueId(idFromParams = null) {
41
41
  function PanelWithForwardedRef({
42
42
  children,
43
43
  className: classNameFromProps = "",
44
- collapsedSizePercentage,
45
- collapsedSizePixels,
44
+ collapsedSize,
46
45
  collapsible,
47
- dataAttributes,
48
- defaultSizePercentage,
49
- defaultSizePixels,
46
+ defaultSize,
50
47
  forwardedRef,
51
48
  id: idFromProps,
52
- maxSizePercentage,
53
- maxSizePixels,
54
- minSizePercentage,
55
- minSizePixels,
49
+ maxSize,
50
+ minSize,
56
51
  onCollapse,
57
52
  onExpand,
58
53
  onResize,
59
54
  order,
60
55
  style: styleFromProps,
61
- tagName: Type = "div"
56
+ tagName: Type = "div",
57
+ ...rest
62
58
  }) {
63
59
  const context = useContext(PanelGroupContext);
64
60
  if (context === null) {
@@ -83,15 +79,11 @@ function PanelWithForwardedRef({
83
79
  onResize
84
80
  },
85
81
  constraints: {
86
- collapsedSizePercentage,
87
- collapsedSizePixels,
82
+ collapsedSize,
88
83
  collapsible,
89
- defaultSizePercentage,
90
- defaultSizePixels,
91
- maxSizePercentage,
92
- maxSizePixels,
93
- minSizePercentage,
94
- minSizePixels
84
+ defaultSize,
85
+ maxSize,
86
+ minSize
95
87
  },
96
88
  id: panelId,
97
89
  idIsFromProps: idFromProps !== undefined,
@@ -117,15 +109,11 @@ function PanelWithForwardedRef({
117
109
  callbacks.onCollapse = onCollapse;
118
110
  callbacks.onExpand = onExpand;
119
111
  callbacks.onResize = onResize;
120
- constraints.collapsedSizePercentage = collapsedSizePercentage;
121
- constraints.collapsedSizePixels = collapsedSizePixels;
112
+ constraints.collapsedSize = collapsedSize;
122
113
  constraints.collapsible = collapsible;
123
- constraints.defaultSizePercentage = defaultSizePercentage;
124
- constraints.defaultSizePixels = defaultSizePixels;
125
- constraints.maxSizePercentage = maxSizePercentage;
126
- constraints.maxSizePixels = maxSizePixels;
127
- constraints.minSizePercentage = minSizePercentage;
128
- constraints.minSizePixels = minSizePixels;
114
+ constraints.defaultSize = defaultSize;
115
+ constraints.maxSize = maxSize;
116
+ constraints.minSize = minSize;
129
117
  });
130
118
  useIsomorphicLayoutEffect(() => {
131
119
  const panelData = panelDataRef.current;
@@ -153,19 +141,19 @@ function PanelWithForwardedRef({
153
141
  isExpanded() {
154
142
  return !isPanelCollapsed(panelDataRef.current);
155
143
  },
156
- resize: mixedSizes => {
157
- resizePanel(panelDataRef.current, mixedSizes);
144
+ resize: size => {
145
+ resizePanel(panelDataRef.current, size);
158
146
  }
159
147
  }), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
160
148
  const style = getPanelStyle(panelDataRef.current);
161
149
  return createElement(Type, {
150
+ ...rest,
162
151
  children,
163
152
  className: classNameFromProps,
164
153
  style: {
165
154
  ...style,
166
155
  ...styleFromProps
167
156
  },
168
- ...dataAttributes,
169
157
  // CSS selectors
170
158
  "data-panel": "",
171
159
  "data-panel-id": panelId,
@@ -182,81 +170,11 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
182
170
  PanelWithForwardedRef.displayName = "Panel";
183
171
  Panel.displayName = "forwardRef(Panel)";
184
172
 
185
- function convertPixelsToPercentage(pixels, groupSizePixels) {
186
- return pixels / groupSizePixels * 100;
187
- }
188
-
189
- function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels) {
190
- let {
191
- collapsedSizePercentage = 0,
192
- collapsedSizePixels,
193
- defaultSizePercentage,
194
- defaultSizePixels,
195
- maxSizePercentage = 100,
196
- maxSizePixels,
197
- minSizePercentage = 0,
198
- minSizePixels
199
- } = panelConstraints;
200
- const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
201
- if (hasPixelConstraints && groupSizePixels <= 0) {
202
- console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
203
- return {
204
- collapsedSizePercentage: 0,
205
- defaultSizePercentage,
206
- maxSizePercentage: 0,
207
- minSizePercentage: 0
208
- };
209
- }
210
- if (collapsedSizePixels != null) {
211
- collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
212
- }
213
- if (defaultSizePixels != null) {
214
- defaultSizePercentage = convertPixelsToPercentage(defaultSizePixels, groupSizePixels);
215
- }
216
- if (minSizePixels != null) {
217
- minSizePercentage = convertPixelsToPercentage(minSizePixels, groupSizePixels);
218
- }
219
- if (maxSizePixels != null) {
220
- maxSizePercentage = convertPixelsToPercentage(maxSizePixels, groupSizePixels);
221
- }
222
- return {
223
- collapsedSizePercentage,
224
- defaultSizePercentage,
225
- maxSizePercentage,
226
- minSizePercentage
227
- };
228
- }
229
-
230
- function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels) {
231
- // All panel constraints, excluding the current one
232
- let totalMinConstraints = 0;
233
- let totalMaxConstraints = 0;
234
- for (let index = 0; index < panelConstraintsArray.length; index++) {
235
- if (index !== panelIndex) {
236
- const {
237
- collapsible
238
- } = panelConstraintsArray[index];
239
- const {
240
- collapsedSizePercentage,
241
- maxSizePercentage,
242
- minSizePercentage
243
- } = convertPixelConstraintsToPercentages(panelConstraintsArray[index], groupSizePixels);
244
- totalMaxConstraints += maxSizePercentage;
245
- totalMinConstraints += collapsible ? collapsedSizePercentage : minSizePercentage;
246
- }
173
+ function assert(expectedCondition, message = "Assertion failed!") {
174
+ if (!expectedCondition) {
175
+ console.error(message);
176
+ throw Error(message);
247
177
  }
248
- const {
249
- collapsedSizePercentage,
250
- defaultSizePercentage,
251
- maxSizePercentage,
252
- minSizePercentage
253
- } = convertPixelConstraintsToPercentages(panelConstraintsArray[panelIndex], groupSizePixels);
254
- return {
255
- collapsedSizePercentage,
256
- defaultSizePercentage,
257
- maxSizePercentage: panelConstraintsArray.length > 1 ? Math.min(maxSizePercentage, 100 - totalMinConstraints) : maxSizePercentage,
258
- minSizePercentage: panelConstraintsArray.length > 1 ? Math.max(minSizePercentage, 100 - totalMaxConstraints) : minSizePercentage
259
- };
260
178
  }
261
179
 
262
180
  const PRECISION = 10;
@@ -278,56 +196,41 @@ function fuzzyNumbersEqual(actual, expected, fractionDigits) {
278
196
 
279
197
  // Panel size must be in percentages; pixel values should be pre-converted
280
198
  function resizePanel({
281
- groupSizePixels,
282
- panelConstraints,
199
+ panelConstraints: panelConstraintsArray,
283
200
  panelIndex,
284
201
  size
285
202
  }) {
286
- const hasPixelConstraints = panelConstraints.some(({
287
- collapsedSizePixels,
288
- defaultSizePixels,
289
- minSizePixels,
290
- maxSizePixels
291
- }) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
292
- if (hasPixelConstraints && groupSizePixels <= 0) {
293
- console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
294
- return 0;
295
- }
203
+ const panelConstraints = panelConstraintsArray[panelIndex];
204
+ assert(panelConstraints != null);
296
205
  let {
297
- collapsible
298
- } = panelConstraints[panelIndex];
299
- const {
300
- collapsedSizePercentage,
301
- maxSizePercentage,
302
- minSizePercentage
303
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
304
- if (minSizePercentage != null) {
305
- if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
306
- if (collapsible) {
307
- // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
308
- const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
309
- if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
310
- size = collapsedSizePercentage;
311
- } else {
312
- size = minSizePercentage;
313
- }
206
+ collapsedSize = 0,
207
+ collapsible,
208
+ maxSize = 100,
209
+ minSize = 0
210
+ } = panelConstraints;
211
+ if (fuzzyCompareNumbers(size, minSize) < 0) {
212
+ if (collapsible) {
213
+ // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
214
+ const halfwayPoint = (collapsedSize + minSize) / 2;
215
+ if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
216
+ size = collapsedSize;
314
217
  } else {
315
- size = minSizePercentage;
218
+ size = minSize;
316
219
  }
220
+ } else {
221
+ size = minSize;
317
222
  }
318
223
  }
319
- if (maxSizePercentage != null) {
320
- size = Math.min(maxSizePercentage, size);
321
- }
224
+ size = Math.min(maxSize, size);
225
+ size = parseFloat(size.toFixed(PRECISION));
322
226
  return size;
323
227
  }
324
228
 
325
229
  // All units must be in percentages; pixel values should be pre-converted
326
230
  function adjustLayoutByDelta({
327
231
  delta,
328
- groupSizePixels,
329
232
  layout: prevLayout,
330
- panelConstraints,
233
+ panelConstraints: panelConstraintsArray,
331
234
  pivotIndices,
332
235
  trigger
333
236
  }) {
@@ -335,6 +238,9 @@ function adjustLayoutByDelta({
335
238
  return prevLayout;
336
239
  }
337
240
  const nextLayout = [...prevLayout];
241
+ const [firstPivotIndex, secondPivotIndex] = pivotIndices;
242
+ assert(firstPivotIndex != null);
243
+ assert(secondPivotIndex != null);
338
244
  let deltaApplied = 0;
339
245
 
340
246
  //const DEBUG = [];
@@ -358,18 +264,23 @@ function adjustLayoutByDelta({
358
264
  if (trigger === "keyboard") {
359
265
  {
360
266
  // Check if we should expand a collapsed panel
361
- const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
362
- const constraints = panelConstraints[index];
267
+ const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
268
+ const panelConstraints = panelConstraintsArray[index];
269
+ assert(panelConstraints);
270
+
363
271
  //DEBUG.push(`edge case check 1: ${index}`);
364
272
  //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
365
- if (constraints.collapsible) {
273
+ if (panelConstraints.collapsible) {
366
274
  const prevSize = prevLayout[index];
275
+ assert(prevSize != null);
276
+ const panelConstraints = panelConstraintsArray[index];
277
+ assert(panelConstraints);
367
278
  const {
368
- collapsedSizePercentage,
369
- minSizePercentage
370
- } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
371
- if (fuzzyNumbersEqual(prevSize, collapsedSizePercentage)) {
372
- const localDelta = minSizePercentage - prevSize;
279
+ collapsedSize = 0,
280
+ minSize = 0
281
+ } = panelConstraints;
282
+ if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
283
+ const localDelta = minSize - prevSize;
373
284
  //DEBUG.push(` -> expand delta: ${localDelta}`);
374
285
 
375
286
  if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
@@ -382,18 +293,26 @@ function adjustLayoutByDelta({
382
293
 
383
294
  {
384
295
  // Check if we should collapse a panel at its minimum size
385
- const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
386
- const constraints = panelConstraints[index];
296
+ const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
297
+ const panelConstraints = panelConstraintsArray[index];
298
+ assert(panelConstraints);
299
+ const {
300
+ collapsible
301
+ } = panelConstraints;
302
+
387
303
  //DEBUG.push(`edge case check 2: ${index}`);
388
- //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
389
- if (constraints.collapsible) {
304
+ //DEBUG.push(` -> collapsible? ${collapsible}`);
305
+ if (collapsible) {
390
306
  const prevSize = prevLayout[index];
307
+ assert(prevSize != null);
308
+ const panelConstraints = panelConstraintsArray[index];
309
+ assert(panelConstraints);
391
310
  const {
392
- collapsedSizePercentage,
393
- minSizePercentage
394
- } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
395
- if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
396
- const localDelta = prevSize - collapsedSizePercentage;
311
+ collapsedSize = 0,
312
+ minSize = 0
313
+ } = panelConstraints;
314
+ if (fuzzyNumbersEqual(prevSize, minSize)) {
315
+ const localDelta = prevSize - collapsedSize;
397
316
  //DEBUG.push(` -> expand delta: ${localDelta}`);
398
317
 
399
318
  if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
@@ -415,15 +334,15 @@ function adjustLayoutByDelta({
415
334
  // as an expanding panel might change from collapsed to min size.
416
335
 
417
336
  const increment = delta < 0 ? 1 : -1;
418
- let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
337
+ let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
419
338
  let maxAvailableDelta = 0;
420
339
 
421
340
  //DEBUG.push("pre calc...");
422
341
  while (true) {
423
342
  const prevSize = prevLayout[index];
343
+ assert(prevSize != null);
424
344
  const maxSafeSize = resizePanel({
425
- groupSizePixels,
426
- panelConstraints,
345
+ panelConstraints: panelConstraintsArray,
427
346
  panelIndex: index,
428
347
  size: 100
429
348
  });
@@ -432,7 +351,7 @@ function adjustLayoutByDelta({
432
351
 
433
352
  maxAvailableDelta += delta;
434
353
  index += increment;
435
- if (index < 0 || index >= panelConstraints.length) {
354
+ if (index < 0 || index >= panelConstraintsArray.length) {
436
355
  break;
437
356
  }
438
357
  }
@@ -447,15 +366,15 @@ function adjustLayoutByDelta({
447
366
  {
448
367
  // Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
449
368
 
450
- const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
369
+ const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
451
370
  let index = pivotIndex;
452
- while (index >= 0 && index < panelConstraints.length) {
371
+ while (index >= 0 && index < panelConstraintsArray.length) {
453
372
  const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
454
373
  const prevSize = prevLayout[index];
374
+ assert(prevSize != null);
455
375
  const unsafeSize = prevSize - deltaRemaining;
456
376
  const safeSize = resizePanel({
457
- groupSizePixels,
458
- panelConstraints,
377
+ panelConstraints: panelConstraintsArray,
459
378
  panelIndex: index,
460
379
  size: unsafeSize
461
380
  });
@@ -487,11 +406,12 @@ function adjustLayoutByDelta({
487
406
  }
488
407
  {
489
408
  // Now distribute the applied delta to the panels in the other direction
490
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
491
- const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
409
+ const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
410
+ const prevSize = prevLayout[pivotIndex];
411
+ assert(prevSize != null);
412
+ const unsafeSize = prevSize + deltaApplied;
492
413
  const safeSize = resizePanel({
493
- groupSizePixels,
494
- panelConstraints,
414
+ panelConstraints: panelConstraintsArray,
495
415
  panelIndex: pivotIndex,
496
416
  size: unsafeSize
497
417
  });
@@ -502,14 +422,14 @@ function adjustLayoutByDelta({
502
422
  // Edge case where expanding or contracting one panel caused another one to change collapsed state
503
423
  if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
504
424
  let deltaRemaining = unsafeSize - safeSize;
505
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
425
+ const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
506
426
  let index = pivotIndex;
507
- while (index >= 0 && index < panelConstraints.length) {
427
+ while (index >= 0 && index < panelConstraintsArray.length) {
508
428
  const prevSize = nextLayout[index];
429
+ assert(prevSize != null);
509
430
  const unsafeSize = prevSize + deltaRemaining;
510
431
  const safeSize = resizePanel({
511
- groupSizePixels,
512
- panelConstraints,
432
+ panelConstraints: panelConstraintsArray,
513
433
  panelIndex: index,
514
434
  size: unsafeSize
515
435
  });
@@ -533,9 +453,7 @@ function adjustLayoutByDelta({
533
453
  //DEBUG.push("");
534
454
 
535
455
  const totalSize = nextLayout.reduce((total, size) => size + total, 0);
536
- deltaApplied = 100 - totalSize;
537
456
  //DEBUG.push(`total size: ${totalSize}`);
538
- //DEBUG.push(` deltaApplied: ${deltaApplied}`);
539
457
  //console.log(DEBUG.join("\n"));
540
458
 
541
459
  if (!fuzzyNumbersEqual(totalSize, 100)) {
@@ -544,27 +462,7 @@ function adjustLayoutByDelta({
544
462
  return nextLayout;
545
463
  }
546
464
 
547
- function assert(expectedCondition, message = "Assertion failed!") {
548
- if (!expectedCondition) {
549
- console.error(message);
550
- throw Error(message);
551
- }
552
- }
553
-
554
- function getPercentageSizeFromMixedSizes({
555
- sizePercentage,
556
- sizePixels
557
- }, groupSizePixels) {
558
- if (sizePercentage != null) {
559
- return sizePercentage;
560
- } else if (sizePixels != null) {
561
- return convertPixelsToPercentage(sizePixels, groupSizePixels);
562
- }
563
- return undefined;
564
- }
565
-
566
465
  function calculateAriaValues({
567
- groupSizePixels,
568
466
  layout,
569
467
  panelsArray,
570
468
  pivotIndices
@@ -573,28 +471,19 @@ function calculateAriaValues({
573
471
  let currentMaxSize = 100;
574
472
  let totalMinSize = 0;
575
473
  let totalMaxSize = 0;
474
+ const firstIndex = pivotIndices[0];
475
+ assert(firstIndex != null);
576
476
 
577
477
  // A panel's effective min/max sizes also need to account for other panel's sizes.
578
478
  panelsArray.forEach((panelData, index) => {
579
- var _getPercentageSizeFro, _getPercentageSizeFro2;
580
479
  const {
581
480
  constraints
582
481
  } = panelData;
583
482
  const {
584
- maxSizePercentage,
585
- maxSizePixels,
586
- minSizePercentage,
587
- minSizePixels
483
+ maxSize = 100,
484
+ minSize = 0
588
485
  } = constraints;
589
- const minSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
590
- sizePercentage: minSizePercentage,
591
- sizePixels: minSizePixels
592
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
593
- const maxSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
594
- sizePercentage: maxSizePercentage,
595
- sizePixels: maxSizePixels
596
- }, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 100;
597
- if (index === pivotIndices[0]) {
486
+ if (index === firstIndex) {
598
487
  currentMinSize = minSize;
599
488
  currentMaxSize = maxSize;
600
489
  } else {
@@ -604,7 +493,7 @@ function calculateAriaValues({
604
493
  });
605
494
  const valueMax = Math.min(currentMaxSize, 100 - totalMinSize);
606
495
  const valueMin = Math.max(currentMinSize, 100 - totalMaxSize);
607
- const valueNow = layout[pivotIndices[0]];
496
+ const valueNow = layout[firstIndex];
608
497
  return {
609
498
  valueMax,
610
499
  valueMin,
@@ -635,42 +524,6 @@ function getPanelGroupElement(id) {
635
524
  return null;
636
525
  }
637
526
 
638
- function calculateAvailablePanelSizeInPixels(groupId) {
639
- const panelGroupElement = getPanelGroupElement(groupId);
640
- if (panelGroupElement == null) {
641
- return NaN;
642
- }
643
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
644
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
645
- if (direction === "horizontal") {
646
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
647
- return accumulated + handle.offsetWidth;
648
- }, 0);
649
- } else {
650
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
651
- return accumulated + handle.offsetHeight;
652
- }, 0);
653
- }
654
- }
655
-
656
- function getAvailableGroupSizePixels(groupId) {
657
- const panelGroupElement = getPanelGroupElement(groupId);
658
- if (panelGroupElement == null) {
659
- return NaN;
660
- }
661
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
662
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
663
- if (direction === "horizontal") {
664
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
665
- return accumulated + handle.offsetWidth;
666
- }, 0);
667
- } else {
668
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
669
- return accumulated + handle.offsetHeight;
670
- }, 0);
671
- }
672
- }
673
-
674
527
  function getResizeHandleElement(id) {
675
528
  const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
676
529
  if (element) {
@@ -703,7 +556,6 @@ function useWindowSplitterPanelGroupBehavior({
703
556
  didWarnAboutMissingResizeHandle: false
704
557
  });
705
558
  useIsomorphicLayoutEffect(() => {
706
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
707
559
  const resizeHandleElements = getResizeHandleElementsForGroup(groupId);
708
560
  for (let index = 0; index < panelDataArray.length - 1; index++) {
709
561
  const {
@@ -711,7 +563,6 @@ function useWindowSplitterPanelGroupBehavior({
711
563
  valueMin,
712
564
  valueNow
713
565
  } = calculateAriaValues({
714
- groupSizePixels,
715
566
  layout,
716
567
  panelsArray: panelDataArray,
717
568
  pivotIndices: [index, index + 1]
@@ -728,10 +579,12 @@ function useWindowSplitterPanelGroupBehavior({
728
579
  }
729
580
  }
730
581
  } else {
731
- resizeHandleElement.setAttribute("aria-controls", panelDataArray[index].id);
582
+ const panelData = panelDataArray[index];
583
+ assert(panelData);
584
+ resizeHandleElement.setAttribute("aria-controls", panelData.id);
732
585
  resizeHandleElement.setAttribute("aria-valuemax", "" + Math.round(valueMax));
733
586
  resizeHandleElement.setAttribute("aria-valuemin", "" + Math.round(valueMin));
734
- resizeHandleElement.setAttribute("aria-valuenow", "" + Math.round(valueNow));
587
+ resizeHandleElement.setAttribute("aria-valuenow", valueNow != null ? "" + Math.round(valueNow) : "");
735
588
  }
736
589
  }
737
590
  return () => {
@@ -744,14 +597,18 @@ function useWindowSplitterPanelGroupBehavior({
744
597
  };
745
598
  }, [groupId, layout, panelDataArray]);
746
599
  useEffect(() => {
600
+ const eagerValues = eagerValuesRef.current;
601
+ assert(eagerValues);
747
602
  const {
748
603
  panelDataArray
749
- } = eagerValuesRef.current;
604
+ } = eagerValues;
750
605
  const groupElement = getPanelGroupElement(groupId);
751
606
  assert(groupElement != null, `No group found for id "${groupId}"`);
752
607
  const handles = getResizeHandleElementsForGroup(groupId);
608
+ assert(handles);
753
609
  const cleanupFunctions = handles.map(handle => {
754
610
  const handleId = handle.getAttribute("data-panel-resize-handle-id");
611
+ assert(handleId);
755
612
  const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
756
613
  if (idBefore == null || idAfter == null) {
757
614
  return () => {};
@@ -767,21 +624,16 @@ function useWindowSplitterPanelGroupBehavior({
767
624
  const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
768
625
  if (index >= 0) {
769
626
  const panelData = panelDataArray[index];
627
+ assert(panelData);
770
628
  const size = layout[index];
771
- if (size != null && panelData.constraints.collapsible) {
772
- var _getPercentageSizeFro, _getPercentageSizeFro2;
773
- const groupSizePixels = getAvailableGroupSizePixels(groupId);
774
- const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
775
- sizePercentage: panelData.constraints.collapsedSizePercentage,
776
- sizePixels: panelData.constraints.collapsedSizePixels
777
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
778
- const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
779
- sizePercentage: panelData.constraints.minSizePercentage,
780
- sizePixels: panelData.constraints.minSizePixels
781
- }, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
629
+ const {
630
+ collapsedSize = 0,
631
+ collapsible,
632
+ minSize = 0
633
+ } = panelData.constraints;
634
+ if (size != null && collapsible) {
782
635
  const nextLayout = adjustLayoutByDelta({
783
636
  delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
784
- groupSizePixels,
785
637
  layout,
786
638
  panelConstraints: panelDataArray.map(panelData => panelData.constraints),
787
639
  pivotIndices: determinePivotIndices(groupId, handleId),
@@ -835,6 +687,7 @@ function getResizeEventCursorPosition(direction, event) {
835
687
  return isHorizontal ? event.clientX : event.clientY;
836
688
  } else if (isTouchEvent(event)) {
837
689
  const firstTouch = event.touches[0];
690
+ assert(firstTouch);
838
691
  return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
839
692
  } else {
840
693
  throw Error(`Unsupported event type "${event.type}"`);
@@ -844,12 +697,15 @@ function getResizeEventCursorPosition(direction, event) {
844
697
  function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
845
698
  const isHorizontal = direction === "horizontal";
846
699
  const handleElement = getResizeHandleElement(dragHandleId);
700
+ assert(handleElement);
847
701
  const groupId = handleElement.getAttribute("data-panel-group-id");
702
+ assert(groupId);
848
703
  let {
849
704
  initialCursorPosition
850
705
  } = initialDragState;
851
706
  const cursorPosition = getResizeEventCursorPosition(direction, event);
852
707
  const groupElement = getPanelGroupElement(groupId);
708
+ assert(groupElement);
853
709
  const groupRect = groupElement.getBoundingClientRect();
854
710
  const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
855
711
  const offsetPixels = cursorPosition - initialCursorPosition;
@@ -858,19 +714,14 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
858
714
  }
859
715
 
860
716
  // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
861
- function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initialDragState, keyboardResizeByOptions) {
717
+ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
862
718
  if (isKeyDown(event)) {
863
719
  const isHorizontal = direction === "horizontal";
864
- const groupElement = getPanelGroupElement(groupId);
865
- const rect = groupElement.getBoundingClientRect();
866
- const groupSizeInPixels = isHorizontal ? rect.width : rect.height;
867
720
  let delta = 0;
868
721
  if (event.shiftKey) {
869
722
  delta = 100;
870
- } else if (keyboardResizeByOptions.percentage != null) {
871
- delta = keyboardResizeByOptions.percentage;
872
- } else if (keyboardResizeByOptions.pixels != null) {
873
- delta = keyboardResizeByOptions.pixels / groupSizeInPixels;
723
+ } else if (keyboardResizeBy != null) {
724
+ delta = keyboardResizeBy;
874
725
  } else {
875
726
  delta = 10;
876
727
  }
@@ -897,37 +748,43 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
897
748
  }
898
749
  return movement;
899
750
  } else {
751
+ if (initialDragState == null) {
752
+ return 0;
753
+ }
900
754
  return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
901
755
  }
902
756
  }
903
757
 
904
758
  function calculateUnsafeDefaultLayout({
905
- groupSizePixels,
906
759
  panelDataArray
907
760
  }) {
908
761
  const layout = Array(panelDataArray.length);
909
- const panelDataConstraints = panelDataArray.map(panelData => panelData.constraints);
762
+ const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
910
763
  let numPanelsWithSizes = 0;
911
764
  let remainingSize = 100;
912
765
 
913
766
  // Distribute default sizes first
914
767
  for (let index = 0; index < panelDataArray.length; index++) {
768
+ const panelConstraints = panelConstraintsArray[index];
769
+ assert(panelConstraints);
915
770
  const {
916
- defaultSizePercentage
917
- } = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
918
- if (defaultSizePercentage != null) {
771
+ defaultSize
772
+ } = panelConstraints;
773
+ if (defaultSize != null) {
919
774
  numPanelsWithSizes++;
920
- layout[index] = defaultSizePercentage;
921
- remainingSize -= defaultSizePercentage;
775
+ layout[index] = defaultSize;
776
+ remainingSize -= defaultSize;
922
777
  }
923
778
  }
924
779
 
925
780
  // Remaining size should be distributed evenly between panels without default sizes
926
781
  for (let index = 0; index < panelDataArray.length; index++) {
782
+ const panelConstraints = panelConstraintsArray[index];
783
+ assert(panelConstraints);
927
784
  const {
928
- defaultSizePercentage
929
- } = computePercentagePanelConstraints(panelDataConstraints, index, groupSizePixels);
930
- if (defaultSizePercentage != null) {
785
+ defaultSize
786
+ } = panelConstraints;
787
+ if (defaultSize != null) {
931
788
  continue;
932
789
  }
933
790
  const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
@@ -939,54 +796,36 @@ function calculateUnsafeDefaultLayout({
939
796
  return layout;
940
797
  }
941
798
 
942
- function convertPercentageToPixels(percentage, groupSizePixels) {
943
- return percentage / 100 * groupSizePixels;
944
- }
945
-
946
799
  // Layout should be pre-converted into percentages
947
- function callPanelCallbacks(groupId, panelsArray, layout, panelIdToLastNotifiedMixedSizesMap) {
948
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
949
- layout.forEach((sizePercentage, index) => {
800
+ function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
801
+ layout.forEach((size, index) => {
950
802
  const panelData = panelsArray[index];
951
- if (!panelData) {
952
- // Handle initial mount (when panels are registered too late to be in the panels array)
953
- // The subsequent render+effects will handle the resize notification
954
- return;
955
- }
803
+ assert(panelData);
956
804
  const {
957
805
  callbacks,
958
806
  constraints,
959
807
  id: panelId
960
808
  } = panelData;
961
809
  const {
810
+ collapsedSize = 0,
962
811
  collapsible
963
812
  } = constraints;
964
- const mixedSizes = {
965
- sizePercentage,
966
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
967
- };
968
- const lastNotifiedMixedSizes = panelIdToLastNotifiedMixedSizesMap[panelId];
969
- if (lastNotifiedMixedSizes == null || mixedSizes.sizePercentage !== lastNotifiedMixedSizes.sizePercentage || mixedSizes.sizePixels !== lastNotifiedMixedSizes.sizePixels) {
970
- panelIdToLastNotifiedMixedSizesMap[panelId] = mixedSizes;
813
+ const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
814
+ if (lastNotifiedSize == null || size !== lastNotifiedSize) {
815
+ panelIdToLastNotifiedSizeMap[panelId] = size;
971
816
  const {
972
817
  onCollapse,
973
818
  onExpand,
974
819
  onResize
975
820
  } = callbacks;
976
821
  if (onResize) {
977
- onResize(mixedSizes, lastNotifiedMixedSizes);
822
+ onResize(size, lastNotifiedSize);
978
823
  }
979
824
  if (collapsible && (onCollapse || onExpand)) {
980
- var _getPercentageSizeFro;
981
- const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
982
- sizePercentage: constraints.collapsedSizePercentage,
983
- sizePixels: constraints.collapsedSizePixels
984
- }, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
985
- const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
986
- if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
825
+ if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
987
826
  onExpand();
988
827
  }
989
- if (onCollapse && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage !== collapsedSize) && size === collapsedSize) {
828
+ if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
990
829
  onCollapse();
991
830
  }
992
831
  }
@@ -1169,74 +1008,39 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
1169
1008
  }
1170
1009
  }
1171
1010
 
1172
- function shouldMonitorPixelBasedConstraints(constraints) {
1173
- return constraints.some(constraints => {
1174
- return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
1175
- });
1176
- }
1177
-
1178
1011
  function validatePanelConstraints({
1179
- groupSizePixels,
1180
- panelConstraints,
1012
+ panelConstraints: panelConstraintsArray,
1181
1013
  panelId,
1182
1014
  panelIndex
1183
1015
  }) {
1184
1016
  {
1185
1017
  const warnings = [];
1186
- {
1187
- const {
1188
- collapsedSizePercentage,
1189
- collapsedSizePixels,
1190
- defaultSizePercentage,
1191
- defaultSizePixels,
1192
- maxSizePercentage,
1193
- maxSizePixels,
1194
- minSizePercentage,
1195
- minSizePixels
1196
- } = panelConstraints[panelIndex];
1197
- const conflictingUnits = [];
1198
- if (collapsedSizePercentage != null && collapsedSizePixels != null) {
1199
- conflictingUnits.push("collapsed size");
1200
- }
1201
- if (defaultSizePercentage != null && defaultSizePixels != null) {
1202
- conflictingUnits.push("default size");
1203
- }
1204
- if (maxSizePercentage != null && maxSizePixels != null) {
1205
- conflictingUnits.push("max size");
1206
- }
1207
- if (minSizePercentage != null && minSizePixels != null) {
1208
- conflictingUnits.push("min size");
1209
- }
1210
- if (conflictingUnits.length > 0) {
1211
- warnings.push(`should not specify both percentage and pixel units for: ${conflictingUnits.join(", ")}`);
1212
- }
1018
+ const panelConstraints = panelConstraintsArray[panelIndex];
1019
+ assert(panelConstraints);
1020
+ const {
1021
+ collapsedSize = 0,
1022
+ defaultSize,
1023
+ maxSize = 100,
1024
+ minSize = 0
1025
+ } = panelConstraints;
1026
+ if (minSize > maxSize) {
1027
+ warnings.push(`min size (${minSize}%) should not be greater than max size (${maxSize}%)`);
1213
1028
  }
1214
- {
1215
- const {
1216
- collapsedSizePercentage,
1217
- defaultSizePercentage,
1218
- maxSizePercentage,
1219
- minSizePercentage
1220
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
1221
- if (minSizePercentage > maxSizePercentage) {
1222
- warnings.push(`min size (${minSizePercentage}%) should not be greater than max size (${maxSizePercentage}%)`);
1223
- }
1224
- if (defaultSizePercentage != null) {
1225
- if (defaultSizePercentage < 0) {
1226
- warnings.push("default size should not be less than 0");
1227
- } else if (defaultSizePercentage < minSizePercentage) {
1228
- warnings.push("default size should not be less than min size");
1229
- }
1230
- if (defaultSizePercentage > 100) {
1231
- warnings.push("default size should not be greater than 100");
1232
- } else if (defaultSizePercentage > maxSizePercentage) {
1233
- warnings.push("default size should not be greater than max size");
1234
- }
1029
+ if (defaultSize != null) {
1030
+ if (defaultSize < 0) {
1031
+ warnings.push("default size should not be less than 0");
1032
+ } else if (defaultSize < minSize) {
1033
+ warnings.push("default size should not be less than min size");
1235
1034
  }
1236
- if (collapsedSizePercentage > minSizePercentage) {
1237
- warnings.push("collapsed size should not be greater than min size");
1035
+ if (defaultSize > 100) {
1036
+ warnings.push("default size should not be greater than 100");
1037
+ } else if (defaultSize > maxSize) {
1038
+ warnings.push("default size should not be greater than max size");
1238
1039
  }
1239
1040
  }
1041
+ if (collapsedSize > minSize) {
1042
+ warnings.push("collapsed size should not be greater than min size");
1043
+ }
1240
1044
  if (warnings.length > 0) {
1241
1045
  const name = panelId != null ? `Panel "${panelId}"` : "Panel";
1242
1046
  console.warn(`${name} has an invalid configuration:\n\n${warnings.join("\n")}`);
@@ -1248,20 +1052,26 @@ function validatePanelConstraints({
1248
1052
 
1249
1053
  // All units must be in percentages; pixel values should be pre-converted
1250
1054
  function validatePanelGroupLayout({
1251
- groupSizePixels,
1252
1055
  layout: prevLayout,
1253
1056
  panelConstraints
1254
1057
  }) {
1255
1058
  const nextLayout = [...prevLayout];
1059
+ const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
1256
1060
 
1257
1061
  // Validate layout expectations
1258
1062
  if (nextLayout.length !== panelConstraints.length) {
1259
1063
  throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
1260
- } else if (!fuzzyNumbersEqual(nextLayout.reduce((accumulated, current) => accumulated + current, 0), 100)) {
1064
+ } else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
1261
1065
  // This is not ideal so we should warn about it, but it may be recoverable in some cases
1262
1066
  // (especially if the amount is small)
1263
1067
  {
1264
- console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}`);
1068
+ console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}. Layout normalization will be applied.`);
1069
+ }
1070
+ for (let index = 0; index < panelConstraints.length; index++) {
1071
+ const unsafeSize = nextLayout[index];
1072
+ assert(unsafeSize != null);
1073
+ const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
1074
+ nextLayout[index] = safeSize;
1265
1075
  }
1266
1076
  }
1267
1077
  let remainingSize = 0;
@@ -1269,8 +1079,8 @@ function validatePanelGroupLayout({
1269
1079
  // First pass: Validate the proposed layout given each panel's constraints
1270
1080
  for (let index = 0; index < panelConstraints.length; index++) {
1271
1081
  const unsafeSize = nextLayout[index];
1082
+ assert(unsafeSize != null);
1272
1083
  const safeSize = resizePanel({
1273
- groupSizePixels,
1274
1084
  panelConstraints,
1275
1085
  panelIndex: index,
1276
1086
  size: unsafeSize
@@ -1286,9 +1096,9 @@ function validatePanelGroupLayout({
1286
1096
  if (!fuzzyNumbersEqual(remainingSize, 0)) {
1287
1097
  for (let index = 0; index < panelConstraints.length; index++) {
1288
1098
  const prevSize = nextLayout[index];
1099
+ assert(prevSize != null);
1289
1100
  const unsafeSize = prevSize + remainingSize;
1290
1101
  const safeSize = resizePanel({
1291
- groupSizePixels,
1292
1102
  panelConstraints,
1293
1103
  panelIndex: index,
1294
1104
  size: unsafeSize
@@ -1323,21 +1133,20 @@ function PanelGroupWithForwardedRef({
1323
1133
  autoSaveId = null,
1324
1134
  children,
1325
1135
  className: classNameFromProps = "",
1326
- dataAttributes,
1327
1136
  direction,
1328
1137
  forwardedRef,
1329
- id: idFromProps,
1138
+ id: idFromProps = null,
1330
1139
  onLayout = null,
1331
- keyboardResizeByPercentage = null,
1332
- keyboardResizeByPixels = null,
1140
+ keyboardResizeBy = null,
1333
1141
  storage = defaultStorage,
1334
1142
  style: styleFromProps,
1335
- tagName: Type = "div"
1143
+ tagName: Type = "div",
1144
+ ...rest
1336
1145
  }) {
1337
1146
  const groupId = useUniqueId(idFromProps);
1338
1147
  const [dragState, setDragState] = useState(null);
1339
1148
  const [layout, setLayout] = useState([]);
1340
- const panelIdToLastNotifiedMixedSizesMapRef = useRef({});
1149
+ const panelIdToLastNotifiedSizeMapRef = useRef({});
1341
1150
  const panelSizeBeforeCollapseRef = useRef(new Map());
1342
1151
  const prevDeltaRef = useRef(0);
1343
1152
  const committedValuesRef = useRef({
@@ -1345,8 +1154,7 @@ function PanelGroupWithForwardedRef({
1345
1154
  direction,
1346
1155
  dragState,
1347
1156
  id: groupId,
1348
- keyboardResizeByPercentage,
1349
- keyboardResizeByPixels,
1157
+ keyboardResizeBy,
1350
1158
  onLayout,
1351
1159
  storage
1352
1160
  });
@@ -1362,33 +1170,20 @@ function PanelGroupWithForwardedRef({
1362
1170
  useImperativeHandle(forwardedRef, () => ({
1363
1171
  getId: () => committedValuesRef.current.id,
1364
1172
  getLayout: () => {
1365
- const {
1366
- id: groupId
1367
- } = committedValuesRef.current;
1368
1173
  const {
1369
1174
  layout
1370
1175
  } = eagerValuesRef.current;
1371
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1372
- return layout.map(sizePercentage => {
1373
- return {
1374
- sizePercentage,
1375
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1376
- };
1377
- });
1176
+ return layout;
1378
1177
  },
1379
- setLayout: mixedSizes => {
1178
+ setLayout: unsafeLayout => {
1380
1179
  const {
1381
- id: groupId,
1382
1180
  onLayout
1383
1181
  } = committedValuesRef.current;
1384
1182
  const {
1385
1183
  layout: prevLayout,
1386
1184
  panelDataArray
1387
1185
  } = eagerValuesRef.current;
1388
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1389
- const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
1390
1186
  const safeLayout = validatePanelGroupLayout({
1391
- groupSizePixels,
1392
1187
  layout: unsafeLayout,
1393
1188
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1394
1189
  });
@@ -1396,12 +1191,9 @@ function PanelGroupWithForwardedRef({
1396
1191
  setLayout(safeLayout);
1397
1192
  eagerValuesRef.current.layout = safeLayout;
1398
1193
  if (onLayout) {
1399
- onLayout(safeLayout.map(sizePercentage => ({
1400
- sizePercentage,
1401
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1402
- })));
1194
+ onLayout(safeLayout);
1403
1195
  }
1404
- callPanelCallbacks(groupId, panelDataArray, safeLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1196
+ callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
1405
1197
  }
1406
1198
  }
1407
1199
  }), []);
@@ -1412,11 +1204,7 @@ function PanelGroupWithForwardedRef({
1412
1204
  committedValuesRef.current.id = groupId;
1413
1205
  committedValuesRef.current.onLayout = onLayout;
1414
1206
  committedValuesRef.current.storage = storage;
1415
-
1416
- // panelDataArray and layout are updated in-sync with scheduled state updates.
1417
- // TODO [217] Move these values into a separate ref
1418
1207
  });
1419
-
1420
1208
  useWindowSplitterPanelGroupBehavior({
1421
1209
  committedValuesRef,
1422
1210
  eagerValuesRef,
@@ -1435,57 +1223,16 @@ function PanelGroupWithForwardedRef({
1435
1223
  if (layout.length === 0 || layout.length !== panelDataArray.length) {
1436
1224
  return;
1437
1225
  }
1226
+ let debouncedSave = debounceMap[autoSaveId];
1438
1227
 
1439
1228
  // Limit the frequency of localStorage updates.
1440
- if (!debounceMap[autoSaveId]) {
1441
- debounceMap[autoSaveId] = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1229
+ if (debouncedSave == null) {
1230
+ debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1231
+ debounceMap[autoSaveId] = debouncedSave;
1442
1232
  }
1443
- debounceMap[autoSaveId](autoSaveId, panelDataArray, layout, storage);
1233
+ debouncedSave(autoSaveId, panelDataArray, layout, storage);
1444
1234
  }
1445
1235
  }, [autoSaveId, layout, storage]);
1446
- useIsomorphicLayoutEffect(() => {
1447
- const {
1448
- layout: prevLayout,
1449
- panelDataArray
1450
- } = eagerValuesRef.current;
1451
- const constraints = panelDataArray.map(({
1452
- constraints
1453
- }) => constraints);
1454
- if (!shouldMonitorPixelBasedConstraints(constraints)) {
1455
- // Avoid the overhead of ResizeObserver if no pixel constraints require monitoring
1456
- return;
1457
- }
1458
- if (typeof ResizeObserver === "undefined") {
1459
- console.warn(`WARNING: Pixel based constraints require ResizeObserver but it is not supported by the current browser.`);
1460
- } else {
1461
- const resizeObserver = new ResizeObserver(() => {
1462
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1463
- const {
1464
- onLayout
1465
- } = committedValuesRef.current;
1466
- const nextLayout = validatePanelGroupLayout({
1467
- groupSizePixels,
1468
- layout: prevLayout,
1469
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1470
- });
1471
- if (!areEqual(prevLayout, nextLayout)) {
1472
- setLayout(nextLayout);
1473
- eagerValuesRef.current.layout = nextLayout;
1474
- if (onLayout) {
1475
- onLayout(nextLayout.map(sizePercentage => ({
1476
- sizePercentage,
1477
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1478
- })));
1479
- }
1480
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1481
- }
1482
- });
1483
- resizeObserver.observe(getPanelGroupElement(groupId));
1484
- return () => {
1485
- resizeObserver.disconnect();
1486
- };
1487
- }
1488
- }, [groupId]);
1489
1236
 
1490
1237
  // DEV warnings
1491
1238
  useEffect(() => {
@@ -1516,12 +1263,12 @@ function PanelGroupWithForwardedRef({
1516
1263
  }
1517
1264
  if (!didLogPanelConstraintsWarning) {
1518
1265
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1519
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1520
1266
  for (let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++) {
1267
+ const panelData = panelDataArray[panelIndex];
1268
+ assert(panelData);
1521
1269
  const isValid = validatePanelConstraints({
1522
- groupSizePixels,
1523
1270
  panelConstraints,
1524
- panelId: panelDataArray[panelIndex].id,
1271
+ panelId: panelData.id,
1525
1272
  panelIndex
1526
1273
  });
1527
1274
  if (!isValid) {
@@ -1545,20 +1292,19 @@ function PanelGroupWithForwardedRef({
1545
1292
  if (panelData.constraints.collapsible) {
1546
1293
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1547
1294
  const {
1548
- collapsedSizePercentage,
1549
- panelSizePercentage,
1550
- pivotIndices,
1551
- groupSizePixels
1552
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1553
- if (panelSizePercentage !== collapsedSizePercentage) {
1295
+ collapsedSize = 0,
1296
+ panelSize,
1297
+ pivotIndices
1298
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1299
+ assert(panelSize != null);
1300
+ if (panelSize !== collapsedSize) {
1554
1301
  // Store size before collapse;
1555
1302
  // This is the size that gets restored if the expand() API is used.
1556
- panelSizeBeforeCollapseRef.current.set(panelData.id, panelSizePercentage);
1303
+ panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1557
1304
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1558
- const delta = isLastPanel ? panelSizePercentage - collapsedSizePercentage : collapsedSizePercentage - panelSizePercentage;
1305
+ const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1559
1306
  const nextLayout = adjustLayoutByDelta({
1560
1307
  delta,
1561
- groupSizePixels,
1562
1308
  layout: prevLayout,
1563
1309
  panelConstraints: panelConstraintsArray,
1564
1310
  pivotIndices,
@@ -1568,16 +1314,13 @@ function PanelGroupWithForwardedRef({
1568
1314
  setLayout(nextLayout);
1569
1315
  eagerValuesRef.current.layout = nextLayout;
1570
1316
  if (onLayout) {
1571
- onLayout(nextLayout.map(sizePercentage => ({
1572
- sizePercentage,
1573
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1574
- })));
1317
+ onLayout(nextLayout);
1575
1318
  }
1576
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1319
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1577
1320
  }
1578
1321
  }
1579
1322
  }
1580
- }, [groupId]);
1323
+ }, []);
1581
1324
 
1582
1325
  // External APIs are safe to memoize via committed values ref
1583
1326
  const expandPanel = useCallback(panelData => {
@@ -1591,21 +1334,19 @@ function PanelGroupWithForwardedRef({
1591
1334
  if (panelData.constraints.collapsible) {
1592
1335
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1593
1336
  const {
1594
- collapsedSizePercentage,
1595
- panelSizePercentage,
1596
- minSizePercentage,
1597
- pivotIndices,
1598
- groupSizePixels
1599
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1600
- if (panelSizePercentage === collapsedSizePercentage) {
1337
+ collapsedSize = 0,
1338
+ panelSize,
1339
+ minSize = 0,
1340
+ pivotIndices
1341
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1342
+ if (panelSize === collapsedSize) {
1601
1343
  // Restore this panel to the size it was before it was collapsed, if possible.
1602
- const prevPanelSizePercentage = panelSizeBeforeCollapseRef.current.get(panelData.id);
1603
- const baseSizePercentage = prevPanelSizePercentage != null && prevPanelSizePercentage >= minSizePercentage ? prevPanelSizePercentage : minSizePercentage;
1344
+ const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
1345
+ const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
1604
1346
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1605
- const delta = isLastPanel ? panelSizePercentage - baseSizePercentage : baseSizePercentage - panelSizePercentage;
1347
+ const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1606
1348
  const nextLayout = adjustLayoutByDelta({
1607
1349
  delta,
1608
- groupSizePixels,
1609
1350
  layout: prevLayout,
1610
1351
  panelConstraints: panelConstraintsArray,
1611
1352
  pivotIndices,
@@ -1615,16 +1356,13 @@ function PanelGroupWithForwardedRef({
1615
1356
  setLayout(nextLayout);
1616
1357
  eagerValuesRef.current.layout = nextLayout;
1617
1358
  if (onLayout) {
1618
- onLayout(nextLayout.map(sizePercentage => ({
1619
- sizePercentage,
1620
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1621
- })));
1359
+ onLayout(nextLayout);
1622
1360
  }
1623
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1361
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1624
1362
  }
1625
1363
  }
1626
1364
  }
1627
- }, [groupId]);
1365
+ }, []);
1628
1366
 
1629
1367
  // External APIs are safe to memoize via committed values ref
1630
1368
  const getPanelSize = useCallback(panelData => {
@@ -1633,14 +1371,11 @@ function PanelGroupWithForwardedRef({
1633
1371
  panelDataArray
1634
1372
  } = eagerValuesRef.current;
1635
1373
  const {
1636
- panelSizePercentage,
1637
- panelSizePixels
1638
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1639
- return {
1640
- sizePercentage: panelSizePercentage,
1641
- sizePixels: panelSizePixels
1642
- };
1643
- }, [groupId]);
1374
+ panelSize
1375
+ } = panelDataHelper(panelDataArray, panelData, layout);
1376
+ assert(panelSize != null);
1377
+ return panelSize;
1378
+ }, []);
1644
1379
 
1645
1380
  // This API should never read from committedValuesRef
1646
1381
  const getPanelStyle = useCallback(panelData => {
@@ -1663,12 +1398,12 @@ function PanelGroupWithForwardedRef({
1663
1398
  panelDataArray
1664
1399
  } = eagerValuesRef.current;
1665
1400
  const {
1666
- collapsedSizePercentage,
1401
+ collapsedSize,
1667
1402
  collapsible,
1668
- panelSizePercentage
1669
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1670
- return collapsible === true && panelSizePercentage === collapsedSizePercentage;
1671
- }, [groupId]);
1403
+ panelSize
1404
+ } = panelDataHelper(panelDataArray, panelData, layout);
1405
+ return collapsible === true && panelSize === collapsedSize;
1406
+ }, []);
1672
1407
 
1673
1408
  // External APIs are safe to memoize via committed values ref
1674
1409
  const isPanelExpanded = useCallback(panelData => {
@@ -1677,12 +1412,13 @@ function PanelGroupWithForwardedRef({
1677
1412
  panelDataArray
1678
1413
  } = eagerValuesRef.current;
1679
1414
  const {
1680
- collapsedSizePercentage,
1415
+ collapsedSize = 0,
1681
1416
  collapsible,
1682
- panelSizePercentage
1683
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1684
- return !collapsible || panelSizePercentage > collapsedSizePercentage;
1685
- }, [groupId]);
1417
+ panelSize
1418
+ } = panelDataHelper(panelDataArray, panelData, layout);
1419
+ assert(panelSize != null);
1420
+ return !collapsible || panelSize > collapsedSize;
1421
+ }, []);
1686
1422
  const registerPanel = useCallback(panelData => {
1687
1423
  const {
1688
1424
  autoSaveId,
@@ -1722,18 +1458,8 @@ function PanelGroupWithForwardedRef({
1722
1458
  if (autoSaveId) {
1723
1459
  unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1724
1460
  }
1725
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1726
- if (groupSizePixels <= 0) {
1727
- if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
1728
- constraints
1729
- }) => constraints))) {
1730
- // Wait until the group has rendered a non-zero size before computing layout.
1731
- return;
1732
- }
1733
- }
1734
1461
  if (unsafeLayout == null) {
1735
1462
  unsafeLayout = calculateUnsafeDefaultLayout({
1736
- groupSizePixels,
1737
1463
  panelDataArray
1738
1464
  });
1739
1465
  }
@@ -1741,7 +1467,6 @@ function PanelGroupWithForwardedRef({
1741
1467
  // Validate even saved layouts in case something has changed since last render
1742
1468
  // e.g. for pixel groups, this could be the size of the window
1743
1469
  const nextLayout = validatePanelGroupLayout({
1744
- groupSizePixels,
1745
1470
  layout: unsafeLayout,
1746
1471
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1747
1472
  });
@@ -1753,12 +1478,9 @@ function PanelGroupWithForwardedRef({
1753
1478
  eagerValuesRef.current.layout = nextLayout;
1754
1479
  if (!areEqual(prevLayout, nextLayout)) {
1755
1480
  if (onLayout) {
1756
- onLayout(nextLayout.map(sizePercentage => ({
1757
- sizePercentage,
1758
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1759
- })));
1481
+ onLayout(nextLayout);
1760
1482
  }
1761
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1483
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1762
1484
  }
1763
1485
  }, []);
1764
1486
  const registerResizeHandle = useCallback(dragHandleId => {
@@ -1768,8 +1490,7 @@ function PanelGroupWithForwardedRef({
1768
1490
  direction,
1769
1491
  dragState,
1770
1492
  id: groupId,
1771
- keyboardResizeByPercentage,
1772
- keyboardResizeByPixels,
1493
+ keyboardResizeBy,
1773
1494
  onLayout
1774
1495
  } = committedValuesRef.current;
1775
1496
  const {
@@ -1780,10 +1501,7 @@ function PanelGroupWithForwardedRef({
1780
1501
  initialLayout
1781
1502
  } = dragState !== null && dragState !== void 0 ? dragState : {};
1782
1503
  const pivotIndices = determinePivotIndices(groupId, dragHandleId);
1783
- let delta = calculateDeltaPercentage(event, groupId, dragHandleId, direction, dragState, {
1784
- percentage: keyboardResizeByPercentage,
1785
- pixels: keyboardResizeByPixels
1786
- });
1504
+ let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
1787
1505
  if (delta === 0) {
1788
1506
  return;
1789
1507
  }
@@ -1793,11 +1511,9 @@ function PanelGroupWithForwardedRef({
1793
1511
  if (document.dir === "rtl" && isHorizontal) {
1794
1512
  delta = -delta;
1795
1513
  }
1796
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1797
1514
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1798
1515
  const nextLayout = adjustLayoutByDelta({
1799
1516
  delta,
1800
- groupSizePixels,
1801
1517
  layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
1802
1518
  panelConstraints,
1803
1519
  pivotIndices,
@@ -1833,18 +1549,15 @@ function PanelGroupWithForwardedRef({
1833
1549
  setLayout(nextLayout);
1834
1550
  eagerValuesRef.current.layout = nextLayout;
1835
1551
  if (onLayout) {
1836
- onLayout(nextLayout.map(sizePercentage => ({
1837
- sizePercentage,
1838
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1839
- })));
1552
+ onLayout(nextLayout);
1840
1553
  }
1841
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1554
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1842
1555
  }
1843
1556
  };
1844
1557
  }, []);
1845
1558
 
1846
1559
  // External APIs are safe to memoize via committed values ref
1847
- const resizePanel = useCallback((panelData, mixedSizes) => {
1560
+ const resizePanel = useCallback((panelData, unsafePanelSize) => {
1848
1561
  const {
1849
1562
  onLayout
1850
1563
  } = committedValuesRef.current;
@@ -1854,16 +1567,14 @@ function PanelGroupWithForwardedRef({
1854
1567
  } = eagerValuesRef.current;
1855
1568
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1856
1569
  const {
1857
- groupSizePixels,
1858
- panelSizePercentage,
1570
+ panelSize,
1859
1571
  pivotIndices
1860
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1861
- const sizePercentage = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
1572
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1573
+ assert(panelSize != null);
1862
1574
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1863
- const delta = isLastPanel ? panelSizePercentage - sizePercentage : sizePercentage - panelSizePercentage;
1575
+ const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1864
1576
  const nextLayout = adjustLayoutByDelta({
1865
1577
  delta,
1866
- groupSizePixels,
1867
1578
  layout: prevLayout,
1868
1579
  panelConstraints: panelConstraintsArray,
1869
1580
  pivotIndices,
@@ -1873,14 +1584,11 @@ function PanelGroupWithForwardedRef({
1873
1584
  setLayout(nextLayout);
1874
1585
  eagerValuesRef.current.layout = nextLayout;
1875
1586
  if (onLayout) {
1876
- onLayout(nextLayout.map(sizePercentage => ({
1877
- sizePercentage,
1878
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1879
- })));
1587
+ onLayout(nextLayout);
1880
1588
  }
1881
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1589
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1882
1590
  }
1883
- }, [groupId]);
1591
+ }, []);
1884
1592
  const startDragging = useCallback((dragHandleId, event) => {
1885
1593
  const {
1886
1594
  direction
@@ -1889,6 +1597,7 @@ function PanelGroupWithForwardedRef({
1889
1597
  layout
1890
1598
  } = eagerValuesRef.current;
1891
1599
  const handleElement = getResizeHandleElement(dragHandleId);
1600
+ assert(handleElement);
1892
1601
  const initialCursorPosition = getResizeEventCursorPosition(direction, event);
1893
1602
  setDragState({
1894
1603
  dragHandleId,
@@ -1907,7 +1616,6 @@ function PanelGroupWithForwardedRef({
1907
1616
  });
1908
1617
  const unregisterPanel = useCallback(panelData => {
1909
1618
  const {
1910
- id: groupId,
1911
1619
  onLayout
1912
1620
  } = committedValuesRef.current;
1913
1621
  const {
@@ -1930,7 +1638,7 @@ function PanelGroupWithForwardedRef({
1930
1638
  const {
1931
1639
  pendingPanelIds
1932
1640
  } = unregisterPanelRef.current;
1933
- const map = panelIdToLastNotifiedMixedSizesMapRef.current;
1641
+ const map = panelIdToLastNotifiedSizeMapRef.current;
1934
1642
 
1935
1643
  // TRICKY
1936
1644
  // Strict effects mode
@@ -1939,7 +1647,7 @@ function PanelGroupWithForwardedRef({
1939
1647
  pendingPanelIds.delete(panelId);
1940
1648
  if (panelDataArray.find(({
1941
1649
  id
1942
- }) => id === panelId) == null) {
1650
+ }) => id === panelId) != null) {
1943
1651
  unmountDueToStrictMode = true;
1944
1652
 
1945
1653
  // TRICKY
@@ -1956,16 +1664,13 @@ function PanelGroupWithForwardedRef({
1956
1664
  // The group is unmounting; skip layout calculation.
1957
1665
  return;
1958
1666
  }
1959
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1960
1667
  let unsafeLayout = calculateUnsafeDefaultLayout({
1961
- groupSizePixels,
1962
1668
  panelDataArray
1963
1669
  });
1964
1670
 
1965
1671
  // Validate even saved layouts in case something has changed since last render
1966
1672
  // e.g. for pixel groups, this could be the size of the window
1967
1673
  const nextLayout = validatePanelGroupLayout({
1968
- groupSizePixels,
1969
1674
  layout: unsafeLayout,
1970
1675
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1971
1676
  });
@@ -1973,12 +1678,9 @@ function PanelGroupWithForwardedRef({
1973
1678
  setLayout(nextLayout);
1974
1679
  eagerValuesRef.current.layout = nextLayout;
1975
1680
  if (onLayout) {
1976
- onLayout(nextLayout.map(sizePercentage => ({
1977
- sizePercentage,
1978
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1979
- })));
1681
+ onLayout(nextLayout);
1980
1682
  }
1981
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1683
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1982
1684
  }
1983
1685
  }, 0);
1984
1686
  }, []);
@@ -2009,13 +1711,13 @@ function PanelGroupWithForwardedRef({
2009
1711
  return createElement(PanelGroupContext.Provider, {
2010
1712
  value: context
2011
1713
  }, createElement(Type, {
1714
+ ...rest,
2012
1715
  children,
2013
1716
  className: classNameFromProps,
2014
1717
  style: {
2015
1718
  ...style,
2016
1719
  ...styleFromProps
2017
1720
  },
2018
- ...dataAttributes,
2019
1721
  // CSS selectors
2020
1722
  "data-panel-group": "",
2021
1723
  "data-panel-group-direction": direction,
@@ -2028,22 +1730,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
2028
1730
  }));
2029
1731
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
2030
1732
  PanelGroup.displayName = "forwardRef(PanelGroup)";
2031
- function panelDataHelper(groupId, panelDataArray, panelData, layout) {
1733
+ function panelDataHelper(panelDataArray, panelData, layout) {
2032
1734
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
2033
1735
  const panelIndex = panelDataArray.indexOf(panelData);
2034
1736
  const panelConstraints = panelConstraintsArray[panelIndex];
2035
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
2036
- const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
2037
1737
  const isLastPanel = panelIndex === panelDataArray.length - 1;
2038
1738
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
2039
- const panelSizePercentage = layout[panelIndex];
2040
- const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
1739
+ const panelSize = layout[panelIndex];
2041
1740
  return {
2042
- ...percentagePanelConstraints,
2043
- collapsible: panelConstraints.collapsible,
2044
- panelSizePercentage,
2045
- panelSizePixels,
2046
- groupSizePixels,
1741
+ ...panelConstraints,
1742
+ panelSize,
2047
1743
  pivotIndices
2048
1744
  };
2049
1745
  }
@@ -2083,6 +1779,7 @@ function useWindowSplitterResizeHandlerBehavior({
2083
1779
  {
2084
1780
  event.preventDefault();
2085
1781
  const groupId = handleElement.getAttribute("data-panel-group-id");
1782
+ assert(groupId);
2086
1783
  const handles = getResizeHandleElementsForGroup(groupId);
2087
1784
  const index = getResizeHandleElementIndex(groupId, handleId);
2088
1785
  assert(index !== null);
@@ -2103,12 +1800,13 @@ function useWindowSplitterResizeHandlerBehavior({
2103
1800
  function PanelResizeHandle({
2104
1801
  children = null,
2105
1802
  className: classNameFromProps = "",
2106
- dataAttributes,
2107
1803
  disabled = false,
2108
- id: idFromProps = null,
1804
+ id: idFromProps,
2109
1805
  onDragging,
2110
1806
  style: styleFromProps = {},
2111
- tagName: Type = "div"
1807
+ tabIndex = 0,
1808
+ tagName: Type = "div",
1809
+ ...rest
2112
1810
  }) {
2113
1811
  const divElementRef = useRef(null);
2114
1812
 
@@ -2138,8 +1836,9 @@ function PanelResizeHandle({
2138
1836
  const stopDraggingAndBlur = useCallback(() => {
2139
1837
  // Clicking on the drag handle shouldn't leave it focused;
2140
1838
  // That would cause the PanelGroup to think it was still active.
2141
- const div = divElementRef.current;
2142
- div.blur();
1839
+ const divElement = divElementRef.current;
1840
+ assert(divElement);
1841
+ divElement.blur();
2143
1842
  stopDragging();
2144
1843
  const {
2145
1844
  onDragging
@@ -2167,6 +1866,7 @@ function PanelResizeHandle({
2167
1866
  resizeHandler(event);
2168
1867
  };
2169
1868
  const divElement = divElementRef.current;
1869
+ assert(divElement);
2170
1870
  const targetDocument = divElement.ownerDocument;
2171
1871
  targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
2172
1872
  targetDocument.body.addEventListener("mousemove", onMove);
@@ -2194,15 +1894,18 @@ function PanelResizeHandle({
2194
1894
  userSelect: "none"
2195
1895
  };
2196
1896
  return createElement(Type, {
1897
+ ...rest,
2197
1898
  children,
2198
1899
  className: classNameFromProps,
2199
1900
  onBlur: () => setIsFocused(false),
2200
1901
  onFocus: () => setIsFocused(true),
2201
1902
  onMouseDown: event => {
2202
1903
  startDragging(resizeHandleId, event.nativeEvent);
1904
+ const callbacks = callbacksRef.current;
1905
+ assert(callbacks);
2203
1906
  const {
2204
1907
  onDragging
2205
- } = callbacksRef.current;
1908
+ } = callbacks;
2206
1909
  if (onDragging) {
2207
1910
  onDragging(true);
2208
1911
  }
@@ -2212,9 +1915,11 @@ function PanelResizeHandle({
2212
1915
  onTouchEnd: stopDraggingAndBlur,
2213
1916
  onTouchStart: event => {
2214
1917
  startDragging(resizeHandleId, event.nativeEvent);
1918
+ const callbacks = callbacksRef.current;
1919
+ assert(callbacks);
2215
1920
  const {
2216
1921
  onDragging
2217
- } = callbacksRef.current;
1922
+ } = callbacks;
2218
1923
  if (onDragging) {
2219
1924
  onDragging(true);
2220
1925
  }
@@ -2225,8 +1930,7 @@ function PanelResizeHandle({
2225
1930
  ...style,
2226
1931
  ...styleFromProps
2227
1932
  },
2228
- tabIndex: 0,
2229
- ...dataAttributes,
1933
+ tabIndex,
2230
1934
  // CSS selectors
2231
1935
  "data-panel-group-direction": direction,
2232
1936
  "data-panel-group-id": groupId,
@@ -2238,4 +1942,4 @@ function PanelResizeHandle({
2238
1942
  }
2239
1943
  PanelResizeHandle.displayName = "PanelResizeHandle";
2240
1944
 
2241
- export { Panel, PanelGroup, PanelResizeHandle };
1945
+ export { Panel, PanelGroup, PanelResizeHandle, assert };