}>
  Global bindings (attached to `document`) work well for app-wide shortcuts like <Kbd>Ctrl+K</Kbd>. But some shortcuts should only work when a specific element is focused.

## Why scope bindings?

Global bindings work well for app-wide shortcuts like <Kbd>Ctrl+K</Kbd> for a command palette. But some shortcuts should only work when a specific element is focused, like <Kbd>Ctrl+S</Kbd> in an editor panel or arrow keys in a list.

duck-vim supports scoped bindings in both vanilla and React usage.

***

## Vanilla: Scoped KeyHandler

Create a separate `KeyHandler` and attach it to a specific element:

```ts
import { Registry, KeyHandler } from '@gentleduck/vim/command'

const registry = new Registry()
const editorHandler = new KeyHandler(registry, 600)

registry.register('ctrl+s', {
  name: 'Save',
  execute: () => saveDocument(),
}, { preventDefault: true })

// Only listens on the editor element
const editor = document.getElementById('editor')!
editorHandler.attach(editor)
```

The binding only fires when keydown events originate from within the editor element.

***

## Vanilla: Standalone handler

For a quick one-off, use `createKeyBindHandler` and attach to any element:

```ts
import { createKeyBindHandler } from '@gentleduck/vim/matcher'

const handler = createKeyBindHandler({
  binding: 'ctrl+enter',
  handler: () => submitForm(),
  options: { preventDefault: true },
})

document.getElementById('form')!.addEventListener('keydown', handler)
```

***

## React: `targetRef` option

Both `useKeyBind` and `useKeySequence` accept a `targetRef` option:

```tsx
function Editor() {
  const editorRef = useRef<HTMLDivElement>(null)

  useKeyBind('ctrl+s', () => save(), {
    preventDefault: true,
    targetRef: editorRef,
  })

  useKeyBind('ctrl+z', () => undo(), {
    preventDefault: true,
    targetRef: editorRef,
  })

  return (
    <div ref={editorRef} tabIndex={0} className="editor">
      {/* Editor content */}
    </div>
  )
}
```

}>
  The target element must be focusable to receive keyboard events. Add `tabIndex={0}` if it's not natively focusable (like a `div`).

***

## Multiple scopes

You can create isolated shortcut systems by using separate registries or by leveraging `useKeyBind` with different `targetRef` values:

```tsx
function App() {
  const sidebarRef = useRef<HTMLDivElement>(null)
  const mainRef = useRef<HTMLDivElement>(null)

  // Only fires in sidebar
  useKeyBind('j', () => nextItem(), { targetRef: sidebarRef })
  useKeyBind('k', () => prevItem(), { targetRef: sidebarRef })

  // Only fires in main area
  useKeyBind('e', () => editSelected(), { targetRef: mainRef })

  // Global (no targetRef)
  useKeyBind('ctrl+k', () => openPalette(), { preventDefault: true })

  return (
    <div className="flex">
      <div ref={sidebarRef} tabIndex={0}>Sidebar</div>
      <div ref={mainRef} tabIndex={0}>Main</div>
    </div>
  )
}
```

***

## Nested scopes

}>
  When a scoped binding fires, it calls `event.stopPropagation()` if that option is set. This prevents parent handlers from also firing. Use this to create nested shortcut contexts.

```tsx
useKeyBind('escape', () => closeModal(), {
  targetRef: modalRef,
  stopPropagation: true,
})

// This won't fire when Escape is pressed inside the modal
useKeyBind('escape', () => closeSidebar())
```