Hotkey
Invisible keyboard shortcut listener that supports modifier combos (Ctrl+K) and chord sequences (g i). Fires an event when the key pattern is matched.
<arc-hotkey> Overview
>
Hotkey is a zero-UI component that listens for keyboard shortcuts and fires an `arc-hotkey-trigger` event when a matching key pattern is detected. It renders nothing visible — `display: none` is enforced — so it acts purely as a declarative shortcut binding you drop into your template.
The `keys` prop accepts modifier combos like `"ctrl+k"`, `"meta+shift+p"`, and `"alt+n"`, as well as Vim-style chord sequences where space-separated keys must be pressed in order (e.g. `"g i"` means press G, release, then press I within 1 second). Modifier names are normalized: `cmd`/`command` → `meta`, `option` → `alt`, `control` → `ctrl`.
By default, Hotkey skips events when focus is inside an input, textarea, select, or contentEditable element, preventing shortcuts from interfering with typing. Setting `global` attaches the listener to `window` and removes this filter, useful for app-wide shortcuts that must work regardless of focus.Guidelines
When to use
- Use for app-level shortcuts like Ctrl+K for search or Ctrl+S for save
- Set `global` for shortcuts that must work inside text inputs (e.g. Ctrl+S)
- Provide visual hints elsewhere in the UI (tooltips, menu items) showing available shortcuts
- Use `disabled` to suspend shortcuts when a modal or dialog is open
When not to use
- Do not override browser-reserved shortcuts (Ctrl+T, Ctrl+W, Ctrl+N) — they won't work
- Do not create chord sequences longer than 2-3 keys — users can't remember them
- Do not rely on hotkeys as the only way to access a feature — always provide a clickable alternative
- Do not forget the 1-second chord timeout — slow typists may miss the window
Features
- Modifier combos: ctrl+k, meta+shift+p, alt+n, etc.
- Chord sequences: "g i" (press G, then I within 1 second)
- Normalized modifier names: cmd/command → meta, option → alt
- Automatic input/textarea/select filtering — won't fire while typing
- Global mode attaches to window and bypasses focus filtering
- Disabled prop to temporarily suspend the shortcut
- Zero UI — `display: none` enforced, no layout impact
- Fires `arc-hotkey-trigger` with `event.detail.keys` containing the matched pattern
Preview
Press
Usage
This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.
<!-- Search shortcut -->
<arc-hotkey keys="ctrl+k" id="search-hotkey"></arc-hotkey>
<!-- Vim-style chord: press g, then i -->
<arc-hotkey keys="g i" id="go-inbox"></arc-hotkey>
<!-- Global shortcut (works in inputs) -->
<arc-hotkey keys="ctrl+s" global id="save-hotkey"></arc-hotkey>
<script type="module">
document.getElementById('search-hotkey')
.addEventListener('arc-hotkey-trigger', () => openSearch());
document.getElementById('save-hotkey')
.addEventListener('arc-hotkey-trigger', () => saveDocument());
</script> import { Hotkey } from '@arclux/arc-ui-react';
function App() {
const handleSearch = () => openSearch();
const handleSave = () => saveDocument();
return (
<>
<Hotkey keys="ctrl+k" onArcHotkeyTrigger={handleSearch} />
<Hotkey keys="ctrl+s" global onArcHotkeyTrigger={handleSave} />
</>
);
} <script setup>
import { Hotkey } from '@arclux/arc-ui-vue';
function openSearch() { /* ... */ }
function saveDoc() { /* ... */ }
</script>
<template>
<Hotkey keys="ctrl+k" @arc-hotkey-trigger="openSearch" />
<Hotkey keys="ctrl+s" global @arc-hotkey-trigger="saveDoc" />
</template> <script>
import { Hotkey } from '@arclux/arc-ui-svelte';
function openSearch() { /* ... */ }
</script>
<Hotkey keys="ctrl+k" on:arc-hotkey-trigger={openSearch} /> import { Component } from '@angular/core';
import { Hotkey } from '@arclux/arc-ui-angular';
@Component({
imports: [Hotkey],
template: `
<arc-hotkey keys="ctrl+k" (arc-hotkey-trigger)="openSearch()" />
<arc-hotkey keys="ctrl+s" global (arc-hotkey-trigger)="save()" />
`,
})
export class AppComponent {
openSearch() { /* ... */ }
save() { /* ... */ }
} import { Hotkey } from '@arclux/arc-ui-solid';
export default function Example() {
return (
<>
<Hotkey keys="ctrl+k" onArcHotkeyTrigger={() => openSearch()} />
<Hotkey keys="ctrl+s" global onArcHotkeyTrigger={() => save()} />
</>
);
} import { Hotkey } from '@arclux/arc-ui-preact';
export default function Example() {
return (
<>
<Hotkey keys="ctrl+k" onArcHotkeyTrigger={() => openSearch()} />
<Hotkey keys="ctrl+s" global onArcHotkeyTrigger={() => save()} />
</>
);
} API
-
keysstring'' - Key pattern to match. Modifier combos use "+" (e.g., "ctrl+k"). Chords use spaces (e.g., "g i").
-
disabledbooleanfalse - Temporarily suspends the shortcut listener.
-
globalbooleanfalse - When true, attaches to `window` instead of `document` and skips input/textarea filtering.
Events
-
arc-hotkey-triggerdetail: { keys: string } - Fired when the full key pattern is matched. `event.detail.keys` contains the matched pattern string.