react-resizable-panels 1.0.0-rc.2 → 1.0.0-rc.3
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/dist/react-resizable-panels.browser.cjs.js +26 -10
- package/dist/react-resizable-panels.browser.development.cjs.js +26 -10
- package/dist/react-resizable-panels.browser.development.esm.js +26 -10
- package/dist/react-resizable-panels.browser.esm.js +26 -10
- package/dist/react-resizable-panels.cjs.d.ts +1 -88
- package/dist/react-resizable-panels.cjs.d.ts.map +1 -1
- package/dist/react-resizable-panels.cjs.js +1741 -1488
- package/dist/react-resizable-panels.development.cjs.js +26 -10
- package/dist/react-resizable-panels.development.esm.js +26 -10
- package/dist/react-resizable-panels.development.node.cjs.js +26 -10
- package/dist/react-resizable-panels.development.node.esm.js +26 -10
- package/dist/react-resizable-panels.esm.js +1716 -1483
- package/dist/react-resizable-panels.node.cjs.js +26 -10
- package/dist/react-resizable-panels.node.esm.js +26 -10
- package/package.json +1 -1
- package/src/NewPanelGroup.ts +149 -0
- package/dist/react-resizable-panels.cjs.js.map +0 -1
- package/dist/react-resizable-panels.esm.js.map +0 -1
|
@@ -1,1632 +1,1885 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
+
|
|
5
|
+
var React = require('react');
|
|
6
|
+
|
|
7
|
+
function _interopNamespace(e) {
|
|
8
|
+
if (e && e.__esModule) return e;
|
|
9
|
+
var n = Object.create(null);
|
|
10
|
+
if (e) {
|
|
11
|
+
Object.keys(e).forEach(function (k) {
|
|
12
|
+
if (k !== 'default') {
|
|
13
|
+
var d = Object.getOwnPropertyDescriptor(e, k);
|
|
14
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
15
|
+
enumerable: true,
|
|
16
|
+
get: function () { return e[k]; }
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
n["default"] = e;
|
|
22
|
+
return Object.freeze(n);
|
|
5
23
|
}
|
|
6
24
|
|
|
7
|
-
|
|
8
|
-
$parcel$export(module.exports, "Panel", () => $45da0e827c614f1d$export$2ddb90ad54e5f587);
|
|
9
|
-
$parcel$export(module.exports, "PanelGroup", () => $cec4cafe75f3db78$export$1d05749f6f573bb);
|
|
10
|
-
$parcel$export(module.exports, "PanelResizeHandle", () => $3a26a712c9163348$export$8829ecf6b6b15484);
|
|
11
|
-
const $168036e9e9a9d9f8$export$4e09c449d6c407f7 = true;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const $95f7f0116122f6f8$export$df77466336fe5355 = true;
|
|
25
|
+
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
15
26
|
|
|
27
|
+
const isBrowser = typeof window !== "undefined";
|
|
16
28
|
|
|
17
29
|
// This module exists to work around Webpack issue https://github.com/webpack/webpack/issues/14814
|
|
18
|
-
// and limitations with ParcelJS parsing of the useId workaround (used below).
|
|
19
|
-
// For the time being, all react-resizable-panels must import "react" with the "* as React" syntax.
|
|
20
|
-
// To avoid mistakes, we use the ESLint "no-restricted-imports" to prevent "react" imports except in this file.
|
|
21
|
-
// See https://github.com/bvaughn/react-resizable-panels/issues/118
|
|
22
|
-
// eslint-disable-next-line no-restricted-imports
|
|
23
|
-
|
|
24
|
-
const { createElement: $6e687094f9ca8395$export$c8a8987d4410bf2d, createContext: $6e687094f9ca8395$export$fd42f52fd3ae1109, createRef: $6e687094f9ca8395$export$7d1e3a5e95ceca43, forwardRef: $6e687094f9ca8395$export$257a8862b851cb5b, useCallback: $6e687094f9ca8395$export$35808ee640e87ca7, useContext: $6e687094f9ca8395$export$fae74005e78b1a27, useEffect: $6e687094f9ca8395$export$6d9c69b0de29b591, useImperativeHandle: $6e687094f9ca8395$export$d5a552a76deda3c2, useLayoutEffect: $6e687094f9ca8395$export$e5c5a5f917a5871c, useMemo: $6e687094f9ca8395$export$1538c33de8887b59, useRef: $6e687094f9ca8395$export$b8f5890fc79d6aca, useState: $6e687094f9ca8395$export$60241385465d0a34 } = $2IMI0$react;
|
|
25
|
-
// `toString()` prevents bundlers from trying to `import { useId } from 'react'`
|
|
26
|
-
const $6e687094f9ca8395$export$f680877a34711e37 = $2IMI0$react["useId".toString()];
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
const $a15c28001c46e071$export$7d8c6d083caec74a = (0, $6e687094f9ca8395$export$fd42f52fd3ae1109)(null);
|
|
30
|
-
$a15c28001c46e071$export$7d8c6d083caec74a.displayName = "PanelGroupContext";
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
const $129b5b9a317dcc10$var$useIsomorphicLayoutEffect = (0, $168036e9e9a9d9f8$export$4e09c449d6c407f7) ? (0, $6e687094f9ca8395$export$e5c5a5f917a5871c) : ()=>{};
|
|
36
|
-
var $129b5b9a317dcc10$export$2e2bcd8739ae039 = $129b5b9a317dcc10$var$useIsomorphicLayoutEffect;
|
|
37
30
|
|
|
31
|
+
// eslint-disable-next-line no-restricted-imports
|
|
38
32
|
|
|
33
|
+
const {
|
|
34
|
+
createElement,
|
|
35
|
+
createContext,
|
|
36
|
+
createRef,
|
|
37
|
+
forwardRef,
|
|
38
|
+
useCallback,
|
|
39
|
+
useContext,
|
|
40
|
+
useEffect,
|
|
41
|
+
useImperativeHandle,
|
|
42
|
+
useLayoutEffect,
|
|
43
|
+
useMemo,
|
|
44
|
+
useRef,
|
|
45
|
+
useState
|
|
46
|
+
} = React__namespace;
|
|
39
47
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
48
|
+
// `toString()` prevents bundlers from trying to `import { useId } from 'react'`
|
|
49
|
+
const useId = React__namespace["useId".toString()];
|
|
50
|
+
|
|
51
|
+
const PanelGroupContext = createContext(null);
|
|
52
|
+
PanelGroupContext.displayName = "PanelGroupContext";
|
|
53
|
+
|
|
54
|
+
const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : () => {};
|
|
55
|
+
|
|
56
|
+
const wrappedUseId = typeof useId === "function" ? useId : () => null;
|
|
57
|
+
let counter = 0;
|
|
58
|
+
function useUniqueId(idFromParams = null) {
|
|
59
|
+
const idFromUseId = wrappedUseId();
|
|
60
|
+
const idRef = useRef(idFromParams || idFromUseId || null);
|
|
61
|
+
if (idRef.current === null) {
|
|
62
|
+
idRef.current = "" + counter++;
|
|
63
|
+
}
|
|
64
|
+
return idFromParams !== null && idFromParams !== void 0 ? idFromParams : idRef.current;
|
|
47
65
|
}
|
|
48
66
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
67
|
+
function PanelWithForwardedRef({
|
|
68
|
+
children,
|
|
69
|
+
className: classNameFromProps = "",
|
|
70
|
+
collapsedSize,
|
|
71
|
+
collapsible,
|
|
72
|
+
defaultSize,
|
|
73
|
+
forwardedRef,
|
|
74
|
+
id: idFromProps,
|
|
75
|
+
maxSize,
|
|
76
|
+
minSize,
|
|
77
|
+
onCollapse,
|
|
78
|
+
onExpand,
|
|
79
|
+
onResize,
|
|
80
|
+
order,
|
|
81
|
+
style: styleFromProps,
|
|
82
|
+
tagName: Type = "div",
|
|
83
|
+
...rest
|
|
84
|
+
}) {
|
|
85
|
+
const context = useContext(PanelGroupContext);
|
|
86
|
+
if (context === null) {
|
|
87
|
+
throw Error(`Panel components must be rendered within a PanelGroup container`);
|
|
88
|
+
}
|
|
89
|
+
const {
|
|
90
|
+
collapsePanel,
|
|
91
|
+
expandPanel,
|
|
92
|
+
getPanelSize,
|
|
93
|
+
getPanelStyle,
|
|
94
|
+
groupId,
|
|
95
|
+
isPanelCollapsed,
|
|
96
|
+
registerPanel,
|
|
97
|
+
resizePanel,
|
|
98
|
+
unregisterPanel
|
|
99
|
+
} = context;
|
|
100
|
+
const panelId = useUniqueId(idFromProps);
|
|
101
|
+
const panelDataRef = useRef({
|
|
102
|
+
callbacks: {
|
|
103
|
+
onCollapse,
|
|
104
|
+
onExpand,
|
|
105
|
+
onResize
|
|
106
|
+
},
|
|
107
|
+
constraints: {
|
|
108
|
+
collapsedSize,
|
|
109
|
+
collapsible,
|
|
110
|
+
defaultSize,
|
|
111
|
+
maxSize,
|
|
112
|
+
minSize
|
|
113
|
+
},
|
|
114
|
+
id: panelId,
|
|
115
|
+
idIsFromProps: idFromProps !== undefined,
|
|
116
|
+
order
|
|
117
|
+
});
|
|
118
|
+
useRef({
|
|
119
|
+
didLogMissingDefaultSizeWarning: false
|
|
120
|
+
});
|
|
121
|
+
useIsomorphicLayoutEffect(() => {
|
|
122
|
+
const {
|
|
123
|
+
callbacks,
|
|
124
|
+
constraints
|
|
125
|
+
} = panelDataRef.current;
|
|
126
|
+
panelDataRef.current.id = panelId;
|
|
127
|
+
panelDataRef.current.idIsFromProps = idFromProps !== undefined;
|
|
128
|
+
panelDataRef.current.order = order;
|
|
129
|
+
callbacks.onCollapse = onCollapse;
|
|
130
|
+
callbacks.onExpand = onExpand;
|
|
131
|
+
callbacks.onResize = onResize;
|
|
132
|
+
constraints.collapsedSize = collapsedSize;
|
|
133
|
+
constraints.collapsible = collapsible;
|
|
134
|
+
constraints.defaultSize = defaultSize;
|
|
135
|
+
constraints.maxSize = maxSize;
|
|
136
|
+
constraints.minSize = minSize;
|
|
137
|
+
});
|
|
138
|
+
useIsomorphicLayoutEffect(() => {
|
|
139
|
+
const panelData = panelDataRef.current;
|
|
140
|
+
registerPanel(panelData);
|
|
141
|
+
return () => {
|
|
142
|
+
unregisterPanel(panelData);
|
|
143
|
+
};
|
|
144
|
+
}, [order, panelId, registerPanel, unregisterPanel]);
|
|
145
|
+
useImperativeHandle(forwardedRef, () => ({
|
|
146
|
+
collapse: () => {
|
|
147
|
+
collapsePanel(panelDataRef.current);
|
|
148
|
+
},
|
|
149
|
+
expand: () => {
|
|
150
|
+
expandPanel(panelDataRef.current);
|
|
151
|
+
},
|
|
152
|
+
getId() {
|
|
153
|
+
return panelId;
|
|
154
|
+
},
|
|
155
|
+
getSize() {
|
|
156
|
+
return getPanelSize(panelDataRef.current);
|
|
157
|
+
},
|
|
158
|
+
isCollapsed() {
|
|
159
|
+
return isPanelCollapsed(panelDataRef.current);
|
|
160
|
+
},
|
|
161
|
+
isExpanded() {
|
|
162
|
+
return !isPanelCollapsed(panelDataRef.current);
|
|
163
|
+
},
|
|
164
|
+
resize: size => {
|
|
165
|
+
resizePanel(panelDataRef.current, size);
|
|
85
166
|
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
unregisterPanel(panelData);
|
|
105
|
-
};
|
|
106
|
-
}, [
|
|
107
|
-
order,
|
|
108
|
-
panelId,
|
|
109
|
-
registerPanel,
|
|
110
|
-
unregisterPanel
|
|
111
|
-
]);
|
|
112
|
-
(0, $6e687094f9ca8395$export$d5a552a76deda3c2)(forwardedRef, ()=>({
|
|
113
|
-
collapse: ()=>{
|
|
114
|
-
collapsePanel(panelDataRef.current);
|
|
115
|
-
},
|
|
116
|
-
expand: ()=>{
|
|
117
|
-
expandPanel(panelDataRef.current);
|
|
118
|
-
},
|
|
119
|
-
getId () {
|
|
120
|
-
return panelId;
|
|
121
|
-
},
|
|
122
|
-
getSize () {
|
|
123
|
-
return getPanelSize(panelDataRef.current);
|
|
124
|
-
},
|
|
125
|
-
isCollapsed () {
|
|
126
|
-
return isPanelCollapsed(panelDataRef.current);
|
|
127
|
-
},
|
|
128
|
-
isExpanded () {
|
|
129
|
-
return !isPanelCollapsed(panelDataRef.current);
|
|
130
|
-
},
|
|
131
|
-
resize: (size)=>{
|
|
132
|
-
resizePanel(panelDataRef.current, size);
|
|
133
|
-
}
|
|
134
|
-
}), [
|
|
135
|
-
collapsePanel,
|
|
136
|
-
expandPanel,
|
|
137
|
-
getPanelSize,
|
|
138
|
-
isPanelCollapsed,
|
|
139
|
-
panelId,
|
|
140
|
-
resizePanel
|
|
141
|
-
]);
|
|
142
|
-
const style = getPanelStyle(panelDataRef.current);
|
|
143
|
-
return (0, $6e687094f9ca8395$export$c8a8987d4410bf2d)(Type, {
|
|
144
|
-
...rest,
|
|
145
|
-
children: children,
|
|
146
|
-
className: classNameFromProps,
|
|
147
|
-
style: {
|
|
148
|
-
...style,
|
|
149
|
-
...styleFromProps
|
|
150
|
-
},
|
|
151
|
-
// CSS selectors
|
|
152
|
-
"data-panel": "",
|
|
153
|
-
"data-panel-id": panelId,
|
|
154
|
-
"data-panel-group-id": groupId,
|
|
155
|
-
// e2e test attributes
|
|
156
|
-
"data-panel-collapsible": (0, $95f7f0116122f6f8$export$df77466336fe5355) ? collapsible || undefined : undefined,
|
|
157
|
-
"data-panel-size": (0, $95f7f0116122f6f8$export$df77466336fe5355) ? parseFloat("" + style.flexGrow).toFixed(1) : undefined
|
|
158
|
-
});
|
|
167
|
+
}), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
|
|
168
|
+
const style = getPanelStyle(panelDataRef.current);
|
|
169
|
+
return createElement(Type, {
|
|
170
|
+
...rest,
|
|
171
|
+
children,
|
|
172
|
+
className: classNameFromProps,
|
|
173
|
+
style: {
|
|
174
|
+
...style,
|
|
175
|
+
...styleFromProps
|
|
176
|
+
},
|
|
177
|
+
// CSS selectors
|
|
178
|
+
"data-panel": "",
|
|
179
|
+
"data-panel-id": panelId,
|
|
180
|
+
"data-panel-group-id": groupId,
|
|
181
|
+
// e2e test attributes
|
|
182
|
+
"data-panel-collapsible": undefined,
|
|
183
|
+
"data-panel-size": undefined
|
|
184
|
+
});
|
|
159
185
|
}
|
|
160
|
-
const
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
function $3b727a2145ecd6f8$export$a7a9523472993e97(expectedCondition, message = "Assertion failed!") {
|
|
174
|
-
if (!expectedCondition) {
|
|
175
|
-
console.error(message);
|
|
176
|
-
throw Error(message);
|
|
177
|
-
}
|
|
186
|
+
const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
|
|
187
|
+
...props,
|
|
188
|
+
forwardedRef: ref
|
|
189
|
+
}));
|
|
190
|
+
PanelWithForwardedRef.displayName = "Panel";
|
|
191
|
+
Panel.displayName = "forwardRef(Panel)";
|
|
192
|
+
|
|
193
|
+
function assert(expectedCondition, message = "Assertion failed!") {
|
|
194
|
+
if (!expectedCondition) {
|
|
195
|
+
console.error(message);
|
|
196
|
+
throw Error(message);
|
|
197
|
+
}
|
|
178
198
|
}
|
|
179
199
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
200
|
+
const PRECISION = 10;
|
|
201
|
+
|
|
202
|
+
function fuzzyCompareNumbers(actual, expected, fractionDigits = PRECISION) {
|
|
203
|
+
actual = parseFloat(actual.toFixed(fractionDigits));
|
|
204
|
+
expected = parseFloat(expected.toFixed(fractionDigits));
|
|
205
|
+
const delta = actual - expected;
|
|
206
|
+
if (delta === 0) {
|
|
207
|
+
return 0;
|
|
208
|
+
} else {
|
|
209
|
+
return delta > 0 ? 1 : -1;
|
|
210
|
+
}
|
|
190
211
|
}
|
|
191
212
|
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
function $599218a3c5f0640f$export$db9c8bd2fae72e82(actual, expected, fractionDigits) {
|
|
195
|
-
return (0, $b4416cfcd0b81788$export$1d75b1119dff900)(actual, expected, fractionDigits) === 0;
|
|
213
|
+
function fuzzyNumbersEqual(actual, expected, fractionDigits) {
|
|
214
|
+
return fuzzyCompareNumbers(actual, expected, fractionDigits) === 0;
|
|
196
215
|
}
|
|
197
216
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
217
|
+
// Panel size must be in percentages; pixel values should be pre-converted
|
|
218
|
+
function resizePanel({
|
|
219
|
+
panelConstraints: panelConstraintsArray,
|
|
220
|
+
panelIndex,
|
|
221
|
+
size
|
|
222
|
+
}) {
|
|
223
|
+
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
224
|
+
assert(panelConstraints != null);
|
|
225
|
+
let {
|
|
226
|
+
collapsedSize = 0,
|
|
227
|
+
collapsible,
|
|
228
|
+
maxSize = 100,
|
|
229
|
+
minSize = 0
|
|
230
|
+
} = panelConstraints;
|
|
231
|
+
if (fuzzyCompareNumbers(size, minSize) < 0) {
|
|
232
|
+
if (collapsible) {
|
|
233
|
+
// Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
|
|
234
|
+
const halfwayPoint = (collapsedSize + minSize) / 2;
|
|
235
|
+
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
236
|
+
size = collapsedSize;
|
|
237
|
+
} else {
|
|
238
|
+
size = minSize;
|
|
239
|
+
}
|
|
240
|
+
} else {
|
|
241
|
+
size = minSize;
|
|
213
242
|
}
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
243
|
+
}
|
|
244
|
+
size = Math.min(maxSize, size);
|
|
245
|
+
size = parseFloat(size.toFixed(PRECISION));
|
|
246
|
+
return size;
|
|
217
247
|
}
|
|
218
248
|
|
|
219
|
-
|
|
220
|
-
function
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
249
|
+
// All units must be in percentages; pixel values should be pre-converted
|
|
250
|
+
function adjustLayoutByDelta({
|
|
251
|
+
delta,
|
|
252
|
+
layout: prevLayout,
|
|
253
|
+
panelConstraints: panelConstraintsArray,
|
|
254
|
+
pivotIndices,
|
|
255
|
+
trigger
|
|
256
|
+
}) {
|
|
257
|
+
if (fuzzyNumbersEqual(delta, 0)) {
|
|
258
|
+
return prevLayout;
|
|
259
|
+
}
|
|
260
|
+
const nextLayout = [...prevLayout];
|
|
261
|
+
const [firstPivotIndex, secondPivotIndex] = pivotIndices;
|
|
262
|
+
assert(firstPivotIndex != null);
|
|
263
|
+
assert(secondPivotIndex != null);
|
|
264
|
+
let deltaApplied = 0;
|
|
265
|
+
|
|
266
|
+
//const DEBUG = [];
|
|
267
|
+
//DEBUG.push(`adjustLayoutByDelta() ${prevLayout.join(", ")}`);
|
|
268
|
+
//DEBUG.push(` delta: ${delta}`);
|
|
269
|
+
//DEBUG.push(` pivotIndices: ${pivotIndices.join(", ")}`);
|
|
270
|
+
//DEBUG.push(` trigger: ${trigger}`);
|
|
271
|
+
//DEBUG.push("");
|
|
272
|
+
|
|
273
|
+
// A resizing panel affects the panels before or after it.
|
|
274
|
+
//
|
|
275
|
+
// A negative delta means the panel(s) immediately after the resize handle should grow/expand by decreasing its offset.
|
|
276
|
+
// Other panels may also need to shrink/contract (and shift) to make room, depending on the min weights.
|
|
277
|
+
//
|
|
278
|
+
// A positive delta means the panel(s) immediately before the resize handle should "expand".
|
|
279
|
+
// This is accomplished by shrinking/contracting (and shifting) one or more of the panels after the resize handle.
|
|
280
|
+
|
|
281
|
+
{
|
|
229
282
|
// If this is a resize triggered by a keyboard event, our logic for expanding/collapsing is different.
|
|
230
283
|
// We no longer check the halfway threshold because this may prevent the panel from expanding at all.
|
|
231
284
|
if (trigger === "keyboard") {
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
285
|
+
{
|
|
286
|
+
// Check if we should expand a collapsed panel
|
|
287
|
+
const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
288
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
289
|
+
assert(panelConstraints);
|
|
290
|
+
|
|
291
|
+
//DEBUG.push(`edge case check 1: ${index}`);
|
|
292
|
+
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
293
|
+
if (panelConstraints.collapsible) {
|
|
294
|
+
const prevSize = prevLayout[index];
|
|
295
|
+
assert(prevSize != null);
|
|
296
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
297
|
+
assert(panelConstraints);
|
|
298
|
+
const {
|
|
299
|
+
collapsedSize = 0,
|
|
300
|
+
minSize = 0
|
|
301
|
+
} = panelConstraints;
|
|
302
|
+
if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
|
|
303
|
+
const localDelta = minSize - prevSize;
|
|
304
|
+
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
305
|
+
|
|
306
|
+
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
307
|
+
delta = delta < 0 ? 0 - localDelta : localDelta;
|
|
308
|
+
//DEBUG.push(` -> delta: ${delta}`);
|
|
250
309
|
}
|
|
310
|
+
}
|
|
251
311
|
}
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
{
|
|
315
|
+
// Check if we should collapse a panel at its minimum size
|
|
316
|
+
const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
317
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
318
|
+
assert(panelConstraints);
|
|
319
|
+
const {
|
|
320
|
+
collapsible
|
|
321
|
+
} = panelConstraints;
|
|
322
|
+
|
|
323
|
+
//DEBUG.push(`edge case check 2: ${index}`);
|
|
324
|
+
//DEBUG.push(` -> collapsible? ${collapsible}`);
|
|
325
|
+
if (collapsible) {
|
|
326
|
+
const prevSize = prevLayout[index];
|
|
327
|
+
assert(prevSize != null);
|
|
328
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
329
|
+
assert(panelConstraints);
|
|
330
|
+
const {
|
|
331
|
+
collapsedSize = 0,
|
|
332
|
+
minSize = 0
|
|
333
|
+
} = panelConstraints;
|
|
334
|
+
if (fuzzyNumbersEqual(prevSize, minSize)) {
|
|
335
|
+
const localDelta = prevSize - collapsedSize;
|
|
336
|
+
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
337
|
+
|
|
338
|
+
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
339
|
+
delta = delta < 0 ? 0 - localDelta : localDelta;
|
|
340
|
+
//DEBUG.push(` -> delta: ${delta}`);
|
|
271
341
|
}
|
|
342
|
+
}
|
|
272
343
|
}
|
|
344
|
+
}
|
|
273
345
|
}
|
|
274
|
-
{
|
|
275
|
-
// Pre-calculate max available delta in the opposite direction of our pivot.
|
|
276
|
-
// This will be the maximum amount we're allowed to expand/contract the panels in the primary direction.
|
|
277
|
-
// If this amount is less than the requested delta, adjust the requested delta.
|
|
278
|
-
// If this amount is greater than the requested delta, that's useful information too–
|
|
279
|
-
// as an expanding panel might change from collapsed to min size.
|
|
280
|
-
const increment = delta < 0 ? 1 : -1;
|
|
281
|
-
let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
282
|
-
let maxAvailableDelta = 0;
|
|
283
|
-
//DEBUG.push("pre calc...");
|
|
284
|
-
while(true){
|
|
285
|
-
const prevSize = prevLayout[index];
|
|
286
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(prevSize != null);
|
|
287
|
-
const maxSafeSize = (0, $34bbe1da7b6ad885$export$2f98edcf4006376f)({
|
|
288
|
-
panelConstraints: panelConstraintsArray,
|
|
289
|
-
panelIndex: index,
|
|
290
|
-
size: 100
|
|
291
|
-
});
|
|
292
|
-
const delta = maxSafeSize - prevSize;
|
|
293
|
-
//DEBUG.push(` ${index}: ${prevSize} -> ${maxSafeSize}`);
|
|
294
|
-
maxAvailableDelta += delta;
|
|
295
|
-
index += increment;
|
|
296
|
-
if (index < 0 || index >= panelConstraintsArray.length) break;
|
|
297
|
-
}
|
|
298
|
-
//DEBUG.push(` -> max available delta: ${maxAvailableDelta}`);
|
|
299
|
-
const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
|
|
300
|
-
delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
|
|
301
|
-
//DEBUG.push(` -> adjusted delta: ${delta}`);
|
|
302
346
|
//DEBUG.push("");
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
{
|
|
350
|
+
// Pre-calculate max available delta in the opposite direction of our pivot.
|
|
351
|
+
// This will be the maximum amount we're allowed to expand/contract the panels in the primary direction.
|
|
352
|
+
// If this amount is less than the requested delta, adjust the requested delta.
|
|
353
|
+
// If this amount is greater than the requested delta, that's useful information too–
|
|
354
|
+
// as an expanding panel might change from collapsed to min size.
|
|
355
|
+
|
|
356
|
+
const increment = delta < 0 ? 1 : -1;
|
|
357
|
+
let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
358
|
+
let maxAvailableDelta = 0;
|
|
359
|
+
|
|
360
|
+
//DEBUG.push("pre calc...");
|
|
361
|
+
while (true) {
|
|
362
|
+
const prevSize = prevLayout[index];
|
|
363
|
+
assert(prevSize != null);
|
|
364
|
+
const maxSafeSize = resizePanel({
|
|
365
|
+
panelConstraints: panelConstraintsArray,
|
|
366
|
+
panelIndex: index,
|
|
367
|
+
size: 100
|
|
368
|
+
});
|
|
369
|
+
const delta = maxSafeSize - prevSize;
|
|
370
|
+
//DEBUG.push(` ${index}: ${prevSize} -> ${maxSafeSize}`);
|
|
371
|
+
|
|
372
|
+
maxAvailableDelta += delta;
|
|
373
|
+
index += increment;
|
|
374
|
+
if (index < 0 || index >= panelConstraintsArray.length) {
|
|
375
|
+
break;
|
|
376
|
+
}
|
|
303
377
|
}
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
310
|
-
const prevSize = prevLayout[index];
|
|
311
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(prevSize != null);
|
|
312
|
-
const unsafeSize = prevSize - deltaRemaining;
|
|
313
|
-
const safeSize = (0, $34bbe1da7b6ad885$export$2f98edcf4006376f)({
|
|
314
|
-
panelConstraints: panelConstraintsArray,
|
|
315
|
-
panelIndex: index,
|
|
316
|
-
size: unsafeSize
|
|
317
|
-
});
|
|
318
|
-
if (!(0, $599218a3c5f0640f$export$db9c8bd2fae72e82)(prevSize, safeSize)) {
|
|
319
|
-
deltaApplied += prevSize - safeSize;
|
|
320
|
-
nextLayout[index] = safeSize;
|
|
321
|
-
if (deltaApplied.toPrecision(3).localeCompare(Math.abs(delta).toPrecision(3), undefined, {
|
|
322
|
-
numeric: true
|
|
323
|
-
}) >= 0) break;
|
|
324
|
-
}
|
|
325
|
-
if (delta < 0) index--;
|
|
326
|
-
else index++;
|
|
327
|
-
}
|
|
328
|
-
}
|
|
329
|
-
//DEBUG.push(`after 1: ${nextLayout.join(", ")}`);
|
|
330
|
-
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
378
|
+
|
|
379
|
+
//DEBUG.push(` -> max available delta: ${maxAvailableDelta}`);
|
|
380
|
+
const minAbsDelta = Math.min(Math.abs(delta), Math.abs(maxAvailableDelta));
|
|
381
|
+
delta = delta < 0 ? 0 - minAbsDelta : minAbsDelta;
|
|
382
|
+
//DEBUG.push(` -> adjusted delta: ${delta}`);
|
|
331
383
|
//DEBUG.push("");
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(prevSize != null);
|
|
357
|
-
const unsafeSize = prevSize + deltaRemaining;
|
|
358
|
-
const safeSize = (0, $34bbe1da7b6ad885$export$2f98edcf4006376f)({
|
|
359
|
-
panelConstraints: panelConstraintsArray,
|
|
360
|
-
panelIndex: index,
|
|
361
|
-
size: unsafeSize
|
|
362
|
-
});
|
|
363
|
-
if (!(0, $599218a3c5f0640f$export$db9c8bd2fae72e82)(prevSize, safeSize)) {
|
|
364
|
-
deltaRemaining -= safeSize - prevSize;
|
|
365
|
-
nextLayout[index] = safeSize;
|
|
366
|
-
}
|
|
367
|
-
if ((0, $599218a3c5f0640f$export$db9c8bd2fae72e82)(deltaRemaining, 0)) break;
|
|
368
|
-
if (delta > 0) index--;
|
|
369
|
-
else index++;
|
|
370
|
-
}
|
|
384
|
+
}
|
|
385
|
+
|
|
386
|
+
{
|
|
387
|
+
// Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
|
|
388
|
+
|
|
389
|
+
const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
390
|
+
let index = pivotIndex;
|
|
391
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
392
|
+
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
393
|
+
const prevSize = prevLayout[index];
|
|
394
|
+
assert(prevSize != null);
|
|
395
|
+
const unsafeSize = prevSize - deltaRemaining;
|
|
396
|
+
const safeSize = resizePanel({
|
|
397
|
+
panelConstraints: panelConstraintsArray,
|
|
398
|
+
panelIndex: index,
|
|
399
|
+
size: unsafeSize
|
|
400
|
+
});
|
|
401
|
+
if (!fuzzyNumbersEqual(prevSize, safeSize)) {
|
|
402
|
+
deltaApplied += prevSize - safeSize;
|
|
403
|
+
nextLayout[index] = safeSize;
|
|
404
|
+
if (deltaApplied.toPrecision(3).localeCompare(Math.abs(delta).toPrecision(3), undefined, {
|
|
405
|
+
numeric: true
|
|
406
|
+
}) >= 0) {
|
|
407
|
+
break;
|
|
371
408
|
}
|
|
409
|
+
}
|
|
410
|
+
if (delta < 0) {
|
|
411
|
+
index--;
|
|
412
|
+
} else {
|
|
413
|
+
index++;
|
|
414
|
+
}
|
|
372
415
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
416
|
+
}
|
|
417
|
+
//DEBUG.push(`after 1: ${nextLayout.join(", ")}`);
|
|
418
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
419
|
+
//DEBUG.push("");
|
|
420
|
+
|
|
421
|
+
// If we were unable to resize any of the panels panels, return the previous state.
|
|
422
|
+
// This will essentially bailout and ignore e.g. drags past a panel's boundaries
|
|
423
|
+
if (fuzzyNumbersEqual(deltaApplied, 0)) {
|
|
378
424
|
//console.log(DEBUG.join("\n"));
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
425
|
+
return prevLayout;
|
|
426
|
+
}
|
|
427
|
+
{
|
|
428
|
+
// Now distribute the applied delta to the panels in the other direction
|
|
429
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
430
|
+
const prevSize = prevLayout[pivotIndex];
|
|
431
|
+
assert(prevSize != null);
|
|
432
|
+
const unsafeSize = prevSize + deltaApplied;
|
|
433
|
+
const safeSize = resizePanel({
|
|
434
|
+
panelConstraints: panelConstraintsArray,
|
|
435
|
+
panelIndex: pivotIndex,
|
|
436
|
+
size: unsafeSize
|
|
437
|
+
});
|
|
384
438
|
|
|
439
|
+
// Adjust the pivot panel before, but only by the amount that surrounding panels were able to shrink/contract.
|
|
440
|
+
nextLayout[pivotIndex] = safeSize;
|
|
385
441
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
const
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
442
|
+
// Edge case where expanding or contracting one panel caused another one to change collapsed state
|
|
443
|
+
if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
|
|
444
|
+
let deltaRemaining = unsafeSize - safeSize;
|
|
445
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
446
|
+
let index = pivotIndex;
|
|
447
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
448
|
+
const prevSize = nextLayout[index];
|
|
449
|
+
assert(prevSize != null);
|
|
450
|
+
const unsafeSize = prevSize + deltaRemaining;
|
|
451
|
+
const safeSize = resizePanel({
|
|
452
|
+
panelConstraints: panelConstraintsArray,
|
|
453
|
+
panelIndex: index,
|
|
454
|
+
size: unsafeSize
|
|
455
|
+
});
|
|
456
|
+
if (!fuzzyNumbersEqual(prevSize, safeSize)) {
|
|
457
|
+
deltaRemaining -= safeSize - prevSize;
|
|
458
|
+
nextLayout[index] = safeSize;
|
|
459
|
+
}
|
|
460
|
+
if (fuzzyNumbersEqual(deltaRemaining, 0)) {
|
|
461
|
+
break;
|
|
462
|
+
}
|
|
463
|
+
if (delta > 0) {
|
|
464
|
+
index--;
|
|
400
465
|
} else {
|
|
401
|
-
|
|
402
|
-
totalMaxSize += maxSize;
|
|
466
|
+
index++;
|
|
403
467
|
}
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
valueMin: valueMin,
|
|
411
|
-
valueNow: valueNow
|
|
412
|
-
};
|
|
413
|
-
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
//DEBUG.push(`after 2: ${nextLayout.join(", ")}`);
|
|
472
|
+
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
473
|
+
//DEBUG.push("");
|
|
414
474
|
|
|
475
|
+
const totalSize = nextLayout.reduce((total, size) => size + total, 0);
|
|
476
|
+
//DEBUG.push(`total size: ${totalSize}`);
|
|
477
|
+
//console.log(DEBUG.join("\n"));
|
|
415
478
|
|
|
416
|
-
|
|
417
|
-
return
|
|
479
|
+
if (!fuzzyNumbersEqual(totalSize, 100)) {
|
|
480
|
+
return prevLayout;
|
|
481
|
+
}
|
|
482
|
+
return nextLayout;
|
|
418
483
|
}
|
|
419
484
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
485
|
+
function calculateAriaValues({
|
|
486
|
+
layout,
|
|
487
|
+
panelsArray,
|
|
488
|
+
pivotIndices
|
|
489
|
+
}) {
|
|
490
|
+
let currentMinSize = 0;
|
|
491
|
+
let currentMaxSize = 100;
|
|
492
|
+
let totalMinSize = 0;
|
|
493
|
+
let totalMaxSize = 0;
|
|
494
|
+
const firstIndex = pivotIndices[0];
|
|
495
|
+
assert(firstIndex != null);
|
|
496
|
+
|
|
497
|
+
// A panel's effective min/max sizes also need to account for other panel's sizes.
|
|
498
|
+
panelsArray.forEach((panelData, index) => {
|
|
499
|
+
const {
|
|
500
|
+
constraints
|
|
501
|
+
} = panelData;
|
|
502
|
+
const {
|
|
503
|
+
maxSize = 100,
|
|
504
|
+
minSize = 0
|
|
505
|
+
} = constraints;
|
|
506
|
+
if (index === firstIndex) {
|
|
507
|
+
currentMinSize = minSize;
|
|
508
|
+
currentMaxSize = maxSize;
|
|
509
|
+
} else {
|
|
510
|
+
totalMinSize += minSize;
|
|
511
|
+
totalMaxSize += maxSize;
|
|
512
|
+
}
|
|
513
|
+
});
|
|
514
|
+
const valueMax = Math.min(currentMaxSize, 100 - totalMinSize);
|
|
515
|
+
const valueMin = Math.max(currentMinSize, 100 - totalMaxSize);
|
|
516
|
+
const valueNow = layout[firstIndex];
|
|
517
|
+
return {
|
|
518
|
+
valueMax,
|
|
519
|
+
valueMin,
|
|
520
|
+
valueNow
|
|
521
|
+
};
|
|
425
522
|
}
|
|
426
523
|
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
const index = (0, $645e6f06f14b1fbf$export$4c92fedbbc2381ca)(groupId, dragHandleId);
|
|
430
|
-
return index != null ? [
|
|
431
|
-
index,
|
|
432
|
-
index + 1
|
|
433
|
-
] : [
|
|
434
|
-
-1,
|
|
435
|
-
-1
|
|
436
|
-
];
|
|
524
|
+
function getResizeHandleElementsForGroup(groupId) {
|
|
525
|
+
return Array.from(document.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
|
|
437
526
|
}
|
|
438
527
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
return null;
|
|
528
|
+
function getResizeHandleElementIndex(groupId, id) {
|
|
529
|
+
const handles = getResizeHandleElementsForGroup(groupId);
|
|
530
|
+
const index = handles.findIndex(handle => handle.getAttribute("data-panel-resize-handle-id") === id);
|
|
531
|
+
return index !== null && index !== void 0 ? index : null;
|
|
444
532
|
}
|
|
445
533
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
|
|
450
|
-
if (element) return element;
|
|
451
|
-
return null;
|
|
534
|
+
function determinePivotIndices(groupId, dragHandleId) {
|
|
535
|
+
const index = getResizeHandleElementIndex(groupId, dragHandleId);
|
|
536
|
+
return index != null ? [index, index + 1] : [-1, -1];
|
|
452
537
|
}
|
|
453
538
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
const index = handle ? handles.indexOf(handle) : -1;
|
|
461
|
-
var _panelsArray_index_id;
|
|
462
|
-
const idBefore = (_panelsArray_index_id = (_panelsArray_index = panelsArray[index]) === null || _panelsArray_index === void 0 ? void 0 : _panelsArray_index.id) !== null && _panelsArray_index_id !== void 0 ? _panelsArray_index_id : null;
|
|
463
|
-
var _panelsArray__id;
|
|
464
|
-
const idAfter = (_panelsArray__id = (_panelsArray_ = panelsArray[index + 1]) === null || _panelsArray_ === void 0 ? void 0 : _panelsArray_.id) !== null && _panelsArray__id !== void 0 ? _panelsArray__id : null;
|
|
465
|
-
return [
|
|
466
|
-
idBefore,
|
|
467
|
-
idAfter
|
|
468
|
-
];
|
|
539
|
+
function getPanelGroupElement(id) {
|
|
540
|
+
const element = document.querySelector(`[data-panel-group][data-panel-group-id="${id}"]`);
|
|
541
|
+
if (element) {
|
|
542
|
+
return element;
|
|
543
|
+
}
|
|
544
|
+
return null;
|
|
469
545
|
}
|
|
470
546
|
|
|
547
|
+
function getResizeHandleElement(id) {
|
|
548
|
+
const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
|
|
549
|
+
if (element) {
|
|
550
|
+
return element;
|
|
551
|
+
}
|
|
552
|
+
return null;
|
|
553
|
+
}
|
|
471
554
|
|
|
555
|
+
function getResizeHandlePanelIds(groupId, handleId, panelsArray) {
|
|
556
|
+
var _panelsArray$index$id, _panelsArray$index, _panelsArray$id, _panelsArray;
|
|
557
|
+
const handle = getResizeHandleElement(handleId);
|
|
558
|
+
const handles = getResizeHandleElementsForGroup(groupId);
|
|
559
|
+
const index = handle ? handles.indexOf(handle) : -1;
|
|
560
|
+
const idBefore = (_panelsArray$index$id = (_panelsArray$index = panelsArray[index]) === null || _panelsArray$index === void 0 ? void 0 : _panelsArray$index.id) !== null && _panelsArray$index$id !== void 0 ? _panelsArray$index$id : null;
|
|
561
|
+
const idAfter = (_panelsArray$id = (_panelsArray = panelsArray[index + 1]) === null || _panelsArray === void 0 ? void 0 : _panelsArray.id) !== null && _panelsArray$id !== void 0 ? _panelsArray$id : null;
|
|
562
|
+
return [idBefore, idAfter];
|
|
563
|
+
}
|
|
472
564
|
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
function
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
565
|
+
// https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/
|
|
566
|
+
|
|
567
|
+
function useWindowSplitterPanelGroupBehavior({
|
|
568
|
+
committedValuesRef,
|
|
569
|
+
eagerValuesRef,
|
|
570
|
+
groupId,
|
|
571
|
+
layout,
|
|
572
|
+
panelDataArray,
|
|
573
|
+
setLayout
|
|
574
|
+
}) {
|
|
575
|
+
useRef({
|
|
576
|
+
didWarnAboutMissingResizeHandle: false
|
|
577
|
+
});
|
|
578
|
+
useIsomorphicLayoutEffect(() => {
|
|
579
|
+
const resizeHandleElements = getResizeHandleElementsForGroup(groupId);
|
|
580
|
+
for (let index = 0; index < panelDataArray.length - 1; index++) {
|
|
581
|
+
const {
|
|
582
|
+
valueMax,
|
|
583
|
+
valueMin,
|
|
584
|
+
valueNow
|
|
585
|
+
} = calculateAriaValues({
|
|
586
|
+
layout,
|
|
587
|
+
panelsArray: panelDataArray,
|
|
588
|
+
pivotIndices: [index, index + 1]
|
|
589
|
+
});
|
|
590
|
+
const resizeHandleElement = resizeHandleElements[index];
|
|
591
|
+
if (resizeHandleElement == null) ; else {
|
|
592
|
+
const panelData = panelDataArray[index];
|
|
593
|
+
assert(panelData);
|
|
594
|
+
resizeHandleElement.setAttribute("aria-controls", panelData.id);
|
|
595
|
+
resizeHandleElement.setAttribute("aria-valuemax", "" + Math.round(valueMax));
|
|
596
|
+
resizeHandleElement.setAttribute("aria-valuemin", "" + Math.round(valueMin));
|
|
597
|
+
resizeHandleElement.setAttribute("aria-valuenow", valueNow != null ? "" + Math.round(valueNow) : "");
|
|
598
|
+
}
|
|
599
|
+
}
|
|
600
|
+
return () => {
|
|
601
|
+
resizeHandleElements.forEach((resizeHandleElement, index) => {
|
|
602
|
+
resizeHandleElement.removeAttribute("aria-controls");
|
|
603
|
+
resizeHandleElement.removeAttribute("aria-valuemax");
|
|
604
|
+
resizeHandleElement.removeAttribute("aria-valuemin");
|
|
605
|
+
resizeHandleElement.removeAttribute("aria-valuenow");
|
|
606
|
+
});
|
|
607
|
+
};
|
|
608
|
+
}, [groupId, layout, panelDataArray]);
|
|
609
|
+
useEffect(() => {
|
|
610
|
+
const eagerValues = eagerValuesRef.current;
|
|
611
|
+
assert(eagerValues);
|
|
612
|
+
const {
|
|
613
|
+
panelDataArray
|
|
614
|
+
} = eagerValues;
|
|
615
|
+
const groupElement = getPanelGroupElement(groupId);
|
|
616
|
+
assert(groupElement != null, `No group found for id "${groupId}"`);
|
|
617
|
+
const handles = getResizeHandleElementsForGroup(groupId);
|
|
618
|
+
assert(handles);
|
|
619
|
+
const cleanupFunctions = handles.map(handle => {
|
|
620
|
+
const handleId = handle.getAttribute("data-panel-resize-handle-id");
|
|
621
|
+
assert(handleId);
|
|
622
|
+
const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
|
|
623
|
+
if (idBefore == null || idAfter == null) {
|
|
624
|
+
return () => {};
|
|
625
|
+
}
|
|
626
|
+
const onKeyDown = event => {
|
|
627
|
+
if (event.defaultPrevented) {
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
switch (event.key) {
|
|
631
|
+
case "Enter":
|
|
632
|
+
{
|
|
633
|
+
event.preventDefault();
|
|
634
|
+
const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
|
|
635
|
+
if (index >= 0) {
|
|
500
636
|
const panelData = panelDataArray[index];
|
|
501
|
-
(
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
637
|
+
assert(panelData);
|
|
638
|
+
const size = layout[index];
|
|
639
|
+
const {
|
|
640
|
+
collapsedSize = 0,
|
|
641
|
+
collapsible,
|
|
642
|
+
minSize = 0
|
|
643
|
+
} = panelData.constraints;
|
|
644
|
+
if (size != null && collapsible) {
|
|
645
|
+
const nextLayout = adjustLayoutByDelta({
|
|
646
|
+
delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
|
|
647
|
+
layout,
|
|
648
|
+
panelConstraints: panelDataArray.map(panelData => panelData.constraints),
|
|
649
|
+
pivotIndices: determinePivotIndices(groupId, handleId),
|
|
650
|
+
trigger: "keyboard"
|
|
651
|
+
});
|
|
652
|
+
if (layout !== nextLayout) {
|
|
653
|
+
setLayout(nextLayout);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}
|
|
657
|
+
break;
|
|
506
658
|
}
|
|
507
659
|
}
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
}
|
|
517
|
-
|
|
518
|
-
layout,
|
|
519
|
-
panelDataArray
|
|
520
|
-
]);
|
|
521
|
-
(0, $6e687094f9ca8395$export$6d9c69b0de29b591)(()=>{
|
|
522
|
-
const eagerValues = eagerValuesRef.current;
|
|
523
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(eagerValues);
|
|
524
|
-
const { panelDataArray: panelDataArray } = eagerValues;
|
|
525
|
-
const groupElement = (0, $2119d3fcdfae277d$export$4e72aefa594058df)(groupId);
|
|
526
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(groupElement != null, `No group found for id "${groupId}"`);
|
|
527
|
-
const handles = (0, $ef847a5e9ce851d7$export$63eb605e437b214f)(groupId);
|
|
528
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(handles);
|
|
529
|
-
const cleanupFunctions = handles.map((handle)=>{
|
|
530
|
-
const handleId = handle.getAttribute("data-panel-resize-handle-id");
|
|
531
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(handleId);
|
|
532
|
-
const [idBefore, idAfter] = (0, $76ab5cd6038e6c4f$export$68d3a33c21dfbe27)(groupId, handleId, panelDataArray);
|
|
533
|
-
if (idBefore == null || idAfter == null) return ()=>{};
|
|
534
|
-
const onKeyDown = (event)=>{
|
|
535
|
-
if (event.defaultPrevented) return;
|
|
536
|
-
switch(event.key){
|
|
537
|
-
case "Enter":
|
|
538
|
-
{
|
|
539
|
-
event.preventDefault();
|
|
540
|
-
const index = panelDataArray.findIndex((panelData)=>panelData.id === idBefore);
|
|
541
|
-
if (index >= 0) {
|
|
542
|
-
const panelData = panelDataArray[index];
|
|
543
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(panelData);
|
|
544
|
-
const size = layout[index];
|
|
545
|
-
const { collapsedSize: collapsedSize = 0, collapsible: collapsible, minSize: minSize = 0 } = panelData.constraints;
|
|
546
|
-
if (size != null && collapsible) {
|
|
547
|
-
const nextLayout = (0, $0c110d593c066642$export$7fead5cc734d205b)({
|
|
548
|
-
delta: (0, $599218a3c5f0640f$export$db9c8bd2fae72e82)(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
|
|
549
|
-
layout: layout,
|
|
550
|
-
panelConstraints: panelDataArray.map((panelData)=>panelData.constraints),
|
|
551
|
-
pivotIndices: (0, $28ee5ac1ce973de1$export$cf92598869f99b8f)(groupId, handleId),
|
|
552
|
-
trigger: "keyboard"
|
|
553
|
-
});
|
|
554
|
-
if (layout !== nextLayout) setLayout(nextLayout);
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
break;
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
};
|
|
561
|
-
handle.addEventListener("keydown", onKeyDown);
|
|
562
|
-
return ()=>{
|
|
563
|
-
handle.removeEventListener("keydown", onKeyDown);
|
|
564
|
-
};
|
|
565
|
-
});
|
|
566
|
-
return ()=>{
|
|
567
|
-
cleanupFunctions.forEach((cleanupFunction)=>cleanupFunction());
|
|
568
|
-
};
|
|
569
|
-
}, [
|
|
570
|
-
committedValuesRef,
|
|
571
|
-
eagerValuesRef,
|
|
572
|
-
groupId,
|
|
573
|
-
layout,
|
|
574
|
-
panelDataArray,
|
|
575
|
-
setLayout
|
|
576
|
-
]);
|
|
660
|
+
};
|
|
661
|
+
handle.addEventListener("keydown", onKeyDown);
|
|
662
|
+
return () => {
|
|
663
|
+
handle.removeEventListener("keydown", onKeyDown);
|
|
664
|
+
};
|
|
665
|
+
});
|
|
666
|
+
return () => {
|
|
667
|
+
cleanupFunctions.forEach(cleanupFunction => cleanupFunction());
|
|
668
|
+
};
|
|
669
|
+
}, [committedValuesRef, eagerValuesRef, groupId, layout, panelDataArray, setLayout]);
|
|
577
670
|
}
|
|
578
671
|
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
672
|
+
function areEqual(arrayA, arrayB) {
|
|
673
|
+
if (arrayA.length !== arrayB.length) {
|
|
674
|
+
return false;
|
|
675
|
+
}
|
|
676
|
+
for (let index = 0; index < arrayA.length; index++) {
|
|
677
|
+
if (arrayA[index] !== arrayB[index]) {
|
|
678
|
+
return false;
|
|
585
679
|
}
|
|
586
|
-
|
|
680
|
+
}
|
|
681
|
+
return true;
|
|
587
682
|
}
|
|
588
683
|
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
function $601a2b3c71af04bb$export$e7bf60a870f429b0(event) {
|
|
596
|
-
return event.type === "keydown";
|
|
684
|
+
function isKeyDown(event) {
|
|
685
|
+
return event.type === "keydown";
|
|
597
686
|
}
|
|
598
|
-
function
|
|
599
|
-
|
|
687
|
+
function isMouseEvent(event) {
|
|
688
|
+
return event.type.startsWith("mouse");
|
|
600
689
|
}
|
|
601
|
-
function
|
|
602
|
-
|
|
690
|
+
function isTouchEvent(event) {
|
|
691
|
+
return event.type.startsWith("touch");
|
|
603
692
|
}
|
|
604
693
|
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
694
|
+
function getResizeEventCursorPosition(direction, event) {
|
|
695
|
+
const isHorizontal = direction === "horizontal";
|
|
696
|
+
if (isMouseEvent(event)) {
|
|
697
|
+
return isHorizontal ? event.clientX : event.clientY;
|
|
698
|
+
} else if (isTouchEvent(event)) {
|
|
699
|
+
const firstTouch = event.touches[0];
|
|
700
|
+
assert(firstTouch);
|
|
701
|
+
return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
|
|
702
|
+
} else {
|
|
703
|
+
throw Error(`Unsupported event type "${event.type}"`);
|
|
704
|
+
}
|
|
614
705
|
}
|
|
615
706
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
707
|
+
function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
|
|
708
|
+
const isHorizontal = direction === "horizontal";
|
|
709
|
+
const handleElement = getResizeHandleElement(dragHandleId);
|
|
710
|
+
assert(handleElement);
|
|
711
|
+
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
712
|
+
assert(groupId);
|
|
713
|
+
let {
|
|
714
|
+
initialCursorPosition
|
|
715
|
+
} = initialDragState;
|
|
716
|
+
const cursorPosition = getResizeEventCursorPosition(direction, event);
|
|
717
|
+
const groupElement = getPanelGroupElement(groupId);
|
|
718
|
+
assert(groupElement);
|
|
719
|
+
const groupRect = groupElement.getBoundingClientRect();
|
|
720
|
+
const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
|
|
721
|
+
const offsetPixels = cursorPosition - initialCursorPosition;
|
|
722
|
+
const offsetPercentage = offsetPixels / groupSizeInPixels * 100;
|
|
723
|
+
return offsetPercentage;
|
|
632
724
|
}
|
|
633
725
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
let movement = 0;
|
|
644
|
-
switch(event.key){
|
|
645
|
-
case "ArrowDown":
|
|
646
|
-
movement = isHorizontal ? 0 : delta;
|
|
647
|
-
break;
|
|
648
|
-
case "ArrowLeft":
|
|
649
|
-
movement = isHorizontal ? -delta : 0;
|
|
650
|
-
break;
|
|
651
|
-
case "ArrowRight":
|
|
652
|
-
movement = isHorizontal ? delta : 0;
|
|
653
|
-
break;
|
|
654
|
-
case "ArrowUp":
|
|
655
|
-
movement = isHorizontal ? 0 : -delta;
|
|
656
|
-
break;
|
|
657
|
-
case "End":
|
|
658
|
-
movement = 100;
|
|
659
|
-
break;
|
|
660
|
-
case "Home":
|
|
661
|
-
movement = -100;
|
|
662
|
-
break;
|
|
663
|
-
}
|
|
664
|
-
return movement;
|
|
726
|
+
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
|
|
727
|
+
function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
|
|
728
|
+
if (isKeyDown(event)) {
|
|
729
|
+
const isHorizontal = direction === "horizontal";
|
|
730
|
+
let delta = 0;
|
|
731
|
+
if (event.shiftKey) {
|
|
732
|
+
delta = 100;
|
|
733
|
+
} else if (keyboardResizeBy != null) {
|
|
734
|
+
delta = keyboardResizeBy;
|
|
665
735
|
} else {
|
|
666
|
-
|
|
667
|
-
|
|
736
|
+
delta = 10;
|
|
737
|
+
}
|
|
738
|
+
let movement = 0;
|
|
739
|
+
switch (event.key) {
|
|
740
|
+
case "ArrowDown":
|
|
741
|
+
movement = isHorizontal ? 0 : delta;
|
|
742
|
+
break;
|
|
743
|
+
case "ArrowLeft":
|
|
744
|
+
movement = isHorizontal ? -delta : 0;
|
|
745
|
+
break;
|
|
746
|
+
case "ArrowRight":
|
|
747
|
+
movement = isHorizontal ? delta : 0;
|
|
748
|
+
break;
|
|
749
|
+
case "ArrowUp":
|
|
750
|
+
movement = isHorizontal ? 0 : -delta;
|
|
751
|
+
break;
|
|
752
|
+
case "End":
|
|
753
|
+
movement = 100;
|
|
754
|
+
break;
|
|
755
|
+
case "Home":
|
|
756
|
+
movement = -100;
|
|
757
|
+
break;
|
|
758
|
+
}
|
|
759
|
+
return movement;
|
|
760
|
+
} else {
|
|
761
|
+
if (initialDragState == null) {
|
|
762
|
+
return 0;
|
|
668
763
|
}
|
|
764
|
+
return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
|
|
765
|
+
}
|
|
669
766
|
}
|
|
670
767
|
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
768
|
+
function calculateUnsafeDefaultLayout({
|
|
769
|
+
panelDataArray
|
|
770
|
+
}) {
|
|
771
|
+
const layout = Array(panelDataArray.length);
|
|
772
|
+
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
773
|
+
let numPanelsWithSizes = 0;
|
|
774
|
+
let remainingSize = 100;
|
|
775
|
+
|
|
776
|
+
// Distribute default sizes first
|
|
777
|
+
for (let index = 0; index < panelDataArray.length; index++) {
|
|
778
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
779
|
+
assert(panelConstraints);
|
|
780
|
+
const {
|
|
781
|
+
defaultSize
|
|
782
|
+
} = panelConstraints;
|
|
783
|
+
if (defaultSize != null) {
|
|
784
|
+
numPanelsWithSizes++;
|
|
785
|
+
layout[index] = defaultSize;
|
|
786
|
+
remainingSize -= defaultSize;
|
|
688
787
|
}
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
// Remaining size should be distributed evenly between panels without default sizes
|
|
791
|
+
for (let index = 0; index < panelDataArray.length; index++) {
|
|
792
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
793
|
+
assert(panelConstraints);
|
|
794
|
+
const {
|
|
795
|
+
defaultSize
|
|
796
|
+
} = panelConstraints;
|
|
797
|
+
if (defaultSize != null) {
|
|
798
|
+
continue;
|
|
700
799
|
}
|
|
701
|
-
|
|
800
|
+
const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
|
|
801
|
+
const size = remainingSize / numRemainingPanels;
|
|
802
|
+
numPanelsWithSizes++;
|
|
803
|
+
layout[index] = size;
|
|
804
|
+
remainingSize -= size;
|
|
805
|
+
}
|
|
806
|
+
return layout;
|
|
702
807
|
}
|
|
703
808
|
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
809
|
+
// Layout should be pre-converted into percentages
|
|
810
|
+
function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
|
|
811
|
+
layout.forEach((size, index) => {
|
|
812
|
+
const panelData = panelsArray[index];
|
|
813
|
+
assert(panelData);
|
|
814
|
+
const {
|
|
815
|
+
callbacks,
|
|
816
|
+
constraints,
|
|
817
|
+
id: panelId
|
|
818
|
+
} = panelData;
|
|
819
|
+
const {
|
|
820
|
+
collapsedSize = 0,
|
|
821
|
+
collapsible
|
|
822
|
+
} = constraints;
|
|
823
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
|
|
824
|
+
if (lastNotifiedSize == null || size !== lastNotifiedSize) {
|
|
825
|
+
panelIdToLastNotifiedSizeMap[panelId] = size;
|
|
826
|
+
const {
|
|
827
|
+
onCollapse,
|
|
828
|
+
onExpand,
|
|
829
|
+
onResize
|
|
830
|
+
} = callbacks;
|
|
831
|
+
if (onResize) {
|
|
832
|
+
onResize(size, lastNotifiedSize);
|
|
833
|
+
}
|
|
834
|
+
if (collapsible && (onCollapse || onExpand)) {
|
|
835
|
+
if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
|
|
836
|
+
onExpand();
|
|
721
837
|
}
|
|
722
|
-
|
|
838
|
+
if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
|
|
839
|
+
onCollapse();
|
|
840
|
+
}
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
});
|
|
723
844
|
}
|
|
724
845
|
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
846
|
+
function compareLayouts(a, b) {
|
|
847
|
+
if (a.length !== b.length) {
|
|
848
|
+
return false;
|
|
849
|
+
} else {
|
|
850
|
+
for (let index = 0; index < a.length; index++) {
|
|
851
|
+
if (a[index] != b[index]) {
|
|
852
|
+
return false;
|
|
853
|
+
}
|
|
730
854
|
}
|
|
731
|
-
|
|
855
|
+
}
|
|
856
|
+
return true;
|
|
732
857
|
}
|
|
733
858
|
|
|
734
|
-
|
|
735
859
|
// This method returns a number between 1 and 100 representing
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
860
|
+
|
|
861
|
+
// the % of the group's overall space this panel should occupy.
|
|
862
|
+
function computePanelFlexBoxStyle({
|
|
863
|
+
dragState,
|
|
864
|
+
layout,
|
|
865
|
+
panelData,
|
|
866
|
+
panelIndex,
|
|
867
|
+
precision = 3
|
|
868
|
+
}) {
|
|
869
|
+
const size = layout[panelIndex];
|
|
870
|
+
let flexGrow;
|
|
871
|
+
if (panelData.length === 1) {
|
|
741
872
|
flexGrow = "1";
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
873
|
+
} else if (size == null) {
|
|
874
|
+
// Initial render (before panels have registered themselves)
|
|
875
|
+
flexGrow = "1";
|
|
876
|
+
} else {
|
|
877
|
+
flexGrow = size.toPrecision(precision);
|
|
878
|
+
}
|
|
879
|
+
return {
|
|
880
|
+
flexBasis: 0,
|
|
881
|
+
flexGrow,
|
|
882
|
+
flexShrink: 1,
|
|
883
|
+
// Without this, Panel sizes may be unintentionally overridden by their content
|
|
884
|
+
overflow: "hidden",
|
|
885
|
+
// Disable pointer events inside of a panel during resize
|
|
886
|
+
// This avoid edge cases like nested iframes
|
|
887
|
+
pointerEvents: dragState !== null ? "none" : undefined
|
|
888
|
+
};
|
|
753
889
|
}
|
|
754
890
|
|
|
755
|
-
|
|
756
|
-
let
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
}
|
|
891
|
+
let currentState = null;
|
|
892
|
+
let element = null;
|
|
893
|
+
function getCursorStyle(state) {
|
|
894
|
+
switch (state) {
|
|
895
|
+
case "horizontal":
|
|
896
|
+
return "ew-resize";
|
|
897
|
+
case "horizontal-max":
|
|
898
|
+
return "w-resize";
|
|
899
|
+
case "horizontal-min":
|
|
900
|
+
return "e-resize";
|
|
901
|
+
case "vertical":
|
|
902
|
+
return "ns-resize";
|
|
903
|
+
case "vertical-max":
|
|
904
|
+
return "n-resize";
|
|
905
|
+
case "vertical-min":
|
|
906
|
+
return "s-resize";
|
|
907
|
+
}
|
|
773
908
|
}
|
|
774
|
-
function
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
909
|
+
function resetGlobalCursorStyle() {
|
|
910
|
+
if (element !== null) {
|
|
911
|
+
document.head.removeChild(element);
|
|
912
|
+
currentState = null;
|
|
913
|
+
element = null;
|
|
914
|
+
}
|
|
780
915
|
}
|
|
781
|
-
function
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
916
|
+
function setGlobalCursorStyle(state) {
|
|
917
|
+
if (currentState === state) {
|
|
918
|
+
return;
|
|
919
|
+
}
|
|
920
|
+
currentState = state;
|
|
921
|
+
const style = getCursorStyle(state);
|
|
922
|
+
if (element === null) {
|
|
923
|
+
element = document.createElement("style");
|
|
924
|
+
document.head.appendChild(element);
|
|
925
|
+
}
|
|
926
|
+
element.innerHTML = `*{cursor: ${style}!important;}`;
|
|
790
927
|
}
|
|
791
928
|
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
};
|
|
801
|
-
|
|
929
|
+
function debounce(callback, durationMs = 10) {
|
|
930
|
+
let timeoutId = null;
|
|
931
|
+
let callable = (...args) => {
|
|
932
|
+
if (timeoutId !== null) {
|
|
933
|
+
clearTimeout(timeoutId);
|
|
934
|
+
}
|
|
935
|
+
timeoutId = setTimeout(() => {
|
|
936
|
+
callback(...args);
|
|
937
|
+
}, durationMs);
|
|
938
|
+
};
|
|
939
|
+
return callable;
|
|
802
940
|
}
|
|
803
941
|
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
function $3ffc7498c21f3969$export$80bbb698e7429afe(groupId) {
|
|
807
|
-
return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
942
|
+
function getPanelElementsForGroup(groupId) {
|
|
943
|
+
return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
|
|
808
944
|
}
|
|
809
945
|
|
|
810
|
-
|
|
811
|
-
|
|
812
|
-
|
|
813
|
-
|
|
814
|
-
function
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
console.error(error);
|
|
827
|
-
storageObject.getItem = ()=>null;
|
|
828
|
-
storageObject.setItem = ()=>{};
|
|
946
|
+
// PanelGroup might be rendering in a server-side environment where localStorage is not available
|
|
947
|
+
// or on a browser with cookies/storage disabled.
|
|
948
|
+
// In either case, this function avoids accessing localStorage until needed,
|
|
949
|
+
// and avoids throwing user-visible errors.
|
|
950
|
+
function initializeDefaultStorage(storageObject) {
|
|
951
|
+
try {
|
|
952
|
+
if (typeof localStorage !== "undefined") {
|
|
953
|
+
// Bypass this check for future calls
|
|
954
|
+
storageObject.getItem = name => {
|
|
955
|
+
return localStorage.getItem(name);
|
|
956
|
+
};
|
|
957
|
+
storageObject.setItem = (name, value) => {
|
|
958
|
+
localStorage.setItem(name, value);
|
|
959
|
+
};
|
|
960
|
+
} else {
|
|
961
|
+
throw new Error("localStorage not supported in this environment");
|
|
829
962
|
}
|
|
963
|
+
} catch (error) {
|
|
964
|
+
console.error(error);
|
|
965
|
+
storageObject.getItem = () => null;
|
|
966
|
+
storageObject.setItem = () => {};
|
|
967
|
+
}
|
|
830
968
|
}
|
|
831
969
|
|
|
832
|
-
|
|
833
970
|
// Note that Panel ids might be user-provided (stable) or useId generated (non-deterministic)
|
|
834
971
|
// so they should not be used as part of the serialization key.
|
|
835
972
|
// Using the min/max size attributes should work well enough as a backup.
|
|
836
973
|
// Pre-sorting by minSize allows remembering layouts even if panels are re-ordered/dragged.
|
|
837
|
-
function
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
if (typeof parsed === "object" && parsed != null) return parsed;
|
|
850
|
-
}
|
|
851
|
-
} catch (error) {}
|
|
852
|
-
return null;
|
|
853
|
-
}
|
|
854
|
-
function $f9cb001fbb908626$export$9c80c6617f0386da(autoSaveId, panels, storage) {
|
|
855
|
-
const state = $f9cb001fbb908626$var$loadSerializedPanelGroupState(autoSaveId, storage);
|
|
856
|
-
if (state) {
|
|
857
|
-
const key = $f9cb001fbb908626$var$getSerializationKey(panels);
|
|
858
|
-
var _state_key;
|
|
859
|
-
return (_state_key = state[key]) !== null && _state_key !== void 0 ? _state_key : null;
|
|
974
|
+
function getSerializationKey(panels) {
|
|
975
|
+
return panels.map(panel => {
|
|
976
|
+
const {
|
|
977
|
+
constraints,
|
|
978
|
+
id,
|
|
979
|
+
idIsFromProps,
|
|
980
|
+
order
|
|
981
|
+
} = panel;
|
|
982
|
+
if (idIsFromProps) {
|
|
983
|
+
return id;
|
|
984
|
+
} else {
|
|
985
|
+
return `${order}:${JSON.stringify(constraints)}`;
|
|
860
986
|
}
|
|
861
|
-
|
|
987
|
+
}).sort((a, b) => a.localeCompare(b)).join(",");
|
|
862
988
|
}
|
|
863
|
-
function
|
|
864
|
-
|
|
865
|
-
const
|
|
866
|
-
|
|
867
|
-
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
|
|
989
|
+
function loadSerializedPanelGroupState(autoSaveId, storage) {
|
|
990
|
+
try {
|
|
991
|
+
const serialized = storage.getItem(`PanelGroup:sizes:${autoSaveId}`);
|
|
992
|
+
if (serialized) {
|
|
993
|
+
const parsed = JSON.parse(serialized);
|
|
994
|
+
if (typeof parsed === "object" && parsed != null) {
|
|
995
|
+
return parsed;
|
|
996
|
+
}
|
|
871
997
|
}
|
|
998
|
+
} catch (error) {}
|
|
999
|
+
return null;
|
|
1000
|
+
}
|
|
1001
|
+
function loadPanelLayout(autoSaveId, panels, storage) {
|
|
1002
|
+
const state = loadSerializedPanelGroupState(autoSaveId, storage);
|
|
1003
|
+
if (state) {
|
|
1004
|
+
var _state$key;
|
|
1005
|
+
const key = getSerializationKey(panels);
|
|
1006
|
+
return (_state$key = state[key]) !== null && _state$key !== void 0 ? _state$key : null;
|
|
1007
|
+
}
|
|
1008
|
+
return null;
|
|
1009
|
+
}
|
|
1010
|
+
function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
|
|
1011
|
+
const key = getSerializationKey(panels);
|
|
1012
|
+
const state = loadSerializedPanelGroupState(autoSaveId, storage) || {};
|
|
1013
|
+
state[key] = sizes;
|
|
1014
|
+
try {
|
|
1015
|
+
storage.setItem(`PanelGroup:sizes:${autoSaveId}`, JSON.stringify(state));
|
|
1016
|
+
} catch (error) {
|
|
1017
|
+
console.error(error);
|
|
1018
|
+
}
|
|
872
1019
|
}
|
|
873
1020
|
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
891
|
-
|
|
892
|
-
|
|
893
|
-
|
|
894
|
-
|
|
1021
|
+
// All units must be in percentages; pixel values should be pre-converted
|
|
1022
|
+
function validatePanelGroupLayout({
|
|
1023
|
+
layout: prevLayout,
|
|
1024
|
+
panelConstraints
|
|
1025
|
+
}) {
|
|
1026
|
+
const nextLayout = [...prevLayout];
|
|
1027
|
+
const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
|
|
1028
|
+
|
|
1029
|
+
// Validate layout expectations
|
|
1030
|
+
if (nextLayout.length !== panelConstraints.length) {
|
|
1031
|
+
throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
|
|
1032
|
+
} else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
|
|
1033
|
+
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1034
|
+
const unsafeSize = nextLayout[index];
|
|
1035
|
+
assert(unsafeSize != null);
|
|
1036
|
+
const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
|
|
1037
|
+
nextLayout[index] = safeSize;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1040
|
+
let remainingSize = 0;
|
|
1041
|
+
|
|
1042
|
+
// First pass: Validate the proposed layout given each panel's constraints
|
|
1043
|
+
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1044
|
+
const unsafeSize = nextLayout[index];
|
|
1045
|
+
assert(unsafeSize != null);
|
|
1046
|
+
const safeSize = resizePanel({
|
|
1047
|
+
panelConstraints,
|
|
1048
|
+
panelIndex: index,
|
|
1049
|
+
size: unsafeSize
|
|
1050
|
+
});
|
|
1051
|
+
if (unsafeSize != safeSize) {
|
|
1052
|
+
remainingSize += unsafeSize - safeSize;
|
|
1053
|
+
nextLayout[index] = safeSize;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
|
|
1057
|
+
// If there is additional, left over space, assign it to any panel(s) that permits it
|
|
1058
|
+
// (It's not worth taking multiple additional passes to evenly distribute)
|
|
1059
|
+
if (!fuzzyNumbersEqual(remainingSize, 0)) {
|
|
1060
|
+
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1061
|
+
const prevSize = nextLayout[index];
|
|
1062
|
+
assert(prevSize != null);
|
|
1063
|
+
const unsafeSize = prevSize + remainingSize;
|
|
1064
|
+
const safeSize = resizePanel({
|
|
1065
|
+
panelConstraints,
|
|
1066
|
+
panelIndex: index,
|
|
1067
|
+
size: unsafeSize
|
|
1068
|
+
});
|
|
1069
|
+
if (prevSize !== safeSize) {
|
|
1070
|
+
remainingSize -= safeSize - prevSize;
|
|
1071
|
+
nextLayout[index] = safeSize;
|
|
1072
|
+
|
|
1073
|
+
// Once we've used up the remainder, bail
|
|
1074
|
+
if (fuzzyNumbersEqual(remainingSize, 0)) {
|
|
1075
|
+
break;
|
|
895
1076
|
}
|
|
1077
|
+
}
|
|
896
1078
|
}
|
|
897
|
-
|
|
1079
|
+
}
|
|
1080
|
+
return nextLayout;
|
|
898
1081
|
}
|
|
899
1082
|
|
|
900
|
-
|
|
901
|
-
|
|
902
|
-
|
|
903
|
-
|
|
904
|
-
|
|
905
|
-
|
|
906
|
-
|
|
907
|
-
|
|
908
|
-
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
|
|
912
|
-
|
|
913
|
-
|
|
914
|
-
|
|
915
|
-
|
|
916
|
-
|
|
917
|
-
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
1083
|
+
const LOCAL_STORAGE_DEBOUNCE_INTERVAL = 100;
|
|
1084
|
+
const defaultStorage = {
|
|
1085
|
+
getItem: name => {
|
|
1086
|
+
initializeDefaultStorage(defaultStorage);
|
|
1087
|
+
return defaultStorage.getItem(name);
|
|
1088
|
+
},
|
|
1089
|
+
setItem: (name, value) => {
|
|
1090
|
+
initializeDefaultStorage(defaultStorage);
|
|
1091
|
+
defaultStorage.setItem(name, value);
|
|
1092
|
+
}
|
|
1093
|
+
};
|
|
1094
|
+
const debounceMap = {};
|
|
1095
|
+
function PanelGroupWithForwardedRef({
|
|
1096
|
+
autoSaveId = null,
|
|
1097
|
+
children,
|
|
1098
|
+
className: classNameFromProps = "",
|
|
1099
|
+
direction,
|
|
1100
|
+
forwardedRef,
|
|
1101
|
+
id: idFromProps = null,
|
|
1102
|
+
onLayout = null,
|
|
1103
|
+
keyboardResizeBy = null,
|
|
1104
|
+
storage = defaultStorage,
|
|
1105
|
+
style: styleFromProps,
|
|
1106
|
+
tagName: Type = "div",
|
|
1107
|
+
...rest
|
|
1108
|
+
}) {
|
|
1109
|
+
const groupId = useUniqueId(idFromProps);
|
|
1110
|
+
const [dragState, setDragState] = useState(null);
|
|
1111
|
+
const [layout, setLayout] = useState([]);
|
|
1112
|
+
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1113
|
+
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1114
|
+
const prevDeltaRef = useRef(0);
|
|
1115
|
+
const committedValuesRef = useRef({
|
|
1116
|
+
autoSaveId,
|
|
1117
|
+
direction,
|
|
1118
|
+
dragState,
|
|
1119
|
+
id: groupId,
|
|
1120
|
+
keyboardResizeBy,
|
|
1121
|
+
onLayout,
|
|
1122
|
+
storage
|
|
1123
|
+
});
|
|
1124
|
+
const eagerValuesRef = useRef({
|
|
1125
|
+
layout,
|
|
1126
|
+
panelDataArray: []
|
|
1127
|
+
});
|
|
1128
|
+
useRef({
|
|
1129
|
+
didLogIdAndOrderWarning: false,
|
|
1130
|
+
didLogPanelConstraintsWarning: false,
|
|
1131
|
+
prevPanelIds: []
|
|
1132
|
+
});
|
|
1133
|
+
useImperativeHandle(forwardedRef, () => ({
|
|
1134
|
+
getId: () => committedValuesRef.current.id,
|
|
1135
|
+
getLayout: () => {
|
|
1136
|
+
const {
|
|
1137
|
+
layout
|
|
1138
|
+
} = eagerValuesRef.current;
|
|
1139
|
+
return layout;
|
|
1140
|
+
},
|
|
1141
|
+
setLayout: unsafeLayout => {
|
|
1142
|
+
const {
|
|
1143
|
+
onLayout
|
|
1144
|
+
} = committedValuesRef.current;
|
|
1145
|
+
const {
|
|
1146
|
+
layout: prevLayout,
|
|
1147
|
+
panelDataArray
|
|
1148
|
+
} = eagerValuesRef.current;
|
|
1149
|
+
const safeLayout = validatePanelGroupLayout({
|
|
1150
|
+
layout: unsafeLayout,
|
|
1151
|
+
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1152
|
+
});
|
|
1153
|
+
if (!areEqual(prevLayout, safeLayout)) {
|
|
1154
|
+
setLayout(safeLayout);
|
|
1155
|
+
eagerValuesRef.current.layout = safeLayout;
|
|
1156
|
+
if (onLayout) {
|
|
1157
|
+
onLayout(safeLayout);
|
|
921
1158
|
}
|
|
1159
|
+
callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1160
|
+
}
|
|
1161
|
+
}
|
|
1162
|
+
}), []);
|
|
1163
|
+
useIsomorphicLayoutEffect(() => {
|
|
1164
|
+
committedValuesRef.current.autoSaveId = autoSaveId;
|
|
1165
|
+
committedValuesRef.current.direction = direction;
|
|
1166
|
+
committedValuesRef.current.dragState = dragState;
|
|
1167
|
+
committedValuesRef.current.id = groupId;
|
|
1168
|
+
committedValuesRef.current.onLayout = onLayout;
|
|
1169
|
+
committedValuesRef.current.storage = storage;
|
|
1170
|
+
});
|
|
1171
|
+
useWindowSplitterPanelGroupBehavior({
|
|
1172
|
+
committedValuesRef,
|
|
1173
|
+
eagerValuesRef,
|
|
1174
|
+
groupId,
|
|
1175
|
+
layout,
|
|
1176
|
+
panelDataArray: eagerValuesRef.current.panelDataArray,
|
|
1177
|
+
setLayout
|
|
1178
|
+
});
|
|
1179
|
+
useEffect(() => {
|
|
1180
|
+
const {
|
|
1181
|
+
panelDataArray
|
|
1182
|
+
} = eagerValuesRef.current;
|
|
1183
|
+
|
|
1184
|
+
// If this panel has been configured to persist sizing information, save sizes to local storage.
|
|
1185
|
+
if (autoSaveId) {
|
|
1186
|
+
if (layout.length === 0 || layout.length !== panelDataArray.length) {
|
|
1187
|
+
return;
|
|
1188
|
+
}
|
|
1189
|
+
let debouncedSave = debounceMap[autoSaveId];
|
|
1190
|
+
|
|
1191
|
+
// Limit the frequency of localStorage updates.
|
|
1192
|
+
if (debouncedSave == null) {
|
|
1193
|
+
debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1194
|
+
debounceMap[autoSaveId] = debouncedSave;
|
|
1195
|
+
}
|
|
1196
|
+
debouncedSave(autoSaveId, panelDataArray, layout, storage);
|
|
922
1197
|
}
|
|
923
|
-
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
1198
|
+
}, [autoSaveId, layout, storage]);
|
|
1199
|
+
|
|
1200
|
+
// DEV warnings
|
|
1201
|
+
useEffect(() => {
|
|
1202
|
+
});
|
|
1203
|
+
|
|
1204
|
+
// External APIs are safe to memoize via committed values ref
|
|
1205
|
+
const collapsePanel = useCallback(panelData => {
|
|
1206
|
+
const {
|
|
1207
|
+
onLayout
|
|
1208
|
+
} = committedValuesRef.current;
|
|
1209
|
+
const {
|
|
1210
|
+
layout: prevLayout,
|
|
1211
|
+
panelDataArray
|
|
1212
|
+
} = eagerValuesRef.current;
|
|
1213
|
+
if (panelData.constraints.collapsible) {
|
|
1214
|
+
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1215
|
+
const {
|
|
1216
|
+
collapsedSize = 0,
|
|
1217
|
+
panelSize,
|
|
1218
|
+
pivotIndices
|
|
1219
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1220
|
+
assert(panelSize != null);
|
|
1221
|
+
if (panelSize !== collapsedSize) {
|
|
1222
|
+
// Store size before collapse;
|
|
1223
|
+
// This is the size that gets restored if the expand() API is used.
|
|
1224
|
+
panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
|
|
1225
|
+
const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
|
|
1226
|
+
const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
|
|
1227
|
+
const nextLayout = adjustLayoutByDelta({
|
|
1228
|
+
delta,
|
|
1229
|
+
layout: prevLayout,
|
|
1230
|
+
panelConstraints: panelConstraintsArray,
|
|
1231
|
+
pivotIndices,
|
|
1232
|
+
trigger: "imperative-api"
|
|
932
1233
|
});
|
|
933
|
-
if (
|
|
934
|
-
|
|
935
|
-
|
|
1234
|
+
if (!compareLayouts(prevLayout, nextLayout)) {
|
|
1235
|
+
setLayout(nextLayout);
|
|
1236
|
+
eagerValuesRef.current.layout = nextLayout;
|
|
1237
|
+
if (onLayout) {
|
|
1238
|
+
onLayout(nextLayout);
|
|
1239
|
+
}
|
|
1240
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
936
1241
|
}
|
|
1242
|
+
}
|
|
937
1243
|
}
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
1244
|
+
}, []);
|
|
1245
|
+
|
|
1246
|
+
// External APIs are safe to memoize via committed values ref
|
|
1247
|
+
const expandPanel = useCallback(panelData => {
|
|
1248
|
+
const {
|
|
1249
|
+
onLayout
|
|
1250
|
+
} = committedValuesRef.current;
|
|
1251
|
+
const {
|
|
1252
|
+
layout: prevLayout,
|
|
1253
|
+
panelDataArray
|
|
1254
|
+
} = eagerValuesRef.current;
|
|
1255
|
+
if (panelData.constraints.collapsible) {
|
|
1256
|
+
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1257
|
+
const {
|
|
1258
|
+
collapsedSize = 0,
|
|
1259
|
+
panelSize,
|
|
1260
|
+
minSize = 0,
|
|
1261
|
+
pivotIndices
|
|
1262
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1263
|
+
if (panelSize === collapsedSize) {
|
|
1264
|
+
// Restore this panel to the size it was before it was collapsed, if possible.
|
|
1265
|
+
const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
|
|
1266
|
+
const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
|
|
1267
|
+
const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
|
|
1268
|
+
const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
|
|
1269
|
+
const nextLayout = adjustLayoutByDelta({
|
|
1270
|
+
delta,
|
|
1271
|
+
layout: prevLayout,
|
|
1272
|
+
panelConstraints: panelConstraintsArray,
|
|
1273
|
+
pivotIndices,
|
|
1274
|
+
trigger: "imperative-api"
|
|
948
1275
|
});
|
|
949
|
-
if (
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
1276
|
+
if (!compareLayouts(prevLayout, nextLayout)) {
|
|
1277
|
+
setLayout(nextLayout);
|
|
1278
|
+
eagerValuesRef.current.layout = nextLayout;
|
|
1279
|
+
if (onLayout) {
|
|
1280
|
+
onLayout(nextLayout);
|
|
1281
|
+
}
|
|
1282
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
954
1283
|
}
|
|
1284
|
+
}
|
|
955
1285
|
}
|
|
956
|
-
|
|
957
|
-
|
|
1286
|
+
}, []);
|
|
1287
|
+
|
|
1288
|
+
// External APIs are safe to memoize via committed values ref
|
|
1289
|
+
const getPanelSize = useCallback(panelData => {
|
|
1290
|
+
const {
|
|
1291
|
+
layout,
|
|
1292
|
+
panelDataArray
|
|
1293
|
+
} = eagerValuesRef.current;
|
|
1294
|
+
const {
|
|
1295
|
+
panelSize
|
|
1296
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1297
|
+
assert(panelSize != null);
|
|
1298
|
+
return panelSize;
|
|
1299
|
+
}, []);
|
|
1300
|
+
|
|
1301
|
+
// This API should never read from committedValuesRef
|
|
1302
|
+
const getPanelStyle = useCallback(panelData => {
|
|
1303
|
+
const {
|
|
1304
|
+
panelDataArray
|
|
1305
|
+
} = eagerValuesRef.current;
|
|
1306
|
+
const panelIndex = findPanelDataIndex(panelDataArray, panelData);
|
|
1307
|
+
return computePanelFlexBoxStyle({
|
|
1308
|
+
dragState,
|
|
1309
|
+
layout,
|
|
1310
|
+
panelData: panelDataArray,
|
|
1311
|
+
panelIndex
|
|
1312
|
+
});
|
|
1313
|
+
}, [dragState, layout]);
|
|
1314
|
+
|
|
1315
|
+
// External APIs are safe to memoize via committed values ref
|
|
1316
|
+
const isPanelCollapsed = useCallback(panelData => {
|
|
1317
|
+
const {
|
|
1318
|
+
layout,
|
|
1319
|
+
panelDataArray
|
|
1320
|
+
} = eagerValuesRef.current;
|
|
1321
|
+
const {
|
|
1322
|
+
collapsedSize,
|
|
1323
|
+
collapsible,
|
|
1324
|
+
panelSize
|
|
1325
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1326
|
+
return collapsible === true && panelSize === collapsedSize;
|
|
1327
|
+
}, []);
|
|
1328
|
+
|
|
1329
|
+
// External APIs are safe to memoize via committed values ref
|
|
1330
|
+
const isPanelExpanded = useCallback(panelData => {
|
|
1331
|
+
const {
|
|
1332
|
+
layout,
|
|
1333
|
+
panelDataArray
|
|
1334
|
+
} = eagerValuesRef.current;
|
|
1335
|
+
const {
|
|
1336
|
+
collapsedSize = 0,
|
|
1337
|
+
collapsible,
|
|
1338
|
+
panelSize
|
|
1339
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1340
|
+
assert(panelSize != null);
|
|
1341
|
+
return !collapsible || panelSize > collapsedSize;
|
|
1342
|
+
}, []);
|
|
1343
|
+
const registerPanel = useCallback(panelData => {
|
|
1344
|
+
const {
|
|
1345
|
+
autoSaveId,
|
|
1346
|
+
id: groupId,
|
|
1347
|
+
onLayout,
|
|
1348
|
+
storage
|
|
1349
|
+
} = committedValuesRef.current;
|
|
1350
|
+
const {
|
|
1351
|
+
layout: prevLayout,
|
|
1352
|
+
panelDataArray
|
|
1353
|
+
} = eagerValuesRef.current;
|
|
1354
|
+
|
|
1355
|
+
// HACK
|
|
1356
|
+
// This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
|
|
1357
|
+
// see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
|
|
1358
|
+
const index = findPanelDataIndex(panelDataArray, panelData);
|
|
1359
|
+
if (index >= 0) {
|
|
1360
|
+
if (panelData.idIsFromProps) {
|
|
1361
|
+
console.warn(`Panel with id "${panelData.id}" registered twice`);
|
|
1362
|
+
} else {
|
|
1363
|
+
console.warn(`Panel registered twice`);
|
|
1364
|
+
}
|
|
1365
|
+
return;
|
|
1366
|
+
}
|
|
1367
|
+
panelDataArray.push(panelData);
|
|
1368
|
+
panelDataArray.sort((panelA, panelB) => {
|
|
1369
|
+
const orderA = panelA.order;
|
|
1370
|
+
const orderB = panelB.order;
|
|
1371
|
+
if (orderA == null && orderB == null) {
|
|
1372
|
+
return 0;
|
|
1373
|
+
} else if (orderA == null) {
|
|
1374
|
+
return -1;
|
|
1375
|
+
} else if (orderB == null) {
|
|
1376
|
+
return 1;
|
|
1377
|
+
} else {
|
|
1378
|
+
return orderA - orderB;
|
|
1379
|
+
}
|
|
1380
|
+
});
|
|
958
1381
|
|
|
1382
|
+
// Wait until all panels have registered before we try to compute layout;
|
|
1383
|
+
// doing it earlier is both wasteful and may trigger misleading warnings in development mode.
|
|
1384
|
+
const panelElements = getPanelElementsForGroup(groupId);
|
|
1385
|
+
if (panelElements.length !== panelDataArray.length) {
|
|
1386
|
+
return;
|
|
1387
|
+
}
|
|
959
1388
|
|
|
1389
|
+
// If this panel has been configured to persist sizing information,
|
|
1390
|
+
// default size should be restored from local storage if possible.
|
|
1391
|
+
let unsafeLayout = null;
|
|
1392
|
+
if (autoSaveId) {
|
|
1393
|
+
unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
|
|
1394
|
+
}
|
|
1395
|
+
if (unsafeLayout == null) {
|
|
1396
|
+
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1397
|
+
panelDataArray
|
|
1398
|
+
});
|
|
1399
|
+
}
|
|
960
1400
|
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
}
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1401
|
+
// Validate even saved layouts in case something has changed since last render
|
|
1402
|
+
// e.g. for pixel groups, this could be the size of the window
|
|
1403
|
+
const nextLayout = validatePanelGroupLayout({
|
|
1404
|
+
layout: unsafeLayout,
|
|
1405
|
+
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1406
|
+
});
|
|
1407
|
+
|
|
1408
|
+
// Offscreen mode makes this a bit weird;
|
|
1409
|
+
// Panels unregister when hidden and re-register when shown again,
|
|
1410
|
+
// but the overall layout doesn't change between these two cases.
|
|
1411
|
+
setLayout(nextLayout);
|
|
1412
|
+
eagerValuesRef.current.layout = nextLayout;
|
|
1413
|
+
if (!areEqual(prevLayout, nextLayout)) {
|
|
1414
|
+
if (onLayout) {
|
|
1415
|
+
onLayout(nextLayout);
|
|
1416
|
+
}
|
|
1417
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
970
1418
|
}
|
|
971
|
-
};
|
|
972
|
-
const
|
|
973
|
-
function
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
const panelSizeBeforeCollapseRef = (0, $6e687094f9ca8395$export$b8f5890fc79d6aca)(new Map());
|
|
979
|
-
const prevDeltaRef = (0, $6e687094f9ca8395$export$b8f5890fc79d6aca)(0);
|
|
980
|
-
const committedValuesRef = (0, $6e687094f9ca8395$export$b8f5890fc79d6aca)({
|
|
981
|
-
autoSaveId: autoSaveId,
|
|
982
|
-
direction: direction,
|
|
983
|
-
dragState: dragState,
|
|
1419
|
+
}, []);
|
|
1420
|
+
const registerResizeHandle = useCallback(dragHandleId => {
|
|
1421
|
+
return function resizeHandler(event) {
|
|
1422
|
+
event.preventDefault();
|
|
1423
|
+
const {
|
|
1424
|
+
direction,
|
|
1425
|
+
dragState,
|
|
984
1426
|
id: groupId,
|
|
985
|
-
keyboardResizeBy
|
|
986
|
-
onLayout
|
|
987
|
-
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
setLayout: setLayout
|
|
1034
|
-
});
|
|
1035
|
-
(0, $6e687094f9ca8395$export$6d9c69b0de29b591)(()=>{
|
|
1036
|
-
const { panelDataArray: panelDataArray } = eagerValuesRef.current;
|
|
1037
|
-
// If this panel has been configured to persist sizing information, save sizes to local storage.
|
|
1038
|
-
if (autoSaveId) {
|
|
1039
|
-
if (layout.length === 0 || layout.length !== panelDataArray.length) return;
|
|
1040
|
-
let debouncedSave = $cec4cafe75f3db78$var$debounceMap[autoSaveId];
|
|
1041
|
-
// Limit the frequency of localStorage updates.
|
|
1042
|
-
if (debouncedSave == null) {
|
|
1043
|
-
debouncedSave = (0, $2e8572579e31d898$export$2e2bcd8739ae039)((0, $f9cb001fbb908626$export$af183b313c61be4f), $cec4cafe75f3db78$var$LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1044
|
-
$cec4cafe75f3db78$var$debounceMap[autoSaveId] = debouncedSave;
|
|
1427
|
+
keyboardResizeBy,
|
|
1428
|
+
onLayout
|
|
1429
|
+
} = committedValuesRef.current;
|
|
1430
|
+
const {
|
|
1431
|
+
layout: prevLayout,
|
|
1432
|
+
panelDataArray
|
|
1433
|
+
} = eagerValuesRef.current;
|
|
1434
|
+
const {
|
|
1435
|
+
initialLayout
|
|
1436
|
+
} = dragState !== null && dragState !== void 0 ? dragState : {};
|
|
1437
|
+
const pivotIndices = determinePivotIndices(groupId, dragHandleId);
|
|
1438
|
+
let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
|
|
1439
|
+
if (delta === 0) {
|
|
1440
|
+
return;
|
|
1441
|
+
}
|
|
1442
|
+
|
|
1443
|
+
// Support RTL layouts
|
|
1444
|
+
const isHorizontal = direction === "horizontal";
|
|
1445
|
+
if (document.dir === "rtl" && isHorizontal) {
|
|
1446
|
+
delta = -delta;
|
|
1447
|
+
}
|
|
1448
|
+
const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
|
|
1449
|
+
const nextLayout = adjustLayoutByDelta({
|
|
1450
|
+
delta,
|
|
1451
|
+
layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
|
|
1452
|
+
panelConstraints,
|
|
1453
|
+
pivotIndices,
|
|
1454
|
+
trigger: isKeyDown(event) ? "keyboard" : "mouse-or-touch"
|
|
1455
|
+
});
|
|
1456
|
+
const layoutChanged = !compareLayouts(prevLayout, nextLayout);
|
|
1457
|
+
|
|
1458
|
+
// Only update the cursor for layout changes triggered by touch/mouse events (not keyboard)
|
|
1459
|
+
// Update the cursor even if the layout hasn't changed (we may need to show an invalid cursor state)
|
|
1460
|
+
if (isMouseEvent(event) || isTouchEvent(event)) {
|
|
1461
|
+
// Watch for multiple subsequent deltas; this might occur for tiny cursor movements.
|
|
1462
|
+
// In this case, Panel sizes might not change–
|
|
1463
|
+
// but updating cursor in this scenario would cause a flicker.
|
|
1464
|
+
if (prevDeltaRef.current != delta) {
|
|
1465
|
+
prevDeltaRef.current = delta;
|
|
1466
|
+
if (!layoutChanged) {
|
|
1467
|
+
// If the pointer has moved too far to resize the panel any further,
|
|
1468
|
+
// update the cursor style for a visual clue.
|
|
1469
|
+
// This mimics VS Code behavior.
|
|
1470
|
+
|
|
1471
|
+
if (isHorizontal) {
|
|
1472
|
+
setGlobalCursorStyle(delta < 0 ? "horizontal-min" : "horizontal-max");
|
|
1473
|
+
} else {
|
|
1474
|
+
setGlobalCursorStyle(delta < 0 ? "vertical-min" : "vertical-max");
|
|
1045
1475
|
}
|
|
1046
|
-
|
|
1476
|
+
} else {
|
|
1477
|
+
// Reset the cursor style to the the normal resize cursor.
|
|
1478
|
+
setGlobalCursorStyle(isHorizontal ? "horizontal" : "vertical");
|
|
1479
|
+
}
|
|
1047
1480
|
}
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
(0, $6e687094f9ca8395$export$6d9c69b0de29b591)(()=>{
|
|
1055
|
-
if (0, $95f7f0116122f6f8$export$df77466336fe5355) {
|
|
1056
|
-
const { panelDataArray: panelDataArray } = eagerValuesRef.current;
|
|
1057
|
-
const { didLogIdAndOrderWarning: didLogIdAndOrderWarning, didLogPanelConstraintsWarning: didLogPanelConstraintsWarning, prevPanelIds: prevPanelIds } = devWarningsRef.current;
|
|
1058
|
-
if (!didLogIdAndOrderWarning) {
|
|
1059
|
-
const panelIds = panelDataArray.map(({ id: id })=>id);
|
|
1060
|
-
devWarningsRef.current.prevPanelIds = panelIds;
|
|
1061
|
-
const panelsHaveChanged = prevPanelIds.length > 0 && !(0, $d31ef7445a11a6c5$export$b141efd0b0fb9174)(prevPanelIds, panelIds);
|
|
1062
|
-
if (panelsHaveChanged) {
|
|
1063
|
-
if (panelDataArray.find(({ idIsFromProps: idIsFromProps, order: order })=>!idIsFromProps || order == null)) {
|
|
1064
|
-
devWarningsRef.current.didLogIdAndOrderWarning = true;
|
|
1065
|
-
console.warn(`WARNING: Panel id and order props recommended when panels are dynamically rendered`);
|
|
1066
|
-
}
|
|
1067
|
-
}
|
|
1068
|
-
}
|
|
1069
|
-
if (!didLogPanelConstraintsWarning) {
|
|
1070
|
-
const panelConstraints = panelDataArray.map((panelData)=>panelData.constraints);
|
|
1071
|
-
for(let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++){
|
|
1072
|
-
const panelData = panelDataArray[panelIndex];
|
|
1073
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(panelData);
|
|
1074
|
-
const isValid = (0, $0531c662514b8c6a$export$d00cfefa2c395b39)({
|
|
1075
|
-
panelConstraints: panelConstraints,
|
|
1076
|
-
panelId: panelData.id,
|
|
1077
|
-
panelIndex: panelIndex
|
|
1078
|
-
});
|
|
1079
|
-
if (!isValid) {
|
|
1080
|
-
devWarningsRef.current.didLogPanelConstraintsWarning = true;
|
|
1081
|
-
break;
|
|
1082
|
-
}
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1481
|
+
}
|
|
1482
|
+
if (layoutChanged) {
|
|
1483
|
+
setLayout(nextLayout);
|
|
1484
|
+
eagerValuesRef.current.layout = nextLayout;
|
|
1485
|
+
if (onLayout) {
|
|
1486
|
+
onLayout(nextLayout);
|
|
1085
1487
|
}
|
|
1488
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1489
|
+
}
|
|
1490
|
+
};
|
|
1491
|
+
}, []);
|
|
1492
|
+
|
|
1493
|
+
// External APIs are safe to memoize via committed values ref
|
|
1494
|
+
const resizePanel = useCallback((panelData, unsafePanelSize) => {
|
|
1495
|
+
const {
|
|
1496
|
+
onLayout
|
|
1497
|
+
} = committedValuesRef.current;
|
|
1498
|
+
const {
|
|
1499
|
+
layout: prevLayout,
|
|
1500
|
+
panelDataArray
|
|
1501
|
+
} = eagerValuesRef.current;
|
|
1502
|
+
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1503
|
+
const {
|
|
1504
|
+
panelSize,
|
|
1505
|
+
pivotIndices
|
|
1506
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1507
|
+
assert(panelSize != null);
|
|
1508
|
+
const isLastPanel = findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
|
|
1509
|
+
const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
|
|
1510
|
+
const nextLayout = adjustLayoutByDelta({
|
|
1511
|
+
delta,
|
|
1512
|
+
layout: prevLayout,
|
|
1513
|
+
panelConstraints: panelConstraintsArray,
|
|
1514
|
+
pivotIndices,
|
|
1515
|
+
trigger: "imperative-api"
|
|
1086
1516
|
});
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
});
|
|
1163
|
-
}, [
|
|
1164
|
-
dragState,
|
|
1165
|
-
layout
|
|
1166
|
-
]);
|
|
1167
|
-
// External APIs are safe to memoize via committed values ref
|
|
1168
|
-
const isPanelCollapsed = (0, $6e687094f9ca8395$export$35808ee640e87ca7)((panelData)=>{
|
|
1169
|
-
const { layout: layout, panelDataArray: panelDataArray } = eagerValuesRef.current;
|
|
1170
|
-
const { collapsedSize: collapsedSize, collapsible: collapsible, panelSize: panelSize } = $cec4cafe75f3db78$var$panelDataHelper(panelDataArray, panelData, layout);
|
|
1171
|
-
return collapsible === true && panelSize === collapsedSize;
|
|
1172
|
-
}, []);
|
|
1173
|
-
// External APIs are safe to memoize via committed values ref
|
|
1174
|
-
const isPanelExpanded = (0, $6e687094f9ca8395$export$35808ee640e87ca7)((panelData)=>{
|
|
1175
|
-
const { layout: layout, panelDataArray: panelDataArray } = eagerValuesRef.current;
|
|
1176
|
-
const { collapsedSize: collapsedSize = 0, collapsible: collapsible, panelSize: panelSize } = $cec4cafe75f3db78$var$panelDataHelper(panelDataArray, panelData, layout);
|
|
1177
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(panelSize != null);
|
|
1178
|
-
return !collapsible || panelSize > collapsedSize;
|
|
1179
|
-
}, []);
|
|
1180
|
-
const registerPanel = (0, $6e687094f9ca8395$export$35808ee640e87ca7)((panelData)=>{
|
|
1181
|
-
const { autoSaveId: autoSaveId, id: groupId, onLayout: onLayout, storage: storage } = committedValuesRef.current;
|
|
1182
|
-
const { layout: prevLayout, panelDataArray: panelDataArray } = eagerValuesRef.current;
|
|
1183
|
-
// HACK
|
|
1184
|
-
// This appears to be triggered by some React Suspense+Offscreen+StrictMode bug;
|
|
1185
|
-
// see app.replay.io/recording/17b6e11d-4500-4173-b23d-61dfd141fed1
|
|
1186
|
-
const index = $cec4cafe75f3db78$var$findPanelDataIndex(panelDataArray, panelData);
|
|
1187
|
-
if (index >= 0) {
|
|
1188
|
-
if (panelData.idIsFromProps) console.warn(`Panel with id "${panelData.id}" registered twice`);
|
|
1189
|
-
else console.warn(`Panel registered twice`);
|
|
1190
|
-
return;
|
|
1517
|
+
if (!compareLayouts(prevLayout, nextLayout)) {
|
|
1518
|
+
setLayout(nextLayout);
|
|
1519
|
+
eagerValuesRef.current.layout = nextLayout;
|
|
1520
|
+
if (onLayout) {
|
|
1521
|
+
onLayout(nextLayout);
|
|
1522
|
+
}
|
|
1523
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1524
|
+
}
|
|
1525
|
+
}, []);
|
|
1526
|
+
const startDragging = useCallback((dragHandleId, event) => {
|
|
1527
|
+
const {
|
|
1528
|
+
direction
|
|
1529
|
+
} = committedValuesRef.current;
|
|
1530
|
+
const {
|
|
1531
|
+
layout
|
|
1532
|
+
} = eagerValuesRef.current;
|
|
1533
|
+
const handleElement = getResizeHandleElement(dragHandleId);
|
|
1534
|
+
assert(handleElement);
|
|
1535
|
+
const initialCursorPosition = getResizeEventCursorPosition(direction, event);
|
|
1536
|
+
setDragState({
|
|
1537
|
+
dragHandleId,
|
|
1538
|
+
dragHandleRect: handleElement.getBoundingClientRect(),
|
|
1539
|
+
initialCursorPosition,
|
|
1540
|
+
initialLayout: layout
|
|
1541
|
+
});
|
|
1542
|
+
}, []);
|
|
1543
|
+
const stopDragging = useCallback(() => {
|
|
1544
|
+
resetGlobalCursorStyle();
|
|
1545
|
+
setDragState(null);
|
|
1546
|
+
}, []);
|
|
1547
|
+
const unregisterPanelRef = useRef({
|
|
1548
|
+
pendingPanelIds: new Set(),
|
|
1549
|
+
timeout: null
|
|
1550
|
+
});
|
|
1551
|
+
const unregisterPanel = useCallback(panelData => {
|
|
1552
|
+
const {
|
|
1553
|
+
onLayout
|
|
1554
|
+
} = committedValuesRef.current;
|
|
1555
|
+
const {
|
|
1556
|
+
layout: prevLayout,
|
|
1557
|
+
panelDataArray
|
|
1558
|
+
} = eagerValuesRef.current;
|
|
1559
|
+
const index = findPanelDataIndex(panelDataArray, panelData);
|
|
1560
|
+
if (index >= 0) {
|
|
1561
|
+
panelDataArray.splice(index, 1);
|
|
1562
|
+
unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
|
|
1563
|
+
}
|
|
1564
|
+
if (unregisterPanelRef.current.timeout != null) {
|
|
1565
|
+
clearTimeout(unregisterPanelRef.current.timeout);
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
// Batch panel unmounts so that we only calculate layout once;
|
|
1569
|
+
// This is more efficient and avoids misleading warnings in development mode.
|
|
1570
|
+
// We can't check the DOM to detect this because Panel elements have not yet been removed.
|
|
1571
|
+
unregisterPanelRef.current.timeout = setTimeout(() => {
|
|
1572
|
+
const {
|
|
1573
|
+
pendingPanelIds
|
|
1574
|
+
} = unregisterPanelRef.current;
|
|
1575
|
+
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1576
|
+
|
|
1577
|
+
// TRICKY
|
|
1578
|
+
// Strict effects mode
|
|
1579
|
+
let unmountDueToStrictMode = false;
|
|
1580
|
+
pendingPanelIds.forEach(panelId => {
|
|
1581
|
+
pendingPanelIds.delete(panelId);
|
|
1582
|
+
if (panelDataArray.find(({
|
|
1583
|
+
id
|
|
1584
|
+
}) => id === panelId) != null) {
|
|
1585
|
+
unmountDueToStrictMode = true;
|
|
1586
|
+
} else {
|
|
1587
|
+
// TRICKY
|
|
1588
|
+
// When a panel is removed from the group, we should delete the most recent prev-size entry for it.
|
|
1589
|
+
// If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
|
|
1590
|
+
// Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
|
|
1591
|
+
delete panelIdToLastNotifiedSizeMap[panelId];
|
|
1191
1592
|
}
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1202
|
-
|
|
1203
|
-
|
|
1204
|
-
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
});
|
|
1212
|
-
// Validate even saved layouts in case something has changed since last render
|
|
1213
|
-
// e.g. for pixel groups, this could be the size of the window
|
|
1214
|
-
const nextLayout = (0, $aa44a0a11da9fc89$export$64432a52a1035c18)({
|
|
1215
|
-
layout: unsafeLayout,
|
|
1216
|
-
panelConstraints: panelDataArray.map((panelData)=>panelData.constraints)
|
|
1217
|
-
});
|
|
1218
|
-
// Offscreen mode makes this a bit weird;
|
|
1219
|
-
// Panels unregister when hidden and re-register when shown again,
|
|
1220
|
-
// but the overall layout doesn't change between these two cases.
|
|
1593
|
+
});
|
|
1594
|
+
if (unmountDueToStrictMode) {
|
|
1595
|
+
return;
|
|
1596
|
+
}
|
|
1597
|
+
if (panelDataArray.length === 0) {
|
|
1598
|
+
// The group is unmounting; skip layout calculation.
|
|
1599
|
+
return;
|
|
1600
|
+
}
|
|
1601
|
+
let unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1602
|
+
panelDataArray
|
|
1603
|
+
});
|
|
1604
|
+
|
|
1605
|
+
// Validate even saved layouts in case something has changed since last render
|
|
1606
|
+
// e.g. for pixel groups, this could be the size of the window
|
|
1607
|
+
const nextLayout = validatePanelGroupLayout({
|
|
1608
|
+
layout: unsafeLayout,
|
|
1609
|
+
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1610
|
+
});
|
|
1611
|
+
if (!areEqual(prevLayout, nextLayout)) {
|
|
1221
1612
|
setLayout(nextLayout);
|
|
1222
1613
|
eagerValuesRef.current.layout = nextLayout;
|
|
1223
|
-
if (
|
|
1224
|
-
|
|
1225
|
-
(0, $3c80a05711c0e5f5$export$b8e48269e4faa934)(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1614
|
+
if (onLayout) {
|
|
1615
|
+
onLayout(nextLayout);
|
|
1226
1616
|
}
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1234
|
-
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1251
|
-
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
|
|
1262
|
-
|
|
1263
|
-
|
|
1264
|
-
|
|
1265
|
-
|
|
1266
|
-
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
if (onLayout) onLayout(nextLayout);
|
|
1271
|
-
(0, $3c80a05711c0e5f5$export$b8e48269e4faa934)(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1272
|
-
}
|
|
1273
|
-
};
|
|
1274
|
-
}, []);
|
|
1275
|
-
// External APIs are safe to memoize via committed values ref
|
|
1276
|
-
const resizePanel = (0, $6e687094f9ca8395$export$35808ee640e87ca7)((panelData, unsafePanelSize)=>{
|
|
1277
|
-
const { onLayout: onLayout } = committedValuesRef.current;
|
|
1278
|
-
const { layout: prevLayout, panelDataArray: panelDataArray } = eagerValuesRef.current;
|
|
1279
|
-
const panelConstraintsArray = panelDataArray.map((panelData)=>panelData.constraints);
|
|
1280
|
-
const { panelSize: panelSize, pivotIndices: pivotIndices } = $cec4cafe75f3db78$var$panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1281
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(panelSize != null);
|
|
1282
|
-
const isLastPanel = $cec4cafe75f3db78$var$findPanelDataIndex(panelDataArray, panelData) === panelDataArray.length - 1;
|
|
1283
|
-
const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
|
|
1284
|
-
const nextLayout = (0, $0c110d593c066642$export$7fead5cc734d205b)({
|
|
1285
|
-
delta: delta,
|
|
1286
|
-
layout: prevLayout,
|
|
1287
|
-
panelConstraints: panelConstraintsArray,
|
|
1288
|
-
pivotIndices: pivotIndices,
|
|
1289
|
-
trigger: "imperative-api"
|
|
1290
|
-
});
|
|
1291
|
-
if (!(0, $11f1460202e20b00$export$a10903e2e57656c1)(prevLayout, nextLayout)) {
|
|
1292
|
-
setLayout(nextLayout);
|
|
1293
|
-
eagerValuesRef.current.layout = nextLayout;
|
|
1294
|
-
if (onLayout) onLayout(nextLayout);
|
|
1295
|
-
(0, $3c80a05711c0e5f5$export$b8e48269e4faa934)(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1296
|
-
}
|
|
1297
|
-
}, []);
|
|
1298
|
-
const startDragging = (0, $6e687094f9ca8395$export$35808ee640e87ca7)((dragHandleId, event)=>{
|
|
1299
|
-
const { direction: direction } = committedValuesRef.current;
|
|
1300
|
-
const { layout: layout } = eagerValuesRef.current;
|
|
1301
|
-
const handleElement = (0, $58762ed3a79a85a2$export$4c5229c874a62620)(dragHandleId);
|
|
1302
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(handleElement);
|
|
1303
|
-
const initialCursorPosition = (0, $9b677018bf1ac728$export$ae0c59ca751ba81d)(direction, event);
|
|
1304
|
-
setDragState({
|
|
1305
|
-
dragHandleId: dragHandleId,
|
|
1306
|
-
dragHandleRect: handleElement.getBoundingClientRect(),
|
|
1307
|
-
initialCursorPosition: initialCursorPosition,
|
|
1308
|
-
initialLayout: layout
|
|
1309
|
-
});
|
|
1310
|
-
}, []);
|
|
1311
|
-
const stopDragging = (0, $6e687094f9ca8395$export$35808ee640e87ca7)(()=>{
|
|
1312
|
-
(0, $08745f7373322b05$export$b61932ee18f96e08)();
|
|
1313
|
-
setDragState(null);
|
|
1314
|
-
}, []);
|
|
1315
|
-
const unregisterPanelRef = (0, $6e687094f9ca8395$export$b8f5890fc79d6aca)({
|
|
1316
|
-
pendingPanelIds: new Set(),
|
|
1317
|
-
timeout: null
|
|
1318
|
-
});
|
|
1319
|
-
const unregisterPanel = (0, $6e687094f9ca8395$export$35808ee640e87ca7)((panelData)=>{
|
|
1320
|
-
const { onLayout: onLayout } = committedValuesRef.current;
|
|
1321
|
-
const { layout: prevLayout, panelDataArray: panelDataArray } = eagerValuesRef.current;
|
|
1322
|
-
const index = $cec4cafe75f3db78$var$findPanelDataIndex(panelDataArray, panelData);
|
|
1323
|
-
if (index >= 0) {
|
|
1324
|
-
panelDataArray.splice(index, 1);
|
|
1325
|
-
unregisterPanelRef.current.pendingPanelIds.add(panelData.id);
|
|
1326
|
-
}
|
|
1327
|
-
if (unregisterPanelRef.current.timeout != null) clearTimeout(unregisterPanelRef.current.timeout);
|
|
1328
|
-
// Batch panel unmounts so that we only calculate layout once;
|
|
1329
|
-
// This is more efficient and avoids misleading warnings in development mode.
|
|
1330
|
-
// We can't check the DOM to detect this because Panel elements have not yet been removed.
|
|
1331
|
-
unregisterPanelRef.current.timeout = setTimeout(()=>{
|
|
1332
|
-
const { pendingPanelIds: pendingPanelIds } = unregisterPanelRef.current;
|
|
1333
|
-
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1334
|
-
// TRICKY
|
|
1335
|
-
// Strict effects mode
|
|
1336
|
-
let unmountDueToStrictMode = false;
|
|
1337
|
-
pendingPanelIds.forEach((panelId)=>{
|
|
1338
|
-
pendingPanelIds.delete(panelId);
|
|
1339
|
-
if (panelDataArray.find(({ id: id })=>id === panelId) != null) unmountDueToStrictMode = true;
|
|
1340
|
-
else // TRICKY
|
|
1341
|
-
// When a panel is removed from the group, we should delete the most recent prev-size entry for it.
|
|
1342
|
-
// If we don't do this, then a conditionally rendered panel might not call onResize when it's re-mounted.
|
|
1343
|
-
// Strict effects mode makes this tricky though because all panels will be registered, unregistered, then re-registered on mount.
|
|
1344
|
-
delete panelIdToLastNotifiedSizeMap[panelId];
|
|
1345
|
-
});
|
|
1346
|
-
if (unmountDueToStrictMode) return;
|
|
1347
|
-
if (panelDataArray.length === 0) // The group is unmounting; skip layout calculation.
|
|
1348
|
-
return;
|
|
1349
|
-
let unsafeLayout = (0, $17c359958d4c9de7$export$47337a21c443778e)({
|
|
1350
|
-
panelDataArray: panelDataArray
|
|
1351
|
-
});
|
|
1352
|
-
// Validate even saved layouts in case something has changed since last render
|
|
1353
|
-
// e.g. for pixel groups, this could be the size of the window
|
|
1354
|
-
const nextLayout = (0, $aa44a0a11da9fc89$export$64432a52a1035c18)({
|
|
1355
|
-
layout: unsafeLayout,
|
|
1356
|
-
panelConstraints: panelDataArray.map((panelData)=>panelData.constraints)
|
|
1357
|
-
});
|
|
1358
|
-
if (!(0, $d31ef7445a11a6c5$export$b141efd0b0fb9174)(prevLayout, nextLayout)) {
|
|
1359
|
-
setLayout(nextLayout);
|
|
1360
|
-
eagerValuesRef.current.layout = nextLayout;
|
|
1361
|
-
if (onLayout) onLayout(nextLayout);
|
|
1362
|
-
(0, $3c80a05711c0e5f5$export$b8e48269e4faa934)(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1363
|
-
}
|
|
1364
|
-
}, 0);
|
|
1365
|
-
}, []);
|
|
1366
|
-
const context = (0, $6e687094f9ca8395$export$1538c33de8887b59)(()=>({
|
|
1367
|
-
collapsePanel: collapsePanel,
|
|
1368
|
-
direction: direction,
|
|
1369
|
-
dragState: dragState,
|
|
1370
|
-
expandPanel: expandPanel,
|
|
1371
|
-
getPanelSize: getPanelSize,
|
|
1372
|
-
getPanelStyle: getPanelStyle,
|
|
1373
|
-
groupId: groupId,
|
|
1374
|
-
isPanelCollapsed: isPanelCollapsed,
|
|
1375
|
-
isPanelExpanded: isPanelExpanded,
|
|
1376
|
-
registerPanel: registerPanel,
|
|
1377
|
-
registerResizeHandle: registerResizeHandle,
|
|
1378
|
-
resizePanel: resizePanel,
|
|
1379
|
-
startDragging: startDragging,
|
|
1380
|
-
stopDragging: stopDragging,
|
|
1381
|
-
unregisterPanel: unregisterPanel
|
|
1382
|
-
}), [
|
|
1383
|
-
collapsePanel,
|
|
1384
|
-
dragState,
|
|
1385
|
-
direction,
|
|
1386
|
-
expandPanel,
|
|
1387
|
-
getPanelSize,
|
|
1388
|
-
getPanelStyle,
|
|
1389
|
-
groupId,
|
|
1390
|
-
isPanelCollapsed,
|
|
1391
|
-
isPanelExpanded,
|
|
1392
|
-
registerPanel,
|
|
1393
|
-
registerResizeHandle,
|
|
1394
|
-
resizePanel,
|
|
1395
|
-
startDragging,
|
|
1396
|
-
stopDragging,
|
|
1397
|
-
unregisterPanel
|
|
1398
|
-
]);
|
|
1399
|
-
const style = {
|
|
1400
|
-
display: "flex",
|
|
1401
|
-
flexDirection: direction === "horizontal" ? "row" : "column",
|
|
1402
|
-
height: "100%",
|
|
1403
|
-
overflow: "hidden",
|
|
1404
|
-
width: "100%"
|
|
1405
|
-
};
|
|
1406
|
-
return (0, $6e687094f9ca8395$export$c8a8987d4410bf2d)((0, $a15c28001c46e071$export$7d8c6d083caec74a).Provider, {
|
|
1407
|
-
value: context
|
|
1408
|
-
}, (0, $6e687094f9ca8395$export$c8a8987d4410bf2d)(Type, {
|
|
1409
|
-
...rest,
|
|
1410
|
-
children: children,
|
|
1411
|
-
className: classNameFromProps,
|
|
1412
|
-
style: {
|
|
1413
|
-
...style,
|
|
1414
|
-
...styleFromProps
|
|
1415
|
-
},
|
|
1416
|
-
// CSS selectors
|
|
1417
|
-
"data-panel-group": "",
|
|
1418
|
-
"data-panel-group-direction": direction,
|
|
1419
|
-
"data-panel-group-id": groupId
|
|
1420
|
-
}));
|
|
1617
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1618
|
+
}
|
|
1619
|
+
}, 0);
|
|
1620
|
+
}, []);
|
|
1621
|
+
const context = useMemo(() => ({
|
|
1622
|
+
collapsePanel,
|
|
1623
|
+
direction,
|
|
1624
|
+
dragState,
|
|
1625
|
+
expandPanel,
|
|
1626
|
+
getPanelSize,
|
|
1627
|
+
getPanelStyle,
|
|
1628
|
+
groupId,
|
|
1629
|
+
isPanelCollapsed,
|
|
1630
|
+
isPanelExpanded,
|
|
1631
|
+
registerPanel,
|
|
1632
|
+
registerResizeHandle,
|
|
1633
|
+
resizePanel,
|
|
1634
|
+
startDragging,
|
|
1635
|
+
stopDragging,
|
|
1636
|
+
unregisterPanel
|
|
1637
|
+
}), [collapsePanel, dragState, direction, expandPanel, getPanelSize, getPanelStyle, groupId, isPanelCollapsed, isPanelExpanded, registerPanel, registerResizeHandle, resizePanel, startDragging, stopDragging, unregisterPanel]);
|
|
1638
|
+
const style = {
|
|
1639
|
+
display: "flex",
|
|
1640
|
+
flexDirection: direction === "horizontal" ? "row" : "column",
|
|
1641
|
+
height: "100%",
|
|
1642
|
+
overflow: "hidden",
|
|
1643
|
+
width: "100%"
|
|
1644
|
+
};
|
|
1645
|
+
return createElement(PanelGroupContext.Provider, {
|
|
1646
|
+
value: context
|
|
1647
|
+
}, createElement(Type, {
|
|
1648
|
+
...rest,
|
|
1649
|
+
children,
|
|
1650
|
+
className: classNameFromProps,
|
|
1651
|
+
style: {
|
|
1652
|
+
...style,
|
|
1653
|
+
...styleFromProps
|
|
1654
|
+
},
|
|
1655
|
+
// CSS selectors
|
|
1656
|
+
"data-panel-group": "",
|
|
1657
|
+
"data-panel-group-direction": direction,
|
|
1658
|
+
"data-panel-group-id": groupId
|
|
1659
|
+
}));
|
|
1421
1660
|
}
|
|
1422
|
-
const
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
function
|
|
1429
|
-
|
|
1661
|
+
const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwardedRef, {
|
|
1662
|
+
...props,
|
|
1663
|
+
forwardedRef: ref
|
|
1664
|
+
}));
|
|
1665
|
+
PanelGroupWithForwardedRef.displayName = "PanelGroup";
|
|
1666
|
+
PanelGroup.displayName = "forwardRef(PanelGroup)";
|
|
1667
|
+
function findPanelDataIndex(panelDataArray, panelData) {
|
|
1668
|
+
return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
|
|
1430
1669
|
}
|
|
1431
|
-
function
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
const panelSize = layout[panelIndex];
|
|
1444
|
-
return {
|
|
1445
|
-
...panelConstraints,
|
|
1446
|
-
panelSize: panelSize,
|
|
1447
|
-
pivotIndices: pivotIndices
|
|
1448
|
-
};
|
|
1670
|
+
function panelDataHelper(panelDataArray, panelData, layout) {
|
|
1671
|
+
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1672
|
+
const panelIndex = findPanelDataIndex(panelDataArray, panelData);
|
|
1673
|
+
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
1674
|
+
const isLastPanel = panelIndex === panelDataArray.length - 1;
|
|
1675
|
+
const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
|
|
1676
|
+
const panelSize = layout[panelIndex];
|
|
1677
|
+
return {
|
|
1678
|
+
...panelConstraints,
|
|
1679
|
+
panelSize,
|
|
1680
|
+
pivotIndices
|
|
1681
|
+
};
|
|
1449
1682
|
}
|
|
1450
1683
|
|
|
1684
|
+
// https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/
|
|
1451
1685
|
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
event.preventDefault();
|
|
1479
|
-
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
1480
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(groupId);
|
|
1481
|
-
const handles = (0, $ef847a5e9ce851d7$export$63eb605e437b214f)(groupId);
|
|
1482
|
-
const index = (0, $645e6f06f14b1fbf$export$4c92fedbbc2381ca)(groupId, handleId);
|
|
1483
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(index !== null);
|
|
1484
|
-
const nextIndex = event.shiftKey ? index > 0 ? index - 1 : handles.length - 1 : index + 1 < handles.length ? index + 1 : 0;
|
|
1485
|
-
const nextHandle = handles[nextIndex];
|
|
1486
|
-
nextHandle.focus();
|
|
1487
|
-
break;
|
|
1488
|
-
}
|
|
1489
|
-
}
|
|
1490
|
-
};
|
|
1491
|
-
handleElement.addEventListener("keydown", onKeyDown);
|
|
1492
|
-
return ()=>{
|
|
1493
|
-
handleElement.removeEventListener("keydown", onKeyDown);
|
|
1494
|
-
};
|
|
1495
|
-
}, [
|
|
1496
|
-
disabled,
|
|
1497
|
-
handleId,
|
|
1498
|
-
resizeHandler
|
|
1499
|
-
]);
|
|
1500
|
-
}
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
function $3a26a712c9163348$export$8829ecf6b6b15484({ children: children = null, className: classNameFromProps = "", disabled: disabled = false, id: idFromProps, onDragging: onDragging, style: styleFromProps = {}, tabIndex: tabIndex = 0, tagName: Type = "div", ...rest }) {
|
|
1507
|
-
const divElementRef = (0, $6e687094f9ca8395$export$b8f5890fc79d6aca)(null);
|
|
1508
|
-
// Use a ref to guard against users passing inline props
|
|
1509
|
-
const callbacksRef = (0, $6e687094f9ca8395$export$b8f5890fc79d6aca)({
|
|
1510
|
-
onDragging: onDragging
|
|
1511
|
-
});
|
|
1512
|
-
(0, $6e687094f9ca8395$export$6d9c69b0de29b591)(()=>{
|
|
1513
|
-
callbacksRef.current.onDragging = onDragging;
|
|
1514
|
-
});
|
|
1515
|
-
const panelGroupContext = (0, $6e687094f9ca8395$export$fae74005e78b1a27)((0, $a15c28001c46e071$export$7d8c6d083caec74a));
|
|
1516
|
-
if (panelGroupContext === null) throw Error(`PanelResizeHandle components must be rendered within a PanelGroup container`);
|
|
1517
|
-
const { direction: direction, dragState: dragState, groupId: groupId, registerResizeHandle: registerResizeHandle, startDragging: startDragging, stopDragging: stopDragging } = panelGroupContext;
|
|
1518
|
-
const resizeHandleId = (0, $b1693d8d8f570e9c$export$2e2bcd8739ae039)(idFromProps);
|
|
1519
|
-
const isDragging = (dragState === null || dragState === void 0 ? void 0 : dragState.dragHandleId) === resizeHandleId;
|
|
1520
|
-
const [isFocused, setIsFocused] = (0, $6e687094f9ca8395$export$60241385465d0a34)(false);
|
|
1521
|
-
const [resizeHandler, setResizeHandler] = (0, $6e687094f9ca8395$export$60241385465d0a34)(null);
|
|
1522
|
-
const stopDraggingAndBlur = (0, $6e687094f9ca8395$export$35808ee640e87ca7)(()=>{
|
|
1523
|
-
// Clicking on the drag handle shouldn't leave it focused;
|
|
1524
|
-
// That would cause the PanelGroup to think it was still active.
|
|
1525
|
-
const divElement = divElementRef.current;
|
|
1526
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(divElement);
|
|
1527
|
-
divElement.blur();
|
|
1528
|
-
stopDragging();
|
|
1529
|
-
const { onDragging: onDragging } = callbacksRef.current;
|
|
1530
|
-
if (onDragging) onDragging(false);
|
|
1531
|
-
}, [
|
|
1532
|
-
stopDragging
|
|
1533
|
-
]);
|
|
1534
|
-
(0, $6e687094f9ca8395$export$6d9c69b0de29b591)(()=>{
|
|
1535
|
-
if (disabled) setResizeHandler(null);
|
|
1536
|
-
else {
|
|
1537
|
-
const resizeHandler = registerResizeHandle(resizeHandleId);
|
|
1538
|
-
setResizeHandler(()=>resizeHandler);
|
|
1539
|
-
}
|
|
1540
|
-
}, [
|
|
1541
|
-
disabled,
|
|
1542
|
-
resizeHandleId,
|
|
1543
|
-
registerResizeHandle
|
|
1544
|
-
]);
|
|
1545
|
-
(0, $6e687094f9ca8395$export$6d9c69b0de29b591)(()=>{
|
|
1546
|
-
if (disabled || resizeHandler == null || !isDragging) return;
|
|
1547
|
-
const onMove = (event)=>{
|
|
1548
|
-
resizeHandler(event);
|
|
1549
|
-
};
|
|
1550
|
-
const onMouseLeave = (event)=>{
|
|
1686
|
+
function useWindowSplitterResizeHandlerBehavior({
|
|
1687
|
+
disabled,
|
|
1688
|
+
handleId,
|
|
1689
|
+
resizeHandler
|
|
1690
|
+
}) {
|
|
1691
|
+
useEffect(() => {
|
|
1692
|
+
if (disabled || resizeHandler == null) {
|
|
1693
|
+
return;
|
|
1694
|
+
}
|
|
1695
|
+
const handleElement = getResizeHandleElement(handleId);
|
|
1696
|
+
if (handleElement == null) {
|
|
1697
|
+
return;
|
|
1698
|
+
}
|
|
1699
|
+
const onKeyDown = event => {
|
|
1700
|
+
if (event.defaultPrevented) {
|
|
1701
|
+
return;
|
|
1702
|
+
}
|
|
1703
|
+
switch (event.key) {
|
|
1704
|
+
case "ArrowDown":
|
|
1705
|
+
case "ArrowLeft":
|
|
1706
|
+
case "ArrowRight":
|
|
1707
|
+
case "ArrowUp":
|
|
1708
|
+
case "End":
|
|
1709
|
+
case "Home":
|
|
1710
|
+
{
|
|
1711
|
+
event.preventDefault();
|
|
1551
1712
|
resizeHandler(event);
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
window.removeEventListener("touchend", stopDraggingAndBlur);
|
|
1569
|
-
};
|
|
1570
|
-
}, [
|
|
1571
|
-
direction,
|
|
1572
|
-
disabled,
|
|
1573
|
-
isDragging,
|
|
1574
|
-
resizeHandler,
|
|
1575
|
-
stopDraggingAndBlur
|
|
1576
|
-
]);
|
|
1577
|
-
(0, $a695670cc57a5969$export$33b0bea6ac3ffb03)({
|
|
1578
|
-
disabled: disabled,
|
|
1579
|
-
handleId: resizeHandleId,
|
|
1580
|
-
resizeHandler: resizeHandler
|
|
1581
|
-
});
|
|
1582
|
-
const style = {
|
|
1583
|
-
cursor: (0, $08745f7373322b05$export$fa35f3322c52262f)(direction),
|
|
1584
|
-
touchAction: "none",
|
|
1585
|
-
userSelect: "none"
|
|
1713
|
+
break;
|
|
1714
|
+
}
|
|
1715
|
+
case "F6":
|
|
1716
|
+
{
|
|
1717
|
+
event.preventDefault();
|
|
1718
|
+
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
1719
|
+
assert(groupId);
|
|
1720
|
+
const handles = getResizeHandleElementsForGroup(groupId);
|
|
1721
|
+
const index = getResizeHandleElementIndex(groupId, handleId);
|
|
1722
|
+
assert(index !== null);
|
|
1723
|
+
const nextIndex = event.shiftKey ? index > 0 ? index - 1 : handles.length - 1 : index + 1 < handles.length ? index + 1 : 0;
|
|
1724
|
+
const nextHandle = handles[nextIndex];
|
|
1725
|
+
nextHandle.focus();
|
|
1726
|
+
break;
|
|
1727
|
+
}
|
|
1728
|
+
}
|
|
1586
1729
|
};
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
onFocus: ()=>setIsFocused(true),
|
|
1593
|
-
onMouseDown: (event)=>{
|
|
1594
|
-
startDragging(resizeHandleId, event.nativeEvent);
|
|
1595
|
-
const callbacks = callbacksRef.current;
|
|
1596
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(callbacks);
|
|
1597
|
-
const { onDragging: onDragging } = callbacks;
|
|
1598
|
-
if (onDragging) onDragging(true);
|
|
1599
|
-
},
|
|
1600
|
-
onMouseUp: stopDraggingAndBlur,
|
|
1601
|
-
onTouchCancel: stopDraggingAndBlur,
|
|
1602
|
-
onTouchEnd: stopDraggingAndBlur,
|
|
1603
|
-
onTouchStart: (event)=>{
|
|
1604
|
-
startDragging(resizeHandleId, event.nativeEvent);
|
|
1605
|
-
const callbacks = callbacksRef.current;
|
|
1606
|
-
(0, $3b727a2145ecd6f8$export$a7a9523472993e97)(callbacks);
|
|
1607
|
-
const { onDragging: onDragging } = callbacks;
|
|
1608
|
-
if (onDragging) onDragging(true);
|
|
1609
|
-
},
|
|
1610
|
-
ref: divElementRef,
|
|
1611
|
-
role: "separator",
|
|
1612
|
-
style: {
|
|
1613
|
-
...style,
|
|
1614
|
-
...styleFromProps
|
|
1615
|
-
},
|
|
1616
|
-
tabIndex: tabIndex,
|
|
1617
|
-
// CSS selectors
|
|
1618
|
-
"data-panel-group-direction": direction,
|
|
1619
|
-
"data-panel-group-id": groupId,
|
|
1620
|
-
"data-resize-handle": "",
|
|
1621
|
-
"data-resize-handle-active": isDragging ? "pointer" : isFocused ? "keyboard" : undefined,
|
|
1622
|
-
"data-panel-resize-handle-enabled": !disabled,
|
|
1623
|
-
"data-panel-resize-handle-id": resizeHandleId
|
|
1624
|
-
});
|
|
1730
|
+
handleElement.addEventListener("keydown", onKeyDown);
|
|
1731
|
+
return () => {
|
|
1732
|
+
handleElement.removeEventListener("keydown", onKeyDown);
|
|
1733
|
+
};
|
|
1734
|
+
}, [disabled, handleId, resizeHandler]);
|
|
1625
1735
|
}
|
|
1626
|
-
$3a26a712c9163348$export$8829ecf6b6b15484.displayName = "PanelResizeHandle";
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
1736
|
|
|
1737
|
+
function PanelResizeHandle({
|
|
1738
|
+
children = null,
|
|
1739
|
+
className: classNameFromProps = "",
|
|
1740
|
+
disabled = false,
|
|
1741
|
+
id: idFromProps,
|
|
1742
|
+
onDragging,
|
|
1743
|
+
style: styleFromProps = {},
|
|
1744
|
+
tabIndex = 0,
|
|
1745
|
+
tagName: Type = "div",
|
|
1746
|
+
...rest
|
|
1747
|
+
}) {
|
|
1748
|
+
const divElementRef = useRef(null);
|
|
1749
|
+
|
|
1750
|
+
// Use a ref to guard against users passing inline props
|
|
1751
|
+
const callbacksRef = useRef({
|
|
1752
|
+
onDragging
|
|
1753
|
+
});
|
|
1754
|
+
useEffect(() => {
|
|
1755
|
+
callbacksRef.current.onDragging = onDragging;
|
|
1756
|
+
});
|
|
1757
|
+
const panelGroupContext = useContext(PanelGroupContext);
|
|
1758
|
+
if (panelGroupContext === null) {
|
|
1759
|
+
throw Error(`PanelResizeHandle components must be rendered within a PanelGroup container`);
|
|
1760
|
+
}
|
|
1761
|
+
const {
|
|
1762
|
+
direction,
|
|
1763
|
+
dragState,
|
|
1764
|
+
groupId,
|
|
1765
|
+
registerResizeHandle,
|
|
1766
|
+
startDragging,
|
|
1767
|
+
stopDragging
|
|
1768
|
+
} = panelGroupContext;
|
|
1769
|
+
const resizeHandleId = useUniqueId(idFromProps);
|
|
1770
|
+
const isDragging = (dragState === null || dragState === void 0 ? void 0 : dragState.dragHandleId) === resizeHandleId;
|
|
1771
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
1772
|
+
const [resizeHandler, setResizeHandler] = useState(null);
|
|
1773
|
+
const stopDraggingAndBlur = useCallback(() => {
|
|
1774
|
+
// Clicking on the drag handle shouldn't leave it focused;
|
|
1775
|
+
// That would cause the PanelGroup to think it was still active.
|
|
1776
|
+
const divElement = divElementRef.current;
|
|
1777
|
+
assert(divElement);
|
|
1778
|
+
divElement.blur();
|
|
1779
|
+
stopDragging();
|
|
1780
|
+
const {
|
|
1781
|
+
onDragging
|
|
1782
|
+
} = callbacksRef.current;
|
|
1783
|
+
if (onDragging) {
|
|
1784
|
+
onDragging(false);
|
|
1785
|
+
}
|
|
1786
|
+
}, [stopDragging]);
|
|
1787
|
+
useEffect(() => {
|
|
1788
|
+
if (disabled) {
|
|
1789
|
+
setResizeHandler(null);
|
|
1790
|
+
} else {
|
|
1791
|
+
const resizeHandler = registerResizeHandle(resizeHandleId);
|
|
1792
|
+
setResizeHandler(() => resizeHandler);
|
|
1793
|
+
}
|
|
1794
|
+
}, [disabled, resizeHandleId, registerResizeHandle]);
|
|
1795
|
+
useEffect(() => {
|
|
1796
|
+
if (disabled || resizeHandler == null || !isDragging) {
|
|
1797
|
+
return;
|
|
1798
|
+
}
|
|
1799
|
+
const onMove = event => {
|
|
1800
|
+
resizeHandler(event);
|
|
1801
|
+
};
|
|
1802
|
+
const onMouseLeave = event => {
|
|
1803
|
+
resizeHandler(event);
|
|
1804
|
+
};
|
|
1805
|
+
const divElement = divElementRef.current;
|
|
1806
|
+
assert(divElement);
|
|
1807
|
+
const targetDocument = divElement.ownerDocument;
|
|
1808
|
+
targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
|
|
1809
|
+
targetDocument.body.addEventListener("mousemove", onMove);
|
|
1810
|
+
targetDocument.body.addEventListener("touchmove", onMove);
|
|
1811
|
+
targetDocument.body.addEventListener("mouseleave", onMouseLeave);
|
|
1812
|
+
window.addEventListener("mouseup", stopDraggingAndBlur);
|
|
1813
|
+
window.addEventListener("touchend", stopDraggingAndBlur);
|
|
1814
|
+
return () => {
|
|
1815
|
+
targetDocument.body.removeEventListener("contextmenu", stopDraggingAndBlur);
|
|
1816
|
+
targetDocument.body.removeEventListener("mousemove", onMove);
|
|
1817
|
+
targetDocument.body.removeEventListener("touchmove", onMove);
|
|
1818
|
+
targetDocument.body.removeEventListener("mouseleave", onMouseLeave);
|
|
1819
|
+
window.removeEventListener("mouseup", stopDraggingAndBlur);
|
|
1820
|
+
window.removeEventListener("touchend", stopDraggingAndBlur);
|
|
1821
|
+
};
|
|
1822
|
+
}, [direction, disabled, isDragging, resizeHandler, stopDraggingAndBlur]);
|
|
1823
|
+
useWindowSplitterResizeHandlerBehavior({
|
|
1824
|
+
disabled,
|
|
1825
|
+
handleId: resizeHandleId,
|
|
1826
|
+
resizeHandler
|
|
1827
|
+
});
|
|
1828
|
+
const style = {
|
|
1829
|
+
cursor: getCursorStyle(direction),
|
|
1830
|
+
touchAction: "none",
|
|
1831
|
+
userSelect: "none"
|
|
1832
|
+
};
|
|
1833
|
+
return createElement(Type, {
|
|
1834
|
+
...rest,
|
|
1835
|
+
children,
|
|
1836
|
+
className: classNameFromProps,
|
|
1837
|
+
onBlur: () => setIsFocused(false),
|
|
1838
|
+
onFocus: () => setIsFocused(true),
|
|
1839
|
+
onMouseDown: event => {
|
|
1840
|
+
startDragging(resizeHandleId, event.nativeEvent);
|
|
1841
|
+
const callbacks = callbacksRef.current;
|
|
1842
|
+
assert(callbacks);
|
|
1843
|
+
const {
|
|
1844
|
+
onDragging
|
|
1845
|
+
} = callbacks;
|
|
1846
|
+
if (onDragging) {
|
|
1847
|
+
onDragging(true);
|
|
1848
|
+
}
|
|
1849
|
+
},
|
|
1850
|
+
onMouseUp: stopDraggingAndBlur,
|
|
1851
|
+
onTouchCancel: stopDraggingAndBlur,
|
|
1852
|
+
onTouchEnd: stopDraggingAndBlur,
|
|
1853
|
+
onTouchStart: event => {
|
|
1854
|
+
startDragging(resizeHandleId, event.nativeEvent);
|
|
1855
|
+
const callbacks = callbacksRef.current;
|
|
1856
|
+
assert(callbacks);
|
|
1857
|
+
const {
|
|
1858
|
+
onDragging
|
|
1859
|
+
} = callbacks;
|
|
1860
|
+
if (onDragging) {
|
|
1861
|
+
onDragging(true);
|
|
1862
|
+
}
|
|
1863
|
+
},
|
|
1864
|
+
ref: divElementRef,
|
|
1865
|
+
role: "separator",
|
|
1866
|
+
style: {
|
|
1867
|
+
...style,
|
|
1868
|
+
...styleFromProps
|
|
1869
|
+
},
|
|
1870
|
+
tabIndex,
|
|
1871
|
+
// CSS selectors
|
|
1872
|
+
"data-panel-group-direction": direction,
|
|
1873
|
+
"data-panel-group-id": groupId,
|
|
1874
|
+
"data-resize-handle": "",
|
|
1875
|
+
"data-resize-handle-active": isDragging ? "pointer" : isFocused ? "keyboard" : undefined,
|
|
1876
|
+
"data-panel-resize-handle-enabled": !disabled,
|
|
1877
|
+
"data-panel-resize-handle-id": resizeHandleId
|
|
1878
|
+
});
|
|
1879
|
+
}
|
|
1880
|
+
PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
1631
1881
|
|
|
1632
|
-
|
|
1882
|
+
exports.Panel = Panel;
|
|
1883
|
+
exports.PanelGroup = PanelGroup;
|
|
1884
|
+
exports.PanelResizeHandle = PanelResizeHandle;
|
|
1885
|
+
exports.assert = assert;
|