react-resizable-panels 2.0.2 → 2.0.4

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.4
4
+
5
+ - Fixed `PanelResizeHandle` `onDragging` prop to only be called for the handle being dragged (#289)
6
+
7
+ ## 2.0.3
8
+
9
+ - Fix resize handle onDragging callback (#278)
10
+
3
11
  ## 2.0.2
4
12
 
5
13
  - Fixed an issue where size might not be re-initialized correctly after a panel was hidden by the `unstable_Activity` (previously "Offscreen") API.
@@ -1,6 +1,7 @@
1
1
  import { CSSProperties, HTMLAttributes, PropsWithChildren, ReactElement } from "./vendor/react.js";
2
2
  import { PointerHitAreaMargins } from "./PanelResizeHandleRegistry.js";
3
3
  export type PanelResizeHandleOnDragging = (isDragging: boolean) => void;
4
+ export type ResizeHandlerState = "drag" | "hover" | "inactive";
4
5
  export type PanelResizeHandleProps = Omit<HTMLAttributes<keyof HTMLElementTagNameMap>, "id"> & PropsWithChildren<{
5
6
  className?: string;
6
7
  disabled?: boolean;
@@ -1,7 +1,6 @@
1
1
  import { Direction, ResizeEvent } from "./types.js";
2
2
  export type ResizeHandlerAction = "down" | "move" | "up";
3
- export type ResizeHandlerState = "drag" | "hover" | "inactive";
4
- export type SetResizeHandlerState = (action: ResizeHandlerAction, state: ResizeHandlerState, event: ResizeEvent) => void;
3
+ export type SetResizeHandlerState = (action: ResizeHandlerAction, isActive: boolean, event: ResizeEvent) => void;
5
4
  export type PointerHitAreaMargins = {
6
5
  coarse: number;
7
6
  fine: number;
@@ -352,24 +352,19 @@ function handlePointerMove(event) {
352
352
  x,
353
353
  y
354
354
  } = getResizeEventCoordinates(event);
355
- if (isPointerDown) {
356
- intersectingHandles.forEach(data => {
357
- const {
358
- setResizeHandlerState
359
- } = data;
360
- setResizeHandlerState("move", "drag", event);
361
- });
362
-
363
- // Update cursor based on return value(s) from active handles
364
- updateCursor();
365
- } else {
355
+ if (!isPointerDown) {
356
+ // Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
357
+ // at that point, the handles may not move with the pointer (depending on constraints)
358
+ // but the same set of active handles should be locked until the pointer is released
366
359
  recalculateIntersectingHandles({
367
360
  x,
368
361
  y
369
362
  });
370
- updateResizeHandlerStates("move", event);
371
- updateCursor();
372
363
  }
364
+ updateResizeHandlerStates("move", event);
365
+
366
+ // Update cursor based on return value(s) from active handles
367
+ updateCursor();
373
368
  if (intersectingHandles.length > 0) {
374
369
  event.preventDefault();
375
370
  }
@@ -502,15 +497,8 @@ function updateResizeHandlerStates(action, event) {
502
497
  const {
503
498
  setResizeHandlerState
504
499
  } = data;
505
- if (intersectingHandles.includes(data)) {
506
- if (isPointerDown) {
507
- setResizeHandlerState(action, "drag", event);
508
- } else {
509
- setResizeHandlerState(action, "hover", event);
510
- }
511
- } else {
512
- setResizeHandlerState(action, "inactive", event);
513
- }
500
+ const isActive = intersectingHandles.includes(data);
501
+ setResizeHandlerState(action, isActive, event);
514
502
  });
515
503
  }
516
504
 
@@ -2047,6 +2035,12 @@ function PanelResizeHandle({
2047
2035
  const [state, setState] = useState("inactive");
2048
2036
  const [isFocused, setIsFocused] = useState(false);
2049
2037
  const [resizeHandler, setResizeHandler] = useState(null);
2038
+ const committedValuesRef = useRef({
2039
+ state
2040
+ });
2041
+ useLayoutEffect(() => {
2042
+ committedValuesRef.current.state = state;
2043
+ });
2050
2044
  useEffect(() => {
2051
2045
  if (disabled) {
2052
2046
  setResizeHandler(null);
@@ -2062,26 +2056,47 @@ function PanelResizeHandle({
2062
2056
  }
2063
2057
  const element = elementRef.current;
2064
2058
  assert(element);
2065
- const setResizeHandlerState = (action, state, event) => {
2066
- setState(state);
2067
- switch (action) {
2068
- case "down":
2069
- {
2070
- startDragging(resizeHandleId, event);
2071
- break;
2072
- }
2073
- case "up":
2074
- {
2075
- stopDragging();
2076
- break;
2077
- }
2078
- }
2079
- switch (state) {
2080
- case "drag":
2081
- {
2082
- resizeHandler(event);
2083
- break;
2084
- }
2059
+ const setResizeHandlerState = (action, isActive, event) => {
2060
+ if (isActive) {
2061
+ switch (action) {
2062
+ case "down":
2063
+ {
2064
+ setState("drag");
2065
+ startDragging(resizeHandleId, event);
2066
+ const {
2067
+ onDragging
2068
+ } = callbacksRef.current;
2069
+ if (onDragging) {
2070
+ onDragging(true);
2071
+ }
2072
+ break;
2073
+ }
2074
+ case "move":
2075
+ {
2076
+ const {
2077
+ state
2078
+ } = committedValuesRef.current;
2079
+ if (state !== "drag") {
2080
+ setState("hover");
2081
+ }
2082
+ resizeHandler(event);
2083
+ break;
2084
+ }
2085
+ case "up":
2086
+ {
2087
+ setState("hover");
2088
+ stopDragging();
2089
+ const {
2090
+ onDragging
2091
+ } = callbacksRef.current;
2092
+ if (onDragging) {
2093
+ onDragging(false);
2094
+ }
2095
+ break;
2096
+ }
2097
+ }
2098
+ } else {
2099
+ setState("inactive");
2085
2100
  }
2086
2101
  };
2087
2102
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -358,24 +358,19 @@ function handlePointerMove(event) {
358
358
  x,
359
359
  y
360
360
  } = getResizeEventCoordinates(event);
361
- if (isPointerDown) {
362
- intersectingHandles.forEach(data => {
363
- const {
364
- setResizeHandlerState
365
- } = data;
366
- setResizeHandlerState("move", "drag", event);
367
- });
368
-
369
- // Update cursor based on return value(s) from active handles
370
- updateCursor();
371
- } else {
361
+ if (!isPointerDown) {
362
+ // Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
363
+ // at that point, the handles may not move with the pointer (depending on constraints)
364
+ // but the same set of active handles should be locked until the pointer is released
372
365
  recalculateIntersectingHandles({
373
366
  x,
374
367
  y
375
368
  });
376
- updateResizeHandlerStates("move", event);
377
- updateCursor();
378
369
  }
370
+ updateResizeHandlerStates("move", event);
371
+
372
+ // Update cursor based on return value(s) from active handles
373
+ updateCursor();
379
374
  if (intersectingHandles.length > 0) {
380
375
  event.preventDefault();
381
376
  }
@@ -508,15 +503,8 @@ function updateResizeHandlerStates(action, event) {
508
503
  const {
509
504
  setResizeHandlerState
510
505
  } = data;
511
- if (intersectingHandles.includes(data)) {
512
- if (isPointerDown) {
513
- setResizeHandlerState(action, "drag", event);
514
- } else {
515
- setResizeHandlerState(action, "hover", event);
516
- }
517
- } else {
518
- setResizeHandlerState(action, "inactive", event);
519
- }
506
+ const isActive = intersectingHandles.includes(data);
507
+ setResizeHandlerState(action, isActive, event);
520
508
  });
521
509
  }
522
510
 
@@ -2153,6 +2141,12 @@ function PanelResizeHandle({
2153
2141
  const [state, setState] = useState("inactive");
2154
2142
  const [isFocused, setIsFocused] = useState(false);
2155
2143
  const [resizeHandler, setResizeHandler] = useState(null);
2144
+ const committedValuesRef = useRef({
2145
+ state
2146
+ });
2147
+ useLayoutEffect(() => {
2148
+ committedValuesRef.current.state = state;
2149
+ });
2156
2150
  useEffect(() => {
2157
2151
  if (disabled) {
2158
2152
  setResizeHandler(null);
@@ -2168,26 +2162,47 @@ function PanelResizeHandle({
2168
2162
  }
2169
2163
  const element = elementRef.current;
2170
2164
  assert(element);
2171
- const setResizeHandlerState = (action, state, event) => {
2172
- setState(state);
2173
- switch (action) {
2174
- case "down":
2175
- {
2176
- startDragging(resizeHandleId, event);
2177
- break;
2178
- }
2179
- case "up":
2180
- {
2181
- stopDragging();
2182
- break;
2183
- }
2184
- }
2185
- switch (state) {
2186
- case "drag":
2187
- {
2188
- resizeHandler(event);
2189
- break;
2190
- }
2165
+ const setResizeHandlerState = (action, isActive, event) => {
2166
+ if (isActive) {
2167
+ switch (action) {
2168
+ case "down":
2169
+ {
2170
+ setState("drag");
2171
+ startDragging(resizeHandleId, event);
2172
+ const {
2173
+ onDragging
2174
+ } = callbacksRef.current;
2175
+ if (onDragging) {
2176
+ onDragging(true);
2177
+ }
2178
+ break;
2179
+ }
2180
+ case "move":
2181
+ {
2182
+ const {
2183
+ state
2184
+ } = committedValuesRef.current;
2185
+ if (state !== "drag") {
2186
+ setState("hover");
2187
+ }
2188
+ resizeHandler(event);
2189
+ break;
2190
+ }
2191
+ case "up":
2192
+ {
2193
+ setState("hover");
2194
+ stopDragging();
2195
+ const {
2196
+ onDragging
2197
+ } = callbacksRef.current;
2198
+ if (onDragging) {
2199
+ onDragging(false);
2200
+ }
2201
+ break;
2202
+ }
2203
+ }
2204
+ } else {
2205
+ setState("inactive");
2191
2206
  }
2192
2207
  };
2193
2208
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -334,24 +334,19 @@ function handlePointerMove(event) {
334
334
  x,
335
335
  y
336
336
  } = getResizeEventCoordinates(event);
337
- if (isPointerDown) {
338
- intersectingHandles.forEach(data => {
339
- const {
340
- setResizeHandlerState
341
- } = data;
342
- setResizeHandlerState("move", "drag", event);
343
- });
344
-
345
- // Update cursor based on return value(s) from active handles
346
- updateCursor();
347
- } else {
337
+ if (!isPointerDown) {
338
+ // Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
339
+ // at that point, the handles may not move with the pointer (depending on constraints)
340
+ // but the same set of active handles should be locked until the pointer is released
348
341
  recalculateIntersectingHandles({
349
342
  x,
350
343
  y
351
344
  });
352
- updateResizeHandlerStates("move", event);
353
- updateCursor();
354
345
  }
346
+ updateResizeHandlerStates("move", event);
347
+
348
+ // Update cursor based on return value(s) from active handles
349
+ updateCursor();
355
350
  if (intersectingHandles.length > 0) {
356
351
  event.preventDefault();
357
352
  }
@@ -484,15 +479,8 @@ function updateResizeHandlerStates(action, event) {
484
479
  const {
485
480
  setResizeHandlerState
486
481
  } = data;
487
- if (intersectingHandles.includes(data)) {
488
- if (isPointerDown) {
489
- setResizeHandlerState(action, "drag", event);
490
- } else {
491
- setResizeHandlerState(action, "hover", event);
492
- }
493
- } else {
494
- setResizeHandlerState(action, "inactive", event);
495
- }
482
+ const isActive = intersectingHandles.includes(data);
483
+ setResizeHandlerState(action, isActive, event);
496
484
  });
497
485
  }
498
486
 
@@ -2129,6 +2117,12 @@ function PanelResizeHandle({
2129
2117
  const [state, setState] = useState("inactive");
2130
2118
  const [isFocused, setIsFocused] = useState(false);
2131
2119
  const [resizeHandler, setResizeHandler] = useState(null);
2120
+ const committedValuesRef = useRef({
2121
+ state
2122
+ });
2123
+ useLayoutEffect(() => {
2124
+ committedValuesRef.current.state = state;
2125
+ });
2132
2126
  useEffect(() => {
2133
2127
  if (disabled) {
2134
2128
  setResizeHandler(null);
@@ -2144,26 +2138,47 @@ function PanelResizeHandle({
2144
2138
  }
2145
2139
  const element = elementRef.current;
2146
2140
  assert(element);
2147
- const setResizeHandlerState = (action, state, event) => {
2148
- setState(state);
2149
- switch (action) {
2150
- case "down":
2151
- {
2152
- startDragging(resizeHandleId, event);
2153
- break;
2154
- }
2155
- case "up":
2156
- {
2157
- stopDragging();
2158
- break;
2159
- }
2160
- }
2161
- switch (state) {
2162
- case "drag":
2163
- {
2164
- resizeHandler(event);
2165
- break;
2166
- }
2141
+ const setResizeHandlerState = (action, isActive, event) => {
2142
+ if (isActive) {
2143
+ switch (action) {
2144
+ case "down":
2145
+ {
2146
+ setState("drag");
2147
+ startDragging(resizeHandleId, event);
2148
+ const {
2149
+ onDragging
2150
+ } = callbacksRef.current;
2151
+ if (onDragging) {
2152
+ onDragging(true);
2153
+ }
2154
+ break;
2155
+ }
2156
+ case "move":
2157
+ {
2158
+ const {
2159
+ state
2160
+ } = committedValuesRef.current;
2161
+ if (state !== "drag") {
2162
+ setState("hover");
2163
+ }
2164
+ resizeHandler(event);
2165
+ break;
2166
+ }
2167
+ case "up":
2168
+ {
2169
+ setState("hover");
2170
+ stopDragging();
2171
+ const {
2172
+ onDragging
2173
+ } = callbacksRef.current;
2174
+ if (onDragging) {
2175
+ onDragging(false);
2176
+ }
2177
+ break;
2178
+ }
2179
+ }
2180
+ } else {
2181
+ setState("inactive");
2167
2182
  }
2168
2183
  };
2169
2184
  return registerResizeHandle(resizeHandleId, element, direction, {
@@ -328,24 +328,19 @@ function handlePointerMove(event) {
328
328
  x,
329
329
  y
330
330
  } = getResizeEventCoordinates(event);
331
- if (isPointerDown) {
332
- intersectingHandles.forEach(data => {
333
- const {
334
- setResizeHandlerState
335
- } = data;
336
- setResizeHandlerState("move", "drag", event);
337
- });
338
-
339
- // Update cursor based on return value(s) from active handles
340
- updateCursor();
341
- } else {
331
+ if (!isPointerDown) {
332
+ // Recalculate intersecting handles whenever the pointer moves, except if it has already been pressed
333
+ // at that point, the handles may not move with the pointer (depending on constraints)
334
+ // but the same set of active handles should be locked until the pointer is released
342
335
  recalculateIntersectingHandles({
343
336
  x,
344
337
  y
345
338
  });
346
- updateResizeHandlerStates("move", event);
347
- updateCursor();
348
339
  }
340
+ updateResizeHandlerStates("move", event);
341
+
342
+ // Update cursor based on return value(s) from active handles
343
+ updateCursor();
349
344
  if (intersectingHandles.length > 0) {
350
345
  event.preventDefault();
351
346
  }
@@ -478,15 +473,8 @@ function updateResizeHandlerStates(action, event) {
478
473
  const {
479
474
  setResizeHandlerState
480
475
  } = data;
481
- if (intersectingHandles.includes(data)) {
482
- if (isPointerDown) {
483
- setResizeHandlerState(action, "drag", event);
484
- } else {
485
- setResizeHandlerState(action, "hover", event);
486
- }
487
- } else {
488
- setResizeHandlerState(action, "inactive", event);
489
- }
476
+ const isActive = intersectingHandles.includes(data);
477
+ setResizeHandlerState(action, isActive, event);
490
478
  });
491
479
  }
492
480
 
@@ -2023,6 +2011,12 @@ function PanelResizeHandle({
2023
2011
  const [state, setState] = useState("inactive");
2024
2012
  const [isFocused, setIsFocused] = useState(false);
2025
2013
  const [resizeHandler, setResizeHandler] = useState(null);
2014
+ const committedValuesRef = useRef({
2015
+ state
2016
+ });
2017
+ useLayoutEffect(() => {
2018
+ committedValuesRef.current.state = state;
2019
+ });
2026
2020
  useEffect(() => {
2027
2021
  if (disabled) {
2028
2022
  setResizeHandler(null);
@@ -2038,26 +2032,47 @@ function PanelResizeHandle({
2038
2032
  }
2039
2033
  const element = elementRef.current;
2040
2034
  assert(element);
2041
- const setResizeHandlerState = (action, state, event) => {
2042
- setState(state);
2043
- switch (action) {
2044
- case "down":
2045
- {
2046
- startDragging(resizeHandleId, event);
2047
- break;
2048
- }
2049
- case "up":
2050
- {
2051
- stopDragging();
2052
- break;
2053
- }
2054
- }
2055
- switch (state) {
2056
- case "drag":
2057
- {
2058
- resizeHandler(event);
2059
- break;
2060
- }
2035
+ const setResizeHandlerState = (action, isActive, event) => {
2036
+ if (isActive) {
2037
+ switch (action) {
2038
+ case "down":
2039
+ {
2040
+ setState("drag");
2041
+ startDragging(resizeHandleId, event);
2042
+ const {
2043
+ onDragging
2044
+ } = callbacksRef.current;
2045
+ if (onDragging) {
2046
+ onDragging(true);
2047
+ }
2048
+ break;
2049
+ }
2050
+ case "move":
2051
+ {
2052
+ const {
2053
+ state
2054
+ } = committedValuesRef.current;
2055
+ if (state !== "drag") {
2056
+ setState("hover");
2057
+ }
2058
+ resizeHandler(event);
2059
+ break;
2060
+ }
2061
+ case "up":
2062
+ {
2063
+ setState("hover");
2064
+ stopDragging();
2065
+ const {
2066
+ onDragging
2067
+ } = callbacksRef.current;
2068
+ if (onDragging) {
2069
+ onDragging(false);
2070
+ }
2071
+ break;
2072
+ }
2073
+ }
2074
+ } else {
2075
+ setState("inactive");
2061
2076
  }
2062
2077
  };
2063
2078
  return registerResizeHandle(resizeHandleId, element, direction, {