react-resizable-panels 0.0.62 → 1.0.0-rc.1
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 +9 -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 +255 -519
- package/dist/react-resizable-panels.browser.cjs.mjs +2 -1
- package/dist/react-resizable-panels.browser.development.cjs.js +281 -575
- package/dist/react-resizable-panels.browser.development.cjs.mjs +2 -1
- package/dist/react-resizable-panels.browser.development.esm.js +281 -576
- package/dist/react-resizable-panels.browser.esm.js +255 -520
- package/dist/react-resizable-panels.cjs.js +255 -519
- package/dist/react-resizable-panels.cjs.js.map +1 -0
- package/dist/react-resizable-panels.cjs.mjs +2 -1
- package/dist/react-resizable-panels.development.cjs.js +283 -577
- package/dist/react-resizable-panels.development.cjs.mjs +2 -1
- package/dist/react-resizable-panels.development.esm.js +283 -578
- package/dist/react-resizable-panels.development.node.cjs.js +269 -503
- package/dist/react-resizable-panels.development.node.cjs.mjs +2 -1
- package/dist/react-resizable-panels.development.node.esm.js +269 -504
- package/dist/react-resizable-panels.esm.js +255 -520
- package/dist/react-resizable-panels.esm.js.map +1 -0
- package/dist/react-resizable-panels.node.cjs.js +241 -445
- package/dist/react-resizable-panels.node.cjs.mjs +2 -1
- package/dist/react-resizable-panels.node.esm.js +241 -446
- 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 +189 -403
- 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/computePanelFlexBoxStyle.ts +3 -2
- 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
|
@@ -63,24 +63,20 @@ function useUniqueId(idFromParams = null) {
|
|
|
63
63
|
function PanelWithForwardedRef({
|
|
64
64
|
children,
|
|
65
65
|
className: classNameFromProps = "",
|
|
66
|
-
|
|
67
|
-
collapsedSizePixels,
|
|
66
|
+
collapsedSize,
|
|
68
67
|
collapsible,
|
|
69
|
-
|
|
70
|
-
defaultSizePercentage,
|
|
71
|
-
defaultSizePixels,
|
|
68
|
+
defaultSize,
|
|
72
69
|
forwardedRef,
|
|
73
70
|
id: idFromProps,
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
minSizePercentage,
|
|
77
|
-
minSizePixels,
|
|
71
|
+
maxSize,
|
|
72
|
+
minSize,
|
|
78
73
|
onCollapse,
|
|
79
74
|
onExpand,
|
|
80
75
|
onResize,
|
|
81
76
|
order,
|
|
82
77
|
style: styleFromProps,
|
|
83
|
-
tagName: Type = "div"
|
|
78
|
+
tagName: Type = "div",
|
|
79
|
+
...rest
|
|
84
80
|
}) {
|
|
85
81
|
const context = useContext(PanelGroupContext);
|
|
86
82
|
if (context === null) {
|
|
@@ -105,15 +101,11 @@ function PanelWithForwardedRef({
|
|
|
105
101
|
onResize
|
|
106
102
|
},
|
|
107
103
|
constraints: {
|
|
108
|
-
|
|
109
|
-
collapsedSizePixels,
|
|
104
|
+
collapsedSize,
|
|
110
105
|
collapsible,
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
maxSizePixels,
|
|
115
|
-
minSizePercentage,
|
|
116
|
-
minSizePixels
|
|
106
|
+
defaultSize,
|
|
107
|
+
maxSize,
|
|
108
|
+
minSize
|
|
117
109
|
},
|
|
118
110
|
id: panelId,
|
|
119
111
|
idIsFromProps: idFromProps !== undefined,
|
|
@@ -127,9 +119,9 @@ function PanelWithForwardedRef({
|
|
|
127
119
|
// but effects don't run on the server, so we can't do it there
|
|
128
120
|
{
|
|
129
121
|
if (!devWarningsRef.current.didLogMissingDefaultSizeWarning) {
|
|
130
|
-
if (
|
|
122
|
+
if (defaultSize == null) {
|
|
131
123
|
devWarningsRef.current.didLogMissingDefaultSizeWarning = true;
|
|
132
|
-
console.warn(`WARNING: Panel
|
|
124
|
+
console.warn(`WARNING: Panel defaultSize prop recommended to avoid layout shift after server rendering`);
|
|
133
125
|
}
|
|
134
126
|
}
|
|
135
127
|
}
|
|
@@ -152,19 +144,19 @@ function PanelWithForwardedRef({
|
|
|
152
144
|
isExpanded() {
|
|
153
145
|
return !isPanelCollapsed(panelDataRef.current);
|
|
154
146
|
},
|
|
155
|
-
resize:
|
|
156
|
-
resizePanel(panelDataRef.current,
|
|
147
|
+
resize: size => {
|
|
148
|
+
resizePanel(panelDataRef.current, size);
|
|
157
149
|
}
|
|
158
150
|
}), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
|
|
159
151
|
const style = getPanelStyle(panelDataRef.current);
|
|
160
152
|
return createElement(Type, {
|
|
153
|
+
...rest,
|
|
161
154
|
children,
|
|
162
155
|
className: classNameFromProps,
|
|
163
156
|
style: {
|
|
164
157
|
...style,
|
|
165
158
|
...styleFromProps
|
|
166
159
|
},
|
|
167
|
-
...dataAttributes,
|
|
168
160
|
// CSS selectors
|
|
169
161
|
"data-panel": "",
|
|
170
162
|
"data-panel-id": panelId,
|
|
@@ -181,81 +173,11 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
|
|
|
181
173
|
PanelWithForwardedRef.displayName = "Panel";
|
|
182
174
|
Panel.displayName = "forwardRef(Panel)";
|
|
183
175
|
|
|
184
|
-
function
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels) {
|
|
189
|
-
let {
|
|
190
|
-
collapsedSizePercentage = 0,
|
|
191
|
-
collapsedSizePixels,
|
|
192
|
-
defaultSizePercentage,
|
|
193
|
-
defaultSizePixels,
|
|
194
|
-
maxSizePercentage = 100,
|
|
195
|
-
maxSizePixels,
|
|
196
|
-
minSizePercentage = 0,
|
|
197
|
-
minSizePixels
|
|
198
|
-
} = panelConstraints;
|
|
199
|
-
const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
|
|
200
|
-
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
201
|
-
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
202
|
-
return {
|
|
203
|
-
collapsedSizePercentage: 0,
|
|
204
|
-
defaultSizePercentage,
|
|
205
|
-
maxSizePercentage: 0,
|
|
206
|
-
minSizePercentage: 0
|
|
207
|
-
};
|
|
208
|
-
}
|
|
209
|
-
if (collapsedSizePixels != null) {
|
|
210
|
-
collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
|
|
211
|
-
}
|
|
212
|
-
if (defaultSizePixels != null) {
|
|
213
|
-
defaultSizePercentage = convertPixelsToPercentage(defaultSizePixels, groupSizePixels);
|
|
214
|
-
}
|
|
215
|
-
if (minSizePixels != null) {
|
|
216
|
-
minSizePercentage = convertPixelsToPercentage(minSizePixels, groupSizePixels);
|
|
217
|
-
}
|
|
218
|
-
if (maxSizePixels != null) {
|
|
219
|
-
maxSizePercentage = convertPixelsToPercentage(maxSizePixels, groupSizePixels);
|
|
220
|
-
}
|
|
221
|
-
return {
|
|
222
|
-
collapsedSizePercentage,
|
|
223
|
-
defaultSizePercentage,
|
|
224
|
-
maxSizePercentage,
|
|
225
|
-
minSizePercentage
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels) {
|
|
230
|
-
// All panel constraints, excluding the current one
|
|
231
|
-
let totalMinConstraints = 0;
|
|
232
|
-
let totalMaxConstraints = 0;
|
|
233
|
-
for (let index = 0; index < panelConstraintsArray.length; index++) {
|
|
234
|
-
if (index !== panelIndex) {
|
|
235
|
-
const {
|
|
236
|
-
collapsible
|
|
237
|
-
} = panelConstraintsArray[index];
|
|
238
|
-
const {
|
|
239
|
-
collapsedSizePercentage,
|
|
240
|
-
maxSizePercentage,
|
|
241
|
-
minSizePercentage
|
|
242
|
-
} = convertPixelConstraintsToPercentages(panelConstraintsArray[index], groupSizePixels);
|
|
243
|
-
totalMaxConstraints += maxSizePercentage;
|
|
244
|
-
totalMinConstraints += collapsible ? collapsedSizePercentage : minSizePercentage;
|
|
245
|
-
}
|
|
176
|
+
function assert(expectedCondition, message = "Assertion failed!") {
|
|
177
|
+
if (!expectedCondition) {
|
|
178
|
+
console.error(message);
|
|
179
|
+
throw Error(message);
|
|
246
180
|
}
|
|
247
|
-
const {
|
|
248
|
-
collapsedSizePercentage,
|
|
249
|
-
defaultSizePercentage,
|
|
250
|
-
maxSizePercentage,
|
|
251
|
-
minSizePercentage
|
|
252
|
-
} = convertPixelConstraintsToPercentages(panelConstraintsArray[panelIndex], groupSizePixels);
|
|
253
|
-
return {
|
|
254
|
-
collapsedSizePercentage,
|
|
255
|
-
defaultSizePercentage,
|
|
256
|
-
maxSizePercentage: panelConstraintsArray.length > 1 ? Math.min(maxSizePercentage, 100 - totalMinConstraints) : maxSizePercentage,
|
|
257
|
-
minSizePercentage: panelConstraintsArray.length > 1 ? Math.max(minSizePercentage, 100 - totalMaxConstraints) : minSizePercentage
|
|
258
|
-
};
|
|
259
181
|
}
|
|
260
182
|
|
|
261
183
|
const PRECISION = 10;
|
|
@@ -277,56 +199,41 @@ function fuzzyNumbersEqual(actual, expected, fractionDigits) {
|
|
|
277
199
|
|
|
278
200
|
// Panel size must be in percentages; pixel values should be pre-converted
|
|
279
201
|
function resizePanel({
|
|
280
|
-
|
|
281
|
-
panelConstraints,
|
|
202
|
+
panelConstraints: panelConstraintsArray,
|
|
282
203
|
panelIndex,
|
|
283
204
|
size
|
|
284
205
|
}) {
|
|
285
|
-
const
|
|
286
|
-
|
|
287
|
-
defaultSizePixels,
|
|
288
|
-
minSizePixels,
|
|
289
|
-
maxSizePixels
|
|
290
|
-
}) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
|
|
291
|
-
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
292
|
-
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
293
|
-
return 0;
|
|
294
|
-
}
|
|
206
|
+
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
207
|
+
assert(panelConstraints != null);
|
|
295
208
|
let {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if (
|
|
306
|
-
|
|
307
|
-
const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
|
|
308
|
-
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
309
|
-
size = collapsedSizePercentage;
|
|
310
|
-
} else {
|
|
311
|
-
size = minSizePercentage;
|
|
312
|
-
}
|
|
209
|
+
collapsedSize = 0,
|
|
210
|
+
collapsible,
|
|
211
|
+
maxSize = 100,
|
|
212
|
+
minSize = 0
|
|
213
|
+
} = panelConstraints;
|
|
214
|
+
if (fuzzyCompareNumbers(size, minSize) < 0) {
|
|
215
|
+
if (collapsible) {
|
|
216
|
+
// Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
|
|
217
|
+
const halfwayPoint = (collapsedSize + minSize) / 2;
|
|
218
|
+
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
219
|
+
size = collapsedSize;
|
|
313
220
|
} else {
|
|
314
|
-
size =
|
|
221
|
+
size = minSize;
|
|
315
222
|
}
|
|
223
|
+
} else {
|
|
224
|
+
size = minSize;
|
|
316
225
|
}
|
|
317
226
|
}
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
}
|
|
227
|
+
size = Math.min(maxSize, size);
|
|
228
|
+
size = parseFloat(size.toFixed(PRECISION));
|
|
321
229
|
return size;
|
|
322
230
|
}
|
|
323
231
|
|
|
324
232
|
// All units must be in percentages; pixel values should be pre-converted
|
|
325
233
|
function adjustLayoutByDelta({
|
|
326
234
|
delta,
|
|
327
|
-
groupSizePixels,
|
|
328
235
|
layout: prevLayout,
|
|
329
|
-
panelConstraints,
|
|
236
|
+
panelConstraints: panelConstraintsArray,
|
|
330
237
|
pivotIndices,
|
|
331
238
|
trigger
|
|
332
239
|
}) {
|
|
@@ -334,6 +241,9 @@ function adjustLayoutByDelta({
|
|
|
334
241
|
return prevLayout;
|
|
335
242
|
}
|
|
336
243
|
const nextLayout = [...prevLayout];
|
|
244
|
+
const [firstPivotIndex, secondPivotIndex] = pivotIndices;
|
|
245
|
+
assert(firstPivotIndex != null);
|
|
246
|
+
assert(secondPivotIndex != null);
|
|
337
247
|
let deltaApplied = 0;
|
|
338
248
|
|
|
339
249
|
//const DEBUG = [];
|
|
@@ -357,18 +267,23 @@ function adjustLayoutByDelta({
|
|
|
357
267
|
if (trigger === "keyboard") {
|
|
358
268
|
{
|
|
359
269
|
// Check if we should expand a collapsed panel
|
|
360
|
-
const index = delta < 0 ?
|
|
361
|
-
const
|
|
270
|
+
const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
271
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
272
|
+
assert(panelConstraints);
|
|
273
|
+
|
|
362
274
|
//DEBUG.push(`edge case check 1: ${index}`);
|
|
363
275
|
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
364
|
-
if (
|
|
276
|
+
if (panelConstraints.collapsible) {
|
|
365
277
|
const prevSize = prevLayout[index];
|
|
278
|
+
assert(prevSize != null);
|
|
279
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
280
|
+
assert(panelConstraints);
|
|
366
281
|
const {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
} =
|
|
370
|
-
if (fuzzyNumbersEqual(prevSize,
|
|
371
|
-
const localDelta =
|
|
282
|
+
collapsedSize = 0,
|
|
283
|
+
minSize = 0
|
|
284
|
+
} = panelConstraints;
|
|
285
|
+
if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
|
|
286
|
+
const localDelta = minSize - prevSize;
|
|
372
287
|
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
373
288
|
|
|
374
289
|
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
@@ -381,18 +296,26 @@ function adjustLayoutByDelta({
|
|
|
381
296
|
|
|
382
297
|
{
|
|
383
298
|
// Check if we should collapse a panel at its minimum size
|
|
384
|
-
const index = delta < 0 ?
|
|
385
|
-
const
|
|
299
|
+
const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
300
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
301
|
+
assert(panelConstraints);
|
|
302
|
+
const {
|
|
303
|
+
collapsible
|
|
304
|
+
} = panelConstraints;
|
|
305
|
+
|
|
386
306
|
//DEBUG.push(`edge case check 2: ${index}`);
|
|
387
|
-
//DEBUG.push(` -> collapsible? ${
|
|
388
|
-
if (
|
|
307
|
+
//DEBUG.push(` -> collapsible? ${collapsible}`);
|
|
308
|
+
if (collapsible) {
|
|
389
309
|
const prevSize = prevLayout[index];
|
|
310
|
+
assert(prevSize != null);
|
|
311
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
312
|
+
assert(panelConstraints);
|
|
390
313
|
const {
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
} =
|
|
394
|
-
if (fuzzyNumbersEqual(prevSize,
|
|
395
|
-
const localDelta = prevSize -
|
|
314
|
+
collapsedSize = 0,
|
|
315
|
+
minSize = 0
|
|
316
|
+
} = panelConstraints;
|
|
317
|
+
if (fuzzyNumbersEqual(prevSize, minSize)) {
|
|
318
|
+
const localDelta = prevSize - collapsedSize;
|
|
396
319
|
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
397
320
|
|
|
398
321
|
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
@@ -414,15 +337,15 @@ function adjustLayoutByDelta({
|
|
|
414
337
|
// as an expanding panel might change from collapsed to min size.
|
|
415
338
|
|
|
416
339
|
const increment = delta < 0 ? 1 : -1;
|
|
417
|
-
let index = delta < 0 ?
|
|
340
|
+
let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
418
341
|
let maxAvailableDelta = 0;
|
|
419
342
|
|
|
420
343
|
//DEBUG.push("pre calc...");
|
|
421
344
|
while (true) {
|
|
422
345
|
const prevSize = prevLayout[index];
|
|
346
|
+
assert(prevSize != null);
|
|
423
347
|
const maxSafeSize = resizePanel({
|
|
424
|
-
|
|
425
|
-
panelConstraints,
|
|
348
|
+
panelConstraints: panelConstraintsArray,
|
|
426
349
|
panelIndex: index,
|
|
427
350
|
size: 100
|
|
428
351
|
});
|
|
@@ -431,7 +354,7 @@ function adjustLayoutByDelta({
|
|
|
431
354
|
|
|
432
355
|
maxAvailableDelta += delta;
|
|
433
356
|
index += increment;
|
|
434
|
-
if (index < 0 || index >=
|
|
357
|
+
if (index < 0 || index >= panelConstraintsArray.length) {
|
|
435
358
|
break;
|
|
436
359
|
}
|
|
437
360
|
}
|
|
@@ -446,15 +369,15 @@ function adjustLayoutByDelta({
|
|
|
446
369
|
{
|
|
447
370
|
// Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
|
|
448
371
|
|
|
449
|
-
const pivotIndex = delta < 0 ?
|
|
372
|
+
const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
450
373
|
let index = pivotIndex;
|
|
451
|
-
while (index >= 0 && index <
|
|
374
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
452
375
|
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
453
376
|
const prevSize = prevLayout[index];
|
|
377
|
+
assert(prevSize != null);
|
|
454
378
|
const unsafeSize = prevSize - deltaRemaining;
|
|
455
379
|
const safeSize = resizePanel({
|
|
456
|
-
|
|
457
|
-
panelConstraints,
|
|
380
|
+
panelConstraints: panelConstraintsArray,
|
|
458
381
|
panelIndex: index,
|
|
459
382
|
size: unsafeSize
|
|
460
383
|
});
|
|
@@ -486,11 +409,12 @@ function adjustLayoutByDelta({
|
|
|
486
409
|
}
|
|
487
410
|
{
|
|
488
411
|
// Now distribute the applied delta to the panels in the other direction
|
|
489
|
-
const pivotIndex = delta < 0 ?
|
|
490
|
-
const
|
|
412
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
413
|
+
const prevSize = prevLayout[pivotIndex];
|
|
414
|
+
assert(prevSize != null);
|
|
415
|
+
const unsafeSize = prevSize + deltaApplied;
|
|
491
416
|
const safeSize = resizePanel({
|
|
492
|
-
|
|
493
|
-
panelConstraints,
|
|
417
|
+
panelConstraints: panelConstraintsArray,
|
|
494
418
|
panelIndex: pivotIndex,
|
|
495
419
|
size: unsafeSize
|
|
496
420
|
});
|
|
@@ -501,14 +425,14 @@ function adjustLayoutByDelta({
|
|
|
501
425
|
// Edge case where expanding or contracting one panel caused another one to change collapsed state
|
|
502
426
|
if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
|
|
503
427
|
let deltaRemaining = unsafeSize - safeSize;
|
|
504
|
-
const pivotIndex = delta < 0 ?
|
|
428
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
505
429
|
let index = pivotIndex;
|
|
506
|
-
while (index >= 0 && index <
|
|
430
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
507
431
|
const prevSize = nextLayout[index];
|
|
432
|
+
assert(prevSize != null);
|
|
508
433
|
const unsafeSize = prevSize + deltaRemaining;
|
|
509
434
|
const safeSize = resizePanel({
|
|
510
|
-
|
|
511
|
-
panelConstraints,
|
|
435
|
+
panelConstraints: panelConstraintsArray,
|
|
512
436
|
panelIndex: index,
|
|
513
437
|
size: unsafeSize
|
|
514
438
|
});
|
|
@@ -532,9 +456,7 @@ function adjustLayoutByDelta({
|
|
|
532
456
|
//DEBUG.push("");
|
|
533
457
|
|
|
534
458
|
const totalSize = nextLayout.reduce((total, size) => size + total, 0);
|
|
535
|
-
deltaApplied = 100 - totalSize;
|
|
536
459
|
//DEBUG.push(`total size: ${totalSize}`);
|
|
537
|
-
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
538
460
|
//console.log(DEBUG.join("\n"));
|
|
539
461
|
|
|
540
462
|
if (!fuzzyNumbersEqual(totalSize, 100)) {
|
|
@@ -543,25 +465,6 @@ function adjustLayoutByDelta({
|
|
|
543
465
|
return nextLayout;
|
|
544
466
|
}
|
|
545
467
|
|
|
546
|
-
function assert(expectedCondition, message = "Assertion failed!") {
|
|
547
|
-
if (!expectedCondition) {
|
|
548
|
-
console.error(message);
|
|
549
|
-
throw Error(message);
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
|
|
553
|
-
function getPercentageSizeFromMixedSizes({
|
|
554
|
-
sizePercentage,
|
|
555
|
-
sizePixels
|
|
556
|
-
}, groupSizePixels) {
|
|
557
|
-
if (sizePercentage != null) {
|
|
558
|
-
return sizePercentage;
|
|
559
|
-
} else if (sizePixels != null) {
|
|
560
|
-
return convertPixelsToPercentage(sizePixels, groupSizePixels);
|
|
561
|
-
}
|
|
562
|
-
return undefined;
|
|
563
|
-
}
|
|
564
|
-
|
|
565
468
|
function getResizeHandleElementsForGroup(groupId) {
|
|
566
469
|
return Array.from(document.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
|
|
567
470
|
}
|
|
@@ -585,42 +488,6 @@ function getPanelGroupElement(id) {
|
|
|
585
488
|
return null;
|
|
586
489
|
}
|
|
587
490
|
|
|
588
|
-
function calculateAvailablePanelSizeInPixels(groupId) {
|
|
589
|
-
const panelGroupElement = getPanelGroupElement(groupId);
|
|
590
|
-
if (panelGroupElement == null) {
|
|
591
|
-
return NaN;
|
|
592
|
-
}
|
|
593
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
594
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId);
|
|
595
|
-
if (direction === "horizontal") {
|
|
596
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
597
|
-
return accumulated + handle.offsetWidth;
|
|
598
|
-
}, 0);
|
|
599
|
-
} else {
|
|
600
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
601
|
-
return accumulated + handle.offsetHeight;
|
|
602
|
-
}, 0);
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
function getAvailableGroupSizePixels(groupId) {
|
|
607
|
-
const panelGroupElement = getPanelGroupElement(groupId);
|
|
608
|
-
if (panelGroupElement == null) {
|
|
609
|
-
return NaN;
|
|
610
|
-
}
|
|
611
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
612
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId);
|
|
613
|
-
if (direction === "horizontal") {
|
|
614
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
615
|
-
return accumulated + handle.offsetWidth;
|
|
616
|
-
}, 0);
|
|
617
|
-
} else {
|
|
618
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
619
|
-
return accumulated + handle.offsetHeight;
|
|
620
|
-
}, 0);
|
|
621
|
-
}
|
|
622
|
-
}
|
|
623
|
-
|
|
624
491
|
function getResizeHandleElement(id) {
|
|
625
492
|
const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
|
|
626
493
|
if (element) {
|
|
@@ -653,14 +520,18 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
653
520
|
didWarnAboutMissingResizeHandle: false
|
|
654
521
|
});
|
|
655
522
|
useEffect(() => {
|
|
523
|
+
const eagerValues = eagerValuesRef.current;
|
|
524
|
+
assert(eagerValues);
|
|
656
525
|
const {
|
|
657
526
|
panelDataArray
|
|
658
|
-
} =
|
|
527
|
+
} = eagerValues;
|
|
659
528
|
const groupElement = getPanelGroupElement(groupId);
|
|
660
529
|
assert(groupElement != null, `No group found for id "${groupId}"`);
|
|
661
530
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
531
|
+
assert(handles);
|
|
662
532
|
const cleanupFunctions = handles.map(handle => {
|
|
663
533
|
const handleId = handle.getAttribute("data-panel-resize-handle-id");
|
|
534
|
+
assert(handleId);
|
|
664
535
|
const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
|
|
665
536
|
if (idBefore == null || idAfter == null) {
|
|
666
537
|
return () => {};
|
|
@@ -676,21 +547,16 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
676
547
|
const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
|
|
677
548
|
if (index >= 0) {
|
|
678
549
|
const panelData = panelDataArray[index];
|
|
550
|
+
assert(panelData);
|
|
679
551
|
const size = layout[index];
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
687
|
-
const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
|
|
688
|
-
sizePercentage: panelData.constraints.minSizePercentage,
|
|
689
|
-
sizePixels: panelData.constraints.minSizePixels
|
|
690
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
|
|
552
|
+
const {
|
|
553
|
+
collapsedSize = 0,
|
|
554
|
+
collapsible,
|
|
555
|
+
minSize = 0
|
|
556
|
+
} = panelData.constraints;
|
|
557
|
+
if (size != null && collapsible) {
|
|
691
558
|
const nextLayout = adjustLayoutByDelta({
|
|
692
559
|
delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
|
|
693
|
-
groupSizePixels,
|
|
694
560
|
layout,
|
|
695
561
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints),
|
|
696
562
|
pivotIndices: determinePivotIndices(groupId, handleId),
|
|
@@ -744,6 +610,7 @@ function getResizeEventCursorPosition(direction, event) {
|
|
|
744
610
|
return isHorizontal ? event.clientX : event.clientY;
|
|
745
611
|
} else if (isTouchEvent(event)) {
|
|
746
612
|
const firstTouch = event.touches[0];
|
|
613
|
+
assert(firstTouch);
|
|
747
614
|
return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
|
|
748
615
|
} else {
|
|
749
616
|
throw Error(`Unsupported event type "${event.type}"`);
|
|
@@ -753,12 +620,15 @@ function getResizeEventCursorPosition(direction, event) {
|
|
|
753
620
|
function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
|
|
754
621
|
const isHorizontal = direction === "horizontal";
|
|
755
622
|
const handleElement = getResizeHandleElement(dragHandleId);
|
|
623
|
+
assert(handleElement);
|
|
756
624
|
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
625
|
+
assert(groupId);
|
|
757
626
|
let {
|
|
758
627
|
initialCursorPosition
|
|
759
628
|
} = initialDragState;
|
|
760
629
|
const cursorPosition = getResizeEventCursorPosition(direction, event);
|
|
761
630
|
const groupElement = getPanelGroupElement(groupId);
|
|
631
|
+
assert(groupElement);
|
|
762
632
|
const groupRect = groupElement.getBoundingClientRect();
|
|
763
633
|
const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
|
|
764
634
|
const offsetPixels = cursorPosition - initialCursorPosition;
|
|
@@ -767,19 +637,14 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
|
|
|
767
637
|
}
|
|
768
638
|
|
|
769
639
|
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
|
|
770
|
-
function calculateDeltaPercentage(event,
|
|
640
|
+
function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
|
|
771
641
|
if (isKeyDown(event)) {
|
|
772
642
|
const isHorizontal = direction === "horizontal";
|
|
773
|
-
const groupElement = getPanelGroupElement(groupId);
|
|
774
|
-
const rect = groupElement.getBoundingClientRect();
|
|
775
|
-
const groupSizeInPixels = isHorizontal ? rect.width : rect.height;
|
|
776
643
|
let delta = 0;
|
|
777
644
|
if (event.shiftKey) {
|
|
778
645
|
delta = 100;
|
|
779
|
-
} else if (
|
|
780
|
-
delta =
|
|
781
|
-
} else if (keyboardResizeByOptions.pixels != null) {
|
|
782
|
-
delta = keyboardResizeByOptions.pixels / groupSizeInPixels;
|
|
646
|
+
} else if (keyboardResizeBy != null) {
|
|
647
|
+
delta = keyboardResizeBy;
|
|
783
648
|
} else {
|
|
784
649
|
delta = 10;
|
|
785
650
|
}
|
|
@@ -806,37 +671,43 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
|
|
|
806
671
|
}
|
|
807
672
|
return movement;
|
|
808
673
|
} else {
|
|
674
|
+
if (initialDragState == null) {
|
|
675
|
+
return 0;
|
|
676
|
+
}
|
|
809
677
|
return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
|
|
810
678
|
}
|
|
811
679
|
}
|
|
812
680
|
|
|
813
681
|
function calculateUnsafeDefaultLayout({
|
|
814
|
-
groupSizePixels,
|
|
815
682
|
panelDataArray
|
|
816
683
|
}) {
|
|
817
684
|
const layout = Array(panelDataArray.length);
|
|
818
|
-
const
|
|
685
|
+
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
819
686
|
let numPanelsWithSizes = 0;
|
|
820
687
|
let remainingSize = 100;
|
|
821
688
|
|
|
822
689
|
// Distribute default sizes first
|
|
823
690
|
for (let index = 0; index < panelDataArray.length; index++) {
|
|
691
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
692
|
+
assert(panelConstraints);
|
|
824
693
|
const {
|
|
825
|
-
|
|
826
|
-
} =
|
|
827
|
-
if (
|
|
694
|
+
defaultSize
|
|
695
|
+
} = panelConstraints;
|
|
696
|
+
if (defaultSize != null) {
|
|
828
697
|
numPanelsWithSizes++;
|
|
829
|
-
layout[index] =
|
|
830
|
-
remainingSize -=
|
|
698
|
+
layout[index] = defaultSize;
|
|
699
|
+
remainingSize -= defaultSize;
|
|
831
700
|
}
|
|
832
701
|
}
|
|
833
702
|
|
|
834
703
|
// Remaining size should be distributed evenly between panels without default sizes
|
|
835
704
|
for (let index = 0; index < panelDataArray.length; index++) {
|
|
705
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
706
|
+
assert(panelConstraints);
|
|
836
707
|
const {
|
|
837
|
-
|
|
838
|
-
} =
|
|
839
|
-
if (
|
|
708
|
+
defaultSize
|
|
709
|
+
} = panelConstraints;
|
|
710
|
+
if (defaultSize != null) {
|
|
840
711
|
continue;
|
|
841
712
|
}
|
|
842
713
|
const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
|
|
@@ -848,54 +719,36 @@ function calculateUnsafeDefaultLayout({
|
|
|
848
719
|
return layout;
|
|
849
720
|
}
|
|
850
721
|
|
|
851
|
-
function convertPercentageToPixels(percentage, groupSizePixels) {
|
|
852
|
-
return percentage / 100 * groupSizePixels;
|
|
853
|
-
}
|
|
854
|
-
|
|
855
722
|
// Layout should be pre-converted into percentages
|
|
856
|
-
function callPanelCallbacks(
|
|
857
|
-
|
|
858
|
-
layout.forEach((sizePercentage, index) => {
|
|
723
|
+
function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
|
|
724
|
+
layout.forEach((size, index) => {
|
|
859
725
|
const panelData = panelsArray[index];
|
|
860
|
-
|
|
861
|
-
// Handle initial mount (when panels are registered too late to be in the panels array)
|
|
862
|
-
// The subsequent render+effects will handle the resize notification
|
|
863
|
-
return;
|
|
864
|
-
}
|
|
726
|
+
assert(panelData);
|
|
865
727
|
const {
|
|
866
728
|
callbacks,
|
|
867
729
|
constraints,
|
|
868
730
|
id: panelId
|
|
869
731
|
} = panelData;
|
|
870
732
|
const {
|
|
733
|
+
collapsedSize = 0,
|
|
871
734
|
collapsible
|
|
872
735
|
} = constraints;
|
|
873
|
-
const
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
};
|
|
877
|
-
const lastNotifiedMixedSizes = panelIdToLastNotifiedMixedSizesMap[panelId];
|
|
878
|
-
if (lastNotifiedMixedSizes == null || mixedSizes.sizePercentage !== lastNotifiedMixedSizes.sizePercentage || mixedSizes.sizePixels !== lastNotifiedMixedSizes.sizePixels) {
|
|
879
|
-
panelIdToLastNotifiedMixedSizesMap[panelId] = mixedSizes;
|
|
736
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
|
|
737
|
+
if (lastNotifiedSize == null || size !== lastNotifiedSize) {
|
|
738
|
+
panelIdToLastNotifiedSizeMap[panelId] = size;
|
|
880
739
|
const {
|
|
881
740
|
onCollapse,
|
|
882
741
|
onExpand,
|
|
883
742
|
onResize
|
|
884
743
|
} = callbacks;
|
|
885
744
|
if (onResize) {
|
|
886
|
-
onResize(
|
|
745
|
+
onResize(size, lastNotifiedSize);
|
|
887
746
|
}
|
|
888
747
|
if (collapsible && (onCollapse || onExpand)) {
|
|
889
|
-
|
|
890
|
-
const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
|
|
891
|
-
sizePercentage: constraints.collapsedSizePercentage,
|
|
892
|
-
sizePixels: constraints.collapsedSizePixels
|
|
893
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
894
|
-
const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
|
|
895
|
-
if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
|
|
748
|
+
if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
|
|
896
749
|
onExpand();
|
|
897
750
|
}
|
|
898
|
-
if (onCollapse && (
|
|
751
|
+
if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
|
|
899
752
|
onCollapse();
|
|
900
753
|
}
|
|
901
754
|
}
|
|
@@ -929,9 +782,10 @@ function computePanelFlexBoxStyle({
|
|
|
929
782
|
const size = layout[panelIndex];
|
|
930
783
|
let flexGrow;
|
|
931
784
|
if (panelData.length === 1) {
|
|
932
|
-
flexGrow = "
|
|
785
|
+
flexGrow = "1";
|
|
933
786
|
} else if (size == null) {
|
|
934
|
-
|
|
787
|
+
// Initial render (before panels have registered themselves)
|
|
788
|
+
flexGrow = "1";
|
|
935
789
|
} else {
|
|
936
790
|
flexGrow = size.toPrecision(precision);
|
|
937
791
|
}
|
|
@@ -1077,74 +931,39 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
|
|
|
1077
931
|
}
|
|
1078
932
|
}
|
|
1079
933
|
|
|
1080
|
-
function shouldMonitorPixelBasedConstraints(constraints) {
|
|
1081
|
-
return constraints.some(constraints => {
|
|
1082
|
-
return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
|
|
1083
|
-
});
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
934
|
function validatePanelConstraints({
|
|
1087
|
-
|
|
1088
|
-
panelConstraints,
|
|
935
|
+
panelConstraints: panelConstraintsArray,
|
|
1089
936
|
panelId,
|
|
1090
937
|
panelIndex
|
|
1091
938
|
}) {
|
|
1092
939
|
{
|
|
1093
940
|
const warnings = [];
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
} = panelConstraints[panelIndex];
|
|
1105
|
-
const conflictingUnits = [];
|
|
1106
|
-
if (collapsedSizePercentage != null && collapsedSizePixels != null) {
|
|
1107
|
-
conflictingUnits.push("collapsed size");
|
|
1108
|
-
}
|
|
1109
|
-
if (defaultSizePercentage != null && defaultSizePixels != null) {
|
|
1110
|
-
conflictingUnits.push("default size");
|
|
1111
|
-
}
|
|
1112
|
-
if (maxSizePercentage != null && maxSizePixels != null) {
|
|
1113
|
-
conflictingUnits.push("max size");
|
|
1114
|
-
}
|
|
1115
|
-
if (minSizePercentage != null && minSizePixels != null) {
|
|
1116
|
-
conflictingUnits.push("min size");
|
|
1117
|
-
}
|
|
1118
|
-
if (conflictingUnits.length > 0) {
|
|
1119
|
-
warnings.push(`should not specify both percentage and pixel units for: ${conflictingUnits.join(", ")}`);
|
|
1120
|
-
}
|
|
941
|
+
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
942
|
+
assert(panelConstraints);
|
|
943
|
+
const {
|
|
944
|
+
collapsedSize = 0,
|
|
945
|
+
defaultSize,
|
|
946
|
+
maxSize = 100,
|
|
947
|
+
minSize = 0
|
|
948
|
+
} = panelConstraints;
|
|
949
|
+
if (minSize > maxSize) {
|
|
950
|
+
warnings.push(`min size (${minSize}%) should not be greater than max size (${maxSize}%)`);
|
|
1121
951
|
}
|
|
1122
|
-
{
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
minSizePercentage
|
|
1128
|
-
} = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
|
|
1129
|
-
if (minSizePercentage > maxSizePercentage) {
|
|
1130
|
-
warnings.push(`min size (${minSizePercentage}%) should not be greater than max size (${maxSizePercentage}%)`);
|
|
1131
|
-
}
|
|
1132
|
-
if (defaultSizePercentage != null) {
|
|
1133
|
-
if (defaultSizePercentage < 0) {
|
|
1134
|
-
warnings.push("default size should not be less than 0");
|
|
1135
|
-
} else if (defaultSizePercentage < minSizePercentage) {
|
|
1136
|
-
warnings.push("default size should not be less than min size");
|
|
1137
|
-
}
|
|
1138
|
-
if (defaultSizePercentage > 100) {
|
|
1139
|
-
warnings.push("default size should not be greater than 100");
|
|
1140
|
-
} else if (defaultSizePercentage > maxSizePercentage) {
|
|
1141
|
-
warnings.push("default size should not be greater than max size");
|
|
1142
|
-
}
|
|
952
|
+
if (defaultSize != null) {
|
|
953
|
+
if (defaultSize < 0) {
|
|
954
|
+
warnings.push("default size should not be less than 0");
|
|
955
|
+
} else if (defaultSize < minSize) {
|
|
956
|
+
warnings.push("default size should not be less than min size");
|
|
1143
957
|
}
|
|
1144
|
-
if (
|
|
1145
|
-
warnings.push("
|
|
958
|
+
if (defaultSize > 100) {
|
|
959
|
+
warnings.push("default size should not be greater than 100");
|
|
960
|
+
} else if (defaultSize > maxSize) {
|
|
961
|
+
warnings.push("default size should not be greater than max size");
|
|
1146
962
|
}
|
|
1147
963
|
}
|
|
964
|
+
if (collapsedSize > minSize) {
|
|
965
|
+
warnings.push("collapsed size should not be greater than min size");
|
|
966
|
+
}
|
|
1148
967
|
if (warnings.length > 0) {
|
|
1149
968
|
const name = panelId != null ? `Panel "${panelId}"` : "Panel";
|
|
1150
969
|
console.warn(`${name} has an invalid configuration:\n\n${warnings.join("\n")}`);
|
|
@@ -1156,20 +975,26 @@ function validatePanelConstraints({
|
|
|
1156
975
|
|
|
1157
976
|
// All units must be in percentages; pixel values should be pre-converted
|
|
1158
977
|
function validatePanelGroupLayout({
|
|
1159
|
-
groupSizePixels,
|
|
1160
978
|
layout: prevLayout,
|
|
1161
979
|
panelConstraints
|
|
1162
980
|
}) {
|
|
1163
981
|
const nextLayout = [...prevLayout];
|
|
982
|
+
const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
|
|
1164
983
|
|
|
1165
984
|
// Validate layout expectations
|
|
1166
985
|
if (nextLayout.length !== panelConstraints.length) {
|
|
1167
986
|
throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
|
|
1168
|
-
} else if (!fuzzyNumbersEqual(
|
|
987
|
+
} else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
|
|
1169
988
|
// This is not ideal so we should warn about it, but it may be recoverable in some cases
|
|
1170
989
|
// (especially if the amount is small)
|
|
1171
990
|
{
|
|
1172
|
-
console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}
|
|
991
|
+
console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}. Layout normalization will be applied.`);
|
|
992
|
+
}
|
|
993
|
+
for (let index = 0; index < panelConstraints.length; index++) {
|
|
994
|
+
const unsafeSize = nextLayout[index];
|
|
995
|
+
assert(unsafeSize != null);
|
|
996
|
+
const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
|
|
997
|
+
nextLayout[index] = safeSize;
|
|
1173
998
|
}
|
|
1174
999
|
}
|
|
1175
1000
|
let remainingSize = 0;
|
|
@@ -1177,8 +1002,8 @@ function validatePanelGroupLayout({
|
|
|
1177
1002
|
// First pass: Validate the proposed layout given each panel's constraints
|
|
1178
1003
|
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1179
1004
|
const unsafeSize = nextLayout[index];
|
|
1005
|
+
assert(unsafeSize != null);
|
|
1180
1006
|
const safeSize = resizePanel({
|
|
1181
|
-
groupSizePixels,
|
|
1182
1007
|
panelConstraints,
|
|
1183
1008
|
panelIndex: index,
|
|
1184
1009
|
size: unsafeSize
|
|
@@ -1194,9 +1019,9 @@ function validatePanelGroupLayout({
|
|
|
1194
1019
|
if (!fuzzyNumbersEqual(remainingSize, 0)) {
|
|
1195
1020
|
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1196
1021
|
const prevSize = nextLayout[index];
|
|
1022
|
+
assert(prevSize != null);
|
|
1197
1023
|
const unsafeSize = prevSize + remainingSize;
|
|
1198
1024
|
const safeSize = resizePanel({
|
|
1199
|
-
groupSizePixels,
|
|
1200
1025
|
panelConstraints,
|
|
1201
1026
|
panelIndex: index,
|
|
1202
1027
|
size: unsafeSize
|
|
@@ -1231,21 +1056,20 @@ function PanelGroupWithForwardedRef({
|
|
|
1231
1056
|
autoSaveId = null,
|
|
1232
1057
|
children,
|
|
1233
1058
|
className: classNameFromProps = "",
|
|
1234
|
-
dataAttributes,
|
|
1235
1059
|
direction,
|
|
1236
1060
|
forwardedRef,
|
|
1237
|
-
id: idFromProps,
|
|
1061
|
+
id: idFromProps = null,
|
|
1238
1062
|
onLayout = null,
|
|
1239
|
-
|
|
1240
|
-
keyboardResizeByPixels = null,
|
|
1063
|
+
keyboardResizeBy = null,
|
|
1241
1064
|
storage = defaultStorage,
|
|
1242
1065
|
style: styleFromProps,
|
|
1243
|
-
tagName: Type = "div"
|
|
1066
|
+
tagName: Type = "div",
|
|
1067
|
+
...rest
|
|
1244
1068
|
}) {
|
|
1245
1069
|
const groupId = useUniqueId(idFromProps);
|
|
1246
1070
|
const [dragState, setDragState] = useState(null);
|
|
1247
1071
|
const [layout, setLayout] = useState([]);
|
|
1248
|
-
const
|
|
1072
|
+
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1249
1073
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1250
1074
|
const prevDeltaRef = useRef(0);
|
|
1251
1075
|
const committedValuesRef = useRef({
|
|
@@ -1253,8 +1077,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1253
1077
|
direction,
|
|
1254
1078
|
dragState,
|
|
1255
1079
|
id: groupId,
|
|
1256
|
-
|
|
1257
|
-
keyboardResizeByPixels,
|
|
1080
|
+
keyboardResizeBy,
|
|
1258
1081
|
onLayout,
|
|
1259
1082
|
storage
|
|
1260
1083
|
});
|
|
@@ -1270,33 +1093,20 @@ function PanelGroupWithForwardedRef({
|
|
|
1270
1093
|
useImperativeHandle(forwardedRef, () => ({
|
|
1271
1094
|
getId: () => committedValuesRef.current.id,
|
|
1272
1095
|
getLayout: () => {
|
|
1273
|
-
const {
|
|
1274
|
-
id: groupId
|
|
1275
|
-
} = committedValuesRef.current;
|
|
1276
1096
|
const {
|
|
1277
1097
|
layout
|
|
1278
1098
|
} = eagerValuesRef.current;
|
|
1279
|
-
|
|
1280
|
-
return layout.map(sizePercentage => {
|
|
1281
|
-
return {
|
|
1282
|
-
sizePercentage,
|
|
1283
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1284
|
-
};
|
|
1285
|
-
});
|
|
1099
|
+
return layout;
|
|
1286
1100
|
},
|
|
1287
|
-
setLayout:
|
|
1101
|
+
setLayout: unsafeLayout => {
|
|
1288
1102
|
const {
|
|
1289
|
-
id: groupId,
|
|
1290
1103
|
onLayout
|
|
1291
1104
|
} = committedValuesRef.current;
|
|
1292
1105
|
const {
|
|
1293
1106
|
layout: prevLayout,
|
|
1294
1107
|
panelDataArray
|
|
1295
1108
|
} = eagerValuesRef.current;
|
|
1296
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1297
|
-
const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
|
|
1298
1109
|
const safeLayout = validatePanelGroupLayout({
|
|
1299
|
-
groupSizePixels,
|
|
1300
1110
|
layout: unsafeLayout,
|
|
1301
1111
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1302
1112
|
});
|
|
@@ -1304,16 +1114,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1304
1114
|
setLayout(safeLayout);
|
|
1305
1115
|
eagerValuesRef.current.layout = safeLayout;
|
|
1306
1116
|
if (onLayout) {
|
|
1307
|
-
onLayout(safeLayout
|
|
1308
|
-
sizePercentage,
|
|
1309
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1310
|
-
})));
|
|
1117
|
+
onLayout(safeLayout);
|
|
1311
1118
|
}
|
|
1312
|
-
callPanelCallbacks(
|
|
1119
|
+
callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1313
1120
|
}
|
|
1314
1121
|
}
|
|
1315
1122
|
}), []);
|
|
1316
|
-
|
|
1317
1123
|
useWindowSplitterPanelGroupBehavior({
|
|
1318
1124
|
committedValuesRef,
|
|
1319
1125
|
eagerValuesRef,
|
|
@@ -1332,12 +1138,14 @@ function PanelGroupWithForwardedRef({
|
|
|
1332
1138
|
if (layout.length === 0 || layout.length !== panelDataArray.length) {
|
|
1333
1139
|
return;
|
|
1334
1140
|
}
|
|
1141
|
+
let debouncedSave = debounceMap[autoSaveId];
|
|
1335
1142
|
|
|
1336
1143
|
// Limit the frequency of localStorage updates.
|
|
1337
|
-
if (
|
|
1338
|
-
|
|
1144
|
+
if (debouncedSave == null) {
|
|
1145
|
+
debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1146
|
+
debounceMap[autoSaveId] = debouncedSave;
|
|
1339
1147
|
}
|
|
1340
|
-
|
|
1148
|
+
debouncedSave(autoSaveId, panelDataArray, layout, storage);
|
|
1341
1149
|
}
|
|
1342
1150
|
}, [autoSaveId, layout, storage]);
|
|
1343
1151
|
|
|
@@ -1370,12 +1178,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1370
1178
|
}
|
|
1371
1179
|
if (!didLogPanelConstraintsWarning) {
|
|
1372
1180
|
const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
|
|
1373
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1374
1181
|
for (let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++) {
|
|
1182
|
+
const panelData = panelDataArray[panelIndex];
|
|
1183
|
+
assert(panelData);
|
|
1375
1184
|
const isValid = validatePanelConstraints({
|
|
1376
|
-
groupSizePixels,
|
|
1377
1185
|
panelConstraints,
|
|
1378
|
-
panelId:
|
|
1186
|
+
panelId: panelData.id,
|
|
1379
1187
|
panelIndex
|
|
1380
1188
|
});
|
|
1381
1189
|
if (!isValid) {
|
|
@@ -1399,20 +1207,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1399
1207
|
if (panelData.constraints.collapsible) {
|
|
1400
1208
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1401
1209
|
const {
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
pivotIndices
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
if (
|
|
1210
|
+
collapsedSize = 0,
|
|
1211
|
+
panelSize,
|
|
1212
|
+
pivotIndices
|
|
1213
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1214
|
+
assert(panelSize != null);
|
|
1215
|
+
if (panelSize !== collapsedSize) {
|
|
1408
1216
|
// Store size before collapse;
|
|
1409
1217
|
// This is the size that gets restored if the expand() API is used.
|
|
1410
|
-
panelSizeBeforeCollapseRef.current.set(panelData.id,
|
|
1218
|
+
panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
|
|
1411
1219
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1412
|
-
const delta = isLastPanel ?
|
|
1220
|
+
const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
|
|
1413
1221
|
const nextLayout = adjustLayoutByDelta({
|
|
1414
1222
|
delta,
|
|
1415
|
-
groupSizePixels,
|
|
1416
1223
|
layout: prevLayout,
|
|
1417
1224
|
panelConstraints: panelConstraintsArray,
|
|
1418
1225
|
pivotIndices,
|
|
@@ -1422,16 +1229,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1422
1229
|
setLayout(nextLayout);
|
|
1423
1230
|
eagerValuesRef.current.layout = nextLayout;
|
|
1424
1231
|
if (onLayout) {
|
|
1425
|
-
onLayout(nextLayout
|
|
1426
|
-
sizePercentage,
|
|
1427
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1428
|
-
})));
|
|
1232
|
+
onLayout(nextLayout);
|
|
1429
1233
|
}
|
|
1430
|
-
callPanelCallbacks(
|
|
1234
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1431
1235
|
}
|
|
1432
1236
|
}
|
|
1433
1237
|
}
|
|
1434
|
-
}, [
|
|
1238
|
+
}, []);
|
|
1435
1239
|
|
|
1436
1240
|
// External APIs are safe to memoize via committed values ref
|
|
1437
1241
|
const expandPanel = useCallback(panelData => {
|
|
@@ -1445,21 +1249,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1445
1249
|
if (panelData.constraints.collapsible) {
|
|
1446
1250
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1447
1251
|
const {
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
pivotIndices
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
if (panelSizePercentage === collapsedSizePercentage) {
|
|
1252
|
+
collapsedSize = 0,
|
|
1253
|
+
panelSize,
|
|
1254
|
+
minSize = 0,
|
|
1255
|
+
pivotIndices
|
|
1256
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1257
|
+
if (panelSize === collapsedSize) {
|
|
1455
1258
|
// Restore this panel to the size it was before it was collapsed, if possible.
|
|
1456
|
-
const
|
|
1457
|
-
const
|
|
1259
|
+
const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
|
|
1260
|
+
const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
|
|
1458
1261
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1459
|
-
const delta = isLastPanel ?
|
|
1262
|
+
const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
|
|
1460
1263
|
const nextLayout = adjustLayoutByDelta({
|
|
1461
1264
|
delta,
|
|
1462
|
-
groupSizePixels,
|
|
1463
1265
|
layout: prevLayout,
|
|
1464
1266
|
panelConstraints: panelConstraintsArray,
|
|
1465
1267
|
pivotIndices,
|
|
@@ -1469,16 +1271,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1469
1271
|
setLayout(nextLayout);
|
|
1470
1272
|
eagerValuesRef.current.layout = nextLayout;
|
|
1471
1273
|
if (onLayout) {
|
|
1472
|
-
onLayout(nextLayout
|
|
1473
|
-
sizePercentage,
|
|
1474
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1475
|
-
})));
|
|
1274
|
+
onLayout(nextLayout);
|
|
1476
1275
|
}
|
|
1477
|
-
callPanelCallbacks(
|
|
1276
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1478
1277
|
}
|
|
1479
1278
|
}
|
|
1480
1279
|
}
|
|
1481
|
-
}, [
|
|
1280
|
+
}, []);
|
|
1482
1281
|
|
|
1483
1282
|
// External APIs are safe to memoize via committed values ref
|
|
1484
1283
|
const getPanelSize = useCallback(panelData => {
|
|
@@ -1487,14 +1286,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1487
1286
|
panelDataArray
|
|
1488
1287
|
} = eagerValuesRef.current;
|
|
1489
1288
|
const {
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
return
|
|
1494
|
-
|
|
1495
|
-
sizePixels: panelSizePixels
|
|
1496
|
-
};
|
|
1497
|
-
}, [groupId]);
|
|
1289
|
+
panelSize
|
|
1290
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1291
|
+
assert(panelSize != null);
|
|
1292
|
+
return panelSize;
|
|
1293
|
+
}, []);
|
|
1498
1294
|
|
|
1499
1295
|
// This API should never read from committedValuesRef
|
|
1500
1296
|
const getPanelStyle = useCallback(panelData => {
|
|
@@ -1517,12 +1313,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1517
1313
|
panelDataArray
|
|
1518
1314
|
} = eagerValuesRef.current;
|
|
1519
1315
|
const {
|
|
1520
|
-
|
|
1316
|
+
collapsedSize,
|
|
1521
1317
|
collapsible,
|
|
1522
|
-
|
|
1523
|
-
} = panelDataHelper(
|
|
1524
|
-
return collapsible === true &&
|
|
1525
|
-
}, [
|
|
1318
|
+
panelSize
|
|
1319
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1320
|
+
return collapsible === true && panelSize === collapsedSize;
|
|
1321
|
+
}, []);
|
|
1526
1322
|
|
|
1527
1323
|
// External APIs are safe to memoize via committed values ref
|
|
1528
1324
|
const isPanelExpanded = useCallback(panelData => {
|
|
@@ -1531,12 +1327,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1531
1327
|
panelDataArray
|
|
1532
1328
|
} = eagerValuesRef.current;
|
|
1533
1329
|
const {
|
|
1534
|
-
|
|
1330
|
+
collapsedSize = 0,
|
|
1535
1331
|
collapsible,
|
|
1536
|
-
|
|
1537
|
-
} = panelDataHelper(
|
|
1538
|
-
|
|
1539
|
-
|
|
1332
|
+
panelSize
|
|
1333
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1334
|
+
assert(panelSize != null);
|
|
1335
|
+
return !collapsible || panelSize > collapsedSize;
|
|
1336
|
+
}, []);
|
|
1540
1337
|
const registerPanel = useCallback(panelData => {
|
|
1541
1338
|
const {
|
|
1542
1339
|
autoSaveId,
|
|
@@ -1576,18 +1373,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1576
1373
|
if (autoSaveId) {
|
|
1577
1374
|
unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
|
|
1578
1375
|
}
|
|
1579
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1580
|
-
if (groupSizePixels <= 0) {
|
|
1581
|
-
if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
|
|
1582
|
-
constraints
|
|
1583
|
-
}) => constraints))) {
|
|
1584
|
-
// Wait until the group has rendered a non-zero size before computing layout.
|
|
1585
|
-
return;
|
|
1586
|
-
}
|
|
1587
|
-
}
|
|
1588
1376
|
if (unsafeLayout == null) {
|
|
1589
1377
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1590
|
-
groupSizePixels,
|
|
1591
1378
|
panelDataArray
|
|
1592
1379
|
});
|
|
1593
1380
|
}
|
|
@@ -1595,7 +1382,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1595
1382
|
// Validate even saved layouts in case something has changed since last render
|
|
1596
1383
|
// e.g. for pixel groups, this could be the size of the window
|
|
1597
1384
|
const nextLayout = validatePanelGroupLayout({
|
|
1598
|
-
groupSizePixels,
|
|
1599
1385
|
layout: unsafeLayout,
|
|
1600
1386
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1601
1387
|
});
|
|
@@ -1607,12 +1393,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1607
1393
|
eagerValuesRef.current.layout = nextLayout;
|
|
1608
1394
|
if (!areEqual(prevLayout, nextLayout)) {
|
|
1609
1395
|
if (onLayout) {
|
|
1610
|
-
onLayout(nextLayout
|
|
1611
|
-
sizePercentage,
|
|
1612
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1613
|
-
})));
|
|
1396
|
+
onLayout(nextLayout);
|
|
1614
1397
|
}
|
|
1615
|
-
callPanelCallbacks(
|
|
1398
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1616
1399
|
}
|
|
1617
1400
|
}, []);
|
|
1618
1401
|
const registerResizeHandle = useCallback(dragHandleId => {
|
|
@@ -1622,8 +1405,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1622
1405
|
direction,
|
|
1623
1406
|
dragState,
|
|
1624
1407
|
id: groupId,
|
|
1625
|
-
|
|
1626
|
-
keyboardResizeByPixels,
|
|
1408
|
+
keyboardResizeBy,
|
|
1627
1409
|
onLayout
|
|
1628
1410
|
} = committedValuesRef.current;
|
|
1629
1411
|
const {
|
|
@@ -1634,10 +1416,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1634
1416
|
initialLayout
|
|
1635
1417
|
} = dragState !== null && dragState !== void 0 ? dragState : {};
|
|
1636
1418
|
const pivotIndices = determinePivotIndices(groupId, dragHandleId);
|
|
1637
|
-
let delta = calculateDeltaPercentage(event,
|
|
1638
|
-
percentage: keyboardResizeByPercentage,
|
|
1639
|
-
pixels: keyboardResizeByPixels
|
|
1640
|
-
});
|
|
1419
|
+
let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
|
|
1641
1420
|
if (delta === 0) {
|
|
1642
1421
|
return;
|
|
1643
1422
|
}
|
|
@@ -1647,11 +1426,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1647
1426
|
if (document.dir === "rtl" && isHorizontal) {
|
|
1648
1427
|
delta = -delta;
|
|
1649
1428
|
}
|
|
1650
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1651
1429
|
const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
|
|
1652
1430
|
const nextLayout = adjustLayoutByDelta({
|
|
1653
1431
|
delta,
|
|
1654
|
-
groupSizePixels,
|
|
1655
1432
|
layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
|
|
1656
1433
|
panelConstraints,
|
|
1657
1434
|
pivotIndices,
|
|
@@ -1687,18 +1464,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1687
1464
|
setLayout(nextLayout);
|
|
1688
1465
|
eagerValuesRef.current.layout = nextLayout;
|
|
1689
1466
|
if (onLayout) {
|
|
1690
|
-
onLayout(nextLayout
|
|
1691
|
-
sizePercentage,
|
|
1692
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1693
|
-
})));
|
|
1467
|
+
onLayout(nextLayout);
|
|
1694
1468
|
}
|
|
1695
|
-
callPanelCallbacks(
|
|
1469
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1696
1470
|
}
|
|
1697
1471
|
};
|
|
1698
1472
|
}, []);
|
|
1699
1473
|
|
|
1700
1474
|
// External APIs are safe to memoize via committed values ref
|
|
1701
|
-
const resizePanel = useCallback((panelData,
|
|
1475
|
+
const resizePanel = useCallback((panelData, unsafePanelSize) => {
|
|
1702
1476
|
const {
|
|
1703
1477
|
onLayout
|
|
1704
1478
|
} = committedValuesRef.current;
|
|
@@ -1708,16 +1482,14 @@ function PanelGroupWithForwardedRef({
|
|
|
1708
1482
|
} = eagerValuesRef.current;
|
|
1709
1483
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1710
1484
|
const {
|
|
1711
|
-
|
|
1712
|
-
panelSizePercentage,
|
|
1485
|
+
panelSize,
|
|
1713
1486
|
pivotIndices
|
|
1714
|
-
} = panelDataHelper(
|
|
1715
|
-
|
|
1487
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1488
|
+
assert(panelSize != null);
|
|
1716
1489
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1717
|
-
const delta = isLastPanel ?
|
|
1490
|
+
const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
|
|
1718
1491
|
const nextLayout = adjustLayoutByDelta({
|
|
1719
1492
|
delta,
|
|
1720
|
-
groupSizePixels,
|
|
1721
1493
|
layout: prevLayout,
|
|
1722
1494
|
panelConstraints: panelConstraintsArray,
|
|
1723
1495
|
pivotIndices,
|
|
@@ -1727,14 +1499,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1727
1499
|
setLayout(nextLayout);
|
|
1728
1500
|
eagerValuesRef.current.layout = nextLayout;
|
|
1729
1501
|
if (onLayout) {
|
|
1730
|
-
onLayout(nextLayout
|
|
1731
|
-
sizePercentage,
|
|
1732
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1733
|
-
})));
|
|
1502
|
+
onLayout(nextLayout);
|
|
1734
1503
|
}
|
|
1735
|
-
callPanelCallbacks(
|
|
1504
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1736
1505
|
}
|
|
1737
|
-
}, [
|
|
1506
|
+
}, []);
|
|
1738
1507
|
const startDragging = useCallback((dragHandleId, event) => {
|
|
1739
1508
|
const {
|
|
1740
1509
|
direction
|
|
@@ -1743,6 +1512,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1743
1512
|
layout
|
|
1744
1513
|
} = eagerValuesRef.current;
|
|
1745
1514
|
const handleElement = getResizeHandleElement(dragHandleId);
|
|
1515
|
+
assert(handleElement);
|
|
1746
1516
|
const initialCursorPosition = getResizeEventCursorPosition(direction, event);
|
|
1747
1517
|
setDragState({
|
|
1748
1518
|
dragHandleId,
|
|
@@ -1761,7 +1531,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1761
1531
|
});
|
|
1762
1532
|
const unregisterPanel = useCallback(panelData => {
|
|
1763
1533
|
const {
|
|
1764
|
-
id: groupId,
|
|
1765
1534
|
onLayout
|
|
1766
1535
|
} = committedValuesRef.current;
|
|
1767
1536
|
const {
|
|
@@ -1784,7 +1553,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1784
1553
|
const {
|
|
1785
1554
|
pendingPanelIds
|
|
1786
1555
|
} = unregisterPanelRef.current;
|
|
1787
|
-
const map =
|
|
1556
|
+
const map = panelIdToLastNotifiedSizeMapRef.current;
|
|
1788
1557
|
|
|
1789
1558
|
// TRICKY
|
|
1790
1559
|
// Strict effects mode
|
|
@@ -1810,16 +1579,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1810
1579
|
// The group is unmounting; skip layout calculation.
|
|
1811
1580
|
return;
|
|
1812
1581
|
}
|
|
1813
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1814
1582
|
let unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1815
|
-
groupSizePixels,
|
|
1816
1583
|
panelDataArray
|
|
1817
1584
|
});
|
|
1818
1585
|
|
|
1819
1586
|
// Validate even saved layouts in case something has changed since last render
|
|
1820
1587
|
// e.g. for pixel groups, this could be the size of the window
|
|
1821
1588
|
const nextLayout = validatePanelGroupLayout({
|
|
1822
|
-
groupSizePixels,
|
|
1823
1589
|
layout: unsafeLayout,
|
|
1824
1590
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1825
1591
|
});
|
|
@@ -1827,12 +1593,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1827
1593
|
setLayout(nextLayout);
|
|
1828
1594
|
eagerValuesRef.current.layout = nextLayout;
|
|
1829
1595
|
if (onLayout) {
|
|
1830
|
-
onLayout(nextLayout
|
|
1831
|
-
sizePercentage,
|
|
1832
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1833
|
-
})));
|
|
1596
|
+
onLayout(nextLayout);
|
|
1834
1597
|
}
|
|
1835
|
-
callPanelCallbacks(
|
|
1598
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1836
1599
|
}
|
|
1837
1600
|
}, 0);
|
|
1838
1601
|
}, []);
|
|
@@ -1863,13 +1626,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1863
1626
|
return createElement(PanelGroupContext.Provider, {
|
|
1864
1627
|
value: context
|
|
1865
1628
|
}, createElement(Type, {
|
|
1629
|
+
...rest,
|
|
1866
1630
|
children,
|
|
1867
1631
|
className: classNameFromProps,
|
|
1868
1632
|
style: {
|
|
1869
1633
|
...style,
|
|
1870
1634
|
...styleFromProps
|
|
1871
1635
|
},
|
|
1872
|
-
...dataAttributes,
|
|
1873
1636
|
// CSS selectors
|
|
1874
1637
|
"data-panel-group": "",
|
|
1875
1638
|
"data-panel-group-direction": direction,
|
|
@@ -1882,22 +1645,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
|
|
|
1882
1645
|
}));
|
|
1883
1646
|
PanelGroupWithForwardedRef.displayName = "PanelGroup";
|
|
1884
1647
|
PanelGroup.displayName = "forwardRef(PanelGroup)";
|
|
1885
|
-
function panelDataHelper(
|
|
1648
|
+
function panelDataHelper(panelDataArray, panelData, layout) {
|
|
1886
1649
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1887
1650
|
const panelIndex = panelDataArray.indexOf(panelData);
|
|
1888
1651
|
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
1889
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1890
|
-
const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
|
|
1891
1652
|
const isLastPanel = panelIndex === panelDataArray.length - 1;
|
|
1892
1653
|
const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
|
|
1893
|
-
const
|
|
1894
|
-
const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
|
|
1654
|
+
const panelSize = layout[panelIndex];
|
|
1895
1655
|
return {
|
|
1896
|
-
...
|
|
1897
|
-
|
|
1898
|
-
panelSizePercentage,
|
|
1899
|
-
panelSizePixels,
|
|
1900
|
-
groupSizePixels,
|
|
1656
|
+
...panelConstraints,
|
|
1657
|
+
panelSize,
|
|
1901
1658
|
pivotIndices
|
|
1902
1659
|
};
|
|
1903
1660
|
}
|
|
@@ -1937,6 +1694,7 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1937
1694
|
{
|
|
1938
1695
|
event.preventDefault();
|
|
1939
1696
|
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
1697
|
+
assert(groupId);
|
|
1940
1698
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
1941
1699
|
const index = getResizeHandleElementIndex(groupId, handleId);
|
|
1942
1700
|
assert(index !== null);
|
|
@@ -1957,12 +1715,13 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1957
1715
|
function PanelResizeHandle({
|
|
1958
1716
|
children = null,
|
|
1959
1717
|
className: classNameFromProps = "",
|
|
1960
|
-
dataAttributes,
|
|
1961
1718
|
disabled = false,
|
|
1962
|
-
id: idFromProps
|
|
1719
|
+
id: idFromProps,
|
|
1963
1720
|
onDragging,
|
|
1964
1721
|
style: styleFromProps = {},
|
|
1965
|
-
|
|
1722
|
+
tabIndex = 0,
|
|
1723
|
+
tagName: Type = "div",
|
|
1724
|
+
...rest
|
|
1966
1725
|
}) {
|
|
1967
1726
|
const divElementRef = useRef(null);
|
|
1968
1727
|
|
|
@@ -1992,8 +1751,9 @@ function PanelResizeHandle({
|
|
|
1992
1751
|
const stopDraggingAndBlur = useCallback(() => {
|
|
1993
1752
|
// Clicking on the drag handle shouldn't leave it focused;
|
|
1994
1753
|
// That would cause the PanelGroup to think it was still active.
|
|
1995
|
-
const
|
|
1996
|
-
|
|
1754
|
+
const divElement = divElementRef.current;
|
|
1755
|
+
assert(divElement);
|
|
1756
|
+
divElement.blur();
|
|
1997
1757
|
stopDragging();
|
|
1998
1758
|
const {
|
|
1999
1759
|
onDragging
|
|
@@ -2021,6 +1781,7 @@ function PanelResizeHandle({
|
|
|
2021
1781
|
resizeHandler(event);
|
|
2022
1782
|
};
|
|
2023
1783
|
const divElement = divElementRef.current;
|
|
1784
|
+
assert(divElement);
|
|
2024
1785
|
const targetDocument = divElement.ownerDocument;
|
|
2025
1786
|
targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
|
|
2026
1787
|
targetDocument.body.addEventListener("mousemove", onMove);
|
|
@@ -2048,15 +1809,18 @@ function PanelResizeHandle({
|
|
|
2048
1809
|
userSelect: "none"
|
|
2049
1810
|
};
|
|
2050
1811
|
return createElement(Type, {
|
|
1812
|
+
...rest,
|
|
2051
1813
|
children,
|
|
2052
1814
|
className: classNameFromProps,
|
|
2053
1815
|
onBlur: () => setIsFocused(false),
|
|
2054
1816
|
onFocus: () => setIsFocused(true),
|
|
2055
1817
|
onMouseDown: event => {
|
|
2056
1818
|
startDragging(resizeHandleId, event.nativeEvent);
|
|
1819
|
+
const callbacks = callbacksRef.current;
|
|
1820
|
+
assert(callbacks);
|
|
2057
1821
|
const {
|
|
2058
1822
|
onDragging
|
|
2059
|
-
} =
|
|
1823
|
+
} = callbacks;
|
|
2060
1824
|
if (onDragging) {
|
|
2061
1825
|
onDragging(true);
|
|
2062
1826
|
}
|
|
@@ -2066,9 +1830,11 @@ function PanelResizeHandle({
|
|
|
2066
1830
|
onTouchEnd: stopDraggingAndBlur,
|
|
2067
1831
|
onTouchStart: event => {
|
|
2068
1832
|
startDragging(resizeHandleId, event.nativeEvent);
|
|
1833
|
+
const callbacks = callbacksRef.current;
|
|
1834
|
+
assert(callbacks);
|
|
2069
1835
|
const {
|
|
2070
1836
|
onDragging
|
|
2071
|
-
} =
|
|
1837
|
+
} = callbacks;
|
|
2072
1838
|
if (onDragging) {
|
|
2073
1839
|
onDragging(true);
|
|
2074
1840
|
}
|
|
@@ -2079,8 +1845,7 @@ function PanelResizeHandle({
|
|
|
2079
1845
|
...style,
|
|
2080
1846
|
...styleFromProps
|
|
2081
1847
|
},
|
|
2082
|
-
tabIndex
|
|
2083
|
-
...dataAttributes,
|
|
1848
|
+
tabIndex,
|
|
2084
1849
|
// CSS selectors
|
|
2085
1850
|
"data-panel-group-direction": direction,
|
|
2086
1851
|
"data-panel-group-id": groupId,
|
|
@@ -2095,3 +1860,4 @@ PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
|
2095
1860
|
exports.Panel = Panel;
|
|
2096
1861
|
exports.PanelGroup = PanelGroup;
|
|
2097
1862
|
exports.PanelResizeHandle = PanelResizeHandle;
|
|
1863
|
+
exports.assert = assert;
|