Skip to content

useScope

provider-dependentscope

Push a named scope onto the keyboard scope stack. Declarative scopes follow React tree order, so nested overlays can capture shortcuts until they unmount. Auto-pops on unmount.

useScope declares a keyboard scope for the part of the tree it lives in. While the scope is active, shortcuts registered under it (useKey with scope, or useScopedNavigation) win over shortcuts owned by shallower scopes. The scope is pushed on mount and popped automatically on unmount, so layered overlays capture keys for exactly as long as they are open.

tsx
useScope("modal")

When to use it

  • A dialog, drawer, or popover should claim Escape (or arrow keys) while open, shadowing a page-level binding for the same combo.
  • Several overlays can stack and each deeper one should take priority until it closes.
  • A region needs to register provider shortcuts under a stable, named scope.

Scopes describe priority, not focus containment. To restrict a shortcut to a DOM subtree, use containerRef + focusWithinOnly on useKey. The two compose. For the full model see the scopes guide.

Installation

Requires KeyboardProvider and the @diffgazer/keys package, which is not public on npm yet.

Diffgazer packages are not yet published to npm. Until the first release, pack @diffgazer/ui and @diffgazer/keys from the repository and install those tarballs.

@diffgazer/keys requires no CSS or Tailwind setup.

Parameters

NameTypeDefaultDescription
namerequiredstring | nullUnique name for the scope pushed onto the stack. Pass null to skip pushing without violating Hook call order.
options.enabledbooleantrueWhether the scope is active. When false the scope is not pushed.

Returns

string | nullThe active scope name when enabled and non-null, otherwise null.

Pass the returned value as the scope option to useKey so a binding registers under this scope.

Examples

Basic scope usage

Preview

Nested scopes resolve deepest-first

Preview

Notes

Scope stack lifecycle

The scope is pushed when the component mounts (or when enabled becomes true and name is non-null) and automatically popped when the component unmounts, when enabled becomes false, or when name becomes null.

Active scope ordering

Declarative scopes pushed by useScope are ordered by their React-generated component identity, which keeps siblings and nested overlays deterministic across a single commit. Imperative pushScope calls are ordered above declarative scopes until popped.

Requires KeyboardProvider

useScope is a provider-dependent hook. It must be used within a <KeyboardProvider> tree.

Edge cases

  • name: null. Pass null to skip pushing a scope while keeping the Hook call — the supported way to make a scope conditional without breaking the Rules of Hooks.
  • Ordering across a commit. Declarative scopes are ordered by React component identity, keeping siblings and nested overlays deterministic within a single commit. Imperative pushScope calls from the provider sit above declarative scopes until popped.
  • Requires a provider. useScope reads the registry context and must live inside a KeyboardProvider tree.
  • useKey — register a shortcut under the scope this hook returns.
  • KeyboardProvider — owns the scope stack and key dispatch.
  • Scopes guide — stacking, priority, and imperative pushes.

Source

Highlighted source loads after this disclosure opens. Browse the source repository.