react-resizable-panels 0.0.62 → 1.0.0-rc.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. package/.eslintrc.cjs +1 -0
  2. package/CHANGELOG.md +9 -0
  3. package/dist/declarations/src/Panel.d.ts +19 -34
  4. package/dist/declarations/src/PanelGroup.d.ts +9 -13
  5. package/dist/declarations/src/PanelResizeHandle.d.ts +5 -7
  6. package/dist/declarations/src/index.d.ts +2 -2
  7. package/dist/declarations/src/types.d.ts +0 -7
  8. package/dist/declarations/src/utils/assert.d.ts +1 -0
  9. package/dist/declarations/src/vendor/react.d.ts +2 -2
  10. package/dist/react-resizable-panels.browser.cjs.js +255 -519
  11. package/dist/react-resizable-panels.browser.cjs.mjs +2 -1
  12. package/dist/react-resizable-panels.browser.development.cjs.js +281 -575
  13. package/dist/react-resizable-panels.browser.development.cjs.mjs +2 -1
  14. package/dist/react-resizable-panels.browser.development.esm.js +281 -576
  15. package/dist/react-resizable-panels.browser.esm.js +255 -520
  16. package/dist/react-resizable-panels.cjs.js +255 -519
  17. package/dist/react-resizable-panels.cjs.js.map +1 -0
  18. package/dist/react-resizable-panels.cjs.mjs +2 -1
  19. package/dist/react-resizable-panels.development.cjs.js +283 -577
  20. package/dist/react-resizable-panels.development.cjs.mjs +2 -1
  21. package/dist/react-resizable-panels.development.esm.js +283 -578
  22. package/dist/react-resizable-panels.development.node.cjs.js +269 -503
  23. package/dist/react-resizable-panels.development.node.cjs.mjs +2 -1
  24. package/dist/react-resizable-panels.development.node.esm.js +269 -504
  25. package/dist/react-resizable-panels.esm.js +255 -520
  26. package/dist/react-resizable-panels.esm.js.map +1 -0
  27. package/dist/react-resizable-panels.node.cjs.js +241 -445
  28. package/dist/react-resizable-panels.node.cjs.mjs +2 -1
  29. package/dist/react-resizable-panels.node.esm.js +241 -446
  30. package/package.json +1 -1
  31. package/src/Panel.test.tsx +74 -73
  32. package/src/Panel.ts +44 -68
  33. package/src/PanelGroup.test.tsx +43 -42
  34. package/src/PanelGroup.ts +189 -403
  35. package/src/PanelGroupContext.ts +2 -3
  36. package/src/PanelResizeHandle.test.tsx +68 -0
  37. package/src/PanelResizeHandle.ts +31 -22
  38. package/src/hooks/useWindowSplitterBehavior.ts +2 -1
  39. package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +22 -33
  40. package/src/index.ts +4 -3
  41. package/src/types.ts +0 -9
  42. package/src/utils/adjustLayoutByDelta.test.ts +206 -336
  43. package/src/utils/adjustLayoutByDelta.ts +59 -51
  44. package/src/utils/assert.ts +1 -1
  45. package/src/utils/calculateAriaValues.test.ts +6 -11
  46. package/src/utils/calculateAriaValues.ts +7 -29
  47. package/src/utils/calculateDeltaPercentage.ts +8 -15
  48. package/src/utils/calculateDragOffsetPercentage.ts +11 -5
  49. package/src/utils/calculateUnsafeDefaultLayout.test.ts +4 -9
  50. package/src/utils/calculateUnsafeDefaultLayout.ts +13 -18
  51. package/src/utils/callPanelCallbacks.ts +11 -46
  52. package/src/utils/computePanelFlexBoxStyle.ts +3 -2
  53. package/src/utils/getResizeEventCursorPosition.ts +2 -0
  54. package/src/utils/resizePanel.test.ts +6 -52
  55. package/src/utils/resizePanel.ts +24 -46
  56. package/src/utils/test-utils.ts +6 -7
  57. package/src/utils/validatePanelConstraints.test.ts +12 -65
  58. package/src/utils/validatePanelConstraints.ts +26 -67
  59. package/src/utils/validatePanelGroupLayout.test.ts +27 -142
  60. package/src/utils/validatePanelGroupLayout.ts +17 -13
  61. package/src/vendor/react.ts +2 -0
  62. package/src/utils/computePercentagePanelConstraints.test.ts +0 -98
  63. package/src/utils/computePercentagePanelConstraints.ts +0 -56
  64. package/src/utils/convertPercentageToPixels.test.ts +0 -9
  65. package/src/utils/convertPercentageToPixels.ts +0 -6
  66. package/src/utils/convertPixelConstraintsToPercentages.test.ts +0 -47
  67. package/src/utils/convertPixelConstraintsToPercentages.ts +0 -72
  68. package/src/utils/convertPixelsToPercentage.test.ts +0 -9
  69. package/src/utils/convertPixelsToPercentage.ts +0 -6
  70. package/src/utils/getPercentageSizeFromMixedSizes.test.ts +0 -47
  71. package/src/utils/getPercentageSizeFromMixedSizes.ts +0 -15
  72. package/src/utils/shouldMonitorPixelBasedConstraints.test.ts +0 -23
  73. package/src/utils/shouldMonitorPixelBasedConstraints.ts +0 -13
