@ramstack/alpinegear-hotkey 1.4.3 → 1.4.4

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 CHANGED
@@ -1,208 +1,175 @@
1
- # @ramstack/alpinegear-hotkey
2
- [![NPM](https://img.shields.io/npm/v/@ramstack/alpinegear-hotkey)](https://www.npmjs.com/package/@ramstack/alpinegear-hotkey)
3
- [![MIT](https://img.shields.io/github/license/rameel/ramstack.alpinegear.js)](https://github.com/rameel/ramstack.alpinegear.js/blob/main/LICENSE)
4
-
5
- `@ramstack/alpinegear-hotkey` is a plugin for [Alpine.js](https://alpinejs.dev/) that provides the `x-hotkey` directive.
6
-
7
- This directive allows you to easily handle keyboard shortcuts within your Alpine.js components or application.
8
-
9
- Uses [@ramstack/hotkey](https://github.com/rameel/ramstack.hotkey.js) package under the hood.
10
-
11
- ## Installation
12
-
13
- ### Using CDN
14
- To include the CDN version of this plugin, add the following `<script>` tag before the core `alpine.js` file:
15
-
16
- ```html
17
- <!-- alpine.js plugin -->
18
- <script src="https://cdn.jsdelivr.net/npm/@ramstack/alpinegear-hotkey@1/alpinegear-hotkey.min.js" defer></script>
19
-
20
- <!-- alpine.js -->
21
- <script src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js" defer></script>
22
- ```
23
-
24
- ### Using NPM
25
- Alternatively, you can install the plugin via `npm`:
26
-
27
- ```bash
28
- npm install --save @ramstack/alpinegear-hotkey
29
- ```
30
-
31
- Then initialize it in your bundle:
32
-
33
- ```js
34
- import Alpine from "alpinejs";
35
- import hotkey from "@ramstack/alpinegear-hotkey";
36
-
37
- Alpine.plugin(hotkey);
38
- Alpine.start();
39
- ```
40
-
41
- ## Usage
42
- Define a hotkey combination using the directive by specifying key modifiers (such as `Ctrl`, `Alt`, `Shift`) with a `+` sign
43
- (e.g., `Ctrl+Alt+Shift+S`).
44
-
45
- Here's a simple example:
46
-
47
- ```html
48
- <div x-data x-hotkey.shift+f.window="console.log($event.hotkey)">
49
- Hello, World!
50
- </div>
51
- ```
52
-
53
- > [!TIP]
54
- > The hotkey is **case-insensitive**. Standard key names are used.
55
- >
56
- > You can find a list of key names here [Key values for keyboard events](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values)
57
-
58
- ### Event Object
59
-
60
- The `x-hotkey` directive provides access to the native JavaScript event object via the magic `$event` property.
61
-
62
- ```html
63
- <div x-data x-hotkey.shift+f.window="console.log($event)"></div>
64
- ```
65
-
66
- Also, the `x-hotkey` automatically passes the event object as the first argument to the method handler:
67
-
68
- ```html
69
- <div x-data x-hotkey.shift+f.window="e => console.log(e)"></div>
70
-
71
- <!-- OR -->
72
- <div x-data x-hotkey.shift+f.window="handle"></div>
73
-
74
- <script>
75
- function handle(e) {
76
- console.log(e);
77
- }
78
- </script>
79
- ```
80
-
81
- ### Event Modifiers
82
- To simplify common tasks like calling `event.preventDefault()` or `event.stopPropagation()`,
83
- the `x-hotkey` directive supports following event modifiers:
84
- * `.prevent` - calls `event.preventDefault()` before calling the event handler.
85
- * `.stop` - call `event.stopPropagation()`, stopping the event from propagating further.
86
- * `.passive` - indicates that the handler will never call `event.preventDefault()`.
87
- * `.capture` - calling the event handler in the capture phase instead of the bubbling phase.
88
- * `.once` - ensures the event handler is called only once.
89
- * `.trusted` - ensures that only trusted events are handled.
90
-
91
- ```html
92
- <!-- prevent the default behavior for the keyboard event -->
93
- <div x-hotkey.ctrl+s.prevent="save($event)"></div>
94
-
95
- <!-- the event's propagation will be stopped -->
96
- <div x-hotkey.ctrl+s.stop="save($event)"></div>
97
-
98
- <!-- modifiers can be chained -->
99
- <div x-hotkey.ctrl+s.prevent.stop.trusted="save($event)"></div>
100
- ```
101
-
102
- ### Global Event Listening
103
- Use the `window` or `document` modifiers to listen for hotkeys globally, across the entire page:
104
-
105
- ```html
106
- <div x-hotkey.ctrl+s.window.prevent="save($event)"></div>
107
- ```
108
-
109
- ### Defining Alternative Hotkeys
110
- You can assign multiple hotkeys to a single action by separating them with a dot (`.`).
111
- For instance, in the example below, the same action is triggered by both `Ctrl + Shift + S` and `Alt + U`.
112
-
113
- To determine which hotkey triggered the event, use the `hotkey` property from the event object.
114
- This property contains the string representation of the hotkey.
115
-
116
- ```html
117
- <div x-data x-hotkey.ctrl+shift+f.alt+u.window="console.log($event.hotkey)">
118
- Hello, World!
119
- </div>
120
- ```
121
-
122
- ### Specific Events Listening
123
- To change the event that `x-hotkey` listens for, use a directive argument.
124
- By default, the event is `keydown`, but you can specify `keyup`, `keypress`, or others:
125
-
126
- ```html
127
- <div x-hotkey:keyup.alt+u="console.log('Search...')"></div>
128
- ```
129
-
130
- ### Exclude Elements
131
-
132
- If you want to prevent hotkey handling from being triggered by specific elements, add the `data-hotkey-ignore` attribute to those elements:
133
-
134
- ```html
135
- <div x-hotkey.shift+k="...">
136
- ...
137
- <!-- Ignoring hotkeys from the input element -->
138
- <input type="text" data-hotkey-ignore>
139
- </div>
140
- ```
141
-
142
- You can also exclude a group of elements by applying the attribute to their parent:
143
-
144
- ```html
145
- <div x-hotkey.shift+k="...">
146
- ...
147
-
148
- <!-- Ignoring hotkeys from all elements within the form -->
149
- <form data-hotkey-ignore>
150
- ...
151
- </form>
152
- </div>
153
- ```
154
-
155
- ## Source code
156
- You can find the source code for this plugin on GitHub:
157
-
158
- https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/hotkey
159
-
160
-
161
- ## Related projects
162
-
163
- **[@ramstack/alpinegear-main](https://www.npmjs.com/package/@ramstack/alpinegear-main)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/main))<br>
164
- Provides a combined plugin that includes several useful directives.
165
- This package aggregates multiple individual plugins, offering a convenient all-in-one bundle.
166
- Included directives: `x-bound`, `x-format`, `x-fragment`, `x-match`, `x-template`, and `x-when`.
167
-
168
- **[@ramstack/alpinegear-bound](https://www.npmjs.com/package/@ramstack/alpinegear-bound)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/bound))<br>
169
- Provides the `x-bound` directive, which allows for two-way binding of input elements and their associated data properties.
170
- It works similarly to the binding provided by [Svelte](https://svelte.dev/docs/element-directives#bind-property)
171
- and also supports synchronizing values between two `Alpine.js` data properties.
172
-
173
- **[@ramstack/alpinegear-format](https://www.npmjs.com/package/@ramstack/alpinegear-format)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/format))<br>
174
- Provides the `x-format` directive, which allows you to easily interpolate text using a template syntax similar to what's available in `Vue.js`.
175
-
176
- **[@ramstack/alpinegear-template](https://www.npmjs.com/package/@ramstack/alpinegear-template)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/template))<br>
177
- Provides the `x-template` directive, which allows you to define a template once anywhere in the DOM and reference it by its ID.
178
-
179
- **[@ramstack/alpinegear-fragment](https://www.npmjs.com/package/@ramstack/alpinegear-fragment)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/fragment))<br>
180
- Provides the `x-fragment` directive, which allows for fragment-like behavior similar to what's available in frameworks
181
- like `Vue.js` or `React`, where multiple root elements can be grouped together.
182
-
183
- **[@ramstack/alpinegear-match](https://www.npmjs.com/package/@ramstack/alpinegear-match)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/match))<br>
184
- Provides the `x-match` directive, which functions similarly to the `switch` statement in many programming languages,
185
- allowing you to conditionally render elements based on matching cases.
186
-
187
- **[@ramstack/alpinegear-when](https://www.npmjs.com/package/@ramstack/alpinegear-when)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/when))<br>
188
- Provides the `x-when` directive, which allows for conditional rendering of elements similar to `x-if`, but supports multiple root elements.
189
-
190
- **[@ramstack/alpinegear-destroy](https://www.npmjs.com/package/@ramstack/alpinegear-destroy)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/destroy))<br>
191
- Provides the `x-destroy` directive, which is the opposite of `x-init` and allows you to hook into the cleanup phase
192
- of any element, running a callback when the element is removed from the DOM.
193
-
194
- **[@ramstack/alpinegear-router](https://www.npmjs.com/package/@ramstack/alpinegear-router)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/router))<br>
195
- Provides the `x-router` and `x-route` directives, which enable client-side navigation and routing functionality within your Alpine.js application.
196
-
197
- **[@ramstack/alpinegear-dialog](https://www.npmjs.com/package/@ramstack/alpinegear-dialog)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/dialog))<br>
198
- Provides a headless dialog directive for Alpine.js based on the native HTML `<dialog>` element.
199
- It supports declarative composition, value-based close semantics, and both modal and non-modal dialogs,
200
- with optional Promise-based imperative control.
201
-
202
-
203
- ## Contributions
204
- Bug reports and contributions are welcome.
205
-
206
- ## License
207
- This package is released as open source under the **MIT License**.
208
- See the [LICENSE](https://github.com/rameel/ramstack.alpinegear.js/blob/main/LICENSE) file for more details.
1
+ # @ramstack/alpinegear-hotkey
2
+ [![NPM](https://img.shields.io/npm/v/@ramstack/alpinegear-hotkey)](https://www.npmjs.com/package/@ramstack/alpinegear-hotkey)
3
+ [![MIT](https://img.shields.io/github/license/rameel/ramstack.alpinegear.js)](https://github.com/rameel/ramstack.alpinegear.js/blob/main/LICENSE)
4
+
5
+ `@ramstack/alpinegear-hotkey` is a plugin for [Alpine.js](https://alpinejs.dev/) that provides the `x-hotkey` directive.
6
+
7
+ This directive allows you to easily handle keyboard shortcuts within your Alpine.js components or application.
8
+
9
+ Uses [@ramstack/hotkey](https://github.com/rameel/ramstack.hotkey.js) package under the hood.
10
+
11
+ ## Installation
12
+
13
+ ### Using CDN
14
+ To include the CDN version of this plugin, add the following `<script>` tag before the core `alpine.js` file:
15
+
16
+ ```html
17
+ <!-- alpine.js plugin -->
18
+ <script src="https://cdn.jsdelivr.net/npm/@ramstack/alpinegear-hotkey@1/alpinegear-hotkey.min.js" defer></script>
19
+
20
+ <!-- alpine.js -->
21
+ <script src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js" defer></script>
22
+ ```
23
+
24
+ ### Using NPM
25
+ Alternatively, you can install the plugin via `npm`:
26
+
27
+ ```bash
28
+ npm install --save @ramstack/alpinegear-hotkey
29
+ ```
30
+
31
+ Then initialize it in your bundle:
32
+
33
+ ```js
34
+ import Alpine from "alpinejs";
35
+ import hotkey from "@ramstack/alpinegear-hotkey";
36
+
37
+ Alpine.plugin(hotkey);
38
+ Alpine.start();
39
+ ```
40
+
41
+ ## Usage
42
+ Define a hotkey combination using the directive by specifying key modifiers (such as `Ctrl`, `Alt`, `Shift`)
43
+ with a `+` sign (e.g., `Ctrl+Alt+Shift+S`).
44
+
45
+ Here's a simple example:
46
+
47
+ ```html
48
+ <div x-data x-hotkey.shift+f.window="console.log($event.hotkey)">
49
+ Hello, World!
50
+ </div>
51
+ ```
52
+
53
+ > [!TIP]
54
+ > The hotkey is **case-insensitive**. Standard key names are used.
55
+ >
56
+ > You can find a list of key names here [Key values for keyboard events](https://developer.mozilla.org/en-US/docs/Web/API/UI_Events/Keyboard_event_key_values)
57
+
58
+ ### Event Object
59
+
60
+ The `x-hotkey` directive provides access to the native event object via the magic `$event` property.
61
+
62
+ ```html
63
+ <div x-data x-hotkey.shift+f.window="console.log($event)"></div>
64
+ ```
65
+
66
+ Also, the `x-hotkey` automatically passes the event object as the first argument to the method handler:
67
+
68
+ ```html
69
+ <div x-data x-hotkey.shift+f.window="e => console.log(e)"></div>
70
+
71
+ <!-- OR -->
72
+ <div x-data x-hotkey.shift+f.window="handle"></div>
73
+
74
+ <script>
75
+ function handle(e) {
76
+ console.log(e);
77
+ }
78
+ </script>
79
+ ```
80
+
81
+ ### Event Modifiers
82
+ To simplify common tasks like calling `event.preventDefault()` or `event.stopPropagation()`,
83
+ the `x-hotkey` directive supports following event modifiers:
84
+ * `.prevent` - calls `event.preventDefault()` before calling the event handler.
85
+ * `.stop` - call `event.stopPropagation()`, stopping the event from propagating further.
86
+ * `.passive` - indicates that the handler will never call `event.preventDefault()`.
87
+ * `.capture` - calling the event handler in the capture phase instead of the bubbling phase.
88
+ * `.once` - ensures the event handler is called only once.
89
+ * `.trusted` - ensures that only trusted events are handled.
90
+
91
+ ```html
92
+ <!-- prevent the default behavior for the keyboard event -->
93
+ <div x-hotkey.ctrl+s.prevent="save($event)"></div>
94
+
95
+ <!-- the event's propagation will be stopped -->
96
+ <div x-hotkey.ctrl+s.stop="save($event)"></div>
97
+
98
+ <!-- modifiers can be chained -->
99
+ <div x-hotkey.ctrl+s.prevent.stop.trusted="save($event)"></div>
100
+ ```
101
+
102
+ ### Global Event Listening
103
+ Use the `window` or `document` modifiers to listen for hotkeys globally, across the entire page:
104
+
105
+ ```html
106
+ <div x-hotkey.ctrl+s.window.prevent="save($event)"></div>
107
+ ```
108
+
109
+ ### Defining Alternative Hotkeys
110
+ You can assign multiple hotkeys to a single action by separating them with a dot (`.`).
111
+ For instance, in the example below, the same action is triggered by both `Ctrl + Shift + S` and `Alt + U`.
112
+
113
+ To determine which hotkey triggered the event, use the `hotkey` property from the event object.
114
+ This property contains the string representation of the hotkey.
115
+
116
+ ```html
117
+ <div x-data x-hotkey.ctrl+shift+f.alt+u.window="console.log($event.hotkey)">
118
+ Hello, World!
119
+ </div>
120
+ ```
121
+
122
+ ### Specific Events Listening
123
+ To change the event that `x-hotkey` listens for, use a directive argument.
124
+ By default, the event is `keydown`, but you can specify `keyup`, `keypress`, or others:
125
+
126
+ ```html
127
+ <div x-hotkey:keyup.alt+u="console.log('Search...')"></div>
128
+ ```
129
+
130
+ ### Exclude Elements
131
+
132
+ If you want to prevent hotkey handling from being triggered by specific elements,
133
+ add the `data-hotkey-ignore` attribute to those elements:
134
+
135
+ ```html
136
+ <div x-hotkey.shift+k="...">
137
+ ...
138
+ <!-- Ignoring hotkeys from the input element -->
139
+ <input type="text" data-hotkey-ignore>
140
+ </div>
141
+ ```
142
+
143
+ You can also exclude a group of elements by applying the attribute to their parent:
144
+
145
+ ```html
146
+ <div x-hotkey.shift+k="...">
147
+ ...
148
+
149
+ <!-- Ignoring hotkeys from all elements within the form -->
150
+ <form data-hotkey-ignore>
151
+ ...
152
+ </form>
153
+ </div>
154
+ ```
155
+
156
+ ## Source code
157
+ You can find the source code for this plugin on GitHub:
158
+
159
+ https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/hotkey
160
+
161
+
162
+ ## Related packages
163
+ This package is part of **[AlpineGear](https://github.com/rameel/ramstack.alpinegear.js)** —
164
+ a collection of utilities and directives for [Alpine.js](https://alpinejs.dev).
165
+
166
+ You can find the full list of related packages and their documentation here:
167
+ https://github.com/rameel/ramstack.alpinegear.js
168
+
169
+
170
+ ## Contributions
171
+ Bug reports and contributions are welcome.
172
+
173
+ ## License
174
+ This package is released as open source under the **MIT License**.
175
+ See the [LICENSE](https://github.com/rameel/ramstack.alpinegear.js/blob/main/LICENSE) file for more details.
@@ -90,54 +90,54 @@ function error(message) {
90
90
  throw new Error(message);
91
91
  }
92
92
 
93
- const has_modifier = (modifiers, modifier) => modifiers.includes(modifier);
94
-
95
- const single = (...fns) => (...args) => {
96
- for (const fn of fns) {
97
- fn && fn(...args);
98
- }
93
+ const has_modifier = (modifiers, modifier) => modifiers.includes(modifier);
94
+
95
+ const single = (...fns) => (...args) => {
96
+ for (const fn of fns) {
97
+ fn && fn(...args);
98
+ }
99
99
  };
100
100
 
101
- const option_keys = ["capture", "passive", "once", "prevent", "stop", "trusted", "window", "document"];
102
-
103
- function plugin({ directive }) {
104
- directive("hotkey", (el, { expression, value, modifiers }, { evaluateLater, cleanup }) => {
105
- const listener = e => evaluate(() => { }, { scope: { $event: e }, params: [e] });
106
-
107
- const evaluate = expression
108
- ? evaluateLater(expression)
109
- : () => {};
110
-
111
- const target =
112
- has_modifier(modifiers, "window")
113
- ? window
114
- : has_modifier(modifiers, "document")
115
- ? document
116
- : el;
117
-
118
- const disposes = modifiers
119
- .filter(m => !option_keys.includes(m))
120
- .flatMap(s => s.split(","))
121
- .map(hotkey => registerHotkey(
122
- target,
123
- hotkey,
124
- e => {
125
- has_modifier(modifiers, "prevent") && e.preventDefault();
126
- has_modifier(modifiers, "stop") && e.stopPropogation();
127
-
128
- e.hotkey = hotkey;
129
- listener(e);
130
- },
131
- value || "keydown",
132
- {
133
- capture: has_modifier(modifiers, "capture"),
134
- passive: has_modifier(modifiers, "passive"),
135
- once: has_modifier(modifiers, "once"),
136
- trusted: has_modifier(modifiers, "trusted")
137
- }));
138
-
139
- cleanup(single(...disposes));
140
- });
101
+ const option_keys = ["capture", "passive", "once", "prevent", "stop", "trusted", "window", "document"];
102
+
103
+ function plugin({ directive }) {
104
+ directive("hotkey", (el, { expression, value, modifiers }, { evaluateLater, cleanup }) => {
105
+ const listener = e => evaluate(() => { }, { scope: { $event: e }, params: [e] });
106
+
107
+ const evaluate = expression
108
+ ? evaluateLater(expression)
109
+ : () => {};
110
+
111
+ const target =
112
+ has_modifier(modifiers, "window")
113
+ ? window
114
+ : has_modifier(modifiers, "document")
115
+ ? document
116
+ : el;
117
+
118
+ const disposes = modifiers
119
+ .filter(m => !option_keys.includes(m))
120
+ .flatMap(s => s.split(","))
121
+ .map(hotkey => registerHotkey(
122
+ target,
123
+ hotkey,
124
+ e => {
125
+ has_modifier(modifiers, "prevent") && e.preventDefault();
126
+ has_modifier(modifiers, "stop") && e.stopPropogation();
127
+
128
+ e.hotkey = hotkey;
129
+ listener(e);
130
+ },
131
+ value || "keydown",
132
+ {
133
+ capture: has_modifier(modifiers, "capture"),
134
+ passive: has_modifier(modifiers, "passive"),
135
+ once: has_modifier(modifiers, "once"),
136
+ trusted: has_modifier(modifiers, "trusted")
137
+ }));
138
+
139
+ cleanup(single(...disposes));
140
+ });
141
141
  }
142
142
 
143
- export { plugin as hotkey };
143
+ export { plugin as default, plugin as hotkey };
@@ -1 +1 @@
1
- const e={esc:"escape",ins:"insert",del:"delete",up:"arrowup",down:"arrowdown",right:"arrowright",left:"arrowleft",pgup:"pageup",pgdn:"pagedown",break:"pause",scroll:"scrolllock",scrlk:"scrolllock",prtscr:"printscreen",win:"meta",windows:"meta",cmd:"meta",command:"meta",comma:",",period:".",quote:'"',singlequote:"'",colon:":",semicolon:";",plus:"+",minus:"-",tilde:"~",equal:"=",slash:"/"},t=["ctrlKey","altKey","shiftKey","metaKey"];function o(e){r(`Invalid hotkey: '${e}'`)}function r(e){throw new Error(e)}const n=(e,t)=>e.includes(t),s=["capture","passive","once","prevent","stop","trusted","window","document"];function c({directive:c}){c("hotkey",(c,{expression:a,value:i,modifiers:l},{evaluateLater:u,cleanup:p})=>{const d=a?u(a):()=>{},m=n(l,"window")?window:n(l,"document")?document:c;p(((...e)=>(...t)=>{for(const o of e)o&&o(...t)})(...l.filter(e=>!s.includes(e)).flatMap(e=>e.split(",")).map(s=>function(n,s,c,a="keydown",i){const l=function(t){const r=t.replace(/\s+/g,"").toLowerCase().split("+").reduce((r,n)=>{switch(n=e[n]??n){case"ctrl":case"alt":case"shift":case"meta":r[`${n}Key`]=!0;break;default:n.length||o(t),n=n.toUpperCase(),r.code=1!==n.length||"A">n||n>"Z"?n:`KEY${n}`}return r},{code:"",ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1});return r.code||o(t),r}(s);return"string"==typeof n&&(n=document.querySelector(n)??r(`No element found for selector '${n}'`)),function(e,t,o,r){return e.addEventListener(t,o,r),()=>e.removeEventListener(t,o,r)}(n,a,function(e){i?.trusted&&!e.isTrusted||e.target?.closest("[data-hotkey-ignore]")||l.code===e.code.toUpperCase()&&t.every(t=>l[t]===e[t])&&c.call(this,e)},i)}(m,s,e=>{n(l,"prevent")&&e.preventDefault(),n(l,"stop")&&e.stopPropogation(),e.hotkey=s,(e=>{d(()=>{},{scope:{$event:e},params:[e]})})(e)},i||"keydown",{capture:n(l,"capture"),passive:n(l,"passive"),once:n(l,"once"),trusted:n(l,"trusted")}))))})}export{c as hotkey};
1
+ const e={esc:"escape",ins:"insert",del:"delete",up:"arrowup",down:"arrowdown",right:"arrowright",left:"arrowleft",pgup:"pageup",pgdn:"pagedown",break:"pause",scroll:"scrolllock",scrlk:"scrolllock",prtscr:"printscreen",win:"meta",windows:"meta",cmd:"meta",command:"meta",comma:",",period:".",quote:'"',singlequote:"'",colon:":",semicolon:";",plus:"+",minus:"-",tilde:"~",equal:"=",slash:"/"},t=["ctrlKey","altKey","shiftKey","metaKey"];function o(e){r(`Invalid hotkey: '${e}'`)}function r(e){throw new Error(e)}const n=(e,t)=>e.includes(t),s=["capture","passive","once","prevent","stop","trusted","window","document"];function c({directive:c}){c("hotkey",(c,{expression:a,value:l,modifiers:i},{evaluateLater:u,cleanup:d})=>{const p=a?u(a):()=>{},f=n(i,"window")?window:n(i,"document")?document:c;d(((...e)=>(...t)=>{for(const o of e)o&&o(...t)})(...i.filter(e=>!s.includes(e)).flatMap(e=>e.split(",")).map(s=>function(n,s,c,a="keydown",l){const i=function(t){const r=t.replace(/\s+/g,"").toLowerCase().split("+").reduce((r,n)=>{switch(n=e[n]??n){case"ctrl":case"alt":case"shift":case"meta":r[`${n}Key`]=!0;break;default:n.length||o(t),n=n.toUpperCase(),r.code=1!==n.length||"A">n||n>"Z"?n:`KEY${n}`}return r},{code:"",ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1});return r.code||o(t),r}(s);return"string"==typeof n&&(n=document.querySelector(n)??r(`No element found for selector '${n}'`)),function(e,t,o,r){return e.addEventListener(t,o,r),()=>e.removeEventListener(t,o,r)}(n,a,function(e){l?.trusted&&!e.isTrusted||e.target?.closest("[data-hotkey-ignore]")||i.code===e.code.toUpperCase()&&t.every(t=>i[t]===e[t])&&c.call(this,e)},l)}(f,s,e=>{n(i,"prevent")&&e.preventDefault(),n(i,"stop")&&e.stopPropogation(),e.hotkey=s,(e=>{p(()=>{},{scope:{$event:e},params:[e]})})(e)},l||"keydown",{capture:n(i,"capture"),passive:n(i,"passive"),once:n(i,"once"),trusted:n(i,"trusted")}))))})}export{c as default,c as hotkey};
@@ -1,6 +1,19 @@
1
1
  (function () {
2
2
  'use strict';
3
3
 
4
+ const has_modifier = (modifiers, modifier) => modifiers.includes(modifier);
5
+
6
+ const listen$1 = (target, type, listener, options) => {
7
+ target.addEventListener(type, listener, options);
8
+ return () => target.removeEventListener(type, listener, options);
9
+ };
10
+
11
+ const single = (...fns) => (...args) => {
12
+ for (const fn of fns) {
13
+ fn && fn(...args);
14
+ }
15
+ };
16
+
4
17
  const aliases = {
5
18
  "esc": "escape",
6
19
  "ins": "insert",
@@ -93,56 +106,48 @@
93
106
  throw new Error(message);
94
107
  }
95
108
 
96
- const has_modifier = (modifiers, modifier) => modifiers.includes(modifier);
97
-
98
- const single = (...fns) => (...args) => {
99
- for (const fn of fns) {
100
- fn && fn(...args);
101
- }
102
- };
109
+ const option_keys = ["capture", "passive", "once", "prevent", "stop", "trusted", "window", "document"];
103
110
 
104
- const option_keys = ["capture", "passive", "once", "prevent", "stop", "trusted", "window", "document"];
105
-
106
- function plugin({ directive }) {
107
- directive("hotkey", (el, { expression, value, modifiers }, { evaluateLater, cleanup }) => {
108
- const listener = e => evaluate(() => { }, { scope: { $event: e }, params: [e] });
109
-
110
- const evaluate = expression
111
- ? evaluateLater(expression)
112
- : () => {};
113
-
114
- const target =
115
- has_modifier(modifiers, "window")
116
- ? window
117
- : has_modifier(modifiers, "document")
118
- ? document
119
- : el;
120
-
121
- const disposes = modifiers
122
- .filter(m => !option_keys.includes(m))
123
- .flatMap(s => s.split(","))
124
- .map(hotkey => registerHotkey(
125
- target,
126
- hotkey,
127
- e => {
128
- has_modifier(modifiers, "prevent") && e.preventDefault();
129
- has_modifier(modifiers, "stop") && e.stopPropogation();
130
-
131
- e.hotkey = hotkey;
132
- listener(e);
133
- },
134
- value || "keydown",
135
- {
136
- capture: has_modifier(modifiers, "capture"),
137
- passive: has_modifier(modifiers, "passive"),
138
- once: has_modifier(modifiers, "once"),
139
- trusted: has_modifier(modifiers, "trusted")
140
- }));
141
-
142
- cleanup(single(...disposes));
143
- });
111
+ function plugin({ directive }) {
112
+ directive("hotkey", (el, { expression, value, modifiers }, { evaluateLater, cleanup }) => {
113
+ const listener = e => evaluate(() => { }, { scope: { $event: e }, params: [e] });
114
+
115
+ const evaluate = expression
116
+ ? evaluateLater(expression)
117
+ : () => {};
118
+
119
+ const target =
120
+ has_modifier(modifiers, "window")
121
+ ? window
122
+ : has_modifier(modifiers, "document")
123
+ ? document
124
+ : el;
125
+
126
+ const disposes = modifiers
127
+ .filter(m => !option_keys.includes(m))
128
+ .flatMap(s => s.split(","))
129
+ .map(hotkey => registerHotkey(
130
+ target,
131
+ hotkey,
132
+ e => {
133
+ has_modifier(modifiers, "prevent") && e.preventDefault();
134
+ has_modifier(modifiers, "stop") && e.stopPropogation();
135
+
136
+ e.hotkey = hotkey;
137
+ listener(e);
138
+ },
139
+ value || "keydown",
140
+ {
141
+ capture: has_modifier(modifiers, "capture"),
142
+ passive: has_modifier(modifiers, "passive"),
143
+ once: has_modifier(modifiers, "once"),
144
+ trusted: has_modifier(modifiers, "trusted")
145
+ }));
146
+
147
+ cleanup(single(...disposes));
148
+ });
144
149
  }
145
150
 
146
- document.addEventListener("alpine:init", () => { Alpine.plugin(plugin); });
151
+ listen$1(document, "alpine:init", () => Alpine.plugin(plugin));
147
152
 
148
153
  })();
@@ -1 +1 @@
1
- !function(){"use strict";const e={esc:"escape",ins:"insert",del:"delete",up:"arrowup",down:"arrowdown",right:"arrowright",left:"arrowleft",pgup:"pageup",pgdn:"pagedown",break:"pause",scroll:"scrolllock",scrlk:"scrolllock",prtscr:"printscreen",win:"meta",windows:"meta",cmd:"meta",command:"meta",comma:",",period:".",quote:'"',singlequote:"'",colon:":",semicolon:";",plus:"+",minus:"-",tilde:"~",equal:"=",slash:"/"},t=["ctrlKey","altKey","shiftKey","metaKey"];function o(e){n(`Invalid hotkey: '${e}'`)}function n(e){throw new Error(e)}const r=(e,t)=>e.includes(t),s=["capture","passive","once","prevent","stop","trusted","window","document"];function c({directive:c}){c("hotkey",(c,{expression:a,value:i,modifiers:l},{evaluateLater:u,cleanup:d})=>{const p=a?u(a):()=>{},m=r(l,"window")?window:r(l,"document")?document:c;d(((...e)=>(...t)=>{for(const o of e)o&&o(...t)})(...l.filter(e=>!s.includes(e)).flatMap(e=>e.split(",")).map(s=>function(r,s,c,a="keydown",i){const l=function(t){const n=t.replace(/\s+/g,"").toLowerCase().split("+").reduce((n,r)=>{switch(r=e[r]??r){case"ctrl":case"alt":case"shift":case"meta":n[`${r}Key`]=!0;break;default:r.length||o(t),r=r.toUpperCase(),n.code=1!==r.length||"A">r||r>"Z"?r:`KEY${r}`}return n},{code:"",ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1});return n.code||o(t),n}(s);return"string"==typeof r&&(r=document.querySelector(r)??n(`No element found for selector '${r}'`)),function(e,t,o,n){return e.addEventListener(t,o,n),()=>e.removeEventListener(t,o,n)}(r,a,function(e){i?.trusted&&!e.isTrusted||e.target?.closest("[data-hotkey-ignore]")||l.code===e.code.toUpperCase()&&t.every(t=>l[t]===e[t])&&c.call(this,e)},i)}(m,s,e=>{r(l,"prevent")&&e.preventDefault(),r(l,"stop")&&e.stopPropogation(),e.hotkey=s,(e=>{p(()=>{},{scope:{$event:e},params:[e]})})(e)},i||"keydown",{capture:r(l,"capture"),passive:r(l,"passive"),once:r(l,"once"),trusted:r(l,"trusted")}))))})}document.addEventListener("alpine:init",()=>{Alpine.plugin(c)})}();
1
+ !function(){"use strict";const e=(e,t)=>e.includes(t),t={esc:"escape",ins:"insert",del:"delete",up:"arrowup",down:"arrowdown",right:"arrowright",left:"arrowleft",pgup:"pageup",pgdn:"pagedown",break:"pause",scroll:"scrolllock",scrlk:"scrolllock",prtscr:"printscreen",win:"meta",windows:"meta",cmd:"meta",command:"meta",comma:",",period:".",quote:'"',singlequote:"'",colon:":",semicolon:";",plus:"+",minus:"-",tilde:"~",equal:"=",slash:"/"},o=["ctrlKey","altKey","shiftKey","metaKey"];function n(e){r(`Invalid hotkey: '${e}'`)}function r(e){throw new Error(e)}const s=["capture","passive","once","prevent","stop","trusted","window","document"];function c({directive:c}){c("hotkey",(c,{expression:a,value:i,modifiers:l},{evaluateLater:u,cleanup:d})=>{const p=a?u(a):()=>{},m=e(l,"window")?window:e(l,"document")?document:c;d(((...e)=>(...t)=>{for(const o of e)o&&o(...t)})(...l.filter(e=>!s.includes(e)).flatMap(e=>e.split(",")).map(s=>function(e,s,c,a="keydown",i){const l=function(e){const o=e.replace(/\s+/g,"").toLowerCase().split("+").reduce((o,r)=>{switch(r=t[r]??r){case"ctrl":case"alt":case"shift":case"meta":o[`${r}Key`]=!0;break;default:r.length||n(e),r=r.toUpperCase(),o.code=1!==r.length||"A">r||r>"Z"?r:`KEY${r}`}return o},{code:"",ctrlKey:!1,altKey:!1,shiftKey:!1,metaKey:!1});return o.code||n(e),o}(s);return"string"==typeof e&&(e=document.querySelector(e)??r(`No element found for selector '${e}'`)),function(e,t,o,n){return e.addEventListener(t,o,n),()=>e.removeEventListener(t,o,n)}(e,a,function(e){i?.trusted&&!e.isTrusted||e.target?.closest("[data-hotkey-ignore]")||l.code===e.code.toUpperCase()&&o.every(t=>l[t]===e[t])&&c.call(this,e)},i)}(m,s,t=>{e(l,"prevent")&&t.preventDefault(),e(l,"stop")&&t.stopPropogation(),t.hotkey=s,(e=>{p(()=>{},{scope:{$event:e},params:[e]})})(t)},i||"keydown",{capture:e(l,"capture"),passive:e(l,"passive"),once:e(l,"once"),trusted:e(l,"trusted")}))))})}document.addEventListener("alpine:init",()=>Alpine.plugin(c),void 0)}();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ramstack/alpinegear-hotkey",
3
- "version": "1.4.3",
3
+ "version": "1.4.4",
4
4
  "description": "@ramstack/alpinegear-hotkey provides 'x-hotkey' Alpine.js directive, allowing easily handle keyboard shortcuts.",
5
5
  "author": "Rameel Burhan",
6
6
  "license": "MIT",
@@ -19,6 +19,12 @@
19
19
  "alpinejs-directive",
20
20
  "alpinejs-plugin"
21
21
  ],
22
- "main": "alpinegear-hotkey.js",
23
- "module": "alpinegear-hotkey.esm.js"
22
+ "exports": {
23
+ ".": {
24
+ "import": {
25
+ "production": "./alpinegear-hotkey.esm.min.js",
26
+ "default": "./alpinegear-hotkey.esm.js"
27
+ }
28
+ }
29
+ }
24
30
  }