Skip to content

Commit e3c4412

Browse files
committed
Removed duplicate code in touch/mouse resizing
1 parent 32b940d commit e3c4412

File tree

2 files changed

+68
-88
lines changed

2 files changed

+68
-88
lines changed

react-spaces/src/Globals/Resizing.ts

Lines changed: 66 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,53 @@ import { ResizeType, AllProps, AnchorToResizeTypeMap, ISpace } from "./Types";
22
import { isHorizontalSpace } from "./Utils";
33
import { ISpaceContext, updateSpace } from "./ISpaceContext";
44
import { throttle } from "./Throttle";
5+
import { SyntheticEvent } from "react";
56

67
const RESIZE_THROTTLE = 5;
78

8-
const onResizeEnd = (props: AllProps, resizeType: ResizeType, element: HTMLElement) => {
9+
enum MoveEvent {
10+
Mouse = "mousemove",
11+
Touch = "touchmove",
12+
}
13+
14+
enum EndEvent {
15+
Mouse = "mouseup",
16+
Touch = "touchend",
17+
}
18+
19+
export function startTouchResize(
20+
e: React.TouchEvent<HTMLElement>,
21+
parentContext: ISpaceContext | undefined,
22+
space: ISpace,
23+
props: AllProps,
24+
element: HTMLElement | undefined,
25+
) {
26+
return startResize(e, parentContext, space, props, element, EndEvent.Touch, MoveEvent.Touch, (e) => ({
27+
x: e.touches[0].pageX,
28+
y: e.touches[0].pageY,
29+
}));
30+
}
31+
32+
export function startMouseResize(
33+
e: React.MouseEvent<HTMLElement>,
34+
parentContext: ISpaceContext | undefined,
35+
space: ISpace,
36+
props: AllProps,
37+
element: HTMLElement | undefined,
38+
) {
39+
return startResize(e, parentContext, space, props, element, EndEvent.Mouse, MoveEvent.Mouse, (e) => ({
40+
x: e.pageX,
41+
y: e.pageY,
42+
}));
43+
}
44+
45+
function onResizeEnd(props: AllProps, resizeType: ResizeType, element: HTMLElement) {
946
const currentRect = element.getBoundingClientRect();
1047
props.onResizeEnd &&
1148
props.onResizeEnd(Math.floor(resizeType === ResizeType.Left || resizeType === ResizeType.Right ? currentRect.width : currentRect.height));
12-
};
49+
}
1350

