react-resizable-panels 2.0.0 → 2.0.2

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,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 2.0.2
4
+
5
+ - Fixed an issue where size might not be re-initialized correctly after a panel was hidden by the `unstable_Activity` (previously "Offscreen") API.
6
+
7
+ ## 2.0.1
8
+
9
+ - Fixed a regression introduced in 2.0.0 that caused React `onClick` and `onMouseUp` handlers not to fire.
10
+
3
11
  ## 2.0.0
4
12
 
5
13
  - Support resizing multiple (intersecting) panels at once (#274)
@@ -337,13 +337,13 @@ function handlePointerDown(event) {
337
337
  y
338
338
  } = getResizeEventCoordinates(event);
339
339
  isPointerDown = true;
340
- updateResizeHandlerStates("down", event);
341
340
  recalculateIntersectingHandles({
342
341
  x,
343
342
  y
344
343
  });
345
344
  updateListeners();
346
345
  if (intersectingHandles.length > 0) {
346
+ updateResizeHandlerStates("down", event);
347
347
  event.preventDefault();
348
348
  }
349
349
  }
@@ -1709,6 +1709,14 @@ function PanelGroupWithForwardedRef({
1709
1709
  }
1710
1710
  }
1711
1711
  });
1712
+
1713
+ // Reset the cached layout if hidden by the Activity/Offscreen API
1714
+ useIsomorphicLayoutEffect(() => {
1715
+ const eagerValues = eagerValuesRef.current;
1716
+ return () => {
1717
+ eagerValues.layout = [];
1718
+ };
1719
+ }, []);
1712
1720
  const registerResizeHandle = useCallback(dragHandleId => {
1713
1721
  return function resizeHandler(event) {
1714
1722
  event.preventDefault();
@@ -343,13 +343,13 @@ function handlePointerDown(event) {
343
343
  y
344
344
  } = getResizeEventCoordinates(event);
345
345
  isPointerDown = true;
346
- updateResizeHandlerStates("down", event);
347
346
  recalculateIntersectingHandles({
348
347
  x,
349
348
  y
350
349
  });
351
350
  updateListeners();
352
351
  if (intersectingHandles.length > 0) {
352
+ updateResizeHandlerStates("down", event);
353
353
  event.preventDefault();
354
354
  }
355
355
  }
@@ -1815,6 +1815,14 @@ function PanelGroupWithForwardedRef({
1815
1815
  }
1816
1816
  }
1817
1817
  });
1818
+
1819
+ // Reset the cached layout if hidden by the Activity/Offscreen API
1820
+ useIsomorphicLayoutEffect(() => {
1821
+ const eagerValues = eagerValuesRef.current;
1822
+ return () => {
1823
+ eagerValues.layout = [];
1824
+ };
1825
+ }, []);
1818
1826
  const registerResizeHandle = useCallback(dragHandleId => {
1819
1827
  return function resizeHandler(event) {
1820
1828
  event.preventDefault();
@@ -319,13 +319,13 @@ function handlePointerDown(event) {
319
319
  y
320
320
  } = getResizeEventCoordinates(event);
321
321
  isPointerDown = true;
322
- updateResizeHandlerStates("down", event);
323
322
  recalculateIntersectingHandles({
324
323
  x,
325
324
  y
326
325
  });
327
326
  updateListeners();
328
327
  if (intersectingHandles.length > 0) {
328
+ updateResizeHandlerStates("down", event);
329
329
  event.preventDefault();
330
330
  }
331
331
  }
@@ -1791,6 +1791,14 @@ function PanelGroupWithForwardedRef({
1791
1791
  }
1792
1792
  }
1793
1793
  });
1794
+
1795
+ // Reset the cached layout if hidden by the Activity/Offscreen API
1796
+ useIsomorphicLayoutEffect(() => {
1797
+ const eagerValues = eagerValuesRef.current;
1798
+ return () => {
1799
+ eagerValues.layout = [];
1800
+ };
1801
+ }, []);
1794
1802
  const registerResizeHandle = useCallback(dragHandleId => {
1795
1803
  return function resizeHandler(event) {
1796
1804
  event.preventDefault();
@@ -313,13 +313,13 @@ function handlePointerDown(event) {
313
313
  y
314
314
  } = getResizeEventCoordinates(event);
315
315
  isPointerDown = true;
316
- updateResizeHandlerStates("down", event);
317
316
  recalculateIntersectingHandles({
318
317
  x,
319
318
  y
320
319
  });
321
320
  updateListeners();
322
321
  if (intersectingHandles.length > 0) {
322
+ updateResizeHandlerStates("down", event);
323
323
  event.preventDefault();
324
324
  }
325
325
  }
@@ -1685,6 +1685,14 @@ function PanelGroupWithForwardedRef({
1685
1685
  }
1686
1686
  }
1687
1687
  });
