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
@@ -70,6 +70,7 @@ function PanelWithForwardedRef({
70
70
  collapsedSizePercentage,
71
71
  collapsedSizePixels,
72
72
  collapsible,
73
+ dataAttributes,
73
74
  defaultSizePercentage,
74
75
  defaultSizePixels,
75
76
  forwardedRef,
@@ -183,6 +184,7 @@ function PanelWithForwardedRef({
183
184
  ...style,
184
185
  ...styleFromProps
185
186
  },
187
+ ...dataAttributes,
186
188
  // CSS selectors
187
189
  "data-panel": "",
188
190
  "data-panel-id": panelId,
@@ -320,7 +322,13 @@ function resizePanel({
320
322
  if (minSizePercentage != null) {
321
323
  if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
322
324
  if (collapsible) {
323
- size = collapsedSizePercentage;
325
+ // Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
326
+ const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
327
+ if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
328
+ size = collapsedSizePercentage;
329
+ } else {
330
+ size = minSizePercentage;
331
+ }
324
332
  } else {
325
333
  size = minSizePercentage;
326
334
  }
@@ -347,60 +355,123 @@ function adjustLayoutByDelta({
347
355
  const nextLayout = [...prevLayout];
348
356
  let deltaApplied = 0;
349
357
 
358
+ //const DEBUG = [];
359
+ //DEBUG.push(`adjustLayoutByDelta() ${prevLayout.join(", ")}`);
360
+ //DEBUG.push(` delta: ${delta}`);
361
+ //DEBUG.push(` pivotIndices: ${pivotIndices.join(", ")}`);
362
+ //DEBUG.push(` trigger: ${trigger}`);
363
+ //DEBUG.push("");
364
+
350
365
  // A resizing panel affects the panels before or after it.
351
366
  //
352
- // A negative delta means the panel immediately after the resizer should grow/expand by decreasing its offset.
367
+ // A negative delta means the panel(s) immediately after the resize handle should grow/expand by decreasing its offset.
353
368
  // Other panels may also need to shrink/contract (and shift) to make room, depending on the min weights.
354
369
  //
355
- // A positive delta means the panel immediately before the resizer should "expand".
356
- // This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the resizer.
370
+ // A positive delta means the panel(s) immediately before the resize handle should "expand".
371
+ // This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the resize handle.
357
372
 
358
- // First, check the panel we're pivoting around;
359
- // We should only expand or contract by as much as its constraints allow
360
373
  {
361
- const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
362
- const initialSize = nextLayout[pivotIndex];
363
- const {
364
- collapsible
365
- } = panelConstraints[pivotIndex];
366
- const {
367
- collapsedSizePercentage,
368
- minSizePercentage
369
- } = computePercentagePanelConstraints(panelConstraints, pivotIndex, groupSizePixels);
370
- const isCollapsed = collapsible && fuzzyNumbersEqual(initialSize, collapsedSizePercentage);
371
- let unsafeSize = initialSize + Math.abs(delta);
372
- if (isCollapsed) {
373
- switch (trigger) {
374
- case "keyboard":
375
- if (minSizePercentage > unsafeSize) {
376
- unsafeSize = minSizePercentage;
374
+ // If this is a resize triggered by a keyboard event, our logic for expanding/collapsing is different.
375
+ // We no longer check the halfway threshold because this may prevent the panel from expanding at all.
376
+ if (trigger === "keyboard") {
377
+ {
378
+ // Check if we should expand a collapsed panel
379
+ const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
380
+ const constraints = panelConstraints[index];
381
+ //DEBUG.push(`edge case check 1: ${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, collapsedSizePercentage)) {
390
+ const localDelta = minSizePercentage - prevSize;
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
+ }
397
+ }
398
+ }
399
+ }
400
+
401
+ {
402
+ // Check if we should collapse a panel at its minimum size
403
+ const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
404
+ const constraints = panelConstraints[index];
405
+ //DEBUG.push(`edge case check 2: ${index}`);
406
+ //DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
407
+ if (constraints.collapsible) {
408
+ const prevSize = prevLayout[index];
409
+ const {
410
+ collapsedSizePercentage,
411
+ minSizePercentage
412
+ } = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
413
+ if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
414
+ const localDelta = prevSize - collapsedSizePercentage;
415
+ //DEBUG.push(` -> expand delta: ${localDelta}`);
416
+
417
+ if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
418
+ delta = delta < 0 ? 0 - localDelta : localDelta;
419
+ //DEBUG.push(` -> delta: ${delta}`);
420
+ }
377
421
  }
422
+ }
378
423
  }
379
424
  }
380
- const safeSize = resizePanel({
381
- groupSizePixels,
382
- panelConstraints,
383
- panelIndex: pivotIndex,
384
- size: unsafeSize
385
- });
386
- if (fuzzyNumbersEqual(initialSize, safeSize)) {
387
- // If there's no room for the pivot panel to grow, we should ignore this change
388
- return nextLayout;
389
- } else {
390
- delta = delta < 0 ? initialSize - safeSize : safeSize - initialSize;
425
+ //DEBUG.push("");
426
+ }
427
+
428
+ {
429
+ // Pre-calculate max available delta in the opposite direction of our pivot.
430
+ // This will be the maximum amount we're allowed to expand/contract the panels in the primary direction.
431
+ // If this amount is less than the requested delta, adjust the requested delta.
432
+ // If this amount is greater than the requested delta, that's useful information too–
433
+ // as an expanding panel might change from collapsed to min size.
434
+
435
+ const increment = delta < 0 ? 1 : -1;
436
+ let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
437
+ let maxAvailableDelta = 0;
438
+
439
+ //DEBUG.push("pre calc...");
440
+ while (true) {
441
+ const prevSize = prevLayout[index];
442
+ const maxSafeSize = resizePanel({
443
+ groupSizePixels,
444
+ panelConstraints,
445
+ panelIndex: index,
446
+ size: 100
447
+ });
448
+ const delta = maxSafeSize - prevSize;
449
+ //DEBUG.push(` ${index}: ${prevSize} -> ${maxSafeSize}`);
450
+
451
+ maxAvailableDelta += delta;
452
+ index += increment;
453
+ if (index < 0 || index >= panelConstraints.length) {
454
+ break;
455
+ }
391
456
  }
457
+
458
+ //DEBUG.push(` -> max available delta: ${maxAvailableDelta}`);
459
+ const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
460
+ delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
461
+ //DEBUG.push(` -> adjusted delta: ${delta}`);
462
+ //DEBUG.push("");
392
463
  }
393
464
 
394
- // Delta added to a panel needs to be subtracted from other panels
395
- // within the constraints that those panels allow
396
465
  {
466
+ // Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
467
+
397
468
  const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
398
469
  let index = pivotIndex;
399
470
  while (index >= 0 && index < panelConstraints.length) {
400
471
  const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
401
472
  const prevSize = prevLayout[index];
402
473
  const unsafeSize = prevSize - deltaRemaining;
403
- let safeSize = resizePanel({
474
+ const safeSize = resizePanel({
404
475
  groupSizePixels,
405
476
  panelConstraints,
406
477
  panelIndex: index,
@@ -422,13 +493,18 @@ function adjustLayoutByDelta({
422
493
  }
423
494
  }
424
495
  }
496
+ //DEBUG.push(`after 1: ${nextLayout.join(", ")}`);
497
+ //DEBUG.push(` deltaApplied: ${deltaApplied}`);
498
+ //DEBUG.push("");
425
499
 
426
500
  // If we were unable to resize any of the panels panels, return the previous state.
427
501
  // This will essentially bailout and ignore e.g. drags past a panel's boundaries
428
502
  if (fuzzyNumbersEqual(deltaApplied, 0)) {
503
+ //console.log(DEBUG.join("\n"));
429
504
  return prevLayout;
430
505
  }
431
506
  {
507
+ // Now distribute the applied delta to the panels in the other direction
432
508
  const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
433
509
  const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
434
510
  const safeSize = resizePanel({
@@ -468,29 +544,21 @@ function adjustLayoutByDelta({
468
544
  index++;
469
545
  }
470
546
  }
471
-
472
- // If we can't redistribute, this layout is invalid;
473
- // There may be an incremental layout that is valid though
474
- if (!fuzzyNumbersEqual(deltaRemaining, 0)) {
475
- try {
476
- return adjustLayoutByDelta({
477
- delta: delta < 0 ? delta + 1 : delta - 1,
478
- groupSizePixels,
479
- layout: prevLayout,
480
- panelConstraints,
481
- pivotIndices,
482
- trigger
483
- });
484
- } catch (error) {
485
- if (error instanceof RangeError) {
486
- console.error(`Could not apply delta ${delta} to layout`);
487
- return prevLayout;
488
- }
489
- } finally {
490
- }
491
- }
492
547
  }
493
548
  }
549
+ //DEBUG.push(`after 2: ${nextLayout.join(", ")}`);
550
+ //DEBUG.push(` deltaApplied: ${deltaApplied}`);
551
+ //DEBUG.push("");
552
+
553
+ const totalSize = nextLayout.reduce((total, size) => size + total, 0);
554
+ deltaApplied = 100 - totalSize;
555
+ //DEBUG.push(`total size: ${totalSize}`);
556
+ //DEBUG.push(` deltaApplied: ${deltaApplied}`);
557
+ //console.log(DEBUG.join("\n"));
558
+
559
+ if (!fuzzyNumbersEqual(totalSize, 100)) {
560
+ return prevLayout;
561
+ }
494
562
  return nextLayout;
495
563
  }
496
564
 
@@ -1187,6 +1255,7 @@ function PanelGroupWithForwardedRef({
1187
1255
  autoSaveId,
1188
1256
  children,
1189
1257
  className: classNameFromProps = "",
1258
+ dataAttributes,
1190
1259
  direction,
1191
1260
  forwardedRef,
1192
1261
  id: idFromProps,
@@ -1719,6 +1788,7 @@ function PanelGroupWithForwardedRef({
1719
1788
  ...style,
1720
1789
  ...styleFromProps
1721
1790
  },
1791
+ ...dataAttributes,
1722
1792
  // CSS selectors
1723
1793
  "data-panel-group": "",
1724
1794
  "data-panel-group-direction": direction,
@@ -1806,6 +1876,7 @@ function useWindowSplitterResizeHandlerBehavior({
1806
1876
  function PanelResizeHandle({
1807
1877
  children = null,
1808
1878
  className: classNameFromProps = "",
1879
+ dataAttributes,
1809
1880
  disabled = false,
1810
1881
  id: idFromProps = null,
1811
1882
  onDragging,
@@ -1928,6 +1999,7 @@ function PanelResizeHandle({
1928
1999
  ...styleFromProps
1929
2000
  },
1930
2001
  tabIndex: 0,
2002
+ ...dataAttributes,
1931
2003
  // CSS selectors
1932
2004
  "data-panel-group-direction": direction,
1933
2005
  "data-panel-group-id": groupId,