483

useKeysPressed

Hook that tracks all currently pressed keyboard keys and their codes

sensorslowtest coverage
Q
W
E
R
T
Y
U
I
O
P
A
S
D
F
G
H
J
K
L
Shift
Z
X
C
V
B
N
M
Ctrl
Alt
Space
Alt
Ctrl
import { useKeysPressed } from '@siberiacancode/reactuse';

import { cn } from '@/utils/lib';

const KEYBOARD = [
  [
    { code: 'KeyQ', label: 'Q' },
    { code: 'KeyW', label: 'W' },
    { code: 'KeyE', label: 'E' },
    { code: 'KeyR', label: 'R' },
    { code: 'KeyT', label: 'T' },
    { code: 'KeyY', label: 'Y' },
    { code: 'KeyU', label: 'U' },
    { code: 'KeyI', label: 'I' },
    { code: 'KeyO', label: 'O' },
    { code: 'KeyP', label: 'P' }
  ],
  [
    { code: 'KeyA', label: 'A' },
    { code: 'KeyS', label: 'S' },
    { code: 'KeyD', label: 'D' },
    { code: 'KeyF', label: 'F' },
    { code: 'KeyG', label: 'G' },
    { code: 'KeyH', label: 'H' },
    { code: 'KeyJ', label: 'J' },
    { code: 'KeyK', label: 'K' },
    { code: 'KeyL', label: 'L' }
  ],
  [
    { code: 'ShiftLeft', label: 'Shift', wide: true },
    { code: 'KeyZ', label: 'Z' },
    { code: 'KeyX', label: 'X' },
    { code: 'KeyC', label: 'C' },
    { code: 'KeyV', label: 'V' },
    { code: 'KeyB', label: 'B' },
    { code: 'KeyN', label: 'N' },
    { code: 'KeyM', label: 'M' }
  ],
  [
    { code: 'ControlLeft', label: 'Ctrl' },
    { code: 'AltLeft', label: 'Alt' },
    { code: 'Space', label: 'Space', wide: true },
    { code: 'AltRight', label: 'Alt' },
    { code: 'ControlRight', label: 'Ctrl' }
  ]
];

const Demo = () => {
  const keysPressed = useKeysPressed();
  const pressedCodes = new Set(keysPressed.value.map(({ code }) => code));

  return (
    <section className='flex w-full max-w-md flex-col items-center gap-4 p-4'>
      <div className='flex flex-col items-center gap-1.5'>
        {KEYBOARD.map((row, i) => (
          <div key={i} className='flex gap-1.5'>
            {row.map((key) => {
              const active = pressedCodes.has(key.code);
              return (
                <div
                  key={key.code}
                  className={cn(
                    'border-border bg-card text-muted-foreground flex h-8 items-center justify-center rounded-md border font-mono text-[10px] font-medium transition-colors',
                    key.wide ? 'w-16' : 'w-8',
                    active && 'border-foreground bg-foreground text-background'
                  )}
                >
                  {key.label}
                </div>
              );
            })}
          </div>
        ))}
      </div>
    </section>
  );
};

export default Demo;

Installation

pnpm add @siberiacancode/reactuse

Usage

const { value } = useKeysPressed(ref);
// or
const { value, ref } = useKeysPressed();

Type Declarations

import type { HookTarget } from '@/utils/helpers';

import type { StateRef } from '../useRefState/useRefState';

export interface UseKeysPressedOptions {
  /** Enable or disable the event listeners */
  enabled?: boolean;
}

export interface UseKeysPressedReturn {
  /** The array of currently pressed keys */
  value: Array<{ key: string; code: string }>;
}

export interface UseKeysPressed {
  (target: HookTarget | Window, options?: UseKeysPressedOptions): UseKeysPressedReturn;

  <Target extends Element>(
    options?: UseKeysPressedOptions
  ): UseKeysPressedReturn & { ref: StateRef<Target> };
}

API

Parameters

NameTypeDefaultNote
targetHookTarget | WindowwindowDOM element or ref to attach keyboard listeners to
options.enabledUseKeysPressedOptionstrueEnable or disable the event listeners

Returns

UseKeysPressedReturn

Parameters

NameTypeDefaultNote
optionsUseKeysPressedOptions-- Optional configuration options

Returns

UseKeysPressedReturn & { ref: StateRef<Target> }

Contributors

ddebabinhhywaxGGorilla Dev

Last updated on