1688
+
1689
+ // Reset the cached layout if hidden by the Activity/Offscreen API
1690
+ useIsomorphicLayoutEffect(() => {
1691
+ const eagerValues = eagerValuesRef.current;
1692
+ return () => {
1693
+ eagerValues.layout = [];
1694
+ };
1695
+ }, []);
1688
1696
  const registerResizeHandle = useCallback(dragHandleId => {
1689
1697
  return function resizeHandler(event) {
1690
1698
  event.preventDefault();
@@ -339,13 +339,13 @@ function handlePointerDown(event) {
339
339
  y
340
340
  } = getResizeEventCoordinates(event);
341
341
  isPointerDown = true;
342
- updateResizeHandlerStates("down", event);
343
342
  recalculateIntersectingHandles({
344
343
  x,
345
344
  y
346
345
  });
347
346
  updateListeners();
348
347
  if (intersectingHandles.length > 0) {
348
+ updateResizeHandlerStates("down", event);
349
349
  event.preventDefault();
350
350
  }
351
351
  }
@@ -1711,6 +1711,14 @@ function PanelGroupWithForwardedRef({
1711
1711
  }
1712
1712
  }
1713
1713
  });
1714
+
1715
+ // Reset the cached layout if hidden by the Activity/Offscreen API
1716
+ useIsomorphicLayoutEffect(() => {
1717
+ const eagerValues = eagerValuesRef.current;
1718
+ return () => {
1719
+ eagerValues.layout = [];
1720
+ };
1721
+ }, []);
1714
1722
  const registerResizeHandle = useCallback(dragHandleId => {
1715
1723
  return function resizeHandler(event) {
1716
1724
  event.preventDefault();
@@ -350,13 +350,13 @@ function handlePointerDown(event) {
350
350
  y
351
351
  } = getResizeEventCoordinates(event);
352
352
  isPointerDown = true;
353
- updateResizeHandlerStates("down", event);
354
353
  recalculateIntersectingHandles({
355
354
  x,
356
355
  y
357
356
  });
358
357
  updateListeners();
359
358
  if (intersectingHandles.length > 0) {
359
+ updateResizeHandlerStates("down", event);
360
360
  event.preventDefault();
361
361
  }
362
362
  }
@@ -1822,6 +1822,14 @@ function PanelGroupWithForwardedRef({
1822
1822
  }
1823
1823
  }
1824
1824
  });
1825
+
1826
+ // Reset the cached layout if hidden by the Activity/Offscreen API
1827
+ useIsomorphicLayoutEffect(() => {
1828
+ const eagerValues = eagerValuesRef.current;
1829
+ return () => {
1830
+ eagerValues.layout = [];
1831
+ };
1832
+ }, []);
1825
1833
  const registerResizeHandle = useCallback(dragHandleId => {
1826
1834
  return function resizeHandler(event) {
1827
1835
  event.preventDefault();
@@ -326,13 +326,13 @@ function handlePointerDown(event) {
326
326
  y
327
327
  } = getResizeEventCoordinates(event);
328
328
  isPointerDown = true;
329
- updateResizeHandlerStates("down", event);
330
329
  recalculateIntersectingHandles({
331
330
  x,
332
331
  y
333
332
  });
334
333
  updateListeners();
335
334
  if (intersectingHandles.length > 0) {
335
+ updateResizeHandlerStates("down", event);
336
336
  event.preventDefault();
337
337
  }
338
338
  }
@@ -1798,6 +1798,14 @@ function PanelGroupWithForwardedRef({
1798
1798
  }
1799
1799
  }
1800
1800
  });
