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
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.0.58
|
|
4
|
+
|
|
5
|
+
- Change group layout to more thoroughly distribute resize delta to support more flexible group size configurations.
|
|
6
|
+
- Add data attribute support to `Panel`, `PanelGroup`, and `PanelResizeHandle`.
|
|
7
|
+
- Update API documentation to reflect changed imperative API method names.
|
|
8
|
+
- `PanelOnResize` TypeScript def updated to reflect that previous size param is `undefined` the first time it is called.
|
|
9
|
+
|
|
3
10
|
## 0.0.57
|
|
4
11
|
|
|
5
12
|
- [#207](https://github.com/bvaughn/react-resizable-panels/pull/207): Fix DEV conditional error that broke data attributes (and selectors).
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { MixedSizes } from "./types.js";
|
|
1
|
+
import { DataAttributes, MixedSizes } from "./types.js";
|
|
2
2
|
import { ElementType, ForwardedRef, PropsWithChildren } from "./vendor/react.js";
|
|
3
3
|
export type PanelOnCollapse = () => void;
|
|
4
4
|
export type PanelOnExpand = () => void;
|
|
5
|
-
export type PanelOnResize = (mixedSizes: MixedSizes, prevMixedSizes: MixedSizes) => void;
|
|
5
|
+
export type PanelOnResize = (mixedSizes: MixedSizes, prevMixedSizes: MixedSizes | undefined) => void;
|
|
6
6
|
export type PanelCallbacks = {
|
|
7
7
|
onCollapse?: PanelOnCollapse;
|
|
8
8
|
onExpand?: PanelOnExpand;
|
|
@@ -31,6 +31,8 @@ export type ImperativePanelHandle = {
|
|
|
31
31
|
expand: () => void;
|
|
32
32
|
getId(): string;
|
|
33
33
|
getSize(): MixedSizes;
|
|
34
|
+
isCollapsed: () => boolean;
|
|
35
|
+
isExpanded: () => boolean;
|
|
34
36
|
resize: (size: Partial<MixedSizes>) => void;
|
|
35
37
|
};
|
|
36
38
|
export type PanelProps = PropsWithChildren<{
|
|
@@ -38,6 +40,7 @@ export type PanelProps = PropsWithChildren<{
|
|
|
38
40
|
collapsedSizePercentage?: number | undefined;
|
|
39
41
|
collapsedSizePixels?: number | undefined;
|
|
40
42
|
collapsible?: boolean | undefined;
|
|
43
|
+
dataAttributes?: DataAttributes;
|
|
41
44
|
defaultSizePercentage?: number | undefined;
|
|
42
45
|
defaultSizePixels?: number | undefined;
|
|
43
46
|
id?: string;
|
|
@@ -52,7 +55,7 @@ export type PanelProps = PropsWithChildren<{
|
|
|
52
55
|
style?: object;
|
|
53
56
|
tagName?: ElementType;
|
|
54
57
|
}>;
|
|
55
|
-
export declare function PanelWithForwardedRef({ children, className: classNameFromProps, collapsedSizePercentage, collapsedSizePixels, collapsible, defaultSizePercentage, defaultSizePixels, forwardedRef, id: idFromProps, maxSizePercentage, maxSizePixels, minSizePercentage, minSizePixels, onCollapse, onExpand, onResize, order, style: styleFromProps, tagName: Type, }: PanelProps & {
|
|
58
|
+
export declare function PanelWithForwardedRef({ children, className: classNameFromProps, collapsedSizePercentage, collapsedSizePixels, collapsible, dataAttributes, defaultSizePercentage, defaultSizePixels, forwardedRef, id: idFromProps, maxSizePercentage, maxSizePixels, minSizePercentage, minSizePixels, onCollapse, onExpand, onResize, order, style: styleFromProps, tagName: Type, }: PanelProps & {
|
|
56
59
|
forwardedRef: ForwardedRef<ImperativePanelHandle>;
|
|
57
60
|
}): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
58
61
|
export declare namespace PanelWithForwardedRef {
|
|
@@ -63,6 +66,7 @@ export declare const Panel: import("react").ForwardRefExoticComponent<{
|
|
|
63
66
|
collapsedSizePercentage?: number | undefined;
|
|
64
67
|
collapsedSizePixels?: number | undefined;
|
|
65
68
|
collapsible?: boolean | undefined;
|
|
69
|
+
dataAttributes?: DataAttributes | undefined;
|
|
66
70
|
defaultSizePercentage?: number | undefined;
|
|
67
71
|
defaultSizePixels?: number | undefined;
|
|
68
72
|
id?: string | undefined;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Direction, MixedSizes } from "./types.js";
|
|
1
|
+
import { DataAttributes, Direction, MixedSizes } from "./types.js";
|
|
2
2
|
import { CSSProperties, ElementType, PropsWithChildren } from "./vendor/react.js";
|
|
3
3
|
export type ImperativePanelGroupHandle = {
|
|
4
4
|
getId: () => string;
|
|
@@ -13,6 +13,7 @@ export type PanelGroupOnLayout = (layout: MixedSizes[]) => void;
|
|
|
13
13
|
export type PanelGroupProps = PropsWithChildren<{
|
|
14
14
|
autoSaveId?: string;
|
|
15
15
|
className?: string;
|
|
16
|
+
dataAttributes?: DataAttributes;
|
|
16
17
|
direction: Direction;
|
|
17
18
|
id?: string | null;
|
|
18
19
|
keyboardResizeByPercentage?: number | null;
|
|
@@ -25,6 +26,7 @@ export type PanelGroupProps = PropsWithChildren<{
|
|
|
25
26
|
export declare const PanelGroup: import("react").ForwardRefExoticComponent<{
|
|
26
27
|
autoSaveId?: string | undefined;
|
|
27
28
|
className?: string | undefined;
|
|
29
|
+
dataAttributes?: DataAttributes | undefined;
|
|
28
30
|
direction: Direction;
|
|
29
31
|
id?: string | null | undefined;
|
|
30
32
|
keyboardResizeByPercentage?: number | null | undefined;
|
|
@@ -1,15 +1,17 @@
|
|
|
1
1
|
import { CSSProperties, ElementType, ReactNode } from "./vendor/react.js";
|
|
2
|
+
import { DataAttributes } from "./types.js";
|
|
2
3
|
export type PanelResizeHandleOnDragging = (isDragging: boolean) => void;
|
|
3
4
|
export type PanelResizeHandleProps = {
|
|
4
5
|
children?: ReactNode;
|
|
5
6
|
className?: string;
|
|
7
|
+
dataAttributes?: DataAttributes;
|
|
6
8
|
disabled?: boolean;
|
|
7
9
|
id?: string | null;
|
|
8
10
|
onDragging?: PanelResizeHandleOnDragging;
|
|
9
11
|
style?: CSSProperties;
|
|
10
12
|
tagName?: ElementType;
|
|
11
13
|
};
|
|
12
|
-
export declare function PanelResizeHandle({ children, className: classNameFromProps, disabled, id: idFromProps, onDragging, style: styleFromProps, tagName: Type, }: PanelResizeHandleProps): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
14
|
+
export declare function PanelResizeHandle({ children, className: classNameFromProps, dataAttributes, disabled, id: idFromProps, onDragging, style: styleFromProps, tagName: Type, }: PanelResizeHandleProps): import("react").ReactElement<any, string | import("react").JSXElementConstructor<any>>;
|
|
13
15
|
export declare namespace PanelResizeHandle {
|
|
14
16
|
var displayName: string;
|
|
15
17
|
}
|
|
@@ -68,6 +68,7 @@ function PanelWithForwardedRef({
|
|
|
68
68
|
collapsedSizePercentage,
|
|
69
69
|
collapsedSizePixels,
|
|
70
70
|
collapsible,
|
|
71
|
+
dataAttributes,
|
|
71
72
|
defaultSizePercentage,
|
|
72
73
|
defaultSizePixels,
|
|
73
74
|
forwardedRef,
|
|
@@ -181,6 +182,7 @@ function PanelWithForwardedRef({
|
|
|
181
182
|
...style,
|
|
182
183
|
...styleFromProps
|
|
183
184
|
},
|
|
185
|
+
...dataAttributes,
|
|
184
186
|
// CSS selectors
|
|
185
187
|
"data-panel": "",
|
|
186
188
|
"data-panel-id": panelId,
|
|
@@ -318,7 +320,13 @@ function resizePanel({
|
|
|
318
320
|
if (minSizePercentage != null) {
|
|
319
321
|
if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
|
|
320
322
|
if (collapsible) {
|
|
321
|
-
|
|
323
|
+
// Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
|
|
324
|
+
const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
|
|
325
|
+
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
326
|
+
size = collapsedSizePercentage;
|
|
327
|
+
} else {
|
|
328
|
+
size = minSizePercentage;
|
|
329
|
+
}
|
|
322
330
|
} else {
|
|
323
331
|
size = minSizePercentage;
|
|
324
332
|
}
|
|
@@ -345,60 +353,123 @@ function adjustLayoutByDelta({
|
|
|
345
353
|
const nextLayout = [...prevLayout];
|
|
346
354
|
let deltaApplied = 0;
|
|
347
355
|
|
|
356
|
+
//const DEBUG = [];
|
|
357
|
+
//DEBUG.push(`adjustLayoutByDelta() ${prevLayout.join(", ")}`);
|
|
358
|
+
//DEBUG.push(` delta: ${delta}`);
|
|
359
|
+
//DEBUG.push(` pivotIndices: ${pivotIndices.join(", ")}`);
|
|
360
|
+
//DEBUG.push(` trigger: ${trigger}`);
|
|
361
|
+
//DEBUG.push("");
|
|
362
|
+
|
|
348
363
|
// A resizing panel affects the panels before or after it.
|
|
349
364
|
//
|
|
350
|
-
// A negative delta means the panel immediately after the
|
|
365
|
+
// A negative delta means the panel(s) immediately after the resize handle should grow/expand by decreasing its offset.
|
|
351
366
|
// Other panels may also need to shrink/contract (and shift) to make room, depending on the min weights.
|
|
352
367
|
//
|
|
353
|
-
// A positive delta means the panel immediately before the
|
|
354
|
-
// This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the
|
|
368
|
+
// A positive delta means the panel(s) immediately before the resize handle should "expand".
|
|
369
|
+
// This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the resize handle.
|
|
355
370
|
|
|
356
|
-
// First, check the panel we're pivoting around;
|
|
357
|
-
// We should only expand or contract by as much as its constraints allow
|
|
358
371
|
{
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
372
|
+
// If this is a resize triggered by a keyboard event, our logic for expanding/collapsing is different.
|
|
373
|
+
// We no longer check the halfway threshold because this may prevent the panel from expanding at all.
|
|
374
|
+
if (trigger === "keyboard") {
|
|
375
|
+
{
|
|
376
|
+
// Check if we should expand a collapsed panel
|
|
377
|
+
const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
378
|
+
const constraints = panelConstraints[index];
|
|
379
|
+
//DEBUG.push(`edge case check 1: ${index}`);
|
|
380
|
+
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
381
|
+
if (constraints.collapsible) {
|
|
382
|
+
const prevSize = prevLayout[index];
|
|
383
|
+
const {
|
|
384
|
+
collapsedSizePercentage,
|
|
385
|
+
minSizePercentage
|
|
386
|
+
} = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
|
|
387
|
+
if (fuzzyNumbersEqual(prevSize, collapsedSizePercentage)) {
|
|
388
|
+
const localDelta = minSizePercentage - prevSize;
|
|
389
|
+
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
390
|
+
|
|
391
|
+
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
392
|
+
delta = delta < 0 ? 0 - localDelta : localDelta;
|
|
393
|
+
//DEBUG.push(` -> delta: ${delta}`);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
{
|
|
400
|
+
// Check if we should collapse a panel at its minimum size
|
|
401
|
+
const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
|
|
402
|
+
const constraints = panelConstraints[index];
|
|
403
|
+
//DEBUG.push(`edge case check 2: ${index}`);
|
|
404
|
+
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
405
|
+
if (constraints.collapsible) {
|
|
406
|
+
const prevSize = prevLayout[index];
|
|
407
|
+
const {
|
|
408
|
+
collapsedSizePercentage,
|
|
409
|
+
minSizePercentage
|
|
410
|
+
} = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
|
|
411
|
+
if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
|
|
412
|
+
const localDelta = prevSize - collapsedSizePercentage;
|
|
413
|
+
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
414
|
+
|
|
415
|
+
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
416
|
+
delta = delta < 0 ? 0 - localDelta : localDelta;
|
|
417
|
+
//DEBUG.push(` -> delta: ${delta}`);
|
|
418
|
+
}
|
|
375
419
|
}
|
|
420
|
+
}
|
|
376
421
|
}
|
|
377
422
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
423
|
+
//DEBUG.push("");
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
{
|
|
427
|
+
// Pre-calculate max available delta in the opposite direction of our pivot.
|
|
428
|
+
// This will be the maximum amount we're allowed to expand/contract the panels in the primary direction.
|
|
429
|
+
// If this amount is less than the requested delta, adjust the requested delta.
|
|
430
|
+
// If this amount is greater than the requested delta, that's useful information too–
|
|
431
|
+
// as an expanding panel might change from collapsed to min size.
|
|
432
|
+
|
|
433
|
+
const increment = delta < 0 ? 1 : -1;
|
|
434
|
+
let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
435
|
+
let maxAvailableDelta = 0;
|
|
436
|
+
|
|
437
|
+
//DEBUG.push("pre calc...");
|
|
438
|
+
while (true) {
|
|
439
|
+
const prevSize = prevLayout[index];
|
|
440
|
+
const maxSafeSize = resizePanel({
|
|
441
|
+
groupSizePixels,
|
|
442
|
+
panelConstraints,
|
|
443
|
+
panelIndex: index,
|
|
444
|
+
size: 100
|
|
445
|
+
});
|
|
446
|
+
const delta = maxSafeSize - prevSize;
|
|
447
|
+
//DEBUG.push(` ${index}: ${prevSize} -> ${maxSafeSize}`);
|
|
448
|
+
|
|
449
|
+
maxAvailableDelta += delta;
|
|
450
|
+
index += increment;
|
|
451
|
+
if (index < 0 || index >= panelConstraints.length) {
|
|
452
|
+
break;
|
|
453
|
+
}
|
|
389
454
|
}
|
|
455
|
+
|
|
456
|
+
//DEBUG.push(` -> max available delta: ${maxAvailableDelta}`);
|
|
457
|
+
const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
|
|
458
|
+
delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
|
|
459
|
+
//DEBUG.push(` -> adjusted delta: ${delta}`);
|
|
460
|
+
//DEBUG.push("");
|
|
390
461
|
}
|
|
391
462
|
|
|
392
|
-
// Delta added to a panel needs to be subtracted from other panels
|
|
393
|
-
// within the constraints that those panels allow
|
|
394
463
|
{
|
|
464
|
+
// Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
|
|
465
|
+
|
|
395
466
|
const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
|
|
396
467
|
let index = pivotIndex;
|
|
397
468
|
while (index >= 0 && index < panelConstraints.length) {
|
|
398
469
|
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
399
470
|
const prevSize = prevLayout[index];
|
|
400
471
|
const unsafeSize = prevSize - deltaRemaining;
|
|
401
|
-
|
|
472
|
+
const safeSize = resizePanel({
|
|
402
473
|
groupSizePixels,
|
|
403
474
|
panelConstraints,
|
|
404
475
|
panelIndex: index,
|
|
@@ -420,13 +491,18 @@ function adjustLayoutByDelta({
|
|
|
420
491
|
}
|
|
421
492
|
}
|
|
422
493
|
}
|
|
494
|
+
//DEBUG.push(`after 1: ${nextLayout.join(", ")}`);
|
|
495
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
496
|
+
//DEBUG.push("");
|
|
423
497
|
|
|
424
498
|
// If we were unable to resize any of the panels panels, return the previous state.
|
|
425
499
|
// This will essentially bailout and ignore e.g. drags past a panel's boundaries
|
|
426
500
|
if (fuzzyNumbersEqual(deltaApplied, 0)) {
|
|
501
|
+
//console.log(DEBUG.join("\n"));
|
|
427
502
|
return prevLayout;
|
|
428
503
|
}
|
|
429
504
|
{
|
|
505
|
+
// Now distribute the applied delta to the panels in the other direction
|
|
430
506
|
const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
431
507
|
const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
|
|
432
508
|
const safeSize = resizePanel({
|
|
@@ -466,29 +542,21 @@ function adjustLayoutByDelta({
|
|
|
466
542
|
index++;
|
|
467
543
|
}
|
|
468
544
|
}
|
|
469
|
-
|
|
470
|
-
// If we can't redistribute, this layout is invalid;
|
|
471
|
-
// There may be an incremental layout that is valid though
|
|
472
|
-
if (!fuzzyNumbersEqual(deltaRemaining, 0)) {
|
|
473
|
-
try {
|
|
474
|
-
return adjustLayoutByDelta({
|
|
475
|
-
delta: delta < 0 ? delta + 1 : delta - 1,
|
|
476
|
-
groupSizePixels,
|
|
477
|
-
layout: prevLayout,
|
|
478
|
-
panelConstraints,
|
|
479
|
-
pivotIndices,
|
|
480
|
-
trigger
|
|
481
|
-
});
|
|
482
|
-
} catch (error) {
|
|
483
|
-
if (error instanceof RangeError) {
|
|
484
|
-
console.error(`Could not apply delta ${delta} to layout`);
|
|
485
|
-
return prevLayout;
|
|
486
|
-
}
|
|
487
|
-
} finally {
|
|
488
|
-
}
|
|
489
|
-
}
|
|
490
545
|
}
|
|
491
546
|
}
|
|
547
|
+
//DEBUG.push(`after 2: ${nextLayout.join(", ")}`);
|
|
548
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
549
|
+
//DEBUG.push("");
|
|
550
|
+
|
|
551
|
+
const totalSize = nextLayout.reduce((total, size) => size + total, 0);
|
|
552
|
+
deltaApplied = 100 - totalSize;
|
|
553
|
+
//DEBUG.push(`total size: ${totalSize}`);
|
|
554
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
555
|
+
//console.log(DEBUG.join("\n"));
|
|
556
|
+
|
|
557
|
+
if (!fuzzyNumbersEqual(totalSize, 100)) {
|
|
558
|
+
return prevLayout;
|
|
559
|
+
}
|
|
492
560
|
return nextLayout;
|
|
493
561
|
}
|
|
494
562
|
|
|
@@ -1185,6 +1253,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1185
1253
|
autoSaveId,
|
|
1186
1254
|
children,
|
|
1187
1255
|
className: classNameFromProps = "",
|
|
1256
|
+
dataAttributes,
|
|
1188
1257
|
direction,
|
|
1189
1258
|
forwardedRef,
|
|
1190
1259
|
id: idFromProps,
|
|
@@ -1717,6 +1786,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1717
1786
|
...style,
|
|
1718
1787
|
...styleFromProps
|
|
1719
1788
|
},
|
|
1789
|
+
...dataAttributes,
|
|
1720
1790
|
// CSS selectors
|
|
1721
1791
|
"data-panel-group": "",
|
|
1722
1792
|
"data-panel-group-direction": direction,
|
|
@@ -1804,6 +1874,7 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1804
1874
|
function PanelResizeHandle({
|
|
1805
1875
|
children = null,
|
|
1806
1876
|
className: classNameFromProps = "",
|
|
1877
|
+
dataAttributes,
|
|
1807
1878
|
disabled = false,
|
|
1808
1879
|
id: idFromProps = null,
|
|
1809
1880
|
onDragging,
|
|
@@ -1926,6 +1997,7 @@ function PanelResizeHandle({
|
|
|
1926
1997
|
...styleFromProps
|
|
1927
1998
|
},
|
|
1928
1999
|
tabIndex: 0,
|
|
2000
|
+
...dataAttributes,
|
|
1929
2001
|
// CSS selectors
|
|
1930
2002
|
"data-panel-group-direction": direction,
|
|
1931
2003
|
"data-panel-group-id": groupId,
|
|
@@ -68,6 +68,7 @@ function PanelWithForwardedRef({
|
|
|
68
68
|
collapsedSizePercentage,
|
|
69
69
|
collapsedSizePixels,
|
|
70
70
|
collapsible,
|
|
71
|
+
dataAttributes,
|
|
71
72
|
defaultSizePercentage,
|
|
72
73
|
defaultSizePixels,
|
|
73
74
|
forwardedRef,
|
|
@@ -187,6 +188,7 @@ function PanelWithForwardedRef({
|
|
|
187
188
|
...style,
|
|
188
189
|
...styleFromProps
|
|
189
190
|
},
|
|
191
|
+
...dataAttributes,
|
|
190
192
|
// CSS selectors
|
|
191
193
|
"data-panel": "",
|
|
192
194
|
"data-panel-id": panelId,
|
|
@@ -324,7 +326,13 @@ function resizePanel({
|
|
|
324
326
|
if (minSizePercentage != null) {
|
|
325
327
|
if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
|
|
326
328
|
if (collapsible) {
|
|
327
|
-
|
|
329
|
+
// Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
|
|
330
|
+
const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
|
|
331
|
+
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
332
|
+
size = collapsedSizePercentage;
|
|
333
|
+
} else {
|
|
334
|
+
size = minSizePercentage;
|
|
335
|
+
}
|
|
328
336
|
} else {
|
|
329
337
|
size = minSizePercentage;
|
|
330
338
|
}
|
|
@@ -351,60 +359,123 @@ function adjustLayoutByDelta({
|
|
|
351
359
|
const nextLayout = [...prevLayout];
|
|
352
360
|
let deltaApplied = 0;
|
|
353
361
|
|
|
362
|
+
//const DEBUG = [];
|
|
363
|
+
//DEBUG.push(`adjustLayoutByDelta() ${prevLayout.join(", ")}`);
|
|
364
|
+
//DEBUG.push(` delta: ${delta}`);
|
|
365
|
+
//DEBUG.push(` pivotIndices: ${pivotIndices.join(", ")}`);
|
|
366
|
+
//DEBUG.push(` trigger: ${trigger}`);
|
|
367
|
+
//DEBUG.push("");
|
|
368
|
+
|
|
354
369
|
// A resizing panel affects the panels before or after it.
|
|
355
370
|
//
|
|
356
|
-
// A negative delta means the panel immediately after the
|
|
371
|
+
// A negative delta means the panel(s) immediately after the resize handle should grow/expand by decreasing its offset.
|
|
357
372
|
// Other panels may also need to shrink/contract (and shift) to make room, depending on the min weights.
|
|
358
373
|
//
|
|
359
|
-
// A positive delta means the panel immediately before the
|
|
360
|
-
// This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the
|
|
374
|
+
// A positive delta means the panel(s) immediately before the resize handle should "expand".
|
|
375
|
+
// This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the resize handle.
|
|
361
376
|
|
|
362
|
-
// First, check the panel we're pivoting around;
|
|
363
|
-
// We should only expand or contract by as much as its constraints allow
|
|
364
377
|
{
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
378
|
+
// If this is a resize triggered by a keyboard event, our logic for expanding/collapsing is different.
|
|
379
|
+
// We no longer check the halfway threshold because this may prevent the panel from expanding at all.
|
|
380
|
+
if (trigger === "keyboard") {
|
|
381
|
+
{
|
|
382
|
+
// Check if we should expand a collapsed panel
|
|
383
|
+
const index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
384
|
+
const constraints = panelConstraints[index];
|
|
385
|
+
//DEBUG.push(`edge case check 1: ${index}`);
|
|
386
|
+
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
387
|
+
if (constraints.collapsible) {
|
|
388
|
+
const prevSize = prevLayout[index];
|
|
389
|
+
const {
|
|
390
|
+
collapsedSizePercentage,
|
|
391
|
+
minSizePercentage
|
|
392
|
+
} = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
|
|
393
|
+
if (fuzzyNumbersEqual(prevSize, collapsedSizePercentage)) {
|
|
394
|
+
const localDelta = minSizePercentage - prevSize;
|
|
395
|
+
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
396
|
+
|
|
397
|
+
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
398
|
+
delta = delta < 0 ? 0 - localDelta : localDelta;
|
|
399
|
+
//DEBUG.push(` -> delta: ${delta}`);
|
|
400
|
+
}
|
|
381
401
|
}
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
{
|
|
406
|
+
// Check if we should collapse a panel at its minimum size
|
|
407
|
+
const index = delta < 0 ? pivotIndices[0] : pivotIndices[1];
|
|
408
|
+
const constraints = panelConstraints[index];
|
|
409
|
+
//DEBUG.push(`edge case check 2: ${index}`);
|
|
410
|
+
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
411
|
+
if (constraints.collapsible) {
|
|
412
|
+
const prevSize = prevLayout[index];
|
|
413
|
+
const {
|
|
414
|
+
collapsedSizePercentage,
|
|
415
|
+
minSizePercentage
|
|
416
|
+
} = computePercentagePanelConstraints(panelConstraints, index, groupSizePixels);
|
|
417
|
+
if (fuzzyNumbersEqual(prevSize, minSizePercentage)) {
|
|
418
|
+
const localDelta = prevSize - collapsedSizePercentage;
|
|
419
|
+
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
420
|
+
|
|
421
|
+
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
422
|
+
delta = delta < 0 ? 0 - localDelta : localDelta;
|
|
423
|
+
//DEBUG.push(` -> delta: ${delta}`);
|
|
424
|
+
}
|
|
425
|
+
}
|
|
426
|
+
}
|
|
382
427
|
}
|
|
383
428
|
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
429
|
+
//DEBUG.push("");
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
{
|
|
433
|
+
// Pre-calculate max available delta in the opposite direction of our pivot.
|
|
434
|
+
// This will be the maximum amount we're allowed to expand/contract the panels in the primary direction.
|
|
435
|
+
// If this amount is less than the requested delta, adjust the requested delta.
|
|
436
|
+
// If this amount is greater than the requested delta, that's useful information too–
|
|
437
|
+
// as an expanding panel might change from collapsed to min size.
|
|
438
|
+
|
|
439
|
+
const increment = delta < 0 ? 1 : -1;
|
|
440
|
+
let index = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
441
|
+
let maxAvailableDelta = 0;
|
|
442
|
+
|
|
443
|
+
//DEBUG.push("pre calc...");
|
|
444
|
+
while (true) {
|
|
445
|
+
const prevSize = prevLayout[index];
|
|
446
|
+
const maxSafeSize = resizePanel({
|
|
447
|
+
groupSizePixels,
|
|
448
|
+
panelConstraints,
|
|
449
|
+
panelIndex: index,
|
|
450
|
+
size: 100
|
|
451
|
+
});
|
|
452
|
+
const delta = maxSafeSize - prevSize;
|
|
453
|
+
//DEBUG.push(` ${index}: ${prevSize} -> ${maxSafeSize}`);
|
|
454
|
+
|
|
455
|
+
maxAvailableDelta += delta;
|
|
456
|
+
index += increment;
|
|
457
|
+
if (index < 0 || index >= panelConstraints.length) {
|
|
458
|
+
break;
|
|
459
|
+
}
|
|
395
460
|
}
|
|
461
|
+
|
|
462
|
+
//DEBUG.push(` -> max available delta: ${maxAvailableDelta}`);
|
|
463
|
+
const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
|
|
464
|
+
delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
|
|
465
|
+
//DEBUG.push(` -> adjusted delta: ${delta}`);
|
|
466
|
+
//DEBUG.push("");
|
|
396
467
|
}
|
|
397
468
|
|
|
398
|
-
// Delta added to a panel needs to be subtracted from other panels
|
|
399
|
-
// within the constraints that those panels allow
|
|
400
469
|
{
|
|
470
|
+
// Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
|
|
471
|
+
|
|
401
472
|
const pivotIndex = delta < 0 ? pivotIndices[0] : pivotIndices[1];
|
|
402
473
|
let index = pivotIndex;
|
|
403
474
|
while (index >= 0 && index < panelConstraints.length) {
|
|
404
475
|
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
405
476
|
const prevSize = prevLayout[index];
|
|
406
477
|
const unsafeSize = prevSize - deltaRemaining;
|
|
407
|
-
|
|
478
|
+
const safeSize = resizePanel({
|
|
408
479
|
groupSizePixels,
|
|
409
480
|
panelConstraints,
|
|
410
481
|
panelIndex: index,
|
|
@@ -426,13 +497,18 @@ function adjustLayoutByDelta({
|
|
|
426
497
|
}
|
|
427
498
|
}
|
|
428
499
|
}
|
|
500
|
+
//DEBUG.push(`after 1: ${nextLayout.join(", ")}`);
|
|
501
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
502
|
+
//DEBUG.push("");
|
|
429
503
|
|
|
430
504
|
// If we were unable to resize any of the panels panels, return the previous state.
|
|
431
505
|
// This will essentially bailout and ignore e.g. drags past a panel's boundaries
|
|
432
506
|
if (fuzzyNumbersEqual(deltaApplied, 0)) {
|
|
507
|
+
//console.log(DEBUG.join("\n"));
|
|
433
508
|
return prevLayout;
|
|
434
509
|
}
|
|
435
510
|
{
|
|
511
|
+
// Now distribute the applied delta to the panels in the other direction
|
|
436
512
|
const pivotIndex = delta < 0 ? pivotIndices[1] : pivotIndices[0];
|
|
437
513
|
const unsafeSize = prevLayout[pivotIndex] + deltaApplied;
|
|
438
514
|
const safeSize = resizePanel({
|
|
@@ -472,29 +548,21 @@ function adjustLayoutByDelta({
|
|
|
472
548
|
index++;
|
|
473
549
|
}
|
|
474
550
|
}
|
|
475
|
-
|
|
476
|
-
// If we can't redistribute, this layout is invalid;
|
|
477
|
-
// There may be an incremental layout that is valid though
|
|
478
|
-
if (!fuzzyNumbersEqual(deltaRemaining, 0)) {
|
|
479
|
-
try {
|
|
480
|
-
return adjustLayoutByDelta({
|
|
481
|
-
delta: delta < 0 ? delta + 1 : delta - 1,
|
|
482
|
-
groupSizePixels,
|
|
483
|
-
layout: prevLayout,
|
|
484
|
-
panelConstraints,
|
|
485
|
-
pivotIndices,
|
|
486
|
-
trigger
|
|
487
|
-
});
|
|
488
|
-
} catch (error) {
|
|
489
|
-
if (error instanceof RangeError) {
|
|
490
|
-
console.error(`Could not apply delta ${delta} to layout`);
|
|
491
|
-
return prevLayout;
|
|
492
|
-
}
|
|
493
|
-
} finally {
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
551
|
}
|
|
497
552
|
}
|
|
553
|
+
//DEBUG.push(`after 2: ${nextLayout.join(", ")}`);
|
|
554
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
555
|
+
//DEBUG.push("");
|
|
556
|
+
|
|
557
|
+
const totalSize = nextLayout.reduce((total, size) => size + total, 0);
|
|
558
|
+
deltaApplied = 100 - totalSize;
|
|
559
|
+
//DEBUG.push(`total size: ${totalSize}`);
|
|
560
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
561
|
+
//console.log(DEBUG.join("\n"));
|
|
562
|
+
|
|
563
|
+
if (!fuzzyNumbersEqual(totalSize, 100)) {
|
|
564
|
+
return prevLayout;
|
|
565
|
+
}
|
|
498
566
|
return nextLayout;
|
|
499
567
|
}
|
|
500
568
|
|
|
@@ -1278,6 +1346,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1278
1346
|
autoSaveId,
|
|
1279
1347
|
children,
|
|
1280
1348
|
className: classNameFromProps = "",
|
|
1349
|
+
dataAttributes,
|
|
1281
1350
|
direction,
|
|
1282
1351
|
forwardedRef,
|
|
1283
1352
|
id: idFromProps,
|
|
@@ -1852,6 +1921,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1852
1921
|
...style,
|
|
1853
1922
|
...styleFromProps
|
|
1854
1923
|
},
|
|
1924
|
+
...dataAttributes,
|
|
1855
1925
|
// CSS selectors
|
|
1856
1926
|
"data-panel-group": "",
|
|
1857
1927
|
"data-panel-group-direction": direction,
|
|
@@ -1939,6 +2009,7 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1939
2009
|
function PanelResizeHandle({
|
|
1940
2010
|
children = null,
|
|
1941
2011
|
className: classNameFromProps = "",
|
|
2012
|
+
dataAttributes,
|
|
1942
2013
|
disabled = false,
|
|
1943
2014
|
id: idFromProps = null,
|
|
1944
2015
|
onDragging,
|
|
@@ -2061,6 +2132,7 @@ function PanelResizeHandle({
|
|
|
2061
2132
|
...styleFromProps
|
|
2062
2133
|
},
|
|
2063
2134
|
tabIndex: 0,
|
|
2135
|
+
...dataAttributes,
|
|
2064
2136
|
// CSS selectors
|
|
2065
2137
|
"data-panel-group-direction": direction,
|
|
2066
2138
|
"data-panel-group-id": groupId,
|