@react-aria/interactions 3.25.6 → 3.27.0
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/dist/PressResponder.main.js +2 -3
- package/dist/PressResponder.main.js.map +1 -1
- package/dist/PressResponder.mjs +3 -4
- package/dist/PressResponder.module.js +3 -4
- package/dist/PressResponder.module.js.map +1 -1
- package/dist/focusSafely.main.js +4 -4
- package/dist/focusSafely.main.js.map +1 -1
- package/dist/focusSafely.mjs +4 -4
- package/dist/focusSafely.module.js +4 -4
- package/dist/focusSafely.module.js.map +1 -1
- package/dist/import.mjs +2 -2
- package/dist/main.js +1 -0
- package/dist/main.js.map +1 -1
- package/dist/module.js +2 -2
- package/dist/module.js.map +1 -1
- package/dist/types.d.ts +4 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/useFocusVisible.main.js +19 -8
- package/dist/useFocusVisible.main.js.map +1 -1
- package/dist/useFocusVisible.mjs +20 -10
- package/dist/useFocusVisible.module.js +20 -10
- package/dist/useFocusVisible.module.js.map +1 -1
- package/dist/useFocusWithin.main.js +3 -3
- package/dist/useFocusWithin.main.js.map +1 -1
- package/dist/useFocusWithin.mjs +4 -4
- package/dist/useFocusWithin.module.js +4 -4
- package/dist/useFocusWithin.module.js.map +1 -1
- package/dist/useHover.main.js +3 -3
- package/dist/useHover.main.js.map +1 -1
- package/dist/useHover.mjs +4 -4
- package/dist/useHover.module.js +4 -4
- package/dist/useHover.module.js.map +1 -1
- package/dist/useInteractOutside.main.js +2 -4
- package/dist/useInteractOutside.main.js.map +1 -1
- package/dist/useInteractOutside.mjs +3 -5
- package/dist/useInteractOutside.module.js +3 -5
- package/dist/useInteractOutside.module.js.map +1 -1
- package/dist/useMove.main.js +110 -74
- package/dist/useMove.main.js.map +1 -1
- package/dist/useMove.mjs +112 -76
- package/dist/useMove.module.js +112 -76
- package/dist/useMove.module.js.map +1 -1
- package/dist/usePress.main.js +197 -117
- package/dist/usePress.main.js.map +1 -1
- package/dist/usePress.mjs +199 -119
- package/dist/usePress.module.js +199 -119
- package/dist/usePress.module.js.map +1 -1
- package/dist/utils.main.js +2 -5
- package/dist/utils.main.js.map +1 -1
- package/dist/utils.mjs +3 -6
- package/dist/utils.module.js +3 -6
- package/dist/utils.module.js.map +1 -1
- package/package.json +4 -4
- package/src/PressResponder.tsx +3 -4
- package/src/focusSafely.ts +4 -4
- package/src/index.ts +1 -0
- package/src/useFocusVisible.ts +21 -5
- package/src/useFocusWithin.ts +3 -3
- package/src/useHover.ts +3 -3
- package/src/useInteractOutside.ts +3 -3
- package/src/useMove.ts +85 -57
- package/src/usePress.ts +199 -151
- package/src/utils.ts +3 -7
package/src/useFocusVisible.ts
CHANGED
|
@@ -15,8 +15,9 @@
|
|
|
15
15
|
// NOTICE file in the root directory of this source tree.
|
|
16
16
|
// See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions
|
|
17
17
|
|
|
18
|
-
import {getOwnerDocument, getOwnerWindow, isMac, isVirtualClick} from '@react-aria/utils';
|
|
18
|
+
import {getOwnerDocument, getOwnerWindow, isMac, isVirtualClick, openLink} from '@react-aria/utils';
|
|
19
19
|
import {ignoreFocusEvent} from './utils';
|
|
20
|
+
import {PointerType} from '@react-types/shared';
|
|
20
21
|
import {useEffect, useState} from 'react';
|
|
21
22
|
import {useIsSSR} from '@react-aria/ssr';
|
|
22
23
|
|
|
@@ -37,7 +38,8 @@ export interface FocusVisibleResult {
|
|
|
37
38
|
}
|
|
38
39
|
|
|
39
40
|
let currentModality: null | Modality = null;
|
|
40
|
-
let
|
|
41
|
+
let currentPointerType: PointerType = 'keyboard';
|
|
42
|
+
export const changeHandlers = new Set<Handler>();
|
|
41
43
|
interface GlobalListenerData {
|
|
42
44
|
focus: () => void
|
|
43
45
|
}
|
|
@@ -68,14 +70,16 @@ function isValidKey(e: KeyboardEvent) {
|
|
|
68
70
|
|
|
69
71
|
function handleKeyboardEvent(e: KeyboardEvent) {
|
|
70
72
|
hasEventBeforeFocus = true;
|
|
71
|
-
if (isValidKey(e)) {
|
|
73
|
+
if (!(openLink as any).isOpening && isValidKey(e)) {
|
|
72
74
|
currentModality = 'keyboard';
|
|
75
|
+
currentPointerType = 'keyboard';
|
|
73
76
|
triggerChangeHandlers('keyboard', e);
|
|
74
77
|
}
|
|
75
78
|
}
|
|
76
79
|
|
|
77
80
|
function handlePointerEvent(e: PointerEvent | MouseEvent) {
|
|
78
81
|
currentModality = 'pointer';
|
|
82
|
+
currentPointerType = 'pointerType' in e ? e.pointerType as PointerType : 'mouse';
|
|
79
83
|
if (e.type === 'mousedown' || e.type === 'pointerdown') {
|
|
80
84
|
hasEventBeforeFocus = true;
|
|
81
85
|
triggerChangeHandlers('pointer', e);
|
|
@@ -83,9 +87,10 @@ function handlePointerEvent(e: PointerEvent | MouseEvent) {
|
|
|
83
87
|
}
|
|
84
88
|
|
|
85
89
|
function handleClickEvent(e: MouseEvent) {
|
|
86
|
-
if (isVirtualClick(e)) {
|
|
90
|
+
if (!(openLink as any).isOpening && isVirtualClick(e)) {
|
|
87
91
|
hasEventBeforeFocus = true;
|
|
88
92
|
currentModality = 'virtual';
|
|
93
|
+
currentPointerType = 'virtual';
|
|
89
94
|
}
|
|
90
95
|
}
|
|
91
96
|
|
|
@@ -101,6 +106,7 @@ function handleFocusEvent(e: FocusEvent) {
|
|
|
101
106
|
// This occurs, for example, when navigating a form with the next/previous buttons on iOS.
|
|
102
107
|
if (!hasEventBeforeFocus && !hasBlurredWindowRecently) {
|
|
103
108
|
currentModality = 'virtual';
|
|
109
|
+
currentPointerType = 'virtual';
|
|
104
110
|
triggerChangeHandlers('virtual', e);
|
|
105
111
|
}
|
|
106
112
|
|
|
@@ -249,9 +255,15 @@ export function getInteractionModality(): Modality | null {
|
|
|
249
255
|
|
|
250
256
|
export function setInteractionModality(modality: Modality): void {
|
|
251
257
|
currentModality = modality;
|
|
258
|
+
currentPointerType = modality === 'pointer' ? 'mouse' : modality;
|
|
252
259
|
triggerChangeHandlers(modality, null);
|
|
253
260
|
}
|
|
254
261
|
|
|
262
|
+
/** @private */
|
|
263
|
+
export function getPointerType(): PointerType {
|
|
264
|
+
return currentPointerType;
|
|
265
|
+
}
|
|
266
|
+
|
|
255
267
|
/**
|
|
256
268
|
* Keeps state of the current modality.
|
|
257
269
|
*/
|
|
@@ -321,10 +333,13 @@ export function useFocusVisible(props: FocusVisibleProps = {}): FocusVisibleResu
|
|
|
321
333
|
/**
|
|
322
334
|
* Listens for trigger change and reports if focus is visible (i.e., modality is not pointer).
|
|
323
335
|
*/
|
|
324
|
-
export function useFocusVisibleListener(fn: FocusVisibleHandler, deps: ReadonlyArray<any>, opts?: {isTextInput?: boolean}): void {
|
|
336
|
+
export function useFocusVisibleListener(fn: FocusVisibleHandler, deps: ReadonlyArray<any>, opts?: {enabled?: boolean, isTextInput?: boolean}): void {
|
|
325
337
|
setupGlobalFocusEvents();
|
|
326
338
|
|
|
327
339
|
useEffect(() => {
|
|
340
|
+
if (opts?.enabled === false) {
|
|
341
|
+
return;
|
|
342
|
+
}
|
|
328
343
|
let handler = (modality: Modality, e: HandlerEvent) => {
|
|
329
344
|
// We want to early return for any keyboard events that occur inside text inputs EXCEPT for Tab and Escape
|
|
330
345
|
if (!isKeyboardFocusEvent(!!(opts?.isTextInput), modality, e)) {
|
|
@@ -339,3 +354,4 @@ export function useFocusVisibleListener(fn: FocusVisibleHandler, deps: ReadonlyA
|
|
|
339
354
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
340
355
|
}, deps);
|
|
341
356
|
}
|
|
357
|
+
|
package/src/useFocusWithin.ts
CHANGED
|
@@ -54,14 +54,14 @@ export function useFocusWithin(props: FocusWithinProps): FocusWithinResult {
|
|
|
54
54
|
|
|
55
55
|
let onBlur = useCallback((e: FocusEvent) => {
|
|
56
56
|
// Ignore events bubbling through portals.
|
|
57
|
-
if (!e.currentTarget
|
|
57
|
+
if (!nodeContains(e.currentTarget, e.target)) {
|
|
58
58
|
return;
|
|
59
59
|
}
|
|
60
60
|
|
|
61
61
|
// We don't want to trigger onBlurWithin and then immediately onFocusWithin again
|
|
62
62
|
// when moving focus inside the element. Only trigger if the currentTarget doesn't
|
|
63
63
|
// include the relatedTarget (where focus is moving).
|
|
64
|
-
if (state.current.isFocusWithin && !(e.currentTarget as Element
|
|
64
|
+
if (state.current.isFocusWithin && !nodeContains(e.currentTarget as Element, e.relatedTarget as Element)) {
|
|
65
65
|
state.current.isFocusWithin = false;
|
|
66
66
|
removeAllGlobalListeners();
|
|
67
67
|
|
|
@@ -78,7 +78,7 @@ export function useFocusWithin(props: FocusWithinProps): FocusWithinResult {
|
|
|
78
78
|
let onSyntheticFocus = useSyntheticBlurEvent(onBlur);
|
|
79
79
|
let onFocus = useCallback((e: FocusEvent) => {
|
|
80
80
|
// Ignore events bubbling through portals.
|
|
81
|
-
if (!e.currentTarget
|
|
81
|
+
if (!nodeContains(e.currentTarget, e.target)) {
|
|
82
82
|
return;
|
|
83
83
|
}
|
|
84
84
|
|
package/src/useHover.ts
CHANGED
|
@@ -108,7 +108,7 @@ export function useHover(props: HoverProps): HoverResult {
|
|
|
108
108
|
let {hoverProps, triggerHoverEnd} = useMemo(() => {
|
|
109
109
|
let triggerHoverStart = (event, pointerType) => {
|
|
110
110
|
state.pointerType = pointerType;
|
|
111
|
-
if (isDisabled || pointerType === 'touch' || state.isHovered || !event.currentTarget
|
|
111
|
+
if (isDisabled || pointerType === 'touch' || state.isHovered || !nodeContains(event.currentTarget, event.target)) {
|
|
112
112
|
return;
|
|
113
113
|
}
|
|
114
114
|
|
|
@@ -180,7 +180,7 @@ export function useHover(props: HoverProps): HoverResult {
|
|
|
180
180
|
};
|
|
181
181
|
|
|
182
182
|
hoverProps.onPointerLeave = (e) => {
|
|
183
|
-
if (!isDisabled && e.currentTarget
|
|
183
|
+
if (!isDisabled && nodeContains(e.currentTarget, e.target as Element)) {
|
|
184
184
|
triggerHoverEnd(e, e.pointerType);
|
|
185
185
|
}
|
|
186
186
|
};
|
|
@@ -198,7 +198,7 @@ export function useHover(props: HoverProps): HoverResult {
|
|
|
198
198
|
};
|
|
199
199
|
|
|
200
200
|
hoverProps.onMouseLeave = (e) => {
|
|
201
|
-
if (!isDisabled && e.currentTarget
|
|
201
|
+
if (!isDisabled && nodeContains(e.currentTarget, e.target as Element)) {
|
|
202
202
|
triggerHoverEnd(e, 'mouse');
|
|
203
203
|
}
|
|
204
204
|
};
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
// NOTICE file in the root directory of this source tree.
|
|
16
16
|
// See https://github.com/facebook/react/tree/cc7c1aece46a6b69b41958d731e0fd27c94bfc6c/packages/react-interactions
|
|
17
17
|
|
|
18
|
-
import {getOwnerDocument, useEffectEvent} from '@react-aria/utils';
|
|
18
|
+
import {getOwnerDocument, nodeContains, useEffectEvent} from '@react-aria/utils';
|
|
19
19
|
import {RefObject} from '@react-types/shared';
|
|
20
20
|
import {useEffect, useRef} from 'react';
|
|
21
21
|
|
|
@@ -111,7 +111,7 @@ export function useInteractOutside(props: InteractOutsideProps): void {
|
|
|
111
111
|
documentObject.removeEventListener('touchend', onTouchEnd, true);
|
|
112
112
|
};
|
|
113
113
|
}
|
|
114
|
-
}, [ref, isDisabled
|
|
114
|
+
}, [ref, isDisabled]);
|
|
115
115
|
}
|
|
116
116
|
|
|
117
117
|
function isValidEvent(event, ref) {
|
|
@@ -121,7 +121,7 @@ function isValidEvent(event, ref) {
|
|
|
121
121
|
if (event.target) {
|
|
122
122
|
// if the event target is no longer in the document, ignore
|
|
123
123
|
const ownerDocument = event.target.ownerDocument;
|
|
124
|
-
if (!ownerDocument || !ownerDocument.documentElement
|
|
124
|
+
if (!ownerDocument || !nodeContains(ownerDocument.documentElement, event.target)) {
|
|
125
125
|
return false;
|
|
126
126
|
}
|
|
127
127
|
// If the target is within a top layer element (e.g. toasts), ignore.
|
package/src/useMove.ts
CHANGED
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
|
|
13
13
|
import {disableTextSelection, restoreTextSelection} from './textSelection';
|
|
14
14
|
import {DOMAttributes, MoveEvents, PointerType} from '@react-types/shared';
|
|
15
|
-
import React, {useMemo, useRef} from 'react';
|
|
16
|
-
import {useEffectEvent, useGlobalListeners} from '@react-aria/utils';
|
|
15
|
+
import React, {useCallback, useMemo, useRef, useState} from 'react';
|
|
16
|
+
import {useEffectEvent, useGlobalListeners, useLayoutEffect} from '@react-aria/utils';
|
|
17
17
|
|
|
18
18
|
export interface MoveResult {
|
|
19
19
|
/** Props to spread on the target element. */
|
|
@@ -43,7 +43,7 @@ export function useMove(props: MoveEvents): MoveResult {
|
|
|
43
43
|
|
|
44
44
|
let {addGlobalListener, removeGlobalListener} = useGlobalListeners();
|
|
45
45
|
|
|
46
|
-
let move =
|
|
46
|
+
let move = useCallback((originalEvent: EventBase, pointerType: PointerType, deltaX: number, deltaY: number) => {
|
|
47
47
|
if (deltaX === 0 && deltaY === 0) {
|
|
48
48
|
return;
|
|
49
49
|
}
|
|
@@ -69,9 +69,10 @@ export function useMove(props: MoveEvents): MoveResult {
|
|
|
69
69
|
ctrlKey: originalEvent.ctrlKey,
|
|
70
70
|
altKey: originalEvent.altKey
|
|
71
71
|
});
|
|
72
|
-
});
|
|
72
|
+
}, [onMoveStart, onMove, state]);
|
|
73
|
+
let moveEvent = useEffectEvent(move);
|
|
73
74
|
|
|
74
|
-
let end =
|
|
75
|
+
let end = useCallback((originalEvent: EventBase, pointerType: PointerType) => {
|
|
75
76
|
restoreTextSelection();
|
|
76
77
|
if (state.current.didMove) {
|
|
77
78
|
onMoveEnd?.({
|
|
@@ -83,57 +84,111 @@ export function useMove(props: MoveEvents): MoveResult {
|
|
|
83
84
|
altKey: originalEvent.altKey
|
|
84
85
|
});
|
|
85
86
|
}
|
|
86
|
-
});
|
|
87
|
+
}, [onMoveEnd, state]);
|
|
88
|
+
let endEvent = useEffectEvent(end);
|
|
87
89
|
|
|
88
|
-
let
|
|
89
|
-
|
|
90
|
+
let [pointerDown, setPointerDown] = useState<'pointer' | 'mouse' | 'touch' | null>(null);
|
|
91
|
+
useLayoutEffect(() => {
|
|
92
|
+
if (pointerDown === 'pointer') {
|
|
93
|
+
let onPointerMove = (e: PointerEvent) => {
|
|
94
|
+
if (e.pointerId === state.current.id) {
|
|
95
|
+
let pointerType = (e.pointerType || 'mouse') as PointerType;
|
|
90
96
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
97
|
+
// Problems with PointerEvent#movementX/movementY:
|
|
98
|
+
// 1. it is always 0 on macOS Safari.
|
|
99
|
+
// 2. On Chrome Android, it's scaled by devicePixelRatio, but not on Chrome macOS
|
|
100
|
+
moveEvent(e, pointerType, e.pageX - (state.current.lastPosition?.pageX ?? 0), e.pageY - (state.current.lastPosition?.pageY ?? 0));
|
|
101
|
+
state.current.lastPosition = {pageX: e.pageX, pageY: e.pageY};
|
|
102
|
+
}
|
|
103
|
+
};
|
|
95
104
|
|
|
96
|
-
|
|
105
|
+
let onPointerUp = (e: PointerEvent) => {
|
|
106
|
+
if (e.pointerId === state.current.id) {
|
|
107
|
+
let pointerType = (e.pointerType || 'mouse') as PointerType;
|
|
108
|
+
endEvent(e, pointerType);
|
|
109
|
+
state.current.id = null;
|
|
110
|
+
removeGlobalListener(window, 'pointermove', onPointerMove, false);
|
|
111
|
+
removeGlobalListener(window, 'pointerup', onPointerUp, false);
|
|
112
|
+
removeGlobalListener(window, 'pointercancel', onPointerUp, false);
|
|
113
|
+
setPointerDown(null);
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
addGlobalListener(window, 'pointermove', onPointerMove, false);
|
|
117
|
+
addGlobalListener(window, 'pointerup', onPointerUp, false);
|
|
118
|
+
addGlobalListener(window, 'pointercancel', onPointerUp, false);
|
|
119
|
+
return () => {
|
|
120
|
+
removeGlobalListener(window, 'pointermove', onPointerMove, false);
|
|
121
|
+
removeGlobalListener(window, 'pointerup', onPointerUp, false);
|
|
122
|
+
removeGlobalListener(window, 'pointercancel', onPointerUp, false);
|
|
123
|
+
};
|
|
124
|
+
} else if (pointerDown === 'mouse' && process.env.NODE_ENV === 'test') {
|
|
97
125
|
let onMouseMove = (e: MouseEvent) => {
|
|
98
126
|
if (e.button === 0) {
|
|
99
|
-
|
|
127
|
+
moveEvent(e, 'mouse', e.pageX - (state.current.lastPosition?.pageX ?? 0), e.pageY - (state.current.lastPosition?.pageY ?? 0));
|
|
100
128
|
state.current.lastPosition = {pageX: e.pageX, pageY: e.pageY};
|
|
101
129
|
}
|
|
102
130
|
};
|
|
103
131
|
let onMouseUp = (e: MouseEvent) => {
|
|
104
132
|
if (e.button === 0) {
|
|
105
|
-
|
|
133
|
+
endEvent(e, 'mouse');
|
|
106
134
|
removeGlobalListener(window, 'mousemove', onMouseMove, false);
|
|
107
135
|
removeGlobalListener(window, 'mouseup', onMouseUp, false);
|
|
136
|
+
setPointerDown(null);
|
|
108
137
|
}
|
|
109
138
|
};
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
state.current.lastPosition = {pageX: e.pageX, pageY: e.pageY};
|
|
116
|
-
addGlobalListener(window, 'mousemove', onMouseMove, false);
|
|
117
|
-
addGlobalListener(window, 'mouseup', onMouseUp, false);
|
|
118
|
-
}
|
|
139
|
+
addGlobalListener(window, 'mousemove', onMouseMove, false);
|
|
140
|
+
addGlobalListener(window, 'mouseup', onMouseUp, false);
|
|
141
|
+
return () => {
|
|
142
|
+
removeGlobalListener(window, 'mousemove', onMouseMove, false);
|
|
143
|
+
removeGlobalListener(window, 'mouseup', onMouseUp, false);
|
|
119
144
|
};
|
|
120
|
-
|
|
145
|
+
} else if (pointerDown === 'touch' && process.env.NODE_ENV === 'test') {
|
|
121
146
|
let onTouchMove = (e: TouchEvent) => {
|
|
122
147
|
let touch = [...e.changedTouches].findIndex(({identifier}) => identifier === state.current.id);
|
|
123
148
|
if (touch >= 0) {
|
|
124
149
|
let {pageX, pageY} = e.changedTouches[touch];
|
|
125
|
-
|
|
150
|
+
moveEvent(e, 'touch', pageX - (state.current.lastPosition?.pageX ?? 0), pageY - (state.current.lastPosition?.pageY ?? 0));
|
|
126
151
|
state.current.lastPosition = {pageX, pageY};
|
|
127
152
|
}
|
|
128
153
|
};
|
|
129
154
|
let onTouchEnd = (e: TouchEvent) => {
|
|
130
155
|
let touch = [...e.changedTouches].findIndex(({identifier}) => identifier === state.current.id);
|
|
131
156
|
if (touch >= 0) {
|
|
132
|
-
|
|
157
|
+
endEvent(e, 'touch');
|
|
133
158
|
state.current.id = null;
|
|
134
159
|
removeGlobalListener(window, 'touchmove', onTouchMove);
|
|
135
160
|
removeGlobalListener(window, 'touchend', onTouchEnd);
|
|
136
161
|
removeGlobalListener(window, 'touchcancel', onTouchEnd);
|
|
162
|
+
setPointerDown(null);
|
|
163
|
+
}
|
|
164
|
+
};
|
|
165
|
+
addGlobalListener(window, 'touchmove', onTouchMove, false);
|
|
166
|
+
addGlobalListener(window, 'touchend', onTouchEnd, false);
|
|
167
|
+
addGlobalListener(window, 'touchcancel', onTouchEnd, false);
|
|
168
|
+
return () => {
|
|
169
|
+
removeGlobalListener(window, 'touchmove', onTouchMove, false);
|
|
170
|
+
removeGlobalListener(window, 'touchend', onTouchEnd, false);
|
|
171
|
+
removeGlobalListener(window, 'touchcancel', onTouchEnd, false);
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
}, [pointerDown, addGlobalListener, removeGlobalListener]);
|
|
175
|
+
|
|
176
|
+
let moveProps = useMemo(() => {
|
|
177
|
+
let moveProps: DOMAttributes = {};
|
|
178
|
+
|
|
179
|
+
let start = () => {
|
|
180
|
+
disableTextSelection();
|
|
181
|
+
state.current.didMove = false;
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
if (typeof PointerEvent === 'undefined' && process.env.NODE_ENV === 'test') {
|
|
185
|
+
moveProps.onMouseDown = (e: React.MouseEvent) => {
|
|
186
|
+
if (e.button === 0) {
|
|
187
|
+
start();
|
|
188
|
+
e.stopPropagation();
|
|
189
|
+
e.preventDefault();
|
|
190
|
+
state.current.lastPosition = {pageX: e.pageX, pageY: e.pageY};
|
|
191
|
+
setPointerDown('mouse');
|
|
137
192
|
}
|
|
138
193
|
};
|
|
139
194
|
moveProps.onTouchStart = (e: React.TouchEvent) => {
|
|
@@ -147,34 +202,9 @@ export function useMove(props: MoveEvents): MoveResult {
|
|
|
147
202
|
e.preventDefault();
|
|
148
203
|
state.current.lastPosition = {pageX, pageY};
|
|
149
204
|
state.current.id = identifier;
|
|
150
|
-
|
|
151
|
-
addGlobalListener(window, 'touchend', onTouchEnd, false);
|
|
152
|
-
addGlobalListener(window, 'touchcancel', onTouchEnd, false);
|
|
205
|
+
setPointerDown('touch');
|
|
153
206
|
};
|
|
154
207
|
} else {
|
|
155
|
-
let onPointerMove = (e: PointerEvent) => {
|
|
156
|
-
if (e.pointerId === state.current.id) {
|
|
157
|
-
let pointerType = (e.pointerType || 'mouse') as PointerType;
|
|
158
|
-
|
|
159
|
-
// Problems with PointerEvent#movementX/movementY:
|
|
160
|
-
// 1. it is always 0 on macOS Safari.
|
|
161
|
-
// 2. On Chrome Android, it's scaled by devicePixelRatio, but not on Chrome macOS
|
|
162
|
-
move(e, pointerType, e.pageX - (state.current.lastPosition?.pageX ?? 0), e.pageY - (state.current.lastPosition?.pageY ?? 0));
|
|
163
|
-
state.current.lastPosition = {pageX: e.pageX, pageY: e.pageY};
|
|
164
|
-
}
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
let onPointerUp = (e: PointerEvent) => {
|
|
168
|
-
if (e.pointerId === state.current.id) {
|
|
169
|
-
let pointerType = (e.pointerType || 'mouse') as PointerType;
|
|
170
|
-
end(e, pointerType);
|
|
171
|
-
state.current.id = null;
|
|
172
|
-
removeGlobalListener(window, 'pointermove', onPointerMove, false);
|
|
173
|
-
removeGlobalListener(window, 'pointerup', onPointerUp, false);
|
|
174
|
-
removeGlobalListener(window, 'pointercancel', onPointerUp, false);
|
|
175
|
-
}
|
|
176
|
-
};
|
|
177
|
-
|
|
178
208
|
moveProps.onPointerDown = (e: React.PointerEvent) => {
|
|
179
209
|
if (e.button === 0 && state.current.id == null) {
|
|
180
210
|
start();
|
|
@@ -182,9 +212,7 @@ export function useMove(props: MoveEvents): MoveResult {
|
|
|
182
212
|
e.preventDefault();
|
|
183
213
|
state.current.lastPosition = {pageX: e.pageX, pageY: e.pageY};
|
|
184
214
|
state.current.id = e.pointerId;
|
|
185
|
-
|
|
186
|
-
addGlobalListener(window, 'pointerup', onPointerUp, false);
|
|
187
|
-
addGlobalListener(window, 'pointercancel', onPointerUp, false);
|
|
215
|
+
setPointerDown('pointer');
|
|
188
216
|
}
|
|
189
217
|
};
|
|
190
218
|
}
|
|
@@ -225,7 +253,7 @@ export function useMove(props: MoveEvents): MoveResult {
|
|
|
225
253
|
};
|
|
226
254
|
|
|
227
255
|
return moveProps;
|
|
228
|
-
}, [state,
|
|
256
|
+
}, [state, move, end]);
|
|
229
257
|
|
|
230
258
|
return {moveProps};
|
|
231
259
|
}
|