@develemit/web-hooks 0.0.0-stage → 0.2.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/CHANGELOG.md +24 -0
- package/LICENSE +21 -0
- package/README.md +249 -2
- package/dist/auto-grow.cjs +60 -0
- package/dist/auto-grow.d.cts +14 -0
- package/dist/auto-grow.d.ts +14 -0
- package/dist/auto-grow.js +9 -0
- package/dist/chunk-3CACI4OQ.js +68 -0
- package/dist/chunk-3UGRXQIA.js +39 -0
- package/dist/chunk-5CA5RIMH.js +34 -0
- package/dist/chunk-5KIH2XLV.js +136 -0
- package/dist/chunk-6KCRVSLS.js +80 -0
- package/dist/chunk-DNU57XEJ.js +82 -0
- package/dist/chunk-IWQDAJEP.js +69 -0
- package/dist/chunk-LZKAGDER.js +22 -0
- package/dist/chunk-NKLEB5TR.js +98 -0
- package/dist/chunk-OZ4PU4E3.js +115 -0
- package/dist/chunk-S4YKMGQE.js +23 -0
- package/dist/chunk-UPVNSGIK.js +72 -0
- package/dist/chunk-UZADAINO.js +61 -0
- package/dist/clipboard.cjs +94 -0
- package/dist/clipboard.d.cts +17 -0
- package/dist/clipboard.d.ts +17 -0
- package/dist/clipboard.js +9 -0
- package/dist/debounce.cjs +96 -0
- package/dist/debounce.d.cts +21 -0
- package/dist/debounce.d.ts +21 -0
- package/dist/debounce.js +11 -0
- package/dist/drawer-swipe.cjs +149 -0
- package/dist/drawer-swipe.d.cts +26 -0
- package/dist/drawer-swipe.d.ts +26 -0
- package/dist/drawer-swipe.js +25 -0
- package/dist/escape.cjs +48 -0
- package/dist/escape.d.cts +3 -0
- package/dist/escape.d.ts +3 -0
- package/dist/escape.js +7 -0
- package/dist/focus-trap.cjs +110 -0
- package/dist/focus-trap.d.cts +17 -0
- package/dist/focus-trap.d.ts +17 -0
- package/dist/focus-trap.js +13 -0
- package/dist/hotkey.cjs +127 -0
- package/dist/hotkey.d.cts +31 -0
- package/dist/hotkey.d.ts +31 -0
- package/dist/hotkey.js +15 -0
- package/dist/index.cjs +918 -0
- package/dist/index.d.cts +14 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +115 -0
- package/dist/media-query.cjs +90 -0
- package/dist/media-query.d.cts +12 -0
- package/dist/media-query.d.ts +12 -0
- package/dist/media-query.js +15 -0
- package/dist/outside-press.cjs +66 -0
- package/dist/outside-press.d.cts +15 -0
- package/dist/outside-press.d.ts +15 -0
- package/dist/outside-press.js +11 -0
- package/dist/scroll-lock.cjs +107 -0
- package/dist/scroll-lock.d.cts +8 -0
- package/dist/scroll-lock.d.ts +8 -0
- package/dist/scroll-lock.js +11 -0
- package/dist/storage-state.cjs +161 -0
- package/dist/storage-state.d.cts +14 -0
- package/dist/storage-state.d.ts +14 -0
- package/dist/storage-state.js +7 -0
- package/dist/unsaved-guard.cjs +48 -0
- package/dist/unsaved-guard.d.cts +5 -0
- package/dist/unsaved-guard.d.ts +5 -0
- package/dist/unsaved-guard.js +9 -0
- package/dist/visibility-polling.cjs +98 -0
- package/dist/visibility-polling.d.cts +14 -0
- package/dist/visibility-polling.d.ts +14 -0
- package/dist/visibility-polling.js +9 -0
- package/package.json +126 -3
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/focus-trap/index.ts
|
|
22
|
+
var focus_trap_exports = {};
|
|
23
|
+
__export(focus_trap_exports, {
|
|
24
|
+
FOCUSABLE_SELECTOR: () => FOCUSABLE_SELECTOR,
|
|
25
|
+
focusableWithin: () => focusableWithin,
|
|
26
|
+
nextFocusTarget: () => nextFocusTarget,
|
|
27
|
+
useFocusTrap: () => useFocusTrap
|
|
28
|
+
});
|
|
29
|
+
module.exports = __toCommonJS(focus_trap_exports);
|
|
30
|
+
|
|
31
|
+
// src/focus-trap/focusables.ts
|
|
32
|
+
var FOCUSABLE_SELECTOR = 'a[href], button:not([disabled]), input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex="-1"])';
|
|
33
|
+
function focusableWithin(container) {
|
|
34
|
+
return Array.from(
|
|
35
|
+
container.querySelectorAll(FOCUSABLE_SELECTOR)
|
|
36
|
+
).filter((el) => !el.closest("[hidden], [inert]"));
|
|
37
|
+
}
|
|
38
|
+
function nextFocusTarget(items, current, shiftKey, container) {
|
|
39
|
+
const first = items[0];
|
|
40
|
+
const last = items[items.length - 1];
|
|
41
|
+
if (!first || !last) return null;
|
|
42
|
+
if (!current || !container.contains(current)) return shiftKey ? last : first;
|
|
43
|
+
if (shiftKey && (current === first || current === container)) return last;
|
|
44
|
+
if (!shiftKey && current === last) return first;
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/focus-trap/use-focus-trap.ts
|
|
49
|
+
var import_react = require("react");
|
|
50
|
+
var activeTraps = [];
|
|
51
|
+
function useFocusTrap(containerRef, {
|
|
52
|
+
active,
|
|
53
|
+
initialFocusRef,
|
|
54
|
+
returnFocusRef,
|
|
55
|
+
restoreFocus = true
|
|
56
|
+
}) {
|
|
57
|
+
const openerRef = (0, import_react.useRef)(null);
|
|
58
|
+
if (active && !openerRef.current && typeof document !== "undefined") {
|
|
59
|
+
openerRef.current = document.activeElement;
|
|
60
|
+
}
|
|
61
|
+
(0, import_react.useEffect)(() => {
|
|
62
|
+
if (!active) openerRef.current = null;
|
|
63
|
+
}, [active]);
|
|
64
|
+
(0, import_react.useEffect)(() => {
|
|
65
|
+
const container = containerRef.current;
|
|
66
|
+
if (!active || !container) return;
|
|
67
|
+
const token = {};
|
|
68
|
+
activeTraps.push(token);
|
|
69
|
+
if (!container.contains(document.activeElement)) {
|
|
70
|
+
const target = initialFocusRef?.current ?? focusableWithin(container)[0] ?? container;
|
|
71
|
+
if (target === container && !container.hasAttribute("tabindex")) {
|
|
72
|
+
container.setAttribute("tabindex", "-1");
|
|
73
|
+
}
|
|
74
|
+
target.focus();
|
|
75
|
+
}
|
|
76
|
+
function onKeyDown(event) {
|
|
77
|
+
if (event.key !== "Tab" || !container) return;
|
|
78
|
+
if (activeTraps[activeTraps.length - 1] !== token) return;
|
|
79
|
+
const items = focusableWithin(container);
|
|
80
|
+
if (items.length === 0) {
|
|
81
|
+
event.preventDefault();
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
const target = nextFocusTarget(
|
|
85
|
+
items,
|
|
86
|
+
document.activeElement,
|
|
87
|
+
event.shiftKey,
|
|
88
|
+
container
|
|
89
|
+
);
|
|
90
|
+
if (target) {
|
|
91
|
+
event.preventDefault();
|
|
92
|
+
target.focus();
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
document.addEventListener("keydown", onKeyDown);
|
|
96
|
+
return () => {
|
|
97
|
+
document.removeEventListener("keydown", onKeyDown);
|
|
98
|
+
activeTraps.splice(activeTraps.indexOf(token), 1);
|
|
99
|
+
const opener = returnFocusRef?.current ?? openerRef.current;
|
|
100
|
+
if (restoreFocus && opener?.isConnected) opener.focus();
|
|
101
|
+
};
|
|
102
|
+
}, [active, containerRef, initialFocusRef, returnFocusRef, restoreFocus]);
|
|
103
|
+
}
|
|
104
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
105
|
+
0 && (module.exports = {
|
|
106
|
+
FOCUSABLE_SELECTOR,
|
|
107
|
+
focusableWithin,
|
|
108
|
+
nextFocusTarget,
|
|
109
|
+
useFocusTrap
|
|
110
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
declare const FOCUSABLE_SELECTOR = "a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
|
|
4
|
+
declare function focusableWithin(container: HTMLElement): HTMLElement[];
|
|
5
|
+
/** The element Tab must be redirected to, or null when the browser's own move is fine. */
|
|
6
|
+
declare function nextFocusTarget(items: HTMLElement[], current: Element | null, shiftKey: boolean, container: HTMLElement): HTMLElement | null;
|
|
7
|
+
|
|
8
|
+
type UseFocusTrapOptions = {
|
|
9
|
+
active: boolean;
|
|
10
|
+
initialFocusRef?: RefObject<HTMLElement | null>;
|
|
11
|
+
/** Wins over the captured opener. Safari leaves <body> focused after a tap on a button. */
|
|
12
|
+
returnFocusRef?: RefObject<HTMLElement | null>;
|
|
13
|
+
restoreFocus?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare function useFocusTrap(containerRef: RefObject<HTMLElement | null>, { active, initialFocusRef, returnFocusRef, restoreFocus, }: UseFocusTrapOptions): void;
|
|
16
|
+
|
|
17
|
+
export { FOCUSABLE_SELECTOR, type UseFocusTrapOptions, focusableWithin, nextFocusTarget, useFocusTrap };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { RefObject } from 'react';
|
|
2
|
+
|
|
3
|
+
declare const FOCUSABLE_SELECTOR = "a[href], button:not([disabled]), input:not([disabled]):not([type=\"hidden\"]), select:not([disabled]), textarea:not([disabled]), [tabindex]:not([tabindex=\"-1\"])";
|
|
4
|
+
declare function focusableWithin(container: HTMLElement): HTMLElement[];
|
|
5
|
+
/** The element Tab must be redirected to, or null when the browser's own move is fine. */
|
|
6
|
+
declare function nextFocusTarget(items: HTMLElement[], current: Element | null, shiftKey: boolean, container: HTMLElement): HTMLElement | null;
|
|
7
|
+
|
|
8
|
+
type UseFocusTrapOptions = {
|
|
9
|
+
active: boolean;
|
|
10
|
+
initialFocusRef?: RefObject<HTMLElement | null>;
|
|
11
|
+
/** Wins over the captured opener. Safari leaves <body> focused after a tap on a button. */
|
|
12
|
+
returnFocusRef?: RefObject<HTMLElement | null>;
|
|
13
|
+
restoreFocus?: boolean;
|
|
14
|
+
};
|
|
15
|
+
declare function useFocusTrap(containerRef: RefObject<HTMLElement | null>, { active, initialFocusRef, returnFocusRef, restoreFocus, }: UseFocusTrapOptions): void;
|
|
16
|
+
|
|
17
|
+
export { FOCUSABLE_SELECTOR, type UseFocusTrapOptions, focusableWithin, nextFocusTarget, useFocusTrap };
|
package/dist/hotkey.cjs
ADDED
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use strict";
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __export = (target, all) => {
|
|
8
|
+
for (var name in all)
|
|
9
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
10
|
+
};
|
|
11
|
+
var __copyProps = (to, from, except, desc) => {
|
|
12
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
13
|
+
for (let key of __getOwnPropNames(from))
|
|
14
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
15
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
16
|
+
}
|
|
17
|
+
return to;
|
|
18
|
+
};
|
|
19
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
20
|
+
|
|
21
|
+
// src/hotkey/index.ts
|
|
22
|
+
var hotkey_exports = {};
|
|
23
|
+
__export(hotkey_exports, {
|
|
24
|
+
detectApple: () => detectApple,
|
|
25
|
+
isEditableTarget: () => isEditableTarget,
|
|
26
|
+
matchHotkey: () => matchHotkey,
|
|
27
|
+
parseHotkey: () => parseHotkey,
|
|
28
|
+
useHotkey: () => useHotkey
|
|
29
|
+
});
|
|
30
|
+
module.exports = __toCommonJS(hotkey_exports);
|
|
31
|
+
|
|
32
|
+
// src/hotkey/parse-hotkey.ts
|
|
33
|
+
var KEY_ALIASES = {
|
|
34
|
+
esc: "escape",
|
|
35
|
+
space: " ",
|
|
36
|
+
plus: "+",
|
|
37
|
+
up: "arrowup",
|
|
38
|
+
down: "arrowdown",
|
|
39
|
+
left: "arrowleft",
|
|
40
|
+
right: "arrowright"
|
|
41
|
+
};
|
|
42
|
+
function parseHotkey(combo) {
|
|
43
|
+
const parsed = { key: "", mod: false, ctrl: false, meta: false, alt: false, shift: false };
|
|
44
|
+
const parts = combo.trim().toLowerCase().split(/\+(?=.)/);
|
|
45
|
+
for (const part of parts) {
|
|
46
|
+
const token = part.trim();
|
|
47
|
+
if (token === "mod" || token === "ctrl" || token === "meta" || token === "alt" || token === "shift") {
|
|
48
|
+
parsed[token] = true;
|
|
49
|
+
} else {
|
|
50
|
+
parsed.key = KEY_ALIASES[token] ?? token;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
if (!parsed.key) throw new Error(`Invalid hotkey "${combo}": no key`);
|
|
54
|
+
return parsed;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// src/hotkey/match-hotkey.ts
|
|
58
|
+
var CODE_FOR_SYMBOL = {
|
|
59
|
+
"/": "Slash",
|
|
60
|
+
".": "Period",
|
|
61
|
+
",": "Comma",
|
|
62
|
+
";": "Semicolon",
|
|
63
|
+
"'": "Quote",
|
|
64
|
+
"[": "BracketLeft",
|
|
65
|
+
"]": "BracketRight",
|
|
66
|
+
"\\": "Backslash",
|
|
67
|
+
"-": "Minus",
|
|
68
|
+
"=": "Equal",
|
|
69
|
+
"`": "Backquote"
|
|
70
|
+
};
|
|
71
|
+
function physicalCode(key) {
|
|
72
|
+
if (/^[a-z]$/.test(key)) return `Key${key.toUpperCase()}`;
|
|
73
|
+
if (/^[0-9]$/.test(key)) return `Digit${key}`;
|
|
74
|
+
return CODE_FOR_SYMBOL[key] ?? null;
|
|
75
|
+
}
|
|
76
|
+
function keyMatches(event, parsed) {
|
|
77
|
+
if (event.key.toLowerCase() === parsed.key) return true;
|
|
78
|
+
return parsed.shift && physicalCode(parsed.key) === event.code;
|
|
79
|
+
}
|
|
80
|
+
function matchHotkey(event, combo, isApple) {
|
|
81
|
+
const parsed = typeof combo === "string" ? parseHotkey(combo) : combo;
|
|
82
|
+
const wantMeta = parsed.meta || parsed.mod && isApple;
|
|
83
|
+
const wantCtrl = parsed.ctrl || parsed.mod && !isApple;
|
|
84
|
+
return event.metaKey === wantMeta && event.ctrlKey === wantCtrl && event.altKey === parsed.alt && event.shiftKey === parsed.shift && keyMatches(event, parsed);
|
|
85
|
+
}
|
|
86
|
+
function detectApple(nav) {
|
|
87
|
+
if (!nav) return false;
|
|
88
|
+
const platform = nav.userAgentData?.platform || nav.platform || "";
|
|
89
|
+
return /mac|iphone|ipad|ipod/i.test(platform);
|
|
90
|
+
}
|
|
91
|
+
function isEditableTarget(target) {
|
|
92
|
+
const el = target;
|
|
93
|
+
if (!el || typeof el.tagName !== "string") return false;
|
|
94
|
+
const tag = el.tagName.toLowerCase();
|
|
95
|
+
return tag === "input" || tag === "textarea" || tag === "select" || el.isContentEditable === true;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// src/hotkey/use-hotkey.ts
|
|
99
|
+
var import_react = require("react");
|
|
100
|
+
function useHotkey(combo, onHotkey, options = {}) {
|
|
101
|
+
const { enabled = true, allowInInputs = false, preventDefault = true } = options;
|
|
102
|
+
const handlerRef = (0, import_react.useRef)(onHotkey);
|
|
103
|
+
(0, import_react.useEffect)(() => {
|
|
104
|
+
handlerRef.current = onHotkey;
|
|
105
|
+
});
|
|
106
|
+
(0, import_react.useEffect)(() => {
|
|
107
|
+
if (!enabled) return;
|
|
108
|
+
const parsed = parseHotkey(combo);
|
|
109
|
+
function onKeyDown(event) {
|
|
110
|
+
if (event.isComposing || event.keyCode === 229) return;
|
|
111
|
+
if (!allowInInputs && isEditableTarget(event.target)) return;
|
|
112
|
+
if (!matchHotkey(event, parsed, detectApple(navigator))) return;
|
|
113
|
+
if (preventDefault) event.preventDefault();
|
|
114
|
+
handlerRef.current(event);
|
|
115
|
+
}
|
|
116
|
+
document.addEventListener("keydown", onKeyDown);
|
|
117
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
118
|
+
}, [combo, enabled, allowInInputs, preventDefault]);
|
|
119
|
+
}
|
|
120
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
121
|
+
0 && (module.exports = {
|
|
122
|
+
detectApple,
|
|
123
|
+
isEditableTarget,
|
|
124
|
+
matchHotkey,
|
|
125
|
+
parseHotkey,
|
|
126
|
+
useHotkey
|
|
127
|
+
});
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
interface ParsedHotkey {
|
|
2
|
+
key: string;
|
|
3
|
+
mod: boolean;
|
|
4
|
+
ctrl: boolean;
|
|
5
|
+
meta: boolean;
|
|
6
|
+
alt: boolean;
|
|
7
|
+
shift: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare function parseHotkey(combo: string): ParsedHotkey;
|
|
10
|
+
|
|
11
|
+
type KeyEventLike = Pick<KeyboardEvent, 'key' | 'code' | 'ctrlKey' | 'metaKey' | 'altKey' | 'shiftKey'>;
|
|
12
|
+
/** `isApple` decides what `mod` means: Cmd on Apple devices, Ctrl elsewhere. */
|
|
13
|
+
declare function matchHotkey(event: KeyEventLike, combo: string | ParsedHotkey, isApple: boolean): boolean;
|
|
14
|
+
interface NavigatorLike {
|
|
15
|
+
platform?: string;
|
|
16
|
+
userAgentData?: {
|
|
17
|
+
platform?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** iPad in desktop mode reports MacIntel, so it counts as Apple. */
|
|
21
|
+
declare function detectApple(nav: NavigatorLike | undefined): boolean;
|
|
22
|
+
declare function isEditableTarget(target: EventTarget | null): boolean;
|
|
23
|
+
|
|
24
|
+
interface UseHotkeyOptions {
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
allowInInputs?: boolean;
|
|
27
|
+
preventDefault?: boolean;
|
|
28
|
+
}
|
|
29
|
+
declare function useHotkey(combo: string, onHotkey: (event: KeyboardEvent) => void, options?: UseHotkeyOptions): void;
|
|
30
|
+
|
|
31
|
+
export { type ParsedHotkey, type UseHotkeyOptions, detectApple, isEditableTarget, matchHotkey, parseHotkey, useHotkey };
|
package/dist/hotkey.d.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
interface ParsedHotkey {
|
|
2
|
+
key: string;
|
|
3
|
+
mod: boolean;
|
|
4
|
+
ctrl: boolean;
|
|
5
|
+
meta: boolean;
|
|
6
|
+
alt: boolean;
|
|
7
|
+
shift: boolean;
|
|
8
|
+
}
|
|
9
|
+
declare function parseHotkey(combo: string): ParsedHotkey;
|
|
10
|
+
|
|
11
|
+
type KeyEventLike = Pick<KeyboardEvent, 'key' | 'code' | 'ctrlKey' | 'metaKey' | 'altKey' | 'shiftKey'>;
|
|
12
|
+
/** `isApple` decides what `mod` means: Cmd on Apple devices, Ctrl elsewhere. */
|
|
13
|
+
declare function matchHotkey(event: KeyEventLike, combo: string | ParsedHotkey, isApple: boolean): boolean;
|
|
14
|
+
interface NavigatorLike {
|
|
15
|
+
platform?: string;
|
|
16
|
+
userAgentData?: {
|
|
17
|
+
platform?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/** iPad in desktop mode reports MacIntel, so it counts as Apple. */
|
|
21
|
+
declare function detectApple(nav: NavigatorLike | undefined): boolean;
|
|
22
|
+
declare function isEditableTarget(target: EventTarget | null): boolean;
|
|
23
|
+
|
|
24
|
+
interface UseHotkeyOptions {
|
|
25
|
+
enabled?: boolean;
|
|
26
|
+
allowInInputs?: boolean;
|
|
27
|
+
preventDefault?: boolean;
|
|
28
|
+
}
|
|
29
|
+
declare function useHotkey(combo: string, onHotkey: (event: KeyboardEvent) => void, options?: UseHotkeyOptions): void;
|
|
30
|
+
|
|
31
|
+
export { type ParsedHotkey, type UseHotkeyOptions, detectApple, isEditableTarget, matchHotkey, parseHotkey, useHotkey };
|
package/dist/hotkey.js
ADDED