1801
+
1802
+ // Reset the cached layout if hidden by the Activity/Offscreen API
1803
+ useIsomorphicLayoutEffect(() => {
1804
+ const eagerValues = eagerValuesRef.current;
1805
+ return () => {
1806
+ eagerValues.layout = [];
1807
+ };
1808
+ }, []);
1801
1809
  const registerResizeHandle = useCallback(dragHandleId => {
1802
1810
  return function resizeHandler(event) {
1803
1811
  event.preventDefault();
@@ -313,13 +313,13 @@ function handlePointerDown(event) {
313
313
  y
314
314
  } = getResizeEventCoordinates(event);
315
315
  isPointerDown = true;
316
- updateResizeHandlerStates("down", event);
317
316
  recalculateIntersectingHandles({
318
317
  x,
319
318
  y
320
319
  });
321
320
  updateListeners();
322
321
  if (intersectingHandles.length > 0) {
322
+ updateResizeHandlerStates("down", event);
323
323
  event.preventDefault();
324
324
  }
325
325
  }
@@ -289,13 +289,13 @@ function handlePointerDown(event) {
289
289
  y
290
290
  } = getResizeEventCoordinates(event);
291
291
  isPointerDown = true;
292
- updateResizeHandlerStates("down", event);
293
292
  recalculateIntersectingHandles({
294
293
  x,
295
294
  y
296
295
  });
297
296
  updateListeners();
298
297
  if (intersectingHandles.length > 0) {
298
+ updateResizeHandlerStates("down", event);
299
299
  event.preventDefault();
300
300
  }
301
301
  }
@@ -315,13 +315,13 @@ function handlePointerDown(event) {
315
315
  y
316
316
  } = getResizeEventCoordinates(event);
317
317
  isPointerDown = true;
318
- updateResizeHandlerStates("down", event);
319
318
  recalculateIntersectingHandles({
320
319
  x,
321
320
  y
322
321
  });
323
322
  updateListeners();
324
323
  if (intersectingHandles.length > 0) {
324
+ updateResizeHandlerStates("down", event);
325
325
  event.preventDefault();
326
326
  }
327
327
  }
@@ -1687,6 +1687,14 @@ function PanelGroupWithForwardedRef({
1687
1687
  }
1688
1688
  }
1689
1689
  });
