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
|
@@ -43,24 +43,20 @@ function useUniqueId(idFromParams = null) {
|
|
|
43
43
|
function PanelWithForwardedRef({
|
|
44
44
|
children,
|
|
45
45
|
className: classNameFromProps = "",
|
|
46
|
-
|
|
47
|
-
collapsedSizePixels,
|
|
46
|
+
collapsedSize,
|
|
48
47
|
collapsible,
|
|
49
|
-
|
|
50
|
-
defaultSizePercentage,
|
|
51
|
-
defaultSizePixels,
|
|
48
|
+
defaultSize,
|
|
52
49
|
forwardedRef,
|
|
53
50
|
id: idFromProps,
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
minSizePercentage,
|
|
57
|
-
minSizePixels,
|
|
51
|
+
maxSize,
|
|
52
|
+
minSize,
|
|
58
53
|
onCollapse,
|
|
59
54
|
onExpand,
|
|
60
55
|
onResize,
|
|
61
56
|
order,
|
|
62
57
|
style: styleFromProps,
|
|
63
|
-
tagName: Type = "div"
|
|
58
|
+
tagName: Type = "div",
|
|
59
|
+
...rest
|
|
64
60
|
}) {
|
|
65
61
|
const context = useContext(PanelGroupContext);
|
|
66
62
|
if (context === null) {
|
|
@@ -85,15 +81,11 @@ function PanelWithForwardedRef({
|
|
|
85
81
|
onResize
|
|
86
82
|
},
|
|
87
83
|
constraints: {
|
|
88
|
-
|
|
89
|
-
collapsedSizePixels,
|
|
84
|
+
collapsedSize,
|
|
90
85
|
collapsible,
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
maxSizePixels,
|
|
95
|
-
minSizePercentage,
|
|
96
|
-
minSizePixels
|
|
86
|
+
defaultSize,
|
|
87
|
+
maxSize,
|
|
88
|
+
minSize
|
|
97
89
|
},
|
|
98
90
|
id: panelId,
|
|
99
91
|
idIsFromProps: idFromProps !== undefined,
|
|
@@ -113,15 +105,11 @@ function PanelWithForwardedRef({
|
|
|
113
105
|
callbacks.onCollapse = onCollapse;
|
|
114
106
|
callbacks.onExpand = onExpand;
|
|
115
107
|
callbacks.onResize = onResize;
|
|
116
|
-
constraints.
|
|
117
|
-
constraints.collapsedSizePixels = collapsedSizePixels;
|
|
108
|
+
constraints.collapsedSize = collapsedSize;
|
|
118
109
|
constraints.collapsible = collapsible;
|
|
119
|
-
constraints.
|
|
120
|
-
constraints.
|
|
121
|
-
constraints.
|
|
122
|
-
constraints.maxSizePixels = maxSizePixels;
|
|
123
|
-
constraints.minSizePercentage = minSizePercentage;
|
|
124
|
-
constraints.minSizePixels = minSizePixels;
|
|
110
|
+
constraints.defaultSize = defaultSize;
|
|
111
|
+
constraints.maxSize = maxSize;
|
|
112
|
+
constraints.minSize = minSize;
|
|
125
113
|
});
|
|
126
114
|
useIsomorphicLayoutEffect(() => {
|
|
127
115
|
const panelData = panelDataRef.current;
|
|
@@ -149,19 +137,19 @@ function PanelWithForwardedRef({
|
|
|
149
137
|
isExpanded() {
|
|
150
138
|
return !isPanelCollapsed(panelDataRef.current);
|
|
151
139
|
},
|
|
152
|
-
resize:
|
|
153
|
-
resizePanel(panelDataRef.current,
|
|
140
|
+
resize: size => {
|
|
141
|
+
resizePanel(panelDataRef.current, size);
|
|
154
142
|
}
|
|
155
143
|
}), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
|
|
156
144
|
const style = getPanelStyle(panelDataRef.current);
|
|
157
145
|
return createElement(Type, {
|
|
146
|
+
...rest,
|
|
158
147
|
children,
|
|
159
148
|
className: classNameFromProps,
|
|
160
149
|
style: {
|
|
161
150
|
...style,
|
|
162
151
|
...styleFromProps
|
|
163
152
|
},
|
|
164
|
-
...dataAttributes,
|
|
165
153
|
// CSS selectors
|
|
166
154
|
"data-panel": "",
|
|
167
155
|
"data-panel-id": panelId,
|
|
@@ -178,81 +166,11 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
|
|
|
178
166
|
PanelWithForwardedRef.displayName = "Panel";
|
|
179
167
|
Panel.displayName = "forwardRef(Panel)";
|
|
180
168
|
|
|
181
|
-
function
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels) {
|
|
186
|
-
let {
|
|
187
|
-
collapsedSizePercentage = 0,
|
|
188
|
-
collapsedSizePixels,
|
|
189
|
-
defaultSizePercentage,
|
|
190
|
-
defaultSizePixels,
|
|
191
|
-
maxSizePercentage = 100,
|
|
192
|
-
maxSizePixels,
|
|
193
|
-
minSizePercentage = 0,
|
|
194
|
-
minSizePixels
|
|
195
|
-
} = panelConstraints;
|
|
196
|
-
const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
|
|
197
|
-
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
198
|
-
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
199
|
-
return {
|
|
200
|
-
collapsedSizePercentage: 0,
|
|
201
|
-
defaultSizePercentage,
|
|
202
|
-
maxSizePercentage: 0,
|
|
203
|
-
minSizePercentage: 0
|
|
204
|
-
};
|
|
205
|
-
}
|
|
206
|
-
if (collapsedSizePixels != null) {
|
|
207
|
-
collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
|
|
208
|
-
}
|
|
209
|
-
if (defaultSizePixels != null) {
|
|
210
|
-
defaultSizePercentage = convertPixelsToPercentage(defaultSizePixels, groupSizePixels);
|
|
211
|
-
}
|
|
212
|
-
if (minSizePixels != null) {
|
|
213
|
-
minSizePercentage = convertPixelsToPercentage(minSizePixels, groupSizePixels);
|
|
214
|
-
}
|
|
215
|
-
if (maxSizePixels != null) {
|
|
216
|
-
maxSizePercentage = convertPixelsToPercentage(maxSizePixels, groupSizePixels);
|
|
217
|
-
}
|
|
218
|
-
return {
|
|
219
|
-
collapsedSizePercentage,
|
|
220
|
-
defaultSizePercentage,
|
|
221
|
-
maxSizePercentage,
|
|
222
|
-
minSizePercentage
|
|
223
|
-
};
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels) {
|
|
227
|
-
// All panel constraints, excluding the current one
|
|
228
|
-
let totalMinConstraints = 0;
|
|
229
|
-
let totalMaxConstraints = 0;
|
|
230
|
-
for (let index = 0; index < panelConstraintsArray.length; index++) {
|
|
231
|
-
if (index !== panelIndex) {
|
|
232
|
-
const {
|
|
233
|
-
collapsible
|
|
234
|
-
} = panelConstraintsArray[index];
|
|
235
|
-
const {
|
|
236
|
-
collapsedSizePercentage,
|
|
237
|
-
maxSizePercentage,
|
|
238
|
-
minSizePercentage
|
|
239
|
-
} = convertPixelConstraintsToPercentages(panelConstraintsArray[index], groupSizePixels);
|
|
240
|
-
totalMaxConstraints += maxSizePercentage;
|
|
241
|
-
totalMinConstraints += collapsible ? collapsedSizePercentage : minSizePercentage;
|
|
242
|
-
}
|
|
169
|
+
function assert(expectedCondition, message = "Assertion failed!") {
|
|
170
|
+
if (!expectedCondition) {
|
|
171
|
+
console.error(message);
|
|
172
|
+
throw Error(message);
|
|
243
173
|
}
|
|
244
|
-
const {
|
|
245
|
-
collapsedSizePercentage,
|
|
246
|
-
defaultSizePercentage,
|
|
247
|
-
maxSizePercentage,
|
|
248
|
-
minSizePercentage
|
|
249
|
-
} = convertPixelConstraintsToPercentages(panelConstraintsArray[panelIndex], groupSizePixels);
|
|
250
|
-
return {
|
|
251
|
-
collapsedSizePercentage,
|
|
252
|
-
defaultSizePercentage,
|
|
253
|
-
maxSizePercentage: panelConstraintsArray.length > 1 ? Math.min(maxSizePercentage, 100 - totalMinConstraints) : maxSizePercentage,
|
|
254
|
-
minSizePercentage: panelConstraintsArray.length > 1 ? Math.max(minSizePercentage, 100 - totalMaxConstraints) : minSizePercentage
|
|
255
|
-
};
|
|
256
174
|
}
|
|
257
175
|
|
|
258
176
|
const PRECISION = 10;
|
|
@@ -274,56 +192,41 @@ function fuzzyNumbersEqual(actual, expected, fractionDigits) {
|
|
|
274
192
|
|
|
275
193
|
// Panel size must be in percentages; pixel values should be pre-converted
|
|
276
194
|
function resizePanel({
|
|
277
|
-
|
|
278
|
-
panelConstraints,
|
|
195
|
+
panelConstraints: panelConstraintsArray,
|
|
279
196
|
panelIndex,
|
|
280
197
|
size
|
|
281
198
|
}) {
|
|
282
|
-
const
|
|
283
|
-
|
|
284
|
-
defaultSizePixels,
|
|
285
|
-
minSizePixels,
|
|
286
|
-
maxSizePixels
|
|
287
|
-
}) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
|
|
288
|
-
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
289
|
-
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
290
|
-
return 0;
|
|
291
|
-
}
|
|
199
|
+
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
200
|
+
assert(panelConstraints != null);
|
|
292
201
|
let {
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (
|
|
303
|
-
|
|
304
|
-
const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
|
|
305
|
-
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
306
|
-
size = collapsedSizePercentage;
|
|
307
|
-
} else {
|
|
308
|
-
size = minSizePercentage;
|
|
309
|
-
}
|
|
202
|
+
collapsedSize = 0,
|
|
203
|
+
collapsible,
|
|
204
|
+
maxSize = 100,
|
|
205
|
+
minSize = 0
|
|
206
|
+
} = panelConstraints;
|
|
207
|
+
if (fuzzyCompareNumbers(size, minSize) < 0) {
|
|
208
|
+
if (collapsible) {
|
|
209
|
+
// Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
|
|
210
|
+
const halfwayPoint = (collapsedSize + minSize) / 2;
|
|
211
|
+
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
212
|
+
size = collapsedSize;
|
|
310
213
|
} else {
|
|
311
|
-
size =
|
|
214
|
+
size = minSize;
|
|
312
215
|
}
|
|
216
|
+
} else {
|
|
217
|
+
size = minSize;
|
|
313
218
|
}
|
|
314
219
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
}
|
|
220
|
+
size = Math.min(maxSize, size);
|
|
221
|
+
size = parseFloat(size.toFixed(PRECISION));
|
|
318
222
|
return size;
|
|
319
223
|
}
|
|
320
224
|
|
|
321
225
|
// All units must be in percentages; pixel values should be pre-converted
|
|
322
226
|
function adjustLayoutByDelta({
|
|
323
227
|
delta,
|
|
324
|
-
groupSizePixels,
|
|
325
228
|
layout: prevLayout,
|
|
326
|
-
panelConstraints,
|
|
229
|
+
panelConstraints: panelConstraintsArray,
|
|
327
230
|
pivotIndices,
|
|
328
231
|
trigger
|
|
329
232
|
}) {
|
|
@@ -331,6 +234,9 @@ function adjustLayoutByDelta({
|
|
|
331
234
|
return prevLayout;
|
|
332
235
|
}
|
|
333
236
|
const nextLayout = [...prevLayout];
|
|
237
|
+
const [firstPivotIndex, secondPivotIndex] = pivotIndices;
|
|
238
|
+
assert(firstPivotIndex != null);
|
|
239
|
+
assert(secondPivotIndex != null);
|
|
334
240
|
let deltaApplied = 0;
|
|
335
241
|
|
|
336
242
|
//const DEBUG = [];
|
|
@@ -354,18 +260,23 @@ function adjustLayoutByDelta({
|
|
|
354
260
|
if (trigger === "keyboard") {
|
|
355
261
|
{
|
|
356
262
|
// Check if we should expand a collapsed panel
|
|
357
|
-
const index = delta < 0 ?
|
|
358
|
-
const
|
|
263
|
+
const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
264
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
265
|
+
assert(panelConstraints);
|
|
266
|
+
|
|
359
267
|
//DEBUG.push(`edge case check 1: ${index}`);
|
|
360
268
|
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
361
|
-
if (
|
|
269
|
+
if (panelConstraints.collapsible) {
|
|
362
270
|
const prevSize = prevLayout[index];
|
|
271
|
+
assert(prevSize != null);
|
|
272
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
273
|
+
assert(panelConstraints);
|
|
363
274
|
const {
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
} =
|
|
367
|
-
if (fuzzyNumbersEqual(prevSize,
|
|
368
|
-
const localDelta =
|
|
275
|
+
collapsedSize = 0,
|
|
276
|
+
minSize = 0
|
|
277
|
+
} = panelConstraints;
|
|
278
|
+
if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
|
|
279
|
+
const localDelta = minSize - prevSize;
|
|
369
280
|
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
370
281
|
|
|
371
282
|
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
@@ -378,18 +289,26 @@ function adjustLayoutByDelta({
|
|
|
378
289
|
|
|
379
290
|
{
|
|
380
291
|
// Check if we should collapse a panel at its minimum size
|
|
381
|
-
const index = delta < 0 ?
|
|
382
|
-
const
|
|
292
|
+
const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
293
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
294
|
+
assert(panelConstraints);
|
|
295
|
+
const {
|
|
296
|
+
collapsible
|
|
297
|
+
} = panelConstraints;
|
|
298
|
+
|
|
383
299
|
//DEBUG.push(`edge case check 2: ${index}`);
|
|
384
|
-
//DEBUG.push(` -> collapsible? ${
|
|
385
|
-
if (
|
|
300
|
+
//DEBUG.push(` -> collapsible? ${collapsible}`);
|
|
301
|
+
if (collapsible) {
|
|
386
302
|
const prevSize = prevLayout[index];
|
|
303
|
+
assert(prevSize != null);
|
|
304
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
305
|
+
assert(panelConstraints);
|
|
387
306
|
const {
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
} =
|
|
391
|
-
if (fuzzyNumbersEqual(prevSize,
|
|
392
|
-
const localDelta = prevSize -
|
|
307
|
+
collapsedSize = 0,
|
|
308
|
+
minSize = 0
|
|
309
|
+
} = panelConstraints;
|
|
310
|
+
if (fuzzyNumbersEqual(prevSize, minSize)) {
|
|
311
|
+
const localDelta = prevSize - collapsedSize;
|
|
393
312
|
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
394
313
|
|
|
395
314
|
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
@@ -411,15 +330,15 @@ function adjustLayoutByDelta({
|
|
|
411
330
|
// as an expanding panel might change from collapsed to min size.
|
|
412
331
|
|
|
413
332
|
const increment = delta < 0 ? 1 : -1;
|
|
414
|
-
let index = delta < 0 ?
|
|
333
|
+
let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
415
334
|
let maxAvailableDelta = 0;
|
|
416
335
|
|
|
417
336
|
//DEBUG.push("pre calc...");
|
|
418
337
|
while (true) {
|
|
419
338
|
const prevSize = prevLayout[index];
|
|
339
|
+
assert(prevSize != null);
|
|
420
340
|
const maxSafeSize = resizePanel({
|
|
421
|
-
|
|
422
|
-
panelConstraints,
|
|
341
|
+
panelConstraints: panelConstraintsArray,
|
|
423
342
|
panelIndex: index,
|
|
424
343
|
size: 100
|
|
425
344
|
});
|
|
@@ -428,7 +347,7 @@ function adjustLayoutByDelta({
|
|
|
428
347
|
|
|
429
348
|
maxAvailableDelta += delta;
|
|
430
349
|
index += increment;
|
|
431
|
-
if (index < 0 || index >=
|
|
350
|
+
if (index < 0 || index >= panelConstraintsArray.length) {
|
|
432
351
|
break;
|
|
433
352
|
}
|
|
434
353
|
}
|
|
@@ -443,15 +362,15 @@ function adjustLayoutByDelta({
|
|
|
443
362
|
{
|
|
444
363
|
// Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
|
|
445
364
|
|
|
446
|
-
const pivotIndex = delta < 0 ?
|
|
365
|
+
const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
447
366
|
let index = pivotIndex;
|
|
448
|
-
while (index >= 0 && index <
|
|
367
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
449
368
|
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
450
369
|
const prevSize = prevLayout[index];
|
|
370
|
+
assert(prevSize != null);
|
|
451
371
|
const unsafeSize = prevSize - deltaRemaining;
|
|
452
372
|
const safeSize = resizePanel({
|
|
453
|
-
|
|
454
|
-
panelConstraints,
|
|
373
|
+
panelConstraints: panelConstraintsArray,
|
|
455
374
|
panelIndex: index,
|
|
456
375
|
size: unsafeSize
|
|
457
376
|
});
|
|
@@ -483,11 +402,12 @@ function adjustLayoutByDelta({
|
|
|
483
402
|
}
|
|
484
403
|
{
|
|
485
404
|
// Now distribute the applied delta to the panels in the other direction
|
|
486
|
-
const pivotIndex = delta < 0 ?
|
|
487
|
-
const
|
|
405
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
406
|
+
const prevSize = prevLayout[pivotIndex];
|
|
407
|
+
assert(prevSize != null);
|
|
408
|
+
const unsafeSize = prevSize + deltaApplied;
|
|
488
409
|
const safeSize = resizePanel({
|
|
489
|
-
|
|
490
|
-
panelConstraints,
|
|
410
|
+
panelConstraints: panelConstraintsArray,
|
|
491
411
|
panelIndex: pivotIndex,
|
|
492
412
|
size: unsafeSize
|
|
493
413
|
});
|
|
@@ -498,14 +418,14 @@ function adjustLayoutByDelta({
|
|
|
498
418
|
// Edge case where expanding or contracting one panel caused another one to change collapsed state
|
|
499
419
|
if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
|
|
500
420
|
let deltaRemaining = unsafeSize - safeSize;
|
|
501
|
-
const pivotIndex = delta < 0 ?
|
|
421
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
502
422
|
let index = pivotIndex;
|
|
503
|
-
while (index >= 0 && index <
|
|
423
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
504
424
|
const prevSize = nextLayout[index];
|
|
425
|
+
assert(prevSize != null);
|
|
505
426
|
const unsafeSize = prevSize + deltaRemaining;
|
|
506
427
|
const safeSize = resizePanel({
|
|
507
|
-
|
|
508
|
-
panelConstraints,
|
|
428
|
+
panelConstraints: panelConstraintsArray,
|
|
509
429
|
panelIndex: index,
|
|
510
430
|
size: unsafeSize
|
|
511
431
|
});
|
|
@@ -529,9 +449,7 @@ function adjustLayoutByDelta({
|
|
|
529
449
|
//DEBUG.push("");
|
|
530
450
|
|
|
531
451
|
const totalSize = nextLayout.reduce((total, size) => size + total, 0);
|
|
532
|
-
deltaApplied = 100 - totalSize;
|
|
533
452
|
//DEBUG.push(`total size: ${totalSize}`);
|
|
534
|
-
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
535
453
|
//console.log(DEBUG.join("\n"));
|
|
536
454
|
|
|
537
455
|
if (!fuzzyNumbersEqual(totalSize, 100)) {
|
|
@@ -540,27 +458,7 @@ function adjustLayoutByDelta({
|
|
|
540
458
|
return nextLayout;
|
|
541
459
|
}
|
|
542
460
|
|
|
543
|
-
function assert(expectedCondition, message = "Assertion failed!") {
|
|
544
|
-
if (!expectedCondition) {
|
|
545
|
-
console.error(message);
|
|
546
|
-
throw Error(message);
|
|
547
|
-
}
|
|
548
|
-
}
|
|
549
|
-
|
|
550
|
-
function getPercentageSizeFromMixedSizes({
|
|
551
|
-
sizePercentage,
|
|
552
|
-
sizePixels
|
|
553
|
-
}, groupSizePixels) {
|
|
554
|
-
if (sizePercentage != null) {
|
|
555
|
-
return sizePercentage;
|
|
556
|
-
} else if (sizePixels != null) {
|
|
557
|
-
return convertPixelsToPercentage(sizePixels, groupSizePixels);
|
|
558
|
-
}
|
|
559
|
-
return undefined;
|
|
560
|
-
}
|
|
561
|
-
|
|
562
461
|
function calculateAriaValues({
|
|
563
|
-
groupSizePixels,
|
|
564
462
|
layout,
|
|
565
463
|
panelsArray,
|
|
566
464
|
pivotIndices
|
|
@@ -569,28 +467,19 @@ function calculateAriaValues({
|
|
|
569
467
|
let currentMaxSize = 100;
|
|
570
468
|
let totalMinSize = 0;
|
|
571
469
|
let totalMaxSize = 0;
|
|
470
|
+
const firstIndex = pivotIndices[0];
|
|
471
|
+
assert(firstIndex != null);
|
|
572
472
|
|
|
573
473
|
// A panel's effective min/max sizes also need to account for other panel's sizes.
|
|
574
474
|
panelsArray.forEach((panelData, index) => {
|
|
575
|
-
var _getPercentageSizeFro, _getPercentageSizeFro2;
|
|
576
475
|
const {
|
|
577
476
|
constraints
|
|
578
477
|
} = panelData;
|
|
579
478
|
const {
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
minSizePercentage,
|
|
583
|
-
minSizePixels
|
|
479
|
+
maxSize = 100,
|
|
480
|
+
minSize = 0
|
|
584
481
|
} = constraints;
|
|
585
|
-
|
|
586
|
-
sizePercentage: minSizePercentage,
|
|
587
|
-
sizePixels: minSizePixels
|
|
588
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
589
|
-
const maxSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
|
|
590
|
-
sizePercentage: maxSizePercentage,
|
|
591
|
-
sizePixels: maxSizePixels
|
|
592
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 100;
|
|
593
|
-
if (index === pivotIndices[0]) {
|
|
482
|
+
if (index === firstIndex) {
|
|
594
483
|
currentMinSize = minSize;
|
|
595
484
|
currentMaxSize = maxSize;
|
|
596
485
|
} else {
|
|
@@ -600,7 +489,7 @@ function calculateAriaValues({
|
|
|
600
489
|
});
|
|
601
490
|
const valueMax = Math.min(currentMaxSize, 100 - totalMinSize);
|
|
602
491
|
const valueMin = Math.max(currentMinSize, 100 - totalMaxSize);
|
|
603
|
-
const valueNow = layout[
|
|
492
|
+
const valueNow = layout[firstIndex];
|
|
604
493
|
return {
|
|
605
494
|
valueMax,
|
|
606
495
|
valueMin,
|
|
@@ -631,42 +520,6 @@ function getPanelGroupElement(id) {
|
|
|
631
520
|
return null;
|
|
632
521
|
}
|
|
633
522
|
|
|
634
|
-
function calculateAvailablePanelSizeInPixels(groupId) {
|
|
635
|
-
const panelGroupElement = getPanelGroupElement(groupId);
|
|
636
|
-
if (panelGroupElement == null) {
|
|
637
|
-
return NaN;
|
|
638
|
-
}
|
|
639
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
640
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId);
|
|
641
|
-
if (direction === "horizontal") {
|
|
642
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
643
|
-
return accumulated + handle.offsetWidth;
|
|
644
|
-
}, 0);
|
|
645
|
-
} else {
|
|
646
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
647
|
-
return accumulated + handle.offsetHeight;
|
|
648
|
-
}, 0);
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
|
|
652
|
-
function getAvailableGroupSizePixels(groupId) {
|
|
653
|
-
const panelGroupElement = getPanelGroupElement(groupId);
|
|
654
|
-
if (panelGroupElement == null) {
|
|
655
|
-
return NaN;
|
|
656
|
-
}
|
|
657
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
658
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId);
|
|
659
|
-
if (direction === "horizontal") {
|
|
660
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
661
|
-
return accumulated + handle.offsetWidth;
|
|
662
|
-
}, 0);
|
|
663
|
-
} else {
|
|
664
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
665
|
-
return accumulated + handle.offsetHeight;
|
|
666
|
-
}, 0);
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
|
|
670
523
|
function getResizeHandleElement(id) {
|
|
671
524
|
const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
|
|
672
525
|
if (element) {
|
|
@@ -699,7 +552,6 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
699
552
|
didWarnAboutMissingResizeHandle: false
|
|
700
553
|
});
|
|
701
554
|
useIsomorphicLayoutEffect(() => {
|
|
702
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
703
555
|
const resizeHandleElements = getResizeHandleElementsForGroup(groupId);
|
|
704
556
|
for (let index = 0; index < panelDataArray.length - 1; index++) {
|
|
705
557
|
const {
|
|
@@ -707,17 +559,18 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
707
559
|
valueMin,
|
|
708
560
|
valueNow
|
|
709
561
|
} = calculateAriaValues({
|
|
710
|
-
groupSizePixels,
|
|
711
562
|
layout,
|
|
712
563
|
panelsArray: panelDataArray,
|
|
713
564
|
pivotIndices: [index, index + 1]
|
|
714
565
|
});
|
|
715
566
|
const resizeHandleElement = resizeHandleElements[index];
|
|
716
567
|
if (resizeHandleElement == null) ; else {
|
|
717
|
-
|
|
568
|
+
const panelData = panelDataArray[index];
|
|
569
|
+
assert(panelData);
|
|
570
|
+
resizeHandleElement.setAttribute("aria-controls", panelData.id);
|
|
718
571
|
resizeHandleElement.setAttribute("aria-valuemax", "" + Math.round(valueMax));
|
|
719
572
|
resizeHandleElement.setAttribute("aria-valuemin", "" + Math.round(valueMin));
|
|
720
|
-
resizeHandleElement.setAttribute("aria-valuenow", "" + Math.round(valueNow));
|
|
573
|
+
resizeHandleElement.setAttribute("aria-valuenow", valueNow != null ? "" + Math.round(valueNow) : "");
|
|
721
574
|
}
|
|
722
575
|
}
|
|
723
576
|
return () => {
|
|
@@ -730,14 +583,18 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
730
583
|
};
|
|
731
584
|
}, [groupId, layout, panelDataArray]);
|
|
732
585
|
useEffect(() => {
|
|
586
|
+
const eagerValues = eagerValuesRef.current;
|
|
587
|
+
assert(eagerValues);
|
|
733
588
|
const {
|
|
734
589
|
panelDataArray
|
|
735
|
-
} =
|
|
590
|
+
} = eagerValues;
|
|
736
591
|
const groupElement = getPanelGroupElement(groupId);
|
|
737
592
|
assert(groupElement != null, `No group found for id "${groupId}"`);
|
|
738
593
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
594
|
+
assert(handles);
|
|
739
595
|
const cleanupFunctions = handles.map(handle => {
|
|
740
596
|
const handleId = handle.getAttribute("data-panel-resize-handle-id");
|
|
597
|
+
assert(handleId);
|
|
741
598
|
const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
|
|
742
599
|
if (idBefore == null || idAfter == null) {
|
|
743
600
|
return () => {};
|
|
@@ -753,21 +610,16 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
753
610
|
const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
|
|
754
611
|
if (index >= 0) {
|
|
755
612
|
const panelData = panelDataArray[index];
|
|
613
|
+
assert(panelData);
|
|
756
614
|
const size = layout[index];
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
764
|
-
const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
|
|
765
|
-
sizePercentage: panelData.constraints.minSizePercentage,
|
|
766
|
-
sizePixels: panelData.constraints.minSizePixels
|
|
767
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
|
|
615
|
+
const {
|
|
616
|
+
collapsedSize = 0,
|
|
617
|
+
collapsible,
|
|
618
|
+
minSize = 0
|
|
619
|
+
} = panelData.constraints;
|
|
620
|
+
if (size != null && collapsible) {
|
|
768
621
|
const nextLayout = adjustLayoutByDelta({
|
|
769
622
|
delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
|
|
770
|
-
groupSizePixels,
|
|
771
623
|
layout,
|
|
772
624
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints),
|
|
773
625
|
pivotIndices: determinePivotIndices(groupId, handleId),
|
|
@@ -821,6 +673,7 @@ function getResizeEventCursorPosition(direction, event) {
|
|
|
821
673
|
return isHorizontal ? event.clientX : event.clientY;
|
|
822
674
|
} else if (isTouchEvent(event)) {
|
|
823
675
|
const firstTouch = event.touches[0];
|
|
676
|
+
assert(firstTouch);
|
|
824
677
|
return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
|
|
825
678
|
} else {
|
|
826
679
|
throw Error(`Unsupported event type "${event.type}"`);
|
|
@@ -830,12 +683,15 @@ function getResizeEventCursorPosition(direction, event) {
|
|
|
830
683
|
function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
|
|
831
684
|
const isHorizontal = direction === "horizontal";
|
|
832
685
|
const handleElement = getResizeHandleElement(dragHandleId);
|
|
686
|
+
assert(handleElement);
|
|
833
687
|
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
688
|
+
assert(groupId);
|
|
834
689
|
let {
|
|
835
690
|
initialCursorPosition
|
|
836
691
|
} = initialDragState;
|
|
837
692
|
const cursorPosition = getResizeEventCursorPosition(direction, event);
|
|
838
693
|
const groupElement = getPanelGroupElement(groupId);
|
|
694
|
+
assert(groupElement);
|
|
839
695
|
const groupRect = groupElement.getBoundingClientRect();
|
|
840
696
|
const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
|
|
841
697
|
const offsetPixels = cursorPosition - initialCursorPosition;
|
|
@@ -844,19 +700,14 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
|
|
|
844
700
|
}
|
|
845
701
|
|
|
846
702
|
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
|
|
847
|
-
function calculateDeltaPercentage(event,
|
|
703
|
+
function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
|
|
848
704
|
if (isKeyDown(event)) {
|
|
849
705
|
const isHorizontal = direction === "horizontal";
|
|
850
|
-
const groupElement = getPanelGroupElement(groupId);
|
|
851
|
-
const rect = groupElement.getBoundingClientRect();
|
|
852
|
-
const groupSizeInPixels = isHorizontal ? rect.width : rect.height;
|
|
853
706
|
let delta = 0;
|
|
854
707
|
if (event.shiftKey) {
|
|
855
708
|
delta = 100;
|
|
856
|
-
} else if (
|
|
857
|
-
delta =
|
|
858
|
-
} else if (keyboardResizeByOptions.pixels != null) {
|
|
859
|
-
delta = keyboardResizeByOptions.pixels / groupSizeInPixels;
|
|
709
|
+
} else if (keyboardResizeBy != null) {
|
|
710
|
+
delta = keyboardResizeBy;
|
|
860
711
|
} else {
|
|
861
712
|
delta = 10;
|
|
862
713
|
}
|
|
@@ -883,37 +734,43 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
|
|
|
883
734
|
}
|
|
884
735
|
return movement;
|
|
885
736
|
} else {
|
|
737
|
+
if (initialDragState == null) {
|
|
738
|
+
return 0;
|
|
739
|
+
}
|
|
886
740
|
return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
|
|
887
741
|
}
|
|
888
742
|
}
|
|
889
743
|
|
|
890
744
|
function calculateUnsafeDefaultLayout({
|
|
891
|
-
groupSizePixels,
|
|
892
745
|
panelDataArray
|
|
893
746
|
}) {
|
|
894
747
|
const layout = Array(panelDataArray.length);
|
|
895
|
-
const
|
|
748
|
+
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
896
749
|
let numPanelsWithSizes = 0;
|
|
897
750
|
let remainingSize = 100;
|
|
898
751
|
|
|
899
752
|
// Distribute default sizes first
|
|
900
753
|
for (let index = 0; index < panelDataArray.length; index++) {
|
|
754
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
755
|
+
assert(panelConstraints);
|
|
901
756
|
const {
|
|
902
|
-
|
|
903
|
-
} =
|
|
904
|
-
if (
|
|
757
|
+
defaultSize
|
|
758
|
+
} = panelConstraints;
|
|
759
|
+
if (defaultSize != null) {
|
|
905
760
|
numPanelsWithSizes++;
|
|
906
|
-
layout[index] =
|
|
907
|
-
remainingSize -=
|
|
761
|
+
layout[index] = defaultSize;
|
|
762
|
+
remainingSize -= defaultSize;
|
|
908
763
|
}
|
|
909
764
|
}
|
|
910
765
|
|
|
911
766
|
// Remaining size should be distributed evenly between panels without default sizes
|
|
912
767
|
for (let index = 0; index < panelDataArray.length; index++) {
|
|
768
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
769
|
+
assert(panelConstraints);
|
|
913
770
|
const {
|
|
914
|
-
|
|
915
|
-
} =
|
|
916
|
-
if (
|
|
771
|
+
defaultSize
|
|
772
|
+
} = panelConstraints;
|
|
773
|
+
if (defaultSize != null) {
|
|
917
774
|
continue;
|
|
918
775
|
}
|
|
919
776
|
const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
|
|
@@ -925,54 +782,36 @@ function calculateUnsafeDefaultLayout({
|
|
|
925
782
|
return layout;
|
|
926
783
|
}
|
|
927
784
|
|
|
928
|
-
function convertPercentageToPixels(percentage, groupSizePixels) {
|
|
929
|
-
return percentage / 100 * groupSizePixels;
|
|
930
|
-
}
|
|
931
|
-
|
|
932
785
|
// Layout should be pre-converted into percentages
|
|
933
|
-
function callPanelCallbacks(
|
|
934
|
-
|
|
935
|
-
layout.forEach((sizePercentage, index) => {
|
|
786
|
+
function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
|
|
787
|
+
layout.forEach((size, index) => {
|
|
936
788
|
const panelData = panelsArray[index];
|
|
937
|
-
|
|
938
|
-
// Handle initial mount (when panels are registered too late to be in the panels array)
|
|
939
|
-
// The subsequent render+effects will handle the resize notification
|
|
940
|
-
return;
|
|
941
|
-
}
|
|
789
|
+
assert(panelData);
|
|
942
790
|
const {
|
|
943
791
|
callbacks,
|
|
944
792
|
constraints,
|
|
945
793
|
id: panelId
|
|
946
794
|
} = panelData;
|
|
947
795
|
const {
|
|
796
|
+
collapsedSize = 0,
|
|
948
797
|
collapsible
|
|
949
798
|
} = constraints;
|
|
950
|
-
const
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
};
|
|
954
|
-
const lastNotifiedMixedSizes = panelIdToLastNotifiedMixedSizesMap[panelId];
|
|
955
|
-
if (lastNotifiedMixedSizes == null || mixedSizes.sizePercentage !== lastNotifiedMixedSizes.sizePercentage || mixedSizes.sizePixels !== lastNotifiedMixedSizes.sizePixels) {
|
|
956
|
-
panelIdToLastNotifiedMixedSizesMap[panelId] = mixedSizes;
|
|
799
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
|
|
800
|
+
if (lastNotifiedSize == null || size !== lastNotifiedSize) {
|
|
801
|
+
panelIdToLastNotifiedSizeMap[panelId] = size;
|
|
957
802
|
const {
|
|
958
803
|
onCollapse,
|
|
959
804
|
onExpand,
|
|
960
805
|
onResize
|
|
961
806
|
} = callbacks;
|
|
962
807
|
if (onResize) {
|
|
963
|
-
onResize(
|
|
808
|
+
onResize(size, lastNotifiedSize);
|
|
964
809
|
}
|
|
965
810
|
if (collapsible && (onCollapse || onExpand)) {
|
|
966
|
-
|
|
967
|
-
const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
|
|
968
|
-
sizePercentage: constraints.collapsedSizePercentage,
|
|
969
|
-
sizePixels: constraints.collapsedSizePixels
|
|
970
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
971
|
-
const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
|
|
972
|
-
if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
|
|
811
|
+
if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
|
|
973
812
|
onExpand();
|
|
974
813
|
}
|
|
975
|
-
if (onCollapse && (
|
|
814
|
+
if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
|
|
976
815
|
onCollapse();
|
|
977
816
|
}
|
|
978
817
|
}
|
|
@@ -1006,9 +845,10 @@ function computePanelFlexBoxStyle({
|
|
|
1006
845
|
const size = layout[panelIndex];
|
|
1007
846
|
let flexGrow;
|
|
1008
847
|
if (panelData.length === 1) {
|
|
1009
|
-
flexGrow = "
|
|
848
|
+
flexGrow = "1";
|
|
1010
849
|
} else if (size == null) {
|
|
1011
|
-
|
|
850
|
+
// Initial render (before panels have registered themselves)
|
|
851
|
+
flexGrow = "1";
|
|
1012
852
|
} else {
|
|
1013
853
|
flexGrow = size.toPrecision(precision);
|
|
1014
854
|
}
|
|
@@ -1154,31 +994,32 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
|
|
|
1154
994
|
}
|
|
1155
995
|
}
|
|
1156
996
|
|
|
1157
|
-
function shouldMonitorPixelBasedConstraints(constraints) {
|
|
1158
|
-
return constraints.some(constraints => {
|
|
1159
|
-
return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
|
|
1160
|
-
});
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
997
|
// All units must be in percentages; pixel values should be pre-converted
|
|
1164
998
|
function validatePanelGroupLayout({
|
|
1165
|
-
groupSizePixels,
|
|
1166
999
|
layout: prevLayout,
|
|
1167
1000
|
panelConstraints
|
|
1168
1001
|
}) {
|
|
1169
1002
|
const nextLayout = [...prevLayout];
|
|
1003
|
+
const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
|
|
1170
1004
|
|
|
1171
1005
|
// Validate layout expectations
|
|
1172
1006
|
if (nextLayout.length !== panelConstraints.length) {
|
|
1173
1007
|
throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
|
|
1174
|
-
} else if (!fuzzyNumbersEqual(
|
|
1008
|
+
} else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
|
|
1009
|
+
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1010
|
+
const unsafeSize = nextLayout[index];
|
|
1011
|
+
assert(unsafeSize != null);
|
|
1012
|
+
const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
|
|
1013
|
+
nextLayout[index] = safeSize;
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1175
1016
|
let remainingSize = 0;
|
|
1176
1017
|
|
|
1177
1018
|
// First pass: Validate the proposed layout given each panel's constraints
|
|
1178
1019
|
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1179
1020
|
const unsafeSize = nextLayout[index];
|
|
1021
|
+
assert(unsafeSize != null);
|
|
1180
1022
|
const safeSize = resizePanel({
|
|
1181
|
-
groupSizePixels,
|
|
1182
1023
|
panelConstraints,
|
|
1183
1024
|
panelIndex: index,
|
|
1184
1025
|
size: unsafeSize
|
|
@@ -1194,9 +1035,9 @@ function validatePanelGroupLayout({
|
|
|
1194
1035
|
if (!fuzzyNumbersEqual(remainingSize, 0)) {
|
|
1195
1036
|
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1196
1037
|
const prevSize = nextLayout[index];
|
|
1038
|
+
assert(prevSize != null);
|
|
1197
1039
|
const unsafeSize = prevSize + remainingSize;
|
|
1198
1040
|
const safeSize = resizePanel({
|
|
1199
|
-
groupSizePixels,
|
|
1200
1041
|
panelConstraints,
|
|
1201
1042
|
panelIndex: index,
|
|
1202
1043
|
size: unsafeSize
|
|
@@ -1231,21 +1072,20 @@ function PanelGroupWithForwardedRef({
|
|
|
1231
1072
|
autoSaveId = null,
|
|
1232
1073
|
children,
|
|
1233
1074
|
className: classNameFromProps = "",
|
|
1234
|
-
dataAttributes,
|
|
1235
1075
|
direction,
|
|
1236
1076
|
forwardedRef,
|
|
1237
|
-
id: idFromProps,
|
|
1077
|
+
id: idFromProps = null,
|
|
1238
1078
|
onLayout = null,
|
|
1239
|
-
|
|
1240
|
-
keyboardResizeByPixels = null,
|
|
1079
|
+
keyboardResizeBy = null,
|
|
1241
1080
|
storage = defaultStorage,
|
|
1242
1081
|
style: styleFromProps,
|
|
1243
|
-
tagName: Type = "div"
|
|
1082
|
+
tagName: Type = "div",
|
|
1083
|
+
...rest
|
|
1244
1084
|
}) {
|
|
1245
1085
|
const groupId = useUniqueId(idFromProps);
|
|
1246
1086
|
const [dragState, setDragState] = useState(null);
|
|
1247
1087
|
const [layout, setLayout] = useState([]);
|
|
1248
|
-
const
|
|
1088
|
+
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1249
1089
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1250
1090
|
const prevDeltaRef = useRef(0);
|
|
1251
1091
|
const committedValuesRef = useRef({
|
|
@@ -1253,8 +1093,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1253
1093
|
direction,
|
|
1254
1094
|
dragState,
|
|
1255
1095
|
id: groupId,
|
|
1256
|
-
|
|
1257
|
-
keyboardResizeByPixels,
|
|
1096
|
+
keyboardResizeBy,
|
|
1258
1097
|
onLayout,
|
|
1259
1098
|
storage
|
|
1260
1099
|
});
|
|
@@ -1270,33 +1109,20 @@ function PanelGroupWithForwardedRef({
|
|
|
1270
1109
|
useImperativeHandle(forwardedRef, () => ({
|
|
1271
1110
|
getId: () => committedValuesRef.current.id,
|
|
1272
1111
|
getLayout: () => {
|
|
1273
|
-
const {
|
|
1274
|
-
id: groupId
|
|
1275
|
-
} = committedValuesRef.current;
|
|
1276
1112
|
const {
|
|
1277
1113
|
layout
|
|
1278
1114
|
} = eagerValuesRef.current;
|
|
1279
|
-
|
|
1280
|
-
return layout.map(sizePercentage => {
|
|
1281
|
-
return {
|
|
1282
|
-
sizePercentage,
|
|
1283
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1284
|
-
};
|
|
1285
|
-
});
|
|
1115
|
+
return layout;
|
|
1286
1116
|
},
|
|
1287
|
-
setLayout:
|
|
1117
|
+
setLayout: unsafeLayout => {
|
|
1288
1118
|
const {
|
|
1289
|
-
id: groupId,
|
|
1290
1119
|
onLayout
|
|
1291
1120
|
} = committedValuesRef.current;
|
|
1292
1121
|
const {
|
|
1293
1122
|
layout: prevLayout,
|
|
1294
1123
|
panelDataArray
|
|
1295
1124
|
} = eagerValuesRef.current;
|
|
1296
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1297
|
-
const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
|
|
1298
1125
|
const safeLayout = validatePanelGroupLayout({
|
|
1299
|
-
groupSizePixels,
|
|
1300
1126
|
layout: unsafeLayout,
|
|
1301
1127
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1302
1128
|
});
|
|
@@ -1304,12 +1130,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1304
1130
|
setLayout(safeLayout);
|
|
1305
1131
|
eagerValuesRef.current.layout = safeLayout;
|
|
1306
1132
|
if (onLayout) {
|
|
1307
|
-
onLayout(safeLayout
|
|
1308
|
-
sizePercentage,
|
|
1309
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1310
|
-
})));
|
|
1133
|
+
onLayout(safeLayout);
|
|
1311
1134
|
}
|
|
1312
|
-
callPanelCallbacks(
|
|
1135
|
+
callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1313
1136
|
}
|
|
1314
1137
|
}
|
|
1315
1138
|
}), []);
|
|
@@ -1320,11 +1143,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1320
1143
|
committedValuesRef.current.id = groupId;
|
|
1321
1144
|
committedValuesRef.current.onLayout = onLayout;
|
|
1322
1145
|
committedValuesRef.current.storage = storage;
|
|
1323
|
-
|
|
1324
|
-
// panelDataArray and layout are updated in-sync with scheduled state updates.
|
|
1325
|
-
// TODO [217] Move these values into a separate ref
|
|
1326
1146
|
});
|
|
1327
|
-
|
|
1328
1147
|
useWindowSplitterPanelGroupBehavior({
|
|
1329
1148
|
committedValuesRef,
|
|
1330
1149
|
eagerValuesRef,
|
|
@@ -1343,57 +1162,16 @@ function PanelGroupWithForwardedRef({
|
|
|
1343
1162
|
if (layout.length === 0 || layout.length !== panelDataArray.length) {
|
|
1344
1163
|
return;
|
|
1345
1164
|
}
|
|
1165
|
+
let debouncedSave = debounceMap[autoSaveId];
|
|
1346
1166
|
|
|
1347
1167
|
// Limit the frequency of localStorage updates.
|
|
1348
|
-
if (
|
|
1349
|
-
|
|
1168
|
+
if (debouncedSave == null) {
|
|
1169
|
+
debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1170
|
+
debounceMap[autoSaveId] = debouncedSave;
|
|
1350
1171
|
}
|
|
1351
|
-
|
|
1172
|
+
debouncedSave(autoSaveId, panelDataArray, layout, storage);
|
|
1352
1173
|
}
|
|
1353
1174
|
}, [autoSaveId, layout, storage]);
|
|
1354
|
-
useIsomorphicLayoutEffect(() => {
|
|
1355
|
-
const {
|
|
1356
|
-
layout: prevLayout,
|
|
1357
|
-
panelDataArray
|
|
1358
|
-
} = eagerValuesRef.current;
|
|
1359
|
-
const constraints = panelDataArray.map(({
|
|
1360
|
-
constraints
|
|
1361
|
-
}) => constraints);
|
|
1362
|
-
if (!shouldMonitorPixelBasedConstraints(constraints)) {
|
|
1363
|
-
// Avoid the overhead of ResizeObserver if no pixel constraints require monitoring
|
|
1364
|
-
return;
|
|
1365
|
-
}
|
|
1366
|
-
if (typeof ResizeObserver === "undefined") {
|
|
1367
|
-
console.warn(`WARNING: Pixel based constraints require ResizeObserver but it is not supported by the current browser.`);
|
|
1368
|
-
} else {
|
|
1369
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
1370
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1371
|
-
const {
|
|
1372
|
-
onLayout
|
|
1373
|
-
} = committedValuesRef.current;
|
|
1374
|
-
const nextLayout = validatePanelGroupLayout({
|
|
1375
|
-
groupSizePixels,
|
|
1376
|
-
layout: prevLayout,
|
|
1377
|
-
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1378
|
-
});
|
|
1379
|
-
if (!areEqual(prevLayout, nextLayout)) {
|
|
1380
|
-
setLayout(nextLayout);
|
|
1381
|
-
eagerValuesRef.current.layout = nextLayout;
|
|
1382
|
-
if (onLayout) {
|
|
1383
|
-
onLayout(nextLayout.map(sizePercentage => ({
|
|
1384
|
-
sizePercentage,
|
|
1385
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1386
|
-
})));
|
|
1387
|
-
}
|
|
1388
|
-
callPanelCallbacks(groupId, panelDataArray, nextLayout, panelIdToLastNotifiedMixedSizesMapRef.current);
|
|
1389
|
-
}
|
|
1390
|
-
});
|
|
1391
|
-
resizeObserver.observe(getPanelGroupElement(groupId));
|
|
1392
|
-
return () => {
|
|
1393
|
-
resizeObserver.disconnect();
|
|
1394
|
-
};
|
|
1395
|
-
}
|
|
1396
|
-
}, [groupId]);
|
|
1397
1175
|
|
|
1398
1176
|
// DEV warnings
|
|
1399
1177
|
useEffect(() => {
|
|
@@ -1411,20 +1189,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1411
1189
|
if (panelData.constraints.collapsible) {
|
|
1412
1190
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1413
1191
|
const {
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
pivotIndices
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
if (
|
|
1192
|
+
collapsedSize = 0,
|
|
1193
|
+
panelSize,
|
|
1194
|
+
pivotIndices
|
|
1195
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1196
|
+
assert(panelSize != null);
|
|
1197
|
+
if (panelSize !== collapsedSize) {
|
|
1420
1198
|
// Store size before collapse;
|
|
1421
1199
|
// This is the size that gets restored if the expand() API is used.
|
|
1422
|
-
panelSizeBeforeCollapseRef.current.set(panelData.id,
|
|
1200
|
+
panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
|
|
1423
1201
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1424
|
-
const delta = isLastPanel ?
|
|
1202
|
+
const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
|
|
1425
1203
|
const nextLayout = adjustLayoutByDelta({
|
|
1426
1204
|
delta,
|
|
1427
|
-
groupSizePixels,
|
|
1428
1205
|
layout: prevLayout,
|
|
1429
1206
|
panelConstraints: panelConstraintsArray,
|
|
1430
1207
|
pivotIndices,
|
|
@@ -1434,16 +1211,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1434
1211
|
setLayout(nextLayout);
|
|
1435
1212
|
eagerValuesRef.current.layout = nextLayout;
|
|
1436
1213
|
if (onLayout) {
|
|
1437
|
-
onLayout(nextLayout
|
|
1438
|
-
sizePercentage,
|
|
1439
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1440
|
-
})));
|
|
1214
|
+
onLayout(nextLayout);
|
|
1441
1215
|
}
|
|
1442
|
-
callPanelCallbacks(
|
|
1216
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1443
1217
|
}
|
|
1444
1218
|
}
|
|
1445
1219
|
}
|
|
1446
|
-
}, [
|
|
1220
|
+
}, []);
|
|
1447
1221
|
|
|
1448
1222
|
// External APIs are safe to memoize via committed values ref
|
|
1449
1223
|
const expandPanel = useCallback(panelData => {
|
|
@@ -1457,21 +1231,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1457
1231
|
if (panelData.constraints.collapsible) {
|
|
1458
1232
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1459
1233
|
const {
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
pivotIndices
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
if (panelSizePercentage === collapsedSizePercentage) {
|
|
1234
|
+
collapsedSize = 0,
|
|
1235
|
+
panelSize,
|
|
1236
|
+
minSize = 0,
|
|
1237
|
+
pivotIndices
|
|
1238
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1239
|
+
if (panelSize === collapsedSize) {
|
|
1467
1240
|
// Restore this panel to the size it was before it was collapsed, if possible.
|
|
1468
|
-
const
|
|
1469
|
-
const
|
|
1241
|
+
const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
|
|
1242
|
+
const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
|
|
1470
1243
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1471
|
-
const delta = isLastPanel ?
|
|
1244
|
+
const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
|
|
1472
1245
|
const nextLayout = adjustLayoutByDelta({
|
|
1473
1246
|
delta,
|
|
1474
|
-
groupSizePixels,
|
|
1475
1247
|
layout: prevLayout,
|
|
1476
1248
|
panelConstraints: panelConstraintsArray,
|
|
1477
1249
|
pivotIndices,
|
|
@@ -1481,16 +1253,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1481
1253
|
setLayout(nextLayout);
|
|
1482
1254
|
eagerValuesRef.current.layout = nextLayout;
|
|
1483
1255
|
if (onLayout) {
|
|
1484
|
-
onLayout(nextLayout
|
|
1485
|
-
sizePercentage,
|
|
1486
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1487
|
-
})));
|
|
1256
|
+
onLayout(nextLayout);
|
|
1488
1257
|
}
|
|
1489
|
-
callPanelCallbacks(
|
|
1258
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1490
1259
|
}
|
|
1491
1260
|
}
|
|
1492
1261
|
}
|
|
1493
|
-
}, [
|
|
1262
|
+
}, []);
|
|
1494
1263
|
|
|
1495
1264
|
// External APIs are safe to memoize via committed values ref
|
|
1496
1265
|
const getPanelSize = useCallback(panelData => {
|
|
@@ -1499,14 +1268,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1499
1268
|
panelDataArray
|
|
1500
1269
|
} = eagerValuesRef.current;
|
|
1501
1270
|
const {
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
return
|
|
1506
|
-
|
|
1507
|
-
sizePixels: panelSizePixels
|
|
1508
|
-
};
|
|
1509
|
-
}, [groupId]);
|
|
1271
|
+
panelSize
|
|
1272
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1273
|
+
assert(panelSize != null);
|
|
1274
|
+
return panelSize;
|
|
1275
|
+
}, []);
|
|
1510
1276
|
|
|
1511
1277
|
// This API should never read from committedValuesRef
|
|
1512
1278
|
const getPanelStyle = useCallback(panelData => {
|
|
@@ -1529,12 +1295,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1529
1295
|
panelDataArray
|
|
1530
1296
|
} = eagerValuesRef.current;
|
|
1531
1297
|
const {
|
|
1532
|
-
|
|
1298
|
+
collapsedSize,
|
|
1533
1299
|
collapsible,
|
|
1534
|
-
|
|
1535
|
-
} = panelDataHelper(
|
|
1536
|
-
return collapsible === true &&
|
|
1537
|
-
}, [
|
|
1300
|
+
panelSize
|
|
1301
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1302
|
+
return collapsible === true && panelSize === collapsedSize;
|
|
1303
|
+
}, []);
|
|
1538
1304
|
|
|
1539
1305
|
// External APIs are safe to memoize via committed values ref
|
|
1540
1306
|
const isPanelExpanded = useCallback(panelData => {
|
|
@@ -1543,12 +1309,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1543
1309
|
panelDataArray
|
|
1544
1310
|
} = eagerValuesRef.current;
|
|
1545
1311
|
const {
|
|
1546
|
-
|
|
1312
|
+
collapsedSize = 0,
|
|
1547
1313
|
collapsible,
|
|
1548
|
-
|
|
1549
|
-
} = panelDataHelper(
|
|
1550
|
-
|
|
1551
|
-
|
|
1314
|
+
panelSize
|
|
1315
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1316
|
+
assert(panelSize != null);
|
|
1317
|
+
return !collapsible || panelSize > collapsedSize;
|
|
1318
|
+
}, []);
|
|
1552
1319
|
const registerPanel = useCallback(panelData => {
|
|
1553
1320
|
const {
|
|
1554
1321
|
autoSaveId,
|
|
@@ -1588,18 +1355,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1588
1355
|
if (autoSaveId) {
|
|
1589
1356
|
unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
|
|
1590
1357
|
}
|
|
1591
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1592
|
-
if (groupSizePixels <= 0) {
|
|
1593
|
-
if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
|
|
1594
|
-
constraints
|
|
1595
|
-
}) => constraints))) {
|
|
1596
|
-
// Wait until the group has rendered a non-zero size before computing layout.
|
|
1597
|
-
return;
|
|
1598
|
-
}
|
|
1599
|
-
}
|
|
1600
1358
|
if (unsafeLayout == null) {
|
|
1601
1359
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1602
|
-
groupSizePixels,
|
|
1603
1360
|
panelDataArray
|
|
1604
1361
|
});
|
|
1605
1362
|
}
|
|
@@ -1607,7 +1364,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1607
1364
|
// Validate even saved layouts in case something has changed since last render
|
|
1608
1365
|
// e.g. for pixel groups, this could be the size of the window
|
|
1609
1366
|
const nextLayout = validatePanelGroupLayout({
|
|
1610
|
-
groupSizePixels,
|
|
1611
1367
|
layout: unsafeLayout,
|
|
1612
1368
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1613
1369
|
});
|
|
@@ -1619,12 +1375,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1619
1375
|
eagerValuesRef.current.layout = nextLayout;
|
|
1620
1376
|
if (!areEqual(prevLayout, nextLayout)) {
|
|
1621
1377
|
if (onLayout) {
|
|
1622
|
-
onLayout(nextLayout
|
|
1623
|
-
sizePercentage,
|
|
1624
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1625
|
-
})));
|
|
1378
|
+
onLayout(nextLayout);
|
|
1626
1379
|
}
|
|
1627
|
-
callPanelCallbacks(
|
|
1380
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1628
1381
|
}
|
|
1629
1382
|
}, []);
|
|
1630
1383
|
const registerResizeHandle = useCallback(dragHandleId => {
|
|
@@ -1634,8 +1387,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1634
1387
|
direction,
|
|
1635
1388
|
dragState,
|
|
1636
1389
|
id: groupId,
|
|
1637
|
-
|
|
1638
|
-
keyboardResizeByPixels,
|
|
1390
|
+
keyboardResizeBy,
|
|
1639
1391
|
onLayout
|
|
1640
1392
|
} = committedValuesRef.current;
|
|
1641
1393
|
const {
|
|
@@ -1646,10 +1398,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1646
1398
|
initialLayout
|
|
1647
1399
|
} = dragState !== null && dragState !== void 0 ? dragState : {};
|
|
1648
1400
|
const pivotIndices = determinePivotIndices(groupId, dragHandleId);
|
|
1649
|
-
let delta = calculateDeltaPercentage(event,
|
|
1650
|
-
percentage: keyboardResizeByPercentage,
|
|
1651
|
-
pixels: keyboardResizeByPixels
|
|
1652
|
-
});
|
|
1401
|
+
let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
|
|
1653
1402
|
if (delta === 0) {
|
|
1654
1403
|
return;
|
|
1655
1404
|
}
|
|
@@ -1659,11 +1408,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1659
1408
|
if (document.dir === "rtl" && isHorizontal) {
|
|
1660
1409
|
delta = -delta;
|
|
1661
1410
|
}
|
|
1662
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1663
1411
|
const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
|
|
1664
1412
|
const nextLayout = adjustLayoutByDelta({
|
|
1665
1413
|
delta,
|
|
1666
|
-
groupSizePixels,
|
|
1667
1414
|
layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
|
|
1668
1415
|
panelConstraints,
|
|
1669
1416
|
pivotIndices,
|
|
@@ -1699,18 +1446,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1699
1446
|
setLayout(nextLayout);
|
|
1700
1447
|
eagerValuesRef.current.layout = nextLayout;
|
|
1701
1448
|
if (onLayout) {
|
|
1702
|
-
onLayout(nextLayout
|
|
1703
|
-
sizePercentage,
|
|
1704
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1705
|
-
})));
|
|
1449
|
+
onLayout(nextLayout);
|
|
1706
1450
|
}
|
|
1707
|
-
callPanelCallbacks(
|
|
1451
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1708
1452
|
}
|
|
1709
1453
|
};
|
|
1710
1454
|
}, []);
|
|
1711
1455
|
|
|
1712
1456
|
// External APIs are safe to memoize via committed values ref
|
|
1713
|
-
const resizePanel = useCallback((panelData,
|
|
1457
|
+
const resizePanel = useCallback((panelData, unsafePanelSize) => {
|
|
1714
1458
|
const {
|
|
1715
1459
|
onLayout
|
|
1716
1460
|
} = committedValuesRef.current;
|
|
@@ -1720,16 +1464,14 @@ function PanelGroupWithForwardedRef({
|
|
|
1720
1464
|
} = eagerValuesRef.current;
|
|
1721
1465
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1722
1466
|
const {
|
|
1723
|
-
|
|
1724
|
-
panelSizePercentage,
|
|
1467
|
+
panelSize,
|
|
1725
1468
|
pivotIndices
|
|
1726
|
-
} = panelDataHelper(
|
|
1727
|
-
|
|
1469
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1470
|
+
assert(panelSize != null);
|
|
1728
1471
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1729
|
-
const delta = isLastPanel ?
|
|
1472
|
+
const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
|
|
1730
1473
|
const nextLayout = adjustLayoutByDelta({
|
|
1731
1474
|
delta,
|
|
1732
|
-
groupSizePixels,
|
|
1733
1475
|
layout: prevLayout,
|
|
1734
1476
|
panelConstraints: panelConstraintsArray,
|
|
1735
1477
|
pivotIndices,
|
|
@@ -1739,14 +1481,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1739
1481
|
setLayout(nextLayout);
|
|
1740
1482
|
eagerValuesRef.current.layout = nextLayout;
|
|
1741
1483
|
if (onLayout) {
|
|
1742
|
-
onLayout(nextLayout
|
|
1743
|
-
sizePercentage,
|
|
1744
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1745
|
-
})));
|
|
1484
|
+
onLayout(nextLayout);
|
|
1746
1485
|
}
|
|
1747
|
-
callPanelCallbacks(
|
|
1486
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1748
1487
|
}
|
|
1749
|
-
}, [
|
|
1488
|
+
}, []);
|
|
1750
1489
|
const startDragging = useCallback((dragHandleId, event) => {
|
|
1751
1490
|
const {
|
|
1752
1491
|
direction
|
|
@@ -1755,6 +1494,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1755
1494
|
layout
|
|
1756
1495
|
} = eagerValuesRef.current;
|
|
1757
1496
|
const handleElement = getResizeHandleElement(dragHandleId);
|
|
1497
|
+
assert(handleElement);
|
|
1758
1498
|
const initialCursorPosition = getResizeEventCursorPosition(direction, event);
|
|
1759
1499
|
setDragState({
|
|
1760
1500
|
dragHandleId,
|
|
@@ -1773,7 +1513,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1773
1513
|
});
|
|
1774
1514
|
const unregisterPanel = useCallback(panelData => {
|
|
1775
1515
|
const {
|
|
1776
|
-
id: groupId,
|
|
1777
1516
|
onLayout
|
|
1778
1517
|
} = committedValuesRef.current;
|
|
1779
1518
|
const {
|
|
@@ -1796,7 +1535,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1796
1535
|
const {
|
|
1797
1536
|
pendingPanelIds
|
|
1798
1537
|
} = unregisterPanelRef.current;
|
|
1799
|
-
const map =
|
|
1538
|
+
const map = panelIdToLastNotifiedSizeMapRef.current;
|
|
1800
1539
|
|
|
1801
1540
|
// TRICKY
|
|
1802
1541
|
// Strict effects mode
|
|
@@ -1822,16 +1561,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1822
1561
|
// The group is unmounting; skip layout calculation.
|
|
1823
1562
|
return;
|
|
1824
1563
|
}
|
|
1825
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1826
1564
|
let unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1827
|
-
groupSizePixels,
|
|
1828
1565
|
panelDataArray
|
|
1829
1566
|
});
|
|
1830
1567
|
|
|
1831
1568
|
// Validate even saved layouts in case something has changed since last render
|
|
1832
1569
|
// e.g. for pixel groups, this could be the size of the window
|
|
1833
1570
|
const nextLayout = validatePanelGroupLayout({
|
|
1834
|
-
groupSizePixels,
|
|
1835
1571
|
layout: unsafeLayout,
|
|
1836
1572
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1837
1573
|
});
|
|
@@ -1839,12 +1575,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1839
1575
|
setLayout(nextLayout);
|
|
1840
1576
|
eagerValuesRef.current.layout = nextLayout;
|
|
1841
1577
|
if (onLayout) {
|
|
1842
|
-
onLayout(nextLayout
|
|
1843
|
-
sizePercentage,
|
|
1844
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1845
|
-
})));
|
|
1578
|
+
onLayout(nextLayout);
|
|
1846
1579
|
}
|
|
1847
|
-
callPanelCallbacks(
|
|
1580
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1848
1581
|
}
|
|
1849
1582
|
}, 0);
|
|
1850
1583
|
}, []);
|
|
@@ -1875,13 +1608,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1875
1608
|
return createElement(PanelGroupContext.Provider, {
|
|
1876
1609
|
value: context
|
|
1877
1610
|
}, createElement(Type, {
|
|
1611
|
+
...rest,
|
|
1878
1612
|
children,
|
|
1879
1613
|
className: classNameFromProps,
|
|
1880
1614
|
style: {
|
|
1881
1615
|
...style,
|
|
1882
1616
|
...styleFromProps
|
|
1883
1617
|
},
|
|
1884
|
-
...dataAttributes,
|
|
1885
1618
|
// CSS selectors
|
|
1886
1619
|
"data-panel-group": "",
|
|
1887
1620
|
"data-panel-group-direction": direction,
|
|
@@ -1894,22 +1627,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
|
|
|
1894
1627
|
}));
|
|
1895
1628
|
PanelGroupWithForwardedRef.displayName = "PanelGroup";
|
|
1896
1629
|
PanelGroup.displayName = "forwardRef(PanelGroup)";
|
|
1897
|
-
function panelDataHelper(
|
|
1630
|
+
function panelDataHelper(panelDataArray, panelData, layout) {
|
|
1898
1631
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1899
1632
|
const panelIndex = panelDataArray.indexOf(panelData);
|
|
1900
1633
|
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
1901
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1902
|
-
const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
|
|
1903
1634
|
const isLastPanel = panelIndex === panelDataArray.length - 1;
|
|
1904
1635
|
const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
|
|
1905
|
-
const
|
|
1906
|
-
const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
|
|
1636
|
+
const panelSize = layout[panelIndex];
|
|
1907
1637
|
return {
|
|
1908
|
-
...
|
|
1909
|
-
|
|
1910
|
-
panelSizePercentage,
|
|
1911
|
-
panelSizePixels,
|
|
1912
|
-
groupSizePixels,
|
|
1638
|
+
...panelConstraints,
|
|
1639
|
+
panelSize,
|
|
1913
1640
|
pivotIndices
|
|
1914
1641
|
};
|
|
1915
1642
|
}
|
|
@@ -1949,6 +1676,7 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1949
1676
|
{
|
|
1950
1677
|
event.preventDefault();
|
|
1951
1678
|
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
1679
|
+
assert(groupId);
|
|
1952
1680
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
1953
1681
|
const index = getResizeHandleElementIndex(groupId, handleId);
|
|
1954
1682
|
assert(index !== null);
|
|
@@ -1969,12 +1697,13 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1969
1697
|
function PanelResizeHandle({
|
|
1970
1698
|
children = null,
|
|
1971
1699
|
className: classNameFromProps = "",
|
|
1972
|
-
dataAttributes,
|
|
1973
1700
|
disabled = false,
|
|
1974
|
-
id: idFromProps
|
|
1701
|
+
id: idFromProps,
|
|
1975
1702
|
onDragging,
|
|
1976
1703
|
style: styleFromProps = {},
|
|
1977
|
-
|
|
1704
|
+
tabIndex = 0,
|
|
1705
|
+
tagName: Type = "div",
|
|
1706
|
+
...rest
|
|
1978
1707
|
}) {
|
|
1979
1708
|
const divElementRef = useRef(null);
|
|
1980
1709
|
|
|
@@ -2004,8 +1733,9 @@ function PanelResizeHandle({
|
|
|
2004
1733
|
const stopDraggingAndBlur = useCallback(() => {
|
|
2005
1734
|
// Clicking on the drag handle shouldn't leave it focused;
|
|
2006
1735
|
// That would cause the PanelGroup to think it was still active.
|
|
2007
|
-
const
|
|
2008
|
-
|
|
1736
|
+
const divElement = divElementRef.current;
|
|
1737
|
+
assert(divElement);
|
|
1738
|
+
divElement.blur();
|
|
2009
1739
|
stopDragging();
|
|
2010
1740
|
const {
|
|
2011
1741
|
onDragging
|
|
@@ -2033,6 +1763,7 @@ function PanelResizeHandle({
|
|
|
2033
1763
|
resizeHandler(event);
|
|
2034
1764
|
};
|
|
2035
1765
|
const divElement = divElementRef.current;
|
|
1766
|
+
assert(divElement);
|
|
2036
1767
|
const targetDocument = divElement.ownerDocument;
|
|
2037
1768
|
targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
|
|
2038
1769
|
targetDocument.body.addEventListener("mousemove", onMove);
|
|
@@ -2060,15 +1791,18 @@ function PanelResizeHandle({
|
|
|
2060
1791
|
userSelect: "none"
|
|
2061
1792
|
};
|
|
2062
1793
|
return createElement(Type, {
|
|
1794
|
+
...rest,
|
|
2063
1795
|
children,
|
|
2064
1796
|
className: classNameFromProps,
|
|
2065
1797
|
onBlur: () => setIsFocused(false),
|
|
2066
1798
|
onFocus: () => setIsFocused(true),
|
|
2067
1799
|
onMouseDown: event => {
|
|
2068
1800
|
startDragging(resizeHandleId, event.nativeEvent);
|
|
1801
|
+
const callbacks = callbacksRef.current;
|
|
1802
|
+
assert(callbacks);
|
|
2069
1803
|
const {
|
|
2070
1804
|
onDragging
|
|
2071
|
-
} =
|
|
1805
|
+
} = callbacks;
|
|
2072
1806
|
if (onDragging) {
|
|
2073
1807
|
onDragging(true);
|
|
2074
1808
|
}
|
|
@@ -2078,9 +1812,11 @@ function PanelResizeHandle({
|
|
|
2078
1812
|
onTouchEnd: stopDraggingAndBlur,
|
|
2079
1813
|
onTouchStart: event => {
|
|
2080
1814
|
startDragging(resizeHandleId, event.nativeEvent);
|
|
1815
|
+
const callbacks = callbacksRef.current;
|
|
1816
|
+
assert(callbacks);
|
|
2081
1817
|
const {
|
|
2082
1818
|
onDragging
|
|
2083
|
-
} =
|
|
1819
|
+
} = callbacks;
|
|
2084
1820
|
if (onDragging) {
|
|
2085
1821
|
onDragging(true);
|
|
2086
1822
|
}
|
|
@@ -2091,8 +1827,7 @@ function PanelResizeHandle({
|
|
|
2091
1827
|
...style,
|
|
2092
1828
|
...styleFromProps
|
|
2093
1829
|
},
|
|
2094
|
-
tabIndex
|
|
2095
|
-
...dataAttributes,
|
|
1830
|
+
tabIndex,
|
|
2096
1831
|
// CSS selectors
|
|
2097
1832
|
"data-panel-group-direction": direction,
|
|
2098
1833
|
"data-panel-group-id": groupId,
|
|
@@ -2104,4 +1839,4 @@ function PanelResizeHandle({
|
|
|
2104
1839
|
}
|
|
2105
1840
|
PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
2106
1841
|
|
|
2107
|
-
export { Panel, PanelGroup, PanelResizeHandle };
|
|
1842
|
+
export { Panel, PanelGroup, PanelResizeHandle, assert };
|