react-resizable-panels 0.0.9 → 0.0.11

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.
@@ -1,4 +1,11 @@
1
- import { ReactNode, useContext, useEffect, useState } from "react";
1
+ import {
2
+ ReactNode,
3
+ useCallback,
4
+ useContext,
5
+ useEffect,
6
+ useRef,
7
+ useState,
8
+ } from "react";
2
9
 
3
10
  import useUniqueId from "./hooks/useUniqueId";
4
11
  import { useWindowSplitterResizeHandlerBehavior } from "./hooks/useWindowSplitterBehavior";
@@ -16,6 +23,8 @@ export default function PanelResizeHandle({
16
23
  disabled?: boolean;
17
24
  id?: string | null;
18
25
  }) {
26
+ const divElementRef = useRef<HTMLDivElement>(null);
27
+
19
28
  const panelContext = useContext(PanelContext);
20
29
  const panelGroupContext = useContext(PanelGroupContext);
21
30
  if (panelContext === null || panelGroupContext === null) {
@@ -41,6 +50,15 @@ export default function PanelResizeHandle({
41
50
  null
42
51
  );
43
52
 
53
+ const stopDraggingAndBlur = useCallback(() => {
54
+ // Clicking on the drag handle shouldn't leave it focused;
55
+ // That would cause the PanelGroup to think it was still active.
56
+ const div = divElementRef.current!;
57
+ div.blur();
58
+
59
+ stopDragging();
60
+ }, [stopDragging]);
61
+
44
62
  useEffect(() => {
45
63
  if (disabled) {
46
64
  setResizeHandler(null);
@@ -62,20 +80,20 @@ export default function PanelResizeHandle({
62
80
  resizeHandler(event);
63
81
  };
64
82
 
65
- document.body.addEventListener("mouseleave", stopDragging);
83
+ document.body.addEventListener("mouseleave", stopDraggingAndBlur);
66
84
  document.body.addEventListener("mousemove", onMove);
67
85
  document.body.addEventListener("touchmove", onMove);
68
- document.body.addEventListener("mouseup", stopDragging);
86
+ document.body.addEventListener("mouseup", stopDraggingAndBlur);
69
87
 
70
88
  return () => {
71
89
  document.body.style.cursor = "";
72
90
 
73
- document.body.removeEventListener("mouseleave", stopDragging);
91
+ document.body.removeEventListener("mouseleave", stopDraggingAndBlur);
74
92
  document.body.removeEventListener("mousemove", onMove);
75
93
  document.body.removeEventListener("touchmove", onMove);
76
- document.body.removeEventListener("mouseup", stopDragging);
94
+ document.body.removeEventListener("mouseup", stopDraggingAndBlur);
77
95
  };
78
- }, [direction, disabled, isDragging, resizeHandler, stopDragging]);
96
+ }, [direction, disabled, isDragging, resizeHandler, stopDraggingAndBlur]);
79
97
 
80
98
  useWindowSplitterResizeHandlerBehavior({
81
99
  disabled,
@@ -90,10 +108,11 @@ export default function PanelResizeHandle({
90
108
  data-panel-resize-handle-enabled={!disabled}
91
109
  data-panel-resize-handle-id={id}
92
110
  onMouseDown={() => startDragging(id)}
93
- onMouseUp={stopDragging}
94
- onTouchCancel={stopDragging}
95
- onTouchEnd={stopDragging}
111
+ onMouseUp={stopDraggingAndBlur}
112
+ onTouchCancel={stopDraggingAndBlur}
113
+ onTouchEnd={stopDraggingAndBlur}
96
114
  onTouchStart={() => startDragging(id)}
115
+ ref={divElementRef}
97
116
  role="separator"
98
117
  style={{
99
118
  cursor: direction === "horizontal" ? "ew-resize" : "ns-resize",
@@ -1,107 +1,69 @@
1
1
  import { Direction, ResizeEvent } from "../types";
2
+ import { getResizeHandle } from "./group";
2
3
 
3
4
  export type Coordinates = {
4
- screenX: number;
5
- screenY: number;
5
+ movement: number;
6
+ offset: number;
6
7
  };
7
8
 
8
- export type Dimensions = {
9
+ export type Size = {
9
10
  height: number;
10
11
  width: number;
11
12
  };
12
13
 
13
- export type Movement = {
14
- movementX: number;
15
- movementY: number;
16
- };
17
-
18
14
  const element = document.createElement("div");
19
15
  element.getBoundingClientRect();
20
16
 
21
17
  // https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent/movementX
22
- export function getUpdatedCoordinates(
18
+ export function getMovement(
23
19
  event: ResizeEvent,
24
- prevCoordinates: Coordinates,
25
- dimensions: Dimensions,
20
+ handleId: string,
21
+ { height, width }: Size,
26
22
  direction: Direction
27
- ): Coordinates & Movement {
28
- const { screenX: prevScreenX, screenY: prevScreenY } = prevCoordinates;
29
- const { height, width } = dimensions;
30
-
31
- const getMovementBetween = (current: number, prev: number) =>
32
- prev === 0 ? 0 : current - prev;
23
+ ): number {
24
+ const isHorizontal = direction === "horizontal";
25
+ const size = isHorizontal ? width : height;
33
26
 
34
27
  if (isKeyDown(event)) {
35
- let movementX = 0;
36
- let movementY = 0;
37
-
38
- const size = direction === "horizontal" ? width : height;
39
28
  const denominator = event.shiftKey ? 10 : 100;
40
29
  const delta = size / denominator;
41
30
 
42
31
  switch (event.key) {
43
32
  case "ArrowDown":
44
- movementY = delta;
45
- break;
33
+ return delta;
46
34
  case "ArrowLeft":
47
- movementX = -delta;
48
- break;
35
+ return -delta;
49
36
  case "ArrowRight":
50
- movementX = delta;
51
- break;
37
+ return delta;
52
38
  case "ArrowUp":
53
- movementY = -delta;
54
- break;
39
+ return -delta;
55
40
  case "End":
56
- if (direction === "horizontal") {
57
- movementX = size;
41
+ if (isHorizontal) {
42
+ return size;
58
43
  } else {
59
- movementY = size;
44
+ return size;
60
45
  }
61
- break;
62
46
  case "Home":
63
- if (direction === "horizontal") {
64
- movementX = -size;
47
+ if (isHorizontal) {
48
+ return -size;
65
49
  } else {
66
- movementY = -size;
50
+ return -size;
67
51
  }
68
- break;
69
52
  }
53
+ } else {
54
+ const handleElement = getResizeHandle(handleId)!;
55
+ const rect = handleElement.getBoundingClientRect();
56
+ const elementOffset = isHorizontal ? rect.left : rect.top;
70
57
 
71
- // Estimate screen X/Y to be the center of the resize handle.
72
- // Otherwise the first mouse/touch event after a keyboard event will appear to "jump"
73
- let screenX = 0;
74
- let screenY = 0;
75
- if (document.activeElement) {
76
- const rect = document.activeElement.getBoundingClientRect();
77
- screenX = rect.left + rect.width / 2;
78
- screenY = rect.top + rect.height / 2;
58
+ let pointerOffset = 0;
59
+ if (isMouseMoveEvent(event)) {
60
+ pointerOffset = isHorizontal ? event.clientX : event.clientY;
61
+ } else {
62
+ const firstTouch = event.touches[0];
63
+ pointerOffset = isHorizontal ? firstTouch.screenX : firstTouch.screenY;
79
64
  }
80
65
 
81
- return {
82
- movementX,
83
- movementY,
84
- screenX,
85
- screenY,
86
- };
87
- } else if (isTouchMoveEvent(event)) {
88
- const firstTouch = event.touches[0];
89
-
90
- return {
91
- movementX: getMovementBetween(firstTouch.screenX, prevScreenX),
92
- movementY: getMovementBetween(firstTouch.screenY, prevScreenY),
93
- screenX: firstTouch.screenX,
94
- screenY: firstTouch.screenY,
95
- };
96
- } else if (isMouseMoveEvent(event)) {
97
- return {
98
- movementX: getMovementBetween(event.screenX, prevScreenX),
99
- movementY: getMovementBetween(event.screenY, prevScreenY),
100
- screenX: event.screenX,
101
- screenY: event.screenY,
102
- };
103
- } else {
104
- throw Error(`Unsupported event type: "${(event as any).type}"`);
66
+ return pointerOffset - elementOffset;
105
67
  }
106
68
  }
107
69