14-
const onResize = (
51+
function onResize(
1552
props: AllProps,
1653
parentContext: ISpaceContext,
1754
space: ISpace,
@@ -22,7 +59,7 @@ const onResize = (
2259
y: number,
2360
minimumAdjust: number,
2461
maximumAdjust: number | undefined,
25-
) => {
62+
) {
2663
const adjustmentX = Math.min(
2764
Math.max(resizeType === ResizeType.Left ? originalX - x : x - originalX, minimumAdjust),
2865
maximumAdjust === undefined ? 999999 : maximumAdjust,
@@ -37,15 +74,18 @@ const onResize = (
3774
if (adjustment !== space.adjustedSize) {
3875
updateSpace(parentContext, space.id, { adjustedSize: adjustment });
3976
}
40-
};
77+
}
4178

42-
export const startTouchResize = (
43-
e: React.TouchEvent<HTMLElement>,
79+
function startResize<T extends SyntheticEvent<HTMLElement> | MouseEvent | TouchEvent>(
80+
e: T,
4481
parentContext: ISpaceContext | undefined,
4582
space: ISpace,
4683
props: AllProps,
4784
element: HTMLElement | undefined,
48-
) => {
85+
endEvent: EndEvent,
86+
moveEvent: MoveEvent,
87+
getCoords: (event: T) => { x: number; y: number },
88+
) {
4989
if (element && props.resizable && props.anchor && parentContext) {
5090
const resizeType: ResizeType | undefined = AnchorToResizeTypeMap[props.anchor];
5191

@@ -62,105 +102,45 @@ export const startTouchResize = (
62102

63103
var rect = element.getBoundingClientRect();
64104
var size = isHorizontalSpace(props.anchor) ? rect.width : rect.height;
65-
66-
const originalTouchX = resizeType === ResizeType.Left ? e.touches[0].pageX + space.adjustedSize : e.touches[0].pageX - space.adjustedSize;
67-
const originalTouchY = resizeType === ResizeType.Top ? e.touches[0].pageY + space.adjustedSize : e.touches[0].pageY - space.adjustedSize;
105+
const coords = getCoords(e);
106+
const originalMouseX = resizeType === ResizeType.Left ? coords.x + space.adjustedSize : coords.x - space.adjustedSize;
107+
const originalMouseY = resizeType === ResizeType.Top ? coords.y + space.adjustedSize : coords.y - space.adjustedSize;
68108
const minimumAdjust = (props.minimumSize === undefined ? 20 : props.minimumSize) - size + space.adjustedSize;
69109
const maximumAdjust = props.maximumSize ? props.maximumSize - size + space.adjustedSize : undefined;
70110
let lastX = 0;
71111
let lastY = 0;
72112
let moved = false;
73113

74-
const touchResize = (x: number, y: number) =>
75-
onResize(props, parentContext, space, resizeType, originalTouchX, originalTouchY, x, y, minimumAdjust, maximumAdjust);
76-
const throttledTouchResize = throttle<typeof touchResize>(touchResize, RESIZE_THROTTLE);
77-
const withPreventDefault = (e: TouchEvent) => {
114+
const resize = (x: number, y: number) =>
115+
onResize(props, parentContext, space, resizeType, originalMouseX, originalMouseY, x, y, minimumAdjust, maximumAdjust);
116+
117+
const withPreventDefault = (e: T) => {
78118
moved = true;
79-
lastX = e.touches[0].pageX;
80-
lastY = e.touches[0].pageY;
119+
const newCoords = getCoords(e);
120+
lastX = newCoords.x;
121+
lastY = newCoords.y;
81122
e.preventDefault();
82-
e.stopImmediatePropagation();
83-
throttledTouchResize(lastX, lastY);
84-
};
85-
const removeListener = () => {
86-
if (moved) {
87-
touchResize(lastX, lastY);
88-
}
89-
window.removeEventListener("touchmove", withPreventDefault);
90-
window.removeEventListener("touchend", removeListener);
91-
92-
if (parentContext) {
93-
parentContext.updateResizing(false);
94-
}
95123

96-
onResizeEnd(props, resizeType, element);
124+
throttle(resize, RESIZE_THROTTLE)(lastX, lastY);
97125
};
98-
window.addEventListener("touchmove", withPreventDefault);
99-
window.addEventListener("touchend", removeListener);
100-
e.preventDefault();
101-
e.stopPropagation();
102-
}
103-
};
104126

105-
export const startResize = (
106-
e: React.MouseEvent<HTMLElement>,
107-
parentContext: ISpaceContext | undefined,
108-
space: ISpace,
109-
props: AllProps,
110-
element: HTMLElement | undefined,
111-
) => {
112-
if (element && props.resizable && props.anchor && parentContext) {
113-
const resizeType: ResizeType | undefined = AnchorToResizeTypeMap[props.anchor];
114-
115-
if (props.onResizeStart) {
116-
const result = props.onResizeStart();
117-
if (typeof result === "boolean" && !result) {
118-
return;
119-
}
120-
}
121-
122-
if (parentContext) {
123-
parentContext.updateResizing(true);
124-
}
125-
126-
var rect = element.getBoundingClientRect();
127-
var size = isHorizontalSpace(props.anchor) ? rect.width : rect.height;
128-
129-
const originalMouseX = resizeType === ResizeType.Left ? e.pageX + space.adjustedSize : e.pageX - space.adjustedSize;
130-
const originalMouseY = resizeType === ResizeType.Top ? e.pageY + space.adjustedSize : e.pageY - space.adjustedSize;
131-
const minimumAdjust = (props.minimumSize === undefined ? 20 : props.minimumSize) - size + space.adjustedSize;
132-
const maximumAdjust = props.maximumSize ? props.maximumSize - size + space.adjustedSize : undefined;
133-
let lastX = 0;
134-
let lastY = 0;
135-
let moved = false;
136-
137-
const mouseResize = (x: number, y: number) =>
138-
onResize(props, parentContext, space, resizeType, originalMouseX, originalMouseY, x, y, minimumAdjust, maximumAdjust);
139-
const throttledMouseResize = throttle<typeof mouseResize>(mouseResize, RESIZE_THROTTLE);
140-
const withPreventDefault = (e: MouseEvent) => {
141-
moved = true;
142-
lastX = e.pageX;
143-
lastY = e.pageY;
144-
e.preventDefault();
145-
e.stopImmediatePropagation();
146-
throttledMouseResize(lastX, lastY);
147-
};
148127
const removeListener = () => {
149128
if (moved) {
150-
mouseResize(lastX, lastY);
129+
resize(lastX, lastY);
151130
}
152-
window.removeEventListener("mousemove", withPreventDefault);
153-
window.removeEventListener("mouseup", removeListener);
131+
window.removeEventListener(moveEvent, withPreventDefault as EventListener);
132+
window.removeEventListener(endEvent, removeListener);
154133

155134
if (parentContext) {
156135
parentContext.updateResizing(false);
157136
}
158137

159138
onResizeEnd(props, resizeType, element);
160139
};
161-
window.addEventListener("mousemove", withPreventDefault);
162-
window.addEventListener("mouseup", removeListener);
140+
141+
window.addEventListener(moveEvent, withPreventDefault as EventListener);
142+
window.addEventListener(endEvent, removeListener);
163143
e.preventDefault();
164144
e.stopPropagation();
165145
}
166-
};
146+
}

react-spaces/src/ResizeHandle.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import * as React from "react";
22
import "./Styles.css";
33
import { ResizeType, ISpace, AnchorToResizeTypeMap, AnchorType } from "./Globals/Types";
4-
import { startResize, startTouchResize } from "./Globals/Resizing";
4+
import { startMouseResize, startTouchResize } from "./Globals/Resizing";
55
import { ISpaceContext } from "./Globals/ISpaceContext";
66

77
interface IProps {
@@ -23,7 +23,7 @@ export const ResizeHandle: React.FC<IProps> = (props) => {
2323
<div
2424
style={{ width: width, height: height }}
2525
className={`spaces-resize-handle ${AnchorToResizeTypeMap[props.anchor]}`}
26-
onMouseDown={(e) => startResize(e, props.parentContext, props.space, props, props.spaceElement)}
26+
onMouseDown={(e) => startMouseResize(e, props.parentContext, props.space, props, props.spaceElement)}
2727
onTouchStart={(e) => startTouchResize(e, props.parentContext, props.space, props, props.spaceElement)}
2828
/>
2929
);

0 commit comments

Comments
 (0)