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
|
@@ -69,8 +69,8 @@ function PanelWithForwardedRef({
|
|
|
69
69
|
defaultSize = null,
|
|
70
70
|
forwardedRef,
|
|
71
71
|
id: idFromProps = null,
|
|
72
|
-
maxSize =
|
|
73
|
-
minSize
|
|
72
|
+
maxSize = null,
|
|
73
|
+
minSize,
|
|
74
74
|
onCollapse = null,
|
|
75
75
|
onResize = null,
|
|
76
76
|
order = null,
|
|
@@ -85,11 +85,22 @@ function PanelWithForwardedRef({
|
|
|
85
85
|
const {
|
|
86
86
|
collapsePanel,
|
|
87
87
|
expandPanel,
|
|
88
|
+
getPanelSize,
|
|
88
89
|
getPanelStyle,
|
|
89
90
|
registerPanel,
|
|
90
91
|
resizePanel,
|
|
92
|
+
units,
|
|
91
93
|
unregisterPanel
|
|
92
94
|
} = context;
|
|
95
|
+
if (minSize == null) {
|
|
96
|
+
if (units === "percentages") {
|
|
97
|
+
// Mimics legacy default value for percentage based panel groups
|
|
98
|
+
minSize = 10;
|
|
99
|
+
} else {
|
|
100
|
+
// There is no meaningful minimum pixel default we can provide
|
|
101
|
+
minSize = 0;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
93
104
|
|
|
94
105
|
// Use a ref to guard against users passing inline props
|
|
95
106
|
const callbacksRef = useRef({
|
|
@@ -100,22 +111,6 @@ function PanelWithForwardedRef({
|
|
|
100
111
|
callbacksRef.current.onCollapse = onCollapse;
|
|
101
112
|
callbacksRef.current.onResize = onResize;
|
|
102
113
|
});
|
|
103
|
-
|
|
104
|
-
// Basic props validation
|
|
105
|
-
if (minSize < 0 || minSize > 100) {
|
|
106
|
-
throw Error(`Panel minSize must be between 0 and 100, but was ${minSize}`);
|
|
107
|
-
} else if (maxSize < 0 || maxSize > 100) {
|
|
108
|
-
throw Error(`Panel maxSize must be between 0 and 100, but was ${maxSize}`);
|
|
109
|
-
} else {
|
|
110
|
-
if (defaultSize !== null) {
|
|
111
|
-
if (defaultSize < 0 || defaultSize > 100) {
|
|
112
|
-
throw Error(`Panel defaultSize must be between 0 and 100, but was ${defaultSize}`);
|
|
113
|
-
} else if (minSize > defaultSize && !collapsible) {
|
|
114
|
-
console.error(`Panel minSize ${minSize} cannot be greater than defaultSize ${defaultSize}`);
|
|
115
|
-
defaultSize = minSize;
|
|
116
|
-
}
|
|
117
|
-
}
|
|
118
|
-
}
|
|
119
114
|
const style = getPanelStyle(panelId, defaultSize);
|
|
120
115
|
const committedValuesRef = useRef({
|
|
121
116
|
size: parseSizeFromStyle(style)
|
|
@@ -155,11 +150,14 @@ function PanelWithForwardedRef({
|
|
|
155
150
|
getCollapsed() {
|
|
156
151
|
return committedValuesRef.current.size === 0;
|
|
157
152
|
},
|
|
158
|
-
|
|
159
|
-
return
|
|
153
|
+
getId() {
|
|
154
|
+
return panelId;
|
|
160
155
|
},
|
|
161
|
-
|
|
162
|
-
|
|
156
|
+
getSize(units) {
|
|
157
|
+
return getPanelSize(panelId, units);
|
|
158
|
+
},
|
|
159
|
+
resize: (percentage, units) => resizePanel(panelId, percentage, units)
|
|
160
|
+
}), [collapsePanel, expandPanel, getPanelSize, panelId, resizePanel]);
|
|
163
161
|
return createElement(Type, {
|
|
164
162
|
children,
|
|
165
163
|
className: classNameFromProps,
|
|
@@ -195,7 +193,13 @@ function parseSizeFromStyle(style) {
|
|
|
195
193
|
|
|
196
194
|
const PRECISION = 10;
|
|
197
195
|
|
|
198
|
-
function adjustByDelta(event,
|
|
196
|
+
function adjustByDelta(event, committedValues, idBefore, idAfter, deltaPixels, prevSizes, panelSizeBeforeCollapse, initialDragState) {
|
|
197
|
+
const {
|
|
198
|
+
id: groupId,
|
|
199
|
+
panels,
|
|
200
|
+
units
|
|
201
|
+
} = committedValues;
|
|
202
|
+
const groupSizePixels = units === "pixels" ? getAvailableGroupSizePixels(groupId) : NaN;
|
|
199
203
|
const {
|
|
200
204
|
sizes: initialSizes
|
|
201
205
|
} = initialDragState || {};
|
|
@@ -203,9 +207,6 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
203
207
|
// If we're resizing by mouse or touch, use the initial sizes as a base.
|
|
204
208
|
// This has the benefit of causing force-collapsed panels to spring back open if drag is reversed.
|
|
205
209
|
const baseSizes = initialSizes || prevSizes;
|
|
206
|
-
if (delta === 0) {
|
|
207
|
-
return baseSizes;
|
|
208
|
-
}
|
|
209
210
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
210
211
|
const nextSizes = baseSizes.concat();
|
|
211
212
|
let deltaApplied = 0;
|
|
@@ -220,11 +221,11 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
220
221
|
|
|
221
222
|
// Max-bounds check the panel being expanded first.
|
|
222
223
|
{
|
|
223
|
-
const pivotId =
|
|
224
|
+
const pivotId = deltaPixels < 0 ? idAfter : idBefore;
|
|
224
225
|
const index = panelsArray.findIndex(panel => panel.current.id === pivotId);
|
|
225
226
|
const panel = panelsArray[index];
|
|
226
227
|
const baseSize = baseSizes[index];
|
|
227
|
-
const nextSize = safeResizePanel(panel, Math.abs(
|
|
228
|
+
const nextSize = safeResizePanel(units, groupSizePixels, panel, baseSize, baseSize + Math.abs(deltaPixels), event);
|
|
228
229
|
if (baseSize === nextSize) {
|
|
229
230
|
// If there's no room for the pivot panel to grow, we can ignore this drag update.
|
|
230
231
|
return baseSizes;
|
|
@@ -232,29 +233,29 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
232
233
|
if (nextSize === 0 && baseSize > 0) {
|
|
233
234
|
panelSizeBeforeCollapse.set(pivotId, baseSize);
|
|
234
235
|
}
|
|
235
|
-
|
|
236
|
+
deltaPixels = deltaPixels < 0 ? baseSize - nextSize : nextSize - baseSize;
|
|
236
237
|
}
|
|
237
238
|
}
|
|
238
|
-
let pivotId =
|
|
239
|
+
let pivotId = deltaPixels < 0 ? idBefore : idAfter;
|
|
239
240
|
let index = panelsArray.findIndex(panel => panel.current.id === pivotId);
|
|
240
241
|
while (true) {
|
|
241
242
|
const panel = panelsArray[index];
|
|
242
243
|
const baseSize = baseSizes[index];
|
|
243
|
-
const deltaRemaining = Math.abs(
|
|
244
|
-
const nextSize = safeResizePanel(panel,
|
|
244
|
+
const deltaRemaining = Math.abs(deltaPixels) - Math.abs(deltaApplied);
|
|
245
|
+
const nextSize = safeResizePanel(units, groupSizePixels, panel, baseSize, baseSize - deltaRemaining, event);
|
|
245
246
|
if (baseSize !== nextSize) {
|
|
246
247
|
if (nextSize === 0 && baseSize > 0) {
|
|
247
248
|
panelSizeBeforeCollapse.set(panel.current.id, baseSize);
|
|
248
249
|
}
|
|
249
250
|
deltaApplied += baseSize - nextSize;
|
|
250
251
|
nextSizes[index] = nextSize;
|
|
251
|
-
if (deltaApplied.toPrecision(PRECISION).localeCompare(Math.abs(
|
|
252
|
+
if (deltaApplied.toPrecision(PRECISION).localeCompare(Math.abs(deltaPixels).toPrecision(PRECISION), undefined, {
|
|
252
253
|
numeric: true
|
|
253
254
|
}) >= 0) {
|
|
254
255
|
break;
|
|
255
256
|
}
|
|
256
257
|
}
|
|
257
|
-
if (
|
|
258
|
+
if (deltaPixels < 0) {
|
|
258
259
|
if (--index < 0) {
|
|
259
260
|
break;
|
|
260
261
|
}
|
|
@@ -272,7 +273,7 @@ function adjustByDelta(event, panels, idBefore, idAfter, delta, prevSizes, panel
|
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
// Adjust the pivot panel before, but only by the amount that surrounding panels were able to shrink/contract.
|
|
275
|
-
pivotId =
|
|
276
|
+
pivotId = deltaPixels < 0 ? idAfter : idBefore;
|
|
276
277
|
index = panelsArray.findIndex(panel => panel.current.id === pivotId);
|
|
277
278
|
nextSizes[index] = baseSizes[index] + deltaApplied;
|
|
278
279
|
return nextSizes;
|
|
@@ -311,6 +312,89 @@ function callPanelCallbacks(panelsArray, sizes, panelIdToLastNotifiedSizeMap) {
|
|
|
311
312
|
}
|
|
312
313
|
});
|
|
313
314
|
}
|
|
315
|
+
function calculateDefaultLayout({
|
|
316
|
+
groupId,
|
|
317
|
+
panels,
|
|
318
|
+
units
|
|
319
|
+
}) {
|
|
320
|
+
const groupSizePixels = units === "pixels" ? getAvailableGroupSizePixels(groupId) : NaN;
|
|
321
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
322
|
+
const sizes = Array(panelsArray.length);
|
|
323
|
+
let numPanelsWithSizes = 0;
|
|
324
|
+
let remainingSize = 100;
|
|
325
|
+
|
|
326
|
+
// Assigning default sizes requires a couple of passes:
|
|
327
|
+
// First, all panels with defaultSize should be set as-is
|
|
328
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
329
|
+
const panel = panelsArray[index];
|
|
330
|
+
const {
|
|
331
|
+
defaultSize
|
|
332
|
+
} = panel.current;
|
|
333
|
+
if (defaultSize != null) {
|
|
334
|
+
numPanelsWithSizes++;
|
|
335
|
+
sizes[index] = units === "pixels" ? defaultSize / groupSizePixels * 100 : defaultSize;
|
|
336
|
+
remainingSize -= sizes[index];
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
// Remaining total size should be distributed evenly between panels
|
|
341
|
+
// This may require two passes, depending on min/max constraints
|
|
342
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
343
|
+
const panel = panelsArray[index];
|
|
344
|
+
let {
|
|
345
|
+
defaultSize,
|
|
346
|
+
id,
|
|
347
|
+
maxSize,
|
|
348
|
+
minSize
|
|
349
|
+
} = panel.current;
|
|
350
|
+
if (defaultSize != null) {
|
|
351
|
+
continue;
|
|
352
|
+
}
|
|
353
|
+
if (units === "pixels") {
|
|
354
|
+
minSize = minSize / groupSizePixels * 100;
|
|
355
|
+
if (maxSize != null) {
|
|
356
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
const remainingPanels = panelsArray.length - numPanelsWithSizes;
|
|
360
|
+
const size = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, remainingSize / remainingPanels));
|
|
361
|
+
sizes[index] = size;
|
|
362
|
+
numPanelsWithSizes++;
|
|
363
|
+
remainingSize -= size;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// If there is additional, left over space, assign it to any panel(s) that permits it
|
|
367
|
+
// (It's not worth taking multiple additional passes to evenly distribute)
|
|
368
|
+
if (remainingSize !== 0) {
|
|
369
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
370
|
+
const panel = panelsArray[index];
|
|
371
|
+
let {
|
|
372
|
+
maxSize,
|
|
373
|
+
minSize
|
|
374
|
+
} = panel.current;
|
|
375
|
+
if (units === "pixels") {
|
|
376
|
+
minSize = minSize / groupSizePixels * 100;
|
|
377
|
+
if (maxSize != null) {
|
|
378
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
const size = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, sizes[index] + remainingSize));
|
|
382
|
+
if (size !== sizes[index]) {
|
|
383
|
+
remainingSize -= size - sizes[index];
|
|
384
|
+
sizes[index] = size;
|
|
385
|
+
|
|
386
|
+
// Fuzzy comparison to account for imprecise floating point math
|
|
387
|
+
if (Math.abs(remainingSize).toFixed(3) === "0.000") {
|
|
388
|
+
break;
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
// Finally, if there is still left-over size, log an error
|
|
395
|
+
if (Math.abs(remainingSize).toFixed(3) !== "0.000") ;
|
|
396
|
+
return sizes;
|
|
397
|
+
}
|
|
314
398
|
function getBeforeAndAfterIds(id, panelsArray) {
|
|
315
399
|
if (panelsArray.length < 2) {
|
|
316
400
|
return [null, null];
|
|
@@ -324,6 +408,23 @@ function getBeforeAndAfterIds(id, panelsArray) {
|
|
|
324
408
|
const idAfter = isLastPanel ? id : panelsArray[index + 1].current.id;
|
|
325
409
|
return [idBefore, idAfter];
|
|
326
410
|
}
|
|
411
|
+
function getAvailableGroupSizePixels(groupId) {
|
|
412
|
+
const panelGroupElement = getPanelGroup(groupId);
|
|
413
|
+
if (panelGroupElement == null) {
|
|
414
|
+
return NaN;
|
|
415
|
+
}
|
|
416
|
+
const direction = panelGroupElement.getAttribute("data-panel-group-direction");
|
|
417
|
+
const resizeHandles = getResizeHandlesForGroup(groupId);
|
|
418
|
+
if (direction === "horizontal") {
|
|
419
|
+
return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
|
|
420
|
+
return accumulated + handle.offsetWidth;
|
|
421
|
+
}, 0);
|
|
422
|
+
} else {
|
|
423
|
+
return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
|
|
424
|
+
return accumulated + handle.offsetHeight;
|
|
425
|
+
}, 0);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
327
428
|
|
|
328
429
|
// This method returns a number between 1 and 100 representing
|
|
329
430
|
// the % of the group's overall space this panel should occupy.
|
|
@@ -394,18 +495,24 @@ function panelsMapToSortedArray(panels) {
|
|
|
394
495
|
}
|
|
395
496
|
});
|
|
396
497
|
}
|
|
397
|
-
function safeResizePanel(
|
|
398
|
-
|
|
399
|
-
const {
|
|
498
|
+
function safeResizePanel(units, groupSizePixels, panel, prevSize, nextSize, event = null) {
|
|
499
|
+
let {
|
|
400
500
|
collapsedSize,
|
|
401
501
|
collapsible,
|
|
402
502
|
maxSize,
|
|
403
503
|
minSize
|
|
404
504
|
} = panel.current;
|
|
505
|
+
if (units === "pixels") {
|
|
506
|
+
collapsedSize = collapsedSize / groupSizePixels * 100;
|
|
507
|
+
if (maxSize != null) {
|
|
508
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
509
|
+
}
|
|
510
|
+
minSize = minSize / groupSizePixels * 100;
|
|
511
|
+
}
|
|
405
512
|
if (collapsible) {
|
|
406
513
|
if (prevSize > collapsedSize) {
|
|
407
514
|
// Mimic VS COde behavior; collapse a panel if it's smaller than half of its min-size
|
|
408
|
-
if (
|
|
515
|
+
if (nextSize <= minSize / 2 + collapsedSize) {
|
|
409
516
|
return collapsedSize;
|
|
410
517
|
}
|
|
411
518
|
} else {
|
|
@@ -414,14 +521,97 @@ function safeResizePanel(panel, delta, prevSize, event) {
|
|
|
414
521
|
// Keyboard events should expand a collapsed panel to the min size,
|
|
415
522
|
// but mouse events should wait until the panel has reached its min size
|
|
416
523
|
// to avoid a visual flickering when dragging between collapsed and min size.
|
|
417
|
-
if (
|
|
524
|
+
if (nextSize < minSize) {
|
|
418
525
|
return collapsedSize;
|
|
419
526
|
}
|
|
420
527
|
}
|
|
421
528
|
}
|
|
422
529
|
}
|
|
423
|
-
|
|
424
|
-
|
|
530
|
+
return Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, nextSize));
|
|
531
|
+
}
|
|
532
|
+
function validatePanelProps(units, panelData) {
|
|
533
|
+
const {
|
|
534
|
+
collapsible,
|
|
535
|
+
defaultSize,
|
|
536
|
+
maxSize,
|
|
537
|
+
minSize
|
|
538
|
+
} = panelData.current;
|
|
539
|
+
|
|
540
|
+
// Basic props validation
|
|
541
|
+
if (minSize < 0 || units === "percentages" && minSize > 100) {
|
|
542
|
+
panelData.current.minSize = 0;
|
|
543
|
+
}
|
|
544
|
+
if (maxSize != null) {
|
|
545
|
+
if (maxSize < 0 || units === "percentages" && maxSize > 100) {
|
|
546
|
+
panelData.current.maxSize = null;
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
if (defaultSize !== null) {
|
|
550
|
+
if (defaultSize < 0 || units === "percentages" && defaultSize > 100) {
|
|
551
|
+
panelData.current.defaultSize = null;
|
|
552
|
+
} else if (defaultSize < minSize && !collapsible) {
|
|
553
|
+
panelData.current.defaultSize = minSize;
|
|
554
|
+
} else if (maxSize != null && defaultSize > maxSize) {
|
|
555
|
+
panelData.current.defaultSize = maxSize;
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
function validatePanelGroupLayout({
|
|
560
|
+
groupId,
|
|
561
|
+
panels,
|
|
562
|
+
nextSizes,
|
|
563
|
+
prevSizes,
|
|
564
|
+
units
|
|
565
|
+
}) {
|
|
566
|
+
// Clone because this method modifies
|
|
567
|
+
nextSizes = [...nextSizes];
|
|
568
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
569
|
+
const groupSizePixels = units === "pixels" ? getAvailableGroupSizePixels(groupId) : NaN;
|
|
570
|
+
let remainingSize = 0;
|
|
571
|
+
|
|
572
|
+
// First, check all of the proposed sizes against the min/max constraints
|
|
573
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
574
|
+
const panel = panelsArray[index];
|
|
575
|
+
const prevSize = prevSizes[index];
|
|
576
|
+
const nextSize = nextSizes[index];
|
|
577
|
+
const safeNextSize = safeResizePanel(units, groupSizePixels, panel, prevSize, nextSize);
|
|
578
|
+
if (nextSize != safeNextSize) {
|
|
579
|
+
remainingSize += nextSize - safeNextSize;
|
|
580
|
+
nextSizes[index] = safeNextSize;
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// If there is additional, left over space, assign it to any panel(s) that permits it
|
|
585
|
+
// (It's not worth taking multiple additional passes to evenly distribute)
|
|
586
|
+
if (remainingSize.toFixed(3) !== "0.000") {
|
|
587
|
+
for (let index = 0; index < panelsArray.length; index++) {
|
|
588
|
+
const panel = panelsArray[index];
|
|
589
|
+
let {
|
|
590
|
+
maxSize,
|
|
591
|
+
minSize
|
|
592
|
+
} = panel.current;
|
|
593
|
+
if (units === "pixels") {
|
|
594
|
+
minSize = minSize / groupSizePixels * 100;
|
|
595
|
+
if (maxSize != null) {
|
|
596
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
const size = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, nextSizes[index] + remainingSize));
|
|
600
|
+
if (size !== nextSizes[index]) {
|
|
601
|
+
remainingSize -= size - nextSizes[index];
|
|
602
|
+
nextSizes[index] = size;
|
|
603
|
+
|
|
604
|
+
// Fuzzy comparison to account for imprecise floating point math
|
|
605
|
+
if (Math.abs(remainingSize).toFixed(3) === "0.000") {
|
|
606
|
+
break;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
}
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
// If we still have remainder, the requested layout wasn't valid and we should warn about it
|
|
613
|
+
if (remainingSize.toFixed(3) !== "0.000") ;
|
|
614
|
+
return nextSizes;
|
|
425
615
|
}
|
|
426
616
|
|
|
427
617
|
function assert(expectedCondition, message = "Assertion failed!") {
|
|
@@ -447,6 +637,7 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
447
637
|
panels
|
|
448
638
|
} = committedValuesRef.current;
|
|
449
639
|
const groupElement = getPanelGroup(groupId);
|
|
640
|
+
assert(groupElement != null, `No group found for id "${groupId}"`);
|
|
450
641
|
const {
|
|
451
642
|
height,
|
|
452
643
|
width
|
|
@@ -459,23 +650,28 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
459
650
|
if (idBefore == null || idAfter == null) {
|
|
460
651
|
return () => {};
|
|
461
652
|
}
|
|
462
|
-
let
|
|
463
|
-
let
|
|
653
|
+
let currentMinSize = 0;
|
|
654
|
+
let currentMaxSize = 100;
|
|
464
655
|
let totalMinSize = 0;
|
|
465
656
|
let totalMaxSize = 0;
|
|
466
657
|
|
|
467
658
|
// A panel's effective min/max sizes also need to account for other panel's sizes.
|
|
468
659
|
panelsArray.forEach(panelData => {
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
660
|
+
const {
|
|
661
|
+
id,
|
|
662
|
+
maxSize,
|
|
663
|
+
minSize
|
|
664
|
+
} = panelData.current;
|
|
665
|
+
if (id === idBefore) {
|
|
666
|
+
currentMinSize = minSize;
|
|
667
|
+
currentMaxSize = maxSize != null ? maxSize : 100;
|
|
472
668
|
} else {
|
|
473
|
-
totalMinSize +=
|
|
474
|
-
totalMaxSize +=
|
|
669
|
+
totalMinSize += minSize;
|
|
670
|
+
totalMaxSize += maxSize != null ? maxSize : 100;
|
|
475
671
|
}
|
|
476
672
|
});
|
|
477
|
-
const ariaValueMax = Math.min(
|
|
478
|
-
const ariaValueMin = Math.max(
|
|
673
|
+
const ariaValueMax = Math.min(currentMaxSize, 100 - totalMinSize);
|
|
674
|
+
const ariaValueMin = Math.max(currentMinSize, (panelsArray.length - 1) * 100 - totalMaxSize);
|
|
479
675
|
const flexGrow = getFlexGrow(panels, idBefore, sizes);
|
|
480
676
|
handle.setAttribute("aria-valuemax", "" + Math.round(ariaValueMax));
|
|
481
677
|
handle.setAttribute("aria-valuemin", "" + Math.round(ariaValueMin));
|
|
@@ -499,7 +695,7 @@ function useWindowSplitterPanelGroupBehavior({
|
|
|
499
695
|
} else {
|
|
500
696
|
delta = -(direction === "horizontal" ? width : height);
|
|
501
697
|
}
|
|
502
|
-
const nextSizes = adjustByDelta(event,
|
|
698
|
+
const nextSizes = adjustByDelta(event, committedValuesRef.current, idBefore, idAfter, delta, sizes, panelSizeBeforeCollapse.current, null);
|
|
503
699
|
if (sizes !== nextSizes) {
|
|
504
700
|
setSizes(nextSizes);
|
|
505
701
|
}
|
|
@@ -814,9 +1010,6 @@ const defaultStorage = {
|
|
|
814
1010
|
// * dragHandleRect, sizes:
|
|
815
1011
|
// When resizing is done via mouse/touch event– some initial state is stored
|
|
816
1012
|
// so that any panels that contract will also expand if drag direction is reversed.
|
|
817
|
-
// TODO
|
|
818
|
-
// Within an active drag, remember original positions to refine more easily on expand.
|
|
819
|
-
// Look at what the Chrome devtools Sources does.
|
|
820
1013
|
function PanelGroupWithForwardedRef({
|
|
821
1014
|
autoSaveId,
|
|
822
1015
|
children = null,
|
|
@@ -828,7 +1021,8 @@ function PanelGroupWithForwardedRef({
|
|
|
828
1021
|
onLayout,
|
|
829
1022
|
storage = defaultStorage,
|
|
830
1023
|
style: styleFromProps = {},
|
|
831
|
-
tagName: Type = "div"
|
|
1024
|
+
tagName: Type = "div",
|
|
1025
|
+
units = "percentages"
|
|
832
1026
|
}) {
|
|
833
1027
|
const groupId = useUniqueId(idFromProps);
|
|
834
1028
|
const [activeHandleId, setActiveHandleId] = useState(null);
|
|
@@ -841,6 +1035,7 @@ function PanelGroupWithForwardedRef({
|
|
|
841
1035
|
useRef({
|
|
842
1036
|
didLogDefaultSizeWarning: false,
|
|
843
1037
|
didLogIdAndOrderWarning: false,
|
|
1038
|
+
didLogInvalidLayoutWarning: false,
|
|
844
1039
|
prevPanelIds: []
|
|
845
1040
|
});
|
|
846
1041
|
|
|
@@ -863,32 +1058,58 @@ function PanelGroupWithForwardedRef({
|
|
|
863
1058
|
// Store committed values to avoid unnecessarily re-running memoization/effects functions.
|
|
864
1059
|
const committedValuesRef = useRef({
|
|
865
1060
|
direction,
|
|
1061
|
+
id: groupId,
|
|
866
1062
|
panels,
|
|
867
|
-
sizes
|
|
1063
|
+
sizes,
|
|
1064
|
+
units
|
|
868
1065
|
});
|
|
869
1066
|
useImperativeHandle(forwardedRef, () => ({
|
|
870
|
-
|
|
1067
|
+
getId: () => groupId,
|
|
1068
|
+
getLayout: unitsFromParams => {
|
|
871
1069
|
const {
|
|
872
|
-
sizes
|
|
1070
|
+
sizes,
|
|
1071
|
+
units: unitsFromProps
|
|
873
1072
|
} = committedValuesRef.current;
|
|
874
|
-
|
|
1073
|
+
const units = unitsFromParams ?? unitsFromProps;
|
|
1074
|
+
if (units === "pixels") {
|
|
1075
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1076
|
+
return sizes.map(size => size / 100 * groupSizePixels);
|
|
1077
|
+
} else {
|
|
1078
|
+
return sizes;
|
|
1079
|
+
}
|
|
875
1080
|
},
|
|
876
|
-
setLayout: sizes => {
|
|
877
|
-
const total = sizes.reduce((accumulated, current) => accumulated + current, 0);
|
|
878
|
-
assert(total === 100, "Panel sizes must add up to 100%");
|
|
1081
|
+
setLayout: (sizes, unitsFromParams) => {
|
|
879
1082
|
const {
|
|
880
|
-
|
|
1083
|
+
id: groupId,
|
|
1084
|
+
panels,
|
|
1085
|
+
sizes: prevSizes,
|
|
1086
|
+
units
|
|
881
1087
|
} = committedValuesRef.current;
|
|
1088
|
+
if ((unitsFromParams || units) === "pixels") {
|
|
1089
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1090
|
+
sizes = sizes.map(size => size / groupSizePixels * 100);
|
|
1091
|
+
}
|
|
882
1092
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
883
1093
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
884
|
-
|
|
885
|
-
|
|
1094
|
+
const nextSizes = validatePanelGroupLayout({
|
|
1095
|
+
groupId,
|
|
1096
|
+
panels,
|
|
1097
|
+
nextSizes: sizes,
|
|
1098
|
+
prevSizes,
|
|
1099
|
+
units
|
|
1100
|
+
});
|
|
1101
|
+
if (!areEqual(prevSizes, nextSizes)) {
|
|
1102
|
+
setSizes(nextSizes);
|
|
1103
|
+
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1104
|
+
}
|
|
886
1105
|
}
|
|
887
|
-
}), []);
|
|
1106
|
+
}), [groupId]);
|
|
888
1107
|
useIsomorphicLayoutEffect(() => {
|
|
889
1108
|
committedValuesRef.current.direction = direction;
|
|
1109
|
+
committedValuesRef.current.id = groupId;
|
|
890
1110
|
committedValuesRef.current.panels = panels;
|
|
891
1111
|
committedValuesRef.current.sizes = sizes;
|
|
1112
|
+
committedValuesRef.current.units = units;
|
|
892
1113
|
});
|
|
893
1114
|
useWindowSplitterPanelGroupBehavior({
|
|
894
1115
|
committedValuesRef,
|
|
@@ -930,7 +1151,11 @@ function PanelGroupWithForwardedRef({
|
|
|
930
1151
|
// Compute the initial sizes based on default weights.
|
|
931
1152
|
// This assumes that panels register during initial mount (no conditional rendering)!
|
|
932
1153
|
useIsomorphicLayoutEffect(() => {
|
|
933
|
-
const
|
|
1154
|
+
const {
|
|
1155
|
+
id: groupId,
|
|
1156
|
+
sizes,
|
|
1157
|
+
units
|
|
1158
|
+
} = committedValuesRef.current;
|
|
934
1159
|
if (sizes.length === panels.size) {
|
|
935
1160
|
// Only compute (or restore) default sizes once per panel configuration.
|
|
936
1161
|
return;
|
|
@@ -944,39 +1169,23 @@ function PanelGroupWithForwardedRef({
|
|
|
944
1169
|
defaultSizes = loadPanelLayout(autoSaveId, panelsArray, storage);
|
|
945
1170
|
}
|
|
946
1171
|
if (defaultSizes != null) {
|
|
947
|
-
|
|
1172
|
+
// Validate saved sizes in case something has changed since last render
|
|
1173
|
+
// e.g. for pixel groups, this could be the size of the window
|
|
1174
|
+
const validatedSizes = validatePanelGroupLayout({
|
|
1175
|
+
groupId,
|
|
1176
|
+
panels,
|
|
1177
|
+
nextSizes: defaultSizes,
|
|
1178
|
+
prevSizes: defaultSizes,
|
|
1179
|
+
units
|
|
1180
|
+
});
|
|
1181
|
+
setSizes(validatedSizes);
|
|
948
1182
|
} else {
|
|
949
|
-
const
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
// TODO
|
|
955
|
-
// Implicit default size calculations below do not account for inferred min/max size values.
|
|
956
|
-
// 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.
|
|
957
|
-
// For now, these logic edge cases are left to the user to handle via props.
|
|
958
|
-
|
|
959
|
-
panelsArray.forEach(panel => {
|
|
960
|
-
totalMinSize += panel.current.minSize;
|
|
961
|
-
if (panel.current.defaultSize === null) {
|
|
962
|
-
panelsWithNullDefaultSize++;
|
|
963
|
-
} else {
|
|
964
|
-
totalDefaultSize += panel.current.defaultSize;
|
|
965
|
-
}
|
|
1183
|
+
const sizes = calculateDefaultLayout({
|
|
1184
|
+
groupId,
|
|
1185
|
+
panels,
|
|
1186
|
+
units
|
|
966
1187
|
});
|
|
967
|
-
|
|
968
|
-
throw new Error(`Default panel sizes cannot exceed 100%`);
|
|
969
|
-
} else if (panelsArray.length > 1 && panelsWithNullDefaultSize === 0 && totalDefaultSize !== 100) {
|
|
970
|
-
throw new Error(`Invalid default sizes specified for panels`);
|
|
971
|
-
} else if (totalMinSize > 100) {
|
|
972
|
-
throw new Error(`Minimum panel sizes cannot exceed 100%`);
|
|
973
|
-
}
|
|
974
|
-
setSizes(panelsArray.map(panel => {
|
|
975
|
-
if (panel.current.defaultSize === null) {
|
|
976
|
-
return (100 - totalDefaultSize) / panelsWithNullDefaultSize;
|
|
977
|
-
}
|
|
978
|
-
return panel.current.defaultSize;
|
|
979
|
-
}));
|
|
1188
|
+
setSizes(sizes);
|
|
980
1189
|
}
|
|
981
1190
|
}, [autoSaveId, panels, storage]);
|
|
982
1191
|
useEffect(() => {
|
|
@@ -994,6 +1203,48 @@ function PanelGroupWithForwardedRef({
|
|
|
994
1203
|
debounceMap[autoSaveId](autoSaveId, panelsArray, sizes, storage);
|
|
995
1204
|
}
|
|
996
1205
|
}, [autoSaveId, panels, sizes, storage]);
|
|
1206
|
+
useIsomorphicLayoutEffect(() => {
|
|
1207
|
+
// Pixel panel constraints need to be reassessed after a group resize
|
|
1208
|
+
// We can avoid the ResizeObserver overhead for relative layouts
|
|
1209
|
+
if (units === "pixels") {
|
|
1210
|
+
const resizeObserver = new ResizeObserver(() => {
|
|
1211
|
+
const {
|
|
1212
|
+
panels,
|
|
1213
|
+
sizes: prevSizes
|
|
1214
|
+
} = committedValuesRef.current;
|
|
1215
|
+
const nextSizes = validatePanelGroupLayout({
|
|
1216
|
+
groupId,
|
|
1217
|
+
panels,
|
|
1218
|
+
nextSizes: prevSizes,
|
|
1219
|
+
prevSizes,
|
|
1220
|
+
units
|
|
1221
|
+
});
|
|
1222
|
+
if (!areEqual(prevSizes, nextSizes)) {
|
|
1223
|
+
setSizes(nextSizes);
|
|
1224
|
+
}
|
|
1225
|
+
});
|
|
1226
|
+
resizeObserver.observe(getPanelGroup(groupId));
|
|
1227
|
+
return () => {
|
|
1228
|
+
resizeObserver.disconnect();
|
|
1229
|
+
};
|
|
1230
|
+
}
|
|
1231
|
+
}, [groupId, units]);
|
|
1232
|
+
const getPanelSize = useCallback((id, unitsFromParams) => {
|
|
1233
|
+
const {
|
|
1234
|
+
panels,
|
|
1235
|
+
units: unitsFromProps
|
|
1236
|
+
} = committedValuesRef.current;
|
|
1237
|
+
const panelsArray = panelsMapToSortedArray(panels);
|
|
1238
|
+
const index = panelsArray.findIndex(panel => panel.current.id === id);
|
|
1239
|
+
const size = sizes[index];
|
|
1240
|
+
const units = unitsFromParams ?? unitsFromProps;
|
|
1241
|
+
if (units === "pixels") {
|
|
1242
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1243
|
+
return size / 100 * groupSizePixels;
|
|
1244
|
+
} else {
|
|
1245
|
+
return size;
|
|
1246
|
+
}
|
|
1247
|
+
}, [groupId, sizes]);
|
|
997
1248
|
const getPanelStyle = useCallback((id, defaultSize) => {
|
|
998
1249
|
const {
|
|
999
1250
|
panels
|
|
@@ -1024,6 +1275,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1024
1275
|
};
|
|
1025
1276
|
}, [activeHandleId, disablePointerEventsDuringResize, sizes]);
|
|
1026
1277
|
const registerPanel = useCallback((id, panelRef) => {
|
|
1278
|
+
const {
|
|
1279
|
+
units
|
|
1280
|
+
} = committedValuesRef.current;
|
|
1281
|
+
validatePanelProps(units, panelRef);
|
|
1027
1282
|
setPanels(prevPanels => {
|
|
1028
1283
|
if (prevPanels.has(id)) {
|
|
1029
1284
|
return prevPanels;
|
|
@@ -1060,7 +1315,10 @@ function PanelGroupWithForwardedRef({
|
|
|
1060
1315
|
}
|
|
1061
1316
|
const size = isHorizontal ? rect.width : rect.height;
|
|
1062
1317
|
const delta = movement / size * 100;
|
|
1063
|
-
|
|
1318
|
+
|
|
1319
|
+
// If a validateLayout method has been provided
|
|
1320
|
+
// it's important to use it before updating the mouse cursor
|
|
1321
|
+
const nextSizes = adjustByDelta(event, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, initialDragStateRef.current);
|
|
1064
1322
|
const sizesChanged = !areEqual(prevSizes, nextSizes);
|
|
1065
1323
|
|
|
1066
1324
|
// Don't update cursor for resizes triggered by keyboard interactions.
|
|
@@ -1087,6 +1345,8 @@ function PanelGroupWithForwardedRef({
|
|
|
1087
1345
|
}
|
|
1088
1346
|
if (sizesChanged) {
|
|
1089
1347
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1348
|
+
|
|
1349
|
+
// It's okay to bypass in this case because we already validated above
|
|
1090
1350
|
setSizes(nextSizes);
|
|
1091
1351
|
|
|
1092
1352
|
// If resize change handlers have been declared, this is the time to call them.
|
|
@@ -1140,7 +1400,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1140
1400
|
}
|
|
1141
1401
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1142
1402
|
const delta = isLastPanel ? currentSize : collapsedSize - currentSize;
|
|
1143
|
-
const nextSizes = adjustByDelta(null,
|
|
1403
|
+
const nextSizes = adjustByDelta(null, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1144
1404
|
if (prevSizes !== nextSizes) {
|
|
1145
1405
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1146
1406
|
setSizes(nextSizes);
|
|
@@ -1183,7 +1443,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1183
1443
|
}
|
|
1184
1444
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1185
1445
|
const delta = isLastPanel ? collapsedSize - sizeBeforeCollapse : sizeBeforeCollapse;
|
|
1186
|
-
const nextSizes = adjustByDelta(null,
|
|
1446
|
+
const nextSizes = adjustByDelta(null, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1187
1447
|
if (prevSizes !== nextSizes) {
|
|
1188
1448
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1189
1449
|
setSizes(nextSizes);
|
|
@@ -1193,21 +1453,34 @@ function PanelGroupWithForwardedRef({
|
|
|
1193
1453
|
callPanelCallbacks(panelsArray, nextSizes, panelIdToLastNotifiedSizeMap);
|
|
1194
1454
|
}
|
|
1195
1455
|
}, []);
|
|
1196
|
-
const resizePanel = useCallback((id, nextSize) => {
|
|
1456
|
+
const resizePanel = useCallback((id, nextSize, unitsFromParams) => {
|
|
1197
1457
|
const {
|
|
1458
|
+
id: groupId,
|
|
1198
1459
|
panels,
|
|
1199
|
-
sizes: prevSizes
|
|
1460
|
+
sizes: prevSizes,
|
|
1461
|
+
units
|
|
1200
1462
|
} = committedValuesRef.current;
|
|
1463
|
+
if ((unitsFromParams || units) === "pixels") {
|
|
1464
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1465
|
+
nextSize = nextSize / groupSizePixels * 100;
|
|
1466
|
+
}
|
|
1201
1467
|
const panel = panels.get(id);
|
|
1202
1468
|
if (panel == null) {
|
|
1203
1469
|
return;
|
|
1204
1470
|
}
|
|
1205
|
-
|
|
1471
|
+
let {
|
|
1206
1472
|
collapsedSize,
|
|
1207
1473
|
collapsible,
|
|
1208
1474
|
maxSize,
|
|
1209
1475
|
minSize
|
|
1210
1476
|
} = panel.current;
|
|
1477
|
+
if (units === "pixels") {
|
|
1478
|
+
const groupSizePixels = getAvailableGroupSizePixels(groupId);
|
|
1479
|
+
minSize = minSize / groupSizePixels * 100;
|
|
1480
|
+
if (maxSize != null) {
|
|
1481
|
+
maxSize = maxSize / groupSizePixels * 100;
|
|
1482
|
+
}
|
|
1483
|
+
}
|
|
1211
1484
|
const panelsArray = panelsMapToSortedArray(panels);
|
|
1212
1485
|
const index = panelsArray.indexOf(panel);
|
|
1213
1486
|
if (index < 0) {
|
|
@@ -1218,7 +1491,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1218
1491
|
return;
|
|
1219
1492
|
}
|
|
1220
1493
|
if (collapsible && nextSize === collapsedSize) ; else {
|
|
1221
|
-
nextSize = Math.min(maxSize, Math.max(minSize, nextSize));
|
|
1494
|
+
nextSize = Math.min(maxSize != null ? maxSize : 100, Math.max(minSize, nextSize));
|
|
1222
1495
|
}
|
|
1223
1496
|
const [idBefore, idAfter] = getBeforeAndAfterIds(id, panelsArray);
|
|
1224
1497
|
if (idBefore == null || idAfter == null) {
|
|
@@ -1226,7 +1499,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1226
1499
|
}
|
|
1227
1500
|
const isLastPanel = index === panelsArray.length - 1;
|
|
1228
1501
|
const delta = isLastPanel ? currentSize - nextSize : nextSize - currentSize;
|
|
1229
|
-
const nextSizes = adjustByDelta(null,
|
|
1502
|
+
const nextSizes = adjustByDelta(null, committedValuesRef.current, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
|
|
1230
1503
|
if (prevSizes !== nextSizes) {
|
|
1231
1504
|
const panelIdToLastNotifiedSizeMap = panelIdToLastNotifiedSizeMapRef.current;
|
|
1232
1505
|
setSizes(nextSizes);
|
|
@@ -1241,6 +1514,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1241
1514
|
collapsePanel,
|
|
1242
1515
|
direction,
|
|
1243
1516
|
expandPanel,
|
|
1517
|
+
getPanelSize,
|
|
1244
1518
|
getPanelStyle,
|
|
1245
1519
|
groupId,
|
|
1246
1520
|
registerPanel,
|
|
@@ -1262,8 +1536,9 @@ function PanelGroupWithForwardedRef({
|
|
|
1262
1536
|
setActiveHandleId(null);
|
|
1263
1537
|
initialDragStateRef.current = null;
|
|
1264
1538
|
},
|
|
1539
|
+
units,
|
|
1265
1540
|
unregisterPanel
|
|
1266
|
-
}), [activeHandleId, collapsePanel, direction, expandPanel, getPanelStyle, groupId, registerPanel, registerResizeHandle, resizePanel, unregisterPanel]);
|
|
1541
|
+
}), [activeHandleId, collapsePanel, direction, expandPanel, getPanelSize, getPanelStyle, groupId, registerPanel, registerResizeHandle, resizePanel, units, unregisterPanel]);
|
|
1267
1542
|
const style = {
|
|
1268
1543
|
display: "flex",
|
|
1269
1544
|
flexDirection: direction === "horizontal" ? "row" : "column",
|
|
@@ -1278,6 +1553,7 @@ function PanelGroupWithForwardedRef({
|
|
|
1278
1553
|
"data-panel-group": "",
|
|
1279
1554
|
"data-panel-group-direction": direction,
|
|
1280
1555
|
"data-panel-group-id": groupId,
|
|
1556
|
+
"data-panel-group-units": units,
|
|
1281
1557
|
style: {
|
|
1282
1558
|
...style,
|
|
1283
1559
|
...styleFromProps
|
|
@@ -1430,3 +1706,4 @@ PanelResizeHandle.displayName = "PanelResizeHandle";
|
|
|
1430
1706
|
exports.Panel = Panel;
|
|
1431
1707
|
exports.PanelGroup = PanelGroup;
|
|
1432
1708
|
exports.PanelResizeHandle = PanelResizeHandle;
|
|
1709
|
+
exports.getAvailableGroupSizePixels = getAvailableGroupSizePixels;
|