react-resizable-panels 0.0.54 → 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 +29 -0
- package/dist/declarations/src/Panel.d.ts +5 -4
- package/dist/declarations/src/PanelGroup.d.ts +7 -3
- package/dist/declarations/src/index.d.ts +3 -2
- package/dist/declarations/src/types.d.ts +2 -1
- package/dist/declarations/src/utils/group.d.ts +29 -0
- package/dist/react-resizable-panels.browser.cjs.js +385 -108
- package/dist/react-resizable-panels.browser.cjs.mjs +2 -1
- package/dist/react-resizable-panels.browser.development.cjs.js +417 -108
- package/dist/react-resizable-panels.browser.development.cjs.mjs +2 -1
- package/dist/react-resizable-panels.browser.development.esm.js +417 -109
- package/dist/react-resizable-panels.browser.esm.js +385 -109
- package/dist/react-resizable-panels.cjs.js +385 -108
- 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 +417 -108
- package/dist/react-resizable-panels.development.cjs.mjs +2 -1
- package/dist/react-resizable-panels.development.esm.js +417 -109
- package/dist/react-resizable-panels.development.node.cjs.js +282 -76
- package/dist/react-resizable-panels.development.node.cjs.mjs +2 -1
- package/dist/react-resizable-panels.development.node.esm.js +282 -77
- package/dist/react-resizable-panels.esm.js +385 -109
- package/dist/react-resizable-panels.esm.js.map +1 -0
- package/dist/react-resizable-panels.node.cjs.js +254 -76
- package/dist/react-resizable-panels.node.cjs.mjs +2 -1
- package/dist/react-resizable-panels.node.esm.js +254 -77
- package/package.json +1 -1
- package/src/Panel.ts +32 -32
- package/src/PanelContexts.ts +4 -2
- package/src/PanelGroup.ts +221 -111
- package/src/hooks/useWindowSplitterBehavior.ts +14 -11
- package/src/index.ts +11 -3
- package/src/types.ts +2 -1
- package/src/utils/group.ts +327 -28
|
@@ -47,8 +47,8 @@ function PanelWithForwardedRef({
|
|
|
47
47
|
defaultSize = null,
|
|
48
48
|
forwardedRef,
|
|
49
49
|
id: idFromProps = null,
|
|
50
|
-
maxSize =
|
|
51
|
-
minSize
|
|
50
|
+
maxSize = null,
|
|
51
|
+
minSize,
|
|
52
52
|
onCollapse = null,
|
|
53
53
|
onResize = null,
|
|
54
54
|
order = null,
|
|
@@ -63,11 +63,22 @@ function PanelWithForwardedRef({
|
|
|
63
63
|
const {
|
|
64
64
|
collapsePanel,
|
|
65
65
|
expandPanel,
|
|
66
|
+
getPanelSize,
|
|
66
67
|
getPanelStyle,
|
|
67
68
|
registerPanel,
|
|
68
69
|
resizePanel,
|
|
70
|
+
units,
|
|
69
71
|
unregisterPanel
|
|
70
72
|
} = context;
|
|
73
|
+
if (minSize == null) {
|
|
74
|
+
if (units === "percentages") {
|
|
75
|
+
// Mimics legacy default value for percentage based panel groups
|
|
76
|
+
minSize = 10;
|
|
77
|
+
} else {
|
|
78
|
+
// There is no meaningful minimum pixel default we can provide
|
|
79
|
+
minSize = 0;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
71
82
|
|
|
72
83
|
// Use a ref to guard against users passing inline props
|
|
73
84
|
const callbacksRef = useRef({
|
|
@@ -78,22 +89,6 @@ function PanelWithForwardedRef({
|
|
|
78
89
|
callbacksRef.current.onCollapse = onCollapse;
|
|
79
90
|
callbacksRef.current.onResize = onResize;
|
|
80
91
|
});
|
|
81
|
-
|
|
82
|
-
// Basic props validation
|
|
83
|
-
if (minSize < 0 || minSize > 100) {
|
|
84
|
-
throw Error(`Panel minSize must be between 0 and 100, but was ${minSize}`);
|
|
85
|
-
} else if (maxSize < 0 || maxSize > 100) {
|
|
86
|
-
throw Error(`Panel maxSize must be between 0 and 100, but was ${maxSize}`);
|
|
87
|
-
} else {
|
|
88
|
-
if (defaultSize !== null) {
|
|
89
|
-
if (defaultSize < 0 || defaultSize > 100) {
|
|
90
|
-
throw Error(`Panel defaultSize must be between 0 and 100, but was ${defaultSize}`);
|
|
91
|
-
} else if (minSize > defaultSize && !collapsible) {
|
|
92
|
-
console.error(`Panel minSize ${minSize} cannot be greater than defaultSize ${defaultSize}`);
|
|
93
|
-
defaultSize = minSize;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
92
|
const style = getPanelStyle(panelId, defaultSize);
|
|
98
93
|
const committedValuesRef = useRef({
|
|
99
94
|
size: parseSizeFromStyle(style)
|
|
@@ -133,11 +128,14 @@ function PanelWithForwardedRef({
|
|
|
133
128
|
getCollapsed() {
|
|
134
129
|
return committedValuesRef.current.size === 0;
|
|
135
130
|
},
|
|
136
|
-
|
|
137
|
-
return
|
|
131
|
+
getId() {
|
|
132
|
+
return panelId;
|
|
138
133
|
},
|
|
139
|
-
|
|
140
|
-
|
|
134
|
+
getSize(units) {
|
|
135
|
+
return getPanelSize(panelId, units);
|
|
136
|
+
},
|
|
137
|
+
resize: (percentage, units) => resizePanel(panelId, percentage, units)
|
|
138
|
+
}), [collapsePanel, expandPanel, getPanelSize, panelId, resizePanel]);
|
|
141
139
|
return createElement(Type, {
|
|
142
140
|
children,
|
|
143
141
|
className: classNameFromProps,
|
|
@@ -173,7 +171,13 @@ function parseSizeFromStyle(style) {
|
|
|
173
171
|
|
|
174
172
|
const PRECISION = 10;
|
|
175
173
|
|
|
176
|
-
function adjustByDelta(event,
|
|
174
|
+
function adjustByDelta(event, committedValues, idBefore, idAfter, deltaPixels, prevSizes, panelSizeBeforeCollapse, initialDragState) {
|
|
175
|
+
const {
|
|
176
|
+
id: groupId,
|
|
177
|
+
panels,
|
|
178
|
+
units
|
|
179
|
+
} = committedValues;
|
|
180
|
+
const groupSizePixels = units === "pixels" ? getAvailableGroupSizePixels(groupId) : NaN;
|
|
177
181
|
const {
|
|
178
182
|
sizes: initialSizes
|
|
179
183
|
} = initialDragState || {};
|
|
@@ -181,9 +185,6 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
181
185
|
// If we're resizing by mouse or touch, use the initial sizes as a base.
|
|
182
186
|
// This has the benefit of causing force-collapsed panels to spring back open if drag is reversed.
|
|
183
187
|
const baseSizes = initialSizes || prevSizes;
|
|
184
|
-
if (delta === 0) {
|
|
185
|
-
return baseSizes;
|
|
186
|
-
}
|
|
187
188
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
188
189
|
const nextSizes = baseSizes.concat();
|
|
189
190
|
let deltaApplied = 0;
|
|
@@ -198,11 +199,11 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
198
199
|
|
|
199
200
|
// Max-bounds check the panel being expanded first.
|
|
200
201
|
{
|
|
201
|
-
const pivotId =
|
|
202
|
+
const pivotId = deltaPixels < 0 ? idAfter : idBefore;
|
|
202
203
|
const index = panelsArray.findIndex(panel => panel.current.id === pivotId);
|
|
203
204
|
const panel = panelsArray[index];
|
|
204
205
|
const baseSize = baseSizes[index];
|
|
205
|
-
const nextSize = safeResizePanel(panel, Math.abs(
|
|
206
|
+
const nextSize = safeResizePanel(units, groupSizePixels, panel, baseSize, baseSize + Math.abs(deltaPixels), event);
|
|
206
207
|
if (baseSize === nextSize) {
|
|
207
208
|
// If there's no room for the pivot panel to grow, we can ignore this drag update.
|
|
208
209
|
return baseSizes;
|
|
@@ -210,29 +211,29 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
210
211
|
if (nextSize === 0 && baseSize > 0) {
|
|
211
212
|
panelSizeBeforeCollapse.set(pivotId, baseSize);
|
|
212
213
|
}
|
|
213
|
-
|
|
214
|
+
deltaPixels = deltaPixels < 0 ? baseSize - nextSize : nextSize - baseSize;
|
|
214
215
|
}
|
|
215
216
|
}
|
|
216
|
-
let pivotId =
|
|
217
|
+
let pivotId = deltaPixels < 0 ? idBefore : idAfter;
|
|
217
218
|
let index = panelsArray.findIndex(panel => panel.current.id === pivotId);
|
|
218
219
|
while (true) {
|
|
219
220
|
const panel = panelsArray[index];
|
|
220
221
|
const baseSize = baseSizes[index];
|
|
221
|
-
const deltaRemaining = Math.abs(
|
|
222
|
-
const nextSize = safeResizePanel(panel,
|
|
222
|
+
const deltaRemaining = Math.abs(deltaPixels) - Math.abs(deltaApplied);
|
|
223
|
+
const nextSize = safeResizePanel(units, groupSizePixels, panel, baseSize, baseSize - deltaRemaining, event);
|
|
223
224
|
if (baseSize !== nextSize) {
|
|
224
225
|
if (nextSize === 0 && baseSize > 0) {
|
|
225
226
|
panelSizeBeforeCollapse.set(panel.current.id, baseSize);
|
|
226
227
|
}
|
|
227
228
|
deltaApplied += baseSize - nextSize;
|
|
228
229
|
nextSizes[index] = nextSize;
|
|
229
|
-
if (deltaApplied.toPrecision(PRECISION).localeCompare(Math.abs(
|
|
230
|
+
if (deltaApplied.toPrecision(PRECISION).localeCompare(Math.abs(deltaPixels).toPrecision(PRECISION), undefined, {
|
|
230
231
|
numeric: true
|
|
231
232
|
}) >= 0) {
|
|
232
233
|
break;
|
|
233
234
|
}
|
|
234
235
|
}
|
|
235
|
-
if (
|
|
236
|
+
if (deltaPixels < 0) {
|
|
236
237
|
if (--index < 0) {
|
|
237
238
|
break;
|
|
238
239
|
}
|
|
@@ -250,7 +251,7 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
250
251
|
}
|
|
251
252
|
|
|
252
253
|
// Adjust the pivot panel before, but only by the amount that surrounding panels were able to shrink/contract.
|
|
253
|
-
pivotId =
|
|
254
|
+
pivotId = deltaPixels < 0 ? idAfter : idBefore;
|
|
254
255
|
index = panelsArray.findIndex(panel => panel.current.id === pivotId);
|
|
255
256
|
nextSizes[index] = baseSizes[index] + deltaApplied;
|
|
256
257
|
return nextSizes;
|
|
@@ -289,6 +290,89 @@ function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
|
289
290
|
}
|
|
290
291
|
});
|
|
291
292
|
}
|
|
293
|
+
function calculateDefaultLayout({
|
|
294
|
+
groupId,
|
|
295
|
+
panels,
|
|
296
|
+
units
|
|
297
|
+
}) {
|
|
298
|
+
const groupSizePixels = units === "pixels" ? getAvailableGroupSizePixels(groupId) : NaN;
|
|
299
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
300
|
+
const sizes = Array(panelsArray.length);
|
|
301
|
+
let numPanelsWithSizes = 0;
|
|
302
|
+
let remainingSize = 100;
|
|
303
|
+
|
|
304
|
+
// Assigning default sizes requires a couple of passes:
|
|
305
|
+
// First, all panels with defaultSize should be set as-is
|
|
306
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
307
|
+
const panel = panelsArray[index];
|
|
308
|
+
const {
|
|
309
|
+
defaultSize
|
|
310
|
+
} = panel.current;
|
|
311
|
+
if (defaultSize != null) {
|
|
312
|
+
numPanelsWithSizes++;
|
|
313
|
+
sizes[index] = units === "pixels" ? defaultSize / groupSizePixels * 100 : defaultSize;
|
|
314
|
+
remainingSize -= sizes[index];
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
// Remaining total size should be distributed evenly between panels
|
|
319
|
+
// This may require two passes, depending on min/max constraints
|
|
320
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
321
|
+
const panel = panelsArray[index];
|
|
322
|
+
let {
|
|
323
|
+
defaultSize,
|
|
324
|
+
id,
|
|
325
|
+
maxSize,
|
|
326
|
+
minSize
|
|
327
|
+
} = panel.current;
|
|
328
|
+
if (defaultSize != null) {
|
|
329
|
+
continue;
|
|
330
|
+
}
|
|
331
|
+
if (units === "pixels") {
|
|
332
|
+
minSize = minSize / groupSizePixels * 100;
|
|
333
|
+
if (maxSize != null) {
|
|
334
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
const remainingPanels = panelsArray.length - numPanelsWithSizes;
|
|
338
|
+
const size = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, remainingSize / remainingPanels));
|
|
339
|
+
sizes[index] = size;
|
|
340
|
+
numPanelsWithSizes++;
|
|
341
|
+
remainingSize -= size;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
// If there is additional, left over space, assign it to any panel(s) that permits it
|
|
345
|
+
// (It's not worth taking multiple additional passes to evenly distribute)
|
|
346
|
+
if (remainingSize !== 0) {
|
|
347
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
348
|
+
const panel = panelsArray[index];
|
|
349
|
+
let {
|
|
350
|
+
maxSize,
|
|
351
|
+
minSize
|
|
352
|
+
} = panel.current;
|
|
353
|
+
if (units === "pixels") {
|
|
354
|
+
minSize = minSize / groupSizePixels * 100;
|
|
355
|
+
if (maxSize != null) {
|
|
356
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
const size = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, sizes[index] + remainingSize));
|
|
360
|
+
if (size !== sizes[index]) {
|
|
361
|
+
remainingSize -= size - sizes[index];
|
|
362
|
+
sizes[index] = size;
|
|
363
|
+
|
|
364
|
+
// Fuzzy comparison to account for imprecise floating point math
|
|
365
|
+
if (Math.abs(remainingSize).toFixed(3) === "0.000") {
|
|
366
|
+
break;
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
// Finally, if there is still left-over size, log an error
|
|
373
|
+
if (Math.abs(remainingSize).toFixed(3) !== "0.000") ;
|
|
374
|
+
return sizes;
|
|
375
|
+
}
|
|
292
376
|
function getBeforeAndAfterIds(id, panelsArray) {
|
|
293
377
|
if (panelsArray.length < 2) {
|
|
294
378
|
return [null, null];
|
|
@@ -302,6 +386,23 @@ function getBeforeAndAfterIds(id, panelsArray) {
|
|
|
302
386
|
const idAfter = isLastPanel ? id : panelsArray[index + 1].current.id;
|
|
303
387
|
return [idBefore, idAfter];
|
|
304
388
|
}
|
|
389
|
+
function getAvailableGroupSizePixels(groupId) {
|
|
390
|
+
const panelGroupElement = getPanelGroup(groupId);
|
|
391
|
+
if (panelGroupElement == null) {
|
|
392
|
+
return NaN;
|
|
393
|
+
}
|
|
394
|
+
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
395
|
+
const resizeHandles = getResizeHandlesForGroup(groupId);
|
|
396
|
+
if (direction === "horizontal") {
|
|
397
|
+
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
398
|
+
return accumulated + handle.offsetWidth;
|
|
399
|
+
}, 0);
|
|
400
|
+
} else {
|
|
401
|
+
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
402
|
+
return accumulated + handle.offsetHeight;
|
|
403
|
+
}, 0);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
305
406
|
|
|
306
407
|
// This method returns a number between 1 and 100 representing
|
|
307
408
|
// the % of the group's overall space this panel should occupy.
|
|
@@ -372,18 +473,24 @@ function panelsMapToSortedArray(panels) {
|
|
|
372
473
|
}
|
|
373
474
|
});
|
|
374
475
|
}
|
|
375
|
-
function safeResizePanel(
|
|
376
|
-
|
|
377
|
-
const {
|
|
476
|
+
function safeResizePanel(units, groupSizePixels, panel, prevSize, nextSize, event = null) {
|
|
477
|
+
let {
|
|
378
478
|
collapsedSize,
|
|
379
479
|
collapsible,
|
|
380
480
|
maxSize,
|
|
381
481
|
minSize
|
|
382
482
|
} = panel.current;
|
|
483
|
+
if (units === "pixels") {
|
|
484
|
+
collapsedSize = collapsedSize / groupSizePixels * 100;
|
|
485
|
+
if (maxSize != null) {
|
|
486
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
487
|
+
}
|
|
488
|
+
minSize = minSize / groupSizePixels * 100;
|
|
489
|
+
}
|
|
383
490
|
if (collapsible) {
|
|
384
491
|
if (prevSize > collapsedSize) {
|
|
385
492
|
// Mimic VS COde behavior; collapse a panel if it's smaller than half of its min-size
|
|
386
|
-
if (
|
|
493
|
+
if (nextSize <= minSize / 2 + collapsedSize) {
|
|
387
494
|
return collapsedSize;
|
|
388
495
|
}
|
|
389
496
|
} else {
|
|
@@ -392,14 +499,97 @@ function safeResizePanel(panel, delta, prevSize, event) {
|
|
|
392
499
|
// Keyboard events should expand a collapsed panel to the min size,
|
|
393
500
|
// but mouse events should wait until the panel has reached its min size
|
|
394
501
|
// to avoid a visual flickering when dragging between collapsed and min size.
|
|
395
|
-
if (
|
|
502
|
+
if (nextSize < minSize) {
|
|
396
503
|
return collapsedSize;
|
|
397
504
|
}
|
|
398
505
|
}
|
|
399
506
|
}
|
|
400
507
|
}
|
|
401
|
-
|
|
402
|
-
|
|
508
|
+
return Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, nextSize));
|
|
509
|
+
}
|
|
510
|
+
function validatePanelProps(units, panelData) {
|
|
511
|
+
const {
|
|
512
|
+
collapsible,
|
|
513
|
+
defaultSize,
|
|
514
|
+
maxSize,
|
|
515
|
+
minSize
|
|
516
|
+
} = panelData.current;
|
|
517
|
+
|
|
518
|
+
// Basic props validation
|
|
519
|
+
if (minSize < 0 || units === "percentages" && minSize > 100) {
|
|
520
|
+
panelData.current.minSize = 0;
|
|
521
|
+
}
|
|
522
|
+
if (maxSize != null) {
|
|
523
|
+
if (maxSize < 0 || units === "percentages" && maxSize > 100) {
|
|
524
|
+
panelData.current.maxSize = null;
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
if (defaultSize !== null) {
|
|
528
|
+
if (defaultSize < 0 || units === "percentages" && defaultSize > 100) {
|
|
529
|
+
panelData.current.defaultSize = null;
|
|
530
|
+
} else if (defaultSize < minSize && !collapsible) {
|
|
531
|
+
panelData.current.defaultSize = minSize;
|
|
532
|
+
} else if (maxSize != null && defaultSize > maxSize) {
|
|
533
|
+
panelData.current.defaultSize = maxSize;
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
}
|
|
537
|
+
function validatePanelGroupLayout({
|
|
538
|
+
groupId,
|
|
539
|
+
panels,
|
|
540
|
+
nextSizes,
|
|
541
|
+
prevSizes,
|
|
542
|
+
units
|
|
543
|
+
}) {
|
|
544
|
+
// Clone because this method modifies
|
|
545
|
+
nextSizes = [...nextSizes];
|
|
546
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
547
|
+
const groupSizePixels = units === "pixels" ? getAvailableGroupSizePixels(groupId) : NaN;
|
|
548
|
+
let remainingSize = 0;
|
|
549
|
+
|
|
550
|
+
// First, check all of the proposed sizes against the min/max constraints
|
|
551
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
552
|
+
const panel = panelsArray[index];
|
|
553
|
+
const prevSize = prevSizes[index];
|
|
554
|
+
const nextSize = nextSizes[index];
|
|
555
|
+
const safeNextSize = safeResizePanel(units, groupSizePixels, panel, prevSize, nextSize);
|
|
556
|
+
if (nextSize != safeNextSize) {
|
|
557
|
+
remainingSize += nextSize - safeNextSize;
|
|
558
|
+
nextSizes[index] = safeNextSize;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
// If there is additional, left over space, assign it to any panel(s) that permits it
|
|
563
|
+
// (It's not worth taking multiple additional passes to evenly distribute)
|
|
564
|
+
if (remainingSize.toFixed(3) !== "0.000") {
|
|
565
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
566
|
+
const panel = panelsArray[index];
|
|
567
|
+
let {
|
|
568
|
+
maxSize,
|
|
569
|
+
minSize
|
|
570
|
+
} = panel.current;
|
|
571
|
+
if (units === "pixels") {
|
|
572
|
+
minSize = minSize / groupSizePixels * 100;
|
|
573
|
+
if (maxSize != null) {
|
|
574
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
const size = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, nextSizes[index] + remainingSize));
|
|
578
|
+
if (size !== nextSizes[index]) {
|
|
579
|
+
remainingSize -= size - nextSizes[index];
|
|
580
|
+
nextSizes[index] = size;
|
|
581
|
+
|
|
582
|
+
// Fuzzy comparison to account for imprecise floating point math
|
|
583
|
+
if (Math.abs(remainingSize).toFixed(3) === "0.000") {
|
|
584
|
+
break;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
// If we still have remainder, the requested layout wasn't valid and we should warn about it
|
|
591
|
+
if (remainingSize.toFixed(3) !== "0.000") ;
|
|
592
|
+
return nextSizes;
|
|
403
593
|
}
|
|
404
594
|
|
|
405
595
|
function assert(expectedCondition, message = "Assertion failed!") {
|
|
@@ -425,6 +615,7 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
425
615
|
panels
|
|
426
616
|
} = committedValuesRef.current;
|
|
427
617
|
const groupElement = getPanelGroup(groupId);
|
|
618
|
+
assert(groupElement != null, `No group found for id "${groupId}"`);
|
|
428
619
|
const {
|
|
429
620
|
height,
|
|
430
621
|
width
|
|
@@ -437,23 +628,28 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
437
628
|
if (idBefore == null || idAfter == null) {
|
|
438
629
|
return () => {};
|
|
439
630
|
}
|
|
440
|
-
let
|
|
441
|
-
let
|
|
631
|
+
let currentMinSize = 0;
|
|
632
|
+
let currentMaxSize = 100;
|
|
442
633
|
let totalMinSize = 0;
|
|
443
634
|
let totalMaxSize = 0;
|
|
444
635
|
|
|
445
636
|
// A panel's effective min/max sizes also need to account for other panel's sizes.
|
|
446
637
|
panelsArray.forEach(panelData => {
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
638
|
+
const {
|
|
639
|
+
id,
|
|
640
|
+
maxSize,
|
|
641
|
+
minSize
|
|
642
|
+
} = panelData.current;
|
|
643
|
+
if (id === idBefore) {
|
|
644
|
+
currentMinSize = minSize;
|
|
645
|
+
currentMaxSize = maxSize != null ? maxSize : 100;
|
|
450
646
|
} else {
|
|
451
|
-
totalMinSize +=
|
|
452
|
-
totalMaxSize +=
|
|
647
|
+
totalMinSize += minSize;
|
|
648
|
+
totalMaxSize += maxSize != null ? maxSize : 100;
|
|
453
649
|
}
|
|
454
650
|
});
|
|
455
|
-
const ariaValueMax = Math.min(
|
|
456
|
-
const ariaValueMin = Math.max(
|
|
651
|
+
const ariaValueMax = Math.min(currentMaxSize, 100 - totalMinSize);
|
|
652
|
+
const ariaValueMin = Math.max(currentMinSize, (panelsArray.length - 1) * 100 - totalMaxSize);
|
|
457
653
|
const flexGrow = getFlexGrow(panels, idBefore, sizes);
|
|
458
654
|
handle.setAttribute("aria-valuemax", "" + Math.round(ariaValueMax));
|
|
459
655
|
handle.setAttribute("aria-valuemin", "" + Math.round(ariaValueMin));
|
|
@@ -477,7 +673,7 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
477
673
|
} else {
|
|
478
674
|
delta = -(direction === "horizontal" ? width : height);
|
|
479
675
|
}
|
|
480
|
-
const nextSizes = adjustByDelta(event,
|
|
676
|
+
const nextSizes = adjustByDelta(event, committedValuesRef.current, idBefore, idAfter, delta, sizes, panelSizeBeforeCollapse.current, null);
|
|
481
677
|
if (sizes !== nextSizes) {
|
|
482
678
|
setSizes(nextSizes);
|
|
483
679
|
}
|
|
@@ -792,9 +988,6 @@ const defaultStorage = {
|
|
|
792
988
|
// * dragHandleRect, sizes:
|
|
793
989
|
// When resizing is done via mouse/touch event– some initial state is stored
|
|
794
990
|
// so that any panels that contract will also expand if drag direction is reversed.
|
|
795
|
-
// TODO
|
|
796
|
-
// Within an active drag, remember original positions to refine more easily on expand.
|
|
797
|
-
// Look at what the Chrome devtools Sources does.
|
|
798
991
|
function PanelGroupWithForwardedRef({
|
|
799
992
|
autoSaveId,
|
|
800
993
|
children = null,
|
|
@@ -806,7 +999,8 @@ function PanelGroupWithForwardedRef({
|
|
|
806
999
|
onLayout,
|
|
807
1000
|
storage = defaultStorage,
|
|
808
1001
|
style: styleFromProps = {},
|
|
809
|
-
tagName: Type = "div"
|
|
1002
|
+
tagName: Type = "div",
|
|
1003
|
+
units = "percentages"
|
|
810
1004
|
}) {
|
|
811
1005
|
const groupId = useUniqueId(idFromProps);
|
|
812
1006
|
const [activeHandleId, setActiveHandleId] = useState(null);
|
|
@@ -819,6 +1013,7 @@ function PanelGroupWithForwardedRef({
|
|
|
819
1013
|
useRef({
|
|
820
1014
|
didLogDefaultSizeWarning: false,
|
|
821
1015
|
didLogIdAndOrderWarning: false,
|
|
1016
|
+
didLogInvalidLayoutWarning: false,
|
|
822
1017
|
prevPanelIds: []
|
|
823
1018
|
});
|
|
824
1019
|
|
|
@@ -841,32 +1036,58 @@ function PanelGroupWithForwardedRef({
|
|
|
841
1036
|
// Store committed values to avoid unnecessarily re-running memoization/effects functions.
|
|
842
1037
|
const committedValuesRef = useRef({
|
|
843
1038
|
direction,
|
|
1039
|
+
id: groupId,
|
|
844
1040
|
panels,
|
|
845
|
-
sizes
|
|
1041
|
+
sizes,
|
|
1042
|
+
units
|
|
846
1043
|
});
|
|
847
1044
|
useImperativeHandle(forwardedRef, () => ({
|
|
848
|
-
|
|
1045
|
+
getId: () => groupId,
|
|
1046
|
+
getLayout: unitsFromParams => {
|
|
849
1047
|
const {
|
|
850
|
-
sizes
|
|
1048
|
+
sizes,
|
|
1049
|
+
units: unitsFromProps
|
|
851
1050
|
} = committedValuesRef.current;
|
|
852
|
-
|
|
1051
|
+
const units = unitsFromParams ?? unitsFromProps;
|
|
1052
|
+
if (units === "pixels") {
|
|
1053
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1054
|
+
return sizes.map(size => size / 100 * groupSizePixels);
|
|
1055
|
+
} else {
|
|
1056
|
+
return sizes;
|
|
1057
|
+
}
|
|
853
1058
|
},
|
|
854
|
-
setLayout: sizes => {
|
|
855
|
-
const total = sizes.reduce((accumulated, current) => accumulated + current, 0);
|
|
856
|
-
assert(total === 100, "Panel sizes must add up to 100%");
|
|
1059
|
+
setLayout: (sizes, unitsFromParams) => {
|
|
857
1060
|
const {
|
|
858
|
-
|
|
1061
|
+
id: groupId,
|
|
1062
|
+
panels,
|
|
1063
|
+
sizes: prevSizes,
|
|
1064
|
+
units
|
|
859
1065
|
} = committedValuesRef.current;
|
|
1066
|
+
if ((unitsFromParams || units) === "pixels") {
|
|
1067
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1068
|
+
sizes = sizes.map(size => size / groupSizePixels * 100);
|
|
1069
|
+
}
|
|
860
1070
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
861
1071
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
862
|
-
|
|
863
|
-
|
|
1072
|
+
const nextSizes = validatePanelGroupLayout({
|
|
1073
|
+
groupId,
|
|
1074
|
+
panels,
|
|
1075
|
+
nextSizes: sizes,
|
|
1076
|
+
prevSizes,
|
|
1077
|
+
units
|
|
1078
|
+
});
|
|
1079
|
+
if (!areEqual(prevSizes, nextSizes)) {
|
|
1080
|
+
setSizes(nextSizes);
|
|
1081
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1082
|
+
}
|
|
864
1083
|
}
|
|
865
|
-
}), []);
|
|
1084
|
+
}), [groupId]);
|
|
866
1085
|
useIsomorphicLayoutEffect(() => {
|
|
867
1086
|
committedValuesRef.current.direction = direction;
|
|
1087
|
+
committedValuesRef.current.id = groupId;
|
|
868
1088
|
committedValuesRef.current.panels = panels;
|
|
869
1089
|
committedValuesRef.current.sizes = sizes;
|
|
1090
|
+
committedValuesRef.current.units = units;
|
|
870
1091
|
});
|
|
871
1092
|
useWindowSplitterPanelGroupBehavior({
|
|
872
1093
|
committedValuesRef,
|
|
@@ -908,7 +1129,11 @@ function PanelGroupWithForwardedRef({
|
|
|
908
1129
|
// Compute the initial sizes based on default weights.
|
|
909
1130
|
// This assumes that panels register during initial mount (no conditional rendering)!
|
|
910
1131
|
useIsomorphicLayoutEffect(() => {
|
|
911
|
-
const
|
|
1132
|
+
const {
|
|
1133
|
+
id: groupId,
|
|
1134
|
+
sizes,
|
|
1135
|
+
units
|
|
1136
|
+
} = committedValuesRef.current;
|
|
912
1137
|
if (sizes.length === panels.size) {
|
|
913
1138
|
// Only compute (or restore) default sizes once per panel configuration.
|
|
914
1139
|
return;
|
|
@@ -922,39 +1147,23 @@ function PanelGroupWithForwardedRef({
|
|
|
922
1147
|
defaultSizes = loadPanelLayout(autoSaveId, panelsArray, storage);
|
|
923
1148
|
}
|
|
924
1149
|
if (defaultSizes != null) {
|
|
925
|
-
|
|
1150
|
+
// Validate saved sizes in case something has changed since last render
|
|
1151
|
+
// e.g. for pixel groups, this could be the size of the window
|
|
1152
|
+
const validatedSizes = validatePanelGroupLayout({
|
|
1153
|
+
groupId,
|
|
1154
|
+
panels,
|
|
1155
|
+
nextSizes: defaultSizes,
|
|
1156
|
+
prevSizes: defaultSizes,
|
|
1157
|
+
units
|
|
1158
|
+
});
|
|
1159
|
+
setSizes(validatedSizes);
|
|
926
1160
|
} else {
|
|
927
|
-
const
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
932
|
-
// TODO
|
|
933
|
-
// Implicit default size calculations below do not account for inferred min/max size values.
|
|
934
|
-
// 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.
|
|
935
|
-
// For now, these logic edge cases are left to the user to handle via props.
|
|
936
|
-
|
|
937
|
-
panelsArray.forEach(panel => {
|
|
938
|
-
totalMinSize += panel.current.minSize;
|
|
939
|
-
if (panel.current.defaultSize === null) {
|
|
940
|
-
panelsWithNullDefaultSize++;
|
|
941
|
-
} else {
|
|
942
|
-
totalDefaultSize += panel.current.defaultSize;
|
|
943
|
-
}
|
|
1161
|
+
const sizes = calculateDefaultLayout({
|
|
1162
|
+
groupId,
|
|
1163
|
+
panels,
|
|
1164
|
+
units
|
|
944
1165
|
});
|
|
945
|
-
|
|
946
|
-
throw new Error(`Default panel sizes cannot exceed 100%`);
|
|
947
|
-
} else if (panelsArray.length > 1 && panelsWithNullDefaultSize === 0 && totalDefaultSize !== 100) {
|
|
948
|
-
throw new Error(`Invalid default sizes specified for panels`);
|
|
949
|
-
} else if (totalMinSize > 100) {
|
|
950
|
-
throw new Error(`Minimum panel sizes cannot exceed 100%`);
|
|
951
|
-
}
|
|
952
|
-
setSizes(panelsArray.map(panel => {
|
|
953
|
-
if (panel.current.defaultSize === null) {
|
|
954
|
-
return (100 - totalDefaultSize) / panelsWithNullDefaultSize;
|
|
955
|
-
}
|
|
956
|
-
return panel.current.defaultSize;
|
|
957
|
-
}));
|
|
1166
|
+
setSizes(sizes);
|
|
958
1167
|
}
|
|
959
1168
|
}, [autoSaveId, panels, storage]);
|
|
960
1169
|
useEffect(() => {
|
|
@@ -972,6 +1181,48 @@ function PanelGroupWithForwardedRef({
|
|
|
972
1181
|
debounceMap[autoSaveId](autoSaveId, panelsArray, sizes, storage);
|
|
973
1182
|
}
|
|
974
1183
|
}, [autoSaveId, panels, sizes, storage]);
|
|
1184
|
+
useIsomorphicLayoutEffect(() => {
|
|
1185
|
+
// Pixel panel constraints need to be reassessed after a group resize
|
|
1186
|
+
// We can avoid the ResizeObserver overhead for relative layouts
|
|
1187
|
+
if (units === "pixels") {
|
|
1188
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
1189
|
+
const {
|
|
1190
|
+
panels,
|
|
1191
|
+
sizes: prevSizes
|
|
1192
|
+
} = committedValuesRef.current;
|
|
1193
|
+
const nextSizes = validatePanelGroupLayout({
|
|
1194
|
+
groupId,
|
|
1195
|
+
panels,
|
|
1196
|
+
nextSizes: prevSizes,
|
|
1197
|
+
prevSizes,
|
|
1198
|
+
units
|
|
1199
|
+
});
|
|
1200
|
+
if (!areEqual(prevSizes, nextSizes)) {
|
|
1201
|
+
setSizes(nextSizes);
|
|
1202
|
+
}
|
|
1203
|
+
});
|
|
1204
|
+
resizeObserver.observe(getPanelGroup(groupId));
|
|
1205
|
+
return () => {
|
|
1206
|
+
resizeObserver.disconnect();
|
|
1207
|
+
};
|
|
1208
|
+
}
|
|
1209
|
+
}, [groupId, units]);
|
|
1210
|
+
const getPanelSize = useCallback((id, unitsFromParams) => {
|
|
1211
|
+
const {
|
|
1212
|
+
panels,
|
|
1213
|
+
units: unitsFromProps
|
|
1214
|
+
} = committedValuesRef.current;
|
|
1215
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
1216
|
+
const index = panelsArray.findIndex(panel => panel.current.id === id);
|
|
1217
|
+
const size = sizes[index];
|
|
1218
|
+
const units = unitsFromParams ?? unitsFromProps;
|
|
1219
|
+
if (units === "pixels") {
|
|
1220
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1221
|
+
return size / 100 * groupSizePixels;
|
|
1222
|
+
} else {
|
|
1223
|
+
return size;
|
|
1224
|
+
}
|
|
1225
|
+
}, [groupId, sizes]);
|
|
975
1226
|
const getPanelStyle = useCallback((id, defaultSize) => {
|
|
976
1227
|
const {
|
|
977
1228
|
panels
|
|
@@ -1002,6 +1253,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1002
1253
|
};
|
|
1003
1254
|
}, [activeHandleId, disablePointerEventsDuringResize, sizes]);
|
|
1004
1255
|
const registerPanel = useCallback((id, panelRef) => {
|
|
1256
|
+
const {
|
|
1257
|
+
units
|
|
1258
|
+
} = committedValuesRef.current;
|
|
1259
|
+
validatePanelProps(units, panelRef);
|
|
1005
1260
|
setPanels(prevPanels => {
|
|
1006
1261
|
if (prevPanels.has(id)) {
|
|
1007
1262
|
return prevPanels;
|
|
@@ -1038,7 +1293,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1038
1293
|
}
|
|
1039
1294
|
const size = isHorizontal ? rect.width : rect.height;
|
|
1040
1295
|
const delta = movement / size * 100;
|
|
1041
|
-
|
|
1296
|
+
|
|
1297
|
+
// If a validateLayout method has been provided
|
|
1298
|
+
// it's important to use it before updating the mouse cursor
|
|
1299
|
+
const nextSizes = adjustByDelta(event, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, initialDragStateRef.current);
|
|
1042
1300
|
const sizesChanged = !areEqual(prevSizes, nextSizes);
|
|
1043
1301
|
|
|
1044
1302
|
// Don't update cursor for resizes triggered by keyboard interactions.
|
|
@@ -1065,6 +1323,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1065
1323
|
}
|
|
1066
1324
|
if (sizesChanged) {
|
|
1067
1325
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1326
|
+
|
|
1327
|
+
// It's okay to bypass in this case because we already validated above
|
|
1068
1328
|
setSizes(nextSizes);
|
|
1069
1329
|
|
|
1070
1330
|
// If resize change handlers have been declared, this is the time to call them.
|
|
@@ -1118,7 +1378,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1118
1378
|
}
|
|
1119
1379
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1120
1380
|
const delta = isLastPanel ? currentSize : collapsedSize - currentSize;
|
|
1121
|
-
const nextSizes = adjustByDelta(null,
|
|
1381
|
+
const nextSizes = adjustByDelta(null, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1122
1382
|
if (prevSizes !== nextSizes) {
|
|
1123
1383
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1124
1384
|
setSizes(nextSizes);
|
|
@@ -1161,7 +1421,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1161
1421
|
}
|
|
1162
1422
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1163
1423
|
const delta = isLastPanel ? collapsedSize - sizeBeforeCollapse : sizeBeforeCollapse;
|
|
1164
|
-
const nextSizes = adjustByDelta(null,
|
|
1424
|
+
const nextSizes = adjustByDelta(null, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1165
1425
|
if (prevSizes !== nextSizes) {
|
|
1166
1426
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1167
1427
|
setSizes(nextSizes);
|
|
@@ -1171,21 +1431,34 @@ function PanelGroupWithForwardedRef({
|
|
|
1171
1431
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1172
1432
|
}
|
|
1173
1433
|
}, []);
|
|
1174
|
-
const resizePanel = useCallback((id, nextSize) => {
|
|
1434
|
+
const resizePanel = useCallback((id, nextSize, unitsFromParams) => {
|
|
1175
1435
|
const {
|
|
1436
|
+
id: groupId,
|
|
1176
1437
|
panels,
|
|
1177
|
-
sizes: prevSizes
|
|
1438
|
+
sizes: prevSizes,
|
|
1439
|
+
units
|
|
1178
1440
|
} = committedValuesRef.current;
|
|
1441
|
+
if ((unitsFromParams || units) === "pixels") {
|
|
1442
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1443
|
+
nextSize = nextSize / groupSizePixels * 100;
|
|
1444
|
+
}
|
|
1179
1445
|
const panel = panels.get(id);
|
|
1180
1446
|
if (panel == null) {
|
|
1181
1447
|
return;
|
|
1182
1448
|
}
|
|
1183
|
-
|
|
1449
|
+
let {
|
|
1184
1450
|
collapsedSize,
|
|
1185
1451
|
collapsible,
|
|
1186
1452
|
maxSize,
|
|
1187
1453
|
minSize
|
|
1188
1454
|
} = panel.current;
|
|
1455
|
+
if (units === "pixels") {
|
|
1456
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1457
|
+
minSize = minSize / groupSizePixels * 100;
|
|
1458
|
+
if (maxSize != null) {
|
|
1459
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
1460
|
+
}
|
|
1461
|
+
}
|
|
1189
1462
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
1190
1463
|
const index = panelsArray.indexOf(panel);
|
|
1191
1464
|
if (index < 0) {
|
|
@@ -1196,7 +1469,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1196
1469
|
return;
|
|
1197
1470
|
}
|
|
1198
1471
|
if (collapsible && nextSize === collapsedSize) ; else {
|
|
1199
|
-
nextSize = Math.min(maxSize, Math.max(minSize, nextSize));
|
|
1472
|
+
nextSize = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, nextSize));
|
|
1200
1473
|
}
|
|
1201
1474
|
const [idBefore, idAfter] = getBeforeAndAfterIds(id, panelsArray);
|
|
1202
1475
|
if (idBefore == null || idAfter == null) {
|
|
@@ -1204,7 +1477,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1204
1477
|
}
|
|
1205
1478
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1206
1479
|
const delta = isLastPanel ? currentSize - nextSize : nextSize - currentSize;
|
|
1207
|
-
const nextSizes = adjustByDelta(null,
|
|
1480
|
+
const nextSizes = adjustByDelta(null, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1208
1481
|
if (prevSizes !== nextSizes) {
|
|
1209
1482
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1210
1483
|
setSizes(nextSizes);
|
|
@@ -1219,6 +1492,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1219
1492
|
collapsePanel,
|
|
1220
1493
|
direction,
|
|
1221
1494
|
expandPanel,
|
|
1495
|
+
getPanelSize,
|
|
1222
1496
|
getPanelStyle,
|
|
1223
1497
|
groupId,
|
|
1224
1498
|
registerPanel,
|
|
@@ -1240,8 +1514,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1240
1514
|
setActiveHandleId(null);
|
|
1241
1515
|
initialDragStateRef.current = null;
|
|
1242
1516
|
},
|
|
1517
|
+
units,
|
|
1243
1518
|
unregisterPanel
|
|
1244
|
-
}), [activeHandleId, collapsePanel, direction, expandPanel, getPanelStyle, groupId, registerPanel, registerResizeHandle, resizePanel, unregisterPanel]);
|
|
1519
|
+
}), [activeHandleId, collapsePanel, direction, expandPanel, getPanelSize, getPanelStyle, groupId, registerPanel, registerResizeHandle, resizePanel, units, unregisterPanel]);
|
|
1245
1520
|
const style = {
|
|
1246
1521
|
display: "flex",
|
|
1247
1522
|
flexDirection: direction === "horizontal" ? "row" : "column",
|
|
@@ -1256,6 +1531,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1256
1531
|
"data-panel-group": "",
|
|
1257
1532
|
"data-panel-group-direction": direction,
|
|
1258
1533
|
"data-panel-group-id": groupId,
|
|
1534
|
+
"data-panel-group-units": units,
|
|
1259
1535
|
style: {
|
|
1260
1536
|
...style,
|
|
1261
1537
|
...styleFromProps
|
|
@@ -1405,4 +1681,4 @@ function PanelResizeHandle({
|
|
|
1405
1681
|
}
|
|
1406
1682
|
PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
1407
1683
|
|
|
1408
|
-
export { Panel, PanelGroup, PanelResizeHandle };
|
|
1684
|
+
export { Panel, PanelGroup, PanelResizeHandle, getAvailableGroupSizePixels };
|