Skip to content
Sensors

useMagicKeys

Reactive key-press state — access any key as a ReadonlyObservable<boolean> that is true while the key is held down.

Magic Keys

Press keys to see their reactive state change in real-time.

Modifier Keys

Ctrl: Off
Shift: Off
Alt: Off

Combos

Ctrl+A: Off
Ctrl+S: Off

Currently Pressed

(none)

import {
const useMagicKeys: (options?: DeepMaybeObservable<UseMagicKeysOptions>) => UseMagicKeysReturn
useMagicKeys
} from "@usels/web";
function
function KeyboardDemo(): JSX.Element
KeyboardDemo
() {
const
const keys: UseMagicKeysReturn
keys
=
function useMagicKeys(options?: DeepMaybeObservable<UseMagicKeysOptions>): UseMagicKeysReturn

Framework-agnostic magic keys tracker.

Tracks keyboard state via keydown/keyup/blur events on window. Returns a Proxy that exposes any key as a reactive boolean observable, and supports combo keys (e.g. ctrl+a).

useMagicKeys
();
return (
<
JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div
>
{/* Single key — true while held */}
<
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>A: {
const keys: UseMagicKeysReturn
keys
["a"].
ImmutableObservableBase<boolean>.get(trackingType?: TrackingType | GetOptions): {}
get
() ? "pressed" : "released"}</
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>
{/* Modifier keys (aliases: ctrl, cmd, alt, esc, etc.) */}
<
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>Ctrl: {
const keys: UseMagicKeysReturn
keys
["ctrl"].
ImmutableObservableBase<boolean>.get(trackingType?: TrackingType | GetOptions): {}
get
() ? "pressed" : "released"}</
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>
{/* Combo — true only when all parts are pressed simultaneously */}
<
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>Ctrl+S: {
const keys: UseMagicKeysReturn
keys
["ctrl+s"].
ImmutableObservableBase<boolean>.get(trackingType?: TrackingType | GetOptions): {}
get
() ? "pressed" : "released"}</
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>
{/* Current pressed keys set */}
<
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>Pressed: {[...
const keys: UseMagicKeysReturn
keys
.
current$: ReadonlyObservable<Set<string>>

Set of currently pressed key names (lowercase)

current$
.
ImmutableObservableBase<Set<string>>.get(trackingType?: TrackingType | GetOptions): any
get
()].
any
join
(", ")}</
JSX.IntrinsicElements.p: DetailedHTMLProps<HTMLAttributes<HTMLParagraphElement>, HTMLParagraphElement>
p
>
</
JSX.IntrinsicElements.div: DetailedHTMLProps<HTMLAttributes<HTMLDivElement>, HTMLDivElement>
div
>
);
}

Since JavaScript destructuring cannot use + or bracket notation, append $ to key names and use _ instead of + for combos:

// @noErrors
import { useMagicKeys } from "@usels/web";
function DestructuredDemo() {
const { shift$, space$, Ctrl_S$ } = useMagicKeys();
return (
<div>
<p>Shift: {shift$.get() ? "pressed" : "released"}</p>
<p>Ctrl+S: {Ctrl_S$.get() ? "pressed" : "released"}</p>
</div>
);
}
AliasResolves to
ctrlcontrol
cmdmeta
commandmeta
optionalt
escescape
deldelete
space (space)
uparrowup
downarrowdown
leftarrowleft
rightarrowright

Key names are lowercased and resolved through the alias map. Combo keys are specified with + separator (e.g., "ctrl+a", "shift+enter").

For destructuring, append $ to any key name (e.g., shift$) and use _ instead of + for combos (e.g., Ctrl_A$). The $ suffix is stripped and _ is converted to + internally.

export interface UseMagicKeysOptions extends ConfigurableWindow {
/** Custom alias map for key names */
aliasMap?: Record<string, string>;
/** Event handler called on every keydown/keyup. Return false to skip tracking. */
onEventFired?: (e: KeyboardEvent) => boolean | void;
/** Options passed to the underlying addEventListener calls. @default { passive: true } */
eventListenerOptions?: AddEventListenerOptions;
}
export type UseMagicKeysReturn = {
/** Set of currently pressed key names (lowercase) */
current$: ReadonlyObservable<Set<string>>;
} & {
/** Access any key as a reactive boolean. e.g., keys["a"], keys["shift"], keys["ctrl+a"] */
[key: string]: ReadonlyObservable<boolean>;
};
/**
* Framework-agnostic magic keys tracker.
*
* Tracks keyboard state via `keydown`/`keyup`/`blur` events on window.
* Returns a Proxy that exposes any key as a reactive boolean observable,
* and supports combo keys (e.g. `ctrl+a`).
*/
export declare function createMagicKeys(options?: DeepMaybeObservable<UseMagicKeysOptions>): UseMagicKeysReturn;

View on GitHub