hotkey-router 0.0.1 → 0.0.2
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 +25 -9
- package/dist/hotkey-router.cjs +1 -1
- package/dist/hotkey-router.js +1 -1
- package/dist/hotkey-router.min.js +1 -1
- package/package.json +10 -2
package/README.md
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
# hotkey-router
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/hotkey-router)
|
|
4
|
+
[](https://bundlephobia.com/package/hotkey-router)
|
|
5
|
+
[](https://github.com/iWhatty/hotkey-router-js)
|
|
6
|
+
|
|
3
7
|
**A tiny, deterministic keyboard routing engine for modern web apps.**
|
|
4
8
|
|
|
5
9
|
Hotkey Router is not a key utility.
|
|
@@ -32,10 +36,22 @@ No keycodes. No legacy IE hacks. No hidden global scope state.
|
|
|
32
36
|
npm install hotkey-router
|
|
33
37
|
```
|
|
34
38
|
|
|
35
|
-
|
|
39
|
+
### ESM
|
|
40
|
+
|
|
41
|
+
```js
|
|
42
|
+
import hotkeys from 'hotkey-router'
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### CommonJS
|
|
46
|
+
|
|
47
|
+
```js
|
|
48
|
+
const hotkeys = require('hotkey-router')
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### CDN (ESM)
|
|
36
52
|
|
|
37
53
|
```js
|
|
38
|
-
import hotkeys from 'https://cdn.
|
|
54
|
+
import hotkeys from 'https://cdn.jsdelivr.net/npm/hotkey-router/dist/hotkey-router.min.js'
|
|
39
55
|
```
|
|
40
56
|
|
|
41
57
|
---
|
|
@@ -216,7 +232,7 @@ hotkeys.init({
|
|
|
216
232
|
})
|
|
217
233
|
```
|
|
218
234
|
|
|
219
|
-
Auto-initializes on `window` by default.
|
|
235
|
+
Auto-initializes on `window` by default (browser environments).
|
|
220
236
|
|
|
221
237
|
---
|
|
222
238
|
|
|
@@ -241,7 +257,7 @@ Returns `true` if a handler ran.
|
|
|
241
257
|
|
|
242
258
|
# Supported Syntax
|
|
243
259
|
|
|
244
|
-
|
|
260
|
+
## Standard
|
|
245
261
|
|
|
246
262
|
* `ctrl+k`
|
|
247
263
|
* `shift+a`
|
|
@@ -249,7 +265,7 @@ Returns `true` if a handler ran.
|
|
|
249
265
|
* `mod+s` (meta on macOS, ctrl elsewhere)
|
|
250
266
|
* `ctrl++` or `ctrl+plus`
|
|
251
267
|
|
|
252
|
-
|
|
268
|
+
## AHK-Style Prefix Modifiers
|
|
253
269
|
|
|
254
270
|
* `^k` → `ctrl+k`
|
|
255
271
|
* `!k` → `alt+k`
|
|
@@ -259,9 +275,9 @@ Returns `true` if a handler ran.
|
|
|
259
275
|
|
|
260
276
|
Modifiers must appear before the base key.
|
|
261
277
|
|
|
262
|
-
|
|
278
|
+
## Aliases Supported
|
|
263
279
|
|
|
264
|
-
Modifiers
|
|
280
|
+
### Modifiers
|
|
265
281
|
|
|
266
282
|
* `ctrl`, `control`, `⌃`
|
|
267
283
|
* `shift`, `⇧`, `+`
|
|
@@ -269,7 +285,7 @@ Modifiers:
|
|
|
269
285
|
* `meta`, `cmd`, `command`, `win`, `⌘`, `#`
|
|
270
286
|
* `mod` (meta on macOS, ctrl elsewhere)
|
|
271
287
|
|
|
272
|
-
Navigation / Special
|
|
288
|
+
### Navigation / Special Keys
|
|
273
289
|
|
|
274
290
|
* `escape`, `esc`
|
|
275
291
|
* `enter`, `return`
|
|
@@ -312,4 +328,4 @@ Chrome, Firefox, Safari, Edge.
|
|
|
312
328
|
|
|
313
329
|
# License
|
|
314
330
|
|
|
315
|
-
|
|
331
|
+
See LICENSE file for details.
|
package/dist/hotkey-router.cjs
CHANGED
package/dist/hotkey-router.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
// hotkey-router v0.0.
|
|
1
|
+
// hotkey-router v0.0.2 | SEE LICENSE IN LICENSE
|
|
2
2
|
|
|
3
3
|
function E(t,e,n,r){return t.addEventListener(e,n,r),()=>t.removeEventListener(e,n,r)}const C=typeof navigator<"u"&&/Mac|iPhone|iPad|iPod/.test(navigator.platform),L=new Set(["ctrl","shift","alt","meta"]),z=new Map([["^","ctrl"],["!","alt"],["+","shift"],["#","meta"]]),v=Object.freeze({esc:"escape",escape:"escape",space:" ",spacebar:" ",enter:"enter",return:"enter",del:"delete",delete:"delete",backspace:"backspace",tab:"tab",up:"arrowup",down:"arrowdown",left:"arrowleft",right:"arrowright",home:"home",end:"end",pageup:"pageup",pagedown:"pagedown",pgup:"pageup",pgdn:"pagedown",cmd:"meta",command:"meta",win:"meta",meta:"meta",control:"ctrl",ctrl:"ctrl",option:"alt",alt:"alt",shift:"shift","\u2318":"meta","\u2303":"ctrl","\u2325":"alt","\u21E7":"shift",mod:C?"meta":"ctrl",plus:"+"});let I=!0,h=typeof window<"u"?window:null;const u=new Map,d=new Map,p=new Map;let b=!1,D=1;function k(t){const e=String(t??"").trim(),n=e.toLowerCase();return v[n]??(e===" "?" ":n)}function g({ctrl:t,shift:e,alt:n,meta:r,key:i}){let o="";return t&&(o+="ctrl+"),e&&(o+="shift+"),n&&(o+="alt+"),r&&(o+="meta+"),o?o+i:i}function O(t){return g({ctrl:t.ctrlKey,shift:t.shiftKey,alt:t.altKey,meta:t.metaKey,key:k(t.key)})}function U(t){const e=k(t);return L.has(e)}function P(t){const e=String(t||"").trim(),r=e.toLowerCase().endsWith(" up");let i=(r?e.slice(0,-3):e).trim().toLowerCase();const o={ctrl:!1,shift:!1,alt:!1,meta:!1,key:null};for(;i.length;){const s=z.get(i[0])??null;if(!s)break;o[s]=!0,i=i.slice(1).trimStart()}const l=i.split("+").map(s=>s.trim()),a=l.filter(Boolean),f=l.some(s=>s==="")&&i.includes("++");if(!f){let s=!1;for(const c of a)if(U(c)){if(s)throw new Error(`Invalid hotkey "${t}": modifiers must come before the base key (e.g. "ctrl+k", not "k+ctrl")`)}else s||(s=!0)}for(const s of a){const c=v[s]??s;c==="ctrl"?o.ctrl=!0:c==="shift"?o.shift=!0:c==="alt"?o.alt=!0:c==="meta"?o.meta=!0:o.key=k(c)}if(!o.key&&f&&(o.key="+"),!o.key)throw new Error(`Invalid hotkey "${t}" (missing base key)`);return{combo:o,type:r?"keyup":"keydown",raw:t}}function B(t){const e=t?.target;if(!e)return!1;const n=String(e.tagName||"").toUpperCase();return e.isContentEditable||n==="INPUT"||n==="TEXTAREA"||n==="SELECT"||e.getAttribute?.("role")==="textbox"}function F(t,e){const n=e?{...e}:{};return t==="keydown"&&n.repeat==null&&(n.repeat=!1),n.priority==null&&(n.priority=0),n}function $(t,e){let n=u.get(t);n||(n=new Map,u.set(t,n));let r=n.get(e);return r||(r=[],n.set(e,r)),r}function m(t){const e=p.get(t);if(!e)return!1;const{comboStr:n,type:r}=e,i=u.get(n),o=i?.get(r);if(!o?.length)return p.delete(t),!1;const l=o.filter(a=>a.id!==t);return l.length?i.set(r,l):i.delete(r),i.size||u.delete(n),p.delete(t),!0}function K(t,e,n=null,r={}){const{combo:i,type:o,raw:l}=P(t),a=g(i),f=F(o,r),s={id:D++,comboStr:a,type:o,combo:i,handler:e,plugin:n,raw:l,options:f};$(a,o).push(s),p.set(s.id,{comboStr:a,type:o});const c=()=>m(s.id);return c.id=s.id,c.hotkey=l,c}function j(t,e){const{combo:n,type:r}=P(t),i=g(n),o=u.get(i);if(!o)return;const l=o.get(r);if(l?.length){if(e){const a=[];for(const f of l)f.handler===e?p.delete(f.id):a.push(f);a.length?o.set(r,a):o.delete(r)}else{for(const a of l)p.delete(a.id);o.delete(r)}o.size||u.delete(i)}}function N(t,e){if(d.has(t))throw new Error(`Plugin "${t}" already registered`);const n=[];for(const[r,i]of Object.entries(e)){const[o,l]=Array.isArray(i)?i:[i,{}],a=K(r,o,t,l);n.push(a.id)}return d.set(t,n),()=>M(t)}function M(t){const e=d.get(t);if(e){for(const n of e)m(n);d.delete(t)}}function W(){b=!0}function q(){b=!1}function H(t=!0){I=!!t}function R(t){h=t}function T(t){let e=null;for(const n of t)e?(n.options.priority>e.options.priority||n.options.priority===e.options.priority&&n.id>e.id)&&(e=n):e=n;return e}function S(t){return e=>{if(b)return;const n=I&&B(e),r=O(e),i=u.get(r)?.get(t);if(!i?.length)return;const o=[];for(const f of i){const s=f.options;n&&!s.allowIn?.(e)||t==="keydown"&&s.repeat===!1&&e.repeat||s.when&&s.when(e)===!1||o.push(f)}if(!o.length)return;const l=T(o),a=l.options;a.preventDefault&&e.preventDefault(),a.stopImmediatePropagation?e.stopImmediatePropagation():a.stopPropagation&&e.stopPropagation(),l.handler(e),a.once&&m(l.id)}}let y=null,w=null;function x({target:t=h,capture:e=!1}={}){if(!t)throw new Error("hotkeys.init() requires a target (e.g. window)");(y||w)&&A(),y=E(t,"keydown",S("keydown"),{capture:e}),w=E(t,"keyup",S("keyup"),{capture:e})}function A(){y?.(),w?.(),y=null,w=null,u.clear(),d.clear(),p.clear()}function X(t,{type:e}={}){const{combo:n,type:r}=P(t),i=g(n),o=e||r,l=u.get(i)?.get(o);if(!l?.length)return!1;const a={type:o,key:n.key,ctrlKey:!!n.ctrl,shiftKey:!!n.shift,altKey:!!n.alt,metaKey:!!n.meta,repeat:!1,preventDefault(){},stopPropagation(){},stopImmediatePropagation(){},target:null},f=T(l.filter(s=>s.options.when?s.options.when(a)!==!1:!0));return f?(f.handler(a),f.options.once&&m(f.id),!0):!1}h&&x();var G={init:x,destroy:A,setTarget:R,bind:K,unbind:j,registerPlugin:N,unregisterPlugin:M,pause:W,resume:q,ignoreInput:H,trigger:X};export{G as default};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hotkey-router",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.2",
|
|
4
4
|
"description": "A tiny, deterministic keyboard routing engine for modern web apps.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"author": "DR.WATT",
|
|
@@ -46,5 +46,13 @@
|
|
|
46
46
|
|
|
47
47
|
"engines": {
|
|
48
48
|
"node": ">=18"
|
|
49
|
-
}
|
|
49
|
+
},
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "https://github.com/iWhatty/hotkey-router-js.git"
|
|
53
|
+
},
|
|
54
|
+
"bugs": {
|
|
55
|
+
"url": "https://github.com/iWhatty/hotkey-router-js/issues"
|
|
56
|
+
},
|
|
57
|
+
"homepage": "https://github.com/iWhatty/hotkey-router-js#readme"
|
|
50
58
|
}
|