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