react-resizable-panels 1.0.7 → 1.0.9

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.
Files changed (60) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +16 -15
  3. package/dist/declarations/src/Panel.d.ts +3 -3
  4. package/dist/declarations/src/PanelGroup.d.ts +2 -2
  5. package/dist/declarations/src/PanelResizeHandle.d.ts +2 -2
  6. package/dist/declarations/src/index.d.ts +1 -3
  7. package/dist/declarations/src/utils/dom/getPanelElement.d.ts +1 -1
  8. package/dist/declarations/src/utils/dom/getPanelElementsForGroup.d.ts +1 -1
  9. package/dist/declarations/src/utils/dom/getPanelGroupElement.d.ts +1 -1
  10. package/dist/declarations/src/utils/dom/getResizeHandleElement.d.ts +1 -1
  11. package/dist/declarations/src/utils/dom/getResizeHandleElementIndex.d.ts +1 -1
  12. package/dist/declarations/src/utils/dom/getResizeHandleElementsForGroup.d.ts +1 -1
  13. package/dist/declarations/src/utils/dom/getResizeHandlePanelIds.d.ts +1 -1
  14. package/dist/declarations/src/vendor/react.d.ts +2 -2
  15. package/dist/react-resizable-panels.browser.cjs.js +114 -84
  16. package/dist/react-resizable-panels.browser.cjs.mjs +0 -2
  17. package/dist/react-resizable-panels.browser.development.cjs.js +116 -85
  18. package/dist/react-resizable-panels.browser.development.cjs.mjs +0 -2
  19. package/dist/react-resizable-panels.browser.development.esm.js +117 -84
  20. package/dist/react-resizable-panels.browser.esm.js +115 -83
  21. package/dist/react-resizable-panels.cjs.js +114 -84
  22. package/dist/react-resizable-panels.cjs.mjs +0 -2
  23. package/dist/react-resizable-panels.development.cjs.js +116 -85
  24. package/dist/react-resizable-panels.development.cjs.mjs +0 -2
  25. package/dist/react-resizable-panels.development.esm.js +117 -84
  26. package/dist/react-resizable-panels.development.node.cjs.js +102 -83
  27. package/dist/react-resizable-panels.development.node.cjs.mjs +0 -2
  28. package/dist/react-resizable-panels.development.node.esm.js +103 -82
  29. package/dist/react-resizable-panels.esm.js +115 -83
  30. package/dist/react-resizable-panels.node.cjs.js +100 -82
  31. package/dist/react-resizable-panels.node.cjs.mjs +0 -2
  32. package/dist/react-resizable-panels.node.esm.js +101 -81
  33. package/package.json +1 -1
  34. package/src/Panel.test.tsx +137 -2
  35. package/src/Panel.ts +16 -2
  36. package/src/PanelGroup.test.tsx +3 -2
  37. package/src/PanelGroup.ts +95 -35
  38. package/src/PanelGroupContext.ts +9 -3
  39. package/src/PanelResizeHandle.test.tsx +3 -3
  40. package/src/PanelResizeHandle.ts +4 -2
  41. package/src/hooks/useWindowSplitterBehavior.ts +14 -5
  42. package/src/hooks/useWindowSplitterPanelGroupBehavior.ts +23 -7
  43. package/src/index.ts +0 -4
  44. package/src/utils/calculateDeltaPercentage.ts +4 -2
  45. package/src/utils/calculateDragOffsetPercentage.ts +4 -3
  46. package/src/utils/determinePivotIndices.ts +7 -2
  47. package/src/utils/dom/getPanelElement.ts +5 -2
  48. package/src/utils/dom/getPanelElementsForGroup.ts +5 -2
  49. package/src/utils/dom/getPanelGroupElement.ts +14 -2
  50. package/src/utils/dom/getResizeHandleElement.ts +5 -4
  51. package/src/utils/dom/getResizeHandleElementIndex.ts +3 -2
  52. package/src/utils/dom/getResizeHandleElementsForGroup.ts +3 -2
  53. package/src/utils/dom/getResizeHandlePanelIds.ts +4 -3
  54. package/src/utils/validatePanelConstraints.test.ts +45 -0
  55. package/src/utils/validatePanelConstraints.ts +5 -1
  56. package/src/vendor/react.ts +2 -0
  57. package/dist/declarations/src/utils/dom/calculateAvailablePanelSizeInPixels.d.ts +0 -1
  58. package/dist/declarations/src/utils/dom/getAvailableGroupSizePixels.d.ts +0 -1
  59. package/src/utils/dom/calculateAvailablePanelSizeInPixels.ts +0 -29
  60. package/src/utils/dom/getAvailableGroupSizePixels.ts +0 -29
