react-resizable-panels 0.0.57 → 0.0.58

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 (29) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/dist/declarations/src/Panel.d.ts +7 -3
  3. package/dist/declarations/src/PanelGroup.d.ts +3 -1
  4. package/dist/declarations/src/PanelResizeHandle.d.ts +3 -1
  5. package/dist/declarations/src/types.d.ts +3 -0
  6. package/dist/react-resizable-panels.browser.cjs.js +129 -57
  7. package/dist/react-resizable-panels.browser.development.cjs.js +129 -57
  8. package/dist/react-resizable-panels.browser.development.esm.js +129 -57
  9. package/dist/react-resizable-panels.browser.esm.js +129 -57
  10. package/dist/react-resizable-panels.cjs.js +129 -57
  11. package/dist/react-resizable-panels.cjs.js.map +1 -1
  12. package/dist/react-resizable-panels.development.cjs.js +129 -57
  13. package/dist/react-resizable-panels.development.esm.js +129 -57
  14. package/dist/react-resizable-panels.development.node.cjs.js +129 -57
  15. package/dist/react-resizable-panels.development.node.esm.js +129 -57
  16. package/dist/react-resizable-panels.esm.js +129 -57
  17. package/dist/react-resizable-panels.esm.js.map +1 -1
  18. package/dist/react-resizable-panels.node.cjs.js +129 -57
  19. package/dist/react-resizable-panels.node.esm.js +129 -57
  20. package/package.json +1 -1
  21. package/src/Panel.ts +8 -2
  22. package/src/PanelGroup.ts +5 -1
  23. package/src/PanelResizeHandle.ts +5 -0
  24. package/src/types.ts +4 -0
  25. package/src/utils/adjustLayoutByDelta.test.ts +238 -8
  26. package/src/utils/adjustLayoutByDelta.ts +122 -72
  27. package/src/utils/resizePanel.test.ts +61 -1
  28. package/src/utils/resizePanel.ts +7 -1
  29. package/src/utils/validatePanelGroupLayout.test.ts +36 -6
