react-resizable-panels 0.0.57 → 0.0.59
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 +13 -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 +206 -77
- package/dist/react-resizable-panels.browser.development.cjs.js +206 -77
- package/dist/react-resizable-panels.browser.development.esm.js +206 -77
- package/dist/react-resizable-panels.browser.esm.js +206 -77
- package/dist/react-resizable-panels.cjs.js +206 -77
- package/dist/react-resizable-panels.cjs.js.map +1 -1
- package/dist/react-resizable-panels.development.cjs.js +206 -77
- package/dist/react-resizable-panels.development.esm.js +206 -77
- package/dist/react-resizable-panels.development.node.cjs.js +175 -75
- package/dist/react-resizable-panels.development.node.esm.js +175 -75
- package/dist/react-resizable-panels.esm.js +206 -77
- package/dist/react-resizable-panels.esm.js.map +1 -1
- package/dist/react-resizable-panels.node.cjs.js +175 -75
- package/dist/react-resizable-panels.node.esm.js +175 -75
- package/package.json +1 -1
- package/src/Panel.ts +8 -2
- package/src/PanelGroup.ts +89 -3
- package/src/PanelResizeHandle.ts +5 -0
- package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +15 -15
- 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,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.0.59
|
|
4
|
+
|
|
5
|
+
- Support imperative panel API usage on-mount.
|
|
6
|
+
- Made PanelGroup bailout condition smarter (don't bailout for empty groups unless pixel constraints are used).
|
|
7
|
+
- Improved window splitter compatibility by better handling "Enter" key.
|
|
8
|
+
|
|
9
|
+
## 0.0.58
|
|
10
|
+
|
|
11
|
+
- Change group layout to more thoroughly distribute resize delta to support more flexible group size configurations.
|
|
12
|
+
- Add data attribute support to `Panel`, `PanelGroup`, and `PanelResizeHandle`.
|
|
13
|
+
- Update API documentation to reflect changed imperative API method names.
|
|
14
|
+
- `PanelOnResize` TypeScript def updated to reflect that previous size param is `undefined` the first time it is called.
|
|
15
|
+
|
|
3
16
|
## 0.0.57
|
|
4
17
|
|
|
5
18
|
- [#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,
|
|
@@ -196,8 +198,6 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
|
|
|
196
198
|
PanelWithForwardedRef.displayName = "Panel";
|
|
197
199
|
Panel.displayName = "forwardRef(Panel)";
|
|
198
200
|
|
|
199
|
-
const PRECISION = 10;
|
|
200
|
-
|
|
201
201
|
function convertPixelsToPercentage(pixels, groupSizePixels) {
|
|
202
202
|
return pixels / groupSizePixels * 100;
|
|
203
203
|
}
|
|
@@ -275,6 +275,8 @@ function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, gr
|
|
|
275
275
|
};
|
|
276
276
|
}
|
|
277
277
|
|
|
278
|
+
const PRECISION = 10;
|
|
279
|
+
|
|
278
280
|
function fuzzyCompareNumbers(actual, expected, fractionDigits = PRECISION) {
|
|
279
281
|
actual = parseFloat(actual.toFixed(fractionDigits));
|
|
280
282
|
expected = parseFloat(expected.toFixed(fractionDigits));
|
|
@@ -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
|
|
|
@@ -682,15 +750,10 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
682
750
|
}, [groupId, layout, panelDataArray]);
|
|
683
751
|
useEffect(() => {
|
|
684
752
|
const {
|
|
685
|
-
direction,
|
|
686
753
|
panelDataArray
|
|
687
754
|
} = committedValuesRef.current;
|
|
688
755
|
const groupElement = getPanelGroupElement(groupId);
|
|
689
756
|
assert(groupElement != null, `No group found for id "${groupId}"`);
|
|
690
|
-
const {
|
|
691
|
-
height,
|
|
692
|
-
width
|
|
693
|
-
} = groupElement.getBoundingClientRect();
|
|
694
757
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
695
758
|
const cleanupFunctions = handles.map(handle => {
|
|
696
759
|
const handleId = handle.getAttribute("data-panel-resize-handle-id");
|
|
@@ -710,21 +773,19 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
710
773
|
if (index >= 0) {
|
|
711
774
|
const panelData = panelDataArray[index];
|
|
712
775
|
const size = layout[index];
|
|
713
|
-
if (size != null) {
|
|
714
|
-
var _getPercentageSizeFro;
|
|
776
|
+
if (size != null && panelData.constraints.collapsible) {
|
|
777
|
+
var _getPercentageSizeFro, _getPercentageSizeFro2;
|
|
715
778
|
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
716
|
-
const
|
|
779
|
+
const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
|
|
780
|
+
sizePercentage: panelData.constraints.collapsedSizePercentage,
|
|
781
|
+
sizePixels: panelData.constraints.collapsedSizePixels
|
|
782
|
+
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
783
|
+
const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
|
|
717
784
|
sizePercentage: panelData.constraints.minSizePercentage,
|
|
718
785
|
sizePixels: panelData.constraints.minSizePixels
|
|
719
|
-
}, groupSizePixels)) !== null &&
|
|
720
|
-
let delta = 0;
|
|
721
|
-
if (size.toPrecision(PRECISION) <= minSize.toPrecision(PRECISION)) {
|
|
722
|
-
delta = direction === "horizontal" ? width : height;
|
|
723
|
-
} else {
|
|
724
|
-
delta = -(direction === "horizontal" ? width : height);
|
|
725
|
-
}
|
|
786
|
+
}, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
|
|
726
787
|
const nextLayout = adjustLayoutByDelta({
|
|
727
|
-
delta,
|
|
788
|
+
delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
|
|
728
789
|
groupSizePixels,
|
|
729
790
|
layout,
|
|
730
791
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints),
|
|
@@ -1185,6 +1246,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1185
1246
|
autoSaveId,
|
|
1186
1247
|
children,
|
|
1187
1248
|
className: classNameFromProps = "",
|
|
1249
|
+
dataAttributes,
|
|
1188
1250
|
direction,
|
|
1189
1251
|
forwardedRef,
|
|
1190
1252
|
id: idFromProps,
|
|
@@ -1202,6 +1264,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1202
1264
|
const panelIdToLastNotifiedMixedSizesMapRef = useRef({});
|
|
1203
1265
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1204
1266
|
const prevDeltaRef = useRef(0);
|
|
1267
|
+
const [imperativeApiQueue, setImperativeApiQueue] = useState([]);
|
|
1205
1268
|
const committedValuesRef = useRef({
|
|
1206
1269
|
direction,
|
|
1207
1270
|
dragState,
|
|
@@ -1310,8 +1373,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1310
1373
|
}
|
|
1311
1374
|
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1312
1375
|
if (groupSizePixels <= 0) {
|
|
1313
|
-
|
|
1314
|
-
|
|
1376
|
+
if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
|
|
1377
|
+
constraints
|
|
1378
|
+
}) => constraints))) {
|
|
1379
|
+
// Wait until the group has rendered a non-zero size before computing layout.
|
|
1380
|
+
return;
|
|
1381
|
+
}
|
|
1315
1382
|
}
|
|
1316
1383
|
if (unsafeLayout == null) {
|
|
1317
1384
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
@@ -1389,6 +1456,17 @@ function PanelGroupWithForwardedRef({
|
|
|
1389
1456
|
onLayout,
|
|
1390
1457
|
panelDataArray
|
|
1391
1458
|
} = committedValuesRef.current;
|
|
1459
|
+
|
|
1460
|
+
// See issues/211
|
|
1461
|
+
if (panelDataArray.find(({
|
|
1462
|
+
id
|
|
1463
|
+
}) => id === panelData.id) == null) {
|
|
1464
|
+
setImperativeApiQueue(prev => [...prev, {
|
|
1465
|
+
panelData,
|
|
1466
|
+
type: "collapse"
|
|
1467
|
+
}]);
|
|
1468
|
+
return;
|
|
1469
|
+
}
|
|
1392
1470
|
if (panelData.constraints.collapsible) {
|
|
1393
1471
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1394
1472
|
const {
|
|
@@ -1432,6 +1510,17 @@ function PanelGroupWithForwardedRef({
|
|
|
1432
1510
|
onLayout,
|
|
1433
1511
|
panelDataArray
|
|
1434
1512
|
} = committedValuesRef.current;
|
|
1513
|
+
|
|
1514
|
+
// See issues/211
|
|
1515
|
+
if (panelDataArray.find(({
|
|
1516
|
+
id
|
|
1517
|
+
}) => id === panelData.id) == null) {
|
|
1518
|
+
setImperativeApiQueue(prev => [...prev, {
|
|
1519
|
+
panelData,
|
|
1520
|
+
type: "expand"
|
|
1521
|
+
}]);
|
|
1522
|
+
return;
|
|
1523
|
+
}
|
|
1435
1524
|
if (panelData.constraints.collapsible) {
|
|
1436
1525
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1437
1526
|
const {
|
|
@@ -1627,6 +1716,18 @@ function PanelGroupWithForwardedRef({
|
|
|
1627
1716
|
onLayout,
|
|
1628
1717
|
panelDataArray
|
|
1629
1718
|
} = committedValuesRef.current;
|
|
1719
|
+
|
|
1720
|
+
// See issues/211
|
|
1721
|
+
if (panelDataArray.find(({
|
|
1722
|
+
id
|
|
1723
|
+
}) => id === panelData.id) == null) {
|
|
1724
|
+
setImperativeApiQueue(prev => [...prev, {
|
|
1725
|
+
panelData,
|
|
1726
|
+
mixedSizes,
|
|
1727
|
+
type: "resize"
|
|
1728
|
+
}]);
|
|
1729
|
+
return;
|
|
1730
|
+
}
|
|
1630
1731
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1631
1732
|
const {
|
|
1632
1733
|
groupSizePixels,
|
|
@@ -1684,6 +1785,31 @@ function PanelGroupWithForwardedRef({
|
|
|
1684
1785
|
return panelDataArray;
|
|
1685
1786
|
});
|
|
1686
1787
|
}, []);
|
|
1788
|
+
|
|
1789
|
+
// Handle imperative API calls that were made before panels were registered
|
|
1790
|
+
useIsomorphicLayoutEffect(() => {
|
|
1791
|
+
const queue = imperativeApiQueue;
|
|
1792
|
+
while (queue.length > 0) {
|
|
1793
|
+
const current = queue.shift();
|
|
1794
|
+
switch (current.type) {
|
|
1795
|
+
case "collapse":
|
|
1796
|
+
{
|
|
1797
|
+
collapsePanel(current.panelData);
|
|
1798
|
+
break;
|
|
1799
|
+
}
|
|
1800
|
+
case "expand":
|
|
1801
|
+
{
|
|
1802
|
+
expandPanel(current.panelData);
|
|
1803
|
+
break;
|
|
1804
|
+
}
|
|
1805
|
+
case "resize":
|
|
1806
|
+
{
|
|
1807
|
+
resizePanel(current.panelData, current.mixedSizes);
|
|
1808
|
+
break;
|
|
1809
|
+
}
|
|
1810
|
+
}
|
|
1811
|
+
}
|
|
1812
|
+
}, [collapsePanel, expandPanel, imperativeApiQueue, layout, panelDataArray, resizePanel]);
|
|
1687
1813
|
const context = useMemo(() => ({
|
|
1688
1814
|
collapsePanel,
|
|
1689
1815
|
direction,
|
|
@@ -1717,6 +1843,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1717
1843
|
...style,
|
|
1718
1844
|
...styleFromProps
|
|
1719
1845
|
},
|
|
1846
|
+
...dataAttributes,
|
|
1720
1847
|
// CSS selectors
|
|
1721
1848
|
"data-panel-group": "",
|
|
1722
1849
|
"data-panel-group-direction": direction,
|
|
@@ -1804,6 +1931,7 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1804
1931
|
function PanelResizeHandle({
|
|
1805
1932
|
children = null,
|
|
1806
1933
|
className: classNameFromProps = "",
|
|
1934
|
+
dataAttributes,
|
|
1807
1935
|
disabled = false,
|
|
1808
1936
|
id: idFromProps = null,
|
|
1809
1937
|
onDragging,
|
|
@@ -1926,6 +2054,7 @@ function PanelResizeHandle({
|
|
|
1926
2054
|
...styleFromProps
|
|
1927
2055
|
},
|
|
1928
2056
|
tabIndex: 0,
|
|
2057
|
+
...dataAttributes,
|
|
1929
2058
|
// CSS selectors
|
|
1930
2059
|
"data-panel-group-direction": direction,
|
|
1931
2060
|
"data-panel-group-id": groupId,
|