BACK
Use casesKeyboard layers — global/list/modal shortcuts
Use cases · 50

Keyboard layers — global/list/modal shortcuts

Pattern

Enter in a list — "open the selected". Enter in a modal — "confirm". Escape in a modal — "close", in a dropdown — "collapse". The same key means different things depending on the current scope.

The problem it solves

A global document.keydown handler with if-branches intercepts Enter inside input fields, breaks forms, and conflicts with components. Routing by scope is the only sane option.

Operators and why they matter

  • Subject — simulates fromEvent(document, 'keydown').
  • withLatestFrom(scope$) — on each keydown, grab the CURRENT scope at that moment.
  • filter — pass on only if this key is registered in the current scope.
  • map — turn (key, scope) into a specific command.

Gotchas

  • Without a scope, the global handler intercepts Enter inside input/textarea and breaks text entry.
  • mergeMap isn't needed here — command resolution is synchronous.
  • Don't forget to ignore shortcuts when focus is in an input/textarea (or explicitly raise their priority).

What you get

The command is derived declaratively from the (key, scope) pair. No implicit stacks or conflicting handlers.

script.ts // TypeScript
CONSOLE · Console output
Hit Run to see the result...