@@ -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
  }
@@ -1020,9 +859,10 @@ function computePanelFlexBoxStyle({
1020
859
  const size = layout[panelIndex];
1021
860
  let flexGrow;
1022
861
  if (panelData.length === 1) {
1023
- flexGrow = "100";
862
+ flexGrow = "1";
1024
863
  } else if (size == null) {
1025
- flexGrow = "0";
864
+ // Initial render (before panels have registered themselves)
865
+ flexGrow = "1";
1026
866
  } else {
1027
867
  flexGrow = size.toPrecision(precision);
1028
868
  }
@@ -1168,74 +1008,39 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
1168
1008
  }
1169
1009
  }
1170
1010
 
1171
- function shouldMonitorPixelBasedConstraints(constraints) {
1172
- return constraints.some(constraints => {
1173
- return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
1174
- });
1175
- }
1176
-
1177
1011
  function validatePanelConstraints({
1178
- groupSizePixels,
1179
- panelConstraints,
1012
+ panelConstraints: panelConstraintsArray,
1180
1013
  panelId,
1181
1014
  panelIndex
1182
1015
  }) {
1183
1016
  {
1184
1017
  const warnings = [];
1185
- {
1186
- const {
1187
- collapsedSizePercentage,
1188
- collapsedSizePixels,
1189
- defaultSizePercentage,
1190
- defaultSizePixels,
1191
- maxSizePercentage,
1192
- maxSizePixels,
1193
- minSizePercentage,
1194
- minSizePixels
1195
- } = panelConstraints[panelIndex];
1196
- const conflictingUnits = [];
1197
- if (collapsedSizePercentage != null && collapsedSizePixels != null) {
1198
- conflictingUnits.push("collapsed size");
1199
- }
1200
- if (defaultSizePercentage != null && defaultSizePixels != null) {
1201
- conflictingUnits.push("default size");
1202
- }
1203
- if (maxSizePercentage != null && maxSizePixels != null) {
1204
- conflictingUnits.push("max size");
1205
- }
1206
- if (minSizePercentage != null && minSizePixels != null) {
1207
- conflictingUnits.push("min size");
1208
- }
1209
- if (conflictingUnits.length > 0) {
1210
- warnings.push(`should not specify both percentage and pixel units for: ${conflictingUnits.join(", ")}`);
1211
- }
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}%)`);
1212
1028
  }
1213
- {
1214
- const {
1215
- collapsedSizePercentage,
1216
- defaultSizePercentage,
1217
- maxSizePercentage,
1218
- minSizePercentage
1219
- } = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
1220
- if (minSizePercentage > maxSizePercentage) {
1221
- warnings.push(`min size (${minSizePercentage}%) should not be greater than max size (${maxSizePercentage}%)`);
1222
- }
1223
- if (defaultSizePercentage != null) {
1224
- if (defaultSizePercentage < 0) {
1225
- warnings.push("default size should not be less than 0");
1226
- } else if (defaultSizePercentage < minSizePercentage) {
1227
- warnings.push("default size should not be less than min size");
1228
- }
1229
- if (defaultSizePercentage > 100) {
1230
- warnings.push("default size should not be greater than 100");
1231
- } else if (defaultSizePercentage > maxSizePercentage) {
1232
- warnings.push("default size should not be greater than max size");
1233
- }
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");
1234
1034
  }
1235
- if (collapsedSizePercentage > minSizePercentage) {
1236
- 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");
1237
1039
  }
1238
1040
  }
1041
+ if (collapsedSize > minSize) {
1042
+ warnings.push("collapsed size should not be greater than min size");
1043
+ }
1239
1044
  if (warnings.length > 0) {
1240
1045
  const name = panelId != null ? `Panel "${panelId}"` : "Panel";
1241
1046
  console.warn(`${name} has an invalid configuration:\n\n${warnings.join("\n")}`);
@@ -1247,20 +1052,26 @@ function validatePanelConstraints({
1247
1052
 
1248
1053
  // All units must be in percentages; pixel values should be pre-converted
1249
1054
  function validatePanelGroupLayout({
1250
- groupSizePixels,
1251
1055
  layout: prevLayout,
1252
1056
  panelConstraints
1253
1057
  }) {
1254
1058
  const nextLayout = [...prevLayout];
1059
+ const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
1255
1060
 
1256
1061
  // Validate layout expectations
1257
1062
  if (nextLayout.length !== panelConstraints.length) {
1258
1063
  throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
1259
- } else if (!fuzzyNumbersEqual(nextLayout.reduce((accumulated, current) => accumulated + current, 0), 100)) {
1064
+ } else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
1260
1065
  // This is not ideal so we should warn about it, but it may be recoverable in some cases
1261
1066
  // (especially if the amount is small)
1262
1067
  {
1263
- 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;
1264
1075
  }
1265
1076
  }
1266
1077
  let remainingSize = 0;
@@ -1268,8 +1079,8 @@ function validatePanelGroupLayout({
1268
1079
  // First pass: Validate the proposed layout given each panel's constraints
1269
1080
  for (let index = 0; index < panelConstraints.length; index++) {
1270
1081
  const unsafeSize = nextLayout[index];
1082
+ assert(unsafeSize != null);
1271
1083
  const safeSize = resizePanel({
1272
- groupSizePixels,
1273
1084
  panelConstraints,
1274
1085
  panelIndex: index,
1275
1086
  size: unsafeSize
@@ -1285,9 +1096,9 @@ function validatePanelGroupLayout({
1285
1096
  if (!fuzzyNumbersEqual(remainingSize, 0)) {
1286
1097
  for (let index = 0; index < panelConstraints.length; index++) {
1287
1098
  const prevSize = nextLayout[index];
1099
+ assert(prevSize != null);
1288
1100
  const unsafeSize = prevSize + remainingSize;
1289
1101
  const safeSize = resizePanel({
1290
- groupSizePixels,
1291
1102
  panelConstraints,
1292
1103
  panelIndex: index,
1293
1104
  size: unsafeSize
@@ -1322,21 +1133,20 @@ function PanelGroupWithForwardedRef({
1322
1133
  autoSaveId = null,
1323
1134
  children,
1324
1135
  className: classNameFromProps = "",
1325
- dataAttributes,
1326
1136
  direction,
1327
1137
  forwardedRef,
1328
- id: idFromProps,
1138
+ id: idFromProps = null,
1329
1139
  onLayout = null,
1330
- keyboardResizeByPercentage = null,
1331
- keyboardResizeByPixels = null,
1140
+ keyboardResizeBy = null,
1332
1141
  storage = defaultStorage,
1333
1142
  style: styleFromProps,
1334
- tagName: Type = "div"
1143
+ tagName: Type = "div",
1144
+ ...rest
1335
1145
  }) {
1336
1146
  const groupId = useUniqueId(idFromProps);
1337
1147
  const [dragState, setDragState] = useState(null);
1338
1148
  const [layout, setLayout] = useState([]);
1339
- const panelIdToLastNotifiedMixedSizesMapRef = useRef({});
1149
+ const panelIdToLastNotifiedSizeMapRef = useRef({});
1340
1150
  const panelSizeBeforeCollapseRef = useRef(new Map());
1341
1151
  const prevDeltaRef = useRef(0);
1342
1152
  const committedValuesRef = useRef({
@@ -1344,8 +1154,7 @@ function PanelGroupWithForwardedRef({
1344
1154
  direction,
1345
1155
  dragState,
1346
1156
  id: groupId,
1347
- keyboardResizeByPercentage,
1348
- keyboardResizeByPixels,
1157
+ keyboardResizeBy,
1349
1158
  onLayout,
1350
1159
  storage
1351
1160
  });
@@ -1361,33 +1170,20 @@ function PanelGroupWithForwardedRef({
1361
1170
  useImperativeHandle(forwardedRef, () => ({
1362
1171
  getId: () => committedValuesRef.current.id,
1363
1172
  getLayout: () => {
1364
- const {
1365
- id: groupId
1366
- } = committedValuesRef.current;
1367
1173
  const {
1368
1174
  layout
1369
1175
  } = eagerValuesRef.current;
1370
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1371
- return layout.map(sizePercentage => {
1372
- return {
1373
- sizePercentage,
1374
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1375
- };
1376
- });
1176
+ return layout;
1377
1177
  },
1378
- setLayout: mixedSizes => {
1178
+ setLayout: unsafeLayout => {
1379
1179
  const {
1380
- id: groupId,
1381
1180
  onLayout
1382
1181
  } = committedValuesRef.current;
1383
1182
  const {
1384
1183
  layout: prevLayout,
1385
1184
  panelDataArray
1386
1185
  } = eagerValuesRef.current;
1387
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1388
- const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
1389
1186
  const safeLayout = validatePanelGroupLayout({
1390
- groupSizePixels,
1391
1187
  layout: unsafeLayout,
1392
1188
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1393
1189
  });
@@ -1395,12 +1191,9 @@ function PanelGroupWithForwardedRef({
1395
1191
  setLayout(safeLayout);
1396
1192
  eagerValuesRef.current.layout = safeLayout;
1397
1193
  if (onLayout) {
1398
- onLayout(safeLayout.map(sizePercentage => ({
1399
- sizePercentage,
1400
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1401
- })));
1194
+ onLayout(safeLayout);
1402
1195
  }
1403
- callPanelCallbacks(groupId, panelDataArray, safeLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1196
+ callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
1404
1197
  }
1405
1198
  }
1406
1199
  }), []);
@@ -1411,11 +1204,7 @@ function PanelGroupWithForwardedRef({
1411
1204
  committedValuesRef.current.id = groupId;
1412
1205
  committedValuesRef.current.onLayout = onLayout;
1413
1206
  committedValuesRef.current.storage = storage;
1414
-
1415
- // panelDataArray and layout are updated in-sync with scheduled state updates.
1416
- // TODO [217] Move these values into a separate ref
1417
1207
  });
1418
-
1419
1208
  useWindowSplitterPanelGroupBehavior({
1420
1209
  committedValuesRef,
1421
1210
  eagerValuesRef,
@@ -1434,57 +1223,16 @@ function PanelGroupWithForwardedRef({
1434
1223
  if (layout.length === 0 || layout.length !== panelDataArray.length) {
1435
1224
  return;
1436
1225
  }
1226
+ let debouncedSave = debounceMap[autoSaveId];
1437
1227
 
1438
1228
  // Limit the frequency of localStorage updates.
1439
- if (!debounceMap[autoSaveId]) {
1440
- debounceMap[autoSaveId] = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1229
+ if (debouncedSave == null) {
1230
+ debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
1231
+ debounceMap[autoSaveId] = debouncedSave;
1441
1232
  }
1442
- debounceMap[autoSaveId](autoSaveId, panelDataArray, layout, storage);
1233
+ debouncedSave(autoSaveId, panelDataArray, layout, storage);
1443
1234
  }
1444
1235
  }, [autoSaveId, layout, storage]);
1445
- useIsomorphicLayoutEffect(() => {
1446
- const {
1447
- layout: prevLayout,
1448
- panelDataArray
1449
- } = eagerValuesRef.current;
1450
- const constraints = panelDataArray.map(({
1451
- constraints
1452
- }) => constraints);
1453
- if (!shouldMonitorPixelBasedConstraints(constraints)) {
1454
- // Avoid the overhead of ResizeObserver if no pixel constraints require monitoring
1455
- return;
1456
- }
1457
- if (typeof ResizeObserver === "undefined") {
1458
- console.warn(`WARNING: Pixel based constraints require ResizeObserver but it is not supported by the current browser.`);
1459
- } else {
1460
- const resizeObserver = new ResizeObserver(() => {
1461
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1462
- const {
1463
- onLayout
1464
- } = committedValuesRef.current;
1465
- const nextLayout = validatePanelGroupLayout({
1466
- groupSizePixels,
1467
- layout: prevLayout,
1468
- panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1469
- });
1470
- if (!areEqual(prevLayout, nextLayout)) {
1471
- setLayout(nextLayout);
1472
- eagerValuesRef.current.layout = nextLayout;
1473
- if (onLayout) {
1474
- onLayout(nextLayout.map(sizePercentage => ({
1475
- sizePercentage,
1476
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1477
- })));
1478
- }
1479
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1480
- }
1481
- });
1482
- resizeObserver.observe(getPanelGroupElement(groupId));
1483
- return () => {
1484
- resizeObserver.disconnect();
1485
- };
1486
- }
1487
- }, [groupId]);
1488
1236
 
1489
1237
  // DEV warnings
1490
1238
  useEffect(() => {
@@ -1515,12 +1263,12 @@ function PanelGroupWithForwardedRef({
1515
1263
  }
1516
1264
  if (!didLogPanelConstraintsWarning) {
1517
1265
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1518
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1519
1266
  for (let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++) {
1267
+ const panelData = panelDataArray[panelIndex];
1268
+ assert(panelData);
1520
1269
  const isValid = validatePanelConstraints({
1521
- groupSizePixels,
1522
1270
  panelConstraints,
1523
- panelId: panelDataArray[panelIndex].id,
1271
+ panelId: panelData.id,
1524
1272
  panelIndex
1525
1273
  });
1526
1274
  if (!isValid) {
@@ -1544,20 +1292,19 @@ function PanelGroupWithForwardedRef({
1544
1292
  if (panelData.constraints.collapsible) {
1545
1293
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1546
1294
  const {
1547
- collapsedSizePercentage,
1548
- panelSizePercentage,
1549
- pivotIndices,
1550
- groupSizePixels
1551
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1552
- if (panelSizePercentage !== collapsedSizePercentage) {
1295
+ collapsedSize = 0,
1296
+ panelSize,
1297
+ pivotIndices
1298
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1299
+ assert(panelSize != null);
1300
+ if (panelSize !== collapsedSize) {
1553
1301
  // Store size before collapse;
1554
1302
  // This is the size that gets restored if the expand() API is used.
1555
- panelSizeBeforeCollapseRef.current.set(panelData.id, panelSizePercentage);
1303
+ panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
1556
1304
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1557
- const delta = isLastPanel ? panelSizePercentage - collapsedSizePercentage : collapsedSizePercentage - panelSizePercentage;
1305
+ const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
1558
1306
  const nextLayout = adjustLayoutByDelta({
1559
1307
  delta,
1560
- groupSizePixels,
1561
1308
  layout: prevLayout,
1562
1309
  panelConstraints: panelConstraintsArray,
1563
1310
  pivotIndices,
@@ -1567,16 +1314,13 @@ function PanelGroupWithForwardedRef({
1567
1314
  setLayout(nextLayout);
1568
1315
  eagerValuesRef.current.layout = nextLayout;
1569
1316
  if (onLayout) {
1570
- onLayout(nextLayout.map(sizePercentage => ({
1571
- sizePercentage,
1572
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1573
- })));
1317
+ onLayout(nextLayout);
1574
1318
  }
1575
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1319
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1576
1320
  }
1577
1321
  }
1578
1322
  }
1579
- }, [groupId]);
1323
+ }, []);
1580
1324
 
1581
1325
  // External APIs are safe to memoize via committed values ref
1582
1326
  const expandPanel = useCallback(panelData => {
@@ -1590,21 +1334,19 @@ function PanelGroupWithForwardedRef({
1590
1334
  if (panelData.constraints.collapsible) {
1591
1335
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1592
1336
  const {
1593
- collapsedSizePercentage,
1594
- panelSizePercentage,
1595
- minSizePercentage,
1596
- pivotIndices,
1597
- groupSizePixels
1598
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1599
- if (panelSizePercentage === collapsedSizePercentage) {
1337
+ collapsedSize = 0,
1338
+ panelSize,
1339
+ minSize = 0,
1340
+ pivotIndices
1341
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1342
+ if (panelSize === collapsedSize) {
1600
1343
  // Restore this panel to the size it was before it was collapsed, if possible.
1601
- const prevPanelSizePercentage = panelSizeBeforeCollapseRef.current.get(panelData.id);
1602
- 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;
1603
1346
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1604
- const delta = isLastPanel ? panelSizePercentage - baseSizePercentage : baseSizePercentage - panelSizePercentage;
1347
+ const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
1605
1348
  const nextLayout = adjustLayoutByDelta({
1606
1349
  delta,
1607
- groupSizePixels,
1608
1350
  layout: prevLayout,
1609
1351
  panelConstraints: panelConstraintsArray,
1610
1352
  pivotIndices,
@@ -1614,16 +1356,13 @@ function PanelGroupWithForwardedRef({
1614
1356
  setLayout(nextLayout);
1615
1357
  eagerValuesRef.current.layout = nextLayout;
1616
1358
  if (onLayout) {
1617
- onLayout(nextLayout.map(sizePercentage => ({
1618
- sizePercentage,
1619
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1620
- })));
1359
+ onLayout(nextLayout);
1621
1360
  }
1622
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1361
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1623
1362
  }
1624
1363
  }
1625
1364
  }
1626
- }, [groupId]);
1365
+ }, []);
1627
1366
 
1628
1367
  // External APIs are safe to memoize via committed values ref
1629
1368
  const getPanelSize = useCallback(panelData => {
@@ -1632,14 +1371,11 @@ function PanelGroupWithForwardedRef({
1632
1371
  panelDataArray
1633
1372
  } = eagerValuesRef.current;
1634
1373
  const {
1635
- panelSizePercentage,
1636
- panelSizePixels
1637
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1638
- return {
1639
- sizePercentage: panelSizePercentage,
1640
- sizePixels: panelSizePixels
1641
- };
1642
- }, [groupId]);
1374
+ panelSize
1375
+ } = panelDataHelper(panelDataArray, panelData, layout);
1376
+ assert(panelSize != null);
1377
+ return panelSize;
1378
+ }, []);
1643
1379
 
1644
1380
  // This API should never read from committedValuesRef
1645
1381
  const getPanelStyle = useCallback(panelData => {
@@ -1662,12 +1398,12 @@ function PanelGroupWithForwardedRef({
1662
1398
  panelDataArray
1663
1399
  } = eagerValuesRef.current;
1664
1400
  const {
1665
- collapsedSizePercentage,
1401
+ collapsedSize,
1666
1402
  collapsible,
1667
- panelSizePercentage
1668
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1669
- return collapsible === true && panelSizePercentage === collapsedSizePercentage;
1670
- }, [groupId]);
1403
+ panelSize
1404
+ } = panelDataHelper(panelDataArray, panelData, layout);
1405
+ return collapsible === true && panelSize === collapsedSize;
1406
+ }, []);
1671
1407
 
1672
1408
  // External APIs are safe to memoize via committed values ref
1673
1409
  const isPanelExpanded = useCallback(panelData => {
@@ -1676,12 +1412,13 @@ function PanelGroupWithForwardedRef({
1676
1412
  panelDataArray
1677
1413
  } = eagerValuesRef.current;
1678
1414
  const {
1679
- collapsedSizePercentage,
1415
+ collapsedSize = 0,
1680
1416
  collapsible,
1681
- panelSizePercentage
1682
- } = panelDataHelper(groupId, panelDataArray, panelData, layout);
1683
- return !collapsible || panelSizePercentage > collapsedSizePercentage;
1684
- }, [groupId]);
1417
+ panelSize
1418
+ } = panelDataHelper(panelDataArray, panelData, layout);
1419
+ assert(panelSize != null);
1420
+ return !collapsible || panelSize > collapsedSize;
1421
+ }, []);
1685
1422
  const registerPanel = useCallback(panelData => {
1686
1423
  const {
1687
1424
  autoSaveId,
@@ -1721,18 +1458,8 @@ function PanelGroupWithForwardedRef({
1721
1458
  if (autoSaveId) {
1722
1459
  unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
1723
1460
  }
1724
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1725
- if (groupSizePixels <= 0) {
1726
- if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
1727
- constraints
1728
- }) => constraints))) {
1729
- // Wait until the group has rendered a non-zero size before computing layout.
1730
- return;
1731
- }
1732
- }
1733
1461
  if (unsafeLayout == null) {
1734
1462
  unsafeLayout = calculateUnsafeDefaultLayout({
1735
- groupSizePixels,
1736
1463
  panelDataArray
1737
1464
  });
1738
1465
  }
@@ -1740,7 +1467,6 @@ function PanelGroupWithForwardedRef({
1740
1467
  // Validate even saved layouts in case something has changed since last render
1741
1468
  // e.g. for pixel groups, this could be the size of the window
1742
1469
  const nextLayout = validatePanelGroupLayout({
1743
- groupSizePixels,
1744
1470
  layout: unsafeLayout,
1745
1471
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1746
1472
  });
@@ -1752,12 +1478,9 @@ function PanelGroupWithForwardedRef({
1752
1478
  eagerValuesRef.current.layout = nextLayout;
1753
1479
  if (!areEqual(prevLayout, nextLayout)) {
1754
1480
  if (onLayout) {
1755
- onLayout(nextLayout.map(sizePercentage => ({
1756
- sizePercentage,
1757
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1758
- })));
1481
+ onLayout(nextLayout);
1759
1482
  }
1760
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1483
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1761
1484
  }
1762
1485
  }, []);
1763
1486
  const registerResizeHandle = useCallback(dragHandleId => {
@@ -1767,8 +1490,7 @@ function PanelGroupWithForwardedRef({
1767
1490
  direction,
1768
1491
  dragState,
1769
1492
  id: groupId,
1770
- keyboardResizeByPercentage,
1771
- keyboardResizeByPixels,
1493
+ keyboardResizeBy,
1772
1494
  onLayout
1773
1495
  } = committedValuesRef.current;
1774
1496
  const {
@@ -1779,10 +1501,7 @@ function PanelGroupWithForwardedRef({
1779
1501
  initialLayout
1780
1502
  } = dragState !== null && dragState !== void 0 ? dragState : {};
1781
1503
  const pivotIndices = determinePivotIndices(groupId, dragHandleId);
1782
- let delta = calculateDeltaPercentage(event, groupId, dragHandleId, direction, dragState, {
1783
- percentage: keyboardResizeByPercentage,
1784
- pixels: keyboardResizeByPixels
1785
- });
1504
+ let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
1786
1505
  if (delta === 0) {
1787
1506
  return;
1788
1507
  }
@@ -1792,11 +1511,9 @@ function PanelGroupWithForwardedRef({
1792
1511
  if (document.dir === "rtl" && isHorizontal) {
1793
1512
  delta = -delta;
1794
1513
  }
1795
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1796
1514
  const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
1797
1515
  const nextLayout = adjustLayoutByDelta({
1798
1516
  delta,
1799
- groupSizePixels,
1800
1517
  layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
1801
1518
  panelConstraints,
1802
1519
  pivotIndices,
@@ -1832,18 +1549,15 @@ function PanelGroupWithForwardedRef({
1832
1549
  setLayout(nextLayout);
1833
1550
  eagerValuesRef.current.layout = nextLayout;
1834
1551
  if (onLayout) {
1835
- onLayout(nextLayout.map(sizePercentage => ({
1836
- sizePercentage,
1837
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1838
- })));
1552
+ onLayout(nextLayout);
1839
1553
  }
1840
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1554
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1841
1555
  }
1842
1556
  };
1843
1557
  }, []);
1844
1558
 
1845
1559
  // External APIs are safe to memoize via committed values ref
1846
- const resizePanel = useCallback((panelData, mixedSizes) => {
1560
+ const resizePanel = useCallback((panelData, unsafePanelSize) => {
1847
1561
  const {
1848
1562
  onLayout
1849
1563
  } = committedValuesRef.current;
@@ -1853,16 +1567,14 @@ function PanelGroupWithForwardedRef({
1853
1567
  } = eagerValuesRef.current;
1854
1568
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1855
1569
  const {
1856
- groupSizePixels,
1857
- panelSizePercentage,
1570
+ panelSize,
1858
1571
  pivotIndices
1859
- } = panelDataHelper(groupId, panelDataArray, panelData, prevLayout);
1860
- const sizePercentage = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
1572
+ } = panelDataHelper(panelDataArray, panelData, prevLayout);
1573
+ assert(panelSize != null);
1861
1574
  const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
1862
- const delta = isLastPanel ? panelSizePercentage - sizePercentage : sizePercentage - panelSizePercentage;
1575
+ const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
1863
1576
  const nextLayout = adjustLayoutByDelta({
1864
1577
  delta,
1865
- groupSizePixels,
1866
1578
  layout: prevLayout,
1867
1579
  panelConstraints: panelConstraintsArray,
1868
1580
  pivotIndices,
@@ -1872,14 +1584,11 @@ function PanelGroupWithForwardedRef({
1872
1584
  setLayout(nextLayout);
1873
1585
  eagerValuesRef.current.layout = nextLayout;
1874
1586
  if (onLayout) {
1875
- onLayout(nextLayout.map(sizePercentage => ({
1876
- sizePercentage,
1877
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1878
- })));
1587
+ onLayout(nextLayout);
1879
1588
  }
1880
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1589
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1881
1590
  }
1882
- }, [groupId]);
1591
+ }, []);
1883
1592
  const startDragging = useCallback((dragHandleId, event) => {
1884
1593
  const {
1885
1594
  direction
@@ -1888,6 +1597,7 @@ function PanelGroupWithForwardedRef({
1888
1597
  layout
1889
1598
  } = eagerValuesRef.current;
1890
1599
  const handleElement = getResizeHandleElement(dragHandleId);
1600
+ assert(handleElement);
1891
1601
  const initialCursorPosition = getResizeEventCursorPosition(direction, event);
1892
1602
  setDragState({
1893
1603
  dragHandleId,
@@ -1906,7 +1616,6 @@ function PanelGroupWithForwardedRef({
1906
1616
  });
1907
1617
  const unregisterPanel = useCallback(panelData => {
1908
1618
  const {
1909
- id: groupId,
1910
1619
  onLayout
1911
1620
  } = committedValuesRef.current;
1912
1621
  const {
@@ -1929,7 +1638,7 @@ function PanelGroupWithForwardedRef({
1929
1638
  const {
1930
1639
  pendingPanelIds
1931
1640
  } = unregisterPanelRef.current;
1932
- const map = panelIdToLastNotifiedMixedSizesMapRef.current;
1641
+ const map = panelIdToLastNotifiedSizeMapRef.current;
1933
1642
 
1934
1643
  // TRICKY
1935
1644
  // Strict effects mode
@@ -1955,16 +1664,13 @@ function PanelGroupWithForwardedRef({
1955
1664
  // The group is unmounting; skip layout calculation.
1956
1665
  return;
1957
1666
  }
1958
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
1959
1667
  let unsafeLayout = calculateUnsafeDefaultLayout({
1960
- groupSizePixels,
1961
1668
  panelDataArray
1962
1669
  });
1963
1670
 
1964
1671
  // Validate even saved layouts in case something has changed since last render
1965
1672
  // e.g. for pixel groups, this could be the size of the window
1966
1673
  const nextLayout = validatePanelGroupLayout({
1967
- groupSizePixels,
1968
1674
  layout: unsafeLayout,
1969
1675
  panelConstraints: panelDataArray.map(panelData => panelData.constraints)
1970
1676
  });
@@ -1972,12 +1678,9 @@ function PanelGroupWithForwardedRef({
1972
1678
  setLayout(nextLayout);
1973
1679
  eagerValuesRef.current.layout = nextLayout;
1974
1680
  if (onLayout) {
1975
- onLayout(nextLayout.map(sizePercentage => ({
1976
- sizePercentage,
1977
- sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
1978
- })));
1681
+ onLayout(nextLayout);
1979
1682
  }
1980
- callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
1683
+ callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1981
1684
  }
1982
1685
  }, 0);
1983
1686
  }, []);
@@ -2008,13 +1711,13 @@ function PanelGroupWithForwardedRef({
2008
1711
  return createElement(PanelGroupContext.Provider, {
2009
1712
  value: context
2010
1713
  }, createElement(Type, {
1714
+ ...rest,
2011
1715
  children,
2012
1716
  className: classNameFromProps,
2013
1717
  style: {
2014
1718
  ...style,
2015
1719
  ...styleFromProps
2016
1720
  },
2017
- ...dataAttributes,
2018
1721
  // CSS selectors
2019
1722
  "data-panel-group": "",
2020
1723
  "data-panel-group-direction": direction,
@@ -2027,22 +1730,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
2027
1730
  }));
2028
1731
  PanelGroupWithForwardedRef.displayName = "PanelGroup";
2029
1732
  PanelGroup.displayName = "forwardRef(PanelGroup)";
2030
- function panelDataHelper(groupId, panelDataArray, panelData, layout) {
1733
+ function panelDataHelper(panelDataArray, panelData, layout) {
2031
1734
  const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
2032
1735
  const panelIndex = panelDataArray.indexOf(panelData);
2033
1736
  const panelConstraints = panelConstraintsArray[panelIndex];
2034
- const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
2035
- const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
2036
1737
  const isLastPanel = panelIndex === panelDataArray.length - 1;
2037
1738
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
2038
- const panelSizePercentage = layout[panelIndex];
2039
- const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
1739
+ const panelSize = layout[panelIndex];
2040
1740
  return {
2041
- ...percentagePanelConstraints,
2042
- collapsible: panelConstraints.collapsible,
2043
- panelSizePercentage,
2044
- panelSizePixels,
2045
- groupSizePixels,
1741
+ ...panelConstraints,
1742
+ panelSize,
2046
1743
  pivotIndices
2047
1744
  };
2048
1745
  }
@@ -2082,6 +1779,7 @@ function useWindowSplitterResizeHandlerBehavior({
2082
1779
  {
2083
1780
  event.preventDefault();
2084
1781
  const groupId = handleElement.getAttribute("data-panel-group-id");
1782
+ assert(groupId);
2085
1783
  const handles = getResizeHandleElementsForGroup(groupId);
2086
1784
  const index = getResizeHandleElementIndex(groupId, handleId);
2087
1785
  assert(index !== null);
@@ -2102,12 +1800,13 @@ function useWindowSplitterResizeHandlerBehavior({
2102
1800
  function PanelResizeHandle({
2103
1801
  children = null,
2104
1802
  className: classNameFromProps = "",
2105
- dataAttributes,
2106
1803
  disabled = false,
2107
- id: idFromProps = null,
1804
+ id: idFromProps,
2108
1805
  onDragging,
2109
1806
  style: styleFromProps = {},
2110
- tagName: Type = "div"
1807
+ tabIndex = 0,
1808
+ tagName: Type = "div",
1809
+ ...rest
2111
1810
  }) {
2112
1811
  const divElementRef = useRef(null);
2113
1812
 
@@ -2137,8 +1836,9 @@ function PanelResizeHandle({
2137
1836
  const stopDraggingAndBlur = useCallback(() => {
2138
1837
  // Clicking on the drag handle shouldn't leave it focused;
2139
1838
  // That would cause the PanelGroup to think it was still active.
2140
- const div = divElementRef.current;
2141
- div.blur();
1839
+ const divElement = divElementRef.current;
1840
+ assert(divElement);
1841
+ divElement.blur();
2142
1842
  stopDragging();
2143
1843
  const {
2144
1844
  onDragging
@@ -2166,6 +1866,7 @@ function PanelResizeHandle({
2166
1866
  resizeHandler(event);
2167
1867
  };
2168
1868
  const divElement = divElementRef.current;
1869
+ assert(divElement);
2169
1870
  const targetDocument = divElement.ownerDocument;
2170
1871
  targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
2171
1872
  targetDocument.body.addEventListener("mousemove", onMove);
@@ -2193,15 +1894,18 @@ function PanelResizeHandle({
2193
1894
  userSelect: "none"
2194
1895
  };
2195
1896
  return createElement(Type, {
1897
+ ...rest,
2196
1898
  children,
2197
1899
  className: classNameFromProps,
2198
1900
  onBlur: () => setIsFocused(false),
2199
1901
  onFocus: () => setIsFocused(true),
2200
1902
  onMouseDown: event => {
2201
1903
  startDragging(resizeHandleId, event.nativeEvent);
1904
+ const callbacks = callbacksRef.current;
1905
+ assert(callbacks);
2202
1906
  const {
2203
1907
  onDragging
2204
- } = callbacksRef.current;
1908
+ } = callbacks;
2205
1909
  if (onDragging) {
2206
1910
  onDragging(true);
2207
1911
  }
@@ -2211,9 +1915,11 @@ function PanelResizeHandle({
2211
1915
  onTouchEnd: stopDraggingAndBlur,
2212
1916
  onTouchStart: event => {
2213
1917
  startDragging(resizeHandleId, event.nativeEvent);
1918
+ const callbacks = callbacksRef.current;
1919
+ assert(callbacks);
2214
1920
  const {
2215
1921
  onDragging
2216
- } = callbacksRef.current;
1922
+ } = callbacks;
2217
1923
  if (onDragging) {
2218
1924
  onDragging(true);
2219
1925
  }
@@ -2224,8 +1930,7 @@ function PanelResizeHandle({
2224
1930
  ...style,
2225
1931
  ...styleFromProps
2226
1932
  },
2227
- tabIndex: 0,
2228
- ...dataAttributes,
1933
+ tabIndex,
2229
1934
  // CSS selectors
2230
1935
  "data-panel-group-direction": direction,
2231
1936
  "data-panel-group-id": groupId,
@@ -2237,4 +1942,4 @@ function PanelResizeHandle({
2237
1942
  }
2238
1943
  PanelResizeHandle.displayName = "PanelResizeHandle";
2239
1944
 
2240
- export { Panel, PanelGroup, PanelResizeHandle };
1945
+ export { Panel, PanelGroup, PanelResizeHandle, assert };