react-resizable-panels 0.0.53 → 0.0.55
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/CHANGELOG.md +33 -0
- package/dist/declarations/src/Panel.d.ts +6 -5
- package/dist/declarations/src/PanelGroup.d.ts +8 -4
- package/dist/declarations/src/PanelResizeHandle.d.ts +5 -2
- package/dist/declarations/src/index.d.ts +9 -8
- package/dist/declarations/src/types.d.ts +4 -2
- package/dist/declarations/src/utils/group.d.ts +29 -0
- package/dist/react-resizable-panels.browser.cjs.js +1709 -0
- package/dist/react-resizable-panels.browser.cjs.mjs +6 -0
- package/dist/react-resizable-panels.browser.development.cjs.js +1764 -0
- package/dist/react-resizable-panels.browser.development.cjs.mjs +6 -0
- package/dist/react-resizable-panels.browser.development.esm.js +1737 -0
- package/dist/react-resizable-panels.browser.esm.js +1682 -0
- package/dist/react-resizable-panels.cjs.js +395 -126
- 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 +452 -135
- package/dist/react-resizable-panels.development.cjs.mjs +6 -0
- package/dist/react-resizable-panels.development.esm.js +452 -136
- package/dist/react-resizable-panels.development.node.cjs.js +1579 -0
- package/dist/react-resizable-panels.development.node.cjs.mjs +6 -0
- package/dist/react-resizable-panels.development.node.esm.js +1552 -0
- package/dist/react-resizable-panels.esm.js +395 -127
- package/dist/react-resizable-panels.esm.js.map +1 -0
- package/dist/react-resizable-panels.node.cjs.js +1523 -0
- package/dist/react-resizable-panels.node.cjs.mjs +6 -0
- package/dist/react-resizable-panels.node.esm.js +1496 -0
- package/package.json +26 -1
- package/src/Panel.ts +37 -37
- package/src/PanelContexts.ts +5 -6
- package/src/PanelGroup.ts +269 -121
- package/src/PanelResizeHandle.ts +1 -4
- package/src/env-conditions/browser.ts +1 -0
- package/src/env-conditions/node.ts +1 -0
- package/src/env-conditions/unknown.ts +1 -0
- package/src/hooks/useIsomorphicEffect.ts +2 -9
- package/src/hooks/useWindowSplitterBehavior.ts +14 -11
- package/src/index.ts +11 -3
- package/src/types.ts +3 -1
- package/src/utils/group.ts +327 -28
- package/src/utils/ssr.ts +0 -7
|
@@ -24,6 +24,8 @@ function _interopNamespace(e) {
|
|
|
24
24
|
|
|
25
25
|
var React__namespace = /*#__PURE__*/_interopNamespace(React);
|
|
26
26
|
|
|
27
|
+
const isBrowser = typeof window !== "undefined";
|
|
28
|
+
|
|
27
29
|
// This module exists to work around Webpack issue https://github.com/webpack/webpack/issues/14814
|
|
28
30
|
|
|
29
31
|
// eslint-disable-next-line no-restricted-imports
|
|
@@ -45,8 +47,7 @@ const {
|
|
|
45
47
|
// `toString()` prevents bundlers from trying to `import { useId } from 'react'`
|
|
46
48
|
const useId = React__namespace["useId".toString()];
|
|
47
49
|
|
|
48
|
-
const
|
|
49
|
-
const useIsomorphicLayoutEffect = canUseEffectHooks ? useLayoutEffect : () => {};
|
|
50
|
+
const useIsomorphicLayoutEffect = isBrowser ? useLayoutEffect : () => {};
|
|
50
51
|
|
|
51
52
|
const wrappedUseId = typeof useId === "function" ? useId : () => null;
|
|
52
53
|
let counter = 0;
|
|
@@ -60,10 +61,6 @@ function useUniqueId(idFromParams = null) {
|
|
|
60
61
|
}
|
|
61
62
|
|
|
62
63
|
const PanelGroupContext = createContext(null);
|
|
63
|
-
|
|
64
|
-
// Workaround for Parcel scope hoisting (which renames objects/functions).
|
|
65
|
-
// Casting to :any is required to avoid corrupting the generated TypeScript types.
|
|
66
|
-
// See github.com/parcel-bundler/parcel/issues/8724
|
|
67
64
|
PanelGroupContext.displayName = "PanelGroupContext";
|
|
68
65
|
|
|
69
66
|
function PanelWithForwardedRef({
|
|
@@ -74,8 +71,8 @@ function PanelWithForwardedRef({
|
|
|
74
71
|
defaultSize = null,
|
|
75
72
|
forwardedRef,
|
|
76
73
|
id: idFromProps = null,
|
|
77
|
-
maxSize =
|
|
78
|
-
minSize
|
|
74
|
+
maxSize = null,
|
|
75
|
+
minSize,
|
|
79
76
|
onCollapse = null,
|
|
80
77
|
onResize = null,
|
|
81
78
|
order = null,
|
|
@@ -90,11 +87,22 @@ function PanelWithForwardedRef({
|
|
|
90
87
|
const {
|
|
91
88
|
collapsePanel,
|
|
92
89
|
expandPanel,
|
|
90
|
+
getPanelSize,
|
|
93
91
|
getPanelStyle,
|
|
94
92
|
registerPanel,
|
|
95
93
|
resizePanel,
|
|
94
|
+
units,
|
|
96
95
|
unregisterPanel
|
|
97
96
|
} = context;
|
|
97
|
+
if (minSize == null) {
|
|
98
|
+
if (units === "percentages") {
|
|
99
|
+
// Mimics legacy default value for percentage based panel groups
|
|
100
|
+
minSize = 10;
|
|
101
|
+
} else {
|
|
102
|
+
// There is no meaningful minimum pixel default we can provide
|
|
103
|
+
minSize = 0;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
98
106
|
|
|
99
107
|
// Use a ref to guard against users passing inline props
|
|
100
108
|
const callbacksRef = useRef({
|
|
@@ -105,22 +113,6 @@ function PanelWithForwardedRef({
|
|
|
105
113
|
callbacksRef.current.onCollapse = onCollapse;
|
|
106
114
|
callbacksRef.current.onResize = onResize;
|
|
107
115
|
});
|
|
108
|
-
|
|
109
|
-
// Basic props validation
|
|
110
|
-
if (minSize < 0 || minSize > 100) {
|
|
111
|
-
throw Error(`Panel minSize must be between 0 and 100, but was ${minSize}`);
|
|
112
|
-
} else if (maxSize < 0 || maxSize > 100) {
|
|
113
|
-
throw Error(`Panel maxSize must be between 0 and 100, but was ${maxSize}`);
|
|
114
|
-
} else {
|
|
115
|
-
if (defaultSize !== null) {
|
|
116
|
-
if (defaultSize < 0 || defaultSize > 100) {
|
|
117
|
-
throw Error(`Panel defaultSize must be between 0 and 100, but was ${defaultSize}`);
|
|
118
|
-
} else if (minSize > defaultSize && !collapsible) {
|
|
119
|
-
console.error(`Panel minSize ${minSize} cannot be greater than defaultSize ${defaultSize}`);
|
|
120
|
-
defaultSize = minSize;
|
|
121
|
-
}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
116
|
const style = getPanelStyle(panelId, defaultSize);
|
|
125
117
|
const committedValuesRef = useRef({
|
|
126
118
|
size: parseSizeFromStyle(style)
|
|
@@ -131,6 +123,7 @@ function PanelWithForwardedRef({
|
|
|
131
123
|
collapsible,
|
|
132
124
|
defaultSize,
|
|
133
125
|
id: panelId,
|
|
126
|
+
idWasAutoGenerated: idFromProps == null,
|
|
134
127
|
maxSize,
|
|
135
128
|
minSize,
|
|
136
129
|
order
|
|
@@ -142,6 +135,7 @@ function PanelWithForwardedRef({
|
|
|
142
135
|
panelDataRef.current.collapsible = collapsible;
|
|
143
136
|
panelDataRef.current.defaultSize = defaultSize;
|
|
144
137
|
panelDataRef.current.id = panelId;
|
|
138
|
+
panelDataRef.current.idWasAutoGenerated = idFromProps == null;
|
|
145
139
|
panelDataRef.current.maxSize = maxSize;
|
|
146
140
|
panelDataRef.current.minSize = minSize;
|
|
147
141
|
panelDataRef.current.order = order;
|
|
@@ -158,11 +152,14 @@ function PanelWithForwardedRef({
|
|
|
158
152
|
getCollapsed() {
|
|
159
153
|
return committedValuesRef.current.size === 0;
|
|
160
154
|
},
|
|
161
|
-
|
|
162
|
-
return
|
|
155
|
+
getId() {
|
|
156
|
+
return panelId;
|
|
163
157
|
},
|
|
164
|
-
|
|
165
|
-
|
|
158
|
+
getSize(units) {
|
|
159
|
+
return getPanelSize(panelId, units);
|
|
160
|
+
},
|
|
161
|
+
resize: (percentage, units) => resizePanel(panelId, percentage, units)
|
|
162
|
+
}), [collapsePanel, expandPanel, getPanelSize, panelId, resizePanel]);
|
|
166
163
|
return createElement(Type, {
|
|
167
164
|
children,
|
|
168
165
|
className: classNameFromProps,
|
|
@@ -181,10 +178,6 @@ const Panel = forwardRef((props, ref) => createElement(PanelWithForwardedRef, {
|
|
|
181
178
|
...props,
|
|
182
179
|
forwardedRef: ref
|
|
183
180
|
}));
|
|
184
|
-
|
|
185
|
-
// Workaround for Parcel scope hoisting (which renames objects/functions).
|
|
186
|
-
// Casting to :any is required to avoid corrupting the generated TypeScript types.
|
|
187
|
-
// See github.com/parcel-bundler/parcel/issues/8724
|
|
188
181
|
PanelWithForwardedRef.displayName = "Panel";
|
|
189
182
|
Panel.displayName = "forwardRef(Panel)";
|
|
190
183
|
|
|
@@ -202,7 +195,13 @@ function parseSizeFromStyle(style) {
|
|
|
202
195
|
|
|
203
196
|
const PRECISION = 10;
|
|
204
197
|
|
|
205
|
-
function adjustByDelta(event,
|
|
198
|
+
function adjustByDelta(event, committedValues, idBefore, idAfter, deltaPixels, prevSizes, panelSizeBeforeCollapse, initialDragState) {
|
|
199
|
+
const {
|
|
200
|
+
id: groupId,
|
|
201
|
+
panels,
|
|
202
|
+
units
|
|
203
|
+
} = committedValues;
|
|
204
|
+
const groupSizePixels = units === "pixels" ? getAvailableGroupSizePixels(groupId) : NaN;
|
|
206
205
|
const {
|
|
207
206
|
sizes: initialSizes
|
|
208
207
|
} = initialDragState || {};
|
|
@@ -210,9 +209,6 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
210
209
|
// If we're resizing by mouse or touch, use the initial sizes as a base.
|
|
211
210
|
// This has the benefit of causing force-collapsed panels to spring back open if drag is reversed.
|
|
212
211
|
const baseSizes = initialSizes || prevSizes;
|
|
213
|
-
if (delta === 0) {
|
|
214
|
-
return baseSizes;
|
|
215
|
-
}
|
|
216
212
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
217
213
|
const nextSizes = baseSizes.concat();
|
|
218
214
|
let deltaApplied = 0;
|
|
@@ -227,11 +223,11 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
227
223
|
|
|
228
224
|
// Max-bounds check the panel being expanded first.
|
|
229
225
|
{
|
|
230
|
-
const pivotId =
|
|
226
|
+
const pivotId = deltaPixels < 0 ? idAfter : idBefore;
|
|
231
227
|
const index = panelsArray.findIndex(panel => panel.current.id === pivotId);
|
|
232
228
|
const panel = panelsArray[index];
|
|
233
229
|
const baseSize = baseSizes[index];
|
|
234
|
-
const nextSize = safeResizePanel(panel, Math.abs(
|
|
230
|
+
const nextSize = safeResizePanel(units, groupSizePixels, panel, baseSize, baseSize + Math.abs(deltaPixels), event);
|
|
235
231
|
if (baseSize === nextSize) {
|
|
236
232
|
// If there's no room for the pivot panel to grow, we can ignore this drag update.
|
|
237
233
|
return baseSizes;
|
|
@@ -239,29 +235,29 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
239
235
|
if (nextSize === 0 && baseSize > 0) {
|
|
240
236
|
panelSizeBeforeCollapse.set(pivotId, baseSize);
|
|
241
237
|
}
|
|
242
|
-
|
|
238
|
+
deltaPixels = deltaPixels < 0 ? baseSize - nextSize : nextSize - baseSize;
|
|
243
239
|
}
|
|
244
240
|
}
|
|
245
|
-
let pivotId =
|
|
241
|
+
let pivotId = deltaPixels < 0 ? idBefore : idAfter;
|
|
246
242
|
let index = panelsArray.findIndex(panel => panel.current.id === pivotId);
|
|
247
243
|
while (true) {
|
|
248
244
|
const panel = panelsArray[index];
|
|
249
245
|
const baseSize = baseSizes[index];
|
|
250
|
-
const deltaRemaining = Math.abs(
|
|
251
|
-
const nextSize = safeResizePanel(panel,
|
|
246
|
+
const deltaRemaining = Math.abs(deltaPixels) - Math.abs(deltaApplied);
|
|
247
|
+
const nextSize = safeResizePanel(units, groupSizePixels, panel, baseSize, baseSize - deltaRemaining, event);
|
|
252
248
|
if (baseSize !== nextSize) {
|
|
253
249
|
if (nextSize === 0 && baseSize > 0) {
|
|
254
250
|
panelSizeBeforeCollapse.set(panel.current.id, baseSize);
|
|
255
251
|
}
|
|
256
252
|
deltaApplied += baseSize - nextSize;
|
|
257
253
|
nextSizes[index] = nextSize;
|
|
258
|
-
if (deltaApplied.toPrecision(PRECISION).localeCompare(Math.abs(
|
|
254
|
+
if (deltaApplied.toPrecision(PRECISION).localeCompare(Math.abs(deltaPixels).toPrecision(PRECISION), undefined, {
|
|
259
255
|
numeric: true
|
|
260
256
|
}) >= 0) {
|
|
261
257
|
break;
|
|
262
258
|
}
|
|
263
259
|
}
|
|
264
|
-
if (
|
|
260
|
+
if (deltaPixels < 0) {
|
|
265
261
|
if (--index < 0) {
|
|
266
262
|
break;
|
|
267
263
|
}
|
|
@@ -279,7 +275,7 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
279
275
|
}
|
|
280
276
|
|
|
281
277
|
// Adjust the pivot panel before, but only by the amount that surrounding panels were able to shrink/contract.
|
|
282
|
-
pivotId =
|
|
278
|
+
pivotId = deltaPixels < 0 ? idAfter : idBefore;
|
|
283
279
|
index = panelsArray.findIndex(panel => panel.current.id === pivotId);
|
|
284
280
|
nextSizes[index] = baseSizes[index] + deltaApplied;
|
|
285
281
|
return nextSizes;
|
|
@@ -318,6 +314,89 @@ function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
|
318
314
|
}
|
|
319
315
|
});
|
|
320
316
|
}
|
|
317
|
+
function calculateDefaultLayout({
|
|
318
|
+
groupId,
|
|
319
|
+
panels,
|
|
320
|
+
units
|
|
321
|
+
}) {
|
|
322
|
+
const groupSizePixels = units === "pixels" ? getAvailableGroupSizePixels(groupId) : NaN;
|
|
323
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
324
|
+
const sizes = Array(panelsArray.length);
|
|
325
|
+
let numPanelsWithSizes = 0;
|
|
326
|
+
let remainingSize = 100;
|
|
327
|
+
|
|
328
|
+
// Assigning default sizes requires a couple of passes:
|
|
329
|
+
// First, all panels with defaultSize should be set as-is
|
|
330
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
331
|
+
const panel = panelsArray[index];
|
|
332
|
+
const {
|
|
333
|
+
defaultSize
|
|
334
|
+
} = panel.current;
|
|
335
|
+
if (defaultSize != null) {
|
|
336
|
+
numPanelsWithSizes++;
|
|
337
|
+
sizes[index] = units === "pixels" ? defaultSize / groupSizePixels * 100 : defaultSize;
|
|
338
|
+
remainingSize -= sizes[index];
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
// Remaining total size should be distributed evenly between panels
|
|
343
|
+
// This may require two passes, depending on min/max constraints
|
|
344
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
345
|
+
const panel = panelsArray[index];
|
|
346
|
+
let {
|
|
347
|
+
defaultSize,
|
|
348
|
+
id,
|
|
349
|
+
maxSize,
|
|
350
|
+
minSize
|
|
351
|
+
} = panel.current;
|
|
352
|
+
if (defaultSize != null) {
|
|
353
|
+
continue;
|
|
354
|
+
}
|
|
355
|
+
if (units === "pixels") {
|
|
356
|
+
minSize = minSize / groupSizePixels * 100;
|
|
357
|
+
if (maxSize != null) {
|
|
358
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
359
|
+
}
|
|
360
|
+
}
|
|
361
|
+
const remainingPanels = panelsArray.length - numPanelsWithSizes;
|
|
362
|
+
const size = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, remainingSize / remainingPanels));
|
|
363
|
+
sizes[index] = size;
|
|
364
|
+
numPanelsWithSizes++;
|
|
365
|
+
remainingSize -= size;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
// If there is additional, left over space, assign it to any panel(s) that permits it
|
|
369
|
+
// (It's not worth taking multiple additional passes to evenly distribute)
|
|
370
|
+
if (remainingSize !== 0) {
|
|
371
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
372
|
+
const panel = panelsArray[index];
|
|
373
|
+
let {
|
|
374
|
+
maxSize,
|
|
375
|
+
minSize
|
|
376
|
+
} = panel.current;
|
|
377
|
+
if (units === "pixels") {
|
|
378
|
+
minSize = minSize / groupSizePixels * 100;
|
|
379
|
+
if (maxSize != null) {
|
|
380
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
const size = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, sizes[index] + remainingSize));
|
|
384
|
+
if (size !== sizes[index]) {
|
|
385
|
+
remainingSize -= size - sizes[index];
|
|
386
|
+
sizes[index] = size;
|
|
387
|
+
|
|
388
|
+
// Fuzzy comparison to account for imprecise floating point math
|
|
389
|
+
if (Math.abs(remainingSize).toFixed(3) === "0.000") {
|
|
390
|
+
break;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
// Finally, if there is still left-over size, log an error
|
|
397
|
+
if (Math.abs(remainingSize).toFixed(3) !== "0.000") ;
|
|
398
|
+
return sizes;
|
|
399
|
+
}
|
|
321
400
|
function getBeforeAndAfterIds(id, panelsArray) {
|
|
322
401
|
if (panelsArray.length < 2) {
|
|
323
402
|
return [null, null];
|
|
@@ -331,6 +410,23 @@ function getBeforeAndAfterIds(id, panelsArray) {
|
|
|
331
410
|
const idAfter = isLastPanel ? id : panelsArray[index + 1].current.id;
|
|
332
411
|
return [idBefore, idAfter];
|
|
333
412
|
}
|
|
413
|
+
function getAvailableGroupSizePixels(groupId) {
|
|
414
|
+
const panelGroupElement = getPanelGroup(groupId);
|
|
415
|
+
if (panelGroupElement == null) {
|
|
416
|
+
return NaN;
|
|
417
|
+
}
|
|
418
|
+
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
419
|
+
const resizeHandles = getResizeHandlesForGroup(groupId);
|
|
420
|
+
if (direction === "horizontal") {
|
|
421
|
+
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
422
|
+
return accumulated + handle.offsetWidth;
|
|
423
|
+
}, 0);
|
|
424
|
+
} else {
|
|
425
|
+
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
426
|
+
return accumulated + handle.offsetHeight;
|
|
427
|
+
}, 0);
|
|
428
|
+
}
|
|
429
|
+
}
|
|
334
430
|
|
|
335
431
|
// This method returns a number between 1 and 100 representing
|
|
336
432
|
// the % of the group's overall space this panel should occupy.
|
|
@@ -401,18 +497,24 @@ function panelsMapToSortedArray(panels) {
|
|
|
401
497
|
}
|
|
402
498
|
});
|
|
403
499
|
}
|
|
404
|
-
function safeResizePanel(
|
|
405
|
-
|
|
406
|
-
const {
|
|
500
|
+
function safeResizePanel(units, groupSizePixels, panel, prevSize, nextSize, event = null) {
|
|
501
|
+
let {
|
|
407
502
|
collapsedSize,
|
|
408
503
|
collapsible,
|
|
409
504
|
maxSize,
|
|
410
505
|
minSize
|
|
411
506
|
} = panel.current;
|
|
507
|
+
if (units === "pixels") {
|
|
508
|
+
collapsedSize = collapsedSize / groupSizePixels * 100;
|
|
509
|
+
if (maxSize != null) {
|
|
510
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
511
|
+
}
|
|
512
|
+
minSize = minSize / groupSizePixels * 100;
|
|
513
|
+
}
|
|
412
514
|
if (collapsible) {
|
|
413
515
|
if (prevSize > collapsedSize) {
|
|
414
516
|
// Mimic VS COde behavior; collapse a panel if it's smaller than half of its min-size
|
|
415
|
-
if (
|
|
517
|
+
if (nextSize <= minSize / 2 + collapsedSize) {
|
|
416
518
|
return collapsedSize;
|
|
417
519
|
}
|
|
418
520
|
} else {
|
|
@@ -421,14 +523,97 @@ function safeResizePanel(panel, delta, prevSize, event) {
|
|
|
421
523
|
// Keyboard events should expand a collapsed panel to the min size,
|
|
422
524
|
// but mouse events should wait until the panel has reached its min size
|
|
423
525
|
// to avoid a visual flickering when dragging between collapsed and min size.
|
|
424
|
-
if (
|
|
526
|
+
if (nextSize < minSize) {
|
|
425
527
|
return collapsedSize;
|
|
426
528
|
}
|
|
427
529
|
}
|
|
428
530
|
}
|
|
429
531
|
}
|
|
430
|
-
|
|
431
|
-
|
|
532
|
+
return Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, nextSize));
|
|
533
|
+
}
|
|
534
|
+
function validatePanelProps(units, panelData) {
|
|
535
|
+
const {
|
|
536
|
+
collapsible,
|
|
537
|
+
defaultSize,
|
|
538
|
+
maxSize,
|
|
539
|
+
minSize
|
|
540
|
+
} = panelData.current;
|
|
541
|
+
|
|
542
|
+
// Basic props validation
|
|
543
|
+
if (minSize < 0 || units === "percentages" && minSize > 100) {
|
|
544
|
+
panelData.current.minSize = 0;
|
|
545
|
+
}
|
|
546
|
+
if (maxSize != null) {
|
|
547
|
+
if (maxSize < 0 || units === "percentages" && maxSize > 100) {
|
|
548
|
+
panelData.current.maxSize = null;
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
if (defaultSize !== null) {
|
|
552
|
+
if (defaultSize < 0 || units === "percentages" && defaultSize > 100) {
|
|
553
|
+
panelData.current.defaultSize = null;
|
|
554
|
+
} else if (defaultSize < minSize && !collapsible) {
|
|
555
|
+
panelData.current.defaultSize = minSize;
|
|
556
|
+
} else if (maxSize != null && defaultSize > maxSize) {
|
|
557
|
+
panelData.current.defaultSize = maxSize;
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
function validatePanelGroupLayout({
|
|
562
|
+
groupId,
|
|
563
|
+
panels,
|
|
564
|
+
nextSizes,
|
|
565
|
+
prevSizes,
|
|
566
|
+
units
|
|
567
|
+
}) {
|
|
568
|
+
// Clone because this method modifies
|
|
569
|
+
nextSizes = [...nextSizes];
|
|
570
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
571
|
+
const groupSizePixels = units === "pixels" ? getAvailableGroupSizePixels(groupId) : NaN;
|
|
572
|
+
let remainingSize = 0;
|
|
573
|
+
|
|
574
|
+
// First, check all of the proposed sizes against the min/max constraints
|
|
575
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
576
|
+
const panel = panelsArray[index];
|
|
577
|
+
const prevSize = prevSizes[index];
|
|
578
|
+
const nextSize = nextSizes[index];
|
|
579
|
+
const safeNextSize = safeResizePanel(units, groupSizePixels, panel, prevSize, nextSize);
|
|
580
|
+
if (nextSize != safeNextSize) {
|
|
581
|
+
remainingSize += nextSize - safeNextSize;
|
|
582
|
+
nextSizes[index] = safeNextSize;
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
// If there is additional, left over space, assign it to any panel(s) that permits it
|
|
587
|
+
// (It's not worth taking multiple additional passes to evenly distribute)
|
|
588
|
+
if (remainingSize.toFixed(3) !== "0.000") {
|
|
589
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
590
|
+
const panel = panelsArray[index];
|
|
591
|
+
let {
|
|
592
|
+
maxSize,
|
|
593
|
+
minSize
|
|
594
|
+
} = panel.current;
|
|
595
|
+
if (units === "pixels") {
|
|
596
|
+
minSize = minSize / groupSizePixels * 100;
|
|
597
|
+
if (maxSize != null) {
|
|
598
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
const size = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, nextSizes[index] + remainingSize));
|
|
602
|
+
if (size !== nextSizes[index]) {
|
|
603
|
+
remainingSize -= size - nextSizes[index];
|
|
604
|
+
nextSizes[index] = size;
|
|
605
|
+
|
|
606
|
+
// Fuzzy comparison to account for imprecise floating point math
|
|
607
|
+
if (Math.abs(remainingSize).toFixed(3) === "0.000") {
|
|
608
|
+
break;
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
// If we still have remainder, the requested layout wasn't valid and we should warn about it
|
|
615
|
+
if (remainingSize.toFixed(3) !== "0.000") ;
|
|
616
|
+
return nextSizes;
|
|
432
617
|
}
|
|
433
618
|
|
|
434
619
|
function assert(expectedCondition, message = "Assertion failed!") {
|
|
@@ -454,6 +639,7 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
454
639
|
panels
|
|
455
640
|
} = committedValuesRef.current;
|
|
456
641
|
const groupElement = getPanelGroup(groupId);
|
|
642
|
+
assert(groupElement != null, `No group found for id "${groupId}"`);
|
|
457
643
|
const {
|
|
458
644
|
height,
|
|
459
645
|
width
|
|
@@ -466,23 +652,28 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
466
652
|
if (idBefore == null || idAfter == null) {
|
|
467
653
|
return () => {};
|
|
468
654
|
}
|
|
469
|
-
let
|
|
470
|
-
let
|
|
655
|
+
let currentMinSize = 0;
|
|
656
|
+
let currentMaxSize = 100;
|
|
471
657
|
let totalMinSize = 0;
|
|
472
658
|
let totalMaxSize = 0;
|
|
473
659
|
|
|
474
660
|
// A panel's effective min/max sizes also need to account for other panel's sizes.
|
|
475
661
|
panelsArray.forEach(panelData => {
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
662
|
+
const {
|
|
663
|
+
id,
|
|
664
|
+
maxSize,
|
|
665
|
+
minSize
|
|
666
|
+
} = panelData.current;
|
|
667
|
+
if (id === idBefore) {
|
|
668
|
+
currentMinSize = minSize;
|
|
669
|
+
currentMaxSize = maxSize != null ? maxSize : 100;
|
|
479
670
|
} else {
|
|
480
|
-
totalMinSize +=
|
|
481
|
-
totalMaxSize +=
|
|
671
|
+
totalMinSize += minSize;
|
|
672
|
+
totalMaxSize += maxSize != null ? maxSize : 100;
|
|
482
673
|
}
|
|
483
674
|
});
|
|
484
|
-
const ariaValueMax = Math.min(
|
|
485
|
-
const ariaValueMin = Math.max(
|
|
675
|
+
const ariaValueMax = Math.min(currentMaxSize, 100 - totalMinSize);
|
|
676
|
+
const ariaValueMin = Math.max(currentMinSize, (panelsArray.length - 1) * 100 - totalMaxSize);
|
|
486
677
|
const flexGrow = getFlexGrow(panels, idBefore, sizes);
|
|
487
678
|
handle.setAttribute("aria-valuemax", "" + Math.round(ariaValueMax));
|
|
488
679
|
handle.setAttribute("aria-valuemin", "" + Math.round(ariaValueMin));
|
|
@@ -506,7 +697,7 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
506
697
|
} else {
|
|
507
698
|
delta = -(direction === "horizontal" ? width : height);
|
|
508
699
|
}
|
|
509
|
-
const nextSizes = adjustByDelta(event,
|
|
700
|
+
const nextSizes = adjustByDelta(event, committedValuesRef.current, idBefore, idAfter, delta, sizes, panelSizeBeforeCollapse.current, null);
|
|
510
701
|
if (sizes !== nextSizes) {
|
|
511
702
|
setSizes(nextSizes);
|
|
512
703
|
}
|
|
@@ -821,9 +1012,6 @@ const defaultStorage = {
|
|
|
821
1012
|
// * dragHandleRect, sizes:
|
|
822
1013
|
// When resizing is done via mouse/touch event– some initial state is stored
|
|
823
1014
|
// so that any panels that contract will also expand if drag direction is reversed.
|
|
824
|
-
// TODO
|
|
825
|
-
// Within an active drag, remember original positions to refine more easily on expand.
|
|
826
|
-
// Look at what the Chrome devtools Sources does.
|
|
827
1015
|
function PanelGroupWithForwardedRef({
|
|
828
1016
|
autoSaveId,
|
|
829
1017
|
children = null,
|
|
@@ -835,7 +1023,8 @@ function PanelGroupWithForwardedRef({
|
|
|
835
1023
|
onLayout,
|
|
836
1024
|
storage = defaultStorage,
|
|
837
1025
|
style: styleFromProps = {},
|
|
838
|
-
tagName: Type = "div"
|
|
1026
|
+
tagName: Type = "div",
|
|
1027
|
+
units = "percentages"
|
|
839
1028
|
}) {
|
|
840
1029
|
const groupId = useUniqueId(idFromProps);
|
|
841
1030
|
const [activeHandleId, setActiveHandleId] = useState(null);
|
|
@@ -845,6 +1034,12 @@ function PanelGroupWithForwardedRef({
|
|
|
845
1034
|
// We store the initial Panel sizes in this ref, and apply move deltas to them instead of to the current sizes.
|
|
846
1035
|
// This has the benefit of causing force-collapsed panels to spring back open if drag is reversed.
|
|
847
1036
|
const initialDragStateRef = useRef(null);
|
|
1037
|
+
useRef({
|
|
1038
|
+
didLogDefaultSizeWarning: false,
|
|
1039
|
+
didLogIdAndOrderWarning: false,
|
|
1040
|
+
didLogInvalidLayoutWarning: false,
|
|
1041
|
+
prevPanelIds: []
|
|
1042
|
+
});
|
|
848
1043
|
|
|
849
1044
|
// Use a ref to guard against users passing inline props
|
|
850
1045
|
const callbacksRef = useRef({
|
|
@@ -865,32 +1060,58 @@ function PanelGroupWithForwardedRef({
|
|
|
865
1060
|
// Store committed values to avoid unnecessarily re-running memoization/effects functions.
|
|
866
1061
|
const committedValuesRef = useRef({
|
|
867
1062
|
direction,
|
|
1063
|
+
id: groupId,
|
|
868
1064
|
panels,
|
|
869
|
-
sizes
|
|
1065
|
+
sizes,
|
|
1066
|
+
units
|
|
870
1067
|
});
|
|
871
1068
|
useImperativeHandle(forwardedRef, () => ({
|
|
872
|
-
|
|
1069
|
+
getId: () => groupId,
|
|
1070
|
+
getLayout: unitsFromParams => {
|
|
873
1071
|
const {
|
|
874
|
-
sizes
|
|
1072
|
+
sizes,
|
|
1073
|
+
units: unitsFromProps
|
|
875
1074
|
} = committedValuesRef.current;
|
|
876
|
-
|
|
1075
|
+
const units = unitsFromParams ?? unitsFromProps;
|
|
1076
|
+
if (units === "pixels") {
|
|
1077
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1078
|
+
return sizes.map(size => size / 100 * groupSizePixels);
|
|
1079
|
+
} else {
|
|
1080
|
+
return sizes;
|
|
1081
|
+
}
|
|
877
1082
|
},
|
|
878
|
-
setLayout: sizes => {
|
|
879
|
-
const total = sizes.reduce((accumulated, current) => accumulated + current, 0);
|
|
880
|
-
assert(total === 100, "Panel sizes must add up to 100%");
|
|
1083
|
+
setLayout: (sizes, unitsFromParams) => {
|
|
881
1084
|
const {
|
|
882
|
-
|
|
1085
|
+
id: groupId,
|
|
1086
|
+
panels,
|
|
1087
|
+
sizes: prevSizes,
|
|
1088
|
+
units
|
|
883
1089
|
} = committedValuesRef.current;
|
|
1090
|
+
if ((unitsFromParams || units) === "pixels") {
|
|
1091
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1092
|
+
sizes = sizes.map(size => size / groupSizePixels * 100);
|
|
1093
|
+
}
|
|
884
1094
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
885
1095
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
886
|
-
|
|
887
|
-
|
|
1096
|
+
const nextSizes = validatePanelGroupLayout({
|
|
1097
|
+
groupId,
|
|
1098
|
+
panels,
|
|
1099
|
+
nextSizes: sizes,
|
|
1100
|
+
prevSizes,
|
|
1101
|
+
units
|
|
1102
|
+
});
|
|
1103
|
+
if (!areEqual(prevSizes, nextSizes)) {
|
|
1104
|
+
setSizes(nextSizes);
|
|
1105
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1106
|
+
}
|
|
888
1107
|
}
|
|
889
|
-
}), []);
|
|
1108
|
+
}), [groupId]);
|
|
890
1109
|
useIsomorphicLayoutEffect(() => {
|
|
891
1110
|
committedValuesRef.current.direction = direction;
|
|
1111
|
+
committedValuesRef.current.id = groupId;
|
|
892
1112
|
committedValuesRef.current.panels = panels;
|
|
893
1113
|
committedValuesRef.current.sizes = sizes;
|
|
1114
|
+
committedValuesRef.current.units = units;
|
|
894
1115
|
});
|
|
895
1116
|
useWindowSplitterPanelGroupBehavior({
|
|
896
1117
|
committedValuesRef,
|
|
@@ -932,7 +1153,11 @@ function PanelGroupWithForwardedRef({
|
|
|
932
1153
|
// Compute the initial sizes based on default weights.
|
|
933
1154
|
// This assumes that panels register during initial mount (no conditional rendering)!
|
|
934
1155
|
useIsomorphicLayoutEffect(() => {
|
|
935
|
-
const
|
|
1156
|
+
const {
|
|
1157
|
+
id: groupId,
|
|
1158
|
+
sizes,
|
|
1159
|
+
units
|
|
1160
|
+
} = committedValuesRef.current;
|
|
936
1161
|
if (sizes.length === panels.size) {
|
|
937
1162
|
// Only compute (or restore) default sizes once per panel configuration.
|
|
938
1163
|
return;
|
|
@@ -946,39 +1171,23 @@ function PanelGroupWithForwardedRef({
|
|
|
946
1171
|
defaultSizes = loadPanelLayout(autoSaveId, panelsArray, storage);
|
|
947
1172
|
}
|
|
948
1173
|
if (defaultSizes != null) {
|
|
949
|
-
|
|
1174
|
+
// Validate saved sizes in case something has changed since last render
|
|
1175
|
+
// e.g. for pixel groups, this could be the size of the window
|
|
1176
|
+
const validatedSizes = validatePanelGroupLayout({
|
|
1177
|
+
groupId,
|
|
1178
|
+
panels,
|
|
1179
|
+
nextSizes: defaultSizes,
|
|
1180
|
+
prevSizes: defaultSizes,
|
|
1181
|
+
units
|
|
1182
|
+
});
|
|
1183
|
+
setSizes(validatedSizes);
|
|
950
1184
|
} else {
|
|
951
|
-
const
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
// TODO
|
|
957
|
-
// Implicit default size calculations below do not account for inferred min/max size values.
|
|
958
|
-
// e.g. if Panel A has a maxSize of 40 then Panels A and B can't both have an implicit default size of 50.
|
|
959
|
-
// For now, these logic edge cases are left to the user to handle via props.
|
|
960
|
-
|
|
961
|
-
panelsArray.forEach(panel => {
|
|
962
|
-
totalMinSize += panel.current.minSize;
|
|
963
|
-
if (panel.current.defaultSize === null) {
|
|
964
|
-
panelsWithNullDefaultSize++;
|
|
965
|
-
} else {
|
|
966
|
-
totalDefaultSize += panel.current.defaultSize;
|
|
967
|
-
}
|
|
1185
|
+
const sizes = calculateDefaultLayout({
|
|
1186
|
+
groupId,
|
|
1187
|
+
panels,
|
|
1188
|
+
units
|
|
968
1189
|
});
|
|
969
|
-
|
|
970
|
-
throw new Error(`Default panel sizes cannot exceed 100%`);
|
|
971
|
-
} else if (panelsArray.length > 1 && panelsWithNullDefaultSize === 0 && totalDefaultSize !== 100) {
|
|
972
|
-
throw new Error(`Invalid default sizes specified for panels`);
|
|
973
|
-
} else if (totalMinSize > 100) {
|
|
974
|
-
throw new Error(`Minimum panel sizes cannot exceed 100%`);
|
|
975
|
-
}
|
|
976
|
-
setSizes(panelsArray.map(panel => {
|
|
977
|
-
if (panel.current.defaultSize === null) {
|
|
978
|
-
return (100 - totalDefaultSize) / panelsWithNullDefaultSize;
|
|
979
|
-
}
|
|
980
|
-
return panel.current.defaultSize;
|
|
981
|
-
}));
|
|
1190
|
+
setSizes(sizes);
|
|
982
1191
|
}
|
|
983
1192
|
}, [autoSaveId, panels, storage]);
|
|
984
1193
|
useEffect(() => {
|
|
@@ -996,6 +1205,48 @@ function PanelGroupWithForwardedRef({
|
|
|
996
1205
|
debounceMap[autoSaveId](autoSaveId, panelsArray, sizes, storage);
|
|
997
1206
|
}
|
|
998
1207
|
}, [autoSaveId, panels, sizes, storage]);
|
|
1208
|
+
useIsomorphicLayoutEffect(() => {
|
|
1209
|
+
// Pixel panel constraints need to be reassessed after a group resize
|
|
1210
|
+
// We can avoid the ResizeObserver overhead for relative layouts
|
|
1211
|
+
if (units === "pixels") {
|
|
1212
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
1213
|
+
const {
|
|
1214
|
+
panels,
|
|
1215
|
+
sizes: prevSizes
|
|
1216
|
+
} = committedValuesRef.current;
|
|
1217
|
+
const nextSizes = validatePanelGroupLayout({
|
|
1218
|
+
groupId,
|
|
1219
|
+
panels,
|
|
1220
|
+
nextSizes: prevSizes,
|
|
1221
|
+
prevSizes,
|
|
1222
|
+
units
|
|
1223
|
+
});
|
|
1224
|
+
if (!areEqual(prevSizes, nextSizes)) {
|
|
1225
|
+
setSizes(nextSizes);
|
|
1226
|
+
}
|
|
1227
|
+
});
|
|
1228
|
+
resizeObserver.observe(getPanelGroup(groupId));
|
|
1229
|
+
return () => {
|
|
1230
|
+
resizeObserver.disconnect();
|
|
1231
|
+
};
|
|
1232
|
+
}
|
|
1233
|
+
}, [groupId, units]);
|
|
1234
|
+
const getPanelSize = useCallback((id, unitsFromParams) => {
|
|
1235
|
+
const {
|
|
1236
|
+
panels,
|
|
1237
|
+
units: unitsFromProps
|
|
1238
|
+
} = committedValuesRef.current;
|
|
1239
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
1240
|
+
const index = panelsArray.findIndex(panel => panel.current.id === id);
|
|
1241
|
+
const size = sizes[index];
|
|
1242
|
+
const units = unitsFromParams ?? unitsFromProps;
|
|
1243
|
+
if (units === "pixels") {
|
|
1244
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1245
|
+
return size / 100 * groupSizePixels;
|
|
1246
|
+
} else {
|
|
1247
|
+
return size;
|
|
1248
|
+
}
|
|
1249
|
+
}, [groupId, sizes]);
|
|
999
1250
|
const getPanelStyle = useCallback((id, defaultSize) => {
|
|
1000
1251
|
const {
|
|
1001
1252
|
panels
|
|
@@ -1026,6 +1277,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1026
1277
|
};
|
|
1027
1278
|
}, [activeHandleId, disablePointerEventsDuringResize, sizes]);
|
|
1028
1279
|
const registerPanel = useCallback((id, panelRef) => {
|
|
1280
|
+
const {
|
|
1281
|
+
units
|
|
1282
|
+
} = committedValuesRef.current;
|
|
1283
|
+
validatePanelProps(units, panelRef);
|
|
1029
1284
|
setPanels(prevPanels => {
|
|
1030
1285
|
if (prevPanels.has(id)) {
|
|
1031
1286
|
return prevPanels;
|
|
@@ -1062,7 +1317,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1062
1317
|
}
|
|
1063
1318
|
const size = isHorizontal ? rect.width : rect.height;
|
|
1064
1319
|
const delta = movement / size * 100;
|
|
1065
|
-
|
|
1320
|
+
|
|
1321
|
+
// If a validateLayout method has been provided
|
|
1322
|
+
// it's important to use it before updating the mouse cursor
|
|
1323
|
+
const nextSizes = adjustByDelta(event, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, initialDragStateRef.current);
|
|
1066
1324
|
const sizesChanged = !areEqual(prevSizes, nextSizes);
|
|
1067
1325
|
|
|
1068
1326
|
// Don't update cursor for resizes triggered by keyboard interactions.
|
|
@@ -1089,6 +1347,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1089
1347
|
}
|
|
1090
1348
|
if (sizesChanged) {
|
|
1091
1349
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1350
|
+
|
|
1351
|
+
// It's okay to bypass in this case because we already validated above
|
|
1092
1352
|
setSizes(nextSizes);
|
|
1093
1353
|
|
|
1094
1354
|
// If resize change handlers have been declared, this is the time to call them.
|
|
@@ -1142,7 +1402,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1142
1402
|
}
|
|
1143
1403
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1144
1404
|
const delta = isLastPanel ? currentSize : collapsedSize - currentSize;
|
|
1145
|
-
const nextSizes = adjustByDelta(null,
|
|
1405
|
+
const nextSizes = adjustByDelta(null, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1146
1406
|
if (prevSizes !== nextSizes) {
|
|
1147
1407
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1148
1408
|
setSizes(nextSizes);
|
|
@@ -1185,7 +1445,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1185
1445
|
}
|
|
1186
1446
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1187
1447
|
const delta = isLastPanel ? collapsedSize - sizeBeforeCollapse : sizeBeforeCollapse;
|
|
1188
|
-
const nextSizes = adjustByDelta(null,
|
|
1448
|
+
const nextSizes = adjustByDelta(null, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1189
1449
|
if (prevSizes !== nextSizes) {
|
|
1190
1450
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1191
1451
|
setSizes(nextSizes);
|
|
@@ -1195,21 +1455,34 @@ function PanelGroupWithForwardedRef({
|
|
|
1195
1455
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1196
1456
|
}
|
|
1197
1457
|
}, []);
|
|
1198
|
-
const resizePanel = useCallback((id, nextSize) => {
|
|
1458
|
+
const resizePanel = useCallback((id, nextSize, unitsFromParams) => {
|
|
1199
1459
|
const {
|
|
1460
|
+
id: groupId,
|
|
1200
1461
|
panels,
|
|
1201
|
-
sizes: prevSizes
|
|
1462
|
+
sizes: prevSizes,
|
|
1463
|
+
units
|
|
1202
1464
|
} = committedValuesRef.current;
|
|
1465
|
+
if ((unitsFromParams || units) === "pixels") {
|
|
1466
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1467
|
+
nextSize = nextSize / groupSizePixels * 100;
|
|
1468
|
+
}
|
|
1203
1469
|
const panel = panels.get(id);
|
|
1204
1470
|
if (panel == null) {
|
|
1205
1471
|
return;
|
|
1206
1472
|
}
|
|
1207
|
-
|
|
1473
|
+
let {
|
|
1208
1474
|
collapsedSize,
|
|
1209
1475
|
collapsible,
|
|
1210
1476
|
maxSize,
|
|
1211
1477
|
minSize
|
|
1212
1478
|
} = panel.current;
|
|
1479
|
+
if (units === "pixels") {
|
|
1480
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1481
|
+
minSize = minSize / groupSizePixels * 100;
|
|
1482
|
+
if (maxSize != null) {
|
|
1483
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
1484
|
+
}
|
|
1485
|
+
}
|
|
1213
1486
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
1214
1487
|
const index = panelsArray.indexOf(panel);
|
|
1215
1488
|
if (index < 0) {
|
|
@@ -1220,7 +1493,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1220
1493
|
return;
|
|
1221
1494
|
}
|
|
1222
1495
|
if (collapsible && nextSize === collapsedSize) ; else {
|
|
1223
|
-
nextSize = Math.min(maxSize, Math.max(minSize, nextSize));
|
|
1496
|
+
nextSize = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, nextSize));
|
|
1224
1497
|
}
|
|
1225
1498
|
const [idBefore, idAfter] = getBeforeAndAfterIds(id, panelsArray);
|
|
1226
1499
|
if (idBefore == null || idAfter == null) {
|
|
@@ -1228,7 +1501,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1228
1501
|
}
|
|
1229
1502
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1230
1503
|
const delta = isLastPanel ? currentSize - nextSize : nextSize - currentSize;
|
|
1231
|
-
const nextSizes = adjustByDelta(null,
|
|
1504
|
+
const nextSizes = adjustByDelta(null, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1232
1505
|
if (prevSizes !== nextSizes) {
|
|
1233
1506
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1234
1507
|
setSizes(nextSizes);
|
|
@@ -1243,6 +1516,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1243
1516
|
collapsePanel,
|
|
1244
1517
|
direction,
|
|
1245
1518
|
expandPanel,
|
|
1519
|
+
getPanelSize,
|
|
1246
1520
|
getPanelStyle,
|
|
1247
1521
|
groupId,
|
|
1248
1522
|
registerPanel,
|
|
@@ -1264,8 +1538,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1264
1538
|
setActiveHandleId(null);
|
|
1265
1539
|
initialDragStateRef.current = null;
|
|
1266
1540
|
},
|
|
1541
|
+
units,
|
|
1267
1542
|
unregisterPanel
|
|
1268
|
-
}), [activeHandleId, collapsePanel, direction, expandPanel, getPanelStyle, groupId, registerPanel, registerResizeHandle, resizePanel, unregisterPanel]);
|
|
1543
|
+
}), [activeHandleId, collapsePanel, direction, expandPanel, getPanelSize, getPanelStyle, groupId, registerPanel, registerResizeHandle, resizePanel, units, unregisterPanel]);
|
|
1269
1544
|
const style = {
|
|
1270
1545
|
display: "flex",
|
|
1271
1546
|
flexDirection: direction === "horizontal" ? "row" : "column",
|
|
@@ -1280,6 +1555,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1280
1555
|
"data-panel-group": "",
|
|
1281
1556
|
"data-panel-group-direction": direction,
|
|
1282
1557
|
"data-panel-group-id": groupId,
|
|
1558
|
+
"data-panel-group-units": units,
|
|
1283
1559
|
style: {
|
|
1284
1560
|
...style,
|
|
1285
1561
|
...styleFromProps
|
|
@@ -1292,10 +1568,6 @@ const PanelGroup = forwardRef((props, ref) => createElement(PanelGroupWithForwar
|
|
|
1292
1568
|
...props,
|
|
1293
1569
|
forwardedRef: ref
|
|
1294
1570
|
}));
|
|
1295
|
-
|
|
1296
|
-
// Workaround for Parcel scope hoisting (which renames objects/functions).
|
|
1297
|
-
// Casting to :any is required to avoid corrupting the generated TypeScript types.
|
|
1298
|
-
// See github.com/parcel-bundler/parcel/issues/8724
|
|
1299
1571
|
PanelGroupWithForwardedRef.displayName = "PanelGroup";
|
|
1300
1572
|
PanelGroup.displayName = "forwardRef(PanelGroup)";
|
|
1301
1573
|
|
|
@@ -1431,12 +1703,9 @@ function PanelResizeHandle({
|
|
|
1431
1703
|
tabIndex: 0
|
|
1432
1704
|
});
|
|
1433
1705
|
}
|
|
1434
|
-
|
|
1435
|
-
// Workaround for Parcel scope hoisting (which renames objects/functions).
|
|
1436
|
-
// Casting to :any is required to avoid corrupting the generated TypeScript types.
|
|
1437
|
-
// See github.com/parcel-bundler/parcel/issues/8724
|
|
1438
1706
|
PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
1439
1707
|
|
|
1440
1708
|
exports.Panel = Panel;
|
|
1441
1709
|
exports.PanelGroup = PanelGroup;
|
|
1442
1710
|
exports.PanelResizeHandle = PanelResizeHandle;
|
|
1711
|
+
exports.getAvailableGroupSizePixels = getAvailableGroupSizePixels;
|