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
|
@@ -67,24 +67,20 @@ function useUniqueId(idFromParams = null) {
|
|
|
67
67
|
function PanelWithForwardedRef({
|
|
68
68
|
children,
|
|
69
69
|
className: classNameFromProps = "",
|
|
70
|
-
|
|
71
|
-
collapsedSizePixels,
|
|
70
|
+
collapsedSize,
|
|
72
71
|
collapsible,
|
|
73
|
-
|
|
74
|
-
defaultSizePercentage,
|
|
75
|
-
defaultSizePixels,
|
|
72
|
+
defaultSize,
|
|
76
73
|
forwardedRef,
|
|
77
74
|
id: idFromProps,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
minSizePercentage,
|
|
81
|
-
minSizePixels,
|
|
75
|
+
maxSize,
|
|
76
|
+
minSize,
|
|
82
77
|
onCollapse,
|
|
83
78
|
onExpand,
|
|
84
79
|
onResize,
|
|
85
80
|
order,
|
|
86
81
|
style: styleFromProps,
|
|
87
|
-
tagName: Type = "div"
|
|
82
|
+
tagName: Type = "div",
|
|
83
|
+
...rest
|
|
88
84
|
}) {
|
|
89
85
|
const context = useContext(PanelGroupContext);
|
|
90
86
|
if (context === null) {
|
|
@@ -109,15 +105,11 @@ function PanelWithForwardedRef({
|
|
|
109
105
|
onResize
|
|
110
106
|
},
|
|
111
107
|
constraints: {
|
|
112
|
-
|
|
113
|
-
collapsedSizePixels,
|
|
108
|
+
collapsedSize,
|
|
114
109
|
collapsible,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
maxSizePixels,
|
|
119
|
-
minSizePercentage,
|
|
120
|
-
minSizePixels
|
|
110
|
+
defaultSize,
|
|
111
|
+
maxSize,
|
|
112
|
+
minSize
|
|
121
113
|
},
|
|
122
114
|
id: panelId,
|
|
123
115
|
idIsFromProps: idFromProps !== undefined,
|
|
@@ -137,15 +129,11 @@ function PanelWithForwardedRef({
|
|
|
137
129
|
callbacks.onCollapse = onCollapse;
|
|
138
130
|
callbacks.onExpand = onExpand;
|
|
139
131
|
callbacks.onResize = onResize;
|
|
140
|
-
constraints.
|
|
141
|
-
constraints.collapsedSizePixels = collapsedSizePixels;
|
|
132
|
+
constraints.collapsedSize = collapsedSize;
|
|
142
133
|
constraints.collapsible = collapsible;
|
|
143
|
-
constraints.
|
|
144
|
-
constraints.
|
|
145
|
-
constraints.
|
|
146
|
-
constraints.maxSizePixels = maxSizePixels;
|
|
147
|
-
constraints.minSizePercentage = minSizePercentage;
|
|
148
|
-
constraints.minSizePixels = minSizePixels;
|
|
134
|
+
constraints.defaultSize = defaultSize;
|
|
135
|
+
constraints.maxSize = maxSize;
|
|
136
|
+
constraints.minSize = minSize;
|
|
149
137
|
});
|
|
150
138
|
useIsomorphicLayoutEffect(() => {
|
|
151
139
|
const panelData = panelDataRef.current;
|
|
@@ -173,19 +161,19 @@ function PanelWithForwardedRef({
|
|
|
173
161
|
isExpanded() {
|
|
174
162
|
return !isPanelCollapsed(panelDataRef.current);
|
|
175
163
|
},
|
|
176
|
-
resize:
|
|
177
|
-
resizePanel(panelDataRef.current,
|
|
164
|
+
resize: size => {
|
|
165
|
+
resizePanel(panelDataRef.current, size);
|
|
178
166
|
}
|
|
179
167
|
}), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
|
|
180
168
|
const style = getPanelStyle(panelDataRef.current);
|
|
181
169
|
return createElement(Type, {
|
|
170
|
+
...rest,
|
|
182
171
|
children,
|
|
183
172
|
className: classNameFromProps,
|
|
184
173
|
style: {
|
|
185
174
|
...style,
|
|
186
175
|
...styleFromProps
|
|
187
176
|
},
|
|
188
|
-
...dataAttributes,
|
|
189
177
|
// CSS selectors
|
|
190
178
|
"data-panel": "",
|
|
191
179
|
"data-panel-id": panelId,
|
|
@@ -202,81 +190,11 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
|
|
|
202
190
|
PanelWithForwardedRef.displayName = "Panel";
|
|
203
191
|
Panel.displayName = "forwardRef(Panel)";
|
|
204
192
|
|
|
205
|
-
function
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels) {
|
|
210
|
-
let {
|
|
211
|
-
collapsedSizePercentage = 0,
|
|
212
|
-
collapsedSizePixels,
|
|
213
|
-
defaultSizePercentage,
|
|
214
|
-
defaultSizePixels,
|
|
215
|
-
maxSizePercentage = 100,
|
|
216
|
-
maxSizePixels,
|
|
217
|
-
minSizePercentage = 0,
|
|
218
|
-
minSizePixels
|
|
219
|
-
} = panelConstraints;
|
|
220
|
-
const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
|
|
221
|
-
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
222
|
-
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
223
|
-
return {
|
|
224
|
-
collapsedSizePercentage: 0,
|
|
225
|
-
defaultSizePercentage,
|
|
226
|
-
maxSizePercentage: 0,
|
|
227
|
-
minSizePercentage: 0
|
|
228
|
-
};
|
|
229
|
-
}
|
|
230
|
-
if (collapsedSizePixels != null) {
|
|
231
|
-
collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
|
|
232
|
-
}
|
|
233
|
-
if (defaultSizePixels != null) {
|
|
234
|
-
defaultSizePercentage = convertPixelsToPercentage(defaultSizePixels, groupSizePixels);
|
|
235
|
-
}
|
|
236
|
-
if (minSizePixels != null) {
|
|
237
|
-
minSizePercentage = convertPixelsToPercentage(minSizePixels, groupSizePixels);
|
|
238
|
-
}
|
|
239
|
-
if (maxSizePixels != null) {
|
|
240
|
-
maxSizePercentage = convertPixelsToPercentage(maxSizePixels, groupSizePixels);
|
|
241
|
-
}
|
|
242
|
-
return {
|
|
243
|
-
collapsedSizePercentage,
|
|
244
|
-
defaultSizePercentage,
|
|
245
|
-
maxSizePercentage,
|
|
246
|
-
minSizePercentage
|
|
247
|
-
};
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels) {
|
|
251
|
-
// All panel constraints, excluding the current one
|
|
252
|
-
let totalMinConstraints = 0;
|
|
253
|
-
let totalMaxConstraints = 0;
|
|
254
|
-
for (let index = 0; index < panelConstraintsArray.length; index++) {
|
|
255
|
-
if (index !== panelIndex) {
|
|
256
|
-
const {
|
|
257
|
-
collapsible
|
|
258
|
-
} = panelConstraintsArray[index];
|
|
259
|
-
const {
|
|
260
|
-
collapsedSizePercentage,
|
|
261
|
-
maxSizePercentage,
|
|
262
|
-
minSizePercentage
|
|
263
|
-
} = convertPixelConstraintsToPercentages(panelConstraintsArray[index], groupSizePixels);
|
|
264
|
-
totalMaxConstraints += maxSizePercentage;
|
|
265
|
-
totalMinConstraints += collapsible ? collapsedSizePercentage : minSizePercentage;
|
|
266
|
-
}
|
|
193
|
+
function assert(expectedCondition, message = "Assertion failed!") {
|
|
194
|
+
if (!expectedCondition) {
|
|
195
|
+
console.error(message);
|
|
196
|
+
throw Error(message);
|
|
267
197
|
}
|
|
268
|
-
const {
|
|
269
|
-
collapsedSizePercentage,
|
|
270
|
-
defaultSizePercentage,
|
|
271
|
-
maxSizePercentage,
|
|
272
|
-
minSizePercentage
|
|
273
|
-
} = convertPixelConstraintsToPercentages(panelConstraintsArray[panelIndex], groupSizePixels);
|
|
274
|
-
return {
|
|
275
|
-
collapsedSizePercentage,
|
|
276
|
-
defaultSizePercentage,
|
|
277
|
-
maxSizePercentage: panelConstraintsArray.length > 1 ? Math.min(maxSizePercentage, 100 - totalMinConstraints) : maxSizePercentage,
|
|
278
|
-
minSizePercentage: panelConstraintsArray.length > 1 ? Math.max(minSizePercentage, 100 - totalMaxConstraints) : minSizePercentage
|
|
279
|
-
};
|
|
280
198
|
}
|
|
281
199
|
|
|
282
200
|
const PRECISION = 10;
|
|
@@ -298,56 +216,41 @@ function fuzzyNumbersEqual(actual, expected, fractionDigits) {
|
|
|
298
216
|
|
|
299
217
|
// Panel size must be in percentages; pixel values should be pre-converted
|
|
300
218
|
function resizePanel({
|
|
301
|
-
|
|
302
|
-
panelConstraints,
|
|
219
|
+
panelConstraints: panelConstraintsArray,
|
|
303
220
|
panelIndex,
|
|
304
221
|
size
|
|
305
222
|
}) {
|
|
306
|
-
const
|
|
307
|
-
|
|
308
|
-
defaultSizePixels,
|
|
309
|
-
minSizePixels,
|
|
310
|
-
maxSizePixels
|
|
311
|
-
}) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
|
|
312
|
-
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
313
|
-
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
314
|
-
return 0;
|
|
315
|
-
}
|
|
223
|
+
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
224
|
+
assert(panelConstraints != null);
|
|
316
225
|
let {
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
if (
|
|
327
|
-
|
|
328
|
-
const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
|
|
329
|
-
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
330
|
-
size = collapsedSizePercentage;
|
|
331
|
-
} else {
|
|
332
|
-
size = minSizePercentage;
|
|
333
|
-
}
|
|
226
|
+
collapsedSize = 0,
|
|
227
|
+
collapsible,
|
|
228
|
+
maxSize = 100,
|
|
229
|
+
minSize = 0
|
|
230
|
+
} = panelConstraints;
|
|
231
|
+
if (fuzzyCompareNumbers(size, minSize) < 0) {
|
|
232
|
+
if (collapsible) {
|
|
233
|
+
// Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
|
|
234
|
+
const halfwayPoint = (collapsedSize + minSize) / 2;
|
|
235
|
+
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
236
|
+
size = collapsedSize;
|
|
334
237
|
} else {
|
|
335
|
-
size =
|
|
238
|
+
size = minSize;
|
|
336
239
|
}
|
|
240
|
+
} else {
|
|
241
|
+
size = minSize;
|
|
337
242
|
}
|
|
338
243
|
}
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
}
|
|
244
|
+
size = Math.min(maxSize, size);
|
|
245
|
+
size = parseFloat(size.toFixed(PRECISION));
|
|
342
246
|
return size;
|
|
343
247
|
}
|
|
344
248
|
|
|
345
249
|
// All units must be in percentages; pixel values should be pre-converted
|
|
346
250
|
function adjustLayoutByDelta({
|
|
347
251
|
delta,
|
|
348
|
-
groupSizePixels,
|
|
349
252
|
layout: prevLayout,
|
|
350
|
-
panelConstraints,
|
|
253
|
+
panelConstraints: panelConstraintsArray,
|
|
351
254
|
pivotIndices,
|
|
352
255
|
trigger
|
|
353
256
|
}) {
|
|
@@ -355,6 +258,9 @@ function adjustLayoutByDelta({
|
|
|
355
258
|
return prevLayout;
|
|
356
259
|
}
|
|
357
260
|
const nextLayout = [...prevLayout];
|
|
261
|
+
const [firstPivotIndex, secondPivotIndex] = pivotIndices;
|
|
262
|
+
assert(firstPivotIndex != null);
|
|
263
|
+
assert(secondPivotIndex != null);
|
|
358
264
|
let deltaApplied = 0;
|
|
359
265
|
|
|
360
266
|
//const DEBUG = [];
|
|
@@ -378,18 +284,23 @@ function adjustLayoutByDelta({
|
|
|
378
284
|
if (trigger === "keyboard") {
|
|
379
285
|
{
|
|
380
286
|
// Check if we should expand a collapsed panel
|
|
381
|
-
const index = delta < 0 ?
|
|
382
|
-
const
|
|
287
|
+
const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
288
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
289
|
+
assert(panelConstraints);
|
|
290
|
+
|
|
383
291
|
//DEBUG.push(`edge case check 1: ${index}`);
|
|
384
292
|
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
385
|
-
if (
|
|
293
|
+
if (panelConstraints.collapsible) {
|
|
386
294
|
const prevSize = prevLayout[index];
|
|
295
|
+
assert(prevSize != null);
|
|
296
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
297
|
+
assert(panelConstraints);
|
|
387
298
|
const {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
} =
|
|
391
|
-
if (fuzzyNumbersEqual(prevSize,
|
|
392
|
-
const localDelta =
|
|
299
|
+
collapsedSize = 0,
|
|
300
|
+
minSize = 0
|
|
301
|
+
} = panelConstraints;
|
|
302
|
+
if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
|
|
303
|
+
const localDelta = minSize - prevSize;
|
|
393
304
|
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
394
305
|
|
|
395
306
|
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
@@ -402,18 +313,26 @@ function adjustLayoutByDelta({
|
|
|
402
313
|
|
|
403
314
|
{
|
|
404
315
|
// Check if we should collapse a panel at its minimum size
|
|
405
|
-
const index = delta < 0 ?
|
|
406
|
-
const
|
|
316
|
+
const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
317
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
318
|
+
assert(panelConstraints);
|
|
319
|
+
const {
|
|
320
|
+
collapsible
|
|
321
|
+
} = panelConstraints;
|
|
322
|
+
|
|
407
323
|
//DEBUG.push(`edge case check 2: ${index}`);
|
|
408
|
-
//DEBUG.push(` -> collapsible? ${
|
|
409
|
-
if (
|
|
324
|
+
//DEBUG.push(` -> collapsible? ${collapsible}`);
|
|
325
|
+
if (collapsible) {
|
|
410
326
|
const prevSize = prevLayout[index];
|
|
327
|
+
assert(prevSize != null);
|
|
328
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
329
|
+
assert(panelConstraints);
|
|
411
330
|
const {
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
} =
|
|
415
|
-
if (fuzzyNumbersEqual(prevSize,
|
|
416
|
-
const localDelta = prevSize -
|
|
331
|
+
collapsedSize = 0,
|
|
332
|
+
minSize = 0
|
|
333
|
+
} = panelConstraints;
|
|
334
|
+
if (fuzzyNumbersEqual(prevSize, minSize)) {
|
|
335
|
+
const localDelta = prevSize - collapsedSize;
|
|
417
336
|
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
418
337
|
|
|
419
338
|
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
@@ -435,15 +354,15 @@ function adjustLayoutByDelta({
|
|
|
435
354
|
// as an expanding panel might change from collapsed to min size.
|
|
436
355
|
|
|
437
356
|
const increment = delta < 0 ? 1 : -1;
|
|
438
|
-
let index = delta < 0 ?
|
|
357
|
+
let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
439
358
|
let maxAvailableDelta = 0;
|
|
440
359
|
|
|
441
360
|
//DEBUG.push("pre calc...");
|
|
442
361
|
while (true) {
|
|
443
362
|
const prevSize = prevLayout[index];
|
|
363
|
+
assert(prevSize != null);
|
|
444
364
|
const maxSafeSize = resizePanel({
|
|
445
|
-
|
|
446
|
-
panelConstraints,
|
|
365
|
+
panelConstraints: panelConstraintsArray,
|
|
447
366
|
panelIndex: index,
|
|
448
367
|
size: 100
|
|
449
368
|
});
|
|
@@ -452,7 +371,7 @@ function adjustLayoutByDelta({
|
|
|
452
371
|
|
|
453
372
|
maxAvailableDelta += delta;
|
|
454
373
|
index += increment;
|
|
455
|
-
if (index < 0 || index >=
|
|
374
|
+
if (index < 0 || index >= panelConstraintsArray.length) {
|
|
456
375
|
break;
|
|
457
376
|
}
|
|
458
377
|
}
|
|
@@ -467,15 +386,15 @@ function adjustLayoutByDelta({
|
|
|
467
386
|
{
|
|
468
387
|
// Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
|
|
469
388
|
|
|
470
|
-
const pivotIndex = delta < 0 ?
|
|
389
|
+
const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
471
390
|
let index = pivotIndex;
|
|
472
|
-
while (index >= 0 && index <
|
|
391
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
473
392
|
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
474
393
|
const prevSize = prevLayout[index];
|
|
394
|
+
assert(prevSize != null);
|
|
475
395
|
const unsafeSize = prevSize - deltaRemaining;
|
|
476
396
|
const safeSize = resizePanel({
|
|
477
|
-
|
|
478
|
-
panelConstraints,
|
|
397
|
+
panelConstraints: panelConstraintsArray,
|
|
479
398
|
panelIndex: index,
|
|
480
399
|
size: unsafeSize
|
|
481
400
|
});
|
|
@@ -507,11 +426,12 @@ function adjustLayoutByDelta({
|
|
|
507
426
|
}
|
|
508
427
|
{
|
|
509
428
|
// Now distribute the applied delta to the panels in the other direction
|
|
510
|
-
const pivotIndex = delta < 0 ?
|
|
511
|
-
const
|
|
429
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
430
|
+
const prevSize = prevLayout[pivotIndex];
|
|
431
|
+
assert(prevSize != null);
|
|
432
|
+
const unsafeSize = prevSize + deltaApplied;
|
|
512
433
|
const safeSize = resizePanel({
|
|
513
|
-
|
|
514
|
-
panelConstraints,
|
|
434
|
+
panelConstraints: panelConstraintsArray,
|
|
515
435
|
panelIndex: pivotIndex,
|
|
516
436
|
size: unsafeSize
|
|
517
437
|
});
|
|
@@ -522,14 +442,14 @@ function adjustLayoutByDelta({
|
|
|
522
442
|
// Edge case where expanding or contracting one panel caused another one to change collapsed state
|
|
523
443
|
if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
|
|
524
444
|
let deltaRemaining = unsafeSize - safeSize;
|
|
525
|
-
const pivotIndex = delta < 0 ?
|
|
445
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
526
446
|
let index = pivotIndex;
|
|
527
|
-
while (index >= 0 && index <
|
|
447
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
528
448
|
const prevSize = nextLayout[index];
|
|
449
|
+
assert(prevSize != null);
|
|
529
450
|
const unsafeSize = prevSize + deltaRemaining;
|
|
530
451
|
const safeSize = resizePanel({
|
|
531
|
-
|
|
532
|
-
panelConstraints,
|
|
452
|
+
panelConstraints: panelConstraintsArray,
|
|
533
453
|
panelIndex: index,
|
|
534
454
|
size: unsafeSize
|
|
535
455
|
});
|
|
@@ -553,9 +473,7 @@ function adjustLayoutByDelta({
|
|
|
553
473
|
//DEBUG.push("");
|
|
554
474
|
|
|
555
475
|
const totalSize = nextLayout.reduce((total, size) => size + total, 0);
|
|
556
|
-
deltaApplied = 100 - totalSize;
|
|
557
476
|
//DEBUG.push(`total size: ${totalSize}`);
|
|
558
|
-
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
559
477
|
//console.log(DEBUG.join("\n"));
|
|
560
478
|
|
|
561
479
|
if (!fuzzyNumbersEqual(totalSize, 100)) {
|
|
@@ -564,27 +482,7 @@ function adjustLayoutByDelta({
|
|
|
564
482
|
return nextLayout;
|
|
565
483
|
}
|
|
566
484
|
|
|
567
|
-
function assert(expectedCondition, message = "Assertion failed!") {
|
|
568
|
-
if (!expectedCondition) {
|
|
569
|
-
console.error(message);
|
|
570
|
-
throw Error(message);
|
|
571
|
-
}
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
function getPercentageSizeFromMixedSizes({
|
|
575
|
-
sizePercentage,
|
|
576
|
-
sizePixels
|
|
577
|
-
}, groupSizePixels) {
|
|
578
|
-
if (sizePercentage != null) {
|
|
579
|
-
return sizePercentage;
|
|
580
|
-
} else if (sizePixels != null) {
|
|
581
|
-
return convertPixelsToPercentage(sizePixels, groupSizePixels);
|
|
582
|
-
}
|
|
583
|
-
return undefined;
|
|
584
|
-
}
|
|
585
|
-
|
|
586
485
|
function calculateAriaValues({
|
|
587
|
-
groupSizePixels,
|
|
588
486
|
layout,
|
|
589
487
|
panelsArray,
|
|
590
488
|
pivotIndices
|
|
@@ -593,28 +491,19 @@ function calculateAriaValues({
|
|
|
593
491
|
let currentMaxSize = 100;
|
|
594
492
|
let totalMinSize = 0;
|
|
595
493
|
let totalMaxSize = 0;
|
|
494
|
+
const firstIndex = pivotIndices[0];
|
|
495
|
+
assert(firstIndex != null);
|
|
596
496
|
|
|
597
497
|
// A panel's effective min/max sizes also need to account for other panel's sizes.
|
|
598
498
|
panelsArray.forEach((panelData, index) => {
|
|
599
|
-
var _getPercentageSizeFro, _getPercentageSizeFro2;
|
|
600
499
|
const {
|
|
601
500
|
constraints
|
|
602
501
|
} = panelData;
|
|
603
502
|
const {
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
minSizePercentage,
|
|
607
|
-
minSizePixels
|
|
503
|
+
maxSize = 100,
|
|
504
|
+
minSize = 0
|
|
608
505
|
} = constraints;
|
|
609
|
-
|
|
610
|
-
sizePercentage: minSizePercentage,
|
|
611
|
-
sizePixels: minSizePixels
|
|
612
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
613
|
-
const maxSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
|
|
614
|
-
sizePercentage: maxSizePercentage,
|
|
615
|
-
sizePixels: maxSizePixels
|
|
616
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 100;
|
|
617
|
-
if (index === pivotIndices[0]) {
|
|
506
|
+
if (index === firstIndex) {
|
|
618
507
|
currentMinSize = minSize;
|
|
619
508
|
currentMaxSize = maxSize;
|
|
620
509
|
} else {
|
|
@@ -624,7 +513,7 @@ function calculateAriaValues({
|
|
|
624
513
|
});
|
|
625
514
|
const valueMax = Math.min(currentMaxSize, 100 - totalMinSize);
|
|
626
515
|
const valueMin = Math.max(currentMinSize, 100 - totalMaxSize);
|
|
627
|
-
const valueNow = layout[
|
|
516
|
+
const valueNow = layout[firstIndex];
|
|
628
517
|
return {
|
|
629
518
|
valueMax,
|
|
630
519
|
valueMin,
|
|
@@ -655,42 +544,6 @@ function getPanelGroupElement(id) {
|
|
|
655
544
|
return null;
|
|
656
545
|
}
|
|
657
546
|
|
|
658
|
-
function calculateAvailablePanelSizeInPixels(groupId) {
|
|
659
|
-
const panelGroupElement = getPanelGroupElement(groupId);
|
|
660
|
-
if (panelGroupElement == null) {
|
|
661
|
-
return NaN;
|
|
662
|
-
}
|
|
663
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
664
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId);
|
|
665
|
-
if (direction === "horizontal") {
|
|
666
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
667
|
-
return accumulated + handle.offsetWidth;
|
|
668
|
-
}, 0);
|
|
669
|
-
} else {
|
|
670
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
671
|
-
return accumulated + handle.offsetHeight;
|
|
672
|
-
}, 0);
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
function getAvailableGroupSizePixels(groupId) {
|
|
677
|
-
const panelGroupElement = getPanelGroupElement(groupId);
|
|
678
|
-
if (panelGroupElement == null) {
|
|
679
|
-
return NaN;
|
|
680
|
-
}
|
|
681
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
682
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId);
|
|
683
|
-
if (direction === "horizontal") {
|
|
684
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
685
|
-
return accumulated + handle.offsetWidth;
|
|
686
|
-
}, 0);
|
|
687
|
-
} else {
|
|
688
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
689
|
-
return accumulated + handle.offsetHeight;
|
|
690
|
-
}, 0);
|
|
691
|
-
}
|
|
692
|
-
}
|
|
693
|
-
|
|
694
547
|
function getResizeHandleElement(id) {
|
|
695
548
|
const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
|
|
696
549
|
if (element) {
|
|
@@ -723,7 +576,6 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
723
576
|
didWarnAboutMissingResizeHandle: false
|
|
724
577
|
});
|
|
725
578
|
useIsomorphicLayoutEffect(() => {
|
|
726
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
727
579
|
const resizeHandleElements = getResizeHandleElementsForGroup(groupId);
|
|
728
580
|
for (let index = 0; index < panelDataArray.length - 1; index++) {
|
|
729
581
|
const {
|
|
@@ -731,17 +583,18 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
731
583
|
valueMin,
|
|
732
584
|
valueNow
|
|
733
585
|
} = calculateAriaValues({
|
|
734
|
-
groupSizePixels,
|
|
735
586
|
layout,
|
|
736
587
|
panelsArray: panelDataArray,
|
|
737
588
|
pivotIndices: [index, index + 1]
|
|
738
589
|
});
|
|
739
590
|
const resizeHandleElement = resizeHandleElements[index];
|
|
740
591
|
if (resizeHandleElement == null) ; else {
|
|
741
|
-
|
|
592
|
+
const panelData = panelDataArray[index];
|
|
593
|
+
assert(panelData);
|
|
594
|
+
resizeHandleElement.setAttribute("aria-controls", panelData.id);
|
|
742
595
|
resizeHandleElement.setAttribute("aria-valuemax", "" + Math.round(valueMax));
|
|
743
596
|
resizeHandleElement.setAttribute("aria-valuemin", "" + Math.round(valueMin));
|
|
744
|
-
resizeHandleElement.setAttribute("aria-valuenow", "" + Math.round(valueNow));
|
|
597
|
+
resizeHandleElement.setAttribute("aria-valuenow", valueNow != null ? "" + Math.round(valueNow) : "");
|
|
745
598
|
}
|
|
746
599
|
}
|
|
747
600
|
return () => {
|
|
@@ -754,14 +607,18 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
754
607
|
};
|
|
755
608
|
}, [groupId, layout, panelDataArray]);
|
|
756
609
|
useEffect(() => {
|
|
610
|
+
const eagerValues = eagerValuesRef.current;
|
|
611
|
+
assert(eagerValues);
|
|
757
612
|
const {
|
|
758
613
|
panelDataArray
|
|
759
|
-
} =
|
|
614
|
+
} = eagerValues;
|
|
760
615
|
const groupElement = getPanelGroupElement(groupId);
|
|
761
616
|
assert(groupElement != null, `No group found for id "${groupId}"`);
|
|
762
617
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
618
|
+
assert(handles);
|
|
763
619
|
const cleanupFunctions = handles.map(handle => {
|
|
764
620
|
const handleId = handle.getAttribute("data-panel-resize-handle-id");
|
|
621
|
+
assert(handleId);
|
|
765
622
|
const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
|
|
766
623
|
if (idBefore == null || idAfter == null) {
|
|
767
624
|
return () => {};
|
|
@@ -777,21 +634,16 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
777
634
|
const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
|
|
778
635
|
if (index >= 0) {
|
|
779
636
|
const panelData = panelDataArray[index];
|
|
637
|
+
assert(panelData);
|
|
780
638
|
const size = layout[index];
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
788
|
-
const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
|
|
789
|
-
sizePercentage: panelData.constraints.minSizePercentage,
|
|
790
|
-
sizePixels: panelData.constraints.minSizePixels
|
|
791
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
|
|
639
|
+
const {
|
|
640
|
+
collapsedSize = 0,
|
|
641
|
+
collapsible,
|
|
642
|
+
minSize = 0
|
|
643
|
+
} = panelData.constraints;
|
|
644
|
+
if (size != null && collapsible) {
|
|
792
645
|
const nextLayout = adjustLayoutByDelta({
|
|
793
646
|
delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
|
|
794
|
-
groupSizePixels,
|
|
795
647
|
layout,
|
|
796
648
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints),
|
|
797
649
|
pivotIndices: determinePivotIndices(groupId, handleId),
|
|
@@ -845,6 +697,7 @@ function getResizeEventCursorPosition(direction, event) {
|
|
|
845
697
|
return isHorizontal ? event.clientX : event.clientY;
|
|
846
698
|
} else if (isTouchEvent(event)) {
|
|
847
699
|
const firstTouch = event.touches[0];
|
|
700
|
+
assert(firstTouch);
|
|
848
701
|
return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
|
|
849
702
|
} else {
|
|
850
703
|
throw Error(`Unsupported event type "${event.type}"`);
|
|
@@ -854,12 +707,15 @@ function getResizeEventCursorPosition(direction, event) {
|
|
|
854
707
|
function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
|
|
855
708
|
const isHorizontal = direction === "horizontal";
|
|
856
709
|
const handleElement = getResizeHandleElement(dragHandleId);
|
|
710
|
+
assert(handleElement);
|
|
857
711
|
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
712
|
+
assert(groupId);
|
|
858
713
|
let {
|
|
859
714
|
initialCursorPosition
|
|
860
715
|
} = initialDragState;
|
|
861
716
|
const cursorPosition = getResizeEventCursorPosition(direction, event);
|
|
862
717
|
const groupElement = getPanelGroupElement(groupId);
|
|
718
|
+
assert(groupElement);
|
|
863
719
|
const groupRect = groupElement.getBoundingClientRect();
|
|
864
720
|
const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
|
|
865
721
|
const offsetPixels = cursorPosition - initialCursorPosition;
|
|
@@ -868,19 +724,14 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
|
|
|
868
724
|
}
|
|
869
725
|
|
|
870
726
|
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
|
|
871
|
-
function calculateDeltaPercentage(event,
|
|
727
|
+
function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
|
|
872
728
|
if (isKeyDown(event)) {
|
|
873
729
|
const isHorizontal = direction === "horizontal";
|
|
874
|
-
const groupElement = getPanelGroupElement(groupId);
|
|
875
|
-
const rect = groupElement.getBoundingClientRect();
|
|
876
|
-
const groupSizeInPixels = isHorizontal ? rect.width : rect.height;
|
|
877
730
|
let delta = 0;
|
|
878
731
|
if (event.shiftKey) {
|
|
879
732
|
delta = 100;
|
|
880
|
-
} else if (
|
|
881
|
-
delta =
|
|
882
|
-
} else if (keyboardResizeByOptions.pixels != null) {
|
|
883
|
-
delta = keyboardResizeByOptions.pixels / groupSizeInPixels;
|
|
733
|
+
} else if (keyboardResizeBy != null) {
|
|
734
|
+
delta = keyboardResizeBy;
|
|
884
735
|
} else {
|
|
885
736
|
delta = 10;
|
|
886
737
|
}
|
|
@@ -907,37 +758,43 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
|
|
|
907
758
|
}
|
|
908
759
|
return movement;
|
|
909
760
|
} else {
|
|
761
|
+
if (initialDragState == null) {
|
|
762
|
+
return 0;
|
|
763
|
+
}
|
|
910
764
|
return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
|
|
911
765
|
}
|
|
912
766
|
}
|
|
913
767
|
|
|
914
768
|
function calculateUnsafeDefaultLayout({
|
|
915
|
-
groupSizePixels,
|
|
916
769
|
panelDataArray
|
|
917
770
|
}) {
|
|
918
771
|
const layout = Array(panelDataArray.length);
|
|
919
|
-
const
|
|
772
|
+
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
920
773
|
let numPanelsWithSizes = 0;
|
|
921
774
|
let remainingSize = 100;
|
|
922
775
|
|
|
923
776
|
// Distribute default sizes first
|
|
924
777
|
for (let index = 0; index < panelDataArray.length; index++) {
|
|
778
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
779
|
+
assert(panelConstraints);
|
|
925
780
|
const {
|
|
926
|
-
|
|
927
|
-
} =
|
|
928
|
-
if (
|
|
781
|
+
defaultSize
|
|
782
|
+
} = panelConstraints;
|
|
783
|
+
if (defaultSize != null) {
|
|
929
784
|
numPanelsWithSizes++;
|
|
930
|
-
layout[index] =
|
|
931
|
-
remainingSize -=
|
|
785
|
+
layout[index] = defaultSize;
|
|
786
|
+
remainingSize -= defaultSize;
|
|
932
787
|
}
|
|
933
788
|
}
|
|
934
789
|
|
|
935
790
|
// Remaining size should be distributed evenly between panels without default sizes
|
|
936
791
|
for (let index = 0; index < panelDataArray.length; index++) {
|
|
792
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
793
|
+
assert(panelConstraints);
|
|
937
794
|
const {
|
|
938
|
-
|
|
939
|
-
} =
|
|
940
|
-
if (
|
|
795
|
+
defaultSize
|
|
796
|
+
} = panelConstraints;
|
|
797
|
+
if (defaultSize != null) {
|
|
941
798
|
continue;
|
|
942
799
|
}
|
|
943
800
|
const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
|
|
@@ -949,54 +806,36 @@ function calculateUnsafeDefaultLayout({
|
|
|
949
806
|
return layout;
|
|
950
807
|
}
|
|
951
808
|
|
|
952
|
-
function convertPercentageToPixels(percentage, groupSizePixels) {
|
|
953
|
-
return percentage / 100 * groupSizePixels;
|
|
954
|
-
}
|
|
955
|
-
|
|
956
809
|
// Layout should be pre-converted into percentages
|
|
957
|
-
function callPanelCallbacks(
|
|
958
|
-
|
|
959
|
-
layout.forEach((sizePercentage, index) => {
|
|
810
|
+
function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
|
|
811
|
+
layout.forEach((size, index) => {
|
|
960
812
|
const panelData = panelsArray[index];
|
|
961
|
-
|
|
962
|
-
// Handle initial mount (when panels are registered too late to be in the panels array)
|
|
963
|
-
// The subsequent render+effects will handle the resize notification
|
|
964
|
-
return;
|
|
965
|
-
}
|
|
813
|
+
assert(panelData);
|
|
966
814
|
const {
|
|
967
815
|
callbacks,
|
|
968
816
|
constraints,
|
|
969
817
|
id: panelId
|
|
970
818
|
} = panelData;
|
|
971
819
|
const {
|
|
820
|
+
collapsedSize = 0,
|
|
972
821
|
collapsible
|
|
973
822
|
} = constraints;
|
|
974
|
-
const
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
};
|
|
978
|
-
const lastNotifiedMixedSizes = panelIdToLastNotifiedMixedSizesMap[panelId];
|
|
979
|
-
if (lastNotifiedMixedSizes == null || mixedSizes.sizePercentage !== lastNotifiedMixedSizes.sizePercentage || mixedSizes.sizePixels !== lastNotifiedMixedSizes.sizePixels) {
|
|
980
|
-
panelIdToLastNotifiedMixedSizesMap[panelId] = mixedSizes;
|
|
823
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
|
|
824
|
+
if (lastNotifiedSize == null || size !== lastNotifiedSize) {
|
|
825
|
+
panelIdToLastNotifiedSizeMap[panelId] = size;
|
|
981
826
|
const {
|
|
982
827
|
onCollapse,
|
|
983
828
|
onExpand,
|
|
984
829
|
onResize
|
|
985
830
|
} = callbacks;
|
|
986
831
|
if (onResize) {
|
|
987
|
-
onResize(
|
|
832
|
+
onResize(size, lastNotifiedSize);
|
|
988
833
|
}
|
|
989
834
|
if (collapsible && (onCollapse || onExpand)) {
|
|
990
|
-
|
|
991
|
-
const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
|
|
992
|
-
sizePercentage: constraints.collapsedSizePercentage,
|
|
993
|
-
sizePixels: constraints.collapsedSizePixels
|
|
994
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
995
|
-
const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
|
|
996
|
-
if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
|
|
835
|
+
if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
|
|
997
836
|
onExpand();
|
|
998
837
|
}
|
|
999
|
-
if (onCollapse && (
|
|
838
|
+
if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
|
|
1000
839
|
onCollapse();
|
|
1001
840
|
}
|
|
1002
841
|
}
|
|
@@ -1030,9 +869,10 @@ function computePanelFlexBoxStyle({
|
|
|
1030
869
|
const size = layout[panelIndex];
|
|
1031
870
|
let flexGrow;
|
|
1032
871
|
if (panelData.length === 1) {
|
|
1033
|
-
flexGrow = "
|
|
872
|
+
flexGrow = "1";
|
|
1034
873
|
} else if (size == null) {
|
|
1035
|
-
|
|
874
|
+
// Initial render (before panels have registered themselves)
|
|
875
|
+
flexGrow = "1";
|
|
1036
876
|
} else {
|
|
1037
877
|
flexGrow = size.toPrecision(precision);
|
|
1038
878
|
}
|
|
@@ -1178,31 +1018,32 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
|
|
|
1178
1018
|
}
|
|
1179
1019
|
}
|
|
1180
1020
|
|
|
1181
|
-
function shouldMonitorPixelBasedConstraints(constraints) {
|
|
1182
|
-
return constraints.some(constraints => {
|
|
1183
|
-
return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
|
|
1184
|
-
});
|
|
1185
|
-
}
|
|
1186
|
-
|
|
1187
1021
|
// All units must be in percentages; pixel values should be pre-converted
|
|
1188
1022
|
function validatePanelGroupLayout({
|
|
1189
|
-
groupSizePixels,
|
|
1190
1023
|
layout: prevLayout,
|
|
1191
1024
|
panelConstraints
|
|
1192
1025
|
}) {
|
|
1193
1026
|
const nextLayout = [...prevLayout];
|
|
1027
|
+
const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
|
|
1194
1028
|
|
|
1195
1029
|
// Validate layout expectations
|
|
1196
1030
|
if (nextLayout.length !== panelConstraints.length) {
|
|
1197
1031
|
throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
|
|
1198
|
-
} else if (!fuzzyNumbersEqual(
|
|
1032
|
+
} else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
|
|
1033
|
+
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1034
|
+
const unsafeSize = nextLayout[index];
|
|
1035
|
+
assert(unsafeSize != null);
|
|
1036
|
+
const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
|
|
1037
|
+
nextLayout[index] = safeSize;
|
|
1038
|
+
}
|
|
1039
|
+
}
|
|
1199
1040
|
let remainingSize = 0;
|
|
1200
1041
|
|
|
1201
1042
|
// First pass: Validate the proposed layout given each panel's constraints
|
|
1202
1043
|
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1203
1044
|
const unsafeSize = nextLayout[index];
|
|
1045
|
+
assert(unsafeSize != null);
|
|
1204
1046
|
const safeSize = resizePanel({
|
|
1205
|
-
groupSizePixels,
|
|
1206
1047
|
panelConstraints,
|
|
1207
1048
|
panelIndex: index,
|
|
1208
1049
|
size: unsafeSize
|
|
@@ -1218,9 +1059,9 @@ function validatePanelGroupLayout({
|
|
|
1218
1059
|
if (!fuzzyNumbersEqual(remainingSize, 0)) {
|
|
1219
1060
|
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1220
1061
|
const prevSize = nextLayout[index];
|
|
1062
|
+
assert(prevSize != null);
|
|
1221
1063
|
const unsafeSize = prevSize + remainingSize;
|
|
1222
1064
|
const safeSize = resizePanel({
|
|
1223
|
-
groupSizePixels,
|
|
1224
1065
|
panelConstraints,
|
|
1225
1066
|
panelIndex: index,
|
|
1226
1067
|
size: unsafeSize
|
|
@@ -1255,21 +1096,20 @@ function PanelGroupWithForwardedRef({
|
|
|
1255
1096
|
autoSaveId = null,
|
|
1256
1097
|
children,
|
|
1257
1098
|
className: classNameFromProps = "",
|
|
1258
|
-
dataAttributes,
|
|
1259
1099
|
direction,
|
|
1260
1100
|
forwardedRef,
|
|
1261
|
-
id: idFromProps,
|
|
1101
|
+
id: idFromProps = null,
|
|
1262
1102
|
onLayout = null,
|
|
1263
|
-
|
|
1264
|
-
keyboardResizeByPixels = null,
|
|
1103
|
+
keyboardResizeBy = null,
|
|
1265
1104
|
storage = defaultStorage,
|
|
1266
1105
|
style: styleFromProps,
|
|
1267
|
-
tagName: Type = "div"
|
|
1106
|
+
tagName: Type = "div",
|
|
1107
|
+
...rest
|
|
1268
1108
|
}) {
|
|
1269
1109
|
const groupId = useUniqueId(idFromProps);
|
|
1270
1110
|
const [dragState, setDragState] = useState(null);
|
|
1271
1111
|
const [layout, setLayout] = useState([]);
|
|
1272
|
-
const
|
|
1112
|
+
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1273
1113
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1274
1114
|
const prevDeltaRef = useRef(0);
|
|
1275
1115
|
const committedValuesRef = useRef({
|
|
@@ -1277,8 +1117,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1277
1117
|
direction,
|
|
1278
1118
|
dragState,
|
|
1279
1119
|
id: groupId,
|
|
1280
|
-
|
|
1281
|
-
keyboardResizeByPixels,
|
|
1120
|
+
keyboardResizeBy,
|
|
1282
1121
|
onLayout,
|
|
1283
1122
|
storage
|
|
1284
1123
|
});
|
|
@@ -1294,33 +1133,20 @@ function PanelGroupWithForwardedRef({
|
|
|
1294
1133
|
useImperativeHandle(forwardedRef, () => ({
|
|
1295
1134
|
getId: () => committedValuesRef.current.id,
|
|
1296
1135
|
getLayout: () => {
|
|
1297
|
-
const {
|
|
1298
|
-
id: groupId
|
|
1299
|
-
} = committedValuesRef.current;
|
|
1300
1136
|
const {
|
|
1301
1137
|
layout
|
|
1302
1138
|
} = eagerValuesRef.current;
|
|
1303
|
-
|
|
1304
|
-
return layout.map(sizePercentage => {
|
|
1305
|
-
return {
|
|
1306
|
-
sizePercentage,
|
|
1307
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1308
|
-
};
|
|
1309
|
-
});
|
|
1139
|
+
return layout;
|
|
1310
1140
|
},
|
|
1311
|
-
setLayout:
|
|
1141
|
+
setLayout: unsafeLayout => {
|
|
1312
1142
|
const {
|
|
1313
|
-
id: groupId,
|
|
1314
1143
|
onLayout
|
|
1315
1144
|
} = committedValuesRef.current;
|
|
1316
1145
|
const {
|
|
1317
1146
|
layout: prevLayout,
|
|
1318
1147
|
panelDataArray
|
|
1319
1148
|
} = eagerValuesRef.current;
|
|
1320
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1321
|
-
const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
|
|
1322
1149
|
const safeLayout = validatePanelGroupLayout({
|
|
1323
|
-
groupSizePixels,
|
|
1324
1150
|
layout: unsafeLayout,
|
|
1325
1151
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1326
1152
|
});
|
|
@@ -1328,12 +1154,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1328
1154
|
setLayout(safeLayout);
|
|
1329
1155
|
eagerValuesRef.current.layout = safeLayout;
|
|
1330
1156
|
if (onLayout) {
|
|
1331
|
-
onLayout(safeLayout
|
|
1332
|
-
sizePercentage,
|
|
1333
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1334
|
-
})));
|
|
1157
|
+
onLayout(safeLayout);
|
|
1335
1158
|
}
|
|
1336
|
-
callPanelCallbacks(
|
|
1159
|
+
callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1337
1160
|
}
|
|
1338
1161
|
}
|
|
1339
1162
|
}), []);
|
|
@@ -1344,11 +1167,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1344
1167
|
committedValuesRef.current.id = groupId;
|
|
1345
1168
|
committedValuesRef.current.onLayout = onLayout;
|
|
1346
1169
|
committedValuesRef.current.storage = storage;
|
|
1347
|
-
|
|
1348
|
-
// panelDataArray and layout are updated in-sync with scheduled state updates.
|
|
1349
|
-
// TODO [217] Move these values into a separate ref
|
|
1350
1170
|
});
|
|
1351
|
-
|
|
1352
1171
|
useWindowSplitterPanelGroupBehavior({
|
|
1353
1172
|
committedValuesRef,
|
|
1354
1173
|
eagerValuesRef,
|
|
@@ -1367,57 +1186,16 @@ function PanelGroupWithForwardedRef({
|
|
|
1367
1186
|
if (layout.length === 0 || layout.length !== panelDataArray.length) {
|
|
1368
1187
|
return;
|
|
1369
1188
|
}
|
|
1189
|
+
let debouncedSave = debounceMap[autoSaveId];
|
|
1370
1190
|
|
|
1371
1191
|
// Limit the frequency of localStorage updates.
|
|
1372
|
-
if (
|
|
1373
|
-
|
|
1192
|
+
if (debouncedSave == null) {
|
|
1193
|
+
debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1194
|
+
debounceMap[autoSaveId] = debouncedSave;
|
|
1374
1195
|
}
|
|
1375
|
-
|
|
1196
|
+
debouncedSave(autoSaveId, panelDataArray, layout, storage);
|
|
1376
1197
|
}
|
|
1377
1198
|
}, [autoSaveId, layout, storage]);
|
|
1378
|
-
useIsomorphicLayoutEffect(() => {
|
|
1379
|
-
const {
|
|
1380
|
-
layout: prevLayout,
|
|
1381
|
-
panelDataArray
|
|
1382
|
-
} = eagerValuesRef.current;
|
|
1383
|
-
const constraints = panelDataArray.map(({
|
|
1384
|
-
constraints
|
|
1385
|
-
}) => constraints);
|
|
1386
|
-
if (!shouldMonitorPixelBasedConstraints(constraints)) {
|
|
1387
|
-
// Avoid the overhead of ResizeObserver if no pixel constraints require monitoring
|
|
1388
|
-
return;
|
|
1389
|
-
}
|
|
1390
|
-
if (typeof ResizeObserver === "undefined") {
|
|
1391
|
-
console.warn(`WARNING: Pixel based constraints require ResizeObserver but it is not supported by the current browser.`);
|
|
1392
|
-
} else {
|
|
1393
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
1394
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1395
|
-
const {
|
|
1396
|
-
onLayout
|
|
1397
|
-
} = committedValuesRef.current;
|
|
1398
|
-
const nextLayout = validatePanelGroupLayout({
|
|
1399
|
-
groupSizePixels,
|
|
1400
|
-
layout: prevLayout,
|
|
1401
|
-
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1402
|
-
});
|
|
1403
|
-
if (!areEqual(prevLayout, nextLayout)) {
|
|
1404
|
-
setLayout(nextLayout);
|
|
1405
|
-
eagerValuesRef.current.layout = nextLayout;
|
|
1406
|
-
if (onLayout) {
|
|
1407
|
-
onLayout(nextLayout.map(sizePercentage => ({
|
|
1408
|
-
sizePercentage,
|
|
1409
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1410
|
-
})));
|
|
1411
|
-
}
|
|
1412
|
-
callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
|
|
1413
|
-
}
|
|
1414
|
-
});
|
|
1415
|
-
resizeObserver.observe(getPanelGroupElement(groupId));
|
|
1416
|
-
return () => {
|
|
1417
|
-
resizeObserver.disconnect();
|
|
1418
|
-
};
|
|
1419
|
-
}
|
|
1420
|
-
}, [groupId]);
|
|
1421
1199
|
|
|
1422
1200
|
// DEV warnings
|
|
1423
1201
|
useEffect(() => {
|
|
@@ -1435,20 +1213,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1435
1213
|
if (panelData.constraints.collapsible) {
|
|
1436
1214
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1437
1215
|
const {
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
pivotIndices
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
if (
|
|
1216
|
+
collapsedSize = 0,
|
|
1217
|
+
panelSize,
|
|
1218
|
+
pivotIndices
|
|
1219
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1220
|
+
assert(panelSize != null);
|
|
1221
|
+
if (panelSize !== collapsedSize) {
|
|
1444
1222
|
// Store size before collapse;
|
|
1445
1223
|
// This is the size that gets restored if the expand() API is used.
|
|
1446
|
-
panelSizeBeforeCollapseRef.current.set(panelData.id,
|
|
1224
|
+
panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
|
|
1447
1225
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1448
|
-
const delta = isLastPanel ?
|
|
1226
|
+
const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
|
|
1449
1227
|
const nextLayout = adjustLayoutByDelta({
|
|
1450
1228
|
delta,
|
|
1451
|
-
groupSizePixels,
|
|
1452
1229
|
layout: prevLayout,
|
|
1453
1230
|
panelConstraints: panelConstraintsArray,
|
|
1454
1231
|
pivotIndices,
|
|
@@ -1458,16 +1235,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1458
1235
|
setLayout(nextLayout);
|
|
1459
1236
|
eagerValuesRef.current.layout = nextLayout;
|
|
1460
1237
|
if (onLayout) {
|
|
1461
|
-
onLayout(nextLayout
|
|
1462
|
-
sizePercentage,
|
|
1463
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1464
|
-
})));
|
|
1238
|
+
onLayout(nextLayout);
|
|
1465
1239
|
}
|
|
1466
|
-
callPanelCallbacks(
|
|
1240
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1467
1241
|
}
|
|
1468
1242
|
}
|
|
1469
1243
|
}
|
|
1470
|
-
}, [
|
|
1244
|
+
}, []);
|
|
1471
1245
|
|
|
1472
1246
|
// External APIs are safe to memoize via committed values ref
|
|
1473
1247
|
const expandPanel = useCallback(panelData => {
|
|
@@ -1481,21 +1255,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1481
1255
|
if (panelData.constraints.collapsible) {
|
|
1482
1256
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1483
1257
|
const {
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
pivotIndices
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
if (panelSizePercentage === collapsedSizePercentage) {
|
|
1258
|
+
collapsedSize = 0,
|
|
1259
|
+
panelSize,
|
|
1260
|
+
minSize = 0,
|
|
1261
|
+
pivotIndices
|
|
1262
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1263
|
+
if (panelSize === collapsedSize) {
|
|
1491
1264
|
// Restore this panel to the size it was before it was collapsed, if possible.
|
|
1492
|
-
const
|
|
1493
|
-
const
|
|
1265
|
+
const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
|
|
1266
|
+
const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
|
|
1494
1267
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1495
|
-
const delta = isLastPanel ?
|
|
1268
|
+
const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
|
|
1496
1269
|
const nextLayout = adjustLayoutByDelta({
|
|
1497
1270
|
delta,
|
|
1498
|
-
groupSizePixels,
|
|
1499
1271
|
layout: prevLayout,
|
|
1500
1272
|
panelConstraints: panelConstraintsArray,
|
|
1501
1273
|
pivotIndices,
|
|
@@ -1505,16 +1277,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1505
1277
|
setLayout(nextLayout);
|
|
1506
1278
|
eagerValuesRef.current.layout = nextLayout;
|
|
1507
1279
|
if (onLayout) {
|
|
1508
|
-
onLayout(nextLayout
|
|
1509
|
-
sizePercentage,
|
|
1510
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1511
|
-
})));
|
|
1280
|
+
onLayout(nextLayout);
|
|
1512
1281
|
}
|
|
1513
|
-
callPanelCallbacks(
|
|
1282
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1514
1283
|
}
|
|
1515
1284
|
}
|
|
1516
1285
|
}
|
|
1517
|
-
}, [
|
|
1286
|
+
}, []);
|
|
1518
1287
|
|
|
1519
1288
|
// External APIs are safe to memoize via committed values ref
|
|
1520
1289
|
const getPanelSize = useCallback(panelData => {
|
|
@@ -1523,14 +1292,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1523
1292
|
panelDataArray
|
|
1524
1293
|
} = eagerValuesRef.current;
|
|
1525
1294
|
const {
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
return
|
|
1530
|
-
|
|
1531
|
-
sizePixels: panelSizePixels
|
|
1532
|
-
};
|
|
1533
|
-
}, [groupId]);
|
|
1295
|
+
panelSize
|
|
1296
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1297
|
+
assert(panelSize != null);
|
|
1298
|
+
return panelSize;
|
|
1299
|
+
}, []);
|
|
1534
1300
|
|
|
1535
1301
|
// This API should never read from committedValuesRef
|
|
1536
1302
|
const getPanelStyle = useCallback(panelData => {
|
|
@@ -1553,12 +1319,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1553
1319
|
panelDataArray
|
|
1554
1320
|
} = eagerValuesRef.current;
|
|
1555
1321
|
const {
|
|
1556
|
-
|
|
1322
|
+
collapsedSize,
|
|
1557
1323
|
collapsible,
|
|
1558
|
-
|
|
1559
|
-
} = panelDataHelper(
|
|
1560
|
-
return collapsible === true &&
|
|
1561
|
-
}, [
|
|
1324
|
+
panelSize
|
|
1325
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1326
|
+
return collapsible === true && panelSize === collapsedSize;
|
|
1327
|
+
}, []);
|
|
1562
1328
|
|
|
1563
1329
|
// External APIs are safe to memoize via committed values ref
|
|
1564
1330
|
const isPanelExpanded = useCallback(panelData => {
|
|
@@ -1567,12 +1333,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1567
1333
|
panelDataArray
|
|
1568
1334
|
} = eagerValuesRef.current;
|
|
1569
1335
|
const {
|
|
1570
|
-
|
|
1336
|
+
collapsedSize = 0,
|
|
1571
1337
|
collapsible,
|
|
1572
|
-
|
|
1573
|
-
} = panelDataHelper(
|
|
1574
|
-
|
|
1575
|
-
|
|
1338
|
+
panelSize
|
|
1339
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1340
|
+
assert(panelSize != null);
|
|
1341
|
+
return !collapsible || panelSize > collapsedSize;
|
|
1342
|
+
}, []);
|
|
1576
1343
|
const registerPanel = useCallback(panelData => {
|
|
1577
1344
|
const {
|
|
1578
1345
|
autoSaveId,
|
|
@@ -1612,18 +1379,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1612
1379
|
if (autoSaveId) {
|
|
1613
1380
|
unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
|
|
1614
1381
|
}
|
|
1615
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1616
|
-
if (groupSizePixels <= 0) {
|
|
1617
|
-
if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
|
|
1618
|
-
constraints
|
|
1619
|
-
}) => constraints))) {
|
|
1620
|
-
// Wait until the group has rendered a non-zero size before computing layout.
|
|
1621
|
-
return;
|
|
1622
|
-
}
|
|
1623
|
-
}
|
|
1624
1382
|
if (unsafeLayout == null) {
|
|
1625
1383
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1626
|
-
groupSizePixels,
|
|
1627
1384
|
panelDataArray
|
|
1628
1385
|
});
|
|
1629
1386
|
}
|
|
@@ -1631,7 +1388,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1631
1388
|
// Validate even saved layouts in case something has changed since last render
|
|
1632
1389
|
// e.g. for pixel groups, this could be the size of the window
|
|
1633
1390
|
const nextLayout = validatePanelGroupLayout({
|
|
1634
|
-
groupSizePixels,
|
|
1635
1391
|
layout: unsafeLayout,
|
|
1636
1392
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1637
1393
|
});
|
|
@@ -1643,12 +1399,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1643
1399
|
eagerValuesRef.current.layout = nextLayout;
|
|
1644
1400
|
if (!areEqual(prevLayout, nextLayout)) {
|
|
1645
1401
|
if (onLayout) {
|
|
1646
|
-
onLayout(nextLayout
|
|
1647
|
-
sizePercentage,
|
|
1648
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1649
|
-
})));
|
|
1402
|
+
onLayout(nextLayout);
|
|
1650
1403
|
}
|
|
1651
|
-
callPanelCallbacks(
|
|
1404
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1652
1405
|
}
|
|
1653
1406
|
}, []);
|
|
1654
1407
|
const registerResizeHandle = useCallback(dragHandleId => {
|
|
@@ -1658,8 +1411,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1658
1411
|
direction,
|
|
1659
1412
|
dragState,
|
|
1660
1413
|
id: groupId,
|
|
1661
|
-
|
|
1662
|
-
keyboardResizeByPixels,
|
|
1414
|
+
keyboardResizeBy,
|
|
1663
1415
|
onLayout
|
|
1664
1416
|
} = committedValuesRef.current;
|
|
1665
1417
|
const {
|
|
@@ -1670,10 +1422,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1670
1422
|
initialLayout
|
|
1671
1423
|
} = dragState !== null && dragState !== void 0 ? dragState : {};
|
|
1672
1424
|
const pivotIndices = determinePivotIndices(groupId, dragHandleId);
|
|
1673
|
-
let delta = calculateDeltaPercentage(event,
|
|
1674
|
-
percentage: keyboardResizeByPercentage,
|
|
1675
|
-
pixels: keyboardResizeByPixels
|
|
1676
|
-
});
|
|
1425
|
+
let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
|
|
1677
1426
|
if (delta === 0) {
|
|
1678
1427
|
return;
|
|
1679
1428
|
}
|
|
@@ -1683,11 +1432,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1683
1432
|
if (document.dir === "rtl" && isHorizontal) {
|
|
1684
1433
|
delta = -delta;
|
|
1685
1434
|
}
|
|
1686
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1687
1435
|
const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
|
|
1688
1436
|
const nextLayout = adjustLayoutByDelta({
|
|
1689
1437
|
delta,
|
|
1690
|
-
groupSizePixels,
|
|
1691
1438
|
layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
|
|
1692
1439
|
panelConstraints,
|
|
1693
1440
|
pivotIndices,
|
|
@@ -1723,18 +1470,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1723
1470
|
setLayout(nextLayout);
|
|
1724
1471
|
eagerValuesRef.current.layout = nextLayout;
|
|
1725
1472
|
if (onLayout) {
|
|
1726
|
-
onLayout(nextLayout
|
|
1727
|
-
sizePercentage,
|
|
1728
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1729
|
-
})));
|
|
1473
|
+
onLayout(nextLayout);
|
|
1730
1474
|
}
|
|
1731
|
-
callPanelCallbacks(
|
|
1475
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1732
1476
|
}
|
|
1733
1477
|
};
|
|
1734
1478
|
}, []);
|
|
1735
1479
|
|
|
1736
1480
|
// External APIs are safe to memoize via committed values ref
|
|
1737
|
-
const resizePanel = useCallback((panelData,
|
|
1481
|
+
const resizePanel = useCallback((panelData, unsafePanelSize) => {
|
|
1738
1482
|
const {
|
|
1739
1483
|
onLayout
|
|
1740
1484
|
} = committedValuesRef.current;
|
|
@@ -1744,16 +1488,14 @@ function PanelGroupWithForwardedRef({
|
|
|
1744
1488
|
} = eagerValuesRef.current;
|
|
1745
1489
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1746
1490
|
const {
|
|
1747
|
-
|
|
1748
|
-
panelSizePercentage,
|
|
1491
|
+
panelSize,
|
|
1749
1492
|
pivotIndices
|
|
1750
|
-
} = panelDataHelper(
|
|
1751
|
-
|
|
1493
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1494
|
+
assert(panelSize != null);
|
|
1752
1495
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1753
|
-
const delta = isLastPanel ?
|
|
1496
|
+
const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
|
|
1754
1497
|
const nextLayout = adjustLayoutByDelta({
|
|
1755
1498
|
delta,
|
|
1756
|
-
groupSizePixels,
|
|
1757
1499
|
layout: prevLayout,
|
|
1758
1500
|
panelConstraints: panelConstraintsArray,
|
|
1759
1501
|
pivotIndices,
|
|
@@ -1763,14 +1505,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1763
1505
|
setLayout(nextLayout);
|
|
1764
1506
|
eagerValuesRef.current.layout = nextLayout;
|
|
1765
1507
|
if (onLayout) {
|
|
1766
|
-
onLayout(nextLayout
|
|
1767
|
-
sizePercentage,
|
|
1768
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1769
|
-
})));
|
|
1508
|
+
onLayout(nextLayout);
|
|
1770
1509
|
}
|
|
1771
|
-
callPanelCallbacks(
|
|
1510
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1772
1511
|
}
|
|
1773
|
-
}, [
|
|
1512
|
+
}, []);
|
|
1774
1513
|
const startDragging = useCallback((dragHandleId, event) => {
|
|
1775
1514
|
const {
|
|
1776
1515
|
direction
|
|
@@ -1779,6 +1518,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1779
1518
|
layout
|
|
1780
1519
|
} = eagerValuesRef.current;
|
|
1781
1520
|
const handleElement = getResizeHandleElement(dragHandleId);
|
|
1521
|
+
assert(handleElement);
|
|
1782
1522
|
const initialCursorPosition = getResizeEventCursorPosition(direction, event);
|
|
1783
1523
|
setDragState({
|
|
1784
1524
|
dragHandleId,
|
|
@@ -1797,7 +1537,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1797
1537
|
});
|
|
1798
1538
|
const unregisterPanel = useCallback(panelData => {
|
|
1799
1539
|
const {
|
|
1800
|
-
id: groupId,
|
|
1801
1540
|
onLayout
|
|
1802
1541
|
} = committedValuesRef.current;
|
|
1803
1542
|
const {
|
|
@@ -1820,7 +1559,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1820
1559
|
const {
|
|
1821
1560
|
pendingPanelIds
|
|
1822
1561
|
} = unregisterPanelRef.current;
|
|
1823
|
-
const map =
|
|
1562
|
+
const map = panelIdToLastNotifiedSizeMapRef.current;
|
|
1824
1563
|
|
|
1825
1564
|
// TRICKY
|
|
1826
1565
|
// Strict effects mode
|
|
@@ -1846,16 +1585,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1846
1585
|
// The group is unmounting; skip layout calculation.
|
|
1847
1586
|
return;
|
|
1848
1587
|
}
|
|
1849
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1850
1588
|
let unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1851
|
-
groupSizePixels,
|
|
1852
1589
|
panelDataArray
|
|
1853
1590
|
});
|
|
1854
1591
|
|
|
1855
1592
|
// Validate even saved layouts in case something has changed since last render
|
|
1856
1593
|
// e.g. for pixel groups, this could be the size of the window
|
|
1857
1594
|
const nextLayout = validatePanelGroupLayout({
|
|
1858
|
-
groupSizePixels,
|
|
1859
1595
|
layout: unsafeLayout,
|
|
1860
1596
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1861
1597
|
});
|
|
@@ -1863,12 +1599,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1863
1599
|
setLayout(nextLayout);
|
|
1864
1600
|
eagerValuesRef.current.layout = nextLayout;
|
|
1865
1601
|
if (onLayout) {
|
|
1866
|
-
onLayout(nextLayout
|
|
1867
|
-
sizePercentage,
|
|
1868
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1869
|
-
})));
|
|
1602
|
+
onLayout(nextLayout);
|
|
1870
1603
|
}
|
|
1871
|
-
callPanelCallbacks(
|
|
1604
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1872
1605
|
}
|
|
1873
1606
|
}, 0);
|
|
1874
1607
|
}, []);
|
|
@@ -1899,13 +1632,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1899
1632
|
return createElement(PanelGroupContext.Provider, {
|
|
1900
1633
|
value: context
|
|
1901
1634
|
}, createElement(Type, {
|
|
1635
|
+
...rest,
|
|
1902
1636
|
children,
|
|
1903
1637
|
className: classNameFromProps,
|
|
1904
1638
|
style: {
|
|
1905
1639
|
...style,
|
|
1906
1640
|
...styleFromProps
|
|
1907
1641
|
},
|
|
1908
|
-
...dataAttributes,
|
|
1909
1642
|
// CSS selectors
|
|
1910
1643
|
"data-panel-group": "",
|
|
1911
1644
|
"data-panel-group-direction": direction,
|
|
@@ -1918,22 +1651,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
|
|
|
1918
1651
|
}));
|
|
1919
1652
|
PanelGroupWithForwardedRef.displayName = "PanelGroup";
|
|
1920
1653
|
PanelGroup.displayName = "forwardRef(PanelGroup)";
|
|
1921
|
-
function panelDataHelper(
|
|
1654
|
+
function panelDataHelper(panelDataArray, panelData, layout) {
|
|
1922
1655
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1923
1656
|
const panelIndex = panelDataArray.indexOf(panelData);
|
|
1924
1657
|
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
1925
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1926
|
-
const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
|
|
1927
1658
|
const isLastPanel = panelIndex === panelDataArray.length - 1;
|
|
1928
1659
|
const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
|
|
1929
|
-
const
|
|
1930
|
-
const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
|
|
1660
|
+
const panelSize = layout[panelIndex];
|
|
1931
1661
|
return {
|
|
1932
|
-
...
|
|
1933
|
-
|
|
1934
|
-
panelSizePercentage,
|
|
1935
|
-
panelSizePixels,
|
|
1936
|
-
groupSizePixels,
|
|
1662
|
+
...panelConstraints,
|
|
1663
|
+
panelSize,
|
|
1937
1664
|
pivotIndices
|
|
1938
1665
|
};
|
|
1939
1666
|
}
|
|
@@ -1973,6 +1700,7 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1973
1700
|
{
|
|
1974
1701
|
event.preventDefault();
|
|
1975
1702
|
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
1703
|
+
assert(groupId);
|
|
1976
1704
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
1977
1705
|
const index = getResizeHandleElementIndex(groupId, handleId);
|
|
1978
1706
|
assert(index !== null);
|
|
@@ -1993,12 +1721,13 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1993
1721
|
function PanelResizeHandle({
|
|
1994
1722
|
children = null,
|
|
1995
1723
|
className: classNameFromProps = "",
|
|
1996
|
-
dataAttributes,
|
|
1997
1724
|
disabled = false,
|
|
1998
|
-
id: idFromProps
|
|
1725
|
+
id: idFromProps,
|
|
1999
1726
|
onDragging,
|
|
2000
1727
|
style: styleFromProps = {},
|
|
2001
|
-
|
|
1728
|
+
tabIndex = 0,
|
|
1729
|
+
tagName: Type = "div",
|
|
1730
|
+
...rest
|
|
2002
1731
|
}) {
|
|
2003
1732
|
const divElementRef = useRef(null);
|
|
2004
1733
|
|
|
@@ -2028,8 +1757,9 @@ function PanelResizeHandle({
|
|
|
2028
1757
|
const stopDraggingAndBlur = useCallback(() => {
|
|
2029
1758
|
// Clicking on the drag handle shouldn't leave it focused;
|
|
2030
1759
|
// That would cause the PanelGroup to think it was still active.
|
|
2031
|
-
const
|
|
2032
|
-
|
|
1760
|
+
const divElement = divElementRef.current;
|
|
1761
|
+
assert(divElement);
|
|
1762
|
+
divElement.blur();
|
|
2033
1763
|
stopDragging();
|
|
2034
1764
|
const {
|
|
2035
1765
|
onDragging
|
|
@@ -2057,6 +1787,7 @@ function PanelResizeHandle({
|
|
|
2057
1787
|
resizeHandler(event);
|
|
2058
1788
|
};
|
|
2059
1789
|
const divElement = divElementRef.current;
|
|
1790
|
+
assert(divElement);
|
|
2060
1791
|
const targetDocument = divElement.ownerDocument;
|
|
2061
1792
|
targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
|
|
2062
1793
|
targetDocument.body.addEventListener("mousemove", onMove);
|
|
@@ -2084,15 +1815,18 @@ function PanelResizeHandle({
|
|
|
2084
1815
|
userSelect: "none"
|
|
2085
1816
|
};
|
|
2086
1817
|
return createElement(Type, {
|
|
1818
|
+
...rest,
|
|
2087
1819
|
children,
|
|
2088
1820
|
className: classNameFromProps,
|
|
2089
1821
|
onBlur: () => setIsFocused(false),
|
|
2090
1822
|
onFocus: () => setIsFocused(true),
|
|
2091
1823
|
onMouseDown: event => {
|
|
2092
1824
|
startDragging(resizeHandleId, event.nativeEvent);
|
|
1825
|
+
const callbacks = callbacksRef.current;
|
|
1826
|
+
assert(callbacks);
|
|
2093
1827
|
const {
|
|
2094
1828
|
onDragging
|
|
2095
|
-
} =
|
|
1829
|
+
} = callbacks;
|
|
2096
1830
|
if (onDragging) {
|
|
2097
1831
|
onDragging(true);
|
|
2098
1832
|
}
|
|
@@ -2102,9 +1836,11 @@ function PanelResizeHandle({
|
|
|
2102
1836
|
onTouchEnd: stopDraggingAndBlur,
|
|
2103
1837
|
onTouchStart: event => {
|
|
2104
1838
|
startDragging(resizeHandleId, event.nativeEvent);
|
|
1839
|
+
const callbacks = callbacksRef.current;
|
|
1840
|
+
assert(callbacks);
|
|
2105
1841
|
const {
|
|
2106
1842
|
onDragging
|
|
2107
|
-
} =
|
|
1843
|
+
} = callbacks;
|
|
2108
1844
|
if (onDragging) {
|
|
2109
1845
|
onDragging(true);
|
|
2110
1846
|
}
|
|
@@ -2115,8 +1851,7 @@ function PanelResizeHandle({
|
|
|
2115
1851
|
...style,
|
|
2116
1852
|
...styleFromProps
|
|
2117
1853
|
},
|
|
2118
|
-
tabIndex
|
|
2119
|
-
...dataAttributes,
|
|
1854
|
+
tabIndex,
|
|
2120
1855
|
// CSS selectors
|
|
2121
1856
|
"data-panel-group-direction": direction,
|
|
2122
1857
|
"data-panel-group-id": groupId,
|
|
@@ -2131,3 +1866,4 @@ PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
|
2131
1866
|
exports.Panel = Panel;
|
|
2132
1867
|
exports.PanelGroup = PanelGroup;
|
|
2133
1868
|
exports.PanelResizeHandle = PanelResizeHandle;
|
|
1869
|
+
exports.assert = assert;
|