@@ -46,6 +46,7 @@ function PanelWithForwardedRef({
46
46
  collapsedSizePercentage,
47
47
  collapsedSizePixels,
48
48
  collapsible,
49
+ dataAttributes,
49
50
  defaultSizePercentage,
50
51
  defaultSizePixels,
51
52
  forwardedRef,
@@ -159,6 +160,7 @@ function PanelWithForwardedRef({
159
160
  ...style,
160
161
  ...styleFromProps
161
162
  },
163
+ ...dataAttributes,
162
164
  // CSS selectors
163
165
  "data-panel": "",
164
166
  "data-panel-id": panelId,
@@ -296,7 +298,13 @@ function resizePanel({
296
298
  if (minSizePercentage != null) {
297
299
  if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
298
300
  if (collapsible) {
299
- size = collapsedSizePercentage;
301
+ // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
302
+ const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
303
+ if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
304
+ size = collapsedSizePercentage;
305
+ } else {
306
+ size = minSizePercentage;
307
+ }
300
308
  } else {
301
309
  size = minSizePercentage;
302
310
  }
@@ -323,60 +331,123 @@ function adjustLayoutByDelta({
323
331
  const nextLayout = [...prevLayout];
324
332
  let deltaApplied = 0;
325
333
 
334
+ //const DEBUG = [];
335
+ //DEBUG.push(`adjustLayoutByDelta() ${prevLayout.join(", ")}`);
336
+ //DEBUG.push(` delta: ${delta}`);
337
+ //DEBUG.push(` pivotIndices: ${pivotIndices.join(", ")}`);
338
+ //DEBUG.push(` trigger: ${trigger}`);
339
+ //DEBUG.push("");
340
+
326
341
  // A resizing panel affects the panels before or after it.
327
342
  //
328
- // A negative delta means the panel immediately after the resizer should grow/expand by decreasing its offset.
343
+ // A negative delta means the panel(s) immediately after the resize handle should grow/expand by decreasing its offset.
329
344
  // Other panels may also need to shrink/contract (and shift) to make room, depending on the min weights.
330
345
  //
331
- // A positive delta means the panel immediately before the resizer should "expand".
332
- // This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the resizer.
346
+ // A positive delta means the panel(s) immediately before the resize handle should "expand".
347
+ // This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the resize handle.
333
348
 
334
- // First, check the panel we're pivoting around;
335
- // We should only expand or contract by as much as its constraints allow
336
349
  {
337
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
338
- const initialSize = nextLayout[pivotIndex];
339
- const {
340
- collapsible
341
- } = panelConstraints[pivotIndex];
342
- const {
343
- collapsedSizePercentage,
344
- minSizePercentage
345
- } = computePercentagePanelConstraints(panelConstraints, pivotIndex, groupSizePixels);
346
- const isCollapsed = collapsible && fuzzyNumbersEqual(initialSize, collapsedSizePercentage);
347
- let unsafeSize = initialSize + Math.abs(delta);
348
- if (isCollapsed) {
349
- switch (trigger) {
350
- case "keyboard":
351
- if (minSizePercentage > unsafeSize) {
352
- unsafeSize = minSizePercentage;
350
+ // If this is a resize triggered by a keyboard event, our logic for expanding/collapsing is different.
351
+ // We no longer check the halfway threshold because this may prevent the panel from expanding at all.
352
+ if (trigger === "keyboard") {
353
+ {
354
+ // Check if we should expand a collapsed panel
355
+ const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
356
+ const constraints = panelConstraints[index];
357
+ //DEBUG.push(`edge case check 1: ${index}`);
358
+ //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
359
+ if (constraints.collapsible) {
360
+ const prevSize = prevLayout[index];
361
+ const {
362
+ collapsedSizePercentage,
363
+ minSizePercentage
364
+ } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
365
+ if (fuzzyNumbersEqual(prevSize, collapsedSizePercentage)) {
366
+ const localDelta = minSizePercentage - prevSize;
367
+ //DEBUG.push(` -> expand delta: ${localDelta}`);
368
+
369
+ if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
370
+ delta = delta < 0 ? 0 - localDelta : localDelta;
371
+ //DEBUG.push(` -> delta: ${delta}`);
372
+ }
373
+ }
374
+ }
375
+ }
376
+
377
+ {
378
+ // Check if we should collapse a panel at its minimum size
379
+ const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
380
+ const constraints = panelConstraints[index];
381
+ //DEBUG.push(`edge case check 2: ${index}`);
382
+ //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
383
+ if (constraints.collapsible) {
384
+ const prevSize = prevLayout[index];
385
+ const {
386
+ collapsedSizePercentage,
387
+ minSizePercentage
388
+ } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
389
+ if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
390
+ const localDelta = prevSize - collapsedSizePercentage;
391
+ //DEBUG.push(` -> expand delta: ${localDelta}`);
392
+
393
+ if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
394
+ delta = delta < 0 ? 0 - localDelta : localDelta;
395
+ //DEBUG.push(` -> delta: ${delta}`);
396
+ }
353
397
  }
398
+ }
354
399
  }
355
400
  }
356
- const safeSize = resizePanel({
357
- groupSizePixels,
358
- panelConstraints,
359
- panelIndex: pivotIndex,
360
- size: unsafeSize
361
- });
362
- if (fuzzyNumbersEqual(initialSize, safeSize)) {
363
- // If there's no room for the pivot panel to grow, we should ignore this change
364
- return nextLayout;
365
- } else {
366
- delta = delta < 0 ? initialSize - safeSize : safeSize - initialSize;
401
+ //DEBUG.push("");
402
+ }
403
+
404
+ {
405
+ // Pre-calculate max available delta in the opposite direction of our pivot.
406
+ // This will be the maximum amount we're allowed to expand/contract the panels in the primary direction.
407
+ // If this amount is less than the requested delta, adjust the requested delta.
408
+ // If this amount is greater than the requested delta, that's useful information too–
409
+ // as an expanding panel might change from collapsed to min size.
410
+
411
+ const increment = delta < 0 ? 1 : -1;
412
+ let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
413
+ let maxAvailableDelta = 0;
414
+
415
+ //DEBUG.push("pre calc...");
416
+ while (true) {
417
+ const prevSize = prevLayout[index];
418
+ const maxSafeSize = resizePanel({
419
+ groupSizePixels,
420
+ panelConstraints,
421
+ panelIndex: index,
422
+ size: 100
423
+ });
424
+ const delta = maxSafeSize - prevSize;
425
+ //DEBUG.push(` ${index}: ${prevSize} -> ${maxSafeSize}`);
426
+
427
+ maxAvailableDelta += delta;
428
+ index += increment;
429
+ if (index < 0 || index >= panelConstraints.length) {
430
+ break;
431
+ }
367
432
  }
433
+
434
+ //DEBUG.push(` -> max available delta: ${maxAvailableDelta}`);
435
+ const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
436
+ delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
437
+ //DEBUG.push(` -> adjusted delta: ${delta}`);
438
+ //DEBUG.push("");
368
439
  }
369
440
 
370
- // Delta added to a panel needs to be subtracted from other panels
371
- // within the constraints that those panels allow
372
441
  {
442
+ // Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
443
+
373
444
  const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
374
445
  let index = pivotIndex;
375
446
  while (index >= 0 && index < panelConstraints.length) {
376
447
  const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
377
448
  const prevSize = prevLayout[index];
378
449
  const unsafeSize = prevSize - deltaRemaining;
379
- let safeSize = resizePanel({
450
+ const safeSize = resizePanel({
380
451
  groupSizePixels,
381
452
  panelConstraints,
382
453
  panelIndex: index,
@@ -398,13 +469,18 @@ function adjustLayoutByDelta({
398
469
  }
399
470
  }
400
471
  }
472
+ //DEBUG.push(`after 1: ${nextLayout.join(", ")}`);
473
+ //DEBUG.push(` deltaApplied: ${deltaApplied}`);
474
+ //DEBUG.push("");
401
475
 
402
476
  // If we were unable to resize any of the panels panels, return the previous state.
403
477
  // This will essentially bailout and ignore e.g. drags past a panel's boundaries
404
478
  if (fuzzyNumbersEqual(deltaApplied, 0)) {
479
+ //console.log(DEBUG.join("\n"));
405
480
  return prevLayout;
406
481
  }
407
482
  {
483
+ // Now distribute the applied delta to the panels in the other direction
408
484
  const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
409
485
  const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
410
486
  const safeSize = resizePanel({
@@ -444,29 +520,21 @@ function adjustLayoutByDelta({
444
520
  index++;
445
521
  }
446
522
  }
447
-
448
- // If we can't redistribute, this layout is invalid;
449
- // There may be an incremental layout that is valid though
450
- if (!fuzzyNumbersEqual(deltaRemaining, 0)) {
451
- try {
452
- return adjustLayoutByDelta({
453
- delta: delta < 0 ? delta + 1 : delta - 1,
454
- groupSizePixels,
455
- layout: prevLayout,
456
- panelConstraints,
457
- pivotIndices,
458
- trigger
459
- });
460
- } catch (error) {
461
- if (error instanceof RangeError) {
462
- console.error(`Could not apply delta ${delta} to layout`);
463
- return prevLayout;
464
- }
465
- } finally {
466
- }
467
- }
468
523
  }
469
524
  }
525
+ //DEBUG.push(`after 2: ${nextLayout.join(", ")}`);
526
+ //DEBUG.push(` deltaApplied: ${deltaApplied}`);
527
+ //DEBUG.push("");
528
+
529
+ const totalSize = nextLayout.reduce((total, size) => size + total, 0);
530
+ deltaApplied = 100 - totalSize;
531
+ //DEBUG.push(`total size: ${totalSize}`);
532
+ //DEBUG.push(` deltaApplied: ${deltaApplied}`);
533
+ //console.log(DEBUG.join("\n"));
534
+
535
+ if (!fuzzyNumbersEqual(totalSize, 100)) {
536
+ return prevLayout;
537
+ }
470
538
  return nextLayout;
471
539
  }
472
540
 
@@ -1163,6 +1231,7 @@ function PanelGroupWithForwardedRef({
1163
1231
  autoSaveId,
1164
1232
  children,
1165
1233
  className: classNameFromProps = "",
1234
+ dataAttributes,
1166
1235
  direction,
1167
1236
  forwardedRef,
1168
1237
  id: idFromProps,
@@ -1695,6 +1764,7 @@ function PanelGroupWithForwardedRef({
1695
1764
  ...style,
1696
1765
  ...styleFromProps
1697
1766
  },
1767
+ ...dataAttributes,
1698
1768
  // CSS selectors
1699
1769
  "data-panel-group": "",
1700
1770
  "data-panel-group-direction": direction,
@@ -1782,6 +1852,7 @@ function useWindowSplitterResizeHandlerBehavior({
1782
1852
  function PanelResizeHandle({
1783
1853
  children = null,
1784
1854
  className: classNameFromProps = "",
1855
+ dataAttributes,
1785
1856
  disabled = false,
1786
1857
  id: idFromProps = null,
1787
1858
  onDragging,
@@ -1904,6 +1975,7 @@ function PanelResizeHandle({
1904
1975
  ...styleFromProps
1905
1976
  },
1906
1977
  tabIndex: 0,
1978
+ ...dataAttributes,
1907
1979
  // CSS selectors
1908
1980
  "data-panel-group-direction": direction,
1909
1981
  "data-panel-group-id": groupId,