1690
+
1691
+ // Reset the cached layout if hidden by the Activity/Offscreen API
1692
+ useIsomorphicLayoutEffect(() => {
1693
+ const eagerValues = eagerValuesRef.current;
1694
+ return () => {
1695
+ eagerValues.layout = [];
1696
+ };
1697
+ }, []);
1690
1698
  const registerResizeHandle = useCallback(dragHandleId => {
1691
1699
  return function resizeHandler(event) {
1692
1700
  event.preventDefault();
@@ -302,13 +302,13 @@ function handlePointerDown(event) {
302
302
  y
303
303
  } = getResizeEventCoordinates(event);
304
304
  isPointerDown = true;
305
- updateResizeHandlerStates("down", event);
306
305
  recalculateIntersectingHandles({
307
306
  x,
308
307
  y
309
308
  });
310
309
  updateListeners();
311
310
  if (intersectingHandles.length > 0) {
311
+ updateResizeHandlerStates("down", event);
312
312
  event.preventDefault();
313
313
  }
314
314
  }
@@ -278,13 +278,13 @@ function handlePointerDown(event) {
278
278
  y
279
279
  } = getResizeEventCoordinates(event);
280
280
  isPointerDown = true;
281
- updateResizeHandlerStates("down", event);
282
281
  recalculateIntersectingHandles({
283
282
  x,
284
283
  y
285
284
  });
286
285
  updateListeners();
287
286
  if (intersectingHandles.length > 0) {
287
+ updateResizeHandlerStates("down", event);
288
288
  event.preventDefault();
289
289
  }
290
290
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-resizable-panels",
3
- "version": "2.0.0",
3
+ "version": "2.0.2",
4
4
  "description": "React components for resizable panel groups/layouts",
5
5
  "author": "Brian Vaughn <brian.david.vaughn@gmail.com>",
6
6
  "license": "MIT",
@@ -72,8 +72,8 @@
72
72
  "eslint": "^8.37.0",
73
73
  "eslint-plugin-no-restricted-imports": "^0.0.0",
74
74
  "eslint-plugin-react-hooks": "^4.6.0",
75
- "react": "latest",
76
- "react-dom": "latest"
75
+ "react": "experimental",
76
+ "react-dom": "experimental"
77
77
  },
78
78
  "peerDependencies": {
79
79
  "react": "^16.14.0 || ^17.0.0 || ^18.0.0",
@@ -1,3 +1,6 @@
1
+ // @ts-expect-error This is an experimental API
2
+ // eslint-disable-next-line no-restricted-imports
3
+ import { unstable_Activity as Activity } from "react";
1
4
  import { Root, createRoot } from "react-dom/client";
2
5
  import { act } from "react-dom/test-utils";
3
6
  import {
@@ -6,6 +9,7 @@ import {
6
9
  Panel,
7
10
  PanelGroup,
8
11
  PanelResizeHandle,
12
+ getPanelElement,
9
13
  } from ".";
10
14
  import { assert } from "./utils/assert";
11
15
  import { getPanelGroupElement } from "./utils/dom/getPanelGroupElement";
@@ -62,6 +66,67 @@ describe("PanelGroup", () => {
62
66
  expect(expectedWarnings).toHaveLength(0);
63
67
  });
64
68
 
69
+ it("should recalculate layout after being hidden by Activity", () => {
70
+ const panelRef = createRef<ImperativePanelHandle>();
71
+
72
+ let mostRecentLayout: number[] | null = null;
73
+
74
+ const onLayout = (layout: number[]) => {
75
+ mostRecentLayout = layout;
76
+ };
77
+
78
+ act(() => {
79
+ root.render(
80
+ <Activity mode="visible">
81
+ <PanelGroup direction="horizontal" onLayout={onLayout}>
82
+ <Panel id="left" ref={panelRef} />
83
+ <PanelResizeHandle />
84
+ <Panel defaultSize={40} id="right" />
85
+ </PanelGroup>
86
+ </Activity>
87
+ );
88
+ });
89
+
90
+ expect(mostRecentLayout).toEqual([60, 40]);
91
+ expect(panelRef.current?.getSize()).toEqual(60);
92
+
93
+ const leftPanelElement = getPanelElement("left");
94
+ const rightPanelElement = getPanelElement("right");
95
+ expect(leftPanelElement?.getAttribute("data-panel-size")).toBe("60.0");
96
+ expect(rightPanelElement?.getAttribute("data-panel-size")).toBe("40.0");
97
+
98
+ act(() => {
99
+ root.render(
100
+ <Activity mode="hidden">
101
+ <PanelGroup direction="horizontal" onLayout={onLayout}>
102
+ <Panel id="left" ref={panelRef} />
103
+ <PanelResizeHandle />
104
+ <Panel defaultSize={40} id="right" />
105
+ </PanelGroup>
106
+ </Activity>
107
+ );
108
+ });
109
+
110
+ act(() => {
111
+ root.render(
112
+ <Activity mode="visible">
113
+ <PanelGroup direction="horizontal" onLayout={onLayout}>
114
+ <Panel id="left" ref={panelRef} />
115
+ <PanelResizeHandle />
116
+ <Panel defaultSize={40} id="right" />
117
+ </PanelGroup>
118
+ </Activity>
119
+ );
120
+ });
121
+
122
+ expect(mostRecentLayout).toEqual([60, 40]);
123
+ expect(panelRef.current?.getSize()).toEqual(60);
124
+
125
+ // This bug is only observable in the DOM; callbacks will not re-fire
126
+ expect(leftPanelElement?.getAttribute("data-panel-size")).toBe("60.0");
127
+ expect(rightPanelElement?.getAttribute("data-panel-size")).toBe("40.0");
128
+ });
129
+
65
130
  describe("imperative handle API", () => {
66
131
  it("should report the most recently rendered group id", () => {
67
132
  const ref = createRef<ImperativePanelGroupHandle>();
package/src/PanelGroup.ts CHANGED
@@ -25,7 +25,6 @@ import { calculateUnsafeDefaultLayout } from "./utils/calculateUnsafeDefaultLayo
25
25
  import { callPanelCallbacks } from "./utils/callPanelCallbacks";
26
26
  import { compareLayouts } from "./utils/compareLayouts";
27
27
  import { computePanelFlexBoxStyle } from "./utils/computePanelFlexBoxStyle";
28
- import { resetGlobalCursorStyle, setGlobalCursorStyle } from "./utils/cursor";
29
28
  import debounce from "./utils/debounce";
30
29
  import { determinePivotIndices } from "./utils/determinePivotIndices";
31
30
  import { getResizeHandleElement } from "./utils/dom/getResizeHandleElement";
@@ -571,6 +570,14 @@ function PanelGroupWithForwardedRef({
571
570
  }
572
571
  });
573
572
 
573
+ // Reset the cached layout if hidden by the Activity/Offscreen API
574
+ useIsomorphicLayoutEffect(() => {
575
+ const eagerValues = eagerValuesRef.current;
576
+ return () => {
577
+ eagerValues.layout = [];
578
+ };
579
+ }, []);
580
+
574
581
  const registerResizeHandle = useCallback((dragHandleId: string) => {
575
582
  return function resizeHandler(event: ResizeEvent) {
576
583
  event.preventDefault();
@@ -80,12 +80,12 @@ function handlePointerDown(event: ResizeEvent) {
80
80
 
81
81
  isPointerDown = true;
82
82
 
83
- updateResizeHandlerStates("down", event);
84
-
85
83
  recalculateIntersectingHandles({ x, y });
86
84
  updateListeners();
87
85
 
88
86
  if (intersectingHandles.length > 0) {
87
+ updateResizeHandlerStates("down", event);
88
+
89
89
  event.preventDefault();
90
90
  }
91
91
  }