@react-aria/interactions 3.25.6 → 3.26.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.
Files changed (45) hide show
  1. package/dist/focusSafely.main.js +4 -4
  2. package/dist/focusSafely.main.js.map +1 -1
  3. package/dist/focusSafely.mjs +4 -4
  4. package/dist/focusSafely.module.js +4 -4
  5. package/dist/focusSafely.module.js.map +1 -1
  6. package/dist/import.mjs +2 -2
  7. package/dist/main.js +1 -0
  8. package/dist/main.js.map +1 -1
  9. package/dist/module.js +2 -2
  10. package/dist/module.js.map +1 -1
  11. package/dist/types.d.ts +3 -1
  12. package/dist/types.d.ts.map +1 -1
  13. package/dist/useFocusVisible.main.js +12 -2
  14. package/dist/useFocusVisible.main.js.map +1 -1
  15. package/dist/useFocusVisible.mjs +13 -4
  16. package/dist/useFocusVisible.module.js +13 -4
  17. package/dist/useFocusVisible.module.js.map +1 -1
  18. package/dist/useInteractOutside.main.js +1 -3
  19. package/dist/useInteractOutside.main.js.map +1 -1
  20. package/dist/useInteractOutside.mjs +1 -3
  21. package/dist/useInteractOutside.module.js +1 -3
  22. package/dist/useInteractOutside.module.js.map +1 -1
  23. package/dist/useMove.main.js +110 -74
  24. package/dist/useMove.main.js.map +1 -1
  25. package/dist/useMove.mjs +112 -76
  26. package/dist/useMove.module.js +112 -76
  27. package/dist/useMove.module.js.map +1 -1
  28. package/dist/usePress.main.js +186 -114
  29. package/dist/usePress.main.js.map +1 -1
  30. package/dist/usePress.mjs +188 -116
  31. package/dist/usePress.module.js +188 -116
  32. package/dist/usePress.module.js.map +1 -1
  33. package/dist/utils.main.js +2 -5
  34. package/dist/utils.main.js.map +1 -1
  35. package/dist/utils.mjs +3 -6
  36. package/dist/utils.module.js +3 -6
  37. package/dist/utils.module.js.map +1 -1
  38. package/package.json +3 -3
  39. package/src/focusSafely.ts +4 -4
  40. package/src/index.ts +1 -0
  41. package/src/useFocusVisible.ts +15 -3
  42. package/src/useInteractOutside.ts +1 -1
  43. package/src/useMove.ts +85 -57
  44. package/src/usePress.ts +183 -147
  45. package/src/utils.ts +3 -7
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 = useEffectEvent((originalEvent: EventBase, pointerType: PointerType, deltaX: number, deltaY: number) => {
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 = useEffectEvent((originalEvent: EventBase, pointerType: PointerType) => {
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 moveProps = useMemo(() => {
89
- let moveProps: DOMAttributes = {};
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
- let start = () => {
92
- disableTextSelection();
93
- state.current.didMove = false;
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
- if (typeof PointerEvent === 'undefined' && process.env.NODE_ENV === 'test') {
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
- move(e, 'mouse', e.pageX - (state.current.lastPosition?.pageX ?? 0), e.pageY - (state.current.lastPosition?.pageY ?? 0));
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
- end(e, 'mouse');
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
- moveProps.onMouseDown = (e: React.MouseEvent) => {
111
- if (e.button === 0) {
112
- start();
113
- e.stopPropagation();
114
- e.preventDefault();
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
- move(e, 'touch', pageX - (state.current.lastPosition?.pageX ?? 0), pageY - (state.current.lastPosition?.pageY ?? 0));
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
- end(e, 'touch');
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
- addGlobalListener(window, 'touchmove', onTouchMove, false);
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
- addGlobalListener(window, 'pointermove', onPointerMove, false);
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, addGlobalListener, removeGlobalListener, move, end]);
256
+ }, [state, move, end]);
229
257
 
230
258
  return {moveProps};
231
259
  }