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
|
@@ -39,24 +39,20 @@ function useUniqueId(idFromParams = null) {
|
|
|
39
39
|
function PanelWithForwardedRef({
|
|
40
40
|
children,
|
|
41
41
|
className: classNameFromProps = "",
|
|
42
|
-
|
|
43
|
-
collapsedSizePixels,
|
|
42
|
+
collapsedSize,
|
|
44
43
|
collapsible,
|
|
45
|
-
|
|
46
|
-
defaultSizePercentage,
|
|
47
|
-
defaultSizePixels,
|
|
44
|
+
defaultSize,
|
|
48
45
|
forwardedRef,
|
|
49
46
|
id: idFromProps,
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
minSizePercentage,
|
|
53
|
-
minSizePixels,
|
|
47
|
+
maxSize,
|
|
48
|
+
minSize,
|
|
54
49
|
onCollapse,
|
|
55
50
|
onExpand,
|
|
56
51
|
onResize,
|
|
57
52
|
order,
|
|
58
53
|
style: styleFromProps,
|
|
59
|
-
tagName: Type = "div"
|
|
54
|
+
tagName: Type = "div",
|
|
55
|
+
...rest
|
|
60
56
|
}) {
|
|
61
57
|
const context = useContext(PanelGroupContext);
|
|
62
58
|
if (context === null) {
|
|
@@ -81,15 +77,11 @@ function PanelWithForwardedRef({
|
|
|
81
77
|
onResize
|
|
82
78
|
},
|
|
83
79
|
constraints: {
|
|
84
|
-
|
|
85
|
-
collapsedSizePixels,
|
|
80
|
+
collapsedSize,
|
|
86
81
|
collapsible,
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
maxSizePixels,
|
|
91
|
-
minSizePercentage,
|
|
92
|
-
minSizePixels
|
|
82
|
+
defaultSize,
|
|
83
|
+
maxSize,
|
|
84
|
+
minSize
|
|
93
85
|
},
|
|
94
86
|
id: panelId,
|
|
95
87
|
idIsFromProps: idFromProps !== undefined,
|
|
@@ -103,9 +95,9 @@ function PanelWithForwardedRef({
|
|
|
103
95
|
// but effects don't run on the server, so we can't do it there
|
|
104
96
|
{
|
|
105
97
|
if (!devWarningsRef.current.didLogMissingDefaultSizeWarning) {
|
|
106
|
-
if (
|
|
98
|
+
if (defaultSize == null) {
|
|
107
99
|
devWarningsRef.current.didLogMissingDefaultSizeWarning = true;
|
|
108
|
-
console.warn(`WARNING: Panel
|
|
100
|
+
console.warn(`WARNING: Panel defaultSize prop recommended to avoid layout shift after server rendering`);
|
|
109
101
|
}
|
|
110
102
|
}
|
|
111
103
|
}
|
|
@@ -128,19 +120,19 @@ function PanelWithForwardedRef({
|
|
|
128
120
|
isExpanded() {
|
|
129
121
|
return !isPanelCollapsed(panelDataRef.current);
|
|
130
122
|
},
|
|
131
|
-
resize:
|
|
132
|
-
resizePanel(panelDataRef.current,
|
|
123
|
+
resize: size => {
|
|
124
|
+
resizePanel(panelDataRef.current, size);
|
|
133
125
|
}
|
|
134
126
|
}), [collapsePanel, expandPanel, getPanelSize, isPanelCollapsed, panelId, resizePanel]);
|
|
135
127
|
const style = getPanelStyle(panelDataRef.current);
|
|
136
128
|
return createElement(Type, {
|
|
129
|
+
...rest,
|
|
137
130
|
children,
|
|
138
131
|
className: classNameFromProps,
|
|
139
132
|
style: {
|
|
140
133
|
...style,
|
|
141
134
|
...styleFromProps
|
|
142
135
|
},
|
|
143
|
-
...dataAttributes,
|
|
144
136
|
// CSS selectors
|
|
145
137
|
"data-panel": "",
|
|
146
138
|
"data-panel-id": panelId,
|
|
@@ -157,81 +149,11 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
|
|
|
157
149
|
PanelWithForwardedRef.displayName = "Panel";
|
|
158
150
|
Panel.displayName = "forwardRef(Panel)";
|
|
159
151
|
|
|
160
|
-
function
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
function convertPixelConstraintsToPercentages(panelConstraints, groupSizePixels) {
|
|
165
|
-
let {
|
|
166
|
-
collapsedSizePercentage = 0,
|
|
167
|
-
collapsedSizePixels,
|
|
168
|
-
defaultSizePercentage,
|
|
169
|
-
defaultSizePixels,
|
|
170
|
-
maxSizePercentage = 100,
|
|
171
|
-
maxSizePixels,
|
|
172
|
-
minSizePercentage = 0,
|
|
173
|
-
minSizePixels
|
|
174
|
-
} = panelConstraints;
|
|
175
|
-
const hasPixelConstraints = collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null;
|
|
176
|
-
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
177
|
-
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
178
|
-
return {
|
|
179
|
-
collapsedSizePercentage: 0,
|
|
180
|
-
defaultSizePercentage,
|
|
181
|
-
maxSizePercentage: 0,
|
|
182
|
-
minSizePercentage: 0
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
if (collapsedSizePixels != null) {
|
|
186
|
-
collapsedSizePercentage = convertPixelsToPercentage(collapsedSizePixels, groupSizePixels);
|
|
187
|
-
}
|
|
188
|
-
if (defaultSizePixels != null) {
|
|
189
|
-
defaultSizePercentage = convertPixelsToPercentage(defaultSizePixels, groupSizePixels);
|
|
190
|
-
}
|
|
191
|
-
if (minSizePixels != null) {
|
|
192
|
-
minSizePercentage = convertPixelsToPercentage(minSizePixels, groupSizePixels);
|
|
193
|
-
}
|
|
194
|
-
if (maxSizePixels != null) {
|
|
195
|
-
maxSizePercentage = convertPixelsToPercentage(maxSizePixels, groupSizePixels);
|
|
196
|
-
}
|
|
197
|
-
return {
|
|
198
|
-
collapsedSizePercentage,
|
|
199
|
-
defaultSizePercentage,
|
|
200
|
-
maxSizePercentage,
|
|
201
|
-
minSizePercentage
|
|
202
|
-
};
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
function computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels) {
|
|
206
|
-
// All panel constraints, excluding the current one
|
|
207
|
-
let totalMinConstraints = 0;
|
|
208
|
-
let totalMaxConstraints = 0;
|
|
209
|
-
for (let index = 0; index < panelConstraintsArray.length; index++) {
|
|
210
|
-
if (index !== panelIndex) {
|
|
211
|
-
const {
|
|
212
|
-
collapsible
|
|
213
|
-
} = panelConstraintsArray[index];
|
|
214
|
-
const {
|
|
215
|
-
collapsedSizePercentage,
|
|
216
|
-
maxSizePercentage,
|
|
217
|
-
minSizePercentage
|
|
218
|
-
} = convertPixelConstraintsToPercentages(panelConstraintsArray[index], groupSizePixels);
|
|
219
|
-
totalMaxConstraints += maxSizePercentage;
|
|
220
|
-
totalMinConstraints += collapsible ? collapsedSizePercentage : minSizePercentage;
|
|
221
|
-
}
|
|
152
|
+
function assert(expectedCondition, message = "Assertion failed!") {
|
|
153
|
+
if (!expectedCondition) {
|
|
154
|
+
console.error(message);
|
|
155
|
+
throw Error(message);
|
|
222
156
|
}
|
|
223
|
-
const {
|
|
224
|
-
collapsedSizePercentage,
|
|
225
|
-
defaultSizePercentage,
|
|
226
|
-
maxSizePercentage,
|
|
227
|
-
minSizePercentage
|
|
228
|
-
} = convertPixelConstraintsToPercentages(panelConstraintsArray[panelIndex], groupSizePixels);
|
|
229
|
-
return {
|
|
230
|
-
collapsedSizePercentage,
|
|
231
|
-
defaultSizePercentage,
|
|
232
|
-
maxSizePercentage: panelConstraintsArray.length > 1 ? Math.min(maxSizePercentage, 100 - totalMinConstraints) : maxSizePercentage,
|
|
233
|
-
minSizePercentage: panelConstraintsArray.length > 1 ? Math.max(minSizePercentage, 100 - totalMaxConstraints) : minSizePercentage
|
|
234
|
-
};
|
|
235
157
|
}
|
|
236
158
|
|
|
237
159
|
const PRECISION = 10;
|
|
@@ -253,56 +175,41 @@ function fuzzyNumbersEqual(actual, expected, fractionDigits) {
|
|
|
253
175
|
|
|
254
176
|
// Panel size must be in percentages; pixel values should be pre-converted
|
|
255
177
|
function resizePanel({
|
|
256
|
-
|
|
257
|
-
panelConstraints,
|
|
178
|
+
panelConstraints: panelConstraintsArray,
|
|
258
179
|
panelIndex,
|
|
259
180
|
size
|
|
260
181
|
}) {
|
|
261
|
-
const
|
|
262
|
-
|
|
263
|
-
defaultSizePixels,
|
|
264
|
-
minSizePixels,
|
|
265
|
-
maxSizePixels
|
|
266
|
-
}) => collapsedSizePixels != null || defaultSizePixels != null || minSizePixels != null || maxSizePixels != null);
|
|
267
|
-
if (hasPixelConstraints && groupSizePixels <= 0) {
|
|
268
|
-
console.warn(`WARNING: Invalid group size: ${groupSizePixels}px`);
|
|
269
|
-
return 0;
|
|
270
|
-
}
|
|
182
|
+
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
183
|
+
assert(panelConstraints != null);
|
|
271
184
|
let {
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
if (
|
|
282
|
-
|
|
283
|
-
const halfwayPoint = (collapsedSizePercentage + minSizePercentage) / 2;
|
|
284
|
-
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
285
|
-
size = collapsedSizePercentage;
|
|
286
|
-
} else {
|
|
287
|
-
size = minSizePercentage;
|
|
288
|
-
}
|
|
185
|
+
collapsedSize = 0,
|
|
186
|
+
collapsible,
|
|
187
|
+
maxSize = 100,
|
|
188
|
+
minSize = 0
|
|
189
|
+
} = panelConstraints;
|
|
190
|
+
if (fuzzyCompareNumbers(size, minSize) < 0) {
|
|
191
|
+
if (collapsible) {
|
|
192
|
+
// Collapsible panels should snap closed or open only once they cross the halfway point between collapsed and min size.
|
|
193
|
+
const halfwayPoint = (collapsedSize + minSize) / 2;
|
|
194
|
+
if (fuzzyCompareNumbers(size, halfwayPoint) < 0) {
|
|
195
|
+
size = collapsedSize;
|
|
289
196
|
} else {
|
|
290
|
-
size =
|
|
197
|
+
size = minSize;
|
|
291
198
|
}
|
|
199
|
+
} else {
|
|
200
|
+
size = minSize;
|
|
292
201
|
}
|
|
293
202
|
}
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
}
|
|
203
|
+
size = Math.min(maxSize, size);
|
|
204
|
+
size = parseFloat(size.toFixed(PRECISION));
|
|
297
205
|
return size;
|
|
298
206
|
}
|
|
299
207
|
|
|
300
208
|
// All units must be in percentages; pixel values should be pre-converted
|
|
301
209
|
function adjustLayoutByDelta({
|
|
302
210
|
delta,
|
|
303
|
-
groupSizePixels,
|
|
304
211
|
layout: prevLayout,
|
|
305
|
-
panelConstraints,
|
|
212
|
+
panelConstraints: panelConstraintsArray,
|
|
306
213
|
pivotIndices,
|
|
307
214
|
trigger
|
|
308
215
|
}) {
|
|
@@ -310,6 +217,9 @@ function adjustLayoutByDelta({
|
|
|
310
217
|
return prevLayout;
|
|
311
218
|
}
|
|
312
219
|
const nextLayout = [...prevLayout];
|
|
220
|
+
const [firstPivotIndex, secondPivotIndex] = pivotIndices;
|
|
221
|
+
assert(firstPivotIndex != null);
|
|
222
|
+
assert(secondPivotIndex != null);
|
|
313
223
|
let deltaApplied = 0;
|
|
314
224
|
|
|
315
225
|
//const DEBUG = [];
|
|
@@ -333,18 +243,23 @@ function adjustLayoutByDelta({
|
|
|
333
243
|
if (trigger === "keyboard") {
|
|
334
244
|
{
|
|
335
245
|
// Check if we should expand a collapsed panel
|
|
336
|
-
const index = delta < 0 ?
|
|
337
|
-
const
|
|
246
|
+
const index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
247
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
248
|
+
assert(panelConstraints);
|
|
249
|
+
|
|
338
250
|
//DEBUG.push(`edge case check 1: ${index}`);
|
|
339
251
|
//DEBUG.push(` -> collapsible? ${constraints.collapsible}`);
|
|
340
|
-
if (
|
|
252
|
+
if (panelConstraints.collapsible) {
|
|
341
253
|
const prevSize = prevLayout[index];
|
|
254
|
+
assert(prevSize != null);
|
|
255
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
256
|
+
assert(panelConstraints);
|
|
342
257
|
const {
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
} =
|
|
346
|
-
if (fuzzyNumbersEqual(prevSize,
|
|
347
|
-
const localDelta =
|
|
258
|
+
collapsedSize = 0,
|
|
259
|
+
minSize = 0
|
|
260
|
+
} = panelConstraints;
|
|
261
|
+
if (fuzzyNumbersEqual(prevSize, collapsedSize)) {
|
|
262
|
+
const localDelta = minSize - prevSize;
|
|
348
263
|
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
349
264
|
|
|
350
265
|
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
@@ -357,18 +272,26 @@ function adjustLayoutByDelta({
|
|
|
357
272
|
|
|
358
273
|
{
|
|
359
274
|
// Check if we should collapse a panel at its minimum size
|
|
360
|
-
const index = delta < 0 ?
|
|
361
|
-
const
|
|
275
|
+
const index = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
276
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
277
|
+
assert(panelConstraints);
|
|
278
|
+
const {
|
|
279
|
+
collapsible
|
|
280
|
+
} = panelConstraints;
|
|
281
|
+
|
|
362
282
|
//DEBUG.push(`edge case check 2: ${index}`);
|
|
363
|
-
//DEBUG.push(` -> collapsible? ${
|
|
364
|
-
if (
|
|
283
|
+
//DEBUG.push(` -> collapsible? ${collapsible}`);
|
|
284
|
+
if (collapsible) {
|
|
365
285
|
const prevSize = prevLayout[index];
|
|
286
|
+
assert(prevSize != null);
|
|
287
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
288
|
+
assert(panelConstraints);
|
|
366
289
|
const {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
} =
|
|
370
|
-
if (fuzzyNumbersEqual(prevSize,
|
|
371
|
-
const localDelta = prevSize -
|
|
290
|
+
collapsedSize = 0,
|
|
291
|
+
minSize = 0
|
|
292
|
+
} = panelConstraints;
|
|
293
|
+
if (fuzzyNumbersEqual(prevSize, minSize)) {
|
|
294
|
+
const localDelta = prevSize - collapsedSize;
|
|
372
295
|
//DEBUG.push(` -> expand delta: ${localDelta}`);
|
|
373
296
|
|
|
374
297
|
if (fuzzyCompareNumbers(localDelta, Math.abs(delta)) > 0) {
|
|
@@ -390,15 +313,15 @@ function adjustLayoutByDelta({
|
|
|
390
313
|
// as an expanding panel might change from collapsed to min size.
|
|
391
314
|
|
|
392
315
|
const increment = delta < 0 ? 1 : -1;
|
|
393
|
-
let index = delta < 0 ?
|
|
316
|
+
let index = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
394
317
|
let maxAvailableDelta = 0;
|
|
395
318
|
|
|
396
319
|
//DEBUG.push("pre calc...");
|
|
397
320
|
while (true) {
|
|
398
321
|
const prevSize = prevLayout[index];
|
|
322
|
+
assert(prevSize != null);
|
|
399
323
|
const maxSafeSize = resizePanel({
|
|
400
|
-
|
|
401
|
-
panelConstraints,
|
|
324
|
+
panelConstraints: panelConstraintsArray,
|
|
402
325
|
panelIndex: index,
|
|
403
326
|
size: 100
|
|
404
327
|
});
|
|
@@ -407,7 +330,7 @@ function adjustLayoutByDelta({
|
|
|
407
330
|
|
|
408
331
|
maxAvailableDelta += delta;
|
|
409
332
|
index += increment;
|
|
410
|
-
if (index < 0 || index >=
|
|
333
|
+
if (index < 0 || index >= panelConstraintsArray.length) {
|
|
411
334
|
break;
|
|
412
335
|
}
|
|
413
336
|
}
|
|
@@ -422,15 +345,15 @@ function adjustLayoutByDelta({
|
|
|
422
345
|
{
|
|
423
346
|
// Delta added to a panel needs to be subtracted from other panels (within the constraints that those panels allow).
|
|
424
347
|
|
|
425
|
-
const pivotIndex = delta < 0 ?
|
|
348
|
+
const pivotIndex = delta < 0 ? firstPivotIndex : secondPivotIndex;
|
|
426
349
|
let index = pivotIndex;
|
|
427
|
-
while (index >= 0 && index <
|
|
350
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
428
351
|
const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
|
|
429
352
|
const prevSize = prevLayout[index];
|
|
353
|
+
assert(prevSize != null);
|
|
430
354
|
const unsafeSize = prevSize - deltaRemaining;
|
|
431
355
|
const safeSize = resizePanel({
|
|
432
|
-
|
|
433
|
-
panelConstraints,
|
|
356
|
+
panelConstraints: panelConstraintsArray,
|
|
434
357
|
panelIndex: index,
|
|
435
358
|
size: unsafeSize
|
|
436
359
|
});
|
|
@@ -462,11 +385,12 @@ function adjustLayoutByDelta({
|
|
|
462
385
|
}
|
|
463
386
|
{
|
|
464
387
|
// Now distribute the applied delta to the panels in the other direction
|
|
465
|
-
const pivotIndex = delta < 0 ?
|
|
466
|
-
const
|
|
388
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
389
|
+
const prevSize = prevLayout[pivotIndex];
|
|
390
|
+
assert(prevSize != null);
|
|
391
|
+
const unsafeSize = prevSize + deltaApplied;
|
|
467
392
|
const safeSize = resizePanel({
|
|
468
|
-
|
|
469
|
-
panelConstraints,
|
|
393
|
+
panelConstraints: panelConstraintsArray,
|
|
470
394
|
panelIndex: pivotIndex,
|
|
471
395
|
size: unsafeSize
|
|
472
396
|
});
|
|
@@ -477,14 +401,14 @@ function adjustLayoutByDelta({
|
|
|
477
401
|
// Edge case where expanding or contracting one panel caused another one to change collapsed state
|
|
478
402
|
if (!fuzzyNumbersEqual(safeSize, unsafeSize)) {
|
|
479
403
|
let deltaRemaining = unsafeSize - safeSize;
|
|
480
|
-
const pivotIndex = delta < 0 ?
|
|
404
|
+
const pivotIndex = delta < 0 ? secondPivotIndex : firstPivotIndex;
|
|
481
405
|
let index = pivotIndex;
|
|
482
|
-
while (index >= 0 && index <
|
|
406
|
+
while (index >= 0 && index < panelConstraintsArray.length) {
|
|
483
407
|
const prevSize = nextLayout[index];
|
|
408
|
+
assert(prevSize != null);
|
|
484
409
|
const unsafeSize = prevSize + deltaRemaining;
|
|
485
410
|
const safeSize = resizePanel({
|
|
486
|
-
|
|
487
|
-
panelConstraints,
|
|
411
|
+
panelConstraints: panelConstraintsArray,
|
|
488
412
|
panelIndex: index,
|
|
489
413
|
size: unsafeSize
|
|
490
414
|
});
|
|
@@ -508,9 +432,7 @@ function adjustLayoutByDelta({
|
|
|
508
432
|
//DEBUG.push("");
|
|
509
433
|
|
|
510
434
|
const totalSize = nextLayout.reduce((total, size) => size + total, 0);
|
|
511
|
-
deltaApplied = 100 - totalSize;
|
|
512
435
|
//DEBUG.push(`total size: ${totalSize}`);
|
|
513
|
-
//DEBUG.push(` deltaApplied: ${deltaApplied}`);
|
|
514
436
|
//console.log(DEBUG.join("\n"));
|
|
515
437
|
|
|
516
438
|
if (!fuzzyNumbersEqual(totalSize, 100)) {
|
|
@@ -519,25 +441,6 @@ function adjustLayoutByDelta({
|
|
|
519
441
|
return nextLayout;
|
|
520
442
|
}
|
|
521
443
|
|
|
522
|
-
function assert(expectedCondition, message = "Assertion failed!") {
|
|
523
|
-
if (!expectedCondition) {
|
|
524
|
-
console.error(message);
|
|
525
|
-
throw Error(message);
|
|
526
|
-
}
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
function getPercentageSizeFromMixedSizes({
|
|
530
|
-
sizePercentage,
|
|
531
|
-
sizePixels
|
|
532
|
-
}, groupSizePixels) {
|
|
533
|
-
if (sizePercentage != null) {
|
|
534
|
-
return sizePercentage;
|
|
535
|
-
} else if (sizePixels != null) {
|
|
536
|
-
return convertPixelsToPercentage(sizePixels, groupSizePixels);
|
|
537
|
-
}
|
|
538
|
-
return undefined;
|
|
539
|
-
}
|
|
540
|
-
|
|
541
444
|
function getResizeHandleElementsForGroup(groupId) {
|
|
542
445
|
return Array.from(document.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
|
|
543
446
|
}
|
|
@@ -561,42 +464,6 @@ function getPanelGroupElement(id) {
|
|
|
561
464
|
return null;
|
|
562
465
|
}
|
|
563
466
|
|
|
564
|
-
function calculateAvailablePanelSizeInPixels(groupId) {
|
|
565
|
-
const panelGroupElement = getPanelGroupElement(groupId);
|
|
566
|
-
if (panelGroupElement == null) {
|
|
567
|
-
return NaN;
|
|
568
|
-
}
|
|
569
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
570
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId);
|
|
571
|
-
if (direction === "horizontal") {
|
|
572
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
573
|
-
return accumulated + handle.offsetWidth;
|
|
574
|
-
}, 0);
|
|
575
|
-
} else {
|
|
576
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
577
|
-
return accumulated + handle.offsetHeight;
|
|
578
|
-
}, 0);
|
|
579
|
-
}
|
|
580
|
-
}
|
|
581
|
-
|
|
582
|
-
function getAvailableGroupSizePixels(groupId) {
|
|
583
|
-
const panelGroupElement = getPanelGroupElement(groupId);
|
|
584
|
-
if (panelGroupElement == null) {
|
|
585
|
-
return NaN;
|
|
586
|
-
}
|
|
587
|
-
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
588
|
-
const resizeHandles = getResizeHandleElementsForGroup(groupId);
|
|
589
|
-
if (direction === "horizontal") {
|
|
590
|
-
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
591
|
-
return accumulated + handle.offsetWidth;
|
|
592
|
-
}, 0);
|
|
593
|
-
} else {
|
|
594
|
-
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
595
|
-
return accumulated + handle.offsetHeight;
|
|
596
|
-
}, 0);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
599
|
-
|
|
600
467
|
function getResizeHandleElement(id) {
|
|
601
468
|
const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
|
|
602
469
|
if (element) {
|
|
@@ -629,14 +496,18 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
629
496
|
didWarnAboutMissingResizeHandle: false
|
|
630
497
|
});
|
|
631
498
|
useEffect(() => {
|
|
499
|
+
const eagerValues = eagerValuesRef.current;
|
|
500
|
+
assert(eagerValues);
|
|
632
501
|
const {
|
|
633
502
|
panelDataArray
|
|
634
|
-
} =
|
|
503
|
+
} = eagerValues;
|
|
635
504
|
const groupElement = getPanelGroupElement(groupId);
|
|
636
505
|
assert(groupElement != null, `No group found for id "${groupId}"`);
|
|
637
506
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
507
|
+
assert(handles);
|
|
638
508
|
const cleanupFunctions = handles.map(handle => {
|
|
639
509
|
const handleId = handle.getAttribute("data-panel-resize-handle-id");
|
|
510
|
+
assert(handleId);
|
|
640
511
|
const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
|
|
641
512
|
if (idBefore == null || idAfter == null) {
|
|
642
513
|
return () => {};
|
|
@@ -652,21 +523,16 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
652
523
|
const index = panelDataArray.findIndex(panelData => panelData.id === idBefore);
|
|
653
524
|
if (index >= 0) {
|
|
654
525
|
const panelData = panelDataArray[index];
|
|
526
|
+
assert(panelData);
|
|
655
527
|
const size = layout[index];
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
663
|
-
const minSize = (_getPercentageSizeFro2 = getPercentageSizeFromMixedSizes({
|
|
664
|
-
sizePercentage: panelData.constraints.minSizePercentage,
|
|
665
|
-
sizePixels: panelData.constraints.minSizePixels
|
|
666
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro2 !== void 0 ? _getPercentageSizeFro2 : 0;
|
|
528
|
+
const {
|
|
529
|
+
collapsedSize = 0,
|
|
530
|
+
collapsible,
|
|
531
|
+
minSize = 0
|
|
532
|
+
} = panelData.constraints;
|
|
533
|
+
if (size != null && collapsible) {
|
|
667
534
|
const nextLayout = adjustLayoutByDelta({
|
|
668
535
|
delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
|
|
669
|
-
groupSizePixels,
|
|
670
536
|
layout,
|
|
671
537
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints),
|
|
672
538
|
pivotIndices: determinePivotIndices(groupId, handleId),
|
|
@@ -720,6 +586,7 @@ function getResizeEventCursorPosition(direction, event) {
|
|
|
720
586
|
return isHorizontal ? event.clientX : event.clientY;
|
|
721
587
|
} else if (isTouchEvent(event)) {
|
|
722
588
|
const firstTouch = event.touches[0];
|
|
589
|
+
assert(firstTouch);
|
|
723
590
|
return isHorizontal ? firstTouch.screenX : firstTouch.screenY;
|
|
724
591
|
} else {
|
|
725
592
|
throw Error(`Unsupported event type "${event.type}"`);
|
|
@@ -729,12 +596,15 @@ function getResizeEventCursorPosition(direction, event) {
|
|
|
729
596
|
function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
|
|
730
597
|
const isHorizontal = direction === "horizontal";
|
|
731
598
|
const handleElement = getResizeHandleElement(dragHandleId);
|
|
599
|
+
assert(handleElement);
|
|
732
600
|
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
601
|
+
assert(groupId);
|
|
733
602
|
let {
|
|
734
603
|
initialCursorPosition
|
|
735
604
|
} = initialDragState;
|
|
736
605
|
const cursorPosition = getResizeEventCursorPosition(direction, event);
|
|
737
606
|
const groupElement = getPanelGroupElement(groupId);
|
|
607
|
+
assert(groupElement);
|
|
738
608
|
const groupRect = groupElement.getBoundingClientRect();
|
|
739
609
|
const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
|
|
740
610
|
const offsetPixels = cursorPosition - initialCursorPosition;
|
|
@@ -743,19 +613,14 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
|
|
|
743
613
|
}
|
|
744
614
|
|
|
745
615
|
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
|
|
746
|
-
function calculateDeltaPercentage(event,
|
|
616
|
+
function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
|
|
747
617
|
if (isKeyDown(event)) {
|
|
748
618
|
const isHorizontal = direction === "horizontal";
|
|
749
|
-
const groupElement = getPanelGroupElement(groupId);
|
|
750
|
-
const rect = groupElement.getBoundingClientRect();
|
|
751
|
-
const groupSizeInPixels = isHorizontal ? rect.width : rect.height;
|
|
752
619
|
let delta = 0;
|
|
753
620
|
if (event.shiftKey) {
|
|
754
621
|
delta = 100;
|
|
755
|
-
} else if (
|
|
756
|
-
delta =
|
|
757
|
-
} else if (keyboardResizeByOptions.pixels != null) {
|
|
758
|
-
delta = keyboardResizeByOptions.pixels / groupSizeInPixels;
|
|
622
|
+
} else if (keyboardResizeBy != null) {
|
|
623
|
+
delta = keyboardResizeBy;
|
|
759
624
|
} else {
|
|
760
625
|
delta = 10;
|
|
761
626
|
}
|
|
@@ -782,37 +647,43 @@ function calculateDeltaPercentage(event, groupId, dragHandleId, direction, initi
|
|
|
782
647
|
}
|
|
783
648
|
return movement;
|
|
784
649
|
} else {
|
|
650
|
+
if (initialDragState == null) {
|
|
651
|
+
return 0;
|
|
652
|
+
}
|
|
785
653
|
return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
|
|
786
654
|
}
|
|
787
655
|
}
|
|
788
656
|
|
|
789
657
|
function calculateUnsafeDefaultLayout({
|
|
790
|
-
groupSizePixels,
|
|
791
658
|
panelDataArray
|
|
792
659
|
}) {
|
|
793
660
|
const layout = Array(panelDataArray.length);
|
|
794
|
-
const
|
|
661
|
+
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
795
662
|
let numPanelsWithSizes = 0;
|
|
796
663
|
let remainingSize = 100;
|
|
797
664
|
|
|
798
665
|
// Distribute default sizes first
|
|
799
666
|
for (let index = 0; index < panelDataArray.length; index++) {
|
|
667
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
668
|
+
assert(panelConstraints);
|
|
800
669
|
const {
|
|
801
|
-
|
|
802
|
-
} =
|
|
803
|
-
if (
|
|
670
|
+
defaultSize
|
|
671
|
+
} = panelConstraints;
|
|
672
|
+
if (defaultSize != null) {
|
|
804
673
|
numPanelsWithSizes++;
|
|
805
|
-
layout[index] =
|
|
806
|
-
remainingSize -=
|
|
674
|
+
layout[index] = defaultSize;
|
|
675
|
+
remainingSize -= defaultSize;
|
|
807
676
|
}
|
|
808
677
|
}
|
|
809
678
|
|
|
810
679
|
// Remaining size should be distributed evenly between panels without default sizes
|
|
811
680
|
for (let index = 0; index < panelDataArray.length; index++) {
|
|
681
|
+
const panelConstraints = panelConstraintsArray[index];
|
|
682
|
+
assert(panelConstraints);
|
|
812
683
|
const {
|
|
813
|
-
|
|
814
|
-
} =
|
|
815
|
-
if (
|
|
684
|
+
defaultSize
|
|
685
|
+
} = panelConstraints;
|
|
686
|
+
if (defaultSize != null) {
|
|
816
687
|
continue;
|
|
817
688
|
}
|
|
818
689
|
const numRemainingPanels = panelDataArray.length - numPanelsWithSizes;
|
|
@@ -824,54 +695,36 @@ function calculateUnsafeDefaultLayout({
|
|
|
824
695
|
return layout;
|
|
825
696
|
}
|
|
826
697
|
|
|
827
|
-
function convertPercentageToPixels(percentage, groupSizePixels) {
|
|
828
|
-
return percentage / 100 * groupSizePixels;
|
|
829
|
-
}
|
|
830
|
-
|
|
831
698
|
// Layout should be pre-converted into percentages
|
|
832
|
-
function callPanelCallbacks(
|
|
833
|
-
|
|
834
|
-
layout.forEach((sizePercentage, index) => {
|
|
699
|
+
function callPanelCallbacks(panelsArray, layout, panelIdToLastNotifiedSizeMap) {
|
|
700
|
+
layout.forEach((size, index) => {
|
|
835
701
|
const panelData = panelsArray[index];
|
|
836
|
-
|
|
837
|
-
// Handle initial mount (when panels are registered too late to be in the panels array)
|
|
838
|
-
// The subsequent render+effects will handle the resize notification
|
|
839
|
-
return;
|
|
840
|
-
}
|
|
702
|
+
assert(panelData);
|
|
841
703
|
const {
|
|
842
704
|
callbacks,
|
|
843
705
|
constraints,
|
|
844
706
|
id: panelId
|
|
845
707
|
} = panelData;
|
|
846
708
|
const {
|
|
709
|
+
collapsedSize = 0,
|
|
847
710
|
collapsible
|
|
848
711
|
} = constraints;
|
|
849
|
-
const
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
};
|
|
853
|
-
const lastNotifiedMixedSizes = panelIdToLastNotifiedMixedSizesMap[panelId];
|
|
854
|
-
if (lastNotifiedMixedSizes == null || mixedSizes.sizePercentage !== lastNotifiedMixedSizes.sizePercentage || mixedSizes.sizePixels !== lastNotifiedMixedSizes.sizePixels) {
|
|
855
|
-
panelIdToLastNotifiedMixedSizesMap[panelId] = mixedSizes;
|
|
712
|
+
const lastNotifiedSize = panelIdToLastNotifiedSizeMap[panelId];
|
|
713
|
+
if (lastNotifiedSize == null || size !== lastNotifiedSize) {
|
|
714
|
+
panelIdToLastNotifiedSizeMap[panelId] = size;
|
|
856
715
|
const {
|
|
857
716
|
onCollapse,
|
|
858
717
|
onExpand,
|
|
859
718
|
onResize
|
|
860
719
|
} = callbacks;
|
|
861
720
|
if (onResize) {
|
|
862
|
-
onResize(
|
|
721
|
+
onResize(size, lastNotifiedSize);
|
|
863
722
|
}
|
|
864
723
|
if (collapsible && (onCollapse || onExpand)) {
|
|
865
|
-
|
|
866
|
-
const collapsedSize = (_getPercentageSizeFro = getPercentageSizeFromMixedSizes({
|
|
867
|
-
sizePercentage: constraints.collapsedSizePercentage,
|
|
868
|
-
sizePixels: constraints.collapsedSizePixels
|
|
869
|
-
}, groupSizePixels)) !== null && _getPercentageSizeFro !== void 0 ? _getPercentageSizeFro : 0;
|
|
870
|
-
const size = getPercentageSizeFromMixedSizes(mixedSizes, groupSizePixels);
|
|
871
|
-
if (onExpand && (lastNotifiedMixedSizes == null || lastNotifiedMixedSizes.sizePercentage === collapsedSize) && size !== collapsedSize) {
|
|
724
|
+
if (onExpand && (lastNotifiedSize == null || lastNotifiedSize === collapsedSize) && size !== collapsedSize) {
|
|
872
725
|
onExpand();
|
|
873
726
|
}
|
|
874
|
-
if (onCollapse && (
|
|
727
|
+
if (onCollapse && (lastNotifiedSize == null || lastNotifiedSize !== collapsedSize) && size === collapsedSize) {
|
|
875
728
|
onCollapse();
|
|
876
729
|
}
|
|
877
730
|
}
|
|
@@ -905,9 +758,10 @@ function computePanelFlexBoxStyle({
|
|
|
905
758
|
const size = layout[panelIndex];
|
|
906
759
|
let flexGrow;
|
|
907
760
|
if (panelData.length === 1) {
|
|
908
|
-
flexGrow = "
|
|
761
|
+
flexGrow = "1";
|
|
909
762
|
} else if (size == null) {
|
|
910
|
-
|
|
763
|
+
// Initial render (before panels have registered themselves)
|
|
764
|
+
flexGrow = "1";
|
|
911
765
|
} else {
|
|
912
766
|
flexGrow = size.toPrecision(precision);
|
|
913
767
|
}
|
|
@@ -1053,74 +907,39 @@ function savePanelGroupLayout(autoSaveId, panels, sizes, storage) {
|
|
|
1053
907
|
}
|
|
1054
908
|
}
|
|
1055
909
|
|
|
1056
|
-
function shouldMonitorPixelBasedConstraints(constraints) {
|
|
1057
|
-
return constraints.some(constraints => {
|
|
1058
|
-
return constraints.collapsedSizePixels !== undefined || constraints.maxSizePixels !== undefined || constraints.minSizePixels !== undefined;
|
|
1059
|
-
});
|
|
1060
|
-
}
|
|
1061
|
-
|
|
1062
910
|
function validatePanelConstraints({
|
|
1063
|
-
|
|
1064
|
-
panelConstraints,
|
|
911
|
+
panelConstraints: panelConstraintsArray,
|
|
1065
912
|
panelId,
|
|
1066
913
|
panelIndex
|
|
1067
914
|
}) {
|
|
1068
915
|
{
|
|
1069
916
|
const warnings = [];
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
} = panelConstraints[panelIndex];
|
|
1081
|
-
const conflictingUnits = [];
|
|
1082
|
-
if (collapsedSizePercentage != null && collapsedSizePixels != null) {
|
|
1083
|
-
conflictingUnits.push("collapsed size");
|
|
1084
|
-
}
|
|
1085
|
-
if (defaultSizePercentage != null && defaultSizePixels != null) {
|
|
1086
|
-
conflictingUnits.push("default size");
|
|
1087
|
-
}
|
|
1088
|
-
if (maxSizePercentage != null && maxSizePixels != null) {
|
|
1089
|
-
conflictingUnits.push("max size");
|
|
1090
|
-
}
|
|
1091
|
-
if (minSizePercentage != null && minSizePixels != null) {
|
|
1092
|
-
conflictingUnits.push("min size");
|
|
1093
|
-
}
|
|
1094
|
-
if (conflictingUnits.length > 0) {
|
|
1095
|
-
warnings.push(`should not specify both percentage and pixel units for: ${conflictingUnits.join(", ")}`);
|
|
1096
|
-
}
|
|
917
|
+
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
918
|
+
assert(panelConstraints);
|
|
919
|
+
const {
|
|
920
|
+
collapsedSize = 0,
|
|
921
|
+
defaultSize,
|
|
922
|
+
maxSize = 100,
|
|
923
|
+
minSize = 0
|
|
924
|
+
} = panelConstraints;
|
|
925
|
+
if (minSize > maxSize) {
|
|
926
|
+
warnings.push(`min size (${minSize}%) should not be greater than max size (${maxSize}%)`);
|
|
1097
927
|
}
|
|
1098
|
-
{
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
minSizePercentage
|
|
1104
|
-
} = computePercentagePanelConstraints(panelConstraints, panelIndex, groupSizePixels);
|
|
1105
|
-
if (minSizePercentage > maxSizePercentage) {
|
|
1106
|
-
warnings.push(`min size (${minSizePercentage}%) should not be greater than max size (${maxSizePercentage}%)`);
|
|
1107
|
-
}
|
|
1108
|
-
if (defaultSizePercentage != null) {
|
|
1109
|
-
if (defaultSizePercentage < 0) {
|
|
1110
|
-
warnings.push("default size should not be less than 0");
|
|
1111
|
-
} else if (defaultSizePercentage < minSizePercentage) {
|
|
1112
|
-
warnings.push("default size should not be less than min size");
|
|
1113
|
-
}
|
|
1114
|
-
if (defaultSizePercentage > 100) {
|
|
1115
|
-
warnings.push("default size should not be greater than 100");
|
|
1116
|
-
} else if (defaultSizePercentage > maxSizePercentage) {
|
|
1117
|
-
warnings.push("default size should not be greater than max size");
|
|
1118
|
-
}
|
|
928
|
+
if (defaultSize != null) {
|
|
929
|
+
if (defaultSize < 0) {
|
|
930
|
+
warnings.push("default size should not be less than 0");
|
|
931
|
+
} else if (defaultSize < minSize) {
|
|
932
|
+
warnings.push("default size should not be less than min size");
|
|
1119
933
|
}
|
|
1120
|
-
if (
|
|
1121
|
-
warnings.push("
|
|
934
|
+
if (defaultSize > 100) {
|
|
935
|
+
warnings.push("default size should not be greater than 100");
|
|
936
|
+
} else if (defaultSize > maxSize) {
|
|
937
|
+
warnings.push("default size should not be greater than max size");
|
|
1122
938
|
}
|
|
1123
939
|
}
|
|
940
|
+
if (collapsedSize > minSize) {
|
|
941
|
+
warnings.push("collapsed size should not be greater than min size");
|
|
942
|
+
}
|
|
1124
943
|
if (warnings.length > 0) {
|
|
1125
944
|
const name = panelId != null ? `Panel "${panelId}"` : "Panel";
|
|
1126
945
|
console.warn(`${name} has an invalid configuration:\n\n${warnings.join("\n")}`);
|
|
@@ -1132,20 +951,26 @@ function validatePanelConstraints({
|
|
|
1132
951
|
|
|
1133
952
|
// All units must be in percentages; pixel values should be pre-converted
|
|
1134
953
|
function validatePanelGroupLayout({
|
|
1135
|
-
groupSizePixels,
|
|
1136
954
|
layout: prevLayout,
|
|
1137
955
|
panelConstraints
|
|
1138
956
|
}) {
|
|
1139
957
|
const nextLayout = [...prevLayout];
|
|
958
|
+
const nextLayoutTotalSize = nextLayout.reduce((accumulated, current) => accumulated + current, 0);
|
|
1140
959
|
|
|
1141
960
|
// Validate layout expectations
|
|
1142
961
|
if (nextLayout.length !== panelConstraints.length) {
|
|
1143
962
|
throw Error(`Invalid ${panelConstraints.length} panel layout: ${nextLayout.map(size => `${size}%`).join(", ")}`);
|
|
1144
|
-
} else if (!fuzzyNumbersEqual(
|
|
963
|
+
} else if (!fuzzyNumbersEqual(nextLayoutTotalSize, 100)) {
|
|
1145
964
|
// This is not ideal so we should warn about it, but it may be recoverable in some cases
|
|
1146
965
|
// (especially if the amount is small)
|
|
1147
966
|
{
|
|
1148
|
-
console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}
|
|
967
|
+
console.warn(`WARNING: Invalid layout total size: ${nextLayout.map(size => `${size}%`).join(", ")}. Layout normalization will be applied.`);
|
|
968
|
+
}
|
|
969
|
+
for (let index = 0; index < panelConstraints.length; index++) {
|
|
970
|
+
const unsafeSize = nextLayout[index];
|
|
971
|
+
assert(unsafeSize != null);
|
|
972
|
+
const safeSize = 100 / nextLayoutTotalSize * unsafeSize;
|
|
973
|
+
nextLayout[index] = safeSize;
|
|
1149
974
|
}
|
|
1150
975
|
}
|
|
1151
976
|
let remainingSize = 0;
|
|
@@ -1153,8 +978,8 @@ function validatePanelGroupLayout({
|
|
|
1153
978
|
// First pass: Validate the proposed layout given each panel's constraints
|
|
1154
979
|
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1155
980
|
const unsafeSize = nextLayout[index];
|
|
981
|
+
assert(unsafeSize != null);
|
|
1156
982
|
const safeSize = resizePanel({
|
|
1157
|
-
groupSizePixels,
|
|
1158
983
|
panelConstraints,
|
|
1159
984
|
panelIndex: index,
|
|
1160
985
|
size: unsafeSize
|
|
@@ -1170,9 +995,9 @@ function validatePanelGroupLayout({
|
|
|
1170
995
|
if (!fuzzyNumbersEqual(remainingSize, 0)) {
|
|
1171
996
|
for (let index = 0; index < panelConstraints.length; index++) {
|
|
1172
997
|
const prevSize = nextLayout[index];
|
|
998
|
+
assert(prevSize != null);
|
|
1173
999
|
const unsafeSize = prevSize + remainingSize;
|
|
1174
1000
|
const safeSize = resizePanel({
|
|
1175
|
-
groupSizePixels,
|
|
1176
1001
|
panelConstraints,
|
|
1177
1002
|
panelIndex: index,
|
|
1178
1003
|
size: unsafeSize
|
|
@@ -1207,21 +1032,20 @@ function PanelGroupWithForwardedRef({
|
|
|
1207
1032
|
autoSaveId = null,
|
|
1208
1033
|
children,
|
|
1209
1034
|
className: classNameFromProps = "",
|
|
1210
|
-
dataAttributes,
|
|
1211
1035
|
direction,
|
|
1212
1036
|
forwardedRef,
|
|
1213
|
-
id: idFromProps,
|
|
1037
|
+
id: idFromProps = null,
|
|
1214
1038
|
onLayout = null,
|
|
1215
|
-
|
|
1216
|
-
keyboardResizeByPixels = null,
|
|
1039
|
+
keyboardResizeBy = null,
|
|
1217
1040
|
storage = defaultStorage,
|
|
1218
1041
|
style: styleFromProps,
|
|
1219
|
-
tagName: Type = "div"
|
|
1042
|
+
tagName: Type = "div",
|
|
1043
|
+
...rest
|
|
1220
1044
|
}) {
|
|
1221
1045
|
const groupId = useUniqueId(idFromProps);
|
|
1222
1046
|
const [dragState, setDragState] = useState(null);
|
|
1223
1047
|
const [layout, setLayout] = useState([]);
|
|
1224
|
-
const
|
|
1048
|
+
const panelIdToLastNotifiedSizeMapRef = useRef({});
|
|
1225
1049
|
const panelSizeBeforeCollapseRef = useRef(new Map());
|
|
1226
1050
|
const prevDeltaRef = useRef(0);
|
|
1227
1051
|
const committedValuesRef = useRef({
|
|
@@ -1229,8 +1053,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1229
1053
|
direction,
|
|
1230
1054
|
dragState,
|
|
1231
1055
|
id: groupId,
|
|
1232
|
-
|
|
1233
|
-
keyboardResizeByPixels,
|
|
1056
|
+
keyboardResizeBy,
|
|
1234
1057
|
onLayout,
|
|
1235
1058
|
storage
|
|
1236
1059
|
});
|
|
@@ -1246,33 +1069,20 @@ function PanelGroupWithForwardedRef({
|
|
|
1246
1069
|
useImperativeHandle(forwardedRef, () => ({
|
|
1247
1070
|
getId: () => committedValuesRef.current.id,
|
|
1248
1071
|
getLayout: () => {
|
|
1249
|
-
const {
|
|
1250
|
-
id: groupId
|
|
1251
|
-
} = committedValuesRef.current;
|
|
1252
1072
|
const {
|
|
1253
1073
|
layout
|
|
1254
1074
|
} = eagerValuesRef.current;
|
|
1255
|
-
|
|
1256
|
-
return layout.map(sizePercentage => {
|
|
1257
|
-
return {
|
|
1258
|
-
sizePercentage,
|
|
1259
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1260
|
-
};
|
|
1261
|
-
});
|
|
1075
|
+
return layout;
|
|
1262
1076
|
},
|
|
1263
|
-
setLayout:
|
|
1077
|
+
setLayout: unsafeLayout => {
|
|
1264
1078
|
const {
|
|
1265
|
-
id: groupId,
|
|
1266
1079
|
onLayout
|
|
1267
1080
|
} = committedValuesRef.current;
|
|
1268
1081
|
const {
|
|
1269
1082
|
layout: prevLayout,
|
|
1270
1083
|
panelDataArray
|
|
1271
1084
|
} = eagerValuesRef.current;
|
|
1272
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1273
|
-
const unsafeLayout = mixedSizes.map(mixedSize => getPercentageSizeFromMixedSizes(mixedSize, groupSizePixels));
|
|
1274
1085
|
const safeLayout = validatePanelGroupLayout({
|
|
1275
|
-
groupSizePixels,
|
|
1276
1086
|
layout: unsafeLayout,
|
|
1277
1087
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1278
1088
|
});
|
|
@@ -1280,16 +1090,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1280
1090
|
setLayout(safeLayout);
|
|
1281
1091
|
eagerValuesRef.current.layout = safeLayout;
|
|
1282
1092
|
if (onLayout) {
|
|
1283
|
-
onLayout(safeLayout
|
|
1284
|
-
sizePercentage,
|
|
1285
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1286
|
-
})));
|
|
1093
|
+
onLayout(safeLayout);
|
|
1287
1094
|
}
|
|
1288
|
-
callPanelCallbacks(
|
|
1095
|
+
callPanelCallbacks(panelDataArray, safeLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1289
1096
|
}
|
|
1290
1097
|
}
|
|
1291
1098
|
}), []);
|
|
1292
|
-
|
|
1293
1099
|
useWindowSplitterPanelGroupBehavior({
|
|
1294
1100
|
committedValuesRef,
|
|
1295
1101
|
eagerValuesRef,
|
|
@@ -1308,12 +1114,14 @@ function PanelGroupWithForwardedRef({
|
|
|
1308
1114
|
if (layout.length === 0 || layout.length !== panelDataArray.length) {
|
|
1309
1115
|
return;
|
|
1310
1116
|
}
|
|
1117
|
+
let debouncedSave = debounceMap[autoSaveId];
|
|
1311
1118
|
|
|
1312
1119
|
// Limit the frequency of localStorage updates.
|
|
1313
|
-
if (
|
|
1314
|
-
|
|
1120
|
+
if (debouncedSave == null) {
|
|
1121
|
+
debouncedSave = debounce(savePanelGroupLayout, LOCAL_STORAGE_DEBOUNCE_INTERVAL);
|
|
1122
|
+
debounceMap[autoSaveId] = debouncedSave;
|
|
1315
1123
|
}
|
|
1316
|
-
|
|
1124
|
+
debouncedSave(autoSaveId, panelDataArray, layout, storage);
|
|
1317
1125
|
}
|
|
1318
1126
|
}, [autoSaveId, layout, storage]);
|
|
1319
1127
|
|
|
@@ -1346,12 +1154,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1346
1154
|
}
|
|
1347
1155
|
if (!didLogPanelConstraintsWarning) {
|
|
1348
1156
|
const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
|
|
1349
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1350
1157
|
for (let panelIndex = 0; panelIndex < panelConstraints.length; panelIndex++) {
|
|
1158
|
+
const panelData = panelDataArray[panelIndex];
|
|
1159
|
+
assert(panelData);
|
|
1351
1160
|
const isValid = validatePanelConstraints({
|
|
1352
|
-
groupSizePixels,
|
|
1353
1161
|
panelConstraints,
|
|
1354
|
-
panelId:
|
|
1162
|
+
panelId: panelData.id,
|
|
1355
1163
|
panelIndex
|
|
1356
1164
|
});
|
|
1357
1165
|
if (!isValid) {
|
|
@@ -1375,20 +1183,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1375
1183
|
if (panelData.constraints.collapsible) {
|
|
1376
1184
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1377
1185
|
const {
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
pivotIndices
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
if (
|
|
1186
|
+
collapsedSize = 0,
|
|
1187
|
+
panelSize,
|
|
1188
|
+
pivotIndices
|
|
1189
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1190
|
+
assert(panelSize != null);
|
|
1191
|
+
if (panelSize !== collapsedSize) {
|
|
1384
1192
|
// Store size before collapse;
|
|
1385
1193
|
// This is the size that gets restored if the expand() API is used.
|
|
1386
|
-
panelSizeBeforeCollapseRef.current.set(panelData.id,
|
|
1194
|
+
panelSizeBeforeCollapseRef.current.set(panelData.id, panelSize);
|
|
1387
1195
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1388
|
-
const delta = isLastPanel ?
|
|
1196
|
+
const delta = isLastPanel ? panelSize - collapsedSize : collapsedSize - panelSize;
|
|
1389
1197
|
const nextLayout = adjustLayoutByDelta({
|
|
1390
1198
|
delta,
|
|
1391
|
-
groupSizePixels,
|
|
1392
1199
|
layout: prevLayout,
|
|
1393
1200
|
panelConstraints: panelConstraintsArray,
|
|
1394
1201
|
pivotIndices,
|
|
@@ -1398,16 +1205,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1398
1205
|
setLayout(nextLayout);
|
|
1399
1206
|
eagerValuesRef.current.layout = nextLayout;
|
|
1400
1207
|
if (onLayout) {
|
|
1401
|
-
onLayout(nextLayout
|
|
1402
|
-
sizePercentage,
|
|
1403
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1404
|
-
})));
|
|
1208
|
+
onLayout(nextLayout);
|
|
1405
1209
|
}
|
|
1406
|
-
callPanelCallbacks(
|
|
1210
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1407
1211
|
}
|
|
1408
1212
|
}
|
|
1409
1213
|
}
|
|
1410
|
-
}, [
|
|
1214
|
+
}, []);
|
|
1411
1215
|
|
|
1412
1216
|
// External APIs are safe to memoize via committed values ref
|
|
1413
1217
|
const expandPanel = useCallback(panelData => {
|
|
@@ -1421,21 +1225,19 @@ function PanelGroupWithForwardedRef({
|
|
|
1421
1225
|
if (panelData.constraints.collapsible) {
|
|
1422
1226
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1423
1227
|
const {
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
pivotIndices
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
if (panelSizePercentage === collapsedSizePercentage) {
|
|
1228
|
+
collapsedSize = 0,
|
|
1229
|
+
panelSize,
|
|
1230
|
+
minSize = 0,
|
|
1231
|
+
pivotIndices
|
|
1232
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1233
|
+
if (panelSize === collapsedSize) {
|
|
1431
1234
|
// Restore this panel to the size it was before it was collapsed, if possible.
|
|
1432
|
-
const
|
|
1433
|
-
const
|
|
1235
|
+
const prevPanelSize = panelSizeBeforeCollapseRef.current.get(panelData.id);
|
|
1236
|
+
const baseSize = prevPanelSize != null && prevPanelSize >= minSize ? prevPanelSize : minSize;
|
|
1434
1237
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1435
|
-
const delta = isLastPanel ?
|
|
1238
|
+
const delta = isLastPanel ? panelSize - baseSize : baseSize - panelSize;
|
|
1436
1239
|
const nextLayout = adjustLayoutByDelta({
|
|
1437
1240
|
delta,
|
|
1438
|
-
groupSizePixels,
|
|
1439
1241
|
layout: prevLayout,
|
|
1440
1242
|
panelConstraints: panelConstraintsArray,
|
|
1441
1243
|
pivotIndices,
|
|
@@ -1445,16 +1247,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1445
1247
|
setLayout(nextLayout);
|
|
1446
1248
|
eagerValuesRef.current.layout = nextLayout;
|
|
1447
1249
|
if (onLayout) {
|
|
1448
|
-
onLayout(nextLayout
|
|
1449
|
-
sizePercentage,
|
|
1450
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1451
|
-
})));
|
|
1250
|
+
onLayout(nextLayout);
|
|
1452
1251
|
}
|
|
1453
|
-
callPanelCallbacks(
|
|
1252
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1454
1253
|
}
|
|
1455
1254
|
}
|
|
1456
1255
|
}
|
|
1457
|
-
}, [
|
|
1256
|
+
}, []);
|
|
1458
1257
|
|
|
1459
1258
|
// External APIs are safe to memoize via committed values ref
|
|
1460
1259
|
const getPanelSize = useCallback(panelData => {
|
|
@@ -1463,14 +1262,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1463
1262
|
panelDataArray
|
|
1464
1263
|
} = eagerValuesRef.current;
|
|
1465
1264
|
const {
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
return
|
|
1470
|
-
|
|
1471
|
-
sizePixels: panelSizePixels
|
|
1472
|
-
};
|
|
1473
|
-
}, [groupId]);
|
|
1265
|
+
panelSize
|
|
1266
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1267
|
+
assert(panelSize != null);
|
|
1268
|
+
return panelSize;
|
|
1269
|
+
}, []);
|
|
1474
1270
|
|
|
1475
1271
|
// This API should never read from committedValuesRef
|
|
1476
1272
|
const getPanelStyle = useCallback(panelData => {
|
|
@@ -1493,12 +1289,12 @@ function PanelGroupWithForwardedRef({
|
|
|
1493
1289
|
panelDataArray
|
|
1494
1290
|
} = eagerValuesRef.current;
|
|
1495
1291
|
const {
|
|
1496
|
-
|
|
1292
|
+
collapsedSize,
|
|
1497
1293
|
collapsible,
|
|
1498
|
-
|
|
1499
|
-
} = panelDataHelper(
|
|
1500
|
-
return collapsible === true &&
|
|
1501
|
-
}, [
|
|
1294
|
+
panelSize
|
|
1295
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1296
|
+
return collapsible === true && panelSize === collapsedSize;
|
|
1297
|
+
}, []);
|
|
1502
1298
|
|
|
1503
1299
|
// External APIs are safe to memoize via committed values ref
|
|
1504
1300
|
const isPanelExpanded = useCallback(panelData => {
|
|
@@ -1507,12 +1303,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1507
1303
|
panelDataArray
|
|
1508
1304
|
} = eagerValuesRef.current;
|
|
1509
1305
|
const {
|
|
1510
|
-
|
|
1306
|
+
collapsedSize = 0,
|
|
1511
1307
|
collapsible,
|
|
1512
|
-
|
|
1513
|
-
} = panelDataHelper(
|
|
1514
|
-
|
|
1515
|
-
|
|
1308
|
+
panelSize
|
|
1309
|
+
} = panelDataHelper(panelDataArray, panelData, layout);
|
|
1310
|
+
assert(panelSize != null);
|
|
1311
|
+
return !collapsible || panelSize > collapsedSize;
|
|
1312
|
+
}, []);
|
|
1516
1313
|
const registerPanel = useCallback(panelData => {
|
|
1517
1314
|
const {
|
|
1518
1315
|
autoSaveId,
|
|
@@ -1552,18 +1349,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1552
1349
|
if (autoSaveId) {
|
|
1553
1350
|
unsafeLayout = loadPanelLayout(autoSaveId, panelDataArray, storage);
|
|
1554
1351
|
}
|
|
1555
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1556
|
-
if (groupSizePixels <= 0) {
|
|
1557
|
-
if (shouldMonitorPixelBasedConstraints(panelDataArray.map(({
|
|
1558
|
-
constraints
|
|
1559
|
-
}) => constraints))) {
|
|
1560
|
-
// Wait until the group has rendered a non-zero size before computing layout.
|
|
1561
|
-
return;
|
|
1562
|
-
}
|
|
1563
|
-
}
|
|
1564
1352
|
if (unsafeLayout == null) {
|
|
1565
1353
|
unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1566
|
-
groupSizePixels,
|
|
1567
1354
|
panelDataArray
|
|
1568
1355
|
});
|
|
1569
1356
|
}
|
|
@@ -1571,7 +1358,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1571
1358
|
// Validate even saved layouts in case something has changed since last render
|
|
1572
1359
|
// e.g. for pixel groups, this could be the size of the window
|
|
1573
1360
|
const nextLayout = validatePanelGroupLayout({
|
|
1574
|
-
groupSizePixels,
|
|
1575
1361
|
layout: unsafeLayout,
|
|
1576
1362
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1577
1363
|
});
|
|
@@ -1583,12 +1369,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1583
1369
|
eagerValuesRef.current.layout = nextLayout;
|
|
1584
1370
|
if (!areEqual(prevLayout, nextLayout)) {
|
|
1585
1371
|
if (onLayout) {
|
|
1586
|
-
onLayout(nextLayout
|
|
1587
|
-
sizePercentage,
|
|
1588
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1589
|
-
})));
|
|
1372
|
+
onLayout(nextLayout);
|
|
1590
1373
|
}
|
|
1591
|
-
callPanelCallbacks(
|
|
1374
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1592
1375
|
}
|
|
1593
1376
|
}, []);
|
|
1594
1377
|
const registerResizeHandle = useCallback(dragHandleId => {
|
|
@@ -1598,8 +1381,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1598
1381
|
direction,
|
|
1599
1382
|
dragState,
|
|
1600
1383
|
id: groupId,
|
|
1601
|
-
|
|
1602
|
-
keyboardResizeByPixels,
|
|
1384
|
+
keyboardResizeBy,
|
|
1603
1385
|
onLayout
|
|
1604
1386
|
} = committedValuesRef.current;
|
|
1605
1387
|
const {
|
|
@@ -1610,10 +1392,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1610
1392
|
initialLayout
|
|
1611
1393
|
} = dragState !== null && dragState !== void 0 ? dragState : {};
|
|
1612
1394
|
const pivotIndices = determinePivotIndices(groupId, dragHandleId);
|
|
1613
|
-
let delta = calculateDeltaPercentage(event,
|
|
1614
|
-
percentage: keyboardResizeByPercentage,
|
|
1615
|
-
pixels: keyboardResizeByPixels
|
|
1616
|
-
});
|
|
1395
|
+
let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
|
|
1617
1396
|
if (delta === 0) {
|
|
1618
1397
|
return;
|
|
1619
1398
|
}
|
|
@@ -1623,11 +1402,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1623
1402
|
if (document.dir === "rtl" && isHorizontal) {
|
|
1624
1403
|
delta = -delta;
|
|
1625
1404
|
}
|
|
1626
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1627
1405
|
const panelConstraints = panelDataArray.map(panelData => panelData.constraints);
|
|
1628
1406
|
const nextLayout = adjustLayoutByDelta({
|
|
1629
1407
|
delta,
|
|
1630
|
-
groupSizePixels,
|
|
1631
1408
|
layout: initialLayout !== null && initialLayout !== void 0 ? initialLayout : prevLayout,
|
|
1632
1409
|
panelConstraints,
|
|
1633
1410
|
pivotIndices,
|
|
@@ -1663,18 +1440,15 @@ function PanelGroupWithForwardedRef({
|
|
|
1663
1440
|
setLayout(nextLayout);
|
|
1664
1441
|
eagerValuesRef.current.layout = nextLayout;
|
|
1665
1442
|
if (onLayout) {
|
|
1666
|
-
onLayout(nextLayout
|
|
1667
|
-
sizePercentage,
|
|
1668
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1669
|
-
})));
|
|
1443
|
+
onLayout(nextLayout);
|
|
1670
1444
|
}
|
|
1671
|
-
callPanelCallbacks(
|
|
1445
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1672
1446
|
}
|
|
1673
1447
|
};
|
|
1674
1448
|
}, []);
|
|
1675
1449
|
|
|
1676
1450
|
// External APIs are safe to memoize via committed values ref
|
|
1677
|
-
const resizePanel = useCallback((panelData,
|
|
1451
|
+
const resizePanel = useCallback((panelData, unsafePanelSize) => {
|
|
1678
1452
|
const {
|
|
1679
1453
|
onLayout
|
|
1680
1454
|
} = committedValuesRef.current;
|
|
@@ -1684,16 +1458,14 @@ function PanelGroupWithForwardedRef({
|
|
|
1684
1458
|
} = eagerValuesRef.current;
|
|
1685
1459
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1686
1460
|
const {
|
|
1687
|
-
|
|
1688
|
-
panelSizePercentage,
|
|
1461
|
+
panelSize,
|
|
1689
1462
|
pivotIndices
|
|
1690
|
-
} = panelDataHelper(
|
|
1691
|
-
|
|
1463
|
+
} = panelDataHelper(panelDataArray, panelData, prevLayout);
|
|
1464
|
+
assert(panelSize != null);
|
|
1692
1465
|
const isLastPanel = panelDataArray.indexOf(panelData) === panelDataArray.length - 1;
|
|
1693
|
-
const delta = isLastPanel ?
|
|
1466
|
+
const delta = isLastPanel ? panelSize - unsafePanelSize : unsafePanelSize - panelSize;
|
|
1694
1467
|
const nextLayout = adjustLayoutByDelta({
|
|
1695
1468
|
delta,
|
|
1696
|
-
groupSizePixels,
|
|
1697
1469
|
layout: prevLayout,
|
|
1698
1470
|
panelConstraints: panelConstraintsArray,
|
|
1699
1471
|
pivotIndices,
|
|
@@ -1703,14 +1475,11 @@ function PanelGroupWithForwardedRef({
|
|
|
1703
1475
|
setLayout(nextLayout);
|
|
1704
1476
|
eagerValuesRef.current.layout = nextLayout;
|
|
1705
1477
|
if (onLayout) {
|
|
1706
|
-
onLayout(nextLayout
|
|
1707
|
-
sizePercentage,
|
|
1708
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1709
|
-
})));
|
|
1478
|
+
onLayout(nextLayout);
|
|
1710
1479
|
}
|
|
1711
|
-
callPanelCallbacks(
|
|
1480
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1712
1481
|
}
|
|
1713
|
-
}, [
|
|
1482
|
+
}, []);
|
|
1714
1483
|
const startDragging = useCallback((dragHandleId, event) => {
|
|
1715
1484
|
const {
|
|
1716
1485
|
direction
|
|
@@ -1719,6 +1488,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1719
1488
|
layout
|
|
1720
1489
|
} = eagerValuesRef.current;
|
|
1721
1490
|
const handleElement = getResizeHandleElement(dragHandleId);
|
|
1491
|
+
assert(handleElement);
|
|
1722
1492
|
const initialCursorPosition = getResizeEventCursorPosition(direction, event);
|
|
1723
1493
|
setDragState({
|
|
1724
1494
|
dragHandleId,
|
|
@@ -1737,7 +1507,6 @@ function PanelGroupWithForwardedRef({
|
|
|
1737
1507
|
});
|
|
1738
1508
|
const unregisterPanel = useCallback(panelData => {
|
|
1739
1509
|
const {
|
|
1740
|
-
id: groupId,
|
|
1741
1510
|
onLayout
|
|
1742
1511
|
} = committedValuesRef.current;
|
|
1743
1512
|
const {
|
|
@@ -1760,7 +1529,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1760
1529
|
const {
|
|
1761
1530
|
pendingPanelIds
|
|
1762
1531
|
} = unregisterPanelRef.current;
|
|
1763
|
-
const map =
|
|
1532
|
+
const map = panelIdToLastNotifiedSizeMapRef.current;
|
|
1764
1533
|
|
|
1765
1534
|
// TRICKY
|
|
1766
1535
|
// Strict effects mode
|
|
@@ -1786,16 +1555,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1786
1555
|
// The group is unmounting; skip layout calculation.
|
|
1787
1556
|
return;
|
|
1788
1557
|
}
|
|
1789
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1790
1558
|
let unsafeLayout = calculateUnsafeDefaultLayout({
|
|
1791
|
-
groupSizePixels,
|
|
1792
1559
|
panelDataArray
|
|
1793
1560
|
});
|
|
1794
1561
|
|
|
1795
1562
|
// Validate even saved layouts in case something has changed since last render
|
|
1796
1563
|
// e.g. for pixel groups, this could be the size of the window
|
|
1797
1564
|
const nextLayout = validatePanelGroupLayout({
|
|
1798
|
-
groupSizePixels,
|
|
1799
1565
|
layout: unsafeLayout,
|
|
1800
1566
|
panelConstraints: panelDataArray.map(panelData => panelData.constraints)
|
|
1801
1567
|
});
|
|
@@ -1803,12 +1569,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1803
1569
|
setLayout(nextLayout);
|
|
1804
1570
|
eagerValuesRef.current.layout = nextLayout;
|
|
1805
1571
|
if (onLayout) {
|
|
1806
|
-
onLayout(nextLayout
|
|
1807
|
-
sizePercentage,
|
|
1808
|
-
sizePixels: convertPercentageToPixels(sizePercentage, groupSizePixels)
|
|
1809
|
-
})));
|
|
1572
|
+
onLayout(nextLayout);
|
|
1810
1573
|
}
|
|
1811
|
-
callPanelCallbacks(
|
|
1574
|
+
callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
|
|
1812
1575
|
}
|
|
1813
1576
|
}, 0);
|
|
1814
1577
|
}, []);
|
|
@@ -1839,13 +1602,13 @@ function PanelGroupWithForwardedRef({
|
|
|
1839
1602
|
return createElement(PanelGroupContext.Provider, {
|
|
1840
1603
|
value: context
|
|
1841
1604
|
}, createElement(Type, {
|
|
1605
|
+
...rest,
|
|
1842
1606
|
children,
|
|
1843
1607
|
className: classNameFromProps,
|
|
1844
1608
|
style: {
|
|
1845
1609
|
...style,
|
|
1846
1610
|
...styleFromProps
|
|
1847
1611
|
},
|
|
1848
|
-
...dataAttributes,
|
|
1849
1612
|
// CSS selectors
|
|
1850
1613
|
"data-panel-group": "",
|
|
1851
1614
|
"data-panel-group-direction": direction,
|
|
@@ -1858,22 +1621,16 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
|
|
|
1858
1621
|
}));
|
|
1859
1622
|
PanelGroupWithForwardedRef.displayName = "PanelGroup";
|
|
1860
1623
|
PanelGroup.displayName = "forwardRef(PanelGroup)";
|
|
1861
|
-
function panelDataHelper(
|
|
1624
|
+
function panelDataHelper(panelDataArray, panelData, layout) {
|
|
1862
1625
|
const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
|
|
1863
1626
|
const panelIndex = panelDataArray.indexOf(panelData);
|
|
1864
1627
|
const panelConstraints = panelConstraintsArray[panelIndex];
|
|
1865
|
-
const groupSizePixels = calculateAvailablePanelSizeInPixels(groupId);
|
|
1866
|
-
const percentagePanelConstraints = computePercentagePanelConstraints(panelConstraintsArray, panelIndex, groupSizePixels);
|
|
1867
1628
|
const isLastPanel = panelIndex === panelDataArray.length - 1;
|
|
1868
1629
|
const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
|
|
1869
|
-
const
|
|
1870
|
-
const panelSizePixels = convertPercentageToPixels(panelSizePercentage, groupSizePixels);
|
|
1630
|
+
const panelSize = layout[panelIndex];
|
|
1871
1631
|
return {
|
|
1872
|
-
...
|
|
1873
|
-
|
|
1874
|
-
panelSizePercentage,
|
|
1875
|
-
panelSizePixels,
|
|
1876
|
-
groupSizePixels,
|
|
1632
|
+
...panelConstraints,
|
|
1633
|
+
panelSize,
|
|
1877
1634
|
pivotIndices
|
|
1878
1635
|
};
|
|
1879
1636
|
}
|
|
@@ -1913,6 +1670,7 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1913
1670
|
{
|
|
1914
1671
|
event.preventDefault();
|
|
1915
1672
|
const groupId = handleElement.getAttribute("data-panel-group-id");
|
|
1673
|
+
assert(groupId);
|
|
1916
1674
|
const handles = getResizeHandleElementsForGroup(groupId);
|
|
1917
1675
|
const index = getResizeHandleElementIndex(groupId, handleId);
|
|
1918
1676
|
assert(index !== null);
|
|
@@ -1933,12 +1691,13 @@ function useWindowSplitterResizeHandlerBehavior({
|
|
|
1933
1691
|
function PanelResizeHandle({
|
|
1934
1692
|
children = null,
|
|
1935
1693
|
className: classNameFromProps = "",
|
|
1936
|
-
dataAttributes,
|
|
1937
1694
|
disabled = false,
|
|
1938
|
-
id: idFromProps
|
|
1695
|
+
id: idFromProps,
|
|
1939
1696
|
onDragging,
|
|
1940
1697
|
style: styleFromProps = {},
|
|
1941
|
-
|
|
1698
|
+
tabIndex = 0,
|
|
1699
|
+
tagName: Type = "div",
|
|
1700
|
+
...rest
|
|
1942
1701
|
}) {
|
|
1943
1702
|
const divElementRef = useRef(null);
|
|
1944
1703
|
|
|
@@ -1968,8 +1727,9 @@ function PanelResizeHandle({
|
|
|
1968
1727
|
const stopDraggingAndBlur = useCallback(() => {
|
|
1969
1728
|
// Clicking on the drag handle shouldn't leave it focused;
|
|
1970
1729
|
// That would cause the PanelGroup to think it was still active.
|
|
1971
|
-
const
|
|
1972
|
-
|
|
1730
|
+
const divElement = divElementRef.current;
|
|
1731
|
+
assert(divElement);
|
|
1732
|
+
divElement.blur();
|
|
1973
1733
|
stopDragging();
|
|
1974
1734
|
const {
|
|
1975
1735
|
onDragging
|
|
@@ -1997,6 +1757,7 @@ function PanelResizeHandle({
|
|
|
1997
1757
|
resizeHandler(event);
|
|
1998
1758
|
};
|
|
1999
1759
|
const divElement = divElementRef.current;
|
|
1760
|
+
assert(divElement);
|
|
2000
1761
|
const targetDocument = divElement.ownerDocument;
|
|
2001
1762
|
targetDocument.body.addEventListener("contextmenu", stopDraggingAndBlur);
|
|
2002
1763
|
targetDocument.body.addEventListener("mousemove", onMove);
|
|
@@ -2024,15 +1785,18 @@ function PanelResizeHandle({
|
|
|
2024
1785
|
userSelect: "none"
|
|
2025
1786
|
};
|
|
2026
1787
|
return createElement(Type, {
|
|
1788
|
+
...rest,
|
|
2027
1789
|
children,
|
|
2028
1790
|
className: classNameFromProps,
|
|
2029
1791
|
onBlur: () => setIsFocused(false),
|
|
2030
1792
|
onFocus: () => setIsFocused(true),
|
|
2031
1793
|
onMouseDown: event => {
|
|
2032
1794
|
startDragging(resizeHandleId, event.nativeEvent);
|
|
1795
|
+
const callbacks = callbacksRef.current;
|
|
1796
|
+
assert(callbacks);
|
|
2033
1797
|
const {
|
|
2034
1798
|
onDragging
|
|
2035
|
-
} =
|
|
1799
|
+
} = callbacks;
|
|
2036
1800
|
if (onDragging) {
|
|
2037
1801
|
onDragging(true);
|
|
2038
1802
|
}
|
|
@@ -2042,9 +1806,11 @@ function PanelResizeHandle({
|
|
|
2042
1806
|
onTouchEnd: stopDraggingAndBlur,
|
|
2043
1807
|
onTouchStart: event => {
|
|
2044
1808
|
startDragging(resizeHandleId, event.nativeEvent);
|
|
1809
|
+
const callbacks = callbacksRef.current;
|
|
1810
|
+
assert(callbacks);
|
|
2045
1811
|
const {
|
|
2046
1812
|
onDragging
|
|
2047
|
-
} =
|
|
1813
|
+
} = callbacks;
|
|
2048
1814
|
if (onDragging) {
|
|
2049
1815
|
onDragging(true);
|
|
2050
1816
|
}
|
|
@@ -2055,8 +1821,7 @@ function PanelResizeHandle({
|
|
|
2055
1821
|
...style,
|
|
2056
1822
|
...styleFromProps
|
|
2057
1823
|
},
|
|
2058
|
-
tabIndex
|
|
2059
|
-
...dataAttributes,
|
|
1824
|
+
tabIndex,
|
|
2060
1825
|
// CSS selectors
|
|
2061
1826
|
"data-panel-group-direction": direction,
|
|
2062
1827
|
"data-panel-group-id": groupId,
|
|
@@ -2068,4 +1833,4 @@ function PanelResizeHandle({
|
|
|
2068
1833
|
}
|
|
2069
1834
|
PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
2070
1835
|
|
|
2071
|
-
export { Panel, PanelGroup, PanelResizeHandle };
|
|
1836
|
+
export { Panel, PanelGroup, PanelResizeHandle, assert };
|