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