react-resizable-panels 0.0.55 → 0.0.56
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/.eslintrc.cjs +26 -0
- package/CHANGELOG.md +234 -90
- package/README.md +55 -49
- package/dist/declarations/src/Panel.d.ts +75 -20
- package/dist/declarations/src/PanelGroup.d.ts +29 -25
- package/dist/declarations/src/PanelResizeHandle.d.ts +1 -1
- package/dist/declarations/src/index.d.ts +5 -6
- package/dist/declarations/src/types.d.ts +3 -26
- package/dist/declarations/src/vendor/react.d.ts +4 -4
- package/dist/react-resizable-panels.browser.cjs.js +1241 -1035
- package/dist/react-resizable-panels.browser.cjs.mjs +1 -2
- package/dist/react-resizable-panels.browser.development.cjs.js +1367 -1081
- package/dist/react-resizable-panels.browser.development.cjs.mjs +1 -2
- package/dist/react-resizable-panels.browser.development.esm.js +1368 -1081
- package/dist/react-resizable-panels.browser.esm.js +1242 -1035
- package/dist/react-resizable-panels.cjs.js +1241 -1035
- package/dist/react-resizable-panels.cjs.js.map +1 -1
- package/dist/react-resizable-panels.cjs.mjs +1 -2
- package/dist/react-resizable-panels.development.cjs.js +1370 -1084
- package/dist/react-resizable-panels.development.cjs.mjs +1 -2
- package/dist/react-resizable-panels.development.esm.js +1371 -1084
- package/dist/react-resizable-panels.development.node.cjs.js +1151 -940
- package/dist/react-resizable-panels.development.node.cjs.mjs +1 -2
- package/dist/react-resizable-panels.development.node.esm.js +1152 -940
- package/dist/react-resizable-panels.esm.js +1242 -1035
- package/dist/react-resizable-panels.esm.js.map +1 -1
- package/dist/react-resizable-panels.node.cjs.js +1049 -912
- package/dist/react-resizable-panels.node.cjs.mjs +1 -2
- package/dist/react-resizable-panels.node.esm.js +1050 -912
- package/jest.config.js +10 -0
- package/package.json +3 -1
- package/src/Panel.test.tsx +308 -0
- package/src/Panel.ts +175 -123
- package/src/PanelGroup.test.tsx +210 -0
- package/src/PanelGroup.ts +730 -669
- package/src/PanelGroupContext.ts +33 -0
- package/src/PanelResizeHandle.ts +13 -8
- package/src/hooks/useUniqueId.ts +1 -1
- package/src/hooks/useWindowSplitterBehavior.ts +9 -164
- package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +185 -0
- package/src/index.ts +19 -14
- package/src/types.ts +3 -30
- package/src/utils/adjustLayoutByDelta.test.ts +1808 -0
- package/src/utils/adjustLayoutByDelta.ts +211 -0
- package/src/utils/calculateAriaValues.test.ts +111 -0
- package/src/utils/calculateAriaValues.ts +67 -0
- package/src/utils/calculateDeltaPercentage.ts +68 -0
- package/src/utils/calculateDragOffsetPercentage.ts +30 -0
- package/src/utils/calculateUnsafeDefaultLayout.test.ts +92 -0
- package/src/utils/calculateUnsafeDefaultLayout.ts +55 -0
- package/src/utils/callPanelCallbacks.ts +81 -0
- package/src/utils/compareLayouts.test.ts +9 -0
- package/src/utils/compareLayouts.ts +12 -0
- package/src/utils/computePanelFlexBoxStyle.ts +44 -0
- package/src/utils/computePercentagePanelConstraints.test.ts +71 -0
- package/src/utils/computePercentagePanelConstraints.ts +56 -0
- package/src/utils/convertPercentageToPixels.test.ts +9 -0
- package/src/utils/convertPercentageToPixels.ts +6 -0
- package/src/utils/convertPixelConstraintsToPercentages.ts +55 -0
- package/src/utils/convertPixelsToPercentage.test.ts +9 -0
- package/src/utils/convertPixelsToPercentage.ts +6 -0
- package/src/utils/determinePivotIndices.ts +10 -0
- package/src/utils/dom/calculateAvailablePanelSizeInPixels.ts +29 -0
- package/src/utils/dom/getAvailableGroupSizePixels.ts +29 -0
- package/src/utils/dom/getPanelElement.ts +7 -0
- package/src/utils/dom/getPanelGroupElement.ts +7 -0
- package/src/utils/dom/getResizeHandleElement.ts +9 -0
- package/src/utils/dom/getResizeHandleElementIndex.ts +12 -0
- package/src/utils/dom/getResizeHandleElementsForGroup.ts +9 -0
- package/src/utils/dom/getResizeHandlePanelIds.ts +18 -0
- package/src/utils/events.ts +13 -0
- package/src/utils/getPercentageSizeFromMixedSizes.test.ts +47 -0
- package/src/utils/getPercentageSizeFromMixedSizes.ts +15 -0
- package/src/utils/getResizeEventCursorPosition.ts +19 -0
- package/src/utils/initializeDefaultStorage.ts +26 -0
- package/src/utils/numbers/fuzzyCompareNumbers.test.ts +16 -0
- package/src/utils/numbers/fuzzyCompareNumbers.ts +17 -0
- package/src/utils/numbers/fuzzyNumbersEqual.ts +9 -0
- package/src/utils/resizePanel.ts +41 -0
- package/src/utils/serialization.ts +9 -4
- package/src/utils/shouldMonitorPixelBasedConstraints.test.ts +23 -0
- package/src/utils/shouldMonitorPixelBasedConstraints.ts +13 -0
- package/src/utils/test-utils.ts +136 -0
- package/src/utils/validatePanelConstraints.test.ts +151 -0
- package/src/utils/validatePanelConstraints.ts +103 -0
- package/src/utils/validatePanelGroupLayout.test.ts +233 -0
- package/src/utils/validatePanelGroupLayout.ts +88 -0
- package/src/vendor/react.ts +4 -0
- package/.eslintrc.json +0 -22
- package/dist/declarations/src/utils/group.d.ts +0 -29
- package/src/PanelContexts.ts +0 -22
- package/src/utils/coordinates.ts +0 -149
- package/src/utils/group.ts +0 -614
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { PanelConstraints } from "../Panel";
|
|
2
|
+
import { computePercentagePanelConstraints } from "./computePercentagePanelConstraints";
|
|
3
|
+
import { fuzzyCompareNumbers } from "./numbers/fuzzyCompareNumbers";
|
|
4
|
+
|
|
5
|
+
// Panel size must be in percentages; pixel values should be pre-converted
|
|
6
|
+
export function resizePanel({
|
|
7
|
+
groupSizePixels,
|
|
8
|
+
panelConstraints,
|
|
9
|
+
panelIndex,
|
|
10
|
+
size,
|
|
11
|
+
}: {
|
|
12
|
+
groupSizePixels: number;
|
|
13
|
+
panelConstraints: PanelConstraints[];
|
|
14
|
+
panelIndex: number;
|
|
15
|
+
size: number;
|
|
16
|
+
}) {
|
|
17
|
+
let { collapsible } = panelConstraints[panelIndex]!;
|
|
18
|
+
|
|
19
|
+
const { collapsedSizePercentage, maxSizePercentage, minSizePercentage } =
|
|
20
|
+
computePercentagePanelConstraints(
|
|
21
|
+
panelConstraints,
|
|
22
|
+
panelIndex,
|
|
23
|
+
groupSizePixels
|
|
24
|
+
);
|
|
25
|
+
|
|
26
|
+
if (minSizePercentage != null) {
|
|
27
|
+
if (fuzzyCompareNumbers(size, minSizePercentage) < 0) {
|
|
28
|
+
if (collapsible) {
|
|
29
|
+
size = collapsedSizePercentage;
|
|
30
|
+
} else {
|
|
31
|
+
size = minSizePercentage;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
if (maxSizePercentage != null) {
|
|
37
|
+
size = Math.min(maxSizePercentage, size);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return size;
|
|
41
|
+
}
|
|
@@ -1,16 +1,21 @@
|
|
|
1
|
-
import { PanelData
|
|
1
|
+
import { PanelData } from "../Panel";
|
|
2
|
+
import { PanelGroupStorage } from "../PanelGroup";
|
|
2
3
|
|
|
3
4
|
type SerializedPanelGroupState = { [panelIds: string]: number[] };
|
|
4
5
|
|
|
5
6
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
6
7
|
// so they should not be used as part of the serialization key.
|
|
7
|
-
// Using
|
|
8
|
+
// Using the min/max size attributes should work well enough as a backup.
|
|
8
9
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
9
10
|
function getSerializationKey(panels: PanelData[]): string {
|
|
10
11
|
return panels
|
|
11
12
|
.map((panel) => {
|
|
12
|
-
const {
|
|
13
|
-
|
|
13
|
+
const { constraints, id, idIsFromProps, order } = panel;
|
|
14
|
+
if (idIsFromProps) {
|
|
15
|
+
return id;
|
|
16
|
+
} else {
|
|
17
|
+
return `${order}:${JSON.stringify(constraints)}`;
|
|
18
|
+
}
|
|
14
19
|
})
|
|
15
20
|
.sort((a, b) => a.localeCompare(b))
|
|
16
21
|
.join(",");
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { shouldMonitorPixelBasedConstraints } from "./shouldMonitorPixelBasedConstraints";
|
|
2
|
+
|
|
3
|
+
describe("shouldMonitorPixelBasedConstraints", () => {
|
|
4
|
+
it("should identify min, max, or collapsed size pixel constraints", () => {
|
|
5
|
+
expect(
|
|
6
|
+
shouldMonitorPixelBasedConstraints([{}, { collapsedSizePixels: 100 }, {}])
|
|
7
|
+
).toBe(true);
|
|
8
|
+
|
|
9
|
+
expect(
|
|
10
|
+
shouldMonitorPixelBasedConstraints([{ minSizePixels: 100 }, {}, {}])
|
|
11
|
+
).toBe(true);
|
|
12
|
+
|
|
13
|
+
expect(
|
|
14
|
+
shouldMonitorPixelBasedConstraints([{}, {}, { maxSizePixels: 100 }])
|
|
15
|
+
).toBe(true);
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it("should ignore default size constraints", () => {
|
|
19
|
+
expect(
|
|
20
|
+
shouldMonitorPixelBasedConstraints([{ defaultSizePixels: 100 }])
|
|
21
|
+
).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PanelConstraints } from "../Panel";
|
|
2
|
+
|
|
3
|
+
export function shouldMonitorPixelBasedConstraints(
|
|
4
|
+
constraints: PanelConstraints[]
|
|
5
|
+
): boolean {
|
|
6
|
+
return constraints.some((constraints) => {
|
|
7
|
+
return (
|
|
8
|
+
constraints.collapsedSizePixels !== undefined ||
|
|
9
|
+
constraints.maxSizePixels !== undefined ||
|
|
10
|
+
constraints.minSizePixels !== undefined
|
|
11
|
+
);
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
import { MixedSizes } from "../types";
|
|
2
|
+
|
|
3
|
+
const util = require("util");
|
|
4
|
+
|
|
5
|
+
export function expectToBeCloseToArray(
|
|
6
|
+
actualNumbers: number[],
|
|
7
|
+
expectedNumbers: number[]
|
|
8
|
+
) {
|
|
9
|
+
expect(actualNumbers.length).toBe(expectedNumbers.length);
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
actualNumbers.forEach((actualNumber, index) => {
|
|
13
|
+
const expectedNumber = expectedNumbers[index];
|
|
14
|
+
expect(actualNumber).toBeCloseTo(expectedNumber, 1);
|
|
15
|
+
});
|
|
16
|
+
} catch (error) {
|
|
17
|
+
expect(actualNumbers).toEqual(expectedNumbers);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function mockPanelGroupOffsetWidthAndHeight(
|
|
22
|
+
mockWidth = 1_000,
|
|
23
|
+
mockHeight = 1_000
|
|
24
|
+
) {
|
|
25
|
+
const offsetHeightPropertyDescriptor = Object.getOwnPropertyDescriptor(
|
|
26
|
+
HTMLElement.prototype,
|
|
27
|
+
"offsetHeight"
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const offsetWidthPropertyDescriptor = Object.getOwnPropertyDescriptor(
|
|
31
|
+
HTMLElement.prototype,
|
|
32
|
+
"offsetWidth"
|
|
33
|
+
);
|
|
34
|
+
|
|
35
|
+
Object.defineProperty(HTMLElement.prototype, "offsetHeight", {
|
|
36
|
+
configurable: true,
|
|
37
|
+
get: function () {
|
|
38
|
+
if (this.hasAttribute("data-resize-handle")) {
|
|
39
|
+
return 0;
|
|
40
|
+
} else if (this.hasAttribute("data-panel-group")) {
|
|
41
|
+
return mockHeight;
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
Object.defineProperty(HTMLElement.prototype, "offsetWidth", {
|
|
47
|
+
configurable: true,
|
|
48
|
+
get: function () {
|
|
49
|
+
if (this.hasAttribute("data-resize-handle")) {
|
|
50
|
+
return 0;
|
|
51
|
+
} else if (this.hasAttribute("data-panel-group")) {
|
|
52
|
+
return mockWidth;
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
return function uninstallMocks() {
|
|
58
|
+
if (offsetHeightPropertyDescriptor) {
|
|
59
|
+
Object.defineProperty(
|
|
60
|
+
HTMLElement.prototype,
|
|
61
|
+
"offsetHeight",
|
|
62
|
+
offsetHeightPropertyDescriptor
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
if (offsetWidthPropertyDescriptor) {
|
|
67
|
+
Object.defineProperty(
|
|
68
|
+
HTMLElement.prototype,
|
|
69
|
+
"offsetWidth",
|
|
70
|
+
offsetWidthPropertyDescriptor
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
export function verifyExpandedPanelGroupLayout(
|
|
77
|
+
actualLayout: MixedSizes[],
|
|
78
|
+
expectedPercentages: number[]
|
|
79
|
+
) {
|
|
80
|
+
expect(actualLayout).toHaveLength(expectedPercentages.length);
|
|
81
|
+
expect(actualLayout.map(({ sizePercentage }) => sizePercentage)).toEqual(
|
|
82
|
+
expectedPercentages
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export function verifyExpectedWarnings(
|
|
87
|
+
callback: Function,
|
|
88
|
+
...expectedMessages: string[]
|
|
89
|
+
) {
|
|
90
|
+
const consoleSpy = (format: any, ...args: any[]) => {
|
|
91
|
+
const message = util.format(format, ...args);
|
|
92
|
+
|
|
93
|
+
for (let index = 0; index < expectedMessages.length; index++) {
|
|
94
|
+
const expectedMessage = expectedMessages[index];
|
|
95
|
+
if (message.includes(expectedMessage)) {
|
|
96
|
+
expectedMessages.splice(index, 1);
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (expectedMessages.length === 0) {
|
|
102
|
+
throw new Error(`Unexpected message recorded:\n\n${message}`);
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const originalError = console.error;
|
|
107
|
+
const originalWarn = console.warn;
|
|
108
|
+
|
|
109
|
+
console.error = consoleSpy;
|
|
110
|
+
console.warn = consoleSpy;
|
|
111
|
+
|
|
112
|
+
let caughtError;
|
|
113
|
+
let didCatch = false;
|
|
114
|
+
try {
|
|
115
|
+
callback();
|
|
116
|
+
} catch (error) {
|
|
117
|
+
caughtError = error;
|
|
118
|
+
didCatch = true;
|
|
119
|
+
} finally {
|
|
120
|
+
console.error = originalError;
|
|
121
|
+
console.warn = originalWarn;
|
|
122
|
+
|
|
123
|
+
if (didCatch) {
|
|
124
|
+
throw caughtError;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// Any remaining messages indicate a failed expectations.
|
|
128
|
+
if (expectedMessages.length > 0) {
|
|
129
|
+
throw Error(
|
|
130
|
+
`Expected message(s) not recorded:\n\n${expectedMessages.join("\n")}`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return { pass: true };
|
|
135
|
+
}
|
|
136
|
+
}
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { verifyExpectedWarnings } from "./test-utils";
|
|
2
|
+
import { validatePanelConstraints } from "./validatePanelConstraints";
|
|
3
|
+
|
|
4
|
+
describe("validatePanelConstraints", () => {
|
|
5
|
+
it("should not warn if there are no validation errors", () => {
|
|
6
|
+
verifyExpectedWarnings(() => {
|
|
7
|
+
validatePanelConstraints({
|
|
8
|
+
groupSizePixels: 100_000,
|
|
9
|
+
panelConstraints: [{}],
|
|
10
|
+
panelIndex: 0,
|
|
11
|
+
panelId: "test",
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
it("should warn about conflicting percentages and pixels", () => {
|
|
17
|
+
verifyExpectedWarnings(() => {
|
|
18
|
+
validatePanelConstraints({
|
|
19
|
+
groupSizePixels: 100_000,
|
|
20
|
+
panelConstraints: [
|
|
21
|
+
{
|
|
22
|
+
collapsedSizePercentage: 5,
|
|
23
|
+
collapsedSizePixels: 10,
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
panelIndex: 0,
|
|
27
|
+
panelId: "test",
|
|
28
|
+
});
|
|
29
|
+
}, "should not specify both percentage and pixel units for: collapsed size");
|
|
30
|
+
|
|
31
|
+
verifyExpectedWarnings(() => {
|
|
32
|
+
validatePanelConstraints({
|
|
33
|
+
groupSizePixels: 100_000,
|
|
34
|
+
panelConstraints: [
|
|
35
|
+
{
|
|
36
|
+
maxSizePercentage: 5,
|
|
37
|
+
maxSizePixels: 10,
|
|
38
|
+
minSizePercentage: 5,
|
|
39
|
+
minSizePixels: 10,
|
|
40
|
+
},
|
|
41
|
+
],
|
|
42
|
+
panelIndex: 0,
|
|
43
|
+
panelId: "test",
|
|
44
|
+
});
|
|
45
|
+
}, "should not specify both percentage and pixel units for: max size, min size");
|
|
46
|
+
|
|
47
|
+
verifyExpectedWarnings(() => {
|
|
48
|
+
validatePanelConstraints({
|
|
49
|
+
groupSizePixels: 100_000,
|
|
50
|
+
panelConstraints: [
|
|
51
|
+
{
|
|
52
|
+
defaultSizePercentage: 5,
|
|
53
|
+
defaultSizePixels: 10,
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
panelIndex: 0,
|
|
57
|
+
panelId: "test",
|
|
58
|
+
});
|
|
59
|
+
}, "should not specify both percentage and pixel units for: default size");
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it("should warn about conflicting min/max sizes", () => {
|
|
63
|
+
verifyExpectedWarnings(() => {
|
|
64
|
+
validatePanelConstraints({
|
|
65
|
+
groupSizePixels: 100_000,
|
|
66
|
+
panelConstraints: [
|
|
67
|
+
{
|
|
68
|
+
maxSizePercentage: 5,
|
|
69
|
+
minSizePercentage: 10,
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
panelIndex: 0,
|
|
73
|
+
panelId: "test",
|
|
74
|
+
});
|
|
75
|
+
}, "min size (10%) should not be greater than max size (5%)");
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it("should warn about conflicting collapsed and min sizes", () => {
|
|
79
|
+
verifyExpectedWarnings(() => {
|
|
80
|
+
validatePanelConstraints({
|
|
81
|
+
groupSizePixels: 100_000,
|
|
82
|
+
panelConstraints: [
|
|
83
|
+
{
|
|
84
|
+
collapsedSizePercentage: 15,
|
|
85
|
+
minSizePercentage: 10,
|
|
86
|
+
},
|
|
87
|
+
],
|
|
88
|
+
panelIndex: 0,
|
|
89
|
+
panelId: "test",
|
|
90
|
+
});
|
|
91
|
+
}, "collapsed size should not be greater than min size");
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it("should warn about conflicting default and min/max sizes", () => {
|
|
95
|
+
verifyExpectedWarnings(() => {
|
|
96
|
+
validatePanelConstraints({
|
|
97
|
+
groupSizePixels: 100_000,
|
|
98
|
+
panelConstraints: [
|
|
99
|
+
{
|
|
100
|
+
defaultSizePercentage: -1,
|
|
101
|
+
minSizePercentage: 10,
|
|
102
|
+
},
|
|
103
|
+
],
|
|
104
|
+
panelIndex: 0,
|
|
105
|
+
panelId: "test",
|
|
106
|
+
});
|
|
107
|
+
}, "default size should not be less than 0");
|
|
108
|
+
|
|
109
|
+
verifyExpectedWarnings(() => {
|
|
110
|
+
validatePanelConstraints({
|
|
111
|
+
groupSizePixels: 100_000,
|
|
112
|
+
panelConstraints: [
|
|
113
|
+
{
|
|
114
|
+
defaultSizePercentage: 5,
|
|
115
|
+
minSizePercentage: 10,
|
|
116
|
+
},
|
|
117
|
+
],
|
|
118
|
+
panelIndex: 0,
|
|
119
|
+
panelId: "test",
|
|
120
|
+
});
|
|
121
|
+
}, "default size should not be less than min size");
|
|
122
|
+
|
|
123
|
+
verifyExpectedWarnings(() => {
|
|
124
|
+
validatePanelConstraints({
|
|
125
|
+
groupSizePixels: 100_000,
|
|
126
|
+
panelConstraints: [
|
|
127
|
+
{
|
|
128
|
+
defaultSizePercentage: 101,
|
|
129
|
+
maxSizePercentage: 10,
|
|
130
|
+
},
|
|
131
|
+
],
|
|
132
|
+
panelIndex: 0,
|
|
133
|
+
panelId: "test",
|
|
134
|
+
});
|
|
135
|
+
}, "default size should not be greater than 100");
|
|
136
|
+
|
|
137
|
+
verifyExpectedWarnings(() => {
|
|
138
|
+
validatePanelConstraints({
|
|
139
|
+
groupSizePixels: 100_000,
|
|
140
|
+
panelConstraints: [
|
|
141
|
+
{
|
|
142
|
+
defaultSizePercentage: 15,
|
|
143
|
+
maxSizePercentage: 10,
|
|
144
|
+
},
|
|
145
|
+
],
|
|
146
|
+
panelIndex: 0,
|
|
147
|
+
panelId: "test",
|
|
148
|
+
});
|
|
149
|
+
}, "default size should not be greater than max size");
|
|
150
|
+
});
|
|
151
|
+
});
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { isDevelopment } from "#is-development";
|
|
2
|
+
import { PanelConstraints } from "../Panel";
|
|
3
|
+
import { computePercentagePanelConstraints } from "./computePercentagePanelConstraints";
|
|
4
|
+
|
|
5
|
+
export function validatePanelConstraints({
|
|
6
|
+
groupSizePixels,
|
|
7
|
+
panelConstraints,
|
|
8
|
+
panelId,
|
|
9
|
+
panelIndex,
|
|
10
|
+
}: {
|
|
11
|
+
groupSizePixels: number;
|
|
12
|
+
panelConstraints: PanelConstraints[];
|
|
13
|
+
panelId: string | undefined;
|
|
14
|
+
panelIndex: number;
|
|
15
|
+
}): boolean {
|
|
16
|
+
if (isDevelopment) {
|
|
17
|
+
const warnings = [];
|
|
18
|
+
|
|
19
|
+
{
|
|
20
|
+
const {
|
|
21
|
+
collapsedSizePercentage,
|
|
22
|
+
collapsedSizePixels,
|
|
23
|
+
defaultSizePercentage,
|
|
24
|
+
defaultSizePixels,
|
|
25
|
+
maxSizePercentage,
|
|
26
|
+
maxSizePixels,
|
|
27
|
+
minSizePercentage,
|
|
28
|
+
minSizePixels,
|
|
29
|
+
} = panelConstraints[panelIndex]!;
|
|
30
|
+
|
|
31
|
+
const conflictingUnits: string[] = [];
|
|
32
|
+
|
|
33
|
+
if (collapsedSizePercentage != null && collapsedSizePixels != null) {
|
|
34
|
+
conflictingUnits.push("collapsed size");
|
|
35
|
+
}
|
|
36
|
+
if (defaultSizePercentage != null && defaultSizePixels != null) {
|
|
37
|
+
conflictingUnits.push("default size");
|
|
38
|
+
}
|
|
39
|
+
if (maxSizePercentage != null && maxSizePixels != null) {
|
|
40
|
+
conflictingUnits.push("max size");
|
|
41
|
+
}
|
|
42
|
+
if (minSizePercentage != null && minSizePixels != null) {
|
|
43
|
+
conflictingUnits.push("min size");
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (conflictingUnits.length > 0) {
|
|
47
|
+
warnings.push(
|
|
48
|
+
`should not specify both percentage and pixel units for: ${conflictingUnits.join(
|
|
49
|
+
", "
|
|
50
|
+
)}`
|
|
51
|
+
);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
{
|
|
56
|
+
const {
|
|
57
|
+
collapsedSizePercentage,
|
|
58
|
+
defaultSizePercentage,
|
|
59
|
+
maxSizePercentage,
|
|
60
|
+
minSizePercentage,
|
|
61
|
+
} = computePercentagePanelConstraints(
|
|
62
|
+
panelConstraints,
|
|
63
|
+
panelIndex,
|
|
64
|
+
groupSizePixels
|
|
65
|
+
);
|
|
66
|
+
|
|
67
|
+
if (minSizePercentage > maxSizePercentage) {
|
|
68
|
+
warnings.push(
|
|
69
|
+
`min size (${minSizePercentage}%) should not be greater than max size (${maxSizePercentage}%)`
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
if (defaultSizePercentage != null) {
|
|
74
|
+
if (defaultSizePercentage < 0) {
|
|
75
|
+
warnings.push("default size should not be less than 0");
|
|
76
|
+
} else if (defaultSizePercentage < minSizePercentage) {
|
|
77
|
+
warnings.push("default size should not be less than min size");
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
if (defaultSizePercentage > 100) {
|
|
81
|
+
warnings.push("default size should not be greater than 100");
|
|
82
|
+
} else if (defaultSizePercentage > maxSizePercentage) {
|
|
83
|
+
warnings.push("default size should not be greater than max size");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
if (collapsedSizePercentage > minSizePercentage) {
|
|
88
|
+
warnings.push("collapsed size should not be greater than min size");
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
if (warnings.length > 0) {
|
|
93
|
+
const name = panelId != null ? `Panel "${panelId}"` : "Panel";
|
|
94
|
+
console.warn(
|
|
95
|
+
`${name} has an invalid configuration:\n\n${warnings.join("\n")}`
|
|
96
|
+
);
|
|
97
|
+
|
|
98
|
+
return false;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
return true;
|
|
103
|
+
}
|