1# keyboard shortcuts 2 3global keyboard shortcuts for the plyr.fm frontend. 4 5## implementation 6 7shortcuts are handled in the root layout (`frontend/src/routes/+layout.svelte`) with context-aware filtering to avoid conflicts with form inputs and other interactive elements. 8 9## available shortcuts 10 11### Cmd/Ctrl+K - open search 12 13**location**: `frontend/src/routes/+layout.svelte` 14 15opens the unified search modal for searching tracks, artists, albums, and tags. 16 17**behavior**: 18- **Cmd+K** on macOS, **Ctrl+K** on windows/linux 19- works from anywhere, including input fields (uses modifier key) 20- toggles search modal open/closed 21- focuses search input automatically on open 22 23**in-modal navigation**: 24- **arrow up/down** - navigate results 25- **enter** - select highlighted result 26- **esc** - close modal 27 28see [search.md](./search.md) for full documentation. 29 30--- 31 32### Q - toggle queue 33 34**location**: `frontend/src/routes/+layout.svelte` 35 36toggles the queue sidebar visibility. 37 38**behavior**: 39- works from any page in the app 40- ignores when modifier keys are pressed (cmd/ctrl/alt) 41- skips when focus is in input/textarea/contenteditable elements 42- persists visibility state to localStorage 43 44**desktop**: queue opens as 360px fixed sidebar, content shifts left via `margin-right: 360px` 45**mobile**: queue opens as full-screen overlay (no content shift) 46 47**accessibility**: 48- toggle button includes `aria-pressed={showQueue}` 49- `aria-label="toggle queue (Q)"` for screen readers 50- tooltip shows keyboard hint 51 52--- 53 54## playback shortcuts 55 56all playback shortcuts require a track to be loaded and are disabled when the search modal is open. 57 58### Space - play/pause 59 60toggles playback of the current track. 61 62### Left Arrow - seek backward 63 64seeks backward 10 seconds in the current track. 65 66### Right Arrow - seek forward 67 68seeks forward 10 seconds in the current track. 69 70### J - previous track 71 72goes to the previous track in the queue. if more than 3 seconds into the current track, restarts it instead. 73 74### L - next track 75 76advances to the next track in the queue (if available). 77 78### M - mute/unmute 79 80toggles mute. restores previous volume level when unmuting. 81 82--- 83 84## adding new shortcuts 85 86when adding keyboard shortcuts: 87 881. **add handler to root layout** - keeps all shortcuts in one place 892. **filter contexts** - check for modifier keys and active element 903. **prevent conflicts** - avoid letters used in common form inputs 914. **document behavior** - update this file with key, action, and context rules 925. **add accessibility** - include aria-labels and tooltips mentioning the shortcut 93 94### example pattern 95 96```typescript 97function handleShortcut(event: KeyboardEvent) { 98 // ignore modifiers 99 if (event.metaKey || event.ctrlKey || event.altKey) return; 100 101 // ignore in inputs 102 const target = event.target as HTMLElement; 103 if ( 104 target.tagName === 'INPUT' || 105 target.tagName === 'TEXTAREA' || 106 target.isContentEditable 107 ) return; 108 109 // handle key 110 if (event.key.toLowerCase() === 'q') { 111 event.preventDefault(); 112 // do something 113 } 114} 115 116onMount(() => { 117 window.addEventListener('keydown', handleShortcut); 118}); 119 120onDestroy(() => { 121 if (browser) { 122 window.removeEventListener('keydown', handleShortcut); 123 } 124}); 125``` 126 127## future candidates 128 129potential shortcuts to consider: 130- **/** - focus search (alternative to Cmd/Ctrl+K) 131- **T** - cycle theme (dark/light/system) 132- **S** - shuffle queue 133 134## design principles 135 1361. **global availability** - shortcuts should work from anywhere unless context prevents it 1372. **respect focus** - never intercept input from form fields 1383. **progressive disclosure** - show hints in tooltips and UI 1394. **consistency** - follow common web app conventions where possible 1405. **accessibility first** - keyboard shortcuts enhance but don't replace mouse/touch interaction