feat(desktop): rebindable keyboard shortcuts panel
Add a central keybind registry + nanostore so desktop hotkeys are discoverable and user-rebindable. A titlebar ⌨ button (and ⌘/) opens a collapsible map grouped by Composer (read-only) / Profiles / Session / Navigation / View; click any chip to capture a new combo. Overrides persist to localStorage as a delta against shipped defaults, so future default changes aren't shadowed by a stored snapshot. Migrates the previously scattered inline listeners (palette, command center, new session, sidebar, theme) into the registry, and adds profile switch/cycle/create + default-profile hotkeys.
This commit is contained in:
@@ -289,30 +289,8 @@ export function ThemeProvider({ children }: { children: ReactNode }) {
|
||||
window.localStorage.setItem(MODE_KEY, next)
|
||||
}, [])
|
||||
|
||||
// Shift+X toggles light/dark anywhere outside an editable field.
|
||||
useEffect(() => {
|
||||
const onKeyDown = (event: KeyboardEvent) => {
|
||||
const t = event.target as HTMLElement | null
|
||||
|
||||
const editing =
|
||||
t?.isContentEditable ||
|
||||
t instanceof HTMLInputElement ||
|
||||
t instanceof HTMLTextAreaElement ||
|
||||
t instanceof HTMLSelectElement
|
||||
|
||||
if (editing || event.repeat || event.altKey || event.ctrlKey || event.metaKey) {
|
||||
return
|
||||
}
|
||||
|
||||
if (event.shiftKey && event.code === 'KeyX') {
|
||||
setMode(resolvedMode === 'dark' ? 'light' : 'dark')
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener('keydown', onKeyDown)
|
||||
|
||||
return () => window.removeEventListener('keydown', onKeyDown)
|
||||
}, [resolvedMode, setMode])
|
||||
// The light/dark toggle (Shift+X by default) is owned by the keybind runtime
|
||||
// (`appearance.toggleMode`) so it shows up in the hotkey map and is rebindable.
|
||||
|
||||
const value = useMemo<ThemeContextValue>(
|
||||
() => ({ theme: activeTheme, themeName, mode, resolvedMode, availableThemes: SKIN_LIST, setTheme, setMode }),
|
||||
|
||||
Reference in New Issue
Block a user