# @mwillbanks/tuil-focus

Source: /tuil/docs/reference/packages/focus
Locale: en

Deterministic focus scopes, traversal, and restoration for terminal interfaces.



## Overview [#overview]

Deterministic focus scopes, traversal, and restoration for terminal interfaces.

`@mwillbanks/tuil-focus` is independently installable and also participates in the
umbrella `@mwillbanks/tuil` runtime where applicable.

## Installation [#installation]

<CodeBlockTabs defaultValue="npm">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="npm">
      npm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="pnpm">
      pnpm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="yarn">
      yarn
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="bun">
      bun
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="npm">
    ```bash
    npm install @mwillbanks/tuil-focus
    ```
  </CodeBlockTab>

  <CodeBlockTab value="pnpm">
    ```bash
    pnpm add @mwillbanks/tuil-focus
    ```
  </CodeBlockTab>

  <CodeBlockTab value="yarn">
    ```bash
    yarn add @mwillbanks/tuil-focus
    ```
  </CodeBlockTab>

  <CodeBlockTab value="bun">
    ```bash
    bun add @mwillbanks/tuil-focus
    ```
  </CodeBlockTab>
</CodeBlockTabs>

## How it operates [#how-it-operates]

Focus scopes register semantic targets, order traversal deterministically, support directional movement, suspend or restore nested scopes, and expose an observable snapshot.

<Mermaid
  chart="flowchart LR
  S0[&#x22;register scope&#x22;]
  S1[&#x22;register node&#x22;]
  S2[&#x22;activate&#x22;]
  S3[&#x22;move&#x22;]
  S4[&#x22;suspend/restore&#x22;]
  S5[&#x22;dispose&#x22;]
  S0 --> S1
  S1 --> S2
  S2 --> S3
  S3 --> S4
  S4 --> S5"
/>

## API [#api]

| API                                                                                 | Signature                        | Description                            |
| ----------------------------------------------------------------------------------- | -------------------------------- | -------------------------------------- |
| [`FocusChange`](/tuil/docs/reference/packages/focus/api/focus-change)                    | `interface FocusChange`          | Public interface FocusChange.          |
| [`FocusDirection`](/tuil/docs/reference/packages/focus/api/focus-direction)              | `type FocusDirection`            | Public type FocusDirection.            |
| [`FocusManager`](/tuil/docs/reference/packages/focus/api/focus-manager)                  | `class FocusManager`             | Public class FocusManager.             |
| [`FocusNode`](/tuil/docs/reference/packages/focus/api/focus-node)                        | `interface FocusNode`            | Public interface FocusNode.            |
| [`FocusNodeInput`](/tuil/docs/reference/packages/focus/api/focus-node-input)             | `type FocusNodeInput`            | Public type FocusNodeInput.            |
| [`FocusProvider`](/tuil/docs/reference/packages/focus/api/focus-provider)                | `function FocusProvider`         | Public function FocusProvider.         |
| [`FocusScope`](/tuil/docs/reference/packages/focus/api/focus-scope)                      | `function FocusScope`            | Public function FocusScope.            |
| [`FocusScopeDefinition`](/tuil/docs/reference/packages/focus/api/focus-scope-definition) | `interface FocusScopeDefinition` | Public interface FocusScopeDefinition. |
| [`FocusTrap`](/tuil/docs/reference/packages/focus/api/focus-trap)                        | `function FocusTrap`             | Public function FocusTrap.             |
| [`useFocusable`](/tuil/docs/reference/packages/focus/api/use-focusable)                  | `function useFocusable`          | Public function useFocusable.          |
| [`useFocusManager`](/tuil/docs/reference/packages/focus/api/use-focus-manager)           | `function useFocusManager`       | Public function useFocusManager.       |
| [`useFocusScopeId`](/tuil/docs/reference/packages/focus/api/use-focus-scope-id)          | `function useFocusScopeId`       | Public function useFocusScopeId.       |

## Events and lifecycle [#events-and-lifecycle]

Focus changes are exposed through subscriptions; components use them with `useSyncExternalStore` rather than a separate event name.

All subscriptions and registrations return a disposer or belong to an owning
runtime that disposes them in reverse order.

## Example [#example]

```tsx
import { FocusManager } from "@mwillbanks/tuil-focus";

const focus = new FocusManager();
focus.register({ id: "save", scopeId: "dialog" });
focus.focus("save");
```

## Related [#related]

* [Package architecture](/tuil/docs/concepts/packages)
* [Events](/tuil/docs/concepts/events)
* [Testing](/tuil/docs/guides/testing)
