├── docs
└── show.gif
├── package.json
├── README.md
├── Keybinds.svelte
└── maps.js
/docs/show.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ThaUnknown/svelte-keybinds/HEAD/docs/show.gif
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "svelte-keybinds",
3 | "version": "1.0.9",
4 | "description": "Minimalistic keybinds interface, with rebinding and saving. Made for Svelte.",
5 | "main": "Keybinds.svelte",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/ThaUnknown/svelte-keybinds.git"
12 | },
13 | "keywords": [
14 | "keybinds",
15 | "keyboard",
16 | "svelte",
17 | "binds",
18 | "rebinding",
19 | "dragdrop"
20 | ],
21 | "author": "ThaUnknown",
22 | "license": "MIT",
23 | "bugs": {
24 | "url": "https://github.com/ThaUnknown/svelte-keybinds/issues"
25 | },
26 | "homepage": "https://github.com/ThaUnknown/svelte-keybinds#readme"
27 | }
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | Svelte Keybinds
3 |
4 |
5 | 
6 |
7 |
8 | ## Functions:
9 | ```jsx
10 | import Keybinds, { binds, loadWithDefaults, condition } from './Keybinds.svelte'
11 |
12 |
13 | ```
14 | - `clickable` - runs functions when the user clicks the key in the UI
15 | - `condition` - async callback function any time a keybind is ran, if it returns true the keybind is ran, if it returns false it isnt
16 | - `binds` - store/writable, binds object
17 | - `autosave` - automatically saves to localstorage when a user changes binds, requires `id` in binds object
18 | - `loadWithDefaults(defaults)` - loads the stored keybinds from autosave, using specific defaults, if a new keybind was added it will be properly created
19 |
20 | On browsers which support the [keyboard API](https://caniuse.com/mdn-api_navigator_keyboard) this module will respect the user's keyboard layout [dworak etc].
21 |
22 | ## Usage:
23 |
24 | Simple example:
25 | ```html
26 |
44 |
45 |
46 | {item?.label || ''}
47 |
48 |
49 |
60 | ```
61 |
62 | Example with autosave:
63 | ```html
64 |
86 |
87 |
88 | {item?.id || ''}
89 |
90 |
91 |
102 |
103 | ```
104 |
--------------------------------------------------------------------------------
/Keybinds.svelte:
--------------------------------------------------------------------------------
1 |
61 |
62 |
106 |
107 |
108 | {#each Object.values(keys) as key}
109 | {@const { size, dark, name } = key}
110 |
clickable && runBind(Object.assign(e, { code: name }))}>
118 |
119 |
120 | {/each}
121 |
122 |
123 |
185 |
--------------------------------------------------------------------------------
/maps.js:
--------------------------------------------------------------------------------
1 | // Risky as objects dont guarantee order
2 | export const keys = {
3 | Escape: {
4 | dark: true,
5 | name: 'Escape'
6 | },
7 | Digit1: {
8 | name: 'Digit1'
9 | },
10 | Digit2: {
11 | name: 'Digit2'
12 | },
13 | Digit3: {
14 | name: 'Digit3'
15 | },
16 | Digit4: {
17 | name: 'Digit4'
18 | },
19 | Digit5: {
20 | name: 'Digit5'
21 | },
22 | Digit6: {
23 | name: 'Digit6'
24 | },
25 | Digit7: {
26 | name: 'Digit7'
27 | },
28 | Digit8: {
29 | name: 'Digit8'
30 | },
31 | Digit9: {
32 | name: 'Digit9'
33 | },
34 | Digit0: {
35 | name: 'Digit0'
36 | },
37 | Minus: {
38 | name: 'Minus'
39 | },
40 | Equal: {
41 | name: 'Equal'
42 | },
43 | Backspace: {
44 | dark: true,
45 | size: 100,
46 | name: 'Backspace'
47 | },
48 | Delete: {
49 | dark: true,
50 | name: 'Delete'
51 | },
52 | Tab: {
53 | dark: true,
54 | size: 75,
55 | name: 'Tab'
56 | },
57 | KeyQ: {
58 | name: 'KeyQ'
59 | },
60 | KeyW: {
61 | name: 'KeyW'
62 | },
63 | KeyE: {
64 | name: 'KeyE'
65 | },
66 | KeyR: {
67 | name: 'KeyR'
68 | },
69 | KeyT: {
70 | name: 'KeyT'
71 | },
72 | KeyY: {
73 | name: 'KeyY'
74 | },
75 | KeyU: {
76 | name: 'KeyU'
77 | },
78 | KeyI: {
79 | name: 'KeyI'
80 | },
81 | KeyO: {
82 | name: 'KeyO'
83 | },
84 | KeyP: {
85 | name: 'KeyP'
86 | },
87 | BracketLeft: {
88 | name: 'BracketLeft'
89 | },
90 | BracketRight: {
91 | name: 'BracketRight'
92 | },
93 | Backslash: {
94 | dark: true,
95 | size: 75,
96 | name: 'Backslash'
97 | },
98 | Home: {
99 | dark: true,
100 | name: 'Home'
101 | },
102 | CapsLock: {
103 | dark: true,
104 | size: 90,
105 | name: 'CapsLock'
106 | },
107 | KeyA: {
108 | name: 'KeyA'
109 | },
110 | KeyS: {
111 | name: 'KeyS'
112 | },
113 | KeyD: {
114 | name: 'KeyD'
115 | },
116 | KeyF: {
117 | name: 'KeyF'
118 | },
119 | KeyG: {
120 | name: 'KeyG'
121 | },
122 | KeyH: {
123 | name: 'KeyH'
124 | },
125 | KeyJ: {
126 | name: 'KeyJ'
127 | },
128 | KeyK: {
129 | name: 'KeyK'
130 | },
131 | KeyL: {
132 | name: 'KeyL'
133 | },
134 | Semicolon: {
135 | name: 'Semicolon'
136 | },
137 | Quote: {
138 | name: 'Quote'
139 | },
140 | Enter: {
141 | dark: true,
142 | size: 110,
143 | name: 'Enter'
144 | },
145 | PageUp: {
146 | dark: true,
147 | name: 'PageUp'
148 | },
149 | ShiftLeft: {
150 | dark: true,
151 | size: 115,
152 | name: 'ShiftLeft'
153 | },
154 | KeyZ: {
155 | name: 'KeyZ'
156 | },
157 | KeyX: {
158 | name: 'KeyX'
159 | },
160 | KeyC: {
161 | name: 'KeyC'
162 | },
163 | KeyV: {
164 | name: 'KeyV'
165 | },
166 | KeyB: {
167 | name: 'KeyB'
168 | },
169 | KeyN: {
170 | name: 'KeyN'
171 | },
172 | KeyM: {
173 | name: 'KeyM'
174 | },
175 | Comma: {
176 | name: 'Comma'
177 | },
178 | Period: {
179 | name: 'Period'
180 | },
181 | Slash: {
182 | name: 'Slash'
183 | },
184 | ShiftRight: {
185 | dark: true,
186 | size: 85,
187 | name: 'ShiftRight'
188 | },
189 | ArrowUp: {
190 | dark: true,
191 | name: 'ArrowUp'
192 | },
193 | PageDown: {
194 | dark: true,
195 | name: 'PageDown'
196 | },
197 | ControlLeft: {
198 | dark: true,
199 | size: 75,
200 | name: 'ControlLeft'
201 | },
202 | MetaLeft: {
203 | dark: true,
204 | name: 'MetaLeft'
205 | },
206 | AltLeft: {
207 | dark: true,
208 | size: 75,
209 | name: 'AltLeft'
210 | },
211 | Space: {
212 | dark: true,
213 | size: 300,
214 | name: 'Space'
215 | },
216 | AltRight: {
217 | dark: true,
218 | size: 75,
219 | name: 'AltRight'
220 | },
221 | ContextMenu: {
222 | dark: true,
223 | size: 75,
224 | name: 'ContextMenu'
225 | },
226 | ArrowLeft: {
227 | dark: true,
228 | name: 'ArrowLeft'
229 | },
230 | ArrowDown: {
231 | dark: true,
232 | name: 'ArrowDown'
233 | },
234 | ArrowRight: {
235 | dark: true,
236 | name: 'ArrowRight'
237 | }
238 | }
239 | // char => code for navigator.keyboard API
240 | const codeMap = {
241 | 0: 'Digit0',
242 | 1: 'Digit1',
243 | 2: 'Digit2',
244 | 3: 'Digit3',
245 | 4: 'Digit4',
246 | 5: 'Digit5',
247 | 6: 'Digit6',
248 | 7: 'Digit7',
249 | 8: 'Digit8',
250 | 9: 'Digit9',
251 | e: 'KeyE',
252 | d: 'KeyD',
253 | '-': 'Minus',
254 | h: 'KeyH',
255 | z: 'KeyZ',
256 | '=': 'Equal',
257 | n: 'KeyN',
258 | p: 'KeyP',
259 | ']': 'BracketRight',
260 | '[': 'BracketLeft',
261 | s: 'KeyS',
262 | ';': 'Semicolon',
263 | q: 'KeyQ',
264 | o: 'KeyO',
265 | '.': 'Period',
266 | v: 'KeyV',
267 | l: 'KeyL',
268 | '`': 'Backquote',
269 | g: 'KeyG',
270 | j: 'KeyJ',
271 | t: 'KeyT',
272 | "'": 'Quote',
273 | y: 'KeyY',
274 | '\\': 'Backslash',
275 | r: 'KeyR',
276 | u: 'KeyU',
277 | k: 'KeyK',
278 | '/': 'Slash',
279 | f: 'KeyF',
280 | i: 'KeyI',
281 | x: 'KeyX',
282 | a: 'KeyA',
283 | m: 'KeyM',
284 | w: 'KeyW',
285 | b: 'KeyB',
286 | c: 'KeyC',
287 | ',': 'Comma'
288 | }
289 | export const layout = {}
290 | if (navigator.keyboard) {
291 | navigator.keyboard.getLayoutMap().then((map) => {
292 | for (const [key, value] of map.entries()) {
293 | layout[key] = codeMap[value]
294 | }
295 | })
296 | }
297 |
--------------------------------------------------------------------------------