package/CHANGELOG.md CHANGED
@@ -1,5 +1,16 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.0.9
4
+
5
+ - DOM util methods scope param defaults to `document` (#262)
6
+ - Updating a `Panel`'s pixel constraints will trigger revalidation of the `Panel`'s size (#266)
7
+
8
+ ## 1.0.8
9
+
10
+ - Update component signature to declare `ReactElement` return type (rather than `ReactNode`) (#256)
11
+ - Update `Panel` dev warning to avoid warning when `defaultSize === collapsedSize` for collapsible panels (#257)
12
+ - Support shadow dom by removing direct references to / dependencies on the root `document` (#204)
13
+
3
14
  ## 1.0.7
4
15
 
5
16
  - Narrow `tagName` prop to only allow `HTMLElement` names (rather than the broader `Element` type) (#251)
package/README.md CHANGED
@@ -52,21 +52,22 @@ import { Panel, PanelGroup, PanelResizeHandle } from "react-resizable-panels";
52
52
 
53
53
  ### `Panel`
54
54
 
55
- | prop | type | description |
56
- | :-------------- | :------------------------------ | :-------------------------------------------------------------------------------------------- |
57
- | `children` | `ReactNode` | Arbitrary React element(s) |
58
- | `className` | `?string` | Class name to attach to root element |
59
- | `collapsedSize` | `?number=0` | Panel should collapse to this size |
60
- | `collapsible` | `?boolean=false` | Panel should collapse when resized beyond its `minSize` |
61
- | `defaultSize` | `?number` | Initial size of panel (numeric value between 1-100) |
62
- | `id` | `?string` | Panel id (unique within group); falls back to `useId` when not provided |
63
- | `maxSize` | `?number = 100` | Maximum allowable size of panel (numeric value between 1-100); defaults to `100` |
64
- | `minSize` | `?number = 10` | Minimum allowable size of panel (numeric value between 1-100); defaults to `10` |
65
- | `onCollapse` | `?(collapsed: boolean) => void` | Called when panel is collapsed; `collapsed` boolean parameter reflecting the new state |
66
- | `onResize` | `?(size: number) => void` | Called when panel is resized; `size` parameter is a numeric value between 1-100. <sup>1</sup> |
67
- | `order` | `?number` | Order of panel within group; required for groups with conditionally rendered panels |
68
- | `style` | `?CSSProperties` | CSS style to attach to root element |
69
- | `tagName` | `?string = "div"` | HTML element tag name for root element |
55
+ | prop | type | description |
56
+ | :-------------- | :------------------------ | :-------------------------------------------------------------------------------------------- |
57
+ | `children` | `ReactNode` | Arbitrary React element(s) |
58
+ | `className` | `?string` | Class name to attach to root element |
59
+ | `collapsedSize` | `?number=0` | Panel should collapse to this size |
60
+ | `collapsible` | `?boolean=false` | Panel should collapse when resized beyond its `minSize` |
61
+ | `defaultSize` | `?number` | Initial size of panel (numeric value between 1-100) |
62
+ | `id` | `?string` | Panel id (unique within group); falls back to `useId` when not provided |
63
+ | `maxSize` | `?number = 100` | Maximum allowable size of panel (numeric value between 1-100); defaults to `100` |
64
+ | `minSize` | `?number = 10` | Minimum allowable size of panel (numeric value between 1-100); defaults to `10` |
65
+ | `onCollapse` | `?() => void` | Called when panel is collapsed |
66
+ | `onExpande` | `?() => void` | Called when panel is expanded |
67
+ | `onResize` | `?(size: number) => void` | Called when panel is resized; `size` parameter is a numeric value between 1-100. <sup>1</sup> |
68
+ | `order` | `?number` | Order of panel within group; required for groups with conditionally rendered panels |
69
+ | `style` | `?CSSProperties` | CSS style to attach to root element |
70
+ | `tagName` | `?string = "div"` | HTML element tag name for root element |
70
71
 
71
72
  <sup>1</sup>: If any `Panel` has an `onResize` callback, the `order` prop should be provided for all `Panel`s.
72
73
 
@@ -1,4 +1,4 @@
1
- import { ForwardedRef, HTMLAttributes, PropsWithChildren, ReactNode } from "./vendor/react.js";
1
+ import { ForwardedRef, HTMLAttributes, PropsWithChildren, ReactElement } from "./vendor/react.js";
2
2
  export type PanelOnCollapse = () => void;
3
3
  export type PanelOnExpand = () => void;
4
4
  export type PanelOnResize = (size: number, prevSize: number | undefined) => void;
@@ -47,7 +47,7 @@ export type PanelProps = Omit<HTMLAttributes<keyof HTMLElementTagNameMap>, "id"
47
47
  }>;
48
48
  export declare function PanelWithForwardedRef({ children, className: classNameFromProps, collapsedSize, collapsible, defaultSize, forwardedRef, id: idFromProps, maxSize, minSize, onCollapse, onExpand, onResize, order, style: styleFromProps, tagName: Type, ...rest }: PanelProps & {
49
49
  forwardedRef: ForwardedRef<ImperativePanelHandle>;
50
- }): ReactNode;
50
+ }): ReactElement;
51
51
  export declare namespace PanelWithForwardedRef {
52
52
  var displayName: string;
53
53
  }
@@ -66,5 +66,5 @@ export declare const Panel: import("react").ForwardRefExoticComponent<Omit<HTMLA
66
66
  style?: object | undefined;
67
67
  tagName?: keyof HTMLElementTagNameMap | undefined;
68
68
  } & {
69
- children?: ReactNode;
69
+ children?: import("react").ReactNode;
70
70
  } & import("react").RefAttributes<ImperativePanelHandle>>;
@@ -1,5 +1,5 @@
1
1
  import { Direction } from "./types.js";
2
- import { CSSProperties, HTMLAttributes, PropsWithChildren, ReactNode } from "./vendor/react.js";
2
+ import { CSSProperties, HTMLAttributes, PropsWithChildren } from "./vendor/react.js";
3
3
  export type ImperativePanelGroupHandle = {
4
4
  getId: () => string;
5
5
  getLayout: () => number[];
@@ -32,5 +32,5 @@ export declare const PanelGroup: import("react").ForwardRefExoticComponent<Omit<
32
32
  style?: CSSProperties | undefined;
33
33
  tagName?: keyof HTMLElementTagNameMap | undefined;
34
34
  } & {
35
- children?: ReactNode;
35
+ children?: import("react").ReactNode;
36
36
  } & import("react").RefAttributes<ImperativePanelGroupHandle>>;
@@ -1,4 +1,4 @@
1
- import { CSSProperties, HTMLAttributes, PropsWithChildren, ReactNode } from "./vendor/react.js";
1
+ import { CSSProperties, HTMLAttributes, PropsWithChildren, ReactElement } from "./vendor/react.js";
2
2
  export type PanelResizeHandleOnDragging = (isDragging: boolean) => void;
3
3
  export type PanelResizeHandleProps = Omit<HTMLAttributes<keyof HTMLElementTagNameMap>, "id"> & PropsWithChildren<{
4
4
  className?: string;
@@ -9,7 +9,7 @@ export type PanelResizeHandleProps = Omit<HTMLAttributes<keyof HTMLElementTagNam
9
9
  tabIndex?: number;
10
10
  tagName?: keyof HTMLElementTagNameMap;
11
11
  }>;
12
- export declare function PanelResizeHandle({ children, className: classNameFromProps, disabled, id: idFromProps, onDragging, style: styleFromProps, tabIndex, tagName: Type, ...rest }: PanelResizeHandleProps): ReactNode;
12
+ export declare function PanelResizeHandle({ children, className: classNameFromProps, disabled, id: idFromProps, onDragging, style: styleFromProps, tabIndex, tagName: Type, ...rest }: PanelResizeHandleProps): ReactElement;
13
13
  export declare namespace PanelResizeHandle {
14
14
  var displayName: string;
15
15
  }
@@ -2,8 +2,6 @@ import { Panel } from "./Panel.js";
2
2
  import { PanelGroup } from "./PanelGroup.js";
3
3
  import { PanelResizeHandle } from "./PanelResizeHandle.js";
4
4
  import { assert } from "./utils/assert.js";
5
- import { calculateAvailablePanelSizeInPixels } from "./utils/dom/calculateAvailablePanelSizeInPixels.js";
6
- import { getAvailableGroupSizePixels } from "./utils/dom/getAvailableGroupSizePixels.js";
7
5
  import { getPanelElement } from "./utils/dom/getPanelElement.js";
8
6
  import { getPanelElementsForGroup } from "./utils/dom/getPanelElementsForGroup.js";
9
7
  import { getPanelGroupElement } from "./utils/dom/getPanelGroupElement.js";
@@ -14,4 +12,4 @@ import { getResizeHandlePanelIds } from "./utils/dom/getResizeHandlePanelIds.js"
14
12
  import type { ImperativePanelHandle, PanelOnCollapse, PanelOnExpand, PanelOnResize, PanelProps } from "./Panel.js";
15
13
  import type { ImperativePanelGroupHandle, PanelGroupOnLayout, PanelGroupProps, PanelGroupStorage } from "./PanelGroup.js";
16
14
  import type { PanelResizeHandleOnDragging, PanelResizeHandleProps } from "./PanelResizeHandle.js";
17
- export { ImperativePanelGroupHandle, ImperativePanelHandle, PanelGroupOnLayout, PanelGroupProps, PanelGroupStorage, PanelOnCollapse, PanelOnExpand, PanelOnResize, PanelProps, PanelResizeHandleOnDragging, PanelResizeHandleProps, Panel, PanelGroup, PanelResizeHandle, assert, calculateAvailablePanelSizeInPixels, getAvailableGroupSizePixels, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, };
15
+ export { ImperativePanelGroupHandle, ImperativePanelHandle, PanelGroupOnLayout, PanelGroupProps, PanelGroupStorage, PanelOnCollapse, PanelOnExpand, PanelOnResize, PanelProps, PanelResizeHandleOnDragging, PanelResizeHandleProps, Panel, PanelGroup, PanelResizeHandle, assert, getPanelElement, getPanelElementsForGroup, getPanelGroupElement, getResizeHandleElement, getResizeHandleElementIndex, getResizeHandleElementsForGroup, getResizeHandlePanelIds, };
@@ -1 +1 @@
1
- export declare function getPanelElement(id: string): HTMLElement | null;
1
+ export declare function getPanelElement(id: string, scope?: ParentNode | HTMLElement): HTMLElement | null;
@@ -1 +1 @@
1
- export declare function getPanelElementsForGroup(groupId: string): HTMLElement[];
1
+ export declare function getPanelElementsForGroup(groupId: string, scope?: ParentNode | HTMLElement): HTMLElement[];
@@ -1 +1 @@
1
- export declare function getPanelGroupElement(id: string): HTMLElement | null;
1
+ export declare function getPanelGroupElement(id: string, rootElement?: ParentNode | HTMLElement): HTMLElement | null;
@@ -1 +1 @@
1
- export declare function getResizeHandleElement(id: string): HTMLElement | null;
1
+ export declare function getResizeHandleElement(id: string, scope?: ParentNode | HTMLElement): HTMLElement | null;
@@ -1 +1 @@
1
- export declare function getResizeHandleElementIndex(groupId: string, id: string): number | null;
1
+ export declare function getResizeHandleElementIndex(groupId: string, id: string, scope?: ParentNode | HTMLElement): number | null;
@@ -1 +1 @@
1
- export declare function getResizeHandleElementsForGroup(groupId: string): HTMLElement[];
1
+ export declare function getResizeHandleElementsForGroup(groupId: string, scope?: ParentNode | HTMLElement): HTMLElement[];
@@ -1,2 +1,2 @@
1
1
  import { PanelData } from "../../Panel.js";
2
- export declare function getResizeHandlePanelIds(groupId: string, handleId: string, panelsArray: PanelData[]): [idBefore: string | null, idAfter: string | null];
2
+ export declare function getResizeHandlePanelIds(groupId: string, handleId: string, panelsArray: PanelData[], scope?: ParentNode | HTMLElement): [idBefore: string | null, idAfter: string | null];
@@ -1,6 +1,6 @@
1
1
  import * as React from "react";
2
- import type { CSSProperties, ElementType, ForwardedRef, HTMLAttributes, MouseEvent, PropsWithChildren, ReactNode, RefObject, TouchEvent } from "react";
2
+ import type { CSSProperties, ElementType, ForwardedRef, HTMLAttributes, MouseEvent, PropsWithChildren, ReactElement, ReactNode, RefObject, TouchEvent } from "react";
3
3
  declare const createElement: typeof React.createElement, createContext: typeof React.createContext, createRef: typeof React.createRef, forwardRef: typeof React.forwardRef, useCallback: typeof React.useCallback, useContext: typeof React.useContext, useEffect: typeof React.useEffect, useImperativeHandle: typeof React.useImperativeHandle, useLayoutEffect: typeof React.useLayoutEffect, useMemo: typeof React.useMemo, useRef: typeof React.useRef, useState: typeof React.useState;
4
4
  declare const useId: () => string;
5
5
  export { createElement, createContext, createRef, forwardRef, useCallback, useContext, useEffect, useId, useImperativeHandle, useLayoutEffect, useMemo, useRef, useState, };
6
- export type { CSSProperties, ElementType, ForwardedRef, HTMLAttributes, MouseEvent, PropsWithChildren, ReactNode, RefObject, TouchEvent, };
6
+ export type { CSSProperties, ElementType, ForwardedRef, HTMLAttributes, MouseEvent, PropsWithChildren, ReactElement, ReactNode, RefObject, TouchEvent, };
@@ -91,6 +91,7 @@ function PanelWithForwardedRef({
91
91
  getPanelStyle,
92
92
  groupId,
93
93
  isPanelCollapsed,
94
+ reevaluatePanelConstraints,
94
95
  registerPanel,
95
96
  resizePanel,
96
97
  unregisterPanel
@@ -121,6 +122,9 @@ function PanelWithForwardedRef({
121
122
  callbacks,
122
123
  constraints
123
124
  } = panelDataRef.current;
125
+ const prevConstraints = {
126
+ ...constraints
127
+ };
124
128
  panelDataRef.current.id = panelId;
125
129
  panelDataRef.current.idIsFromProps = idFromProps !== undefined;
126
130
  panelDataRef.current.order = order;
@@ -132,6 +136,12 @@ function PanelWithForwardedRef({
132
136
  constraints.defaultSize = defaultSize;
133
137
  constraints.maxSize = maxSize;
134
138
  constraints.minSize = minSize;
139
+
140
+ // If constraints have changed, we should revisit panel sizes.
141
+ // This is uncommon but may happen if people are trying to implement pixel based constraints.
142
+ if (prevConstraints.collapsedSize !== constraints.collapsedSize || prevConstraints.collapsible !== constraints.collapsible || prevConstraints.maxSize !== constraints.maxSize || prevConstraints.minSize !== constraints.minSize) {
143
+ reevaluatePanelConstraints(panelDataRef.current, prevConstraints);
144
+ }
135
145
  });
136
146
  useIsomorphicLayoutEffect(() => {
137
147
  const panelData = panelDataRef.current;
@@ -519,41 +529,48 @@ function calculateAriaValues({
519
529
  };
520
530
  }
521
531
 
522
- function getResizeHandleElementsForGroup(groupId) {
523
- return Array.from(document.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
532
+ function getResizeHandleElementsForGroup(groupId, scope = document) {
533
+ return Array.from(scope.querySelectorAll(`[data-panel-resize-handle-id][data-panel-group-id="${groupId}"]`));
524
534
  }
525
535
 
526
- function getResizeHandleElementIndex(groupId, id) {
527
- const handles = getResizeHandleElementsForGroup(groupId);
536
+ function getResizeHandleElementIndex(groupId, id, scope = document) {
537
+ const handles = getResizeHandleElementsForGroup(groupId, scope);
528
538
  const index = handles.findIndex(handle => handle.getAttribute("data-panel-resize-handle-id") === id);
529
539
  return index !== null && index !== void 0 ? index : null;
530
540
  }
531
541
 
532
- function determinePivotIndices(groupId, dragHandleId) {
533
- const index = getResizeHandleElementIndex(groupId, dragHandleId);
542
+ function determinePivotIndices(groupId, dragHandleId, panelGroupElement) {
543
+ const index = getResizeHandleElementIndex(groupId, dragHandleId, panelGroupElement);
534
544
  return index != null ? [index, index + 1] : [-1, -1];
535
545
  }
536
546
 
537
- function getPanelGroupElement(id) {
538
- const element = document.querySelector(`[data-panel-group][data-panel-group-id="${id}"]`);
547
+ function getPanelGroupElement(id, rootElement = document) {
548
+ var _dataset;
549
+ //If the root element is the PanelGroup
550
+ if (rootElement instanceof HTMLElement && (rootElement === null || rootElement === void 0 ? void 0 : (_dataset = rootElement.dataset) === null || _dataset === void 0 ? void 0 : _dataset.panelGroupId) == id) {
551
+ return rootElement;
552
+ }
553
+
554
+ //Else query children
555
+ const element = rootElement.querySelector(`[data-panel-group][data-panel-group-id="${id}"]`);
539
556
  if (element) {
540
557
  return element;
541
558
  }
542
559
  return null;
543
560
  }
544
561
 
545
- function getResizeHandleElement(id) {
546
- const element = document.querySelector(`[data-panel-resize-handle-id="${id}"]`);
562
+ function getResizeHandleElement(id, scope = document) {
563
+ const element = scope.querySelector(`[data-panel-resize-handle-id="${id}"]`);
547
564
  if (element) {
548
565
  return element;
549
566
  }
550
567
  return null;
551
568
  }
552
569
 
553
- function getResizeHandlePanelIds(groupId, handleId, panelsArray) {
570
+ function getResizeHandlePanelIds(groupId, handleId, panelsArray, scope = document) {
554
571
  var _panelsArray$index$id, _panelsArray$index, _panelsArray$id, _panelsArray;
555
- const handle = getResizeHandleElement(handleId);
556
- const handles = getResizeHandleElementsForGroup(groupId);
572
+ const handle = getResizeHandleElement(handleId, scope);
573
+ const handles = getResizeHandleElementsForGroup(groupId, scope);
557
574
  const index = handle ? handles.indexOf(handle) : -1;
558
575
  const idBefore = (_panelsArray$index$id = (_panelsArray$index = panelsArray[index]) === null || _panelsArray$index === void 0 ? void 0 : _panelsArray$index.id) !== null && _panelsArray$index$id !== void 0 ? _panelsArray$index$id : null;
559
576
  const idAfter = (_panelsArray$id = (_panelsArray = panelsArray[index + 1]) === null || _panelsArray === void 0 ? void 0 : _panelsArray.id) !== null && _panelsArray$id !== void 0 ? _panelsArray$id : null;
@@ -568,13 +585,17 @@ function useWindowSplitterPanelGroupBehavior({
568
585
  groupId,
569
586
  layout,
570
587
  panelDataArray,
588
+ panelGroupElement,
571
589
  setLayout
572
590
  }) {
573
591
  useRef({
574
592
  didWarnAboutMissingResizeHandle: false
575
593
  });
576
594
  useIsomorphicLayoutEffect(() => {
577
- const resizeHandleElements = getResizeHandleElementsForGroup(groupId);
595
+ if (!panelGroupElement) {
596
+ return;
597
+ }
598
+ const resizeHandleElements = getResizeHandleElementsForGroup(groupId, panelGroupElement);
578
599
  for (let index = 0; index < panelDataArray.length - 1; index++) {
579
600
  const {
580
601
  valueMax,
@@ -603,21 +624,24 @@ function useWindowSplitterPanelGroupBehavior({
603
624
  resizeHandleElement.removeAttribute("aria-valuenow");
604
625
  });
605
626
  };
606
- }, [groupId, layout, panelDataArray]);
627
+ }, [groupId, layout, panelDataArray, panelGroupElement]);
607
628
  useEffect(() => {
629
+ if (!panelGroupElement) {
630
+ return;
631
+ }
608
632
  const eagerValues = eagerValuesRef.current;
609
633
  assert(eagerValues);
610
634
  const {
611
635
  panelDataArray
612
636
  } = eagerValues;
613
- const groupElement = getPanelGroupElement(groupId);
637
+ const groupElement = getPanelGroupElement(groupId, panelGroupElement);
614
638
  assert(groupElement != null, `No group found for id "${groupId}"`);
615
- const handles = getResizeHandleElementsForGroup(groupId);
639
+ const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
616
640
  assert(handles);
617
641
  const cleanupFunctions = handles.map(handle => {
618
642
  const handleId = handle.getAttribute("data-panel-resize-handle-id");
619
643
  assert(handleId);
620
- const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray);
644
+ const [idBefore, idAfter] = getResizeHandlePanelIds(groupId, handleId, panelDataArray, panelGroupElement);
621
645
  if (idBefore == null || idAfter == null) {
622
646
  return () => {};
623
647
  }
@@ -644,7 +668,7 @@ function useWindowSplitterPanelGroupBehavior({
644
668
  delta: fuzzyNumbersEqual(size, collapsedSize) ? minSize - collapsedSize : collapsedSize - size,
645
669
  layout,
646
670
  panelConstraints: panelDataArray.map(panelData => panelData.constraints),
647
- pivotIndices: determinePivotIndices(groupId, handleId),
671
+ pivotIndices: determinePivotIndices(groupId, handleId, panelGroupElement),
648
672
  trigger: "keyboard"
649
673
  });
650
674
  if (layout !== nextLayout) {
@@ -664,7 +688,7 @@ function useWindowSplitterPanelGroupBehavior({
664
688
  return () => {
665
689
  cleanupFunctions.forEach(cleanupFunction => cleanupFunction());
666
690
  };
667
- }, [committedValuesRef, eagerValuesRef, groupId, layout, panelDataArray, setLayout]);
691
+ }, [panelGroupElement, committedValuesRef, eagerValuesRef, groupId, layout, panelDataArray, setLayout]);
668
692
  }
669
693
 
670
694
  function areEqual(arrayA, arrayB) {
@@ -702,9 +726,9 @@ function getResizeEventCursorPosition(direction, event) {
702
726
  }
703
727
  }
704
728
 
705
- function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState) {
729
+ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState, panelGroupElement) {
706
730
  const isHorizontal = direction === "horizontal";
707
- const handleElement = getResizeHandleElement(dragHandleId);
731
+ const handleElement = getResizeHandleElement(dragHandleId, panelGroupElement);
708
732
  assert(handleElement);
709
733
  const groupId = handleElement.getAttribute("data-panel-group-id");
710
734
  assert(groupId);
@@ -712,7 +736,7 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
712
736
  initialCursorPosition
713
737
  } = initialDragState;
714
738
  const cursorPosition = getResizeEventCursorPosition(direction, event);
715
- const groupElement = getPanelGroupElement(groupId);
739
+ const groupElement = getPanelGroupElement(groupId, panelGroupElement);
716
740
  assert(groupElement);
717
741
  const groupRect = groupElement.getBoundingClientRect();
718
742
  const groupSizeInPixels = isHorizontal ? groupRect.width : groupRect.height;
@@ -722,7 +746,7 @@ function calculateDragOffsetPercentage(event, dragHandleId, direction, initialDr
722
746
  }
723
747
 
724
748
  // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
725
- function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy) {
749
+ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragState, keyboardResizeBy, panelGroupElement) {
726
750
  if (isKeyDown(event)) {
727
751
  const isHorizontal = direction === "horizontal";
728
752
  let delta = 0;
@@ -759,7 +783,7 @@ function calculateDeltaPercentage(event, dragHandleId, direction, initialDragSta
759
783
  if (initialDragState == null) {
760
784
  return 0;
761
785
  }
762
- return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState);
786
+ return calculateDragOffsetPercentage(event, dragHandleId, direction, initialDragState, panelGroupElement);
763
787
  }
764
788
  }
765
789
 
@@ -1111,6 +1135,7 @@ function PanelGroupWithForwardedRef({
1111
1135
  ...rest
1112
1136
  }) {
1113
1137
  const groupId = useUniqueId(idFromProps);
1138
+ const panelGroupElementRef = useRef(null);
1114
1139
  const [dragState, setDragState] = useState(null);
1115
1140
  const [layout, setLayout] = useState([]);
1116
1141
  const panelIdToLastNotifiedSizeMapRef = useRef({});
@@ -1179,7 +1204,8 @@ function PanelGroupWithForwardedRef({
1179
1204
  groupId,
1180
1205
  layout,
1181
1206
  panelDataArray: eagerValuesRef.current.panelDataArray,
1182
- setLayout
1207
+ setLayout,
1208
+ panelGroupElement: panelGroupElementRef.current
1183
1209
  });
1184
1210
  useEffect(() => {
1185
1211
  const {
@@ -1422,6 +1448,10 @@ function PanelGroupWithForwardedRef({
1422
1448
  const registerResizeHandle = useCallback(dragHandleId => {
1423
1449
  return function resizeHandler(event) {
1424
1450
  event.preventDefault();
1451
+ const panelGroupElement = panelGroupElementRef.current;
1452
+ if (!panelGroupElement) {
1453
+ return () => null;
1454
+ }
1425
1455
  const {
1426
1456
  direction,
1427
1457
  dragState,
@@ -1436,8 +1466,8 @@ function PanelGroupWithForwardedRef({
1436
1466
  const {
1437
1467
  initialLayout
1438
1468
  } = dragState !== null && dragState !== void 0 ? dragState : {};
1439
- const pivotIndices = determinePivotIndices(groupId, dragHandleId);
1440
- let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy);
1469
+ const pivotIndices = determinePivotIndices(groupId, dragHandleId, panelGroupElement);
1470
+ let delta = calculateDeltaPercentage(event, dragHandleId, direction, dragState, keyboardResizeBy, panelGroupElement);
1441
1471
  if (delta === 0) {
1442
1472
  return;
1443
1473
  }
@@ -1525,6 +1555,37 @@ function PanelGroupWithForwardedRef({
1525
1555
  callPanelCallbacks(panelDataArray, nextLayout, panelIdToLastNotifiedSizeMapRef.current);
1526
1556
  }
1527
1557
  }, []);
1558
+ const reevaluatePanelConstraints = useCallback((panelData, prevConstraints) => {
1559
+ const {
1560
+ layout,
1561
+ panelDataArray
1562
+ } = eagerValuesRef.current;
1563
+ const {
1564
+ collapsedSize: prevCollapsedSize = 0,
1565
+ collapsible: prevCollapsible,
1566
+ defaultSize: prevDefaultSize,
1567
+ maxSize: prevMaxSize = 100,
1568
+ minSize: prevMinSize = 0
1569
+ } = prevConstraints;
1570
+ const {
1571
+ collapsedSize: nextCollapsedSize = 0,
1572
+ collapsible: nextCollapsible,
1573
+ defaultSize: nextDefaultSize,
1574
+ maxSize: nextMaxSize = 100,
1575
+ minSize: nextMinSize = 0
1576
+ } = panelData.constraints;
1577
+ const {
1578
+ panelSize: prevPanelSize
1579
+ } = panelDataHelper(panelDataArray, panelData, layout);
1580
+ assert(prevPanelSize != null);
1581
+ if (prevCollapsible && nextCollapsible && prevCollapsedSize !== nextCollapsedSize && prevPanelSize === prevCollapsedSize) {
1582
+ resizePanel(panelData, nextCollapsedSize);
1583
+ } else if (prevPanelSize < nextMinSize) {
1584
+ resizePanel(panelData, nextMinSize);
1585
+ } else if (prevPanelSize > nextMaxSize) {
1586
+ resizePanel(panelData, nextMaxSize);
1587
+ }
1588
+ }, [resizePanel]);
1528
1589
  const startDragging = useCallback((dragHandleId, event) => {
1529
1590
  const {
1530
1591
  direction
@@ -1532,7 +1593,10 @@ function PanelGroupWithForwardedRef({
1532
1593
  const {
1533
1594
  layout
1534
1595
  } = eagerValuesRef.current;
1535
- const handleElement = getResizeHandleElement(dragHandleId);
1596
+ if (!panelGroupElementRef.current) {
1597
+ return;
1598
+ }
1599
+ const handleElement = getResizeHandleElement(dragHandleId, panelGroupElementRef.current);
1536
1600
  assert(handleElement);
1537
1601
  const initialCursorPosition = getResizeEventCursorPosition(direction, event);
1538
1602
  setDragState({
@@ -1572,13 +1636,15 @@ function PanelGroupWithForwardedRef({
1572
1636
  groupId,
1573
1637
  isPanelCollapsed,
1574
1638
  isPanelExpanded,
1639
+ reevaluatePanelConstraints,
1575
1640
  registerPanel,
1576
1641
  registerResizeHandle,
1577
1642
  resizePanel,
1578
1643
  startDragging,
1579
1644
  stopDragging,
1580
- unregisterPanel
1581
- }), [collapsePanel, dragState, direction, expandPanel, getPanelSize, getPanelStyle, groupId, isPanelCollapsed, isPanelExpanded, registerPanel, registerResizeHandle, resizePanel, startDragging, stopDragging, unregisterPanel]);
1645
+ unregisterPanel,
1646
+ panelGroupElement: panelGroupElementRef.current
1647
+ }), [collapsePanel, dragState, direction, expandPanel, getPanelSize, getPanelStyle, groupId, isPanelCollapsed, isPanelExpanded, reevaluatePanelConstraints, registerPanel, registerResizeHandle, resizePanel, startDragging, stopDragging, unregisterPanel]);
1582
1648
  const style = {
1583
1649
  display: "flex",
1584
1650
  flexDirection: direction === "horizontal" ? "row" : "column",
@@ -1596,6 +1662,7 @@ function PanelGroupWithForwardedRef({
1596
1662
  ...style,
1597
1663
  ...styleFromProps
1598
1664
  },
1665
+ ref: panelGroupElementRef,
1599
1666
  // CSS selectors
1600
1667
  "data-panel-group": "",
1601
1668
  "data-panel-group-direction": direction,
@@ -1612,14 +1679,12 @@ function findPanelDataIndex(panelDataArray, panelData) {
1612
1679
  return panelDataArray.findIndex(prevPanelData => prevPanelData === panelData || prevPanelData.id === panelData.id);
1613
1680
  }
1614
1681
  function panelDataHelper(panelDataArray, panelData, layout) {
1615
- const panelConstraintsArray = panelDataArray.map(panelData => panelData.constraints);
1616
1682
  const panelIndex = findPanelDataIndex(panelDataArray, panelData);
1617
- const panelConstraints = panelConstraintsArray[panelIndex];
1618
1683
  const isLastPanel = panelIndex === panelDataArray.length - 1;
1619
1684
  const pivotIndices = isLastPanel ? [panelIndex - 1, panelIndex] : [panelIndex, panelIndex + 1];
1620
1685
  const panelSize = layout[panelIndex];
1621
1686
  return {
1622
- ...panelConstraints,
1687
+ ...panelData.constraints,
1623
1688
  panelSize,
1624
1689
  pivotIndices
1625
1690
  };
@@ -1630,13 +1695,14 @@ function panelDataHelper(panelDataArray, panelData, layout) {
1630
1695
  function useWindowSplitterResizeHandlerBehavior({
1631
1696
  disabled,
1632
1697
  handleId,
1633
- resizeHandler
1698
+ resizeHandler,
1699
+ panelGroupElement
1634
1700
  }) {
1635
1701
  useEffect(() => {
1636
- if (disabled || resizeHandler == null) {
1702
+ if (disabled || resizeHandler == null || panelGroupElement == null) {
1637
1703
  return;
1638
1704
  }
1639
- const handleElement = getResizeHandleElement(handleId);
1705
+ const handleElement = getResizeHandleElement(handleId, panelGroupElement);
1640
1706
  if (handleElement == null) {
1641
1707
  return;
1642
1708
  }
@@ -1661,8 +1727,8 @@ function useWindowSplitterResizeHandlerBehavior({
1661
1727
  event.preventDefault();
1662
1728
  const groupId = handleElement.getAttribute("data-panel-group-id");
1663
1729
  assert(groupId);
1664
- const handles = getResizeHandleElementsForGroup(groupId);
1665
- const index = getResizeHandleElementIndex(groupId, handleId);
1730
+ const handles = getResizeHandleElementsForGroup(groupId, panelGroupElement);
1731
+ const index = getResizeHandleElementIndex(groupId, handleId, panelGroupElement);
1666
1732
  assert(index !== null);
1667
1733
  const nextIndex = event.shiftKey ? index > 0 ? index - 1 : handles.length - 1 : index + 1 < handles.length ? index + 1 : 0;
1668
1734
  const nextHandle = handles[nextIndex];
@@ -1675,7 +1741,7 @@ function useWindowSplitterResizeHandlerBehavior({
1675
1741
  return () => {
1676
1742
  handleElement.removeEventListener("keydown", onKeyDown);
1677
1743
  };
1678
- }, [disabled, handleId, resizeHandler]);
1744
+ }, [panelGroupElement, disabled, handleId, resizeHandler]);
1679
1745
  }
1680
1746
 
1681
1747
  function PanelResizeHandle({
@@ -1708,7 +1774,8 @@ function PanelResizeHandle({
1708
1774
  groupId,
1709
1775
  registerResizeHandle,
1710
1776
  startDragging,
1711
- stopDragging
1777
+ stopDragging,
1778
+ panelGroupElement
1712
1779
  } = panelGroupContext;
1713
1780
  const resizeHandleId = useUniqueId(idFromProps);
1714
1781
  const isDragging = (dragState === null || dragState === void 0 ? void 0 : dragState.dragHandleId) === resizeHandleId;
@@ -1767,7 +1834,8 @@ function PanelResizeHandle({
1767
1834
  useWindowSplitterResizeHandlerBehavior({
1768
1835
  disabled,
1769
1836
  handleId: resizeHandleId,
1770
- resizeHandler
1837
+ resizeHandler,
1838
+ panelGroupElement
1771
1839
  });
1772
1840
  const style = {
1773
1841
  cursor: getCursorStyle(direction),
@@ -1823,60 +1891,22 @@ function PanelResizeHandle({
1823
1891
  }
1824
1892
  PanelResizeHandle.displayName = "PanelResizeHandle";
1825
1893
 
1826
- function calculateAvailablePanelSizeInPixels(groupId) {
1827
- const panelGroupElement = getPanelGroupElement(groupId);
1828
- if (panelGroupElement == null) {
1829
- return NaN;
1830
- }
1831
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
1832
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
1833
- if (direction === "horizontal") {
1834
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
1835
- return accumulated + handle.offsetWidth;
1836
- }, 0);
1837
- } else {
1838
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
1839
- return accumulated + handle.offsetHeight;
1840
- }, 0);
1841
- }
1842
- }
1843
-
1844
- function getAvailableGroupSizePixels(groupId) {
1845
- const panelGroupElement = getPanelGroupElement(groupId);
1846
- if (panelGroupElement == null) {
1847
- return NaN;
1848
- }
1849
- const direction = panelGroupElement.getAttribute("data-panel-group-direction");
1850
- const resizeHandles = getResizeHandleElementsForGroup(groupId);
1851
- if (direction === "horizontal") {
1852
- return panelGroupElement.offsetWidth - resizeHandles.reduce((accumulated, handle) => {
1853
- return accumulated + handle.offsetWidth;
1854
- }, 0);
1855
- } else {
1856
- return panelGroupElement.offsetHeight - resizeHandles.reduce((accumulated, handle) => {
1857
- return accumulated + handle.offsetHeight;
1858
- }, 0);
1859
- }
1860
- }
1861
-
1862
- function getPanelElement(id) {
1863
- const element = document.querySelector(`[data-panel-id="${id}"]`);
1894
+ function getPanelElement(id, scope = document) {
1895
+ const element = scope.querySelector(`[data-panel-id="${id}"]`);
1864
1896
  if (element) {
1865
1897
  return element;
1866
1898
  }
1867
1899
  return null;
1868
1900
  }
1869
1901
 
1870
- function getPanelElementsForGroup(groupId) {
1871
- return Array.from(document.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
1902
+ function getPanelElementsForGroup(groupId, scope = document) {
1903
+ return Array.from(scope.querySelectorAll(`[data-panel][data-panel-group-id="${groupId}"]`));
1872
1904
  }
1873
1905
 
1874
1906
  exports.Panel = Panel;
1875
1907
  exports.PanelGroup = PanelGroup;
1876
1908
  exports.PanelResizeHandle = PanelResizeHandle;
1877
1909
  exports.assert = assert;
1878
- exports.calculateAvailablePanelSizeInPixels = calculateAvailablePanelSizeInPixels;
1879
- exports.getAvailableGroupSizePixels = getAvailableGroupSizePixels;
1880
1910
  exports.getPanelElement = getPanelElement;
1881
1911
  exports.getPanelElementsForGroup = getPanelElementsForGroup;
1882
1912
  exports.getPanelGroupElement = getPanelGroupElement;
@@ -3,8 +3,6 @@ export {
3
3
  PanelGroup,
4
4
  PanelResizeHandle,
5
5
  assert,
6
- calculateAvailablePanelSizeInPixels,
7
- getAvailableGroupSizePixels,
8
6
  getPanelElement,
9
7
  getPanelElementsForGroup,
10
8
  getPanelGroupElement,