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.
- package/CHANGELOG.md +7 -0
- package/dist/declarations/src/Panel.d.ts +7 -3
- package/dist/declarations/src/PanelGroup.d.ts +3 -1
- package/dist/declarations/src/PanelResizeHandle.d.ts +3 -1
- package/dist/declarations/src/types.d.ts +3 -0
- package/dist/react-resizable-panels.browser.cjs.js +129 -57
- package/dist/react-resizable-panels.browser.development.cjs.js +129 -57
- package/dist/react-resizable-panels.browser.development.esm.js +129 -57
- package/dist/react-resizable-panels.browser.esm.js +129 -57
- package/dist/react-resizable-panels.cjs.js +129 -57
- package/dist/react-resizable-panels.cjs.js.map +1 -1
- package/dist/react-resizable-panels.development.cjs.js +129 -57
- package/dist/react-resizable-panels.development.esm.js +129 -57
- package/dist/react-resizable-panels.development.node.cjs.js +129 -57
- package/dist/react-resizable-panels.development.node.esm.js +129 -57
- package/dist/react-resizable-panels.esm.js +129 -57
- package/dist/react-resizable-panels.esm.js.map +1 -1
- package/dist/react-resizable-panels.node.cjs.js +129 -57
- package/dist/react-resizable-panels.node.esm.js +129 -57
- package/package.json +1 -1
- package/src/Panel.ts +8 -2
- package/src/PanelGroup.ts +5 -1
- package/src/PanelResizeHandle.ts +5 -0
- package/src/types.ts +4 -0
- package/src/utils/adjustLayoutByDelta.test.ts +238 -8
- package/src/utils/adjustLayoutByDelta.ts +122 -72
- package/src/utils/resizePanel.test.ts +61 -1
- package/src/utils/resizePanel.ts +7 -1
- package/src/utils/validatePanelGroupLayout.test.ts +36 -6
|
@@ -66,6 +66,7 @@ function PanelWithForwardedRef({
|
|
|
66
66
|
collapsedSizePercentage,
|
|
67
67
|
collapsedSizePixels,
|
|
68
68
|
collapsible,
|
|
69
|
+
dataAttributes,
|
|
69
70
|
defaultSizePercentage,
|
|
70
71
|
defaultSizePixels,
|
|
71
72
|
forwardedRef,
|
|
@@ -151,6 +152,7 @@ function PanelWithForwardedRef({
|
|
|
151
152
|
...style,
|
|
152
153
|
...styleFromProps
|
|
153
154
|
},
|
|
155
|
+
...dataAttributes,
|
|
154
156
|
// CSS selectors
|
|
155
157
|
"data-panel": "",
|
|
156
158
|
"data-panel-id": panelId,
|
|
@@ -288,7 +290,13 @@ function resizePanel({
|
|
|
288
290
|
if (minSizePercentage != null) {
|
|
289
291
|
if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
|
|
290
292
|
if (collapsible) {
|
|
291
|
-
|
|
293
|
+
// Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
|
|
294
|
+
const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
|
|
295
|
+
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
296
|
+
size = collapsedSizePercentage;
|
|
297
|
+
} else {
|
|
298
|
+
size = minSizePercentage;
|
|
299
|
+
}
|
|
292
300
|
} else {
|
|
293
301
|
size = minSizePercentage;
|
|
294
302
|
}
|
|
@@ -315,60 +323,123 @@ function adjustLayoutByDelta({
|
|
|
315
323
|
const nextLayout = [...prevLayout];
|
|
316
324
|
let deltaApplied = 0;
|
|
317
325
|
|
|
326
|
+
//const DEBUG = [];
|
|
327
|
+
//DEBUG.push(`adjustLayoutByDelta() ${prevLayout.join(", ")}`);
|
|
328
|
+
//DEBUG.push(` delta: ${delta}`);
|
|
329
|
+
//DEBUG.push(` pivotIndices: ${pivotIndices.join(", ")}`);
|
|
330
|
+
//DEBUG.push(` trigger: ${trigger}`);
|
|
331
|
+
//DEBUG.push("");
|
|
332
|
+
|
|
318
333
|
// A resizing panel affects the panels before or after it.
|
|
319
334
|
//
|
|
320
|
-
// A negative delta means the panel immediately after the
|
|
335
|
+
// A negative delta means the panel(s) immediately after the resize handle should grow/expand by decreasing its offset.
|
|
321
336
|
// Other panels may also need to shrink/contract (and shift) to make room, depending on the min weights.
|
|
322
337
|
//
|
|
323
|
-
// A positive delta means the panel immediately before the
|
|
324
|
-
// This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the
|
|
338
|
+
// A positive delta means the panel(s) immediately before the resize handle should "expand".
|
|
339
|
+
// This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the resize handle.
|
|
325
340
|
|
|
326
|
-
// First, check the panel we're pivoting around;
|
|
327
|
-
// We should only expand or contract by as much as its constraints allow
|
|
328
341
|
{
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
342
|
+
// If this is a resize triggered by a keyboard event, our logic for expanding/collapsing is different.
|
|
343
|
+
// We no longer check the halfway threshold because this may prevent the panel from expanding at all.
|
|
344
|
+
if (trigger === "keyboard") {
|
|
345
|
+
{
|
|
346
|
+
// Check if we should expand a collapsed panel
|
|
347
|
+
const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
348
|
+
const constraints = panelConstraints[index];
|
|
349
|
+
//DEBUG.push(`edge case check 1: ${index}`);
|
|
350
|
+
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
351
|
+
if (constraints.collapsible) {
|
|
352
|
+
const prevSize = prevLayout[index];
|
|
353
|
+
const {
|
|
354
|
+
collapsedSizePercentage,
|
|
355
|
+
minSizePercentage
|
|
356
|
+
} = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
|
|
357
|
+
if (fuzzyNumbersEqual(prevSize, collapsedSizePercentage)) {
|
|
358
|
+
const localDelta = minSizePercentage - prevSize;
|
|
359
|
+
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
360
|
+
|
|
361
|
+
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
362
|
+
delta = delta < 0 ? 0 - localDelta : localDelta;
|
|
363
|
+
//DEBUG.push(` -> delta: ${delta}`);
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
{
|
|
370
|
+
// Check if we should collapse a panel at its minimum size
|
|
371
|
+
const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
|
|
372
|
+
const constraints = panelConstraints[index];
|
|
373
|
+
//DEBUG.push(`edge case check 2: ${index}`);
|
|
374
|
+
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
375
|
+
if (constraints.collapsible) {
|
|
376
|
+
const prevSize = prevLayout[index];
|
|
377
|
+
const {
|
|
378
|
+
collapsedSizePercentage,
|
|
379
|
+
minSizePercentage
|
|
380
|
+
} = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
|
|
381
|
+
if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
|
|
382
|
+
const localDelta = prevSize - collapsedSizePercentage;
|
|
383
|
+
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
384
|
+
|
|
385
|
+
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
386
|
+
delta = delta < 0 ? 0 - localDelta : localDelta;
|
|
387
|
+
//DEBUG.push(` -> delta: ${delta}`);
|
|
388
|
+
}
|
|
345
389
|
}
|
|
390
|
+
}
|
|
346
391
|
}
|
|
347
392
|
}
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
393
|
+
//DEBUG.push("");
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
{
|
|
397
|
+
// Pre-calculate max available delta in the opposite direction of our pivot.
|
|
398
|
+
// This will be the maximum amount we're allowed to expand/contract the panels in the primary direction.
|
|
399
|
+
// If this amount is less than the requested delta, adjust the requested delta.
|
|
400
|
+
// If this amount is greater than the requested delta, that's useful information too–
|
|
401
|
+
// as an expanding panel might change from collapsed to min size.
|
|
402
|
+
|
|
403
|
+
const increment = delta < 0 ? 1 : -1;
|
|
404
|
+
let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
405
|
+
let maxAvailableDelta = 0;
|
|
406
|
+
|
|
407
|
+
//DEBUG.push("pre calc...");
|
|
408
|
+
while (true) {
|
|
409
|
+
const prevSize = prevLayout[index];
|
|
410
|
+
const maxSafeSize = resizePanel({
|
|
411
|
+
groupSizePixels,
|
|
412
|
+
panelConstraints,
|
|
413
|
+
panelIndex: index,
|
|
414
|
+
size: 100
|
|
415
|
+
});
|
|
416
|
+
const delta = maxSafeSize - prevSize;
|
|
417
|
+
//DEBUG.push(` ${index}: ${prevSize} -> ${maxSafeSize}`);
|
|
418
|
+
|
|
419
|
+
maxAvailableDelta += delta;
|
|
420
|
+
index += increment;
|
|
421
|
+
if (index < 0 || index >= panelConstraints.length) {
|
|
422
|
+
break;
|
|
423
|
+
}
|
|
359
424
|
}
|
|
425
|
+
|
|
426
|
+
//DEBUG.push(` -> max available delta: ${maxAvailableDelta}`);
|
|
427
|
+
const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
|
|
428
|
+
delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
|
|
429
|
+
//DEBUG.push(` -> adjusted delta: ${delta}`);
|
|
430
|
+
//DEBUG.push("");
|
|
360
431
|
}
|
|
361
432
|
|
|
362
|
-
// Delta added to a panel needs to be subtracted from other panels
|
|
363
|
-
// within the constraints that those panels allow
|
|
364
433
|
{
|
|
434
|
+
// Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
|
|
435
|
+
|
|
365
436
|
const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
|
|
366
437
|
let index = pivotIndex;
|
|
367
438
|
while (index >= 0 && index < panelConstraints.length) {
|
|
368
439
|
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
369
440
|
const prevSize = prevLayout[index];
|
|
370
441
|
const unsafeSize = prevSize - deltaRemaining;
|
|
371
|
-
|
|
442
|
+
const safeSize = resizePanel({
|
|
372
443
|
groupSizePixels,
|
|
373
444
|
panelConstraints,
|
|
374
445
|
panelIndex: index,
|
|
@@ -390,13 +461,18 @@ function adjustLayoutByDelta({
|
|
|
390
461
|
}
|
|
391
462
|
}
|
|
392
463
|
}
|
|
464
|
+
//DEBUG.push(`after 1: ${nextLayout.join(", ")}`);
|
|
465
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
466
|
+
//DEBUG.push("");
|
|
393
467
|
|
|
394
468
|
// If we were unable to resize any of the panels panels, return the previous state.
|
|
395
469
|
// This will essentially bailout and ignore e.g. drags past a panel's boundaries
|
|
396
470
|
if (fuzzyNumbersEqual(deltaApplied, 0)) {
|
|
471
|
+
//console.log(DEBUG.join("\n"));
|
|
397
472
|
return prevLayout;
|
|
398
473
|
}
|
|
399
474
|
{
|
|
475
|
+
// Now distribute the applied delta to the panels in the other direction
|
|
400
476
|
const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
401
477
|
const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
|
|
402
478
|
const safeSize = resizePanel({
|
|
@@ -436,29 +512,21 @@ function adjustLayoutByDelta({
|
|
|
436
512
|
index++;
|
|
437
513
|
}
|
|
438
514
|
}
|
|
439
|
-
|
|
440
|
-
// If we can't redistribute, this layout is invalid;
|
|
441
|
-
// There may be an incremental layout that is valid though
|
|
442
|
-
if (!fuzzyNumbersEqual(deltaRemaining, 0)) {
|
|
443
|
-
try {
|
|
444
|
-
return adjustLayoutByDelta({
|
|
445
|
-
delta: delta < 0 ? delta + 1 : delta - 1,
|
|
446
|
-
groupSizePixels,
|
|
447
|
-
layout: prevLayout,
|
|
448
|
-
panelConstraints,
|
|
449
|
-
pivotIndices,
|
|
450
|
-
trigger
|
|
451
|
-
});
|
|
452
|
-
} catch (error) {
|
|
453
|
-
if (error instanceof RangeError) {
|
|
454
|
-
console.error(`Could not apply delta ${delta} to layout`);
|
|
455
|
-
return prevLayout;
|
|
456
|
-
}
|
|
457
|
-
} finally {
|
|
458
|
-
}
|
|
459
|
-
}
|
|
460
515
|
}
|
|
461
516
|
}
|
|
517
|
+
//DEBUG.push(`after 2: ${nextLayout.join(", ")}`);
|
|
518
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
519
|
+
//DEBUG.push("");
|
|
520
|
+
|
|
521
|
+
const totalSize = nextLayout.reduce((total, size) => size + total, 0);
|
|
522
|
+
deltaApplied = 100 - totalSize;
|
|
523
|
+
//DEBUG.push(`total size: ${totalSize}`);
|
|
524
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
525
|
+
//console.log(DEBUG.join("\n"));
|
|
526
|
+
|
|
527
|
+
if (!fuzzyNumbersEqual(totalSize, 100)) {
|
|
528
|
+
return prevLayout;
|
|
529
|
+
}
|
|
462
530
|
return nextLayout;
|
|
463
531
|
}
|
|
464
532
|
|
|
@@ -1022,6 +1090,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1022
1090
|
autoSaveId,
|
|
1023
1091
|
children,
|
|
1024
1092
|
className: classNameFromProps = "",
|
|
1093
|
+
dataAttributes,
|
|
1025
1094
|
direction,
|
|
1026
1095
|
forwardedRef,
|
|
1027
1096
|
id: idFromProps,
|
|
@@ -1456,6 +1525,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1456
1525
|
...style,
|
|
1457
1526
|
...styleFromProps
|
|
1458
1527
|
},
|
|
1528
|
+
...dataAttributes,
|
|
1459
1529
|
// CSS selectors
|
|
1460
1530
|
"data-panel-group": "",
|
|
1461
1531
|
"data-panel-group-direction": direction,
|
|
@@ -1543,6 +1613,7 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1543
1613
|
function PanelResizeHandle({
|
|
1544
1614
|
children = null,
|
|
1545
1615
|
className: classNameFromProps = "",
|
|
1616
|
+
dataAttributes,
|
|
1546
1617
|
disabled = false,
|
|
1547
1618
|
id: idFromProps = null,
|
|
1548
1619
|
onDragging,
|
|
@@ -1665,6 +1736,7 @@ function PanelResizeHandle({
|
|
|
1665
1736
|
...styleFromProps
|
|
1666
1737
|
},
|
|
1667
1738
|
tabIndex: 0,
|
|
1739
|
+
...dataAttributes,
|
|
1668
1740
|
// CSS selectors
|
|
1669
1741
|
"data-panel-group-direction": direction,
|
|
1670
1742
|
"data-panel-group-id": groupId,
|
|
@@ -42,6 +42,7 @@ function PanelWithForwardedRef({
|
|
|
42
42
|
collapsedSizePercentage,
|
|
43
43
|
collapsedSizePixels,
|
|
44
44
|
collapsible,
|
|
45
|
+
dataAttributes,
|
|
45
46
|
defaultSizePercentage,
|
|
46
47
|
defaultSizePixels,
|
|
47
48
|
forwardedRef,
|
|
@@ -127,6 +128,7 @@ function PanelWithForwardedRef({
|
|
|
127
128
|
...style,
|
|
128
129
|
...styleFromProps
|
|
129
130
|
},
|
|
131
|
+
...dataAttributes,
|
|
130
132
|
// CSS selectors
|
|
131
133
|
"data-panel": "",
|
|
132
134
|
"data-panel-id": panelId,
|
|
@@ -264,7 +266,13 @@ function resizePanel({
|
|
|
264
266
|
if (minSizePercentage != null) {
|
|
265
267
|
if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
|
|
266
268
|
if (collapsible) {
|
|
267
|
-
|
|
269
|
+
// Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
|
|
270
|
+
const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
|
|
271
|
+
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
272
|
+
size = collapsedSizePercentage;
|
|
273
|
+
} else {
|
|
274
|
+
size = minSizePercentage;
|
|
275
|
+
}
|
|
268
276
|
} else {
|
|
269
277
|
size = minSizePercentage;
|
|
270
278
|
}
|
|
@@ -291,60 +299,123 @@ function adjustLayoutByDelta({
|
|
|
291
299
|
const nextLayout = [...prevLayout];
|
|
292
300
|
let deltaApplied = 0;
|
|
293
301
|
|
|
302
|
+
//const DEBUG = [];
|
|
303
|
+
//DEBUG.push(`adjustLayoutByDelta() ${prevLayout.join(", ")}`);
|
|
304
|
+
//DEBUG.push(` delta: ${delta}`);
|
|
305
|
+
//DEBUG.push(` pivotIndices: ${pivotIndices.join(", ")}`);
|
|
306
|
+
//DEBUG.push(` trigger: ${trigger}`);
|
|
307
|
+
//DEBUG.push("");
|
|
308
|
+
|
|
294
309
|
// A resizing panel affects the panels before or after it.
|
|
295
310
|
//
|
|
296
|
-
// A negative delta means the panel immediately after the
|
|
311
|
+
// A negative delta means the panel(s) immediately after the resize handle should grow/expand by decreasing its offset.
|
|
297
312
|
// Other panels may also need to shrink/contract (and shift) to make room, depending on the min weights.
|
|
298
313
|
//
|
|
299
|
-
// A positive delta means the panel immediately before the
|
|
300
|
-
// This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the
|
|
314
|
+
// A positive delta means the panel(s) immediately before the resize handle should "expand".
|
|
315
|
+
// This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the resize handle.
|
|
301
316
|
|
|
302
|
-
// First, check the panel we're pivoting around;
|
|
303
|
-
// We should only expand or contract by as much as its constraints allow
|
|
304
317
|
{
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
318
|
+
// If this is a resize triggered by a keyboard event, our logic for expanding/collapsing is different.
|
|
319
|
+
// We no longer check the halfway threshold because this may prevent the panel from expanding at all.
|
|
320
|
+
if (trigger === "keyboard") {
|
|
321
|
+
{
|
|
322
|
+
// Check if we should expand a collapsed panel
|
|
323
|
+
const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
324
|
+
const constraints = panelConstraints[index];
|
|
325
|
+
//DEBUG.push(`edge case check 1: ${index}`);
|
|
326
|
+
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
327
|
+
if (constraints.collapsible) {
|
|
328
|
+
const prevSize = prevLayout[index];
|
|
329
|
+
const {
|
|
330
|
+
collapsedSizePercentage,
|
|
331
|
+
minSizePercentage
|
|
332
|
+
} = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
|
|
333
|
+
if (fuzzyNumbersEqual(prevSize, collapsedSizePercentage)) {
|
|
334
|
+
const localDelta = minSizePercentage - prevSize;
|
|
335
|
+
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
336
|
+
|
|
337
|
+
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
338
|
+
delta = delta < 0 ? 0 - localDelta : localDelta;
|
|
339
|
+
//DEBUG.push(` -> delta: ${delta}`);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
{
|
|
346
|
+
// Check if we should collapse a panel at its minimum size
|
|
347
|
+
const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
|
|
348
|
+
const constraints = panelConstraints[index];
|
|
349
|
+
//DEBUG.push(`edge case check 2: ${index}`);
|
|
350
|
+
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
351
|
+
if (constraints.collapsible) {
|
|
352
|
+
const prevSize = prevLayout[index];
|
|
353
|
+
const {
|
|
354
|
+
collapsedSizePercentage,
|
|
355
|
+
minSizePercentage
|
|
356
|
+
} = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
|
|
357
|
+
if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
|
|
358
|
+
const localDelta = prevSize - collapsedSizePercentage;
|
|
359
|
+
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
360
|
+
|
|
361
|
+
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
362
|
+
delta = delta < 0 ? 0 - localDelta : localDelta;
|
|
363
|
+
//DEBUG.push(` -> delta: ${delta}`);
|
|
364
|
+
}
|
|
321
365
|
}
|
|
366
|
+
}
|
|
322
367
|
}
|
|
323
368
|
}
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
369
|
+
//DEBUG.push("");
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
{
|
|
373
|
+
// Pre-calculate max available delta in the opposite direction of our pivot.
|
|
374
|
+
// This will be the maximum amount we're allowed to expand/contract the panels in the primary direction.
|
|
375
|
+
// If this amount is less than the requested delta, adjust the requested delta.
|
|
376
|
+
// If this amount is greater than the requested delta, that's useful information too–
|
|
377
|
+
// as an expanding panel might change from collapsed to min size.
|
|
378
|
+
|
|
379
|
+
const increment = delta < 0 ? 1 : -1;
|
|
380
|
+
let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
381
|
+
let maxAvailableDelta = 0;
|
|
382
|
+
|
|
383
|
+
//DEBUG.push("pre calc...");
|
|
384
|
+
while (true) {
|
|
385
|
+
const prevSize = prevLayout[index];
|
|
386
|
+
const maxSafeSize = resizePanel({
|
|
387
|
+
groupSizePixels,
|
|
388
|
+
panelConstraints,
|
|
389
|
+
panelIndex: index,
|
|
390
|
+
size: 100
|
|
391
|
+
});
|
|
392
|
+
const delta = maxSafeSize - prevSize;
|
|
393
|
+
//DEBUG.push(` ${index}: ${prevSize} -> ${maxSafeSize}`);
|
|
394
|
+
|
|
395
|
+
maxAvailableDelta += delta;
|
|
396
|
+
index += increment;
|
|
397
|
+
if (index < 0 || index >= panelConstraints.length) {
|
|
398
|
+
break;
|
|
399
|
+
}
|
|
335
400
|
}
|
|
401
|
+
|
|
402
|
+
//DEBUG.push(` -> max available delta: ${maxAvailableDelta}`);
|
|
403
|
+
const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
|
|
404
|
+
delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
|
|
405
|
+
//DEBUG.push(` -> adjusted delta: ${delta}`);
|
|
406
|
+
//DEBUG.push("");
|
|
336
407
|
}
|
|
337
408
|
|
|
338
|
-
// Delta added to a panel needs to be subtracted from other panels
|
|
339
|
-
// within the constraints that those panels allow
|
|
340
409
|
{
|
|
410
|
+
// Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
|
|
411
|
+
|
|
341
412
|
const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
|
|
342
413
|
let index = pivotIndex;
|
|
343
414
|
while (index >= 0 && index < panelConstraints.length) {
|
|
344
415
|
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
345
416
|
const prevSize = prevLayout[index];
|
|
346
417
|
const unsafeSize = prevSize - deltaRemaining;
|
|
347
|
-
|
|
418
|
+
const safeSize = resizePanel({
|
|
348
419
|
groupSizePixels,
|
|
349
420
|
panelConstraints,
|
|
350
421
|
panelIndex: index,
|
|
@@ -366,13 +437,18 @@ function adjustLayoutByDelta({
|
|
|
366
437
|
}
|
|
367
438
|
}
|
|
368
439
|
}
|
|
440
|
+
//DEBUG.push(`after 1: ${nextLayout.join(", ")}`);
|
|
441
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
442
|
+
//DEBUG.push("");
|
|
369
443
|
|
|
370
444
|
// If we were unable to resize any of the panels panels, return the previous state.
|
|
371
445
|
// This will essentially bailout and ignore e.g. drags past a panel's boundaries
|
|
372
446
|
if (fuzzyNumbersEqual(deltaApplied, 0)) {
|
|
447
|
+
//console.log(DEBUG.join("\n"));
|
|
373
448
|
return prevLayout;
|
|
374
449
|
}
|
|
375
450
|
{
|
|
451
|
+
// Now distribute the applied delta to the panels in the other direction
|
|
376
452
|
const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
377
453
|
const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
|
|
378
454
|
const safeSize = resizePanel({
|
|
@@ -412,29 +488,21 @@ function adjustLayoutByDelta({
|
|
|
412
488
|
index++;
|
|
413
489
|
}
|
|
414
490
|
}
|
|
415
|
-
|
|
416
|
-
// If we can't redistribute, this layout is invalid;
|
|
417
|
-
// There may be an incremental layout that is valid though
|
|
418
|
-
if (!fuzzyNumbersEqual(deltaRemaining, 0)) {
|
|
419
|
-
try {
|
|
420
|
-
return adjustLayoutByDelta({
|
|
421
|
-
delta: delta < 0 ? delta + 1 : delta - 1,
|
|
422
|
-
groupSizePixels,
|
|
423
|
-
layout: prevLayout,
|
|
424
|
-
panelConstraints,
|
|
425
|
-
pivotIndices,
|
|
426
|
-
trigger
|
|
427
|
-
});
|
|
428
|
-
} catch (error) {
|
|
429
|
-
if (error instanceof RangeError) {
|
|
430
|
-
console.error(`Could not apply delta ${delta} to layout`);
|
|
431
|
-
return prevLayout;
|
|
432
|
-
}
|
|
433
|
-
} finally {
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
491
|
}
|
|
437
492
|
}
|
|
493
|
+
//DEBUG.push(`after 2: ${nextLayout.join(", ")}`);
|
|
494
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
495
|
+
//DEBUG.push("");
|
|
496
|
+
|
|
497
|
+
const totalSize = nextLayout.reduce((total, size) => size + total, 0);
|
|
498
|
+
deltaApplied = 100 - totalSize;
|
|
499
|
+
//DEBUG.push(`total size: ${totalSize}`);
|
|
500
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
501
|
+
//console.log(DEBUG.join("\n"));
|
|
502
|
+
|
|
503
|
+
if (!fuzzyNumbersEqual(totalSize, 100)) {
|
|
504
|
+
return prevLayout;
|
|
505
|
+
}
|
|
438
506
|
return nextLayout;
|
|
439
507
|
}
|
|
440
508
|
|
|
@@ -998,6 +1066,7 @@ function PanelGroupWithForwardedRef({
|
|
|
998
1066
|
autoSaveId,
|
|
999
1067
|
children,
|
|
1000
1068
|
className: classNameFromProps = "",
|
|
1069
|
+
dataAttributes,
|
|
1001
1070
|
direction,
|
|
1002
1071
|
forwardedRef,
|
|
1003
1072
|
id: idFromProps,
|
|
@@ -1432,6 +1501,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1432
1501
|
...style,
|
|
1433
1502
|
...styleFromProps
|
|
1434
1503
|
},
|
|
1504
|
+
...dataAttributes,
|
|
1435
1505
|
// CSS selectors
|
|
1436
1506
|
"data-panel-group": "",
|
|
1437
1507
|
"data-panel-group-direction": direction,
|
|
@@ -1519,6 +1589,7 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1519
1589
|
function PanelResizeHandle({
|
|
1520
1590
|
children = null,
|
|
1521
1591
|
className: classNameFromProps = "",
|
|
1592
|
+
dataAttributes,
|
|
1522
1593
|
disabled = false,
|
|
1523
1594
|
id: idFromProps = null,
|
|
1524
1595
|
onDragging,
|
|
@@ -1641,6 +1712,7 @@ function PanelResizeHandle({
|
|
|
1641
1712
|
...styleFromProps
|
|
1642
1713
|
},
|
|
1643
1714
|
tabIndex: 0,
|
|
1715
|
+
...dataAttributes,
|
|
1644
1716
|
// CSS selectors
|
|
1645
1717
|
"data-panel-group-direction": direction,
|
|
1646
1718
|
"data-panel-group-id": groupId,
|
package/package.json
CHANGED
package/src/Panel.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { isDevelopment } from "#is-development";
|
|
|
3
3
|
import { PanelGroupContext } from "./PanelGroupContext";
|
|
4
4
|
import useIsomorphicLayoutEffect from "./hooks/useIsomorphicEffect";
|
|
5
5
|
import useUniqueId from "./hooks/useUniqueId";
|
|
6
|
-
import { MixedSizes } from "./types";
|
|
6
|
+
import { DataAttributes, MixedSizes } from "./types";
|
|
7
7
|
import {
|
|
8
8
|
ElementType,
|
|
9
9
|
ForwardedRef,
|
|
@@ -19,7 +19,7 @@ export type PanelOnCollapse = () => void;
|
|
|
19
19
|
export type PanelOnExpand = () => void;
|
|
20
20
|
export type PanelOnResize = (
|
|
21
21
|
mixedSizes: MixedSizes,
|
|
22
|
-
prevMixedSizes: MixedSizes
|
|
22
|
+
prevMixedSizes: MixedSizes | undefined
|
|
23
23
|
) => void;
|
|
24
24
|
|
|
25
25
|
export type PanelCallbacks = {
|
|
@@ -53,6 +53,8 @@ export type ImperativePanelHandle = {
|
|
|
53
53
|
expand: () => void;
|
|
54
54
|
getId(): string;
|
|
55
55
|
getSize(): MixedSizes;
|
|
56
|
+
isCollapsed: () => boolean;
|
|
57
|
+
isExpanded: () => boolean;
|
|
56
58
|
resize: (size: Partial<MixedSizes>) => void;
|
|
57
59
|
};
|
|
58
60
|
|
|
@@ -61,6 +63,7 @@ export type PanelProps = PropsWithChildren<{
|
|
|
61
63
|
collapsedSizePercentage?: number | undefined;
|
|
62
64
|
collapsedSizePixels?: number | undefined;
|
|
63
65
|
collapsible?: boolean | undefined;
|
|
66
|
+
dataAttributes?: DataAttributes;
|
|
64
67
|
defaultSizePercentage?: number | undefined;
|
|
65
68
|
defaultSizePixels?: number | undefined;
|
|
66
69
|
id?: string;
|
|
@@ -82,6 +85,7 @@ export function PanelWithForwardedRef({
|
|
|
82
85
|
collapsedSizePercentage,
|
|
83
86
|
collapsedSizePixels,
|
|
84
87
|
collapsible,
|
|
88
|
+
dataAttributes,
|
|
85
89
|
defaultSizePercentage,
|
|
86
90
|
defaultSizePixels,
|
|
87
91
|
forwardedRef,
|
|
@@ -241,6 +245,8 @@ export function PanelWithForwardedRef({
|
|
|
241
245
|
...styleFromProps,
|
|
242
246
|
},
|
|
243
247
|
|
|
248
|
+
...dataAttributes,
|
|
249
|
+
|
|
244
250
|
// CSS selectors
|
|
245
251
|
"data-panel": "",
|
|
246
252
|
"data-panel-id": panelId,
|
package/src/PanelGroup.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { DragState, PanelGroupContext, ResizeEvent } from "./PanelGroupContext";
|
|
|
4
4
|
import useIsomorphicLayoutEffect from "./hooks/useIsomorphicEffect";
|
|
5
5
|
import useUniqueId from "./hooks/useUniqueId";
|
|
6
6
|
import { useWindowSplitterPanelGroupBehavior } from "./hooks/useWindowSplitterPanelGroupBehavior";
|
|
7
|
-
import { Direction, MixedSizes } from "./types";
|
|
7
|
+
import { DataAttributes, Direction, MixedSizes } from "./types";
|
|
8
8
|
import { adjustLayoutByDelta } from "./utils/adjustLayoutByDelta";
|
|
9
9
|
import { areEqual } from "./utils/arrays";
|
|
10
10
|
import { calculateDeltaPercentage } from "./utils/calculateDeltaPercentage";
|
|
@@ -72,6 +72,7 @@ const defaultStorage: PanelGroupStorage = {
|
|
|
72
72
|
export type PanelGroupProps = PropsWithChildren<{
|
|
73
73
|
autoSaveId?: string;
|
|
74
74
|
className?: string;
|
|
75
|
+
dataAttributes?: DataAttributes;
|
|
75
76
|
direction: Direction;
|
|
76
77
|
id?: string | null;
|
|
77
78
|
keyboardResizeByPercentage?: number | null;
|
|
@@ -90,6 +91,7 @@ function PanelGroupWithForwardedRef({
|
|
|
90
91
|
autoSaveId,
|
|
91
92
|
children,
|
|
92
93
|
className: classNameFromProps = "",
|
|
94
|
+
dataAttributes,
|
|
93
95
|
direction,
|
|
94
96
|
forwardedRef,
|
|
95
97
|
id: idFromProps,
|
|
@@ -927,6 +929,8 @@ function PanelGroupWithForwardedRef({
|
|
|
927
929
|
...styleFromProps,
|
|
928
930
|
},
|
|
929
931
|
|
|
932
|
+
...dataAttributes,
|
|
933
|
+
|
|
930
934
|
// CSS selectors
|
|
931
935
|
"data-panel-group": "",
|
|
932
936
|
"data-panel-group-direction": direction,
|