@msobiecki/react-marauders-path 1.24.3 → 1.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.
- package/README.md +147 -12
- package/dist/index.d.ts +100 -0
- package/dist/index.js +29 -17
- package/dist/index.js.map +1 -1
- package/dist/use-double-tap/invoke-double-tap-action.js +7 -0
- package/dist/use-double-tap/invoke-double-tap-action.js.map +1 -0
- package/dist/use-double-tap/use-double-tap.js +77 -0
- package/dist/use-double-tap/use-double-tap.js.map +1 -0
- package/dist/use-double-tap/use-double-tap.types.js +9 -0
- package/dist/use-double-tap/use-double-tap.types.js.map +1 -0
- package/dist/use-drag/use-drag.js +68 -70
- package/dist/use-drag/use-drag.js.map +1 -1
- package/dist/use-key/use-key.js +96 -104
- package/dist/use-key/use-key.js.map +1 -1
- package/dist/use-pinch/use-pinch.js +77 -79
- package/dist/use-pinch/use-pinch.js.map +1 -1
- package/dist/use-press/invoke-press-action.js +7 -0
- package/dist/use-press/invoke-press-action.js.map +1 -0
- package/dist/use-press/use-press.js +98 -0
- package/dist/use-press/use-press.js.map +1 -0
- package/dist/use-press/use-press.types.js +9 -0
- package/dist/use-press/use-press.types.js.map +1 -0
- package/dist/use-swipe/use-swipe.js +61 -68
- package/dist/use-swipe/use-swipe.js.map +1 -1
- package/dist/use-tap/invoke-tap-action.js +7 -0
- package/dist/use-tap/invoke-tap-action.js.map +1 -0
- package/dist/use-tap/use-tap.js +94 -0
- package/dist/use-tap/use-tap.js.map +1 -0
- package/dist/use-tap/use-tap.types.js +9 -0
- package/dist/use-tap/use-tap.types.js.map +1 -0
- package/dist/use-wheel/use-wheel.js +33 -47
- package/dist/use-wheel/use-wheel.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,17 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://github.com/msobiecki/react-marauders-path/blob/master/LICENSE)
|
|
4
4
|
|
|
5
|
-
A lightweight, type-safe React library for handling keyboard, wheel, swipe, drag, and pinch events. Perfect for games, interactive applications, and input-driven interfaces.
|
|
5
|
+
A lightweight, type-safe React library for handling keyboard, wheel, tap, double-tap, press, swipe, drag, and pinch events. Perfect for games, interactive applications, and input-driven interfaces.
|
|
6
6
|
|
|
7
7
|

|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
|
-
- 🎮 **Keyboard Event Handling** - Detect single keys, key combinations and sequences with configurable timing thresholds
|
|
12
|
-
- 🎡 **Wheel Event Handling** -
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
11
|
+
- 🎮 **Keyboard Event Handling** - Detect single keys, key combinations, and sequences with configurable timing thresholds
|
|
12
|
+
- 🎡 **Wheel Event Handling** - Detect wheel delta values with optional `requestAnimationFrame` batching for smoother updates
|
|
13
|
+
- 👆 **Tap Gesture Handling** - Detect single taps/clicks with configurable movement and duration thresholds
|
|
14
|
+
- 👆👆 **Double-Tap Gesture Handling** - Detect consecutive taps/clicks with configurable timing and position thresholds
|
|
15
|
+
- ✋ **Press Gesture Handling** - Detect press-and-hold interactions with configurable delay and movement thresholds
|
|
16
|
+
- 🖐️ **Swipe Gesture Handling** - Detect directional swipes with configurable distance, velocity, and pointer type filtering
|
|
17
|
+
- ✊ **Drag Gesture Handling** - Detect movement, deltas, duration, and start/end positions with pointer type filtering and optional `requestAnimationFrame` batching
|
|
18
|
+
- 🤏 **Pinch Gesture Handling** - Detect two-finger distance, delta, and scale with pointer type filtering and optional `requestAnimationFrame` batching
|
|
16
19
|
|
|
17
20
|
## Installation
|
|
18
21
|
|
|
@@ -95,6 +98,48 @@ function MyComponent() {
|
|
|
95
98
|
}
|
|
96
99
|
```
|
|
97
100
|
|
|
101
|
+
### Tap Event Hook
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { useTap } from '@msobiecki/react-marauders-path';
|
|
105
|
+
|
|
106
|
+
function MyComponent() {
|
|
107
|
+
useTap((event, data) => {
|
|
108
|
+
console.log(`Tapped at X: ${data.x}, Y: ${data.y}`);
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
return <div>Tap to interact</div>;
|
|
112
|
+
}
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Double Tap Event Hook
|
|
116
|
+
|
|
117
|
+
```typescript
|
|
118
|
+
import { useDoubleTap } from '@msobiecki/react-marauders-path';
|
|
119
|
+
|
|
120
|
+
function MyComponent() {
|
|
121
|
+
useDoubleTap((event, data) => {
|
|
122
|
+
console.log(`Double tapped at X: ${data.x}, Y: ${data.y}`);
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
return <div>Double tap to interact</div>;
|
|
126
|
+
}
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
### Press Event Hook
|
|
130
|
+
|
|
131
|
+
```typescript
|
|
132
|
+
import { usePress } from '@msobiecki/react-marauders-path';
|
|
133
|
+
|
|
134
|
+
function MyComponent() {
|
|
135
|
+
usePress((event, data) => {
|
|
136
|
+
console.log(`Pressed at X: ${data.x}, Y: ${data.y}`);
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
return <div>Press and hold to interact</div>;
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
98
143
|
### Swipe Event Hook
|
|
99
144
|
|
|
100
145
|
```typescript
|
|
@@ -197,6 +242,102 @@ interface WheelData {
|
|
|
197
242
|
}
|
|
198
243
|
```
|
|
199
244
|
|
|
245
|
+
### `useTap(callback, options?)`
|
|
246
|
+
|
|
247
|
+
Hook for handling single tap/click interactions.
|
|
248
|
+
|
|
249
|
+
**Parameters:**
|
|
250
|
+
|
|
251
|
+
- `callback: (event: PointerEvent, data: TapData) => void | boolean` - Called when tap gesture is recognized
|
|
252
|
+
- `options?: UseTapOptions` - Optional configuration
|
|
253
|
+
|
|
254
|
+
**Options:**
|
|
255
|
+
|
|
256
|
+
```typescript
|
|
257
|
+
interface UseTapOptions {
|
|
258
|
+
eventPointerTypes?: Array<"touch" | "mouse" | "pen">; // Default: ["touch", "mouse", "pen"]
|
|
259
|
+
eventCapture?: boolean; // Default: false
|
|
260
|
+
eventOnce?: boolean; // Default: false
|
|
261
|
+
eventStopImmediatePropagation?: boolean; // Default: false
|
|
262
|
+
threshold?: number; // Default: 8 (px) - Maximum movement allowed between pointerdown and pointerup
|
|
263
|
+
maxDuration?: number; // Default: 250 (ms) - Maximum tap duration
|
|
264
|
+
container?: RefObject<HTMLElement>; // Default: window
|
|
265
|
+
}
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**Tap Data:**
|
|
269
|
+
|
|
270
|
+
```typescript
|
|
271
|
+
interface TapData {
|
|
272
|
+
x: number; // Tap pointerup X
|
|
273
|
+
y: number; // Tap pointerup Y
|
|
274
|
+
}
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
### `useDoubleTap(callback, options?)`
|
|
278
|
+
|
|
279
|
+
Hook for handling double-tap / double-click interactions.
|
|
280
|
+
|
|
281
|
+
**Parameters:**
|
|
282
|
+
|
|
283
|
+
- `callback: (event: PointerEvent, data: DoubleTapData) => void | boolean` - Called when double tap is recognized
|
|
284
|
+
- `options?: UseDoubleTapOptions` - Optional configuration
|
|
285
|
+
|
|
286
|
+
**Options:**
|
|
287
|
+
|
|
288
|
+
```typescript
|
|
289
|
+
interface UseDoubleTapOptions {
|
|
290
|
+
eventPointerTypes?: Array<"touch" | "mouse" | "pen">; // Default: ["touch", "mouse", "pen"]
|
|
291
|
+
eventCapture?: boolean; // Default: false
|
|
292
|
+
eventOnce?: boolean; // Default: false
|
|
293
|
+
eventStopImmediatePropagation?: boolean; // Default: false
|
|
294
|
+
delay?: number; // Default: 300 (ms) - Maximum interval between taps
|
|
295
|
+
threshold?: number; // Default: 8 (px) - Maximum distance between two tap positions
|
|
296
|
+
container?: RefObject<HTMLElement>; // Default: window
|
|
297
|
+
}
|
|
298
|
+
```
|
|
299
|
+
|
|
300
|
+
**Double Tap Data:**
|
|
301
|
+
|
|
302
|
+
```typescript
|
|
303
|
+
interface DoubleTapData {
|
|
304
|
+
x: number; // Tap pointerup X
|
|
305
|
+
y: number; // Tap pointerup Y
|
|
306
|
+
}
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### `usePress(callback, options?)`
|
|
310
|
+
|
|
311
|
+
Hook for handling press-and-hold interactions.
|
|
312
|
+
|
|
313
|
+
**Parameters:**
|
|
314
|
+
|
|
315
|
+
- `callback: (event: PointerEvent, data: PressData) => void | boolean` - Called when press delay completes
|
|
316
|
+
- `options?: UsePressOptions` - Optional configuration
|
|
317
|
+
|
|
318
|
+
**Options:**
|
|
319
|
+
|
|
320
|
+
```typescript
|
|
321
|
+
interface UsePressOptions {
|
|
322
|
+
eventPointerTypes?: Array<"touch" | "mouse" | "pen">; // Default: ["touch", "mouse", "pen"]
|
|
323
|
+
eventCapture?: boolean; // Default: false
|
|
324
|
+
eventOnce?: boolean; // Default: false
|
|
325
|
+
eventStopImmediatePropagation?: boolean; // Default: false
|
|
326
|
+
delay?: number; // Default: 500 (ms) - Press-and-hold duration required
|
|
327
|
+
threshold?: number; // Default: 8 (px) - Maximum movement allowed while holding
|
|
328
|
+
container?: RefObject<HTMLElement>; // Default: window
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
**Press Data:**
|
|
333
|
+
|
|
334
|
+
```typescript
|
|
335
|
+
interface PressData {
|
|
336
|
+
x: number; // Pointerdown X at press start
|
|
337
|
+
y: number; // Pointerdown Y at press start
|
|
338
|
+
}
|
|
339
|
+
```
|
|
340
|
+
|
|
200
341
|
### `useSwipe(swipe, callback, options?)`
|
|
201
342
|
|
|
202
343
|
Hook for handling touch swipe gestures with configurable distance and velocity thresholds.
|
|
@@ -414,12 +555,6 @@ npm run lint
|
|
|
414
555
|
- `drag` / `pan` – track movement of finger or mouse
|
|
415
556
|
- `pinch` / `zoom` – two-finger pinch / zoom
|
|
416
557
|
|
|
417
|
-
### Low-level Gesture Hooks
|
|
418
|
-
|
|
419
|
-
- 🚧 **`useTap`** – single tap / click
|
|
420
|
-
- 🚧 **`useDoubleTap`** – quick double tap
|
|
421
|
-
- 🚧 **`usePress`** – press and hold (longPress)
|
|
422
|
-
|
|
423
558
|
### Pointer / Mouse Hooks (Unified)
|
|
424
559
|
|
|
425
560
|
- 🚧 **`usePointer`** – unified hook for MouseEvent, PointerEvent, and TouchEvent
|
package/dist/index.d.ts
CHANGED
|
@@ -9,6 +9,31 @@ export declare interface CombinationState {
|
|
|
9
9
|
activeKeys: Map<Key, CombinationActiveKey>;
|
|
10
10
|
}
|
|
11
11
|
|
|
12
|
+
export declare interface DoubleTapData {
|
|
13
|
+
x: number;
|
|
14
|
+
y: number;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export declare type DoubleTapEventPointerType = (typeof DoubleTapEventPointerTypes)[keyof typeof DoubleTapEventPointerTypes];
|
|
18
|
+
|
|
19
|
+
export declare const DoubleTapEventPointerTypes: {
|
|
20
|
+
readonly Touch: "touch";
|
|
21
|
+
readonly Mouse: "mouse";
|
|
22
|
+
readonly Pen: "pen";
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export declare interface DoubleTapOptions {
|
|
26
|
+
eventPointerTypes: DoubleTapEventPointerType[];
|
|
27
|
+
eventCapture: boolean;
|
|
28
|
+
eventOnce: boolean;
|
|
29
|
+
eventStopImmediatePropagation: boolean;
|
|
30
|
+
delay: number;
|
|
31
|
+
threshold: number;
|
|
32
|
+
container: {
|
|
33
|
+
current: EventTarget | null;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
|
|
12
37
|
export declare interface DragData {
|
|
13
38
|
deltaX: number;
|
|
14
39
|
deltaY: number;
|
|
@@ -108,6 +133,31 @@ export declare interface PinchState {
|
|
|
108
133
|
active: boolean;
|
|
109
134
|
}
|
|
110
135
|
|
|
136
|
+
export declare interface PressData {
|
|
137
|
+
x: number;
|
|
138
|
+
y: number;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
export declare type PressEventPointerType = (typeof PressEventPointerTypes)[keyof typeof PressEventPointerTypes];
|
|
142
|
+
|
|
143
|
+
export declare const PressEventPointerTypes: {
|
|
144
|
+
readonly Touch: "touch";
|
|
145
|
+
readonly Mouse: "mouse";
|
|
146
|
+
readonly Pen: "pen";
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
export declare interface PressOptions {
|
|
150
|
+
eventPointerTypes: PressEventPointerType[];
|
|
151
|
+
eventCapture: boolean;
|
|
152
|
+
eventOnce: boolean;
|
|
153
|
+
eventStopImmediatePropagation: boolean;
|
|
154
|
+
delay: number;
|
|
155
|
+
threshold: number;
|
|
156
|
+
container: {
|
|
157
|
+
current: EventTarget | null;
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
111
161
|
export declare interface SequenceState {
|
|
112
162
|
key: Key;
|
|
113
163
|
chord: KeyChord;
|
|
@@ -161,6 +211,44 @@ export declare interface SwipeState {
|
|
|
161
211
|
active: boolean;
|
|
162
212
|
}
|
|
163
213
|
|
|
214
|
+
export declare interface TapData {
|
|
215
|
+
x: number;
|
|
216
|
+
y: number;
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
export declare type TapEventPointerType = (typeof TapEventPointerTypes)[keyof typeof TapEventPointerTypes];
|
|
220
|
+
|
|
221
|
+
export declare const TapEventPointerTypes: {
|
|
222
|
+
readonly Touch: "touch";
|
|
223
|
+
readonly Mouse: "mouse";
|
|
224
|
+
readonly Pen: "pen";
|
|
225
|
+
};
|
|
226
|
+
|
|
227
|
+
export declare interface TapOptions {
|
|
228
|
+
eventPointerTypes: TapEventPointerType[];
|
|
229
|
+
eventCapture: boolean;
|
|
230
|
+
eventOnce: boolean;
|
|
231
|
+
eventStopImmediatePropagation: boolean;
|
|
232
|
+
threshold: number;
|
|
233
|
+
maxDuration: number;
|
|
234
|
+
container: {
|
|
235
|
+
current: EventTarget | null;
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
export declare interface TapState {
|
|
240
|
+
startX: number;
|
|
241
|
+
startY: number;
|
|
242
|
+
startTime: number;
|
|
243
|
+
active: boolean;
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
export declare const useDoubleTap: (doubleTapCallback: UseDoubleTapCallback, options?: UseDoubleTapOptions) => void;
|
|
247
|
+
|
|
248
|
+
export declare type UseDoubleTapCallback = ((event: PointerEvent, data: DoubleTapData) => boolean) | ((event: PointerEvent, data: DoubleTapData) => void);
|
|
249
|
+
|
|
250
|
+
export declare type UseDoubleTapOptions = Partial<DoubleTapOptions>;
|
|
251
|
+
|
|
164
252
|
export declare const useDrag: (dragCallback: UseDragCallback, options?: UseDragOptions) => void;
|
|
165
253
|
|
|
166
254
|
export declare type UseDragCallback = ((event: PointerEvent, data: DragData) => boolean) | ((event: PointerEvent, data: DragData) => void);
|
|
@@ -241,6 +329,12 @@ export declare type UsePinchCallback = ((event: PointerEvent, data: PinchData) =
|
|
|
241
329
|
|
|
242
330
|
export declare type UsePinchOptions = Partial<PinchOptions>;
|
|
243
331
|
|
|
332
|
+
export declare const usePress: (pressCallback: UsePressCallback, options?: UsePressOptions) => void;
|
|
333
|
+
|
|
334
|
+
export declare type UsePressCallback = ((event: PointerEvent, data: PressData) => void) | ((event: PointerEvent, data: PressData) => boolean);
|
|
335
|
+
|
|
336
|
+
export declare type UsePressOptions = Partial<PressOptions>;
|
|
337
|
+
|
|
244
338
|
export declare const useSwipe: (swipe: UseSwipeSchema, swipeCallback: UseSwipeCallback, options?: UseSwipeOptions) => void;
|
|
245
339
|
|
|
246
340
|
export declare type UseSwipeCallback = ((event: PointerEvent, direction: SwipeDirection, data: SwipeData, ...properties: unknown[]) => boolean) | ((event: PointerEvent, direction: SwipeDirection, data: SwipeData, ...properties: unknown[]) => void);
|
|
@@ -249,6 +343,12 @@ export declare type UseSwipeOptions = Partial<SwipeOptions>;
|
|
|
249
343
|
|
|
250
344
|
export declare type UseSwipeSchema = SwipeDirection | SwipeDirection[];
|
|
251
345
|
|
|
346
|
+
export declare const useTap: (tapCallback: UseTapCallback, options?: UseTapOptions) => void;
|
|
347
|
+
|
|
348
|
+
export declare type UseTapCallback = ((event: PointerEvent, data: TapData) => boolean) | ((event: PointerEvent, data: TapData) => void);
|
|
349
|
+
|
|
350
|
+
export declare type UseTapOptions = Partial<TapOptions>;
|
|
351
|
+
|
|
252
352
|
export declare const useWheel: (wheelCallback: UseWheelCallback, options?: UseWheelOptions) => void;
|
|
253
353
|
|
|
254
354
|
export declare type UseWheelCallback = ((event: WheelEvent, delta: WheelData, ...properties: unknown[]) => void) | ((event: WheelEvent, delta: WheelData, ...properties: unknown[]) => boolean);
|
package/dist/index.js
CHANGED
|
@@ -1,22 +1,34 @@
|
|
|
1
|
-
import { default as o } from "./use-
|
|
2
|
-
import {
|
|
3
|
-
import { default as f } from "./use-
|
|
1
|
+
import { default as o } from "./use-double-tap/use-double-tap.js";
|
|
2
|
+
import { DoubleTapEventPointerTypes as p } from "./use-double-tap/use-double-tap.types.js";
|
|
3
|
+
import { default as f } from "./use-drag/use-drag.js";
|
|
4
|
+
import { DragEventPointerTypes as u } from "./use-drag/use-drag.types.js";
|
|
5
|
+
import { default as m } from "./use-key/use-key.js";
|
|
4
6
|
import { KeyEventTypes as i } from "./use-key/use-key.types.js";
|
|
5
|
-
import { default as
|
|
6
|
-
import { PinchEventPointerTypes as
|
|
7
|
-
import { default as
|
|
8
|
-
import {
|
|
9
|
-
import { default as
|
|
7
|
+
import { default as T } from "./use-pinch/use-pinch.js";
|
|
8
|
+
import { PinchEventPointerTypes as y } from "./use-pinch/use-pinch.types.js";
|
|
9
|
+
import { default as v } from "./use-press/use-press.js";
|
|
10
|
+
import { PressEventPointerTypes as D } from "./use-press/use-press.types.js";
|
|
11
|
+
import { default as h } from "./use-swipe/use-swipe.js";
|
|
12
|
+
import { SwipeDirections as S, SwipeEventPointerTypes as b } from "./use-swipe/use-swipe.types.js";
|
|
13
|
+
import { default as K } from "./use-tap/use-tap.js";
|
|
14
|
+
import { TapEventPointerTypes as j } from "./use-tap/use-tap.types.js";
|
|
15
|
+
import { default as q } from "./use-wheel/use-wheel.js";
|
|
10
16
|
export {
|
|
11
|
-
p as
|
|
17
|
+
p as DoubleTapEventPointerTypes,
|
|
18
|
+
u as DragEventPointerTypes,
|
|
12
19
|
i as KeyEventTypes,
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
y as PinchEventPointerTypes,
|
|
21
|
+
D as PressEventPointerTypes,
|
|
22
|
+
S as SwipeDirections,
|
|
23
|
+
b as SwipeEventPointerTypes,
|
|
24
|
+
j as TapEventPointerTypes,
|
|
25
|
+
o as useDoubleTap,
|
|
26
|
+
f as useDrag,
|
|
27
|
+
m as useKey,
|
|
28
|
+
T as usePinch,
|
|
29
|
+
v as usePress,
|
|
30
|
+
h as useSwipe,
|
|
31
|
+
K as useTap,
|
|
32
|
+
q as useWheel
|
|
21
33
|
};
|
|
22
34
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"invoke-double-tap-action.js","sources":["../../src/use-double-tap/invoke-double-tap-action.ts"],"sourcesContent":["import { DoubleTapData } from \"./use-double-tap.types\";\n\n/**\n * Invokes a double tap action callback with optional event modifications.\n *\n * Handles double tap event processing including preventing default behavior,\n * stopping immediate propagation, and managing one-time event handlers.\n *\n * @param {PointerEvent} event - The double tap event\n * @param {DoubleTapData} data - The normalized double tap data\n * @param {Function} callback - Function to invoke with (event, data). Return true to prevent default.\n * @param {Object} options - Action options\n * @param {boolean} [options.stopImmediate=false] - Whether to stop immediate propagation\n * @param {boolean} [options.once=false] - Whether this is a one-time event\n * @param {Function} [options.onOnce] - Callback to invoke when one-time event fires\n *\n * @example\n * invokeTapAction(event, data, (e, d) => {\n * console.log(`Double tap at: ${d.x}, ${d.y}`);\n * return true; // Prevent default\n * }, { stopImmediate: true });\n */\nexport const invokeDoubleTapAction = (\n event: PointerEvent,\n data: DoubleTapData,\n callback:\n | ((event: PointerEvent, data: DoubleTapData) => boolean)\n | ((event: PointerEvent, data: DoubleTapData) => void),\n options: {\n stopImmediate?: boolean;\n once?: boolean;\n onOnce?: () => void;\n },\n) => {\n if (options.stopImmediate) {\n event.stopImmediatePropagation();\n }\n\n const shouldPrevent = callback(event, data);\n if (shouldPrevent) {\n event.preventDefault();\n }\n\n if (options.once) {\n options.onOnce?.();\n }\n};\n"],"names":["invokeDoubleTapAction","event","data","callback","options"],"mappings":"AAsBO,MAAMA,IAAwB,CACnCC,GACAC,GACAC,GAGAC,MAKG;AACH,EAAIA,EAAQ,iBACVH,EAAM,yBAAA,GAGcE,EAASF,GAAOC,CAAI,KAExCD,EAAM,eAAA,GAGJG,EAAQ,QACVA,EAAQ,SAAA;AAEZ;"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { useRef as c, useCallback as g, useEffect as x } from "react";
|
|
2
|
+
import { invokeDoubleTapAction as X } from "./invoke-double-tap-action.js";
|
|
3
|
+
const Y = {
|
|
4
|
+
eventPointerTypes: ["touch", "mouse", "pen"],
|
|
5
|
+
eventCapture: !1,
|
|
6
|
+
eventOnce: !1,
|
|
7
|
+
eventStopImmediatePropagation: !1,
|
|
8
|
+
delay: 300,
|
|
9
|
+
threshold: 8,
|
|
10
|
+
container: { current: null }
|
|
11
|
+
}, R = (i, h = {}) => {
|
|
12
|
+
const {
|
|
13
|
+
eventPointerTypes: l,
|
|
14
|
+
eventCapture: u,
|
|
15
|
+
eventOnce: a,
|
|
16
|
+
eventStopImmediatePropagation: s,
|
|
17
|
+
delay: p,
|
|
18
|
+
threshold: f,
|
|
19
|
+
container: d
|
|
20
|
+
} = { ...Y, ...h }, m = c(null), r = c(null), t = c(null), y = g(
|
|
21
|
+
(e) => {
|
|
22
|
+
if (!e.isPrimary || !l.includes(
|
|
23
|
+
e.pointerType
|
|
24
|
+
))
|
|
25
|
+
return;
|
|
26
|
+
const n = Date.now();
|
|
27
|
+
if (!t.current) {
|
|
28
|
+
t.current = {
|
|
29
|
+
time: n,
|
|
30
|
+
x: e.clientX,
|
|
31
|
+
y: e.clientY
|
|
32
|
+
};
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const o = n - t.current.time, P = e.clientX - t.current.x, T = e.clientY - t.current.y;
|
|
36
|
+
if (o <= p && Math.hypot(P, T) <= f) {
|
|
37
|
+
const b = {
|
|
38
|
+
x: e.clientX,
|
|
39
|
+
y: e.clientY
|
|
40
|
+
};
|
|
41
|
+
X(e, b, i, {
|
|
42
|
+
stopImmediate: s,
|
|
43
|
+
once: a,
|
|
44
|
+
onOnce: () => r.current?.abort()
|
|
45
|
+
}), t.current = null;
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
t.current = {
|
|
49
|
+
time: n,
|
|
50
|
+
x: e.clientX,
|
|
51
|
+
y: e.clientY
|
|
52
|
+
};
|
|
53
|
+
},
|
|
54
|
+
[
|
|
55
|
+
i,
|
|
56
|
+
p,
|
|
57
|
+
f,
|
|
58
|
+
l,
|
|
59
|
+
a,
|
|
60
|
+
s
|
|
61
|
+
]
|
|
62
|
+
);
|
|
63
|
+
x(() => {
|
|
64
|
+
m.current = d?.current ?? globalThis, r.current = new AbortController();
|
|
65
|
+
const { signal: e } = r.current, n = (o) => o instanceof PointerEvent && y(o);
|
|
66
|
+
return m.current.addEventListener("pointerup", n, {
|
|
67
|
+
capture: u,
|
|
68
|
+
signal: e
|
|
69
|
+
}), () => {
|
|
70
|
+
r.current?.abort(), t.current = null;
|
|
71
|
+
};
|
|
72
|
+
}, [d, u, y]);
|
|
73
|
+
};
|
|
74
|
+
export {
|
|
75
|
+
R as default
|
|
76
|
+
};
|
|
77
|
+
//# sourceMappingURL=use-double-tap.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-double-tap.js","sources":["../../src/use-double-tap/use-double-tap.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\nimport {\n DoubleTapOptions,\n UseDoubleTapCallback,\n UseDoubleTapOptions,\n DoubleTapEventPointerType,\n DoubleTapData,\n} from \"./use-double-tap.types\";\nimport { invokeDoubleTapAction } from \"./invoke-double-tap-action\";\n\nconst defaultOptions: DoubleTapOptions = {\n eventPointerTypes: [\"touch\", \"mouse\", \"pen\"],\n eventCapture: false,\n eventOnce: false,\n eventStopImmediatePropagation: false,\n delay: 300,\n threshold: 8,\n container: { current: null },\n};\n\nconst useDoubleTap = (\n doubleTapCallback: UseDoubleTapCallback,\n options: UseDoubleTapOptions = {},\n) => {\n const {\n eventPointerTypes,\n eventCapture,\n eventOnce,\n eventStopImmediatePropagation,\n delay,\n threshold,\n container,\n } = { ...defaultOptions, ...options };\n\n const targetReference = useRef<EventTarget | null>(null);\n const abortControllerReference = useRef<AbortController | null>(null);\n\n const lastTapReference = useRef<{\n time: number;\n x: number;\n y: number;\n } | null>(null);\n\n const handlePointerUp = useCallback(\n (event: PointerEvent) => {\n if (!event.isPrimary) {\n return;\n }\n if (\n !eventPointerTypes.includes(\n event.pointerType as DoubleTapEventPointerType,\n )\n ) {\n return;\n }\n\n const now = Date.now();\n\n if (!lastTapReference.current) {\n lastTapReference.current = {\n time: now,\n x: event.clientX,\n y: event.clientY,\n };\n return;\n }\n\n const deltaTime = now - lastTapReference.current.time;\n const deltaX = event.clientX - lastTapReference.current.x;\n const deltaY = event.clientY - lastTapReference.current.y;\n\n if (deltaTime <= delay && Math.hypot(deltaX, deltaY) <= threshold) {\n const data: DoubleTapData = {\n x: event.clientX,\n y: event.clientY,\n };\n\n invokeDoubleTapAction(event, data, doubleTapCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => abortControllerReference.current?.abort(),\n });\n\n lastTapReference.current = null;\n return;\n }\n\n lastTapReference.current = {\n time: now,\n x: event.clientX,\n y: event.clientY,\n };\n },\n [\n doubleTapCallback,\n delay,\n threshold,\n eventPointerTypes,\n eventOnce,\n eventStopImmediatePropagation,\n ],\n );\n\n useEffect(() => {\n targetReference.current = container?.current ?? globalThis;\n abortControllerReference.current = new AbortController();\n const { signal } = abortControllerReference.current;\n\n const pointerUpListener = (event: Event) =>\n event instanceof PointerEvent && handlePointerUp(event);\n\n targetReference.current.addEventListener(\"pointerup\", pointerUpListener, {\n capture: eventCapture,\n signal,\n });\n\n return () => {\n abortControllerReference.current?.abort();\n lastTapReference.current = null;\n };\n }, [container, eventCapture, handlePointerUp]);\n};\n\nexport default useDoubleTap;\n"],"names":["defaultOptions","useDoubleTap","doubleTapCallback","options","eventPointerTypes","eventCapture","eventOnce","eventStopImmediatePropagation","delay","threshold","container","targetReference","useRef","abortControllerReference","lastTapReference","handlePointerUp","useCallback","event","now","deltaTime","deltaX","deltaY","data","invokeDoubleTapAction","useEffect","signal","pointerUpListener"],"mappings":";;AAUA,MAAMA,IAAmC;AAAA,EACvC,mBAAmB,CAAC,SAAS,SAAS,KAAK;AAAA,EAC3C,cAAc;AAAA,EACd,WAAW;AAAA,EACX,+BAA+B;AAAA,EAC/B,OAAO;AAAA,EACP,WAAW;AAAA,EACX,WAAW,EAAE,SAAS,KAAA;AACxB,GAEMC,IAAe,CACnBC,GACAC,IAA+B,OAC5B;AACH,QAAM;AAAA,IACJ,mBAAAC;AAAA,IACA,cAAAC;AAAA,IACA,WAAAC;AAAA,IACA,+BAAAC;AAAA,IACA,OAAAC;AAAA,IACA,WAAAC;AAAA,IACA,WAAAC;AAAA,EAAA,IACE,EAAE,GAAGV,GAAgB,GAAGG,EAAA,GAEtBQ,IAAkBC,EAA2B,IAAI,GACjDC,IAA2BD,EAA+B,IAAI,GAE9DE,IAAmBF,EAIf,IAAI,GAERG,IAAkBC;AAAA,IACtB,CAACC,MAAwB;AAIvB,UAHI,CAACA,EAAM,aAIT,CAACb,EAAkB;AAAA,QACjBa,EAAM;AAAA,MAAA;AAGR;AAGF,YAAMC,IAAM,KAAK,IAAA;AAEjB,UAAI,CAACJ,EAAiB,SAAS;AAC7B,QAAAA,EAAiB,UAAU;AAAA,UACzB,MAAMI;AAAA,UACN,GAAGD,EAAM;AAAA,UACT,GAAGA,EAAM;AAAA,QAAA;AAEX;AAAA,MACF;AAEA,YAAME,IAAYD,IAAMJ,EAAiB,QAAQ,MAC3CM,IAASH,EAAM,UAAUH,EAAiB,QAAQ,GAClDO,IAASJ,EAAM,UAAUH,EAAiB,QAAQ;AAExD,UAAIK,KAAaX,KAAS,KAAK,MAAMY,GAAQC,CAAM,KAAKZ,GAAW;AACjE,cAAMa,IAAsB;AAAA,UAC1B,GAAGL,EAAM;AAAA,UACT,GAAGA,EAAM;AAAA,QAAA;AAGX,QAAAM,EAAsBN,GAAOK,GAAMpB,GAAmB;AAAA,UACpD,eAAeK;AAAA,UACf,MAAMD;AAAA,UACN,QAAQ,MAAMO,EAAyB,SAAS,MAAA;AAAA,QAAM,CACvD,GAEDC,EAAiB,UAAU;AAC3B;AAAA,MACF;AAEA,MAAAA,EAAiB,UAAU;AAAA,QACzB,MAAMI;AAAA,QACN,GAAGD,EAAM;AAAA,QACT,GAAGA,EAAM;AAAA,MAAA;AAAA,IAEb;AAAA,IACA;AAAA,MACEf;AAAA,MACAM;AAAA,MACAC;AAAA,MACAL;AAAA,MACAE;AAAA,MACAC;AAAA,IAAA;AAAA,EACF;AAGF,EAAAiB,EAAU,MAAM;AACd,IAAAb,EAAgB,UAAUD,GAAW,WAAW,YAChDG,EAAyB,UAAU,IAAI,gBAAA;AACvC,UAAM,EAAE,QAAAY,MAAWZ,EAAyB,SAEtCa,IAAoB,CAACT,MACzBA,aAAiB,gBAAgBF,EAAgBE,CAAK;AAExD,WAAAN,EAAgB,QAAQ,iBAAiB,aAAae,GAAmB;AAAA,MACvE,SAASrB;AAAA,MACT,QAAAoB;AAAA,IAAA,CACD,GAEM,MAAM;AACX,MAAAZ,EAAyB,SAAS,MAAA,GAClCC,EAAiB,UAAU;AAAA,IAC7B;AAAA,EACF,GAAG,CAACJ,GAAWL,GAAcU,CAAe,CAAC;AAC/C;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-double-tap.types.js","sources":["../../src/use-double-tap/use-double-tap.types.ts"],"sourcesContent":["export const DoubleTapEventPointerTypes = {\n Touch: \"touch\",\n Mouse: \"mouse\",\n Pen: \"pen\",\n} as const;\n\nexport type DoubleTapEventPointerType =\n (typeof DoubleTapEventPointerTypes)[keyof typeof DoubleTapEventPointerTypes];\n\nexport interface DoubleTapData {\n x: number;\n y: number;\n}\n\nexport interface DoubleTapOptions {\n eventPointerTypes: DoubleTapEventPointerType[];\n eventCapture: boolean;\n eventOnce: boolean;\n eventStopImmediatePropagation: boolean;\n delay: number;\n threshold: number;\n container: { current: EventTarget | null };\n}\n\nexport type UseDoubleTapCallback =\n | ((event: PointerEvent, data: DoubleTapData) => boolean)\n | ((event: PointerEvent, data: DoubleTapData) => void);\n\nexport type UseDoubleTapOptions = Partial<DoubleTapOptions>;\n"],"names":["DoubleTapEventPointerTypes"],"mappings":"AAAO,MAAMA,IAA6B;AAAA,EACxC,OAAO;AAAA,EACP,OAAO;AAAA,EACP,KAAK;AACP;"}
|