react-resizable-panels 0.0.63 → 1.0.0-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintrc.cjs +1 -0
- package/CHANGELOG.md +5 -0
- package/dist/declarations/src/Panel.d.ts +19 -34
- package/dist/declarations/src/PanelGroup.d.ts +9 -13
- package/dist/declarations/src/PanelResizeHandle.d.ts +5 -7
- package/dist/declarations/src/index.d.ts +2 -2
- package/dist/declarations/src/types.d.ts +0 -7
- package/dist/declarations/src/utils/assert.d.ts +1 -0
- package/dist/declarations/src/vendor/react.d.ts +2 -2
- package/dist/react-resizable-panels.browser.cjs.js +253 -518
- package/dist/react-resizable-panels.browser.cjs.mjs +2 -1
- package/dist/react-resizable-panels.browser.development.cjs.js +279 -574
- package/dist/react-resizable-panels.browser.development.cjs.mjs +2 -1
- package/dist/react-resizable-panels.browser.development.esm.js +279 -575
- package/dist/react-resizable-panels.browser.esm.js +253 -519
- package/dist/react-resizable-panels.cjs.d.ts +88 -1
- package/dist/react-resizable-panels.cjs.d.ts.map +1 -1
- package/dist/react-resizable-panels.cjs.js +1481 -1983
- package/dist/react-resizable-panels.cjs.js.map +1 -1
- package/dist/react-resizable-panels.cjs.mjs +2 -1
- package/dist/react-resizable-panels.development.cjs.js +281 -576
- package/dist/react-resizable-panels.development.cjs.mjs +2 -1
- package/dist/react-resizable-panels.development.esm.js +281 -577
- package/dist/react-resizable-panels.development.node.cjs.js +267 -502
- package/dist/react-resizable-panels.development.node.cjs.mjs +2 -1
- package/dist/react-resizable-panels.development.node.esm.js +267 -503
- package/dist/react-resizable-panels.esm.js +1476 -1959
- package/dist/react-resizable-panels.esm.js.map +1 -1
- package/dist/react-resizable-panels.node.cjs.js +239 -444
- package/dist/react-resizable-panels.node.cjs.mjs +2 -1
- package/dist/react-resizable-panels.node.esm.js +239 -445
- package/package.json +1 -1
- package/src/Panel.test.tsx +74 -73
- package/src/Panel.ts +44 -68
- package/src/PanelGroup.test.tsx +43 -42
- package/src/PanelGroup.ts +221 -411
- package/src/PanelGroupContext.ts +2 -3
- package/src/PanelResizeHandle.test.tsx +68 -0
- package/src/PanelResizeHandle.ts +31 -22
- package/src/hooks/useWindowSplitterBehavior.ts +2 -1
- package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +22 -33
- package/src/index.ts +4 -3
- package/src/types.ts +0 -9
- package/src/utils/adjustLayoutByDelta.test.ts +206 -336
- package/src/utils/adjustLayoutByDelta.ts +59 -51
- package/src/utils/assert.ts +1 -1
- package/src/utils/calculateAriaValues.test.ts +6 -11
- package/src/utils/calculateAriaValues.ts +7 -29
- package/src/utils/calculateDeltaPercentage.ts +8 -15
- package/src/utils/calculateDragOffsetPercentage.ts +11 -5
- package/src/utils/calculateUnsafeDefaultLayout.test.ts +4 -9
- package/src/utils/calculateUnsafeDefaultLayout.ts +13 -18
- package/src/utils/callPanelCallbacks.ts +11 -46
- package/src/utils/getResizeEventCursorPosition.ts +2 -0
- package/src/utils/resizePanel.test.ts +6 -52
- package/src/utils/resizePanel.ts +24 -46
- package/src/utils/test-utils.ts +6 -7
- package/src/utils/validatePanelConstraints.test.ts +12 -65
- package/src/utils/validatePanelConstraints.ts +26 -67
- package/src/utils/validatePanelGroupLayout.test.ts +27 -142
- package/src/utils/validatePanelGroupLayout.ts +17 -13
- package/src/vendor/react.ts +2 -0
- package/src/utils/computePercentagePanelConstraints.test.ts +0 -98
- package/src/utils/computePercentagePanelConstraints.ts +0 -56
- package/src/utils/convertPercentageToPixels.test.ts +0 -9
- package/src/utils/convertPercentageToPixels.ts +0 -6
- package/src/utils/convertPixelConstraintsToPercentages.test.ts +0 -47
- package/src/utils/convertPixelConstraintsToPercentages.ts +0 -72
- package/src/utils/convertPixelsToPercentage.test.ts +0 -9
- package/src/utils/convertPixelsToPercentage.ts +0 -6
- package/src/utils/getPercentageSizeFromMixedSizes.test.ts +0 -47
- package/src/utils/getPercentageSizeFromMixedSizes.ts +0 -15
- package/src/utils/shouldMonitorPixelBasedConstraints.test.ts +0 -23
- package/src/utils/shouldMonitorPixelBasedConstraints.ts +0 -13
|
@@ -39,24 +39,20 @@ function useUniqueId(idFromParams = null) {
|
|
|
39
39
|
function PanelWithForwardedRef({
|
|
40
40
|
children,
|
|
41
41
|
className: classNameFromProps = "",
|
|
42
|
-
|
|
43
|
-
collapsedSizePixels,
|
|
42
|
+
collapsedSize,
|
|
44
43
|
collapsible,
|
|
45
|
-
|
|
46
|
-
defaultSizePercentage,
|
|
47
|
-
defaultSizePixels,
|
|
44
|
+
defaultSize,
|
|
48
45
|
forwardedRef,
|
|
49
46
|
id: idFromProps,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
minSizePercentage,
|
|
53
|
-
minSizePixels,
|
|
47
|
+
maxSize,
|
|
48
|
+
minSize,
|
|
54
49
|
onCollapse,
|
|
55
50
|
onExpand,
|
|
56
51
|
onResize,
|
|
57
52
|
order,
|
|
58
53
|
style: styleFromProps,
|
|
59
|
-
tagName: Type = "div"
|
|
54
|
+
tagName: Type = "div",
|
|
55
|
+
...rest
|
|
60
56
|
}) {
|
|
61
57
|
const context = useContext(PanelGroupContext);
|
|
62
58
|
if (context === null) {
|
|
@@ -81,15 +77,11 @@ function PanelWithForwardedRef({
|
|
|
81
77
|
onResize
|
|
82
78
|
},
|
|
83
79
|
constraints: {
|
|
84
|
-
|
|
85
|
-
collapsedSizePixels,
|
|
80
|
+
collapsedSize,
|
|
86
81
|
collapsible,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
maxSizePixels,
|
|
91
|
-
minSizePercentage,
|
|
92
|
-
minSizePixels
|
|
82
|
+
defaultSize,
|
|
83
|
+
maxSize,
|
|
84
|
+
minSize
|
|
93
85
|
},
|
|
94
86
|
id: panelId,
|
|
95
87
|
idIsFromProps: idFromProps !== undefined,
|
|
@@ -103,9 +95,9 @@ function PanelWithForwardedRef({
|
|
|
103
95
|
// but effects don't run on the server, so we can't do it there
|
|
104
96
|
{
|
|
105
97
|
if (!devWarningsRef.current.didLogMissingDefaultSizeWarning) {
|
|
106
|
-
if (
|
|
98
|
+
if (defaultSize == null) {
|
|
107
99
|
devWarningsRef.current.didLogMissingDefaultSizeWarning = true;
|
|
108
|
-
console.warn(`WARNING: Panel
|
|
100
|
+
console.warn(`WARNING: Panel defaultSize prop recommended to avoid layout shift after server rendering`);
|
|
109
101
|
}
|
|
110
102
|
}
|
|
111
103
|
}
|
|
@@ -128,19 +120,19 @@ function PanelWithForwardedRef({
|
|
|
128
120
|
isExpanded() {
|
|
129
121
|
return !isPanelCollapsed(panelDataRef.current);
|
|
130
122
|
},
|
|
131
|
-
resize:
|
|
132
|
-
resizePanel(panelDataRef.current,
|
|
123
|
+
resize: size => {
|
|
124
|
+
resizePanel(panelDataRef.current, size);
|
|
133
125
|
}
|
|
134
126
|
}), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
|
|
135
127
|
const style = getPanelStyle(panelDataRef.current);
|
|
136
128
|
return createElement(Type, {
|
|
129
|
+
...rest,
|
|
137
130
|
children,
|
|
138
131
|
className: classNameFromProps,
|
|
139
132
|
style: {
|
|
140
133
|
...style,
|
|
141
134
|
...styleFromProps
|
|
142
135
|
},
|
|
143
|
-
...dataAttributes,
|
|
144
136
|
// CSS selectors
|
|
145
137
|
"data-panel": "",
|
|
146
138
|
"data-panel-id": panelId,
|
|
@@ -157,81 +149,11 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
|
|
|
157
149
|
PanelWithForwardedRef.displayName = "Panel";
|
|
158
150
|
Panel.displayName = "forwardRef(Panel)";
|
|
159
151
|
|
|
160
|
-
function
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels) {
|
|
165
|
-
let {
|
|
166
|
-
collapsedSizePercentage = 0,
|
|
167
|
-
collapsedSizePixels,
|
|
168
|
-
defaultSizePercentage,
|
|
169
|
-
defaultSizePixels,
|
|
170
|
-
maxSizePercentage = 100,
|
|
171
|
-
maxSizePixels,
|
|
172
|
-
minSizePercentage = 0,
|
|
173
|
-
minSizePixels
|
|
174
|
-
} = panelConstraints;
|
|
175
|
-
const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
|
|
176
|
-
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
177
|
-
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
178
|
-
return {
|
|
179
|
-
collapsedSizePercentage: 0,
|
|
180
|
-
defaultSizePercentage,
|
|
181
|
-
maxSizePercentage: 0,
|
|
182
|
-
minSizePercentage: 0
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
if (collapsedSizePixels != null) {
|
|
186
|
-
collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
|
|
187
|
-
}
|
|
188
|
-
if (defaultSizePixels != null) {
|
|
189
|
-
defaultSizePercentage = convertPixelsToPercentage(defaultSizePixels, groupSizePixels);
|
|
190
|
-
}
|
|
191
|
-
if (minSizePixels != null) {
|
|
192
|
-
minSizePercentage = convertPixelsToPercentage(minSizePixels, groupSizePixels);
|
|
193
|
-
}
|
|
194
|
-
if (maxSizePixels != null) {
|
|
195
|
-
maxSizePercentage = convertPixelsToPercentage(maxSizePixels, groupSizePixels);
|
|
196
|
-
}
|
|
197
|
-
return {
|
|
198
|
-
collapsedSizePercentage,
|
|
199
|
-
defaultSizePercentage,
|
|
200
|
-
maxSizePercentage,
|
|
201
|
-
minSizePercentage
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels) {
|
|
206
|
-
// All panel constraints, excluding the current one
|
|
207
|
-
let totalMinConstraints = 0;
|
|
208
|
-
let totalMaxConstraints = 0;
|
|
209
|
-
for (let index = 0; index < panelConstraintsArray.length; index++) {
|
|
210
|
-
if (index !== panelIndex) {
|
|
211
|
-
const {
|
|
212
|
-
collapsible
|
|
213
|
-
} = panelConstraintsArray[index];
|
|
214
|
-
const {
|
|
215
|
-
collapsedSizePercentage,
|
|
216
|
-
maxSizePercentage,
|
|
217
|
-
minSizePercentage
|
|
218
|
-
} = convertPixelConstraintsToPercentages(panelConstraintsArray[index], groupSizePixels);
|
|
219
|
-
totalMaxConstraints += maxSizePercentage;
|
|
220
|
-
totalMinConstraints += collapsible ? collapsedSizePercentage : minSizePercentage;
|
|
221
|
-
}
|
|
152
|
+
function assert(expectedCondition, message = "Assertion failed!") {
|
|
153
|
+
if (!expectedCondition) {
|
|
154
|
+
console.error(message);
|
|
155
|
+
throw Error(message);
|
|
222
156
|
}
|
|
223
|
-
const {
|
|
224
|
-
collapsedSizePercentage,
|
|
225
|
-
defaultSizePercentage,
|
|
226
|
-
maxSizePercentage,
|
|
227
|
-
minSizePercentage
|
|
228
|
-
} = convertPixelConstraintsToPercentages(panelConstraintsArray[panelIndex], groupSizePixels);
|
|
229
|
-
return {
|
|
230
|
-
collapsedSizePercentage,
|
|
231
|
-
defaultSizePercentage,
|
|
232
|
-
maxSizePercentage: panelConstraintsArray.length > 1 ? Math.min(maxSizePercentage, 100 - totalMinConstraints) : maxSizePercentage,
|
|
233
|
-
minSizePercentage: panelConstraintsArray.length > 1 ? Math.max(minSizePercentage, 100 - totalMaxConstraints) : minSizePercentage
|
|
234
|
-
};
|
|
235
157
|
}
|
|
236
158
|
|
|
237
159
|
const PRECISION = 10;
|
|
@@ -253,56 +175,41 @@ function fuzzyNumbersEqual(actual, expected, fractionDigits) {
|
|
|
253
175
|
|
|
254
176
|
// Panel size must be in percentages; pixel values should be pre-converted
|
|
255
177
|
function resizePanel({
|
|
256
|
-
|
|
257
|
-
panelConstraints,
|
|
178
|
+
panelConstraints: panelConstraintsArray,
|
|
258
179
|
panelIndex,
|
|
259
180
|
size
|
|
260
181
|
}) {
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
defaultSizePixels,
|
|
264
|
-
minSizePixels,
|
|
265
|
-
maxSizePixels
|
|
266
|
-
}) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
|
|
267
|
-
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
268
|
-
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
269
|
-
return 0;
|
|
270
|
-
}
|
|
182
|
+
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
183
|
+
assert(panelConstraints != null);
|
|
271
184
|
let {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
if (
|
|
282
|
-
|
|
283
|
-
const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
|
|
284
|
-
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
285
|
-
size = collapsedSizePercentage;
|
|
286
|
-
} else {
|
|
287
|
-
size = minSizePercentage;
|
|
288
|
-
}
|
|
185
|
+
collapsedSize = 0,
|
|
186
|
+
collapsible,
|
|
187
|
+
maxSize = 100,
|
|
188
|
+
minSize = 0
|
|
189
|
+
} = panelConstraints;
|
|
190
|
+
if (fuzzyCompareNumbers(size, minSize) < 0) {
|
|
191
|
+
if (collapsible) {
|
|
192
|
+
// Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
|
|
193
|
+
const halfwayPoint = (collapsedSize + minSize) / 2;
|
|
194
|
+
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
195
|
+
size = collapsedSize;
|
|
289
196
|
} else {
|
|
290
|
-
size =
|
|
197
|
+
size = minSize;
|
|
291
198
|
}
|
|
199
|
+
} else {
|
|
200
|
+
size = minSize;
|
|
292
201
|
}
|
|
293
202
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
203
|
+
size = Math.min(maxSize, size);
|
|
204
|
+
size = parseFloat(size.toFixed(PRECISION));
|
|
297
205
|
return size;
|
|
298
206
|
}
|
|
299
207
|
|
|
300
208
|
// All units must be in percentages; pixel values should be pre-converted
|
|
301
209
|
function adjustLayoutByDelta({
|
|
302
210
|
delta,
|
|
303
|
-
groupSizePixels,
|
|
304
211
|
layout: prevLayout,
|
|
305
|
-
panelConstraints,
|
|
212
|
+
panelConstraints: panelConstraintsArray,
|
|
306
213
|
pivotIndices,
|
|
307
214
|
trigger
|
|
308
215
|
}) {
|
|
@@ -310,6 +217,9 @@ function adjustLayoutByDelta({
|
|
|
310
217
|
return prevLayout;
|
|
311
218
|
}
|
|
312
219
|
const nextLayout = [...prevLayout];
|
|
220
|
+
const [firstPivotIndex, secondPivotIndex] = pivotIndices;
|
|
221
|
+
assert(firstPivotIndex != null);
|
|
222
|
+
assert(secondPivotIndex != null);
|
|
313
223
|
let deltaApplied = 0;
|
|
314
224
|
|
|
315
225
|
//const DEBUG = [];
|
|
@@ -333,18 +243,23 @@ function adjustLayoutByDelta({
|
|
|
333
243
|
if (trigger === "keyboard") {
|
|
334
244
|
{
|
|
335
245
|
// Check if we should expand a collapsed panel
|
|
336
|
-
const index = delta < 0 ?
|
|
337
|
-
const
|
|
246
|
+
const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
247
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
248
|
+
assert(panelConstraints);
|
|
249
|
+
|
|
338
250
|
//DEBUG.push(`edge case check 1: ${index}`);
|
|
339
251
|
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
340
|
-
if (
|
|
252
|
+
if (panelConstraints.collapsible) {
|
|
341
253
|
const prevSize = prevLayout[index];
|
|
254
|
+
assert(prevSize != null);
|
|
255
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
256
|
+
assert(panelConstraints);
|
|
342
257
|
const {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
} =
|
|
346
|
-
if (fuzzyNumbersEqual(prevSize,
|
|
347
|
-
const localDelta =
|
|
258
|
+
collapsedSize = 0,
|
|
259
|
+
minSize = 0
|
|
260
|
+
} = panelConstraints;
|
|
261
|
+
if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
|
|
262
|
+
const localDelta = minSize - prevSize;
|
|
348
263
|
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
349
264
|
|
|
350
265
|
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
@@ -357,18 +272,26 @@ function adjustLayoutByDelta({
|
|
|
357
272
|
|
|
358
273
|
{
|
|
359
274
|
// Check if we should collapse a panel at its minimum size
|
|
360
|
-
const index = delta < 0 ?
|
|
361
|
-
const
|
|
275
|
+
const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
276
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
277
|
+
assert(panelConstraints);
|
|
278
|
+
const {
|
|
279
|
+
collapsible
|
|
280
|
+
} = panelConstraints;
|
|
281
|
+
|
|
362
282
|
//DEBUG.push(`edge case check 2: ${index}`);
|
|
363
|
-
//DEBUG.push(` -> collapsible? ${
|
|
364
|
-
if (
|
|
283
|
+
//DEBUG.push(` -> collapsible? ${collapsible}`);
|
|
284
|
+
if (collapsible) {
|
|
365
285
|
const prevSize = prevLayout[index];
|
|
286
|
+
assert(prevSize != null);
|
|
287
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
288
|
+
assert(panelConstraints);
|
|
366
289
|
const {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
} =
|
|
370
|
-
if (fuzzyNumbersEqual(prevSize,
|
|
371
|
-
const localDelta = prevSize -
|
|
290
|
+
collapsedSize = 0,
|
|
291
|
+
minSize = 0
|
|
292
|
+
} = panelConstraints;
|
|
293
|
+
if (fuzzyNumbersEqual(prevSize, minSize)) {
|
|
294
|
+
const localDelta = prevSize - collapsedSize;
|
|
372
295
|
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
373
296
|
|
|
374
297
|
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
@@ -390,15 +313,15 @@ function adjustLayoutByDelta({
|
|
|
390
313
|
// as an expanding panel might change from collapsed to min size.
|
|
391
314
|
|
|
392
315
|
const increment = delta < 0 ? 1 : -1;
|
|
393
|
-
let index = delta < 0 ?
|
|
316
|
+
let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
394
317
|
let maxAvailableDelta = 0;
|
|
395
318
|
|
|
396
319
|
//DEBUG.push("pre calc...");
|
|
397
320
|
while (true) {
|
|
398
321
|
const prevSize = prevLayout[index];
|
|
322
|
+
assert(prevSize != null);
|
|
399
323
|
const maxSafeSize = resizePanel({
|
|
400
|
-
|
|
401
|
-
panelConstraints,
|
|
324
|
+
panelConstraints: panelConstraintsArray,
|
|
402
325
|
panelIndex: index,
|
|
403
326
|
size: 100
|
|
404
327
|
});
|
|
@@ -407,7 +330,7 @@ function adjustLayoutByDelta({
|
|
|
407
330
|
|
|
408
331
|
maxAvailableDelta += delta;
|
|
409
332
|
index += increment;
|
|
410
|
-
if (index < 0 || index >=
|
|
333
|
+
if (index < 0 || index >= panelConstraintsArray.length) {
|
|
411
334
|
break;
|
|
412
335
|
}
|
|
413
336
|
}
|
|
@@ -422,15 +345,15 @@ function adjustLayoutByDelta({
|
|
|
422
345
|
{
|
|
423
346
|
// Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
|
|
424
347
|
|
|
425
|
-
const pivotIndex = delta < 0 ?
|
|
348
|
+
const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
426
349
|
let index = pivotIndex;
|
|
427
|
-
while (index >= 0 && index <
|
|
350
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
428
351
|
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
429
352
|
const prevSize = prevLayout[index];
|
|
353
|
+
assert(prevSize != null);
|
|
430
354
|
const unsafeSize = prevSize - deltaRemaining;
|
|
431
355
|
const safeSize = resizePanel({
|
|
432
|
-
|
|
433
|
-
panelConstraints,
|
|
356
|
+
panelConstraints: panelConstraintsArray,
|
|
434
357
|
panelIndex: index,
|
|
435
358
|
size: unsafeSize
|
|
436
359
|
});
|
|
@@ -462,11 +385,12 @@ function adjustLayoutByDelta({
|
|
|
462
385
|
}
|
|
463
386
|
{
|
|
464
387
|
// Now distribute the applied delta to the panels in the other direction
|
|
465
|
-
const pivotIndex = delta < 0 ?
|
|
466
|
-
const
|
|
388
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
389
|
+
const prevSize = prevLayout[pivotIndex];
|
|
390
|
+
assert(prevSize != null);
|
|
391
|
+
const unsafeSize = prevSize + deltaApplied;
|
|
467
392
|
const safeSize = resizePanel({
|
|
468
|
-
|
|
469
|
-
panelConstraints,
|
|
393
|
+
panelConstraints: panelConstraintsArray,
|
|
470
394
|
panelIndex: pivotIndex,
|
|
471
395
|
size: unsafeSize
|
|
472
396
|
});
|
|
@@ -477,14 +401,14 @@ function adjustLayoutByDelta({
|
|
|
477
401
|
// Edge case where expanding or contracting one panel caused another one to change collapsed state
|
|
478
402
|
if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
|
|
479
403
|
let deltaRemaining = unsafeSize - safeSize;
|
|
480
|
-
const pivotIndex = delta < 0 ?
|
|
404
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
481
405
|
let index = pivotIndex;
|
|
482
|
-
while (index >= 0 && index <
|
|
406
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
483
407
|
const prevSize = nextLayout[index];
|
|
408
|
+
assert(prevSize != null);
|
|
484
409
|
const unsafeSize = prevSize + deltaRemaining;
|
|
485
410
|
const safeSize = resizePanel({
|
|
486
|
-
|
|
487
|
-
panelConstraints,
|
|
411
|
+
panelConstraints: panelConstraintsArray,
|
|
488
412
|
panelIndex: index,
|
|
489
413
|
size: unsafeSize
|
|
490
414
|
});
|
|
@@ -508,9 +432,7 @@ function adjustLayoutByDelta({
|
|
|
508
432
|
//DEBUG.push("");
|
|
509
433
|
|
|
510
434
|
const totalSize = nextLayout.reduce((total, size) => size + total, 0);
|
|
511
|
-
deltaApplied = 100 - totalSize;
|
|
512
435
|
//DEBUG.push(`total size: ${totalSize}`);
|
|
513
|
-
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
514
436
|
//console.log(DEBUG.join("\n"));
|
|
515
437
|
|
|
516
438
|
if (!fuzzyNumbersEqual(totalSize, 100)) {
|
|
@@ -519,25 +441,6 @@ function adjustLayoutByDelta({
|
|
|
519
441
|
return nextLayout;
|
|
520
442
|
}
|
|
521
443
|
|
|
522
|
-
function assert(expectedCondition, message = "Assertion failed!") {
|
|
523
|
-
if (!expectedCondition) {
|
|
524
|
-
console.error(message);
|
|
525
|
-
throw Error(message);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
function getPercentageSizeFromMixedSizes({
|
|
530
|
-
sizePercentage,
|
|
531
|
-
sizePixels
|
|
532
|
-
}, groupSizePixels) {
|
|
533
|
-
if (sizePercentage != null) {
|
|
534
|
-
return sizePercentage;
|
|
535
|
-
} else if (sizePixels != null) {
|
|
536
|
-
return convertPixelsToPercentage(sizePixels, groupSizePixels);
|
|
537
|
-
}
|
|
538
|
-
return undefined;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
444
|
function getResizeHandleElementsForGroup(groupId) {
|
|
542
445
|
return Array.from(document.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
|
|
543
446
|
}
|
|
@@ -561,42 +464,6 @@ function getPanelGroupElement(id) {
|
|
|
561
464
|
return null;
|
|
562
465
|
}
|
|
563
466
|
|
|
564
|
-
function calculateAvailablePanelSizeInPixels(groupId) {
|
|
565
|
-
const panelGroupElement = getPanelGroupElement(groupId);
|
|
566
|
-
if (panelGroupElement == null) {
|
|
567
|
-
return NaN;
|
|
568
|
-
}
|
|
569
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
570
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId);
|
|
571
|
-
if (direction === "horizontal") {
|
|
572
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
573
|
-
return accumulated + handle.offsetWidth;
|
|
574
|
-
}, 0);
|
|
575
|
-
} else {
|
|
576
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
577
|
-
return accumulated + handle.offsetHeight;
|
|
578
|
-
}, 0);
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
function getAvailableGroupSizePixels(groupId) {
|
|
583
|
-
const panelGroupElement = getPanelGroupElement(groupId);
|
|
584
|
-
if (panelGroupElement == null) {
|
|
585
|
-
return NaN;
|
|
586
|
-
}
|
|
587
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
588
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId);
|
|
589
|
-
if (direction === "horizontal") {
|
|
590
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
591
|
-
return accumulated + handle.offsetWidth;
|
|
592
|
-
}, 0);
|
|
593
|
-
} else {
|
|
594
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
595
|
-
return accumulated + handle.offsetHeight;
|
|
596
|
-
}, 0);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
467
|
function getResizeHandleElement(id) {
|
|
601
468
|
const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
|
|
602
469
|
if (element) {
|
|
@@ -629,14 +496,18 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
629
496
|
didWarnAboutMissingResizeHandle: false
|
|
630
497
|
});
|
|
631
498
|
useEffect(() => {
|
|
499
|
+
const eagerValues = eagerValuesRef.current;
|
|
500
|
+
assert(eagerValues);
|
|
632
501
|
const {
|
|
633
502
|
panelDataArray
|
|
634
|
-
} =
|
|
503
|
+
} = eagerValues;
|
|
635
504
|
const groupElement = getPanelGroupElement(groupId);
|
|
636
505
|
assert(groupElement != null, `No group found for id "${groupId}"`);
|
|
637
506
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
507
|
+
assert(handles);
|
|
638
508
|
const cleanupFunctions = handles.map(handle => {
|
|
639
509
|
const handleId = handle.getAttribute("data-panel-resize-handle-id");
|
|
510
|
+
assert(handleId);
|
|
640
511
|
const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
|
|
641
512
|
if (idBefore == null || idAfter == null) {
|
|
642
513
|
return () => {};
|
|
@@ -652,21 +523,16 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
652
523
|
const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
|
|
653
524
|
if (index >= 0) {
|
|
654
525
|
const panelData = panelDataArray[index];
|
|
526
|
+
assert(panelData);
|
|
655
527
|
const size = layout[index];
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
663
|
-
const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
|
|
664
|
-
sizePercentage: panelData.constraints.minSizePercentage,
|
|
665
|
-
sizePixels: panelData.constraints.minSizePixels
|
|
666
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
|
|
528
|
+
const {
|
|
529
|
+
collapsedSize = 0,
|
|
530
|
+
collapsible,
|
|
531
|
+
minSize = 0
|
|
532
|
+
} = panelData.constraints;
|
|
533
|
+
if (size != null && collapsible) {
|
|
667
534
|
const nextLayout = adjustLayoutByDelta({
|
|
668
535
|
delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
|
|
669
|
-
groupSizePixels,
|
|
670
536
|
layout,
|
|
671
537
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints),
|
|
672
538
|
pivotIndices: determinePivotIndices(groupId, handleId),
|
|
@@ -720,6 +586,7 @@ function getResizeEventCursorPosition(direction, event) {
|
|
|
720
586
|
return isHorizontal ? event.clientX : event.clientY;
|
|
721
587
|
} else if (isTouchEvent(event)) {
|
|
722
588
|
const firstTouch = event.touches[0];
|
|
589
|
+
assert(firstTouch);
|
|
723
590
|
return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
|
|
724
591
|
} else {
|
|
725
592
|
throw Error(`Unsupported event type "${event.type}"`);
|
|
@@ -729,12 +596,15 @@ function getResizeEventCursorPosition(direction, event) {
|
|
|
729
596
|
function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
|
|
730
597
|
const isHorizontal = direction === "horizontal";
|
|
731
598
|
const handleElement = getResizeHandleElement(dragHandleId);
|
|
599
|
+
assert(handleElement);
|
|
732
600
|
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
601
|
+
assert(groupId);
|
|
733
602
|
let {
|
|
734
603
|
initialCursorPosition
|
|
735
604
|
} = initialDragState;
|
|
736
605
|
const cursorPosition = getResizeEventCursorPosition(direction, event);
|
|
737
606
|
const groupElement = getPanelGroupElement(groupId);
|
|
607
|
+
assert(groupElement);
|
|
738
608
|
const groupRect = groupElement.getBoundingClientRect();
|
|
739
609
|
const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
|
|
740
610
|
const offsetPixels = cursorPosition - initialCursorPosition;
|
|
@@ -743,19 +613,14 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
|
|
|
743
613
|
}
|
|
744
614
|
|
|
745
615
|
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
|
|
746
|
-
function calculateDeltaPercentage(event,
|
|
616
|
+
function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
|
|
747
617
|
if (isKeyDown(event)) {
|
|
748
618
|
const isHorizontal = direction === "horizontal";
|
|
749
|
-
const groupElement = getPanelGroupElement(groupId);
|
|
750
|
-
const rect = groupElement.getBoundingClientRect();
|
|
751
|
-
const groupSizeInPixels = isHorizontal ? rect.width : rect.height;
|
|
752
619
|
let delta = 0;
|
|
753
620
|
if (event.shiftKey) {
|
|
754
621
|
delta = 100;
|
|
755
|
-
} else if (
|
|
756
|
-
delta =
|
|
757
|
-
} else if (keyboardResizeByOptions.pixels != null) {
|
|
758
|
-
delta = keyboardResizeByOptions.pixels / groupSizeInPixels;
|
|
622
|
+
} else if (keyboardResizeBy != null) {
|
|
623
|
+
delta = keyboardResizeBy;
|
|
759
624
|
} else {
|
|
760
625
|
delta = 10;
|
|
761
626
|
}
|
|
@@ -782,37 +647,43 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
|
|
|
782
647
|
}
|
|
783
648
|
return movement;
|
|
784
649
|
} else {
|
|
650
|
+
if (initialDragState == null) {
|
|
651
|
+
return 0;
|
|
652
|
+
}
|
|
785
653
|
return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
|
|
786
654
|
}
|
|
787
655
|
}
|
|
788
656
|
|
|
789
657
|
function calculateUnsafeDefaultLayout({
|
|
790
|
-
groupSizePixels,
|
|
791
658
|
panelDataArray
|
|
792
659
|
}) {
|
|
793
660
|
const layout = Array(panelDataArray.length);
|
|
794
|
-
const
|
|
661
|
+
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
795
662
|
let numPanelsWithSizes = 0;
|
|
796
663
|
let remainingSize = 100;
|
|
797
664
|
|
|
798
665
|
// Distribute default sizes first
|
|
799
666
|
for (let index = 0; index < panelDataArray.length; index++) {
|
|
667
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
668
|
+
assert(panelConstraints);
|
|
800
669
|
const {
|
|
801
|
-
|
|
802
|
-
} =
|
|
803
|
-
if (
|
|
670
|
+
defaultSize
|
|
671
|
+
} = panelConstraints;
|
|
672
|
+
if (defaultSize != null) {
|
|
804
673
|
numPanelsWithSizes++;
|
|
805
|
-
layout[index] =
|
|
806
|
-
remainingSize -=
|
|
674
|
+
layout[index] = defaultSize;
|
|
675
|
+
remainingSize -= defaultSize;
|
|
807
676
|
}
|
|
808
677
|
}
|
|
809
678
|
|
|
810
679
|
// Remaining size should be distributed evenly between panels without default sizes
|
|
811
680
|
for (let index = 0; index < panelDataArray.length; index++) {
|
|
681
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
682
|
+
assert(panelConstraints);
|
|
812
683
|
const {
|
|
813
|
-
|
|
814
|
-
} =
|
|
815
|
-
if (
|
|
684
|
+
defaultSize
|
|
685
|
+
} = panelConstraints;
|
|
686
|
+
if (defaultSize != null) {
|
|
816
687
|
continue;
|
|
817
688
|
}
|
|
818
689
|
const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
|
|
@@ -824,54 +695,36 @@ function calculateUnsafeDefaultLayout({
|
|
|
824
695
|
return layout;
|
|
825
696
|
}
|
|
826
697
|
|
|
827
|
-
function convertPercentageToPixels(percentage, groupSizePixels) {
|
|
828
|
-
return percentage / 100 * groupSizePixels;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
698
|
// Layout should be pre-converted into percentages
|
|
832
|
-
function callPanelCallbacks(
|
|
833
|
-
|
|
834
|
-
layout.forEach((sizePercentage, index) => {
|
|
699
|
+
function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
|
|
700
|
+
layout.forEach((size, index) => {
|
|
835
701
|
const panelData = panelsArray[index];
|
|
836
|
-
|
|
837
|
-
// Handle initial mount (when panels are registered too late to be in the panels array)
|
|
838
|
-
// The subsequent render+effects will handle the resize notification
|
|
839
|
-
return;
|
|
840
|
-
}
|
|
702
|
+
assert(panelData);
|
|
841
703
|
const {
|
|
842
704
|
callbacks,
|
|
843
705
|
constraints,
|
|
844
706
|
id: panelId
|
|
845
707
|
} = panelData;
|
|
846
708
|
const {
|
|
709
|
+
collapsedSize = 0,
|
|
847
710
|
collapsible
|
|
848
711
|
} = constraints;
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
};
|
|
853
|
-
const lastNotifiedMixedSizes = panelIdToLastNotifiedMixedSizesMap[panelId];
|
|
854
|
-
if (lastNotifiedMixedSizes == null || mixedSizes.sizePercentage !== lastNotifiedMixedSizes.sizePercentage || mixedSizes.sizePixels !== lastNotifiedMixedSizes.sizePixels) {
|
|
855
|
-
panelIdToLastNotifiedMixedSizesMap[panelId] = mixedSizes;
|
|
712
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
|
|
713
|
+
if (lastNotifiedSize == null || size !== lastNotifiedSize) {
|
|
714
|
+
panelIdToLastNotifiedSizeMap[panelId] = size;
|
|
856
715
|
const {
|
|
857
716
|
onCollapse,
|
|
858
717
|
onExpand,
|
|
859
718
|
onResize
|
|
860
719
|
} = callbacks;
|
|
861
720
|
if (onResize) {
|
|
862
|
-
onResize(
|
|
721
|
+
onResize(size, lastNotifiedSize);
|
|
863
722
|
}
|
|
864
723
|
if (collapsible && (onCollapse || onExpand)) {
|
|
865
|
-
|
|
866
|
-
const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
|
|
867
|
-
sizePercentage: constraints.collapsedSizePercentage,
|
|
868
|
-
sizePixels: constraints.collapsedSizePixels
|
|
869
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
870
|
-
const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
|
|
871
|
-
if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
|
|
724
|
+
if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
|
|
872
725
|
onExpand();
|
|
873
726
|
}
|
|
874
|
-
if (onCollapse && (
|
|
727
|
+
if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
|
|
875
728
|
onCollapse();
|
|
876
729
|
}
|
|
877
730
|
}
|
|
@@ -1054,74 +907,39 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
|
|
|
1054
907
|
}
|
|
1055
908
|
}
|
|
1056
909
|
|
|
1057
|
-
function shouldMonitorPixelBasedConstraints(constraints) {
|
|
1058
|
-
return constraints.some(constraints => {
|
|
1059
|
-
return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
|
|
1060
|
-
});
|
|
1061
|
-
}
|
|
1062
|
-
|
|
1063
910
|
function validatePanelConstraints({
|
|
1064
|
-
|
|
1065
|
-
panelConstraints,
|
|
911
|
+
panelConstraints: panelConstraintsArray,
|
|
1066
912
|
panelId,
|
|
1067
913
|
panelIndex
|
|
1068
914
|
}) {
|
|
1069
915
|
{
|
|
1070
916
|
const warnings = [];
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
} = panelConstraints[panelIndex];
|
|
1082
|
-
const conflictingUnits = [];
|
|
1083
|
-
if (collapsedSizePercentage != null && collapsedSizePixels != null) {
|
|
1084
|
-
conflictingUnits.push("collapsed size");
|
|
1085
|
-
}
|
|
1086
|
-
if (defaultSizePercentage != null && defaultSizePixels != null) {
|
|
1087
|
-
conflictingUnits.push("default size");
|
|
1088
|
-
}
|
|
1089
|
-
if (maxSizePercentage != null && maxSizePixels != null) {
|
|
1090
|
-
conflictingUnits.push("max size");
|
|
1091
|
-
}
|
|
1092
|
-
if (minSizePercentage != null && minSizePixels != null) {
|
|
1093
|
-
conflictingUnits.push("min size");
|
|
1094
|
-
}
|
|
1095
|
-
if (conflictingUnits.length > 0) {
|
|
1096
|
-
warnings.push(`should not specify both percentage and pixel units for: ${conflictingUnits.join(", ")}`);
|
|
1097
|
-
}
|
|
917
|
+
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
918
|
+
assert(panelConstraints);
|
|
919
|
+
const {
|
|
920
|
+
collapsedSize = 0,
|
|
921
|
+
defaultSize,
|
|
922
|
+
maxSize = 100,
|
|
923
|
+
minSize = 0
|
|
924
|
+
} = panelConstraints;
|
|
925
|
+
if (minSize > maxSize) {
|
|
926
|
+
warnings.push(`min size (${minSize}%) should not be greater than max size (${maxSize}%)`);
|
|
1098
927
|
}
|
|
1099
|
-
{
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
minSizePercentage
|
|
1105
|
-
} = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
|
|
1106
|
-
if (minSizePercentage > maxSizePercentage) {
|
|
1107
|
-
warnings.push(`min size (${minSizePercentage}%) should not be greater than max size (${maxSizePercentage}%)`);
|
|
1108
|
-
}
|
|
1109
|
-
if (defaultSizePercentage != null) {
|
|
1110
|
-
if (defaultSizePercentage < 0) {
|
|
1111
|
-
warnings.push("default size should not be less than 0");
|
|
1112
|
-
} else if (defaultSizePercentage < minSizePercentage) {
|
|
1113
|
-
warnings.push("default size should not be less than min size");
|
|
1114
|
-
}
|
|
1115
|
-
if (defaultSizePercentage > 100) {
|
|
1116
|
-
warnings.push("default size should not be greater than 100");
|
|
1117
|
-
} else if (defaultSizePercentage > maxSizePercentage) {
|
|
1118
|
-
warnings.push("default size should not be greater than max size");
|
|
1119
|
-
}
|
|
928
|
+
if (defaultSize != null) {
|
|
929
|
+
if (defaultSize < 0) {
|
|
930
|
+
warnings.push("default size should not be less than 0");
|
|
931
|
+
} else if (defaultSize < minSize) {
|
|
932
|
+
warnings.push("default size should not be less than min size");
|
|
1120
933
|
}
|
|
1121
|
-
if (
|
|
1122
|
-
warnings.push("
|
|
934
|
+
if (defaultSize > 100) {
|
|
935
|
+
warnings.push("default size should not be greater than 100");
|
|
936
|
+
} else if (defaultSize > maxSize) {
|
|
937
|
+
warnings.push("default size should not be greater than max size");
|
|
1123
938
|
}
|
|
1124
939
|
}
|
|
940
|
+
if (collapsedSize > minSize) {
|
|
941
|
+
warnings.push("collapsed size should not be greater than min size");
|
|
942
|
+
}
|
|
1125
943
|
if (warnings.length > 0) {
|
|
1126
944
|
const name = panelId != null ? `Panel "${panelId}"` : "Panel";
|
|
1127
945
|
console.warn(`${name} has an invalid configuration:\n\n${warnings.join("\n")}`);
|
|
@@ -1133,20 +951,26 @@ function validatePanelConstraints({
|
|
|
1133
951
|
|
|
1134
952
|
// All units must be in percentages; pixel values should be pre-converted
|
|
1135
953
|
function validatePanelGroupLayout({
|
|
1136
|
-
groupSizePixels,
|
|
1137
954
|
layout: prevLayout,
|
|
1138
955
|
panelConstraints
|
|
1139
956
|
}) {
|
|
1140
957
|
const nextLayout = [...prevLayout];
|
|
958
|
+
const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
|
|
1141
959
|
|
|
1142
960
|
// Validate layout expectations
|
|
1143
961
|
if (nextLayout.length !== panelConstraints.length) {
|
|
1144
962
|
throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
|
|
1145
|
-
} else if (!fuzzyNumbersEqual(
|
|
963
|
+
} else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
|
|
1146
964
|
// This is not ideal so we should warn about it, but it may be recoverable in some cases
|
|
1147
965
|
// (especially if the amount is small)
|
|
1148
966
|
{
|
|
1149
|
-
console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}
|
|
967
|
+
console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}. Layout normalization will be applied.`);
|
|
968
|
+
}
|
|
969
|
+
for (let index = 0; index < panelConstraints.length; index++) {
|
|
970
|
+
const unsafeSize = nextLayout[index];
|
|
971
|
+
assert(unsafeSize != null);
|
|
972
|
+
const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
|
|
973
|
+
nextLayout[index] = safeSize;
|
|
1150
974
|
}
|
|
1151
975
|
}
|
|
1152
976
|
let remainingSize = 0;
|
|
@@ -1154,8 +978,8 @@ function validatePanelGroupLayout({
|
|
|
1154
978
|
// First pass: Validate the proposed layout given each panel's constraints
|
|
1155
979
|
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1156
980
|
const unsafeSize = nextLayout[index];
|
|
981
|
+
assert(unsafeSize != null);
|
|
1157
982
|
const safeSize = resizePanel({
|
|
1158
|
-
groupSizePixels,
|
|
1159
983
|
panelConstraints,
|
|
1160
984
|
panelIndex: index,
|
|
1161
985
|
size: unsafeSize
|
|
@@ -1171,9 +995,9 @@ function validatePanelGroupLayout({
|
|
|
1171
995
|
if (!fuzzyNumbersEqual(remainingSize, 0)) {
|
|
1172
996
|
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1173
997
|
const prevSize = nextLayout[index];
|
|
998
|
+
assert(prevSize != null);
|
|
1174
999
|
const unsafeSize = prevSize + remainingSize;
|
|
1175
1000
|
const safeSize = resizePanel({
|
|
1176
|
-
groupSizePixels,
|
|
1177
1001
|
panelConstraints,
|
|
1178
1002
|
panelIndex: index,
|
|
1179
1003
|
size: unsafeSize
|
|
@@ -1208,21 +1032,20 @@ function PanelGroupWithForwardedRef({
|
|
|
1208
1032
|
autoSaveId = null,
|
|
1209
1033
|
children,
|
|
1210
1034
|
className: classNameFromProps = "",
|
|
1211
|
-
dataAttributes,
|
|
1212
1035
|
direction,
|
|
1213
1036
|
forwardedRef,
|
|
1214
|
-
id: idFromProps,
|
|
1037
|
+
id: idFromProps = null,
|
|
1215
1038
|
onLayout = null,
|
|
1216
|
-
|
|
1217
|
-
keyboardResizeByPixels = null,
|
|
1039
|
+
keyboardResizeBy = null,
|
|
1218
1040
|
storage = defaultStorage,
|
|
1219
1041
|
style: styleFromProps,
|
|
1220
|
-
tagName: Type = "div"
|
|
1042
|
+
tagName: Type = "div",
|
|
1043
|
+
...rest
|
|
1221
1044
|
}) {
|
|
1222
1045
|
const groupId = useUniqueId(idFromProps);
|
|
1223
1046
|
const [dragState, setDragState] = useState(null);
|
|
1224
1047
|
const [layout, setLayout] = useState([]);
|
|
1225
|
-
const
|
|
1048
|
+
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1226
1049
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1227
1050
|
const prevDeltaRef = useRef(0);
|
|
1228
1051
|
const committedValuesRef = useRef({
|
|
@@ -1230,8 +1053,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1230
1053
|
direction,
|
|
1231
1054
|
dragState,
|
|
1232
1055
|
id: groupId,
|
|
1233
|
-
|
|
1234
|
-
keyboardResizeByPixels,
|
|
1056
|
+
keyboardResizeBy,
|
|
1235
1057
|
onLayout,
|
|
1236
1058
|
storage
|
|
1237
1059
|
});
|
|
@@ -1247,33 +1069,20 @@ function PanelGroupWithForwardedRef({
|
|
|
1247
1069
|
useImperativeHandle(forwardedRef, () => ({
|
|
1248
1070
|
getId: () => committedValuesRef.current.id,
|
|
1249
1071
|
getLayout: () => {
|
|
1250
|
-
const {
|
|
1251
|
-
id: groupId
|
|
1252
|
-
} = committedValuesRef.current;
|
|
1253
1072
|
const {
|
|
1254
1073
|
layout
|
|
1255
1074
|
} = eagerValuesRef.current;
|
|
1256
|
-
|
|
1257
|
-
return layout.map(sizePercentage => {
|
|
1258
|
-
return {
|
|
1259
|
-
sizePercentage,
|
|
1260
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1261
|
-
};
|
|
1262
|
-
});
|
|
1075
|
+
return layout;
|
|
1263
1076
|
},
|
|
1264
|
-
setLayout:
|
|
1077
|
+
setLayout: unsafeLayout => {
|
|
1265
1078
|
const {
|
|
1266
|
-
id: groupId,
|
|
1267
1079
|
onLayout
|
|
1268
1080
|
} = committedValuesRef.current;
|
|
1269
1081
|
const {
|
|
1270
1082
|
layout: prevLayout,
|
|
1271
1083
|
panelDataArray
|
|
1272
1084
|
} = eagerValuesRef.current;
|
|
1273
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1274
|
-
const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
|
|
1275
1085
|
const safeLayout = validatePanelGroupLayout({
|
|
1276
|
-
groupSizePixels,
|
|
1277
1086
|
layout: unsafeLayout,
|
|
1278
1087
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1279
1088
|
});
|
|
@@ -1281,16 +1090,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1281
1090
|
setLayout(safeLayout);
|
|
1282
1091
|
eagerValuesRef.current.layout = safeLayout;
|
|
1283
1092
|
if (onLayout) {
|
|
1284
|
-
onLayout(safeLayout
|
|
1285
|
-
sizePercentage,
|
|
1286
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1287
|
-
})));
|
|
1093
|
+
onLayout(safeLayout);
|
|
1288
1094
|
}
|
|
1289
|
-
callPanelCallbacks(
|
|
1095
|
+
callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1290
1096
|
}
|
|
1291
1097
|
}
|
|
1292
1098
|
}), []);
|
|
1293
|
-
|
|
1294
1099
|
useWindowSplitterPanelGroupBehavior({
|
|
1295
1100
|
committedValuesRef,
|
|
1296
1101
|
eagerValuesRef,
|
|
@@ -1309,12 +1114,14 @@ function PanelGroupWithForwardedRef({
|
|
|
1309
1114
|
if (layout.length === 0 || layout.length !== panelDataArray.length) {
|
|
1310
1115
|
return;
|
|
1311
1116
|
}
|
|
1117
|
+
let debouncedSave = debounceMap[autoSaveId];
|
|
1312
1118
|
|
|
1313
1119
|
// Limit the frequency of localStorage updates.
|
|
1314
|
-
if (
|
|
1315
|
-
|
|
1120
|
+
if (debouncedSave == null) {
|
|
1121
|
+
debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1122
|
+
debounceMap[autoSaveId] = debouncedSave;
|
|
1316
1123
|
}
|
|
1317
|
-
|
|
1124
|
+
debouncedSave(autoSaveId, panelDataArray, layout, storage);
|
|
1318
1125
|
}
|
|
1319
1126
|
}, [autoSaveId, layout, storage]);
|
|
1320
1127
|
|
|
@@ -1347,12 +1154,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1347
1154
|
}
|
|
1348
1155
|
if (!didLogPanelConstraintsWarning) {
|
|
1349
1156
|
const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
|
|
1350
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1351
1157
|
for (let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++) {
|
|
1158
|
+
const panelData = panelDataArray[panelIndex];
|
|
1159
|
+
assert(panelData);
|
|
1352
1160
|
const isValid = validatePanelConstraints({
|
|
1353
|
-
groupSizePixels,
|
|
1354
1161
|
panelConstraints,
|
|
1355
|
-
panelId:
|
|
1162
|
+
panelId: panelData.id,
|
|
1356
1163
|
panelIndex
|
|
1357
1164
|
});
|
|
1358
1165
|
if (!isValid) {
|
|
@@ -1376,20 +1183,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1376
1183
|
if (panelData.constraints.collapsible) {
|
|
1377
1184
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1378
1185
|
const {
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
pivotIndices
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
if (
|
|
1186
|
+
collapsedSize = 0,
|
|
1187
|
+
panelSize,
|
|
1188
|
+
pivotIndices
|
|
1189
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1190
|
+
assert(panelSize != null);
|
|
1191
|
+
if (panelSize !== collapsedSize) {
|
|
1385
1192
|
// Store size before collapse;
|
|
1386
1193
|
// This is the size that gets restored if the expand() API is used.
|
|
1387
|
-
panelSizeBeforeCollapseRef.current.set(panelData.id,
|
|
1194
|
+
panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
|
|
1388
1195
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1389
|
-
const delta = isLastPanel ?
|
|
1196
|
+
const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
|
|
1390
1197
|
const nextLayout = adjustLayoutByDelta({
|
|
1391
1198
|
delta,
|
|
1392
|
-
groupSizePixels,
|
|
1393
1199
|
layout: prevLayout,
|
|
1394
1200
|
panelConstraints: panelConstraintsArray,
|
|
1395
1201
|
pivotIndices,
|
|
@@ -1399,16 +1205,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1399
1205
|
setLayout(nextLayout);
|
|
1400
1206
|
eagerValuesRef.current.layout = nextLayout;
|
|
1401
1207
|
if (onLayout) {
|
|
1402
|
-
onLayout(nextLayout
|
|
1403
|
-
sizePercentage,
|
|
1404
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1405
|
-
})));
|
|
1208
|
+
onLayout(nextLayout);
|
|
1406
1209
|
}
|
|
1407
|
-
callPanelCallbacks(
|
|
1210
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1408
1211
|
}
|
|
1409
1212
|
}
|
|
1410
1213
|
}
|
|
1411
|
-
}, [
|
|
1214
|
+
}, []);
|
|
1412
1215
|
|
|
1413
1216
|
// External APIs are safe to memoize via committed values ref
|
|
1414
1217
|
const expandPanel = useCallback(panelData => {
|
|
@@ -1422,21 +1225,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1422
1225
|
if (panelData.constraints.collapsible) {
|
|
1423
1226
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1424
1227
|
const {
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
pivotIndices
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
if (panelSizePercentage === collapsedSizePercentage) {
|
|
1228
|
+
collapsedSize = 0,
|
|
1229
|
+
panelSize,
|
|
1230
|
+
minSize = 0,
|
|
1231
|
+
pivotIndices
|
|
1232
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1233
|
+
if (panelSize === collapsedSize) {
|
|
1432
1234
|
// Restore this panel to the size it was before it was collapsed, if possible.
|
|
1433
|
-
const
|
|
1434
|
-
const
|
|
1235
|
+
const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
|
|
1236
|
+
const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
|
|
1435
1237
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1436
|
-
const delta = isLastPanel ?
|
|
1238
|
+
const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
|
|
1437
1239
|
const nextLayout = adjustLayoutByDelta({
|
|
1438
1240
|
delta,
|
|
1439
|
-
groupSizePixels,
|
|
1440
1241
|
layout: prevLayout,
|
|
1441
1242
|
panelConstraints: panelConstraintsArray,
|
|
1442
1243
|
pivotIndices,
|
|
@@ -1446,16 +1247,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1446
1247
|
setLayout(nextLayout);
|
|
1447
1248
|
eagerValuesRef.current.layout = nextLayout;
|
|
1448
1249
|
if (onLayout) {
|
|
1449
|
-
onLayout(nextLayout
|
|
1450
|
-
sizePercentage,
|
|
1451
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1452
|
-
})));
|
|
1250
|
+
onLayout(nextLayout);
|
|
1453
1251
|
}
|
|
1454
|
-
callPanelCallbacks(
|
|
1252
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1455
1253
|
}
|
|
1456
1254
|
}
|
|
1457
1255
|
}
|
|
1458
|
-
}, [
|
|
1256
|
+
}, []);
|
|
1459
1257
|
|
|
1460
1258
|
// External APIs are safe to memoize via committed values ref
|
|
1461
1259
|
const getPanelSize = useCallback(panelData => {
|
|
@@ -1464,14 +1262,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1464
1262
|
panelDataArray
|
|
1465
1263
|
} = eagerValuesRef.current;
|
|
1466
1264
|
const {
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
return
|
|
1471
|
-
|
|
1472
|
-
sizePixels: panelSizePixels
|
|
1473
|
-
};
|
|
1474
|
-
}, [groupId]);
|
|
1265
|
+
panelSize
|
|
1266
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1267
|
+
assert(panelSize != null);
|
|
1268
|
+
return panelSize;
|
|
1269
|
+
}, []);
|
|
1475
1270
|
|
|
1476
1271
|
// This API should never read from committedValuesRef
|
|
1477
1272
|
const getPanelStyle = useCallback(panelData => {
|
|
@@ -1494,12 +1289,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1494
1289
|
panelDataArray
|
|
1495
1290
|
} = eagerValuesRef.current;
|
|
1496
1291
|
const {
|
|
1497
|
-
|
|
1292
|
+
collapsedSize,
|
|
1498
1293
|
collapsible,
|
|
1499
|
-
|
|
1500
|
-
} = panelDataHelper(
|
|
1501
|
-
return collapsible === true &&
|
|
1502
|
-
}, [
|
|
1294
|
+
panelSize
|
|
1295
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1296
|
+
return collapsible === true && panelSize === collapsedSize;
|
|
1297
|
+
}, []);
|
|
1503
1298
|
|
|
1504
1299
|
// External APIs are safe to memoize via committed values ref
|
|
1505
1300
|
const isPanelExpanded = useCallback(panelData => {
|
|
@@ -1508,12 +1303,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1508
1303
|
panelDataArray
|
|
1509
1304
|
} = eagerValuesRef.current;
|
|
1510
1305
|
const {
|
|
1511
|
-
|
|
1306
|
+
collapsedSize = 0,
|
|
1512
1307
|
collapsible,
|
|
1513
|
-
|
|
1514
|
-
} = panelDataHelper(
|
|
1515
|
-
|
|
1516
|
-
|
|
1308
|
+
panelSize
|
|
1309
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1310
|
+
assert(panelSize != null);
|
|
1311
|
+
return !collapsible || panelSize > collapsedSize;
|
|
1312
|
+
}, []);
|
|
1517
1313
|
const registerPanel = useCallback(panelData => {
|
|
1518
1314
|
const {
|
|
1519
1315
|
autoSaveId,
|
|
@@ -1553,18 +1349,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1553
1349
|
if (autoSaveId) {
|
|
1554
1350
|
unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
|
|
1555
1351
|
}
|
|
1556
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1557
|
-
if (groupSizePixels <= 0) {
|
|
1558
|
-
if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
|
|
1559
|
-
constraints
|
|
1560
|
-
}) => constraints))) {
|
|
1561
|
-
// Wait until the group has rendered a non-zero size before computing layout.
|
|
1562
|
-
return;
|
|
1563
|
-
}
|
|
1564
|
-
}
|
|
1565
1352
|
if (unsafeLayout == null) {
|
|
1566
1353
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1567
|
-
groupSizePixels,
|
|
1568
1354
|
panelDataArray
|
|
1569
1355
|
});
|
|
1570
1356
|
}
|
|
@@ -1572,7 +1358,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1572
1358
|
// Validate even saved layouts in case something has changed since last render
|
|
1573
1359
|
// e.g. for pixel groups, this could be the size of the window
|
|
1574
1360
|
const nextLayout = validatePanelGroupLayout({
|
|
1575
|
-
groupSizePixels,
|
|
1576
1361
|
layout: unsafeLayout,
|
|
1577
1362
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1578
1363
|
});
|
|
@@ -1584,12 +1369,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1584
1369
|
eagerValuesRef.current.layout = nextLayout;
|
|
1585
1370
|
if (!areEqual(prevLayout, nextLayout)) {
|
|
1586
1371
|
if (onLayout) {
|
|
1587
|
-
onLayout(nextLayout
|
|
1588
|
-
sizePercentage,
|
|
1589
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1590
|
-
})));
|
|
1372
|
+
onLayout(nextLayout);
|
|
1591
1373
|
}
|
|
1592
|
-
callPanelCallbacks(
|
|
1374
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1593
1375
|
}
|
|
1594
1376
|
}, []);
|
|
1595
1377
|
const registerResizeHandle = useCallback(dragHandleId => {
|
|
@@ -1599,8 +1381,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1599
1381
|
direction,
|
|
1600
1382
|
dragState,
|
|
1601
1383
|
id: groupId,
|
|
1602
|
-
|
|
1603
|
-
keyboardResizeByPixels,
|
|
1384
|
+
keyboardResizeBy,
|
|
1604
1385
|
onLayout
|
|
1605
1386
|
} = committedValuesRef.current;
|
|
1606
1387
|
const {
|
|
@@ -1611,10 +1392,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1611
1392
|
initialLayout
|
|
1612
1393
|
} = dragState !== null && dragState !== void 0 ? dragState : {};
|
|
1613
1394
|
const pivotIndices = determinePivotIndices(groupId, dragHandleId);
|
|
1614
|
-
let delta = calculateDeltaPercentage(event,
|
|
1615
|
-
percentage: keyboardResizeByPercentage,
|
|
1616
|
-
pixels: keyboardResizeByPixels
|
|
1617
|
-
});
|
|
1395
|
+
let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
|
|
1618
1396
|
if (delta === 0) {
|
|
1619
1397
|
return;
|
|
1620
1398
|
}
|
|
@@ -1624,11 +1402,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1624
1402
|
if (document.dir === "rtl" && isHorizontal) {
|
|
1625
1403
|
delta = -delta;
|
|
1626
1404
|
}
|
|
1627
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1628
1405
|
const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
|
|
1629
1406
|
const nextLayout = adjustLayoutByDelta({
|
|
1630
1407
|
delta,
|
|
1631
|
-
groupSizePixels,
|
|
1632
1408
|
layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
|
|
1633
1409
|
panelConstraints,
|
|
1634
1410
|
pivotIndices,
|
|
@@ -1664,18 +1440,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1664
1440
|
setLayout(nextLayout);
|
|
1665
1441
|
eagerValuesRef.current.layout = nextLayout;
|
|
1666
1442
|
if (onLayout) {
|
|
1667
|
-
onLayout(nextLayout
|
|
1668
|
-
sizePercentage,
|
|
1669
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1670
|
-
})));
|
|
1443
|
+
onLayout(nextLayout);
|
|
1671
1444
|
}
|
|
1672
|
-
callPanelCallbacks(
|
|
1445
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1673
1446
|
}
|
|
1674
1447
|
};
|
|
1675
1448
|
}, []);
|
|
1676
1449
|
|
|
1677
1450
|
// External APIs are safe to memoize via committed values ref
|
|
1678
|
-
const resizePanel = useCallback((panelData,
|
|
1451
|
+
const resizePanel = useCallback((panelData, unsafePanelSize) => {
|
|
1679
1452
|
const {
|
|
1680
1453
|
onLayout
|
|
1681
1454
|
} = committedValuesRef.current;
|
|
@@ -1685,16 +1458,14 @@ function PanelGroupWithForwardedRef({
|
|
|
1685
1458
|
} = eagerValuesRef.current;
|
|
1686
1459
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1687
1460
|
const {
|
|
1688
|
-
|
|
1689
|
-
panelSizePercentage,
|
|
1461
|
+
panelSize,
|
|
1690
1462
|
pivotIndices
|
|
1691
|
-
} = panelDataHelper(
|
|
1692
|
-
|
|
1463
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1464
|
+
assert(panelSize != null);
|
|
1693
1465
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1694
|
-
const delta = isLastPanel ?
|
|
1466
|
+
const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
|
|
1695
1467
|
const nextLayout = adjustLayoutByDelta({
|
|
1696
1468
|
delta,
|
|
1697
|
-
groupSizePixels,
|
|
1698
1469
|
layout: prevLayout,
|
|
1699
1470
|
panelConstraints: panelConstraintsArray,
|
|
1700
1471
|
pivotIndices,
|
|
@@ -1704,14 +1475,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1704
1475
|
setLayout(nextLayout);
|
|
1705
1476
|
eagerValuesRef.current.layout = nextLayout;
|
|
1706
1477
|
if (onLayout) {
|
|
1707
|
-
onLayout(nextLayout
|
|
1708
|
-
sizePercentage,
|
|
1709
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1710
|
-
})));
|
|
1478
|
+
onLayout(nextLayout);
|
|
1711
1479
|
}
|
|
1712
|
-
callPanelCallbacks(
|
|
1480
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1713
1481
|
}
|
|
1714
|
-
}, [
|
|
1482
|
+
}, []);
|
|
1715
1483
|
const startDragging = useCallback((dragHandleId, event) => {
|
|
1716
1484
|
const {
|
|
1717
1485
|
direction
|
|
@@ -1720,6 +1488,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1720
1488
|
layout
|
|
1721
1489
|
} = eagerValuesRef.current;
|
|
1722
1490
|
const handleElement = getResizeHandleElement(dragHandleId);
|
|
1491
|
+
assert(handleElement);
|
|
1723
1492
|
const initialCursorPosition = getResizeEventCursorPosition(direction, event);
|
|
1724
1493
|
setDragState({
|
|
1725
1494
|
dragHandleId,
|
|
@@ -1738,7 +1507,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1738
1507
|
});
|
|
1739
1508
|
const unregisterPanel = useCallback(panelData => {
|
|
1740
1509
|
const {
|
|
1741
|
-
id: groupId,
|
|
1742
1510
|
onLayout
|
|
1743
1511
|
} = committedValuesRef.current;
|
|
1744
1512
|
const {
|
|
@@ -1761,7 +1529,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1761
1529
|
const {
|
|
1762
1530
|
pendingPanelIds
|
|
1763
1531
|
} = unregisterPanelRef.current;
|
|
1764
|
-
const map =
|
|
1532
|
+
const map = panelIdToLastNotifiedSizeMapRef.current;
|
|
1765
1533
|
|
|
1766
1534
|
// TRICKY
|
|
1767
1535
|
// Strict effects mode
|
|
@@ -1770,7 +1538,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1770
1538
|
pendingPanelIds.delete(panelId);
|
|
1771
1539
|
if (panelDataArray.find(({
|
|
1772
1540
|
id
|
|
1773
|
-
}) => id === panelId)
|
|
1541
|
+
}) => id === panelId) != null) {
|
|
1774
1542
|
unmountDueToStrictMode = true;
|
|
1775
1543
|
|
|
1776
1544
|
// TRICKY
|
|
@@ -1787,16 +1555,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1787
1555
|
// The group is unmounting; skip layout calculation.
|
|
1788
1556
|
return;
|
|
1789
1557
|
}
|
|
1790
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1791
1558
|
let unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1792
|
-
groupSizePixels,
|
|
1793
1559
|
panelDataArray
|
|
1794
1560
|
});
|
|
1795
1561
|
|
|
1796
1562
|
// Validate even saved layouts in case something has changed since last render
|
|
1797
1563
|
// e.g. for pixel groups, this could be the size of the window
|
|
1798
1564
|
const nextLayout = validatePanelGroupLayout({
|
|
1799
|
-
groupSizePixels,
|
|
1800
1565
|
layout: unsafeLayout,
|
|
1801
1566
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1802
1567
|
});
|
|
@@ -1804,12 +1569,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1804
1569
|
setLayout(nextLayout);
|
|
1805
1570
|
eagerValuesRef.current.layout = nextLayout;
|
|
1806
1571
|
if (onLayout) {
|
|
1807
|
-
onLayout(nextLayout
|
|
1808
|
-
sizePercentage,
|
|
1809
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1810
|
-
})));
|
|
1572
|
+
onLayout(nextLayout);
|
|
1811
1573
|
}
|
|
1812
|
-
callPanelCallbacks(
|
|
1574
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1813
1575
|
}
|
|
1814
1576
|
}, 0);
|
|
1815
1577
|
}, []);
|
|
@@ -1840,13 +1602,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1840
1602
|
return createElement(PanelGroupContext.Provider, {
|
|
1841
1603
|
value: context
|
|
1842
1604
|
}, createElement(Type, {
|
|
1605
|
+
...rest,
|
|
1843
1606
|
children,
|
|
1844
1607
|
className: classNameFromProps,
|
|
1845
1608
|
style: {
|
|
1846
1609
|
...style,
|
|
1847
1610
|
...styleFromProps
|
|
1848
1611
|
},
|
|
1849
|
-
...dataAttributes,
|
|
1850
1612
|
// CSS selectors
|
|
1851
1613
|
"data-panel-group": "",
|
|
1852
1614
|
"data-panel-group-direction": direction,
|
|
@@ -1859,22 +1621,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
|
|
|
1859
1621
|
}));
|
|
1860
1622
|
PanelGroupWithForwardedRef.displayName = "PanelGroup";
|
|
1861
1623
|
PanelGroup.displayName = "forwardRef(PanelGroup)";
|
|
1862
|
-
function panelDataHelper(
|
|
1624
|
+
function panelDataHelper(panelDataArray, panelData, layout) {
|
|
1863
1625
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1864
1626
|
const panelIndex = panelDataArray.indexOf(panelData);
|
|
1865
1627
|
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
1866
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1867
|
-
const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
|
|
1868
1628
|
const isLastPanel = panelIndex === panelDataArray.length - 1;
|
|
1869
1629
|
const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
|
|
1870
|
-
const
|
|
1871
|
-
const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
|
|
1630
|
+
const panelSize = layout[panelIndex];
|
|
1872
1631
|
return {
|
|
1873
|
-
...
|
|
1874
|
-
|
|
1875
|
-
panelSizePercentage,
|
|
1876
|
-
panelSizePixels,
|
|
1877
|
-
groupSizePixels,
|
|
1632
|
+
...panelConstraints,
|
|
1633
|
+
panelSize,
|
|
1878
1634
|
pivotIndices
|
|
1879
1635
|
};
|
|
1880
1636
|
}
|
|
@@ -1914,6 +1670,7 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1914
1670
|
{
|
|
1915
1671
|
event.preventDefault();
|
|
1916
1672
|
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
1673
|
+
assert(groupId);
|
|
1917
1674
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
1918
1675
|
const index = getResizeHandleElementIndex(groupId, handleId);
|
|
1919
1676
|
assert(index !== null);
|
|
@@ -1934,12 +1691,13 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1934
1691
|
function PanelResizeHandle({
|
|
1935
1692
|
children = null,
|
|
1936
1693
|
className: classNameFromProps = "",
|
|
1937
|
-
dataAttributes,
|
|
1938
1694
|
disabled = false,
|
|
1939
|
-
id: idFromProps
|
|
1695
|
+
id: idFromProps,
|
|
1940
1696
|
onDragging,
|
|
1941
1697
|
style: styleFromProps = {},
|
|
1942
|
-
|
|
1698
|
+
tabIndex = 0,
|
|
1699
|
+
tagName: Type = "div",
|
|
1700
|
+
...rest
|
|
1943
1701
|
}) {
|
|
1944
1702
|
const divElementRef = useRef(null);
|
|
1945
1703
|
|
|
@@ -1969,8 +1727,9 @@ function PanelResizeHandle({
|
|
|
1969
1727
|
const stopDraggingAndBlur = useCallback(() => {
|
|
1970
1728
|
// Clicking on the drag handle shouldn't leave it focused;
|
|
1971
1729
|
// That would cause the PanelGroup to think it was still active.
|
|
1972
|
-
const
|
|
1973
|
-
|
|
1730
|
+
const divElement = divElementRef.current;
|
|
1731
|
+
assert(divElement);
|
|
1732
|
+
divElement.blur();
|
|
1974
1733
|
stopDragging();
|
|
1975
1734
|
const {
|
|
1976
1735
|
onDragging
|
|
@@ -1998,6 +1757,7 @@ function PanelResizeHandle({
|
|
|
1998
1757
|
resizeHandler(event);
|
|
1999
1758
|
};
|
|
2000
1759
|
const divElement = divElementRef.current;
|
|
1760
|
+
assert(divElement);
|
|
2001
1761
|
const targetDocument = divElement.ownerDocument;
|
|
2002
1762
|
targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
|
|
2003
1763
|
targetDocument.body.addEventListener("mousemove", onMove);
|
|
@@ -2025,15 +1785,18 @@ function PanelResizeHandle({
|
|
|
2025
1785
|
userSelect: "none"
|
|
2026
1786
|
};
|
|
2027
1787
|
return createElement(Type, {
|
|
1788
|
+
...rest,
|
|
2028
1789
|
children,
|
|
2029
1790
|
className: classNameFromProps,
|
|
2030
1791
|
onBlur: () => setIsFocused(false),
|
|
2031
1792
|
onFocus: () => setIsFocused(true),
|
|
2032
1793
|
onMouseDown: event => {
|
|
2033
1794
|
startDragging(resizeHandleId, event.nativeEvent);
|
|
1795
|
+
const callbacks = callbacksRef.current;
|
|
1796
|
+
assert(callbacks);
|
|
2034
1797
|
const {
|
|
2035
1798
|
onDragging
|
|
2036
|
-
} =
|
|
1799
|
+
} = callbacks;
|
|
2037
1800
|
if (onDragging) {
|
|
2038
1801
|
onDragging(true);
|
|
2039
1802
|
}
|
|
@@ -2043,9 +1806,11 @@ function PanelResizeHandle({
|
|
|
2043
1806
|
onTouchEnd: stopDraggingAndBlur,
|
|
2044
1807
|
onTouchStart: event => {
|
|
2045
1808
|
startDragging(resizeHandleId, event.nativeEvent);
|
|
1809
|
+
const callbacks = callbacksRef.current;
|
|
1810
|
+
assert(callbacks);
|
|
2046
1811
|
const {
|
|
2047
1812
|
onDragging
|
|
2048
|
-
} =
|
|
1813
|
+
} = callbacks;
|
|
2049
1814
|
if (onDragging) {
|
|
2050
1815
|
onDragging(true);
|
|
2051
1816
|
}
|
|
@@ -2056,8 +1821,7 @@ function PanelResizeHandle({
|
|
|
2056
1821
|
...style,
|
|
2057
1822
|
...styleFromProps
|
|
2058
1823
|
},
|
|
2059
|
-
tabIndex
|
|
2060
|
-
...dataAttributes,
|
|
1824
|
+
tabIndex,
|
|
2061
1825
|
// CSS selectors
|
|
2062
1826
|
"data-panel-group-direction": direction,
|
|
2063
1827
|
"data-panel-group-id": groupId,
|
|
@@ -2069,4 +1833,4 @@ function PanelResizeHandle({
|
|
|
2069
1833
|
}
|
|
2070
1834
|
PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
2071
1835
|
|
|
2072
|
-
export { Panel, PanelGroup, PanelResizeHandle };
|
|
1836
|
+
export { Panel, PanelGroup, PanelResizeHandle, assert };
|