@msobiecki/react-marauders-path 1.29.0 → 1.30.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 +99 -16
- package/dist/index.d.ts +98 -8
- package/dist/index.js +39 -29
- package/dist/index.js.map +1 -1
- package/dist/use-double-tap/event-guards.js +7 -0
- package/dist/use-double-tap/event-guards.js.map +1 -0
- package/dist/use-double-tap/use-double-tap.js +32 -26
- package/dist/use-double-tap/use-double-tap.js.map +1 -1
- package/dist/use-drag/event-guards.js +7 -0
- package/dist/use-drag/event-guards.js.map +1 -0
- package/dist/use-drag/use-drag.js +72 -53
- package/dist/use-drag/use-drag.js.map +1 -1
- package/dist/use-drag/use-drag.types.js.map +1 -1
- package/dist/use-key/event-guards.js +1 -1
- package/dist/use-key/event-guards.js.map +1 -1
- package/dist/use-key/use-key.js +48 -51
- package/dist/use-key/use-key.js.map +1 -1
- package/dist/use-key/use-key.types.js.map +1 -1
- package/dist/use-mouse/use-mouse.js +100 -0
- package/dist/use-mouse/use-mouse.js.map +1 -0
- package/dist/use-mouse/use-mouse.types.js +23 -0
- package/dist/use-mouse/use-mouse.types.js.map +1 -0
- package/dist/use-pinch/event-guards.js +7 -0
- package/dist/use-pinch/event-guards.js.map +1 -0
- package/dist/use-pinch/use-pinch.js +93 -70
- package/dist/use-pinch/use-pinch.js.map +1 -1
- package/dist/use-pinch/use-pinch.types.js.map +1 -1
- package/dist/use-pointer/event-guards.js +7 -0
- package/dist/use-pointer/event-guards.js.map +1 -0
- package/dist/use-pointer/invoke-pointer-action.js +7 -0
- package/dist/use-pointer/invoke-pointer-action.js.map +1 -0
- package/dist/use-pointer/use-pointer.js +74 -0
- package/dist/use-pointer/use-pointer.js.map +1 -0
- package/dist/use-pointer/use-pointer.types.js +19 -0
- package/dist/use-pointer/use-pointer.types.js.map +1 -0
- package/dist/use-press/event-guards.js +7 -0
- package/dist/use-press/event-guards.js.map +1 -0
- package/dist/use-press/use-press.js +83 -57
- package/dist/use-press/use-press.js.map +1 -1
- package/dist/use-swipe/event-guards.js +7 -0
- package/dist/use-swipe/event-guards.js.map +1 -0
- package/dist/use-swipe/use-swipe.js +81 -62
- package/dist/use-swipe/use-swipe.js.map +1 -1
- package/dist/use-swipe/use-swipe.types.js.map +1 -1
- package/dist/use-tap/event-guards.js +7 -0
- package/dist/use-tap/event-guards.js.map +1 -0
- package/dist/use-tap/use-tap.js +66 -48
- package/dist/use-tap/use-tap.js.map +1 -1
- package/dist/use-wheel/use-wheel.js +1 -1
- package/dist/use-wheel/use-wheel.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,42 +1,50 @@
|
|
|
1
|
-
import { useRef as
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import { useRef as o, useCallback as u, useEffect as M } from "react";
|
|
2
|
+
import { DragEventPointerTypes as E } from "./use-drag.types.js";
|
|
3
|
+
import { invokeDragAction as A } from "./invoke-drag-action.js";
|
|
4
|
+
import { shouldHandleEvent as Y } from "./event-guards.js";
|
|
5
|
+
const F = {
|
|
6
|
+
eventPointerTypes: [
|
|
7
|
+
E.Touch,
|
|
8
|
+
E.Mouse,
|
|
9
|
+
E.Pen
|
|
10
|
+
],
|
|
5
11
|
eventCapture: !1,
|
|
6
12
|
eventOnce: !1,
|
|
7
13
|
eventStopImmediatePropagation: !1,
|
|
8
14
|
threshold: 0,
|
|
9
15
|
container: { current: null },
|
|
10
16
|
raf: !1
|
|
11
|
-
},
|
|
17
|
+
}, j = (f, C = {}) => {
|
|
12
18
|
const {
|
|
13
19
|
eventPointerTypes: r,
|
|
14
|
-
eventCapture:
|
|
20
|
+
eventCapture: c,
|
|
15
21
|
eventOnce: p,
|
|
16
22
|
eventStopImmediatePropagation: d,
|
|
17
|
-
threshold:
|
|
18
|
-
container:
|
|
19
|
-
raf:
|
|
20
|
-
} = { ...
|
|
23
|
+
threshold: g,
|
|
24
|
+
container: D,
|
|
25
|
+
raf: L
|
|
26
|
+
} = { ...F, ...C }, a = o(null), s = o(null), i = o(null), h = o(null), v = o(null), l = o({
|
|
21
27
|
startX: 0,
|
|
22
28
|
startY: 0,
|
|
23
29
|
lastX: 0,
|
|
24
30
|
lastY: 0,
|
|
25
31
|
startTime: 0,
|
|
26
32
|
active: !1
|
|
27
|
-
}), T =
|
|
28
|
-
|
|
29
|
-
const t =
|
|
30
|
-
!t || !e || (
|
|
33
|
+
}), T = u(() => {
|
|
34
|
+
i.current = null;
|
|
35
|
+
const t = h.current, e = v.current;
|
|
36
|
+
!t || !e || (A(e, t, f, {
|
|
31
37
|
stopImmediate: d,
|
|
32
38
|
once: p,
|
|
33
39
|
onOnce: () => {
|
|
34
|
-
|
|
40
|
+
s.current?.abort();
|
|
35
41
|
}
|
|
36
|
-
}),
|
|
37
|
-
}, [f, d, p]),
|
|
42
|
+
}), h.current = null, v.current = null);
|
|
43
|
+
}, [f, d, p]), R = u(
|
|
38
44
|
(t) => {
|
|
39
|
-
|
|
45
|
+
Y(t, {
|
|
46
|
+
eventPointerTypes: r
|
|
47
|
+
}) && (l.current = {
|
|
40
48
|
startX: t.clientX,
|
|
41
49
|
startY: t.clientY,
|
|
42
50
|
lastX: t.clientX,
|
|
@@ -46,94 +54,105 @@ const I = {
|
|
|
46
54
|
});
|
|
47
55
|
},
|
|
48
56
|
[r]
|
|
49
|
-
),
|
|
57
|
+
), w = u(
|
|
50
58
|
(t) => {
|
|
51
|
-
|
|
52
|
-
|
|
59
|
+
if (!Y(t, {
|
|
60
|
+
eventPointerTypes: r
|
|
61
|
+
}))
|
|
53
62
|
return;
|
|
54
|
-
const
|
|
55
|
-
if (
|
|
63
|
+
const e = l.current;
|
|
64
|
+
if (!e.active)
|
|
56
65
|
return;
|
|
57
|
-
const
|
|
66
|
+
const m = t.clientX - e.startX, X = t.clientY - e.startY, P = t.clientX - e.lastX, n = t.clientY - e.lastY;
|
|
67
|
+
if (Math.hypot(m, X) < g)
|
|
68
|
+
return;
|
|
69
|
+
const I = Date.now() - e.startTime, y = {
|
|
58
70
|
deltaX: m,
|
|
59
71
|
deltaY: X,
|
|
60
|
-
movementX:
|
|
72
|
+
movementX: P,
|
|
61
73
|
movementY: n,
|
|
62
|
-
duration:
|
|
74
|
+
duration: I,
|
|
63
75
|
startX: e.startX,
|
|
64
76
|
startY: e.startY,
|
|
65
77
|
endX: t.clientX,
|
|
66
78
|
endY: t.clientY
|
|
67
79
|
};
|
|
68
|
-
if (e.lastX = t.clientX, e.lastY = t.clientY, !
|
|
69
|
-
|
|
80
|
+
if (e.lastX = t.clientX, e.lastY = t.clientY, !L) {
|
|
81
|
+
A(t, y, f, {
|
|
70
82
|
stopImmediate: d,
|
|
71
83
|
once: p,
|
|
72
84
|
onOnce: () => {
|
|
73
|
-
|
|
85
|
+
s.current?.abort();
|
|
74
86
|
}
|
|
75
87
|
});
|
|
76
88
|
return;
|
|
77
89
|
}
|
|
78
|
-
|
|
90
|
+
h.current = y, v.current = t, i.current === null && (i.current = requestAnimationFrame(T));
|
|
79
91
|
},
|
|
80
92
|
[
|
|
81
93
|
r,
|
|
82
|
-
v,
|
|
83
|
-
E,
|
|
84
|
-
f,
|
|
85
94
|
d,
|
|
86
95
|
p,
|
|
96
|
+
g,
|
|
97
|
+
L,
|
|
98
|
+
f,
|
|
87
99
|
T
|
|
88
100
|
]
|
|
89
|
-
),
|
|
101
|
+
), O = u(
|
|
102
|
+
(t) => {
|
|
103
|
+
Y(t, {
|
|
104
|
+
eventPointerTypes: r
|
|
105
|
+
}) && (l.current.active = !1);
|
|
106
|
+
},
|
|
107
|
+
[r]
|
|
108
|
+
), b = u(
|
|
90
109
|
(t) => {
|
|
91
|
-
|
|
110
|
+
Y(t, {
|
|
111
|
+
eventPointerTypes: r
|
|
112
|
+
}) && (l.current.active = !1);
|
|
92
113
|
},
|
|
93
114
|
[r]
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
a.current = y?.current ?? globalThis, i.current = new AbortController();
|
|
99
|
-
const { signal: t } = i.current, e = (n) => n instanceof PointerEvent && L(n), m = (n) => n instanceof PointerEvent && g(n), X = (n) => n instanceof PointerEvent && D(n), h = () => R();
|
|
115
|
+
);
|
|
116
|
+
M(() => {
|
|
117
|
+
a.current = D?.current ?? globalThis, s.current = new AbortController();
|
|
118
|
+
const { signal: t } = s.current, e = (n) => n instanceof PointerEvent && R(n), m = (n) => n instanceof PointerEvent && w(n), X = (n) => n instanceof PointerEvent && O(n), P = (n) => n instanceof PointerEvent && b(n);
|
|
100
119
|
return a.current.addEventListener(
|
|
101
120
|
"pointerdown",
|
|
102
121
|
e,
|
|
103
122
|
{
|
|
104
|
-
capture:
|
|
123
|
+
capture: c,
|
|
105
124
|
signal: t
|
|
106
125
|
}
|
|
107
126
|
), a.current.addEventListener(
|
|
108
127
|
"pointermove",
|
|
109
128
|
m,
|
|
110
129
|
{
|
|
111
|
-
capture:
|
|
130
|
+
capture: c,
|
|
112
131
|
signal: t
|
|
113
132
|
}
|
|
114
133
|
), a.current.addEventListener("pointerup", X, {
|
|
115
|
-
capture:
|
|
134
|
+
capture: c,
|
|
116
135
|
signal: t
|
|
117
136
|
}), a.current.addEventListener(
|
|
118
137
|
"pointercancel",
|
|
119
|
-
|
|
138
|
+
P,
|
|
120
139
|
{
|
|
121
|
-
capture:
|
|
140
|
+
capture: c,
|
|
122
141
|
signal: t
|
|
123
142
|
}
|
|
124
143
|
), () => {
|
|
125
|
-
|
|
144
|
+
s.current?.abort(), l.current.active = !1, i.current !== null && cancelAnimationFrame(i.current);
|
|
126
145
|
};
|
|
127
146
|
}, [
|
|
128
|
-
y,
|
|
129
|
-
o,
|
|
130
|
-
L,
|
|
131
|
-
g,
|
|
132
147
|
D,
|
|
133
|
-
|
|
148
|
+
c,
|
|
149
|
+
R,
|
|
150
|
+
w,
|
|
151
|
+
O,
|
|
152
|
+
b
|
|
134
153
|
]);
|
|
135
154
|
};
|
|
136
155
|
export {
|
|
137
|
-
|
|
156
|
+
j as default
|
|
138
157
|
};
|
|
139
158
|
//# sourceMappingURL=use-drag.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-drag.js","sources":["../../src/use-drag/use-drag.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\nimport {\n DragState,\n DragData,\n UseDragCallback,\n UseDragOptions,\n DragOptions,\n DragEventPointerType,\n} from \"./use-drag.types\";\nimport { invokeDragAction } from \"./invoke-drag-action\";\n\nconst defaultOptions: DragOptions = {\n eventPointerTypes: [\"touch\", \"mouse\", \"pen\"],\n eventCapture: false,\n eventOnce: false,\n eventStopImmediatePropagation: false,\n threshold: 0,\n container: { current: null },\n raf: false,\n};\n\nconst useDrag = (\n dragCallback: UseDragCallback,\n options: UseDragOptions = {},\n) => {\n const {\n eventPointerTypes,\n eventCapture,\n eventOnce,\n eventStopImmediatePropagation,\n threshold,\n container,\n raf,\n } = { ...defaultOptions, ...options };\n\n const targetReference = useRef<EventTarget | null>(null);\n const abortControllerReference = useRef<AbortController | null>(null);\n\n const frameReference = useRef<number | null>(null);\n const pendingDataReference = useRef<DragData | null>(null);\n const pendingEventReference = useRef<PointerEvent | null>(null);\n\n const dragStateReference = useRef<DragState>({\n startX: 0,\n startY: 0,\n lastX: 0,\n lastY: 0,\n startTime: 0,\n active: false,\n });\n\n const flushFrame = useCallback(() => {\n frameReference.current = null;\n\n const data = pendingDataReference.current;\n const event = pendingEventReference.current;\n\n if (!data || !event) {\n return;\n }\n\n invokeDragAction(event, data, dragCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n\n pendingDataReference.current = null;\n pendingEventReference.current = null;\n }, [dragCallback, eventStopImmediatePropagation, eventOnce]);\n\n const handlePointerDown = useCallback(\n (event: PointerEvent) => {\n if (!event.isPrimary) {\n return;\n }\n\n if (\n !eventPointerTypes.includes(event.pointerType as DragEventPointerType)\n ) {\n return;\n }\n\n dragStateReference.current = {\n startX: event.clientX,\n startY: event.clientY,\n lastX: event.clientX,\n lastY: event.clientY,\n startTime: Date.now(),\n active: true,\n };\n },\n [eventPointerTypes],\n );\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n const state = dragStateReference.current;\n if (!state.active) {\n return;\n }\n if (!event.isPrimary) {\n return;\n }\n\n if (\n !eventPointerTypes.includes(event.pointerType as DragEventPointerType)\n ) {\n return;\n }\n\n const deltaX = event.clientX - state.startX;\n const deltaY = event.clientY - state.startY;\n\n const movementX = event.clientX - state.lastX;\n const movementY = event.clientY - state.lastY;\n\n const distance = Math.hypot(deltaX, deltaY);\n\n if (distance < threshold) {\n return;\n }\n\n const duration = Date.now() - state.startTime;\n\n const data: DragData = {\n deltaX,\n deltaY,\n movementX,\n movementY,\n duration,\n startX: state.startX,\n startY: state.startY,\n endX: event.clientX,\n endY: event.clientY,\n };\n\n state.lastX = event.clientX;\n state.lastY = event.clientY;\n\n if (!raf) {\n invokeDragAction(event, data, dragCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n return;\n }\n\n pendingDataReference.current = data;\n pendingEventReference.current = event;\n\n if (frameReference.current === null) {\n frameReference.current = requestAnimationFrame(flushFrame);\n }\n },\n [\n eventPointerTypes,\n threshold,\n raf,\n dragCallback,\n eventStopImmediatePropagation,\n eventOnce,\n flushFrame,\n ],\n );\n\n const handlePointerUp = useCallback(\n (event: PointerEvent) => {\n if (!event.isPrimary) {\n return;\n }\n\n if (\n !eventPointerTypes.includes(event.pointerType as DragEventPointerType)\n ) {\n return;\n }\n\n dragStateReference.current.active = false;\n },\n [eventPointerTypes],\n );\n\n const handlePointerCancel = useCallback(() => {\n dragStateReference.current.active = false;\n }, []);\n\n useEffect(() => {\n targetReference.current = container?.current ?? globalThis;\n abortControllerReference.current = new AbortController();\n const { signal } = abortControllerReference.current;\n\n const pointerDownListener = (event: Event) =>\n event instanceof PointerEvent && handlePointerDown(event);\n\n const pointerMoveListener = (event: Event) =>\n event instanceof PointerEvent && handlePointerMove(event);\n\n const pointerUpListener = (event: Event) =>\n event instanceof PointerEvent && handlePointerUp(event);\n\n const pointerCancelListener = () => handlePointerCancel();\n\n targetReference.current.addEventListener(\n \"pointerdown\",\n pointerDownListener,\n {\n capture: eventCapture,\n signal,\n },\n );\n\n targetReference.current.addEventListener(\n \"pointermove\",\n pointerMoveListener,\n {\n capture: eventCapture,\n signal,\n },\n );\n\n targetReference.current.addEventListener(\"pointerup\", pointerUpListener, {\n capture: eventCapture,\n signal,\n });\n\n targetReference.current.addEventListener(\n \"pointercancel\",\n pointerCancelListener,\n {\n capture: eventCapture,\n signal,\n },\n );\n\n return () => {\n abortControllerReference.current?.abort();\n\n dragStateReference.current.active = false;\n\n if (frameReference.current !== null) {\n cancelAnimationFrame(frameReference.current);\n }\n };\n }, [\n container,\n eventCapture,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n handlePointerCancel,\n ]);\n};\n\nexport default useDrag;\n"],"names":["defaultOptions","useDrag","dragCallback","options","eventPointerTypes","eventCapture","eventOnce","eventStopImmediatePropagation","threshold","container","raf","targetReference","useRef","abortControllerReference","frameReference","pendingDataReference","pendingEventReference","dragStateReference","flushFrame","useCallback","data","event","invokeDragAction","handlePointerDown","handlePointerMove","state","deltaX","deltaY","movementX","movementY","duration","handlePointerUp","handlePointerCancel","useEffect","signal","pointerDownListener","pointerMoveListener","pointerUpListener","pointerCancelListener"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-drag.js","sources":["../../src/use-drag/use-drag.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\nimport {\n DragState,\n DragData,\n DragOptions,\n DragEventPointerTypes,\n UseDragCallback,\n UseDragOptions,\n} from \"./use-drag.types\";\nimport { invokeDragAction } from \"./invoke-drag-action\";\nimport { shouldHandleEvent } from \"./event-guards\";\n\nconst defaultOptions: DragOptions = {\n eventPointerTypes: [\n DragEventPointerTypes.Touch,\n DragEventPointerTypes.Mouse,\n DragEventPointerTypes.Pen,\n ],\n eventCapture: false,\n eventOnce: false,\n eventStopImmediatePropagation: false,\n threshold: 0,\n container: { current: null },\n raf: false,\n};\n\nconst useDrag = (\n dragCallback: UseDragCallback,\n options: UseDragOptions = {},\n) => {\n const {\n eventPointerTypes,\n eventCapture,\n eventOnce,\n eventStopImmediatePropagation,\n threshold,\n container,\n raf,\n } = { ...defaultOptions, ...options };\n\n const targetReference = useRef<EventTarget | null>(null);\n const abortControllerReference = useRef<AbortController | null>(null);\n\n const frameReference = useRef<number | null>(null);\n const pendingDataReference = useRef<DragData | null>(null);\n const pendingEventReference = useRef<PointerEvent | null>(null);\n\n const dragStateReference = useRef<DragState>({\n startX: 0,\n startY: 0,\n lastX: 0,\n lastY: 0,\n startTime: 0,\n active: false,\n });\n\n const flushFrame = useCallback(() => {\n frameReference.current = null;\n\n const data = pendingDataReference.current;\n const event = pendingEventReference.current;\n\n if (!data || !event) {\n return;\n }\n\n invokeDragAction(event, data, dragCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n\n pendingDataReference.current = null;\n pendingEventReference.current = null;\n }, [dragCallback, eventStopImmediatePropagation, eventOnce]);\n\n const handlePointerDown = useCallback(\n (event: PointerEvent) => {\n if (\n !shouldHandleEvent(event, {\n eventPointerTypes,\n })\n ) {\n return;\n }\n\n dragStateReference.current = {\n startX: event.clientX,\n startY: event.clientY,\n lastX: event.clientX,\n lastY: event.clientY,\n startTime: Date.now(),\n active: true,\n };\n },\n [eventPointerTypes],\n );\n\n const handlePointerMove = useCallback(\n (event: PointerEvent) => {\n if (\n !shouldHandleEvent(event, {\n eventPointerTypes,\n })\n ) {\n return;\n }\n\n const state = dragStateReference.current;\n if (!state.active) {\n return;\n }\n\n const deltaX = event.clientX - state.startX;\n const deltaY = event.clientY - state.startY;\n\n const movementX = event.clientX - state.lastX;\n const movementY = event.clientY - state.lastY;\n\n const distance = Math.hypot(deltaX, deltaY);\n\n if (distance < threshold) {\n return;\n }\n\n const duration = Date.now() - state.startTime;\n\n const data: DragData = {\n deltaX,\n deltaY,\n movementX,\n movementY,\n duration,\n startX: state.startX,\n startY: state.startY,\n endX: event.clientX,\n endY: event.clientY,\n };\n\n state.lastX = event.clientX;\n state.lastY = event.clientY;\n\n if (!raf) {\n invokeDragAction(event, data, dragCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n return;\n }\n\n pendingDataReference.current = data;\n pendingEventReference.current = event;\n\n if (frameReference.current === null) {\n frameReference.current = requestAnimationFrame(flushFrame);\n }\n },\n [\n eventPointerTypes,\n eventStopImmediatePropagation,\n eventOnce,\n threshold,\n raf,\n dragCallback,\n flushFrame,\n ],\n );\n\n const handlePointerUp = useCallback(\n (event: PointerEvent) => {\n if (\n !shouldHandleEvent(event, {\n eventPointerTypes,\n })\n ) {\n return;\n }\n\n dragStateReference.current.active = false;\n },\n [eventPointerTypes],\n );\n\n const handlePointerCancel = useCallback(\n (event: PointerEvent) => {\n if (\n !shouldHandleEvent(event, {\n eventPointerTypes,\n })\n ) {\n return;\n }\n\n dragStateReference.current.active = false;\n },\n [eventPointerTypes],\n );\n\n useEffect(() => {\n targetReference.current = container?.current ?? globalThis;\n abortControllerReference.current = new AbortController();\n const { signal } = abortControllerReference.current;\n\n const pointerDownListener = (event: Event) =>\n event instanceof PointerEvent && handlePointerDown(event);\n\n const pointerMoveListener = (event: Event) =>\n event instanceof PointerEvent && handlePointerMove(event);\n\n const pointerUpListener = (event: Event) =>\n event instanceof PointerEvent && handlePointerUp(event);\n\n const pointerCancelListener = (event: Event) =>\n event instanceof PointerEvent && handlePointerCancel(event);\n\n targetReference.current.addEventListener(\n \"pointerdown\",\n pointerDownListener,\n {\n capture: eventCapture,\n signal,\n },\n );\n\n targetReference.current.addEventListener(\n \"pointermove\",\n pointerMoveListener,\n {\n capture: eventCapture,\n signal,\n },\n );\n\n targetReference.current.addEventListener(\"pointerup\", pointerUpListener, {\n capture: eventCapture,\n signal,\n });\n\n targetReference.current.addEventListener(\n \"pointercancel\",\n pointerCancelListener,\n {\n capture: eventCapture,\n signal,\n },\n );\n\n return () => {\n abortControllerReference.current?.abort();\n\n dragStateReference.current.active = false;\n\n if (frameReference.current !== null) {\n cancelAnimationFrame(frameReference.current);\n }\n };\n }, [\n container,\n eventCapture,\n handlePointerDown,\n handlePointerMove,\n handlePointerUp,\n handlePointerCancel,\n ]);\n};\n\nexport default useDrag;\n"],"names":["defaultOptions","DragEventPointerTypes","useDrag","dragCallback","options","eventPointerTypes","eventCapture","eventOnce","eventStopImmediatePropagation","threshold","container","raf","targetReference","useRef","abortControllerReference","frameReference","pendingDataReference","pendingEventReference","dragStateReference","flushFrame","useCallback","data","event","invokeDragAction","handlePointerDown","shouldHandleEvent","handlePointerMove","state","deltaX","deltaY","movementX","movementY","duration","handlePointerUp","handlePointerCancel","useEffect","signal","pointerDownListener","pointerMoveListener","pointerUpListener","pointerCancelListener"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-drag.types.js","sources":["../../src/use-drag/use-drag.types.ts"],"sourcesContent":["export interface DragState {\n startX: number;\n startY: number;\n lastX: number;\n lastY: number;\n startTime: number;\n active: boolean;\n}\n\nexport const DragEventPointerTypes = {\n Touch: \"touch\",\n Mouse: \"mouse\",\n Pen: \"pen\",\n} as const;\n\nexport type DragEventPointerType =\n (typeof DragEventPointerTypes)[keyof typeof DragEventPointerTypes];\n\nexport interface DragData {\n deltaX: number;\n deltaY: number;\n movementX: number;\n movementY: number;\n duration: number;\n startX: number;\n startY: number;\n endX: number;\n endY: number;\n}\n\nexport interface DragOptions {\n eventPointerTypes: DragEventPointerType[];\n eventCapture: boolean;\n eventOnce: boolean;\n eventStopImmediatePropagation: boolean;\n threshold: number;\n container: { current:
|
|
1
|
+
{"version":3,"file":"use-drag.types.js","sources":["../../src/use-drag/use-drag.types.ts"],"sourcesContent":["export interface DragState {\n startX: number;\n startY: number;\n lastX: number;\n lastY: number;\n startTime: number;\n active: boolean;\n}\n\nexport const DragEventPointerTypes = {\n Touch: \"touch\",\n Mouse: \"mouse\",\n Pen: \"pen\",\n} as const;\n\nexport type DragEventPointerType =\n (typeof DragEventPointerTypes)[keyof typeof DragEventPointerTypes];\n\nexport interface DragData {\n deltaX: number;\n deltaY: number;\n movementX: number;\n movementY: number;\n duration: number;\n startX: number;\n startY: number;\n endX: number;\n endY: number;\n}\n\nexport interface DragOptions {\n eventPointerTypes: DragEventPointerType[];\n eventCapture: boolean;\n eventOnce: boolean;\n eventStopImmediatePropagation: boolean;\n threshold: number;\n container: { current: EventTarget | null };\n raf: boolean;\n}\n\nexport type UseDragCallback =\n | ((event: PointerEvent, data: DragData) => boolean)\n | ((event: PointerEvent, data: DragData) => void);\n\nexport type UseDragOptions = Partial<DragOptions>;\n"],"names":["DragEventPointerTypes"],"mappings":"AASO,MAAMA,IAAwB;AAAA,EACnC,OAAO;AAAA,EACP,OAAO;AAAA,EACP,KAAK;AACP;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"event-guards.js","sources":["../../src/use-key/event-guards.ts"],"sourcesContent":["/**\n * Determines whether a keyboard event should be handled based on event options.\n *\n * @param {KeyboardEvent} event - The keyboard event to evaluate\n * @param {Object} options - Event handling options\n * @param {boolean} options.repeat - If true, repeated key presses are allowed\n * @returns {boolean} True if the event should be handled, false otherwise\n *\n * @example\n * const shouldHandle =
|
|
1
|
+
{"version":3,"file":"event-guards.js","sources":["../../src/use-key/event-guards.ts"],"sourcesContent":["/**\n * Determines whether a keyboard event should be handled based on event options.\n *\n * @param {KeyboardEvent} event - The keyboard event to evaluate\n * @param {Object} options - Event handling options\n * @param {boolean} options.repeat - If true, repeated key presses are allowed\n * @returns {boolean} True if the event should be handled, false otherwise\n *\n * @example\n * const shouldHandle = shouldHandleEvent(event, {\n * repeat: false\n * });\n */\nexport const shouldHandleEvent = (\n event: KeyboardEvent,\n options: {\n repeat: boolean;\n },\n) => {\n if (!options.repeat && event.repeat) {\n return false;\n }\n return true;\n};\n"],"names":["shouldHandleEvent","event","options"],"mappings":"AAaO,MAAMA,IAAoB,CAC/BC,GACAC,MAII,GAACA,EAAQ,UAAUD,EAAM;"}
|
package/dist/use-key/use-key.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { useRef as g, useCallback as c, useEffect as
|
|
1
|
+
import { useRef as g, useCallback as c, useEffect as N } from "react";
|
|
2
2
|
import { KeyEventTypes as w } from "./use-key.types.js";
|
|
3
|
-
import { parseKeySequences as
|
|
4
|
-
import { resetSequenceState as
|
|
3
|
+
import { parseKeySequences as j } from "./parse-key-sequences.js";
|
|
4
|
+
import { resetSequenceState as B, advanceSequenceState as U } from "./sequence-state.js";
|
|
5
5
|
import { invokeKeyAction as b } from "./invoke-key-action.js";
|
|
6
|
-
import {
|
|
6
|
+
import { shouldHandleEvent as F } from "./event-guards.js";
|
|
7
7
|
import { SPECIAL_KEYS as u } from "./normalize-key.js";
|
|
8
|
-
const
|
|
8
|
+
const H = {
|
|
9
9
|
eventType: w.KeyUp,
|
|
10
10
|
eventRepeat: !1,
|
|
11
11
|
eventCapture: !1,
|
|
@@ -14,69 +14,64 @@ const _ = {
|
|
|
14
14
|
sequenceThreshold: 1e3,
|
|
15
15
|
combinationThreshold: 200,
|
|
16
16
|
container: { current: null }
|
|
17
|
-
},
|
|
17
|
+
}, ee = (P, f, _ = H) => {
|
|
18
18
|
const {
|
|
19
19
|
eventType: d,
|
|
20
20
|
eventRepeat: R,
|
|
21
21
|
eventCapture: v,
|
|
22
22
|
eventOnce: m,
|
|
23
23
|
eventStopImmediatePropagation: p,
|
|
24
|
-
sequenceThreshold:
|
|
24
|
+
sequenceThreshold: T,
|
|
25
25
|
combinationThreshold: A,
|
|
26
26
|
container: C
|
|
27
|
-
} = { ...
|
|
27
|
+
} = { ...H, ..._ }, S = g(null), l = g(null), y = g({
|
|
28
28
|
activeKeys: /* @__PURE__ */ new Map()
|
|
29
29
|
}), a = g([]), L = c(() => {
|
|
30
30
|
y.current.activeKeys.clear();
|
|
31
31
|
}, []), i = c((e) => {
|
|
32
|
-
a.current =
|
|
32
|
+
a.current = B(
|
|
33
33
|
e,
|
|
34
34
|
a.current
|
|
35
35
|
);
|
|
36
|
-
}, []), D = c(
|
|
37
|
-
(e) => G(e, {
|
|
38
|
-
repeat: R
|
|
39
|
-
}),
|
|
40
|
-
[R]
|
|
41
|
-
), I = c((e) => {
|
|
36
|
+
}, []), D = c((e) => {
|
|
42
37
|
const t = e.key === " " ? u.SPACE : e.key;
|
|
43
38
|
y.current.activeKeys.set(t, {
|
|
44
39
|
pressedAt: Date.now()
|
|
45
40
|
});
|
|
46
|
-
}, []),
|
|
41
|
+
}, []), I = c((e) => {
|
|
47
42
|
const t = e.key === " " ? u.SPACE : e.key, r = y.current.activeKeys.get(t);
|
|
48
43
|
r && (r.releasedAt = Date.now());
|
|
49
|
-
}, []),
|
|
44
|
+
}, []), O = c(() => {
|
|
50
45
|
const e = Date.now(), t = y.current;
|
|
51
46
|
[...t.activeKeys.entries()].forEach(([r, s]) => {
|
|
52
47
|
d === w.KeyDown ? s.releasedAt && t.activeKeys.delete(r) : s.releasedAt && e - s.releasedAt > A && t.activeKeys.delete(r);
|
|
53
48
|
});
|
|
54
|
-
}, [d, A]),
|
|
49
|
+
}, [d, A]), K = c(
|
|
55
50
|
(e, t) => {
|
|
56
51
|
if (d === w.KeyDown)
|
|
57
52
|
return t.size === e.length && e.every((r) => r === u.ANY ? t.size > 0 : t.has(r));
|
|
58
53
|
if (d === w.KeyUp) {
|
|
59
54
|
const r = e.map((o) => {
|
|
60
55
|
if (o === u.ANY) {
|
|
61
|
-
const
|
|
62
|
-
return
|
|
56
|
+
const M = [...t.entries()].at(-1);
|
|
57
|
+
return M ? M[1] : void 0;
|
|
63
58
|
}
|
|
64
59
|
return t.get(o);
|
|
65
60
|
});
|
|
66
61
|
if (r.some((o) => !o?.releasedAt))
|
|
67
62
|
return !1;
|
|
68
|
-
const s = r.map((o) => o?.pressedAt).filter((o) => o !== void 0), n = r.map((o) => o?.releasedAt).filter((o) => o !== void 0), E = Math.min(...n),
|
|
69
|
-
return !(Math.max(...s) > E ||
|
|
63
|
+
const s = r.map((o) => o?.pressedAt).filter((o) => o !== void 0), n = r.map((o) => o?.releasedAt).filter((o) => o !== void 0), E = Math.min(...n), x = Math.max(...n);
|
|
64
|
+
return !(Math.max(...s) > E || x - E > A);
|
|
70
65
|
}
|
|
71
66
|
return !1;
|
|
72
67
|
},
|
|
73
68
|
[d, A]
|
|
74
|
-
),
|
|
69
|
+
), z = c(
|
|
75
70
|
(e, t) => {
|
|
76
71
|
const r = t.chord[0];
|
|
77
72
|
if (Array.isArray(r)) {
|
|
78
73
|
const { activeKeys: n } = y.current;
|
|
79
|
-
if (!
|
|
74
|
+
if (!K(r, n))
|
|
80
75
|
return;
|
|
81
76
|
b(e, t.key, f, {
|
|
82
77
|
stopImmediate: p,
|
|
@@ -100,19 +95,19 @@ const _ = {
|
|
|
100
95
|
p,
|
|
101
96
|
m,
|
|
102
97
|
f,
|
|
103
|
-
|
|
98
|
+
K
|
|
104
99
|
]
|
|
105
|
-
),
|
|
100
|
+
), k = c(
|
|
106
101
|
(e, t) => {
|
|
107
102
|
const r = t.chord[t.index];
|
|
108
103
|
if (Array.isArray(r)) {
|
|
109
|
-
const { activeKeys:
|
|
110
|
-
if (!
|
|
104
|
+
const { activeKeys: x } = y.current;
|
|
105
|
+
if (!K(r, x))
|
|
111
106
|
return;
|
|
112
|
-
const [h, o] =
|
|
107
|
+
const [h, o] = U(
|
|
113
108
|
t,
|
|
114
109
|
a.current,
|
|
115
|
-
|
|
110
|
+
T,
|
|
116
111
|
i
|
|
117
112
|
);
|
|
118
113
|
a.current = o, h.index === h.chord.length && (b(e, h.key, f, {
|
|
@@ -129,10 +124,10 @@ const _ = {
|
|
|
129
124
|
i(t);
|
|
130
125
|
return;
|
|
131
126
|
}
|
|
132
|
-
const [n, E] =
|
|
127
|
+
const [n, E] = U(
|
|
133
128
|
t,
|
|
134
129
|
a.current,
|
|
135
|
-
|
|
130
|
+
T,
|
|
136
131
|
i
|
|
137
132
|
);
|
|
138
133
|
a.current = E, n.index === n.chord.length && (b(e, n.key, f, {
|
|
@@ -146,36 +141,38 @@ const _ = {
|
|
|
146
141
|
[
|
|
147
142
|
m,
|
|
148
143
|
p,
|
|
149
|
-
|
|
144
|
+
T,
|
|
150
145
|
f,
|
|
151
146
|
i,
|
|
152
|
-
|
|
147
|
+
K
|
|
153
148
|
]
|
|
154
|
-
),
|
|
149
|
+
), q = c(
|
|
155
150
|
(e) => {
|
|
156
151
|
a.current.forEach((t) => {
|
|
157
|
-
t.chord.length === 1 ?
|
|
152
|
+
t.chord.length === 1 ? z(e, t) : k(e, t);
|
|
158
153
|
});
|
|
159
154
|
},
|
|
160
|
-
[
|
|
161
|
-
),
|
|
155
|
+
[z, k]
|
|
156
|
+
), Y = c(
|
|
162
157
|
(e) => {
|
|
163
|
-
|
|
158
|
+
F(e, {
|
|
159
|
+
repeat: R
|
|
160
|
+
}) && (O(), q(e));
|
|
164
161
|
},
|
|
165
|
-
[
|
|
162
|
+
[O, q, R]
|
|
166
163
|
);
|
|
167
|
-
|
|
168
|
-
a.current =
|
|
169
|
-
}, [
|
|
170
|
-
|
|
171
|
-
const { signal: e } = l.current, t = (n) =>
|
|
172
|
-
return
|
|
164
|
+
N(() => {
|
|
165
|
+
a.current = j(P);
|
|
166
|
+
}, [P]), N(() => {
|
|
167
|
+
S.current = C?.current ?? globalThis, l.current = new AbortController();
|
|
168
|
+
const { signal: e } = l.current, t = (n) => D(n), r = (n) => I(n), s = (n) => Y(n);
|
|
169
|
+
return S.current.addEventListener("keydown", t, {
|
|
173
170
|
capture: v,
|
|
174
171
|
signal: e
|
|
175
|
-
}),
|
|
172
|
+
}), S.current.addEventListener("keyup", r, {
|
|
176
173
|
capture: v,
|
|
177
174
|
signal: e
|
|
178
|
-
}),
|
|
175
|
+
}), S.current.addEventListener(d, s, {
|
|
179
176
|
capture: v,
|
|
180
177
|
signal: e
|
|
181
178
|
}), () => {
|
|
@@ -185,14 +182,14 @@ const _ = {
|
|
|
185
182
|
d,
|
|
186
183
|
v,
|
|
187
184
|
C,
|
|
185
|
+
D,
|
|
188
186
|
I,
|
|
189
|
-
|
|
190
|
-
M,
|
|
187
|
+
Y,
|
|
191
188
|
L,
|
|
192
189
|
i
|
|
193
190
|
]);
|
|
194
191
|
};
|
|
195
192
|
export {
|
|
196
|
-
|
|
193
|
+
ee as default
|
|
197
194
|
};
|
|
198
195
|
//# sourceMappingURL=use-key.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-key.js","sources":["../../src/use-key/use-key.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\n\nimport {\n KeyOptions,\n SequenceState,\n UseKeySchema,\n UseKeyCallback,\n UseKeyOptions,\n CombinationState,\n KeyEventTypes,\n} from \"./use-key.types\";\nimport { parseKeySequences } from \"./parse-key-sequences\";\nimport { advanceSequenceState, resetSequenceState } from \"./sequence-state\";\nimport { invokeKeyAction } from \"./invoke-key-action\";\nimport { shouldHandleKeyboardEvent } from \"./event-guards\";\nimport { SPECIAL_KEYS } from \"./normalize-key\";\n\nconst defaultOptions: KeyOptions = {\n eventType: KeyEventTypes.KeyUp,\n eventRepeat: false,\n eventCapture: false,\n eventOnce: false,\n eventStopImmediatePropagation: false,\n sequenceThreshold: 1000,\n combinationThreshold: 200,\n container: { current: null },\n};\n\n/**\n * React hook for handling keyboard events with support for key sequences and combinations.\n *\n * Enables listening for single key presses, key combinations, and sequential key presses.\n * Supports customizable options like event type, repeat handling, and one-time listeners.\n *\n * @template T - The callback function type\n * @param {UseKeySchema} key - Single key, combination, sequence, or array of patterns to listen for\n * @param {UseKeyCallback} keyCallback - Callback function invoked when key pattern matches\n * @param {UseKeyOptions} [options] - Configuration options for the hook\n * @param {KeyEventType} [options.eventType=KeyEventTypes.KeyUp] - Type of keyboard event ('keydown' or 'keyup')\n * @param {boolean} [options.eventRepeat=false] - Allow repeated key presses to trigger callback\n * @param {boolean} [options.eventCapture=false] - Use event capture phase instead of bubbling\n * @param {boolean} [options.eventOnce=false] - Trigger callback only once\n * @param {boolean} [options.eventStopImmediatePropagation=false] - Stop immediate propagation\n * @param {number} [options.sequenceThreshold=1000] - Timeout in ms between sequence keys\n * @param {number} [options.combinationThreshold=200] - Timeout in ms between combination keys\n * @param {RefObject<HTMLElement>} [options.container] - DOM element to attach listener to (default: window)\n *\n * @example\n * // Single key schema\n * useKey('a', (event, key) => console.log(`Pressed ${key}`));\n *\n * @example\n * // Multiple patterns of single key schema\n * useKey(['a', 'b', 'c'], (event, key) => console.log(`Pressed ${key}`));\n *\n * @example\n * // Combination key schema\n * useKey('a+b', (event, key) => {\n * console.log(`Pressed ${key}`);\n * });\n *\n * @example\n * // Multiple patterns of combination key schema\n * useKey(['a+b', 'c+d'], (event, key) => {\n * console.log(`Pressed ${key}`);\n * });\n *\n * @example\n * // Sequential key schema\n * useKey('ArrowUp ArrowUp ArrowDown ArrowDown', (event, key) => {\n * console.log(`Pressed ${key}`);\n * });\n *\n * @example\n * // Multiple patterns of sequential key schema\n * useKey(['ArrowUp ArrowUp ArrowDown ArrowDown', 'ArrowLeft ArrowRight'], (event, key) => {\n * console.log(`Pressed ${key}`);\n * });\n *\n * @example\n * // Using options to listen for a key on keydown event and stop propagation\n * useKey('Any', handleSubmit, {\n * eventType: KeyEventTypes.KeyDown,\n * eventStopImmediatePropagation: true,\n * container: inputRef\n * });\n *\n */\nconst useKey = (\n key: UseKeySchema,\n keyCallback: UseKeyCallback,\n options: UseKeyOptions = defaultOptions,\n) => {\n const {\n eventType,\n eventRepeat,\n eventCapture,\n eventOnce,\n eventStopImmediatePropagation,\n sequenceThreshold,\n combinationThreshold,\n container,\n } = { ...defaultOptions, ...options };\n\n const targetReference = useRef<EventTarget | null>(null);\n const abortControllerReference = useRef<AbortController | null>(null);\n\n const combinationReference = useRef<CombinationState>({\n activeKeys: new Map(),\n });\n const sequenceReference = useRef<SequenceState[]>([]);\n\n const resetCombination = useCallback(() => {\n combinationReference.current.activeKeys.clear();\n }, []);\n\n const resetSequence = useCallback((sequence: SequenceState) => {\n sequenceReference.current = resetSequenceState(\n sequence,\n sequenceReference.current,\n );\n }, []);\n\n const shouldProcessEvent = useCallback(\n (event: KeyboardEvent) => {\n return shouldHandleKeyboardEvent(event, {\n repeat: eventRepeat,\n });\n },\n [eventRepeat],\n );\n\n const registerKeyDown = useCallback((event: KeyboardEvent) => {\n const normalizedEventKey =\n event.key === \" \" ? SPECIAL_KEYS.SPACE : event.key;\n combinationReference.current.activeKeys.set(normalizedEventKey, {\n pressedAt: Date.now(),\n });\n }, []);\n\n const registerKeyUp = useCallback((event: KeyboardEvent) => {\n const normalizedEventKey =\n event.key === \" \" ? SPECIAL_KEYS.SPACE : event.key;\n const state =\n combinationReference.current.activeKeys.get(normalizedEventKey);\n if (state) state.releasedAt = Date.now();\n }, []);\n\n const cleanupCombinationKeys = useCallback(() => {\n const now = Date.now();\n const combo = combinationReference.current;\n\n [...combo.activeKeys.entries()].forEach(([key, state]) => {\n if (eventType === KeyEventTypes.KeyDown) {\n if (state.releasedAt) {\n combo.activeKeys.delete(key);\n }\n } else if (\n state.releasedAt &&\n now - state.releasedAt > combinationThreshold\n ) {\n combo.activeKeys.delete(key);\n }\n });\n }, [eventType, combinationThreshold]);\n\n const validateCombination = useCallback(\n (\n expectedKey: string[],\n activeKeys: Map<string, { pressedAt: number; releasedAt?: number }>,\n ): boolean => {\n if (eventType === KeyEventTypes.KeyDown) {\n return (\n activeKeys.size === expectedKey.length &&\n expectedKey.every((key) => {\n if (key === SPECIAL_KEYS.ANY) {\n return activeKeys.size > 0;\n }\n return activeKeys.has(key);\n })\n );\n }\n if (eventType === KeyEventTypes.KeyUp) {\n const keyStates = expectedKey.map((key) => {\n if (key === SPECIAL_KEYS.ANY) {\n const entries = [...activeKeys.entries()];\n const lastEntry = entries.at(-1);\n return lastEntry ? lastEntry[1] : undefined;\n }\n return activeKeys.get(key);\n });\n\n if (keyStates.some((state) => !state?.releasedAt)) {\n return false;\n }\n\n const pressedTimes: number[] = keyStates\n .map((state) => state?.pressedAt)\n .filter((value): value is number => value !== undefined);\n const releasedTimes: number[] = keyStates\n .map((state) => state?.releasedAt)\n .filter((value): value is number => value !== undefined);\n\n const minReleased = Math.min(...releasedTimes);\n const maxReleased = Math.max(...releasedTimes);\n const maxPressed = Math.max(...pressedTimes);\n\n if (maxPressed > minReleased) {\n return false;\n }\n\n if (maxReleased - minReleased > combinationThreshold) {\n return false;\n }\n\n return true;\n }\n\n return false;\n },\n [eventType, combinationThreshold],\n );\n\n const handleSingleKey = useCallback(\n (event: KeyboardEvent, sequence: SequenceState) => {\n const expectedKey = sequence.chord[0];\n\n if (Array.isArray(expectedKey)) {\n const { activeKeys } = combinationReference.current;\n\n if (!validateCombination(expectedKey, activeKeys)) {\n return;\n }\n\n invokeKeyAction(event, sequence.key, keyCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n\n return;\n }\n\n const normalizedEventKey =\n event.key === \" \" ? SPECIAL_KEYS.SPACE : event.key;\n if (\n expectedKey !== SPECIAL_KEYS.ANY &&\n expectedKey !== normalizedEventKey\n ) {\n return;\n }\n\n invokeKeyAction(event, sequence.key, keyCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n },\n [\n eventStopImmediatePropagation,\n eventOnce,\n keyCallback,\n validateCombination,\n ],\n );\n\n const handleSequenceStep = useCallback(\n (event: KeyboardEvent, sequence: SequenceState) => {\n const expectedKey = sequence.chord[sequence.index];\n\n if (Array.isArray(expectedKey)) {\n const { activeKeys } = combinationReference.current;\n\n if (!validateCombination(expectedKey, activeKeys)) {\n return;\n }\n\n const [updatedSequence, updatedSequences] = advanceSequenceState(\n sequence,\n sequenceReference.current,\n sequenceThreshold,\n resetSequence,\n );\n sequenceReference.current = updatedSequences;\n\n if (updatedSequence.index === updatedSequence.chord.length) {\n invokeKeyAction(event, updatedSequence.key, keyCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n\n resetSequence(updatedSequence);\n }\n\n return;\n }\n\n const normalizedEventKey =\n event.key === \" \" ? SPECIAL_KEYS.SPACE : event.key;\n if (\n expectedKey !== SPECIAL_KEYS.ANY &&\n expectedKey !== normalizedEventKey\n ) {\n resetSequence(sequence);\n return;\n }\n\n const [updatedSequence, updatedSequences] = advanceSequenceState(\n sequence,\n sequenceReference.current,\n sequenceThreshold,\n resetSequence,\n );\n sequenceReference.current = updatedSequences;\n\n if (updatedSequence.index === updatedSequence.chord.length) {\n invokeKeyAction(event, updatedSequence.key, keyCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n\n resetSequence(updatedSequence);\n }\n },\n [\n eventOnce,\n eventStopImmediatePropagation,\n sequenceThreshold,\n keyCallback,\n resetSequence,\n validateCombination,\n ],\n );\n\n const evaluateSequences = useCallback(\n (event: KeyboardEvent) => {\n sequenceReference.current.forEach((sequence) => {\n if (sequence.chord.length === 1) {\n handleSingleKey(event, sequence);\n } else {\n handleSequenceStep(event, sequence);\n }\n });\n },\n [handleSingleKey, handleSequenceStep],\n );\n\n const handleEventListener = useCallback(\n (event: KeyboardEvent) => {\n if (!shouldProcessEvent(event)) {\n return;\n }\n\n cleanupCombinationKeys();\n evaluateSequences(event);\n },\n [shouldProcessEvent, cleanupCombinationKeys, evaluateSequences],\n );\n\n useEffect(() => {\n sequenceReference.current = parseKeySequences(key);\n }, [key]);\n\n useEffect(() => {\n targetReference.current = container?.current ?? globalThis;\n abortControllerReference.current = new AbortController();\n const { signal } = abortControllerReference.current;\n\n const keyDownListener = (event: Event) =>\n registerKeyDown(event as KeyboardEvent);\n\n const keyUpListener = (event: Event) =>\n registerKeyUp(event as KeyboardEvent);\n\n const eventListener = (event: Event) =>\n handleEventListener(event as KeyboardEvent);\n\n targetReference.current.addEventListener(\"keydown\", keyDownListener, {\n capture: eventCapture,\n signal,\n });\n\n targetReference.current.addEventListener(\"keyup\", keyUpListener, {\n capture: eventCapture,\n signal,\n });\n\n targetReference.current.addEventListener(eventType, eventListener, {\n capture: eventCapture,\n signal,\n });\n\n return () => {\n abortControllerReference.current?.abort();\n\n resetCombination();\n sequenceReference.current.forEach((sequence) => resetSequence(sequence));\n };\n }, [\n eventType,\n eventCapture,\n container,\n registerKeyDown,\n registerKeyUp,\n handleEventListener,\n resetCombination,\n resetSequence,\n ]);\n};\n\nexport default useKey;\n"],"names":["defaultOptions","KeyEventTypes","useKey","key","keyCallback","options","eventType","eventRepeat","eventCapture","eventOnce","eventStopImmediatePropagation","sequenceThreshold","combinationThreshold","container","targetReference","useRef","abortControllerReference","combinationReference","sequenceReference","resetCombination","useCallback","resetSequence","sequence","resetSequenceState","shouldProcessEvent","event","shouldHandleKeyboardEvent","registerKeyDown","normalizedEventKey","SPECIAL_KEYS","registerKeyUp","state","cleanupCombinationKeys","now","combo","validateCombination","expectedKey","activeKeys","keyStates","lastEntry","pressedTimes","value","releasedTimes","minReleased","maxReleased","handleSingleKey","invokeKeyAction","handleSequenceStep","updatedSequence","updatedSequences","advanceSequenceState","evaluateSequences","handleEventListener","useEffect","parseKeySequences","signal","keyDownListener","keyUpListener","eventListener"],"mappings":";;;;;;;AAiBA,MAAMA,IAA6B;AAAA,EACjC,WAAWC,EAAc;AAAA,EACzB,aAAa;AAAA,EACb,cAAc;AAAA,EACd,WAAW;AAAA,EACX,+BAA+B;AAAA,EAC/B,mBAAmB;AAAA,EACnB,sBAAsB;AAAA,EACtB,WAAW,EAAE,SAAS,KAAA;AACxB,GA8DMC,KAAS,CACbC,GACAC,GACAC,IAAyBL,MACtB;AACH,QAAM;AAAA,IACJ,WAAAM;AAAA,IACA,aAAAC;AAAA,IACA,cAAAC;AAAA,IACA,WAAAC;AAAA,IACA,+BAAAC;AAAA,IACA,mBAAAC;AAAA,IACA,sBAAAC;AAAA,IACA,WAAAC;AAAA,EAAA,IACE,EAAE,GAAGb,GAAgB,GAAGK,EAAA,GAEtBS,IAAkBC,EAA2B,IAAI,GACjDC,IAA2BD,EAA+B,IAAI,GAE9DE,IAAuBF,EAAyB;AAAA,IACpD,gCAAgB,IAAA;AAAA,EAAI,CACrB,GACKG,IAAoBH,EAAwB,EAAE,GAE9CI,IAAmBC,EAAY,MAAM;AACzC,IAAAH,EAAqB,QAAQ,WAAW,MAAA;AAAA,EAC1C,GAAG,CAAA,CAAE,GAECI,IAAgBD,EAAY,CAACE,MAA4B;AAC7D,IAAAJ,EAAkB,UAAUK;AAAA,MAC1BD;AAAA,MACAJ,EAAkB;AAAA,IAAA;AAAA,EAEtB,GAAG,CAAA,CAAE,GAECM,IAAqBJ;AAAA,IACzB,CAACK,MACQC,EAA0BD,GAAO;AAAA,MACtC,QAAQlB;AAAA,IAAA,CACT;AAAA,IAEH,CAACA,CAAW;AAAA,EAAA,GAGRoB,IAAkBP,EAAY,CAACK,MAAyB;AAC5D,UAAMG,IACJH,EAAM,QAAQ,MAAMI,EAAa,QAAQJ,EAAM;AACjD,IAAAR,EAAqB,QAAQ,WAAW,IAAIW,GAAoB;AAAA,MAC9D,WAAW,KAAK,IAAA;AAAA,IAAI,CACrB;AAAA,EACH,GAAG,CAAA,CAAE,GAECE,IAAgBV,EAAY,CAACK,MAAyB;AAC1D,UAAMG,IACJH,EAAM,QAAQ,MAAMI,EAAa,QAAQJ,EAAM,KAC3CM,IACJd,EAAqB,QAAQ,WAAW,IAAIW,CAAkB;AAChE,IAAIG,MAAOA,EAAM,aAAa,KAAK,IAAA;AAAA,EACrC,GAAG,CAAA,CAAE,GAECC,IAAyBZ,EAAY,MAAM;AAC/C,UAAMa,IAAM,KAAK,IAAA,GACXC,IAAQjB,EAAqB;AAEnC,KAAC,GAAGiB,EAAM,WAAW,QAAA,CAAS,EAAE,QAAQ,CAAC,CAAC/B,GAAK4B,CAAK,MAAM;AACxD,MAAIzB,MAAcL,EAAc,UAC1B8B,EAAM,cACRG,EAAM,WAAW,OAAO/B,CAAG,IAG7B4B,EAAM,cACNE,IAAMF,EAAM,aAAanB,KAEzBsB,EAAM,WAAW,OAAO/B,CAAG;AAAA,IAE/B,CAAC;AAAA,EACH,GAAG,CAACG,GAAWM,CAAoB,CAAC,GAE9BuB,IAAsBf;AAAA,IAC1B,CACEgB,GACAC,MACY;AACZ,UAAI/B,MAAcL,EAAc;AAC9B,eACEoC,EAAW,SAASD,EAAY,UAChCA,EAAY,MAAM,CAACjC,MACbA,MAAQ0B,EAAa,MAChBQ,EAAW,OAAO,IAEpBA,EAAW,IAAIlC,CAAG,CAC1B;AAGL,UAAIG,MAAcL,EAAc,OAAO;AACrC,cAAMqC,IAAYF,EAAY,IAAI,CAACjC,MAAQ;AACzC,cAAIA,MAAQ0B,EAAa,KAAK;AAE5B,kBAAMU,IADU,CAAC,GAAGF,EAAW,SAAS,EACd,GAAG,EAAE;AAC/B,mBAAOE,IAAYA,EAAU,CAAC,IAAI;AAAA,UACpC;AACA,iBAAOF,EAAW,IAAIlC,CAAG;AAAA,QAC3B,CAAC;AAED,YAAImC,EAAU,KAAK,CAACP,MAAU,CAACA,GAAO,UAAU;AAC9C,iBAAO;AAGT,cAAMS,IAAyBF,EAC5B,IAAI,CAACP,MAAUA,GAAO,SAAS,EAC/B,OAAO,CAACU,MAA2BA,MAAU,MAAS,GACnDC,IAA0BJ,EAC7B,IAAI,CAACP,MAAUA,GAAO,UAAU,EAChC,OAAO,CAACU,MAA2BA,MAAU,MAAS,GAEnDE,IAAc,KAAK,IAAI,GAAGD,CAAa,GACvCE,IAAc,KAAK,IAAI,GAAGF,CAAa;AAO7C,eAJI,EAFe,KAAK,IAAI,GAAGF,CAAY,IAE1BG,KAIbC,IAAcD,IAAc/B;AAAA,MAKlC;AAEA,aAAO;AAAA,IACT;AAAA,IACA,CAACN,GAAWM,CAAoB;AAAA,EAAA,GAG5BiC,IAAkBzB;AAAA,IACtB,CAACK,GAAsBH,MAA4B;AACjD,YAAMc,IAAcd,EAAS,MAAM,CAAC;AAEpC,UAAI,MAAM,QAAQc,CAAW,GAAG;AAC9B,cAAM,EAAE,YAAAC,MAAepB,EAAqB;AAE5C,YAAI,CAACkB,EAAoBC,GAAaC,CAAU;AAC9C;AAGF,QAAAS,EAAgBrB,GAAOH,EAAS,KAAKlB,GAAa;AAAA,UAChD,eAAeM;AAAA,UACf,MAAMD;AAAA,UACN,QAAQ,MAAM;AACZ,YAAAO,EAAyB,SAAS,MAAA;AAAA,UACpC;AAAA,QAAA,CACD;AAED;AAAA,MACF;AAEA,YAAMY,IACJH,EAAM,QAAQ,MAAMI,EAAa,QAAQJ,EAAM;AACjD,MACEW,MAAgBP,EAAa,OAC7BO,MAAgBR,KAKlBkB,EAAgBrB,GAAOH,EAAS,KAAKlB,GAAa;AAAA,QAChD,eAAeM;AAAA,QACf,MAAMD;AAAA,QACN,QAAQ,MAAM;AACZ,UAAAO,EAAyB,SAAS,MAAA;AAAA,QACpC;AAAA,MAAA,CACD;AAAA,IACH;AAAA,IACA;AAAA,MACEN;AAAA,MACAD;AAAA,MACAL;AAAA,MACA+B;AAAA,IAAA;AAAA,EACF,GAGIY,IAAqB3B;AAAA,IACzB,CAACK,GAAsBH,MAA4B;AACjD,YAAMc,IAAcd,EAAS,MAAMA,EAAS,KAAK;AAEjD,UAAI,MAAM,QAAQc,CAAW,GAAG;AAC9B,cAAM,EAAE,YAAAC,MAAepB,EAAqB;AAE5C,YAAI,CAACkB,EAAoBC,GAAaC,CAAU;AAC9C;AAGF,cAAM,CAACW,GAAiBC,CAAgB,IAAIC;AAAA,UAC1C5B;AAAA,UACAJ,EAAkB;AAAA,UAClBP;AAAA,UACAU;AAAA,QAAA;AAEF,QAAAH,EAAkB,UAAU+B,GAExBD,EAAgB,UAAUA,EAAgB,MAAM,WAClDF,EAAgBrB,GAAOuB,EAAgB,KAAK5C,GAAa;AAAA,UACvD,eAAeM;AAAA,UACf,MAAMD;AAAA,UACN,QAAQ,MAAM;AACZ,YAAAO,EAAyB,SAAS,MAAA;AAAA,UACpC;AAAA,QAAA,CACD,GAEDK,EAAc2B,CAAe;AAG/B;AAAA,MACF;AAEA,YAAMpB,IACJH,EAAM,QAAQ,MAAMI,EAAa,QAAQJ,EAAM;AACjD,UACEW,MAAgBP,EAAa,OAC7BO,MAAgBR,GAChB;AACA,QAAAP,EAAcC,CAAQ;AACtB;AAAA,MACF;AAEA,YAAM,CAAC0B,GAAiBC,CAAgB,IAAIC;AAAA,QAC1C5B;AAAA,QACAJ,EAAkB;AAAA,QAClBP;AAAA,QACAU;AAAA,MAAA;AAEF,MAAAH,EAAkB,UAAU+B,GAExBD,EAAgB,UAAUA,EAAgB,MAAM,WAClDF,EAAgBrB,GAAOuB,EAAgB,KAAK5C,GAAa;AAAA,QACvD,eAAeM;AAAA,QACf,MAAMD;AAAA,QACN,QAAQ,MAAM;AACZ,UAAAO,EAAyB,SAAS,MAAA;AAAA,QACpC;AAAA,MAAA,CACD,GAEDK,EAAc2B,CAAe;AAAA,IAEjC;AAAA,IACA;AAAA,MACEvC;AAAA,MACAC;AAAA,MACAC;AAAA,MACAP;AAAA,MACAiB;AAAA,MACAc;AAAA,IAAA;AAAA,EACF,GAGIgB,IAAoB/B;AAAA,IACxB,CAACK,MAAyB;AACxB,MAAAP,EAAkB,QAAQ,QAAQ,CAACI,MAAa;AAC9C,QAAIA,EAAS,MAAM,WAAW,IAC5BuB,EAAgBpB,GAAOH,CAAQ,IAE/ByB,EAAmBtB,GAAOH,CAAQ;AAAA,MAEtC,CAAC;AAAA,IACH;AAAA,IACA,CAACuB,GAAiBE,CAAkB;AAAA,EAAA,GAGhCK,IAAsBhC;AAAA,IAC1B,CAACK,MAAyB;AACxB,MAAKD,EAAmBC,CAAK,MAI7BO,EAAA,GACAmB,EAAkB1B,CAAK;AAAA,IACzB;AAAA,IACA,CAACD,GAAoBQ,GAAwBmB,CAAiB;AAAA,EAAA;AAGhE,EAAAE,EAAU,MAAM;AACd,IAAAnC,EAAkB,UAAUoC,EAAkBnD,CAAG;AAAA,EACnD,GAAG,CAACA,CAAG,CAAC,GAERkD,EAAU,MAAM;AACd,IAAAvC,EAAgB,UAAUD,GAAW,WAAW,YAChDG,EAAyB,UAAU,IAAI,gBAAA;AACvC,UAAM,EAAE,QAAAuC,MAAWvC,EAAyB,SAEtCwC,IAAkB,CAAC/B,MACvBE,EAAgBF,CAAsB,GAElCgC,IAAgB,CAAChC,MACrBK,EAAcL,CAAsB,GAEhCiC,IAAgB,CAACjC,MACrB2B,EAAoB3B,CAAsB;AAE5C,WAAAX,EAAgB,QAAQ,iBAAiB,WAAW0C,GAAiB;AAAA,MACnE,SAAShD;AAAA,MACT,QAAA+C;AAAA,IAAA,CACD,GAEDzC,EAAgB,QAAQ,iBAAiB,SAAS2C,GAAe;AAAA,MAC/D,SAASjD;AAAA,MACT,QAAA+C;AAAA,IAAA,CACD,GAEDzC,EAAgB,QAAQ,iBAAiBR,GAAWoD,GAAe;AAAA,MACjE,SAASlD;AAAA,MACT,QAAA+C;AAAA,IAAA,CACD,GAEM,MAAM;AACX,MAAAvC,EAAyB,SAAS,MAAA,GAElCG,EAAA,GACAD,EAAkB,QAAQ,QAAQ,CAACI,MAAaD,EAAcC,CAAQ,CAAC;AAAA,IACzE;AAAA,EACF,GAAG;AAAA,IACDhB;AAAA,IACAE;AAAA,IACAK;AAAA,IACAc;AAAA,IACAG;AAAA,IACAsB;AAAA,IACAjC;AAAA,IACAE;AAAA,EAAA,CACD;AACH;"}
|
|
1
|
+
{"version":3,"file":"use-key.js","sources":["../../src/use-key/use-key.ts"],"sourcesContent":["import { useCallback, useEffect, useRef } from \"react\";\n\nimport {\n KeyOptions,\n KeyEventTypes,\n SequenceState,\n CombinationState,\n UseKeySchema,\n UseKeyCallback,\n UseKeyOptions,\n} from \"./use-key.types\";\nimport { parseKeySequences } from \"./parse-key-sequences\";\nimport { advanceSequenceState, resetSequenceState } from \"./sequence-state\";\nimport { invokeKeyAction } from \"./invoke-key-action\";\nimport { shouldHandleEvent } from \"./event-guards\";\nimport { SPECIAL_KEYS } from \"./normalize-key\";\n\nconst defaultOptions: KeyOptions = {\n eventType: KeyEventTypes.KeyUp,\n eventRepeat: false,\n eventCapture: false,\n eventOnce: false,\n eventStopImmediatePropagation: false,\n sequenceThreshold: 1000,\n combinationThreshold: 200,\n container: { current: null },\n};\n\n/**\n * React hook for handling keyboard events with support for key sequences and combinations.\n *\n * Enables listening for single key presses, key combinations, and sequential key presses.\n * Supports customizable options like event type, repeat handling, and one-time listeners.\n *\n * @template T - The callback function type\n * @param {UseKeySchema} key - Single key, combination, sequence, or array of patterns to listen for\n * @param {UseKeyCallback} keyCallback - Callback function invoked when key pattern matches\n * @param {UseKeyOptions} [options] - Configuration options for the hook\n * @param {KeyEventType} [options.eventType=KeyEventTypes.KeyUp] - Type of keyboard event ('keydown' or 'keyup')\n * @param {boolean} [options.eventRepeat=false] - Allow repeated key presses to trigger callback\n * @param {boolean} [options.eventCapture=false] - Use event capture phase instead of bubbling\n * @param {boolean} [options.eventOnce=false] - Trigger callback only once\n * @param {boolean} [options.eventStopImmediatePropagation=false] - Stop immediate propagation\n * @param {number} [options.sequenceThreshold=1000] - Timeout in ms between sequence keys\n * @param {number} [options.combinationThreshold=200] - Timeout in ms between combination keys\n * @param {RefObject<HTMLElement>} [options.container] - DOM element to attach listener to (default: window)\n *\n * @example\n * // Single key schema\n * useKey('a', (event, key) => console.log(`Pressed ${key}`));\n *\n * @example\n * // Multiple patterns of single key schema\n * useKey(['a', 'b', 'c'], (event, key) => console.log(`Pressed ${key}`));\n *\n * @example\n * // Combination key schema\n * useKey('a+b', (event, key) => {\n * console.log(`Pressed ${key}`);\n * });\n *\n * @example\n * // Multiple patterns of combination key schema\n * useKey(['a+b', 'c+d'], (event, key) => {\n * console.log(`Pressed ${key}`);\n * });\n *\n * @example\n * // Sequential key schema\n * useKey('ArrowUp ArrowUp ArrowDown ArrowDown', (event, key) => {\n * console.log(`Pressed ${key}`);\n * });\n *\n * @example\n * // Multiple patterns of sequential key schema\n * useKey(['ArrowUp ArrowUp ArrowDown ArrowDown', 'ArrowLeft ArrowRight'], (event, key) => {\n * console.log(`Pressed ${key}`);\n * });\n *\n * @example\n * // Using options to listen for a key on keydown event and stop propagation\n * useKey('Any', handleSubmit, {\n * eventType: KeyEventTypes.KeyDown,\n * eventStopImmediatePropagation: true,\n * container: inputRef\n * });\n *\n */\nconst useKey = (\n key: UseKeySchema,\n keyCallback: UseKeyCallback,\n options: UseKeyOptions = defaultOptions,\n) => {\n const {\n eventType,\n eventRepeat,\n eventCapture,\n eventOnce,\n eventStopImmediatePropagation,\n sequenceThreshold,\n combinationThreshold,\n container,\n } = { ...defaultOptions, ...options };\n\n const targetReference = useRef<EventTarget | null>(null);\n const abortControllerReference = useRef<AbortController | null>(null);\n\n const combinationReference = useRef<CombinationState>({\n activeKeys: new Map(),\n });\n const sequenceReference = useRef<SequenceState[]>([]);\n\n const resetCombination = useCallback(() => {\n combinationReference.current.activeKeys.clear();\n }, []);\n\n const resetSequence = useCallback((sequence: SequenceState) => {\n sequenceReference.current = resetSequenceState(\n sequence,\n sequenceReference.current,\n );\n }, []);\n\n const registerKeyDown = useCallback((event: KeyboardEvent) => {\n const normalizedEventKey =\n event.key === \" \" ? SPECIAL_KEYS.SPACE : event.key;\n combinationReference.current.activeKeys.set(normalizedEventKey, {\n pressedAt: Date.now(),\n });\n }, []);\n\n const registerKeyUp = useCallback((event: KeyboardEvent) => {\n const normalizedEventKey =\n event.key === \" \" ? SPECIAL_KEYS.SPACE : event.key;\n const state =\n combinationReference.current.activeKeys.get(normalizedEventKey);\n if (state) state.releasedAt = Date.now();\n }, []);\n\n const cleanupCombinationKeys = useCallback(() => {\n const now = Date.now();\n const combo = combinationReference.current;\n\n [...combo.activeKeys.entries()].forEach(([key, state]) => {\n if (eventType === KeyEventTypes.KeyDown) {\n if (state.releasedAt) {\n combo.activeKeys.delete(key);\n }\n } else if (\n state.releasedAt &&\n now - state.releasedAt > combinationThreshold\n ) {\n combo.activeKeys.delete(key);\n }\n });\n }, [eventType, combinationThreshold]);\n\n const validateCombination = useCallback(\n (\n expectedKey: string[],\n activeKeys: Map<string, { pressedAt: number; releasedAt?: number }>,\n ): boolean => {\n if (eventType === KeyEventTypes.KeyDown) {\n return (\n activeKeys.size === expectedKey.length &&\n expectedKey.every((key) => {\n if (key === SPECIAL_KEYS.ANY) {\n return activeKeys.size > 0;\n }\n return activeKeys.has(key);\n })\n );\n }\n if (eventType === KeyEventTypes.KeyUp) {\n const keyStates = expectedKey.map((key) => {\n if (key === SPECIAL_KEYS.ANY) {\n const entries = [...activeKeys.entries()];\n const lastEntry = entries.at(-1);\n return lastEntry ? lastEntry[1] : undefined;\n }\n return activeKeys.get(key);\n });\n\n if (keyStates.some((state) => !state?.releasedAt)) {\n return false;\n }\n\n const pressedTimes: number[] = keyStates\n .map((state) => state?.pressedAt)\n .filter((value): value is number => value !== undefined);\n const releasedTimes: number[] = keyStates\n .map((state) => state?.releasedAt)\n .filter((value): value is number => value !== undefined);\n\n const minReleased = Math.min(...releasedTimes);\n const maxReleased = Math.max(...releasedTimes);\n const maxPressed = Math.max(...pressedTimes);\n\n if (maxPressed > minReleased) {\n return false;\n }\n\n if (maxReleased - minReleased > combinationThreshold) {\n return false;\n }\n\n return true;\n }\n\n return false;\n },\n [eventType, combinationThreshold],\n );\n\n const handleSingleKey = useCallback(\n (event: KeyboardEvent, sequence: SequenceState) => {\n const expectedKey = sequence.chord[0];\n\n if (Array.isArray(expectedKey)) {\n const { activeKeys } = combinationReference.current;\n\n if (!validateCombination(expectedKey, activeKeys)) {\n return;\n }\n\n invokeKeyAction(event, sequence.key, keyCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n\n return;\n }\n\n const normalizedEventKey =\n event.key === \" \" ? SPECIAL_KEYS.SPACE : event.key;\n if (\n expectedKey !== SPECIAL_KEYS.ANY &&\n expectedKey !== normalizedEventKey\n ) {\n return;\n }\n\n invokeKeyAction(event, sequence.key, keyCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n },\n [\n eventStopImmediatePropagation,\n eventOnce,\n keyCallback,\n validateCombination,\n ],\n );\n\n const handleSequenceStep = useCallback(\n (event: KeyboardEvent, sequence: SequenceState) => {\n const expectedKey = sequence.chord[sequence.index];\n\n if (Array.isArray(expectedKey)) {\n const { activeKeys } = combinationReference.current;\n\n if (!validateCombination(expectedKey, activeKeys)) {\n return;\n }\n\n const [updatedSequence, updatedSequences] = advanceSequenceState(\n sequence,\n sequenceReference.current,\n sequenceThreshold,\n resetSequence,\n );\n sequenceReference.current = updatedSequences;\n\n if (updatedSequence.index === updatedSequence.chord.length) {\n invokeKeyAction(event, updatedSequence.key, keyCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n\n resetSequence(updatedSequence);\n }\n\n return;\n }\n\n const normalizedEventKey =\n event.key === \" \" ? SPECIAL_KEYS.SPACE : event.key;\n if (\n expectedKey !== SPECIAL_KEYS.ANY &&\n expectedKey !== normalizedEventKey\n ) {\n resetSequence(sequence);\n return;\n }\n\n const [updatedSequence, updatedSequences] = advanceSequenceState(\n sequence,\n sequenceReference.current,\n sequenceThreshold,\n resetSequence,\n );\n sequenceReference.current = updatedSequences;\n\n if (updatedSequence.index === updatedSequence.chord.length) {\n invokeKeyAction(event, updatedSequence.key, keyCallback, {\n stopImmediate: eventStopImmediatePropagation,\n once: eventOnce,\n onOnce: () => {\n abortControllerReference.current?.abort();\n },\n });\n\n resetSequence(updatedSequence);\n }\n },\n [\n eventOnce,\n eventStopImmediatePropagation,\n sequenceThreshold,\n keyCallback,\n resetSequence,\n validateCombination,\n ],\n );\n\n const evaluateSequences = useCallback(\n (event: KeyboardEvent) => {\n sequenceReference.current.forEach((sequence) => {\n if (sequence.chord.length === 1) {\n handleSingleKey(event, sequence);\n } else {\n handleSequenceStep(event, sequence);\n }\n });\n },\n [handleSingleKey, handleSequenceStep],\n );\n\n const handleEventListener = useCallback(\n (event: KeyboardEvent) => {\n if (\n !shouldHandleEvent(event, {\n repeat: eventRepeat,\n })\n ) {\n return;\n }\n\n cleanupCombinationKeys();\n evaluateSequences(event);\n },\n [cleanupCombinationKeys, evaluateSequences, eventRepeat],\n );\n\n useEffect(() => {\n sequenceReference.current = parseKeySequences(key);\n }, [key]);\n\n useEffect(() => {\n targetReference.current = container?.current ?? globalThis;\n abortControllerReference.current = new AbortController();\n const { signal } = abortControllerReference.current;\n\n const keyDownListener = (event: Event) =>\n registerKeyDown(event as KeyboardEvent);\n\n const keyUpListener = (event: Event) =>\n registerKeyUp(event as KeyboardEvent);\n\n const eventListener = (event: Event) =>\n handleEventListener(event as KeyboardEvent);\n\n targetReference.current.addEventListener(\"keydown\", keyDownListener, {\n capture: eventCapture,\n signal,\n });\n\n targetReference.current.addEventListener(\"keyup\", keyUpListener, {\n capture: eventCapture,\n signal,\n });\n\n targetReference.current.addEventListener(eventType, eventListener, {\n capture: eventCapture,\n signal,\n });\n\n return () => {\n abortControllerReference.current?.abort();\n\n resetCombination();\n sequenceReference.current.forEach((sequence) => resetSequence(sequence));\n };\n }, [\n eventType,\n eventCapture,\n container,\n registerKeyDown,\n registerKeyUp,\n handleEventListener,\n resetCombination,\n resetSequence,\n ]);\n};\n\nexport default useKey;\n"],"names":["defaultOptions","KeyEventTypes","useKey","key","keyCallback","options","eventType","eventRepeat","eventCapture","eventOnce","eventStopImmediatePropagation","sequenceThreshold","combinationThreshold","container","targetReference","useRef","abortControllerReference","combinationReference","sequenceReference","resetCombination","useCallback","resetSequence","sequence","resetSequenceState","registerKeyDown","event","normalizedEventKey","SPECIAL_KEYS","registerKeyUp","state","cleanupCombinationKeys","now","combo","validateCombination","expectedKey","activeKeys","keyStates","lastEntry","pressedTimes","value","releasedTimes","minReleased","maxReleased","handleSingleKey","invokeKeyAction","handleSequenceStep","updatedSequence","updatedSequences","advanceSequenceState","evaluateSequences","handleEventListener","shouldHandleEvent","useEffect","parseKeySequences","signal","keyDownListener","keyUpListener","eventListener"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-key.types.js","sources":["../../src/use-key/use-key.types.ts"],"sourcesContent":["
|
|
1
|
+
{"version":3,"file":"use-key.types.js","sources":["../../src/use-key/use-key.types.ts"],"sourcesContent":["export type Key = string;\n\nexport type KeyEvent = Key | Key[];\n\nexport const KeyEventTypes = {\n KeyUp: \"keyup\",\n KeyDown: \"keydown\",\n} as const;\n\nexport type KeyEventType = (typeof KeyEventTypes)[keyof typeof KeyEventTypes];\n\nexport interface KeyOptions {\n eventType: KeyEventType;\n eventRepeat: boolean;\n eventCapture: boolean;\n eventOnce: boolean;\n eventStopImmediatePropagation: boolean;\n sequenceThreshold: number;\n combinationThreshold: number;\n container: { current: EventTarget | null };\n}\n\nexport interface CombinationActiveKey {\n pressedAt: number;\n releasedAt?: number;\n}\n\nexport interface CombinationState {\n activeKeys: Map<Key, CombinationActiveKey>;\n}\n\nexport type KeyChord = (Key | Key[])[];\n\nexport interface SequenceState {\n key: Key;\n chord: KeyChord;\n index: number;\n sequenceTimeout: ReturnType<typeof setTimeout> | null;\n}\n\nexport type UseKeySchema = KeyEvent;\n\nexport type UseKeyCallback =\n | ((event: KeyboardEvent, key: Key, ...properties: unknown[]) => boolean)\n | ((event: KeyboardEvent, key: Key, ...properties: unknown[]) => void);\n\nexport type UseKeyOptions = Partial<KeyOptions>;\n"],"names":["KeyEventTypes"],"mappings":"AAIO,MAAMA,IAAgB;AAAA,EAC3B,OAAO;AAAA,EACP,SAAS;AACX;"}
|