@tanstack/solid-hotkeys 0.3.3 → 0.4.1

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.
Files changed (2) hide show
  1. package/README.md +122 -305
  2. package/package.json +3 -3
package/README.md CHANGED
@@ -1,305 +1,122 @@
1
- # @tanstack/solid-hotkeys
2
-
3
- > SolidJS adapter for [TanStack Hotkeys](https://tanstack.com/hotkeys) - keyboard shortcuts made easy
4
-
5
- [![npm version](https://img.shields.io/npm/v/@tanstack/solid-hotkeys.svg)](https://www.npmjs.com/package/@tanstack/solid-hotkeys)
6
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
-
8
- ## Features
9
-
10
- ✅ **Type-safe hotkey bindings** - Template strings (`Mod+Shift+S`, `Escape`) or parsed objects
11
- ✅ **Cross-platform** - `Mod` key automatically maps to Cmd on macOS, Ctrl on Windows/Linux
12
- ✅ **Sequence support** - Vim-style multi-key sequences (`g g`, `d d`)
13
- ✅ **Key state tracking** - Track which keys are currently held down
14
- ✅ **Hotkey recording** - Built-in UI helpers for letting users define their own shortcuts
15
- ✅ **SolidJS primitives** - Reactive primitives that work seamlessly with SolidJS
16
-
17
- ## Installation
18
-
19
- ```bash
20
- npm install @tanstack/solid-hotkeys @tanstack/hotkeys
21
- # or
22
- bun add @tanstack/solid-hotkeys @tanstack/hotkeys
23
- # or
24
- pnpm add @tanstack/solid-hotkeys @tanstack/hotkeys
25
- ```
26
-
27
- ## Quick Start
28
-
29
- ```tsx
30
- import { createHotkey } from '@tanstack/solid-hotkeys'
31
-
32
- function App() {
33
- createHotkey('Mod+S', (event) => {
34
- event.preventDefault()
35
- console.log('Save!')
36
- })
37
-
38
- return <div>Press Cmd/Ctrl+S to save</div>
39
- }
40
- ```
41
-
42
- ## Usage
43
-
44
- ### Basic Hotkey
45
-
46
- ```tsx
47
- import { createHotkey } from '@tanstack/solid-hotkeys'
48
-
49
- function SaveButton() {
50
- createHotkey('Mod+S', (event, { hotkey }) => {
51
- event.preventDefault()
52
- handleSave()
53
- })
54
-
55
- return <button>Save (Cmd/Ctrl+S)</button>
56
- }
57
- ```
58
-
59
- ### Conditional Hotkeys
60
-
61
- ```tsx
62
- import { createHotkey } from '@tanstack/solid-hotkeys'
63
- import { Show, createSignal } from 'solid-js'
64
-
65
- function Modal(props) {
66
- // Hotkey only active when modal is open
67
- createHotkey(
68
- 'Escape',
69
- () => props.onClose(),
70
- () => ({
71
- enabled: props.isOpen,
72
- }),
73
- )
74
-
75
- return (
76
- <Show when={props.isOpen}>
77
- <div class="modal">Press Escape to close</div>
78
- </Show>
79
- )
80
- }
81
- ```
82
-
83
- ### Scoped Hotkeys
84
-
85
- ```tsx
86
- import { createHotkey } from '@tanstack/solid-hotkeys'
87
-
88
- function Editor() {
89
- let editorRef: HTMLDivElement | undefined
90
-
91
- // Hotkey only works when editor is focused
92
- createHotkey(
93
- 'Mod+B',
94
- () => {
95
- toggleBold()
96
- },
97
- { target: editorRef },
98
- )
99
-
100
- return <div ref={editorRef} contentEditable />
101
- }
102
- ```
103
-
104
- ### Hotkey Sequences (Vim-style)
105
-
106
- ```tsx
107
- import { createHotkeySequence } from '@tanstack/solid-hotkeys'
108
-
109
- function VimEditor() {
110
- // 'g g' to go to top
111
- createHotkeySequence(['G', 'G'], () => {
112
- scrollToTop()
113
- })
114
-
115
- // 'd d' to delete line
116
- createHotkeySequence(['D', 'D'], () => {
117
- deleteLine()
118
- })
119
-
120
- // 'd i w' to delete inner word
121
- createHotkeySequence(
122
- ['D', 'I', 'W'],
123
- () => {
124
- deleteInnerWord()
125
- },
126
- { timeout: 500 },
127
- )
128
-
129
- return <div>Try Vim shortcuts!</div>
130
- }
131
- ```
132
-
133
- ### Track Held Keys
134
-
135
- ```tsx
136
- import { createHeldKeys, createKeyHold } from '@tanstack/solid-hotkeys'
137
- import { For } from 'solid-js'
138
-
139
- function KeyTracker() {
140
- const heldKeys = createHeldKeys()
141
- const shiftHeld = createKeyHold('Shift')
142
-
143
- return (
144
- <div>
145
- <div>Shift: {shiftHeld() ? 'Pressed' : 'Not pressed'}</div>
146
- <div>
147
- All held keys:
148
- <For each={heldKeys()}>{(key) => <kbd>{key}</kbd>}</For>
149
- </div>
150
- </div>
151
- )
152
- }
153
- ```
154
-
155
- ### Hotkey Recorder
156
-
157
- ```tsx
158
- import { createHotkeyRecorder } from '@tanstack/solid-hotkeys'
159
- import { createSignal, Show } from 'solid-js'
160
-
161
- function ShortcutSettings() {
162
- const [shortcut, setShortcut] = createSignal('Mod+S')
163
-
164
- const recorder = createHotkeyRecorder({
165
- onRecord: (hotkey) => {
166
- setShortcut(hotkey)
167
- },
168
- onCancel: () => {
169
- console.log('Recording cancelled')
170
- },
171
- })
172
-
173
- return (
174
- <div>
175
- <div>Current shortcut: {shortcut()}</div>
176
- <button onClick={recorder.startRecording}>
177
- {recorder.isRecording() ? 'Recording...' : 'Edit Shortcut'}
178
- </button>
179
- <Show when={recorder.recordedHotkey()}>
180
- <div>Preview: {recorder.recordedHotkey()}</div>
181
- </Show>
182
- </div>
183
- )
184
- }
185
- ```
186
-
187
- ### Global Configuration
188
-
189
- ```tsx
190
- import { HotkeysProvider } from '@tanstack/solid-hotkeys'
191
-
192
- function App() {
193
- return (
194
- <HotkeysProvider
195
- defaultOptions={{
196
- hotkey: {
197
- preventDefault: true,
198
- enabled: true,
199
- },
200
- hotkeySequence: {
201
- timeout: 1000,
202
- },
203
- }}
204
- >
205
- <YourApp />
206
- </HotkeysProvider>
207
- )
208
- }
209
- ```
210
-
211
- ## API
212
-
213
- ### `createHotkey(hotkey, callback, options?)`
214
-
215
- Register a keyboard hotkey.
216
-
217
- - `hotkey`: String like `"Mod+S"` or `"Escape"`, or accessor function
218
- - `callback`: Function called when hotkey is pressed
219
- - `options`: Optional configuration (or accessor function for reactive options)
220
-
221
- **Options:**
222
-
223
- - `enabled`: Whether the hotkey is active (default: `true`)
224
- - `preventDefault`: Prevent default browser behavior (default: `false`)
225
- - `stopPropagation`: Stop event propagation (default: `false`)
226
- - `target`: DOM element to attach listener to (default: `document`)
227
- - `platform`: Override platform detection
228
-
229
- ### `createHotkeySequence(sequence, callback, options?)`
230
-
231
- Register a multi-key sequence (Vim-style).
232
-
233
- - `sequence`: Array of hotkey strings like `["G", "G"]`, or accessor function
234
- - `callback`: Function called when sequence completes
235
- - `options`: Optional configuration (or accessor function)
236
-
237
- **Options:**
238
-
239
- - `enabled`: Whether sequence detection is active (default: `true`)
240
- - `timeout`: Max time between keys in ms (default: `1000`)
241
- - `platform`: Override platform detection
242
-
243
- ### `createHeldKeys()`
244
-
245
- Returns a signal accessor for array of currently held keys.
246
-
247
- ```tsx
248
- const heldKeys = createHeldKeys()
249
- // heldKeys() => ["Shift", "A"]
250
- ```
251
-
252
- ### `createHeldKeyCodes()`
253
-
254
- Returns a signal accessor for map of held keys to their physical key codes.
255
-
256
- ```tsx
257
- const heldCodes = createHeldKeyCodes()
258
- // heldCodes() => { "Shift": "ShiftLeft", "A": "KeyA" }
259
- ```
260
-
261
- ### `createKeyHold(key)`
262
-
263
- Returns a signal accessor that's true when specific key is held.
264
-
265
- ```tsx
266
- const isShiftHeld = createKeyHold('Shift')
267
- // isShiftHeld() => true/false
268
- ```
269
-
270
- ### `createHotkeyRecorder(options)`
271
-
272
- Hotkey recording interface.
273
-
274
- **Options:**
275
-
276
- - `onRecord`: Callback when hotkey is recorded
277
- - `onCancel`: Callback when recording is cancelled
278
-
279
- **Returns:**
280
-
281
- - `isRecording`: Signal accessor for recording state
282
- - `recordedHotkey`: Signal accessor for current hotkey preview
283
- - `startRecording`: Function to start recording
284
- - `stopRecording`: Function to stop recording
285
- - `cancelRecording`: Function to cancel recording
286
-
287
- ### `HotkeysProvider`
288
-
289
- Optional provider for global configuration.
290
-
291
- ## Cross-Platform Keys
292
-
293
- Use `Mod` for cross-platform modifier:
294
-
295
- - `Mod+S` → `Cmd+S` on macOS, `Ctrl+S` on Windows/Linux
296
- - `Mod+Shift+P` → `Cmd+Shift+P` on macOS, `Ctrl+Shift+P` elsewhere
297
-
298
- ## Related
299
-
300
- - [TanStack Hotkeys](https://tanstack.com/hotkeys) - The core library
301
- - [@tanstack/react-hotkeys](https://tanstack.com/hotkeys) - React adapter
302
-
303
- ## License
304
-
305
- MIT
1
+ <div align="center">
2
+ <img src="./media/header_hotkeys.png" alt="TanStack Hotkeys" />
3
+ </div>
4
+
5
+ <br />
6
+
7
+ <div align="center">
8
+ <a href="https://www.npmjs.com/package/@tanstack/hotkeys" target="\_parent">
9
+ <img alt="" src="https://img.shields.io/npm/dm/@tanstack/hotkeys.svg" alt="npm downloads" />
10
+ </a>
11
+ <a href="https://github.com/TanStack/hotkeys" target="\_parent">
12
+ <img alt="" src="https://img.shields.io/github/stars/TanStack/hotkeys.svg?style=social&label=Star" alt="GitHub stars" />
13
+ </a>
14
+ <a href="https://bundlephobia.com/result?p=@tanstack/react-hotkeys@latest" target="\_parent">
15
+ <img alt="" src="https://badgen.net/bundlephobia/minzip/@tanstack/react-hotkeys@latest" alt="Bundle size" />
16
+ </a>
17
+ </div>
18
+
19
+ <div align="center">
20
+ <a href="#badge">
21
+ <img alt="semantic-release" src="https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg">
22
+ </a>
23
+ <a href="#badge">
24
+ <img src="https://img.shields.io/github/v/release/tanstack/hotkeys" alt="Release"/>
25
+ </a>
26
+ <a href="https://twitter.com/tan_stack">
27
+ <img src="https://img.shields.io/twitter/follow/tan_stack.svg?style=social" alt="Follow @TanStack"/>
28
+ </a>
29
+ </div>
30
+
31
+ <div align="center">
32
+
33
+ ### [Become a Sponsor!](https://github.com/sponsors/tannerlinsley/)
34
+
35
+ </div>
36
+
37
+ # TanStack Hotkeys
38
+
39
+ > [!NOTE]
40
+ > TanStack Hotkeys is pre-alpha (prototyping phase). We are actively developing the library and are open to feedback and contributions.
41
+
42
+ Type-safe keyboard shortcuts for the web. Template-string bindings, parsed objects, a cross-platform `Mod` key, a singleton Hotkey Manager, and utilities for cheatsheet UIs—built to stay SSR-friendly.
43
+
44
+ - Type-safe bindings — template strings (`Mod+Shift+S`, `Escape`) or parsed objects for full control
45
+ - Flexible options — `keydown`/`keyup`, `preventDefault`, `stopPropagation`, conditional enabled, `requireReset`
46
+ - Cross-platform Mod — maps to Cmd on macOS and Ctrl on Windows/Linux
47
+ - Batteries included — validation + matching, sequences (Vim-style), key-state tracking, recorder UI helpers, framework adapters, and devtools
48
+
49
+ ### <a href="https://tanstack.com/hotkeys">Read the docs →</a>
50
+
51
+ <br />
52
+
53
+ > [!NOTE]
54
+ > You may know **TanStack Hotkeys** by our adapter names, too!
55
+ >
56
+ > - [**React Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/react/react-hotkeys)
57
+ > - [**Preact Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/preact/preact-hotkeys)
58
+ > - [**Solid Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/solid/reference)
59
+ > - [**Angular Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/angular/reference)
60
+ > - [**Vue Hotkeys**](https://tanstack.com/hotkeys/latest/docs/framework/vue/reference)
61
+ > - Svelte Hotkeys – needs a contributor!
62
+
63
+ ## Get Involved
64
+
65
+ - We welcome issues and pull requests!
66
+ - Participate in [GitHub discussions](https://github.com/TanStack/hotkeys/discussions)
67
+ - Chat with the community on [Discord](https://discord.com/invite/WrRKjPJ)
68
+ - See [CONTRIBUTING.md](./CONTRIBUTING.md) for setup instructions
69
+
70
+ ## Partners
71
+
72
+ <div align="center">
73
+
74
+ <table align="center">
75
+ <tr>
76
+ <td>
77
+ <a href="https://www.coderabbit.ai/?via=tanstack&dub_id=aCcEEdAOqqutX6OS" >
78
+ <picture>
79
+ <source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/coderabbit-dark-D643Zkrv.svg" height="40" />
80
+ <source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/coderabbit-light-CIzGLYU_.svg" height="40" />
81
+ <img src="https://tanstack.com/assets/coderabbit-light-DVMJ2jHi.svg" height="40" alt="CodeRabbit" />
82
+ </picture>
83
+ </a>
84
+ </td>
85
+ <td>
86
+ <a href="https://www.cloudflare.com?utm_source=tanstack">
87
+ <picture>
88
+ <source media="(prefers-color-scheme: dark)" srcset="https://tanstack.com/assets/cloudflare-white-Co-Tyjbl.svg" height="60" />
89
+ <source media="(prefers-color-scheme: light)" srcset="https://tanstack.com/assets/cloudflare-black-6Ojsn8yh.svg" height="60" />
90
+ <img src="https://tanstack.com/assets/cloudflare-black-CPufaW0B.svg" height="60" alt="Cloudflare" />
91
+ </picture>
92
+ </a>
93
+ </td>
94
+ </tr>
95
+ </table>
96
+
97
+ <div align="center">
98
+ <img src="media/partner_logo.svg" alt="Keys & you?" height="65">
99
+ <p>
100
+ We're looking for TanStack Hotkeys Partners to join our mission! Partner with us to push the boundaries of TanStack Hotkeys and build amazing things together.
101
+ </p>
102
+ <a href="mailto:partners@tanstack.com?subject=TanStack Hotkeys Partnership"><b>LET'S CHAT</b></a>
103
+ </div>
104
+
105
+ </div>
106
+
107
+ ## Explore the TanStack Ecosystem
108
+
109
+ - <a href="https://github.com/tanstack/config"><b>TanStack Config</b></a> – Tooling for JS/TS packages
110
+ - <a href="https://github.com/tanstack/db"><b>TanStack DB</b></a> – Reactive sync client store
111
+ - <a href="https://github.com/tanstack/devtools"><b>TanStack DevTools</b></a> – Unified devtools panel
112
+ - <a href="https://github.com/tanstack/form"><b>TanStack Form</b></a> – Type‑safe form state
113
+ - <a href="https://github.com/tanstack/hotkeys"><b>TanStack Hotkeys</b></a> – Type‑safe keyboard shortcuts
114
+ - <a href="https://github.com/tanstack/query"><b>TanStack Query</b></a> – Async state & caching
115
+ - <a href="https://github.com/tanstack/ranger"><b>TanStack Ranger</b></a> – Range & slider primitives
116
+ - <a href="https://github.com/tanstack/router"><b>TanStack Router</b></a> – Type‑safe routing, caching & URL state
117
+ - <a href="https://github.com/tanstack/start"><b>TanStack Start</b></a> – Full‑stack SSR & streaming
118
+ - <a href="https://github.com/tanstack/store"><b>TanStack Store</b></a> – Reactive data store
119
+ - <a href="https://github.com/tanstack/table"><b>TanStack Table</b></a> – Headless datagrids
120
+ - <a href="https://github.com/tanstack/virtual"><b>TanStack Virtual</b></a> – Virtualized rendering
121
+
122
+ … and more at <a href="https://tanstack.com"><b>TanStack.com »</b></a>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/solid-hotkeys",
3
- "version": "0.3.3",
3
+ "version": "0.4.1",
4
4
  "description": "SolidJS adapter for TanStack Hotkeys",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -42,8 +42,8 @@
42
42
  "src"
43
43
  ],
44
44
  "dependencies": {
45
- "@tanstack/solid-store": "^0.9.1",
46
- "@tanstack/hotkeys": "0.3.3"
45
+ "@tanstack/solid-store": "^0.9.2",
46
+ "@tanstack/hotkeys": "0.4.1"
47
47
  },
48
48
  "devDependencies": {
49
49
  "@solidjs/testing-library": "^0.8.10",