react-resizable-panels 0.0.32 → 0.0.34

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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.0.34
4
+ * [#85](https://github.com/bvaughn/react-resizable-panels/issues/85): Add optional `storage` prop to `PanelGroup` to make it easier to persist layouts somewhere other than `localStorage` (e.g. like a Cookie).
5
+ * [#70](https://github.com/bvaughn/react-resizable-panels/issues/70): When resizing is done via mouse/touch event– some initial state is stored so that any panels that contract will also expand if drag direction is reversed.
6
+ * [#86](https://github.com/bvaughn/react-resizable-panels/issues/86): Layout changes triggered by keyboard no longer affect the global cursor.
7
+ * Fixed small cursor regression introduced in 0.0.33.
8
+
9
+ ## 0.0.33
10
+ * Collapsible `Panel`s will always call `onCollapse` on-mount regardless of their collapsed state.
11
+ * Fixed regression in b5d3ec1 where arrow keys may fail to expand a collapsed panel.
12
+
3
13
  ## 0.0.32
4
14
  * [#75](https://github.com/bvaughn/react-resizable-panels/issues/75): Ensure `Panel` and `PanelGroup` callbacks are always called after mounting.
5
15
 
package/README.md CHANGED
@@ -30,9 +30,14 @@ import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
30
30
  | `direction` | `"horizontal" \| "vertical"` | Group orientation
31
31
  | `id` | `?string` | Group id; falls back to `useId` when not provided
32
32
  | `onLayout` | `?(sizes: number[]) => void` | Called when group layout changes
33
+ | `storage` | `?PanelGroupStorage` | Custom storage API; defaults to `localStorage` <sup>1</sup>
33
34
  | `style` | `?CSSProperties` | CSS style to attach to root element
34
35
  | `tagName` | `?string = "div"` | HTML element tag name for root element
35
36
 
37
+ <sup>1</sup>: Storage API must define the following _synchronous_ methods:
38
+ * `getItem: (name:string) => string`
39
+ * `setItem: (name: string, value: string) => void`
40
+
36
41
  ### `Panel`
37
42
  | prop | type | description
38
43
  | :------------ | :------------------------------ | :---
@@ -44,11 +49,13 @@ import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
44
49
  | `maxSize` | `?number = 100` | Maximum allowable size of panel (numeric value between 1-100); defaults to `100`
45
50
  | `minSize` | `?number = 10` | Minimum allowable size of panel (numeric value between 1-100); defaults to `10`
46
51
  | `onCollapse` | `?(collapsed: boolean) => void` | Called when panel is collapsed; `collapsed` boolean parameter reflecting the new state
47
- | `onResize` | `?(size: number) => void` | Called when panel is resized; `size` parameter is a numeric value between 1-100
52
+ | `onResize` | `?(size: number) => void` | Called when panel is resized; `size` parameter is a numeric value between 1-100. <sup>1</sup>
48
53
  | `order` | `?number` | Order of panel within group; required for groups with conditionally rendered panels
49
54
  | `style` | `?CSSProperties` | CSS style to attach to root element
50
55
  | `tagName` | `?string = "div"` | HTML element tag name for root element
51
56
 
57
+ <sup>1</sup>: If any `Panel` has an `onResize` callback, the `order` prop should be provided for all `Panel`s.
58
+
52
59
  `Panel` components also expose an imperative API for manual resizing:
53
60
  | method | description
54
61
  | :--------------------------- | :---
@@ -1,5 +1,9 @@
1
1
  import { RefObject, CSSProperties, ElementType, ReactNode } from "react";
2
2
  type Direction = "horizontal" | "vertical";
3
+ export type PanelGroupStorage = {
4
+ getItem(name: string): string | null;
5
+ setItem(name: string, value: string): void;
6
+ };
3
7
  type PanelGroupOnLayout = (sizes: number[]) => void;
4
8
  type PanelOnCollapse = (collapsed: boolean) => void;
5
9
  type PanelOnResize = (size: number) => void;
@@ -45,10 +49,11 @@ export type PanelGroupProps = {
45
49
  direction: Direction;
46
50
  id?: string | null;
47
51
  onLayout?: PanelGroupOnLayout;
52
+ storage?: PanelGroupStorage;
48
53
  style?: CSSProperties;
49
54
  tagName?: ElementType;
50
55
  };
51
- export function PanelGroup({ autoSaveId, children, className: classNameFromProps, direction, id: idFromProps, onLayout, style: styleFromProps, tagName: Type, }: PanelGroupProps): import("react").FunctionComponentElement<import("react").ProviderProps<{
56
+ export function PanelGroup({ autoSaveId, children, className: classNameFromProps, direction, id: idFromProps, onLayout, storage, style: styleFromProps, tagName: Type, }: PanelGroupProps): import("react").FunctionComponentElement<import("react").ProviderProps<{
52
57
  activeHandleId: string;
53
58
  collapsePanel: (id: string) => void;
54
59
  direction: "horizontal" | "vertical";
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/react-resizable-panels/src/src/hooks/useIsomorphicEffect.ts","packages/react-resizable-panels/src/src/hooks/useUniqueId.ts","packages/react-resizable-panels/src/src/types.ts","packages/react-resizable-panels/src/src/PanelContexts.ts","packages/react-resizable-panels/src/src/Panel.ts","packages/react-resizable-panels/src/src/utils/serialization.ts","packages/react-resizable-panels/src/src/constants.ts","packages/react-resizable-panels/src/src/utils/group.ts","packages/react-resizable-panels/src/src/utils/coordinates.ts","packages/react-resizable-panels/src/src/hooks/useWindowSplitterBehavior.ts","packages/react-resizable-panels/src/src/utils/cursor.ts","packages/react-resizable-panels/src/src/utils/debounce.ts","packages/react-resizable-panels/src/src/PanelGroup.ts","packages/react-resizable-panels/src/src/PanelResizeHandle.ts","packages/react-resizable-panels/src/src/index.ts","packages/react-resizable-panels/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"import { Panel } from \"./Panel\";\nimport { PanelGroup } from \"./PanelGroup\";\nimport { PanelResizeHandle } from \"./PanelResizeHandle\";\n\nimport type { ImperativePanelHandle, PanelProps } from \"./Panel\";\nimport type { PanelGroupProps } from \"./PanelGroup\";\nimport type { PanelResizeHandleProps } from \"./PanelResizeHandle\";\n\nexport {\n Panel,\n PanelGroup,\n PanelResizeHandle,\n\n // TypeScript types\n ImperativePanelHandle,\n PanelGroupProps,\n PanelProps,\n PanelResizeHandleProps,\n};\n"],"names":[],"version":3,"file":"react-resizable-panels.d.ts.map"}
1
+ {"mappings":"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","sources":["packages/react-resizable-panels/src/src/hooks/useIsomorphicEffect.ts","packages/react-resizable-panels/src/src/hooks/useUniqueId.ts","packages/react-resizable-panels/src/src/types.ts","packages/react-resizable-panels/src/src/PanelContexts.ts","packages/react-resizable-panels/src/src/Panel.ts","packages/react-resizable-panels/src/src/utils/serialization.ts","packages/react-resizable-panels/src/src/constants.ts","packages/react-resizable-panels/src/src/utils/group.ts","packages/react-resizable-panels/src/src/utils/coordinates.ts","packages/react-resizable-panels/src/src/hooks/useWindowSplitterBehavior.ts","packages/react-resizable-panels/src/src/utils/cursor.ts","packages/react-resizable-panels/src/src/utils/debounce.ts","packages/react-resizable-panels/src/src/utils/arrays.ts","packages/react-resizable-panels/src/src/PanelGroup.ts","packages/react-resizable-panels/src/src/PanelResizeHandle.ts","packages/react-resizable-panels/src/src/index.ts","packages/react-resizable-panels/src/index.ts"],"sourcesContent":[null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,"import { Panel } from \"./Panel\";\nimport { PanelGroup } from \"./PanelGroup\";\nimport { PanelResizeHandle } from \"./PanelResizeHandle\";\n\nimport type { ImperativePanelHandle, PanelProps } from \"./Panel\";\nimport type { PanelGroupProps } from \"./PanelGroup\";\nimport type { PanelResizeHandleProps } from \"./PanelResizeHandle\";\nimport type { PanelGroupStorage } from \"./types\";\n\nexport {\n Panel,\n PanelGroup,\n PanelResizeHandle,\n\n // TypeScript types\n ImperativePanelHandle,\n PanelGroupProps,\n PanelGroupStorage,\n PanelProps,\n PanelResizeHandleProps,\n};\n"],"names":[],"version":3,"file":"react-resizable-panels.d.ts.map"}
@@ -146,9 +146,9 @@ function $e045b0dd313f33c7$var$getSerializationKey(panels) {
146
146
  return order ? `${order}:${minSize}` : `${minSize}`;
147
147
  }).sort((a, b)=>a.localeCompare(b)).join(",");
148
148
  }
149
- function $e045b0dd313f33c7$var$loadSerializedPanelGroupState(autoSaveId) {
149
+ function $e045b0dd313f33c7$var$loadSerializedPanelGroupState(autoSaveId, storage) {
150
150
  try {
151
- const serialized = localStorage.getItem(`PanelGroup:sizes:${autoSaveId}`);
151
+ const serialized = storage.getItem(`PanelGroup:sizes:${autoSaveId}`);
152
152
  if (serialized) {
153
153
  const parsed = JSON.parse(serialized);
154
154
  if (typeof parsed === "object" && parsed != null) return parsed;
@@ -156,20 +156,20 @@ function $e045b0dd313f33c7$var$loadSerializedPanelGroupState(autoSaveId) {
156
156
  } catch (error) {}
157
157
  return null;
158
158
  }
159
- function $e045b0dd313f33c7$export$9c80c6617f0386da(autoSaveId, panels) {
160
- const state = $e045b0dd313f33c7$var$loadSerializedPanelGroupState(autoSaveId);
159
+ function $e045b0dd313f33c7$export$9c80c6617f0386da(autoSaveId, panels, storage) {
160
+ const state = $e045b0dd313f33c7$var$loadSerializedPanelGroupState(autoSaveId, storage);
161
161
  if (state) {
162
162
  const key = $e045b0dd313f33c7$var$getSerializationKey(panels);
163
163
  return state[key] || null;
164
164
  }
165
165
  return null;
166
166
  }
167
- function $e045b0dd313f33c7$export$af183b313c61be4f(autoSaveId, panels, sizes) {
167
+ function $e045b0dd313f33c7$export$af183b313c61be4f(autoSaveId, panels, sizes, storage) {
168
168
  const key = $e045b0dd313f33c7$var$getSerializationKey(panels);
169
- const state = $e045b0dd313f33c7$var$loadSerializedPanelGroupState(autoSaveId) || {};
169
+ const state = $e045b0dd313f33c7$var$loadSerializedPanelGroupState(autoSaveId, storage) || {};
170
170
  state[key] = sizes;
171
171
  try {
172
- localStorage.setItem(`PanelGroup:sizes:${autoSaveId}`, JSON.stringify(state));
172
+ storage.setItem(`PanelGroup:sizes:${autoSaveId}`, JSON.stringify(state));
173
173
  } catch (error) {
174
174
  console.error(error);
175
175
  }
@@ -180,10 +180,14 @@ const $3237bc4a138172cd$export$d6d3992f3becc879 = 10;
180
180
 
181
181
 
182
182
 
183
- function $d520236daad9c5d5$export$f50bae335f53943c(panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse) {
184
- if (delta === 0) return prevSizes;
183
+ function $d520236daad9c5d5$export$f50bae335f53943c(event, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse, initialDragState) {
184
+ const { sizes: initialSizes } = initialDragState || {};
185
+ // If we're resizing by mouse or touch, use the initial sizes as a base.
186
+ // This has the benefit of causing force-collapsed panels to spring back open if drag is reversed.
187
+ const baseSizes = initialSizes || prevSizes;
188
+ if (delta === 0) return baseSizes;
185
189
  const panelsArray = $d520236daad9c5d5$export$a861c0ad45885494(panels);
186
- const nextSizes = prevSizes.concat();
190
+ const nextSizes = baseSizes.concat();
187
191
  let deltaApplied = 0;
188
192
  // A resizing panel affects the panels before or after it.
189
193
  //
@@ -197,25 +201,29 @@ function $d520236daad9c5d5$export$f50bae335f53943c(panels, idBefore, idAfter, de
197
201
  const pivotId = delta < 0 ? idAfter : idBefore;
198
202
  const index = panelsArray.findIndex((panel)=>panel.id === pivotId);
199
203
  const panel = panelsArray[index];
200
- const prevSize = prevSizes[index];
201
- const nextSize = $d520236daad9c5d5$var$safeResizePanel(panel, Math.abs(delta), prevSize);
202
- if (prevSize === nextSize) return prevSizes;
204
+ const baseSize = baseSizes[index];
205
+ const nextSize = $d520236daad9c5d5$var$safeResizePanel(panel, Math.abs(delta), baseSize, event);
206
+ if (baseSize === nextSize) // If there's no room for the pivot panel to grow, we can ignore this drag update.
207
+ return baseSizes;
203
208
  else {
204
- if (nextSize === 0 && prevSize > 0) panelSizeBeforeCollapse.set(pivotId, prevSize);
205
- delta = delta < 0 ? prevSize - nextSize : nextSize - prevSize;
209
+ if (nextSize === 0 && baseSize > 0) panelSizeBeforeCollapse.set(pivotId, baseSize);
210
+ delta = delta < 0 ? baseSize - nextSize : nextSize - baseSize;
206
211
  }
207
212
  }
208
213
  let pivotId1 = delta < 0 ? idBefore : idAfter;
209
214
  let index1 = panelsArray.findIndex((panel)=>panel.id === pivotId1);
210
215
  while(true){
211
216
  const panel1 = panelsArray[index1];
212
- const prevSize1 = prevSizes[index1];
213
- const nextSize1 = $d520236daad9c5d5$var$safeResizePanel(panel1, 0 - Math.abs(delta), prevSize1);
214
- if (prevSize1 !== nextSize1) {
215
- if (nextSize1 === 0 && prevSize1 > 0) panelSizeBeforeCollapse.set(panel1.id, prevSize1);
216
- deltaApplied += prevSize1 - nextSize1;
217
+ const baseSize1 = baseSizes[index1];
218
+ const deltaRemaining = Math.abs(delta) - Math.abs(deltaApplied);
219
+ const nextSize1 = $d520236daad9c5d5$var$safeResizePanel(panel1, 0 - deltaRemaining, baseSize1, event);
220
+ if (baseSize1 !== nextSize1) {
221
+ if (nextSize1 === 0 && baseSize1 > 0) panelSizeBeforeCollapse.set(panel1.id, baseSize1);
222
+ deltaApplied += baseSize1 - nextSize1;
217
223
  nextSizes[index1] = nextSize1;
218
- if (deltaApplied.toPrecision((0, $3237bc4a138172cd$export$d6d3992f3becc879)) >= delta.toPrecision((0, $3237bc4a138172cd$export$d6d3992f3becc879))) break;
224
+ if (deltaApplied.toPrecision((0, $3237bc4a138172cd$export$d6d3992f3becc879)).localeCompare(Math.abs(delta).toPrecision((0, $3237bc4a138172cd$export$d6d3992f3becc879)), undefined, {
225
+ numeric: true
226
+ }) >= 0) break;
219
227
  }
220
228
  if (delta < 0) {
221
229
  if (--index1 < 0) break;
@@ -225,22 +233,24 @@ function $d520236daad9c5d5$export$f50bae335f53943c(panels, idBefore, idAfter, de
225
233
  }
226
234
  // If we were unable to resize any of the panels panels, return the previous state.
227
235
  // This will essentially bailout and ignore the "mousemove" event.
228
- if (deltaApplied === 0) return prevSizes;
236
+ if (deltaApplied === 0) return baseSizes;
229
237
  // Adjust the pivot panel before, but only by the amount that surrounding panels were able to shrink/contract.
230
238
  pivotId1 = delta < 0 ? idAfter : idBefore;
231
239
  index1 = panelsArray.findIndex((panel)=>panel.id === pivotId1);
232
- nextSizes[index1] = prevSizes[index1] + deltaApplied;
240
+ nextSizes[index1] = baseSizes[index1] + deltaApplied;
233
241
  return nextSizes;
234
242
  }
235
243
  function $d520236daad9c5d5$export$b8e48269e4faa934(panelsArray, prevSizes, nextSizes) {
236
244
  nextSizes.forEach((nextSize, index)=>{
237
245
  const prevSize = prevSizes[index];
238
246
  if (prevSize !== nextSize) {
239
- const { callbacksRef: callbacksRef } = panelsArray[index];
247
+ const { callbacksRef: callbacksRef , collapsible: collapsible } = panelsArray[index];
240
248
  const { onCollapse: onCollapse , onResize: onResize } = callbacksRef.current;
241
249
  if (onResize) onResize(nextSize);
242
- if (onCollapse) {
243
- if (prevSize === 0 && nextSize !== 0) onCollapse(false);
250
+ if (collapsible && onCollapse) {
251
+ // Falsy check handles both previous size of 0
252
+ // and initial size of undefined (when mounting)
253
+ if (!prevSize && nextSize !== 0) onCollapse(false);
244
254
  else if (prevSize !== 0 && nextSize === 0) onCollapse(true);
245
255
  }
246
256
  }
@@ -312,13 +322,19 @@ function $d520236daad9c5d5$export$68d3a33c21dfbe27(groupId, handleId, panelsArra
312
322
  function $d520236daad9c5d5$export$a861c0ad45885494(panels) {
313
323
  return Array.from(panels.values()).sort((a, b)=>a.order - b.order);
314
324
  }
315
- function $d520236daad9c5d5$var$safeResizePanel(panel, delta, prevSize) {
325
+ function $d520236daad9c5d5$var$safeResizePanel(panel, delta, prevSize, event) {
316
326
  const nextSizeUnsafe = prevSize + delta;
317
327
  if (panel.collapsible) {
318
328
  if (prevSize > 0) {
319
329
  if (nextSizeUnsafe <= 0) return 0;
320
330
  } else {
321
- if (nextSizeUnsafe < panel.minSize) return 0;
331
+ const isKeyboardEvent = event?.type?.startsWith("key");
332
+ if (!isKeyboardEvent) {
333
+ // Keyboard events should expand a collapsed panel to the min size,
334
+ // but mouse events should wait until the panel has reached its min size
335
+ // to avoid a visual flickering when dragging between collapsed and min size.
336
+ if (nextSizeUnsafe < panel.minSize) return 0;
337
+ }
322
338
  }
323
339
  }
324
340
  const nextSize = Math.min(panel.maxSize, Math.max(panel.minSize, nextSizeUnsafe));
@@ -326,7 +342,7 @@ function $d520236daad9c5d5$var$safeResizePanel(panel, delta, prevSize) {
326
342
  }
327
343
 
328
344
 
329
- function $f5af57c8e042a4ad$export$ec391ce65b083ed4(event, handleId, direction, initialOffset = 0) {
345
+ function $f5af57c8e042a4ad$export$ec391ce65b083ed4(event, handleId, direction, initialOffset = 0, initialHandleElementRect = null) {
330
346
  const isHorizontal = direction === "horizontal";
331
347
  let pointerOffset = 0;
332
348
  if ($f5af57c8e042a4ad$export$764db16956f554f8(event)) pointerOffset = isHorizontal ? event.clientX : event.clientY;
@@ -335,11 +351,15 @@ function $f5af57c8e042a4ad$export$ec391ce65b083ed4(event, handleId, direction, i
335
351
  pointerOffset = isHorizontal ? firstTouch.screenX : firstTouch.screenY;
336
352
  } else return 0;
337
353
  const handleElement = (0, $d520236daad9c5d5$export$2e27d3a347680388)(handleId);
338
- const rect = handleElement.getBoundingClientRect();
354
+ const rect = initialHandleElementRect || handleElement.getBoundingClientRect();
339
355
  const elementOffset = isHorizontal ? rect.left : rect.top;
340
356
  return pointerOffset - elementOffset - initialOffset;
341
357
  }
342
- function $f5af57c8e042a4ad$export$354b17c0684607ed(event, groupId, handleId, panelsArray, direction, sizes, initialOffset) {
358
+ function $f5af57c8e042a4ad$export$354b17c0684607ed(event, groupId, handleId, panelsArray, direction, prevSizes, initialDragState) {
359
+ const { dragOffset: dragOffset = 0 , dragHandleRect: dragHandleRect , sizes: initialSizes } = initialDragState || {};
360
+ // If we're resizing by mouse or touch, use the initial sizes as a base.
361
+ // This has the benefit of causing force-collapsed panels to spring back open if drag is reversed.
362
+ const baseSizes = initialSizes || prevSizes;
343
363
  if ($f5af57c8e042a4ad$export$e7bf60a870f429b0(event)) {
344
364
  const isHorizontal = direction === "horizontal";
345
365
  const groupElement = (0, $d520236daad9c5d5$export$5e67632cf3550a9c)(groupId);
@@ -377,11 +397,11 @@ function $f5af57c8e042a4ad$export$354b17c0684607ed(event, groupId, handleId, pan
377
397
  const targetPanelIndex = panelsArray.findIndex((panel)=>panel.id === targetPanelId);
378
398
  const targetPanel = panelsArray[targetPanelIndex];
379
399
  if (targetPanel.collapsible) {
380
- const prevSize = sizes[targetPanelIndex];
381
- if (prevSize === 0 || prevSize.toPrecision((0, $3237bc4a138172cd$export$d6d3992f3becc879)) === targetPanel.minSize.toPrecision((0, $3237bc4a138172cd$export$d6d3992f3becc879))) movement = movement < 0 ? -targetPanel.minSize * groupSizeInPixels : targetPanel.minSize * groupSizeInPixels;
400
+ const baseSize = baseSizes[targetPanelIndex];
401
+ if (baseSize === 0 || baseSize.toPrecision((0, $3237bc4a138172cd$export$d6d3992f3becc879)) === targetPanel.minSize.toPrecision((0, $3237bc4a138172cd$export$d6d3992f3becc879))) movement = movement < 0 ? -targetPanel.minSize * groupSizeInPixels : targetPanel.minSize * groupSizeInPixels;
382
402
  }
383
403
  return movement;
384
- } else return $f5af57c8e042a4ad$export$ec391ce65b083ed4(event, handleId, direction, initialOffset);
404
+ } else return $f5af57c8e042a4ad$export$ec391ce65b083ed4(event, handleId, direction, dragOffset, dragHandleRect);
385
405
  }
386
406
  function $f5af57c8e042a4ad$export$e7bf60a870f429b0(event) {
387
407
  return event.type === "keydown";
@@ -443,7 +463,7 @@ function $63be9a96d8675f03$export$d9fcbe062527d159({ committedValuesRef: committ
443
463
  let delta = 0;
444
464
  if (size.toPrecision((0, $3237bc4a138172cd$export$d6d3992f3becc879)) <= panelData.minSize.toPrecision((0, $3237bc4a138172cd$export$d6d3992f3becc879))) delta = direction === "horizontal" ? width : height;
445
465
  else delta = -(direction === "horizontal" ? width : height);
446
- const nextSizes = (0, $d520236daad9c5d5$export$f50bae335f53943c)(panels, idBefore, idAfter, delta, sizes, panelSizeBeforeCollapse.current);
466
+ const nextSizes = (0, $d520236daad9c5d5$export$f50bae335f53943c)(event, panels, idBefore, idAfter, delta, sizes, panelSizeBeforeCollapse.current, null);
447
467
  if (sizes !== nextSizes) setSizes(nextSizes);
448
468
  }
449
469
  }
@@ -558,12 +578,32 @@ function $0f7a23424493ebd6$export$2e2bcd8739ae039(callback, durationMs = 10) {
558
578
  }
559
579
 
560
580
 
581
+ function $d6375e31485eb011$export$b141efd0b0fb9174(arrayA, arrayB) {
582
+ if (arrayA.length !== arrayB.length) return false;
583
+ for(let index = 0; index < arrayA.length; index++){
584
+ if (arrayA[index] !== arrayB[index]) return false;
585
+ }
586
+ return true;
587
+ }
588
+
589
+
561
590
  // Limit the frequency of localStorage updates.
562
591
  const $19bf0050f73d236b$var$savePanelGroupLayoutDebounced = (0, $0f7a23424493ebd6$export$2e2bcd8739ae039)((0, $e045b0dd313f33c7$export$af183b313c61be4f), 100);
563
- function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , children: children = null , className: classNameFromProps = "" , direction: direction , id: idFromProps = null , onLayout: onLayout = null , style: styleFromProps = {} , tagName: Type = "div" }) {
592
+ function $19bf0050f73d236b$var$throwServerError() {
593
+ throw new Error('PanelGroup "storage" prop required for server rendering.');
594
+ }
595
+ const $19bf0050f73d236b$var$defaultStorage = {
596
+ getItem: typeof localStorage !== "undefined" ? (name)=>localStorage.getItem(name) : $19bf0050f73d236b$var$throwServerError,
597
+ setItem: typeof localStorage !== "undefined" ? (name, value)=>localStorage.setItem(name, value) : $19bf0050f73d236b$var$throwServerError
598
+ };
599
+ function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , children: children = null , className: classNameFromProps = "" , direction: direction , id: idFromProps = null , onLayout: onLayout = null , storage: storage = $19bf0050f73d236b$var$defaultStorage , style: styleFromProps = {} , tagName: Type = "div" }) {
564
600
  const groupId = (0, $6d548a0d130941e3$export$2e2bcd8739ae039)(idFromProps);
565
601
  const [activeHandleId, setActiveHandleId] = (0, $b2QPe$react.useState)(null);
566
602
  const [panels, setPanels] = (0, $b2QPe$react.useState)(new Map());
603
+ // When resizing is done via mouse/touch event–
604
+ // We store the initial Panel sizes in this ref, and apply move deltas to them instead of to the current sizes.
605
+ // This has the benefit of causing force-collapsed panels to spring back open if drag is reversed.
606
+ const initialDragStateRef = (0, $b2QPe$react.useRef)(null);
567
607
  // Use a ref to guard against users passing inline props
568
608
  const callbacksRef = (0, $b2QPe$react.useRef)({
569
609
  onLayout: onLayout
@@ -573,11 +613,9 @@ function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , chi
573
613
  });
574
614
  // 0-1 values representing the relative size of each panel.
575
615
  const [sizes, setSizes] = (0, $b2QPe$react.useState)([]);
576
- // Resize is calculated by the distance between the current pointer event and the resize handle being "dragged"
577
- // This value accounts for the initial offset when the touch/click starts, so the handle doesn't appear to "jump"
578
- const dragOffsetRef = (0, $b2QPe$react.useRef)(0);
579
616
  // Used to support imperative collapse/expand API.
580
617
  const panelSizeBeforeCollapse = (0, $b2QPe$react.useRef)(new Map());
618
+ const prevDeltaRef = (0, $b2QPe$react.useRef)(0);
581
619
  // Store committed values to avoid unnecessarily re-running memoization/effects functions.
582
620
  const committedValuesRef = (0, $b2QPe$react.useRef)({
583
621
  direction: direction,
@@ -634,7 +672,7 @@ function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , chi
634
672
  let defaultSizes = undefined;
635
673
  if (autoSaveId) {
636
674
  const panelsArray = (0, $d520236daad9c5d5$export$a861c0ad45885494)(panels);
637
- defaultSizes = (0, $e045b0dd313f33c7$export$9c80c6617f0386da)(autoSaveId, panelsArray);
675
+ defaultSizes = (0, $e045b0dd313f33c7$export$9c80c6617f0386da)(autoSaveId, panelsArray, storage);
638
676
  }
639
677
  if (defaultSizes != null) setSizes(defaultSizes);
640
678
  else {
@@ -667,7 +705,7 @@ function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , chi
667
705
  if (autoSaveId) {
668
706
  if (sizes.length === 0 || sizes.length !== panels.size) return;
669
707
  const panelsArray = (0, $d520236daad9c5d5$export$a861c0ad45885494)(panels);
670
- $19bf0050f73d236b$var$savePanelGroupLayoutDebounced(autoSaveId, panelsArray, sizes);
708
+ $19bf0050f73d236b$var$savePanelGroupLayoutDebounced(autoSaveId, panelsArray, sizes, storage);
671
709
  }
672
710
  }, [
673
711
  autoSaveId,
@@ -717,27 +755,37 @@ function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , chi
717
755
  const panelsArray = (0, $d520236daad9c5d5$export$a861c0ad45885494)(panels);
718
756
  const [idBefore, idAfter] = (0, $d520236daad9c5d5$export$68d3a33c21dfbe27)(groupId, handleId, panelsArray);
719
757
  if (idBefore == null || idAfter == null) return;
720
- const movement = (0, $f5af57c8e042a4ad$export$354b17c0684607ed)(event, groupId, handleId, panelsArray, direction, prevSizes, dragOffsetRef.current);
758
+ const movement = (0, $f5af57c8e042a4ad$export$354b17c0684607ed)(event, groupId, handleId, panelsArray, direction, prevSizes, initialDragStateRef.current);
721
759
  if (movement === 0) return;
722
760
  const groupElement = (0, $d520236daad9c5d5$export$5e67632cf3550a9c)(groupId);
723
761
  const rect = groupElement.getBoundingClientRect();
724
762
  const isHorizontal = direction === "horizontal";
725
763
  const size = isHorizontal ? rect.width : rect.height;
726
764
  const delta = movement / size * 100;
727
- const nextSizes = (0, $d520236daad9c5d5$export$f50bae335f53943c)(panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current);
728
- if (prevSizes === nextSizes) {
729
- // If the pointer has moved too far to resize the panel any further,
730
- // update the cursor style for a visual clue.
731
- // This mimics VS Code behavior.
732
- if (isHorizontal) (0, $102aa6bc0f99b2b3$export$d395b5dfd066a659)(movement < 0 ? "horizontal-min" : "horizontal-max");
733
- else (0, $102aa6bc0f99b2b3$export$d395b5dfd066a659)(movement < 0 ? "vertical-min" : "vertical-max");
734
- } else {
735
- // Reset the cursor style to the the normal resize cursor.
736
- (0, $102aa6bc0f99b2b3$export$d395b5dfd066a659)(isHorizontal ? "horizontal" : "vertical");
765
+ const nextSizes = (0, $d520236daad9c5d5$export$f50bae335f53943c)(event, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, initialDragStateRef.current);
766
+ const sizesChanged = !(0, $d6375e31485eb011$export$b141efd0b0fb9174)(prevSizes, nextSizes);
767
+ // Don't update cursor for resizes triggered by keyboard interactions.
768
+ if ((0, $f5af57c8e042a4ad$export$764db16956f554f8)(event) || (0, $f5af57c8e042a4ad$export$c4dfce035d43d1e0)(event)) // Watch for multiple subsequent deltas; this might occur for tiny cursor movements.
769
+ // In this case, Panel sizes might not change–
770
+ // but updating cursor in this scenario would cause a flicker.
771
+ {
772
+ if (prevDeltaRef.current != delta) {
773
+ if (!sizesChanged) {
774
+ // If the pointer has moved too far to resize the panel any further,
775
+ // update the cursor style for a visual clue.
776
+ // This mimics VS Code behavior.
777
+ if (isHorizontal) (0, $102aa6bc0f99b2b3$export$d395b5dfd066a659)(movement < 0 ? "horizontal-min" : "horizontal-max");
778
+ else (0, $102aa6bc0f99b2b3$export$d395b5dfd066a659)(movement < 0 ? "vertical-min" : "vertical-max");
779
+ } else // Reset the cursor style to the the normal resize cursor.
780
+ (0, $102aa6bc0f99b2b3$export$d395b5dfd066a659)(isHorizontal ? "horizontal" : "vertical");
781
+ }
782
+ }
783
+ if (sizesChanged) {
737
784
  // If resize change handlers have been declared, this is the time to call them.
738
785
  (0, $d520236daad9c5d5$export$b8e48269e4faa934)(panelsArray, prevSizes, nextSizes);
739
786
  setSizes(nextSizes);
740
787
  }
788
+ prevDeltaRef.current = delta;
741
789
  };
742
790
  return resizeHandler;
743
791
  }, [
@@ -766,7 +814,7 @@ function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , chi
766
814
  if (idBefore == null || idAfter == null) return;
767
815
  const isLastPanel = index === panelsArray.length - 1;
768
816
  const delta = isLastPanel ? currentSize : 0 - currentSize;
769
- const nextSizes = (0, $d520236daad9c5d5$export$f50bae335f53943c)(panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current);
817
+ const nextSizes = (0, $d520236daad9c5d5$export$f50bae335f53943c)(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
770
818
  if (prevSizes !== nextSizes) {
771
819
  // If resize change handlers have been declared, this is the time to call them.
772
820
  (0, $d520236daad9c5d5$export$b8e48269e4faa934)(panelsArray, prevSizes, nextSizes);
@@ -789,7 +837,7 @@ function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , chi
789
837
  if (idBefore == null || idAfter == null) return;
790
838
  const isLastPanel = index === panelsArray.length - 1;
791
839
  const delta = isLastPanel ? 0 - sizeBeforeCollapse : sizeBeforeCollapse;
792
- const nextSizes = (0, $d520236daad9c5d5$export$f50bae335f53943c)(panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current);
840
+ const nextSizes = (0, $d520236daad9c5d5$export$f50bae335f53943c)(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
793
841
  if (prevSizes !== nextSizes) {
794
842
  // If resize change handlers have been declared, this is the time to call them.
795
843
  (0, $d520236daad9c5d5$export$b8e48269e4faa934)(panelsArray, prevSizes, nextSizes);
@@ -805,11 +853,13 @@ function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , chi
805
853
  if (index < 0) return;
806
854
  const currentSize = prevSizes[index];
807
855
  if (currentSize === nextSize) return;
856
+ if (panel.collapsible && nextSize === 0) ;
857
+ else nextSize = Math.min(panel.maxSize, Math.max(panel.minSize, nextSize));
808
858
  const [idBefore, idAfter] = (0, $d520236daad9c5d5$export$5a5b0c1d38c23c3b)(id, panelsArray);
809
859
  if (idBefore == null || idAfter == null) return;
810
860
  const isLastPanel = index === panelsArray.length - 1;
811
861
  const delta = isLastPanel ? currentSize - nextSize : nextSize - currentSize;
812
- const nextSizes = (0, $d520236daad9c5d5$export$f50bae335f53943c)(panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current);
862
+ const nextSizes = (0, $d520236daad9c5d5$export$f50bae335f53943c)(null, panels, idBefore, idAfter, delta, prevSizes, panelSizeBeforeCollapse.current, null);
813
863
  if (prevSizes !== nextSizes) {
814
864
  // If resize change handlers have been declared, this is the time to call them.
815
865
  (0, $d520236daad9c5d5$export$b8e48269e4faa934)(panelsArray, prevSizes, nextSizes);
@@ -828,11 +878,19 @@ function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , chi
828
878
  resizePanel: resizePanel,
829
879
  startDragging: (id, event)=>{
830
880
  setActiveHandleId(id);
831
- dragOffsetRef.current = (0, $f5af57c8e042a4ad$export$ec391ce65b083ed4)(event, id, direction);
881
+ if ((0, $f5af57c8e042a4ad$export$764db16956f554f8)(event) || (0, $f5af57c8e042a4ad$export$c4dfce035d43d1e0)(event)) {
882
+ const handleElement = (0, $d520236daad9c5d5$export$2e27d3a347680388)(id);
883
+ initialDragStateRef.current = {
884
+ dragHandleRect: handleElement.getBoundingClientRect(),
885
+ dragOffset: (0, $f5af57c8e042a4ad$export$ec391ce65b083ed4)(event, id, direction),
886
+ sizes: committedValuesRef.current.sizes
887
+ };
888
+ }
832
889
  },
833
890
  stopDragging: ()=>{
834
891
  (0, $102aa6bc0f99b2b3$export$b61932ee18f96e08)();
835
892
  setActiveHandleId(null);
893
+ initialDragStateRef.current = null;
836
894
  },
837
895
  unregisterPanel: unregisterPanel
838
896
  }), [
@@ -858,6 +916,7 @@ function $19bf0050f73d236b$export$1d05749f6f573bb({ autoSaveId: autoSaveId , chi
858
916
  children: (0, $b2QPe$react.createElement)(Type, {
859
917
  children: children,
860
918
  className: classNameFromProps,
919
+ "data-panel-group": "",
861
920
  "data-panel-group-direction": direction,
862
921
  "data-panel-group-id": groupId,
863
922
  style: {