Skip to main content
A TV has no touch screen and no pointer. When your app runs on TV, UIProvider starts a spatial navigator: the arrow keys move real DOM focus to the nearest focusable element in that direction, OK clicks it, and Back walks a stack of handlers (close the open sheet, then the next overlay, then leave the app). Every kit component (Pressable, Button, Input, ListItem, TabBar…) is already focusable. You only need the tools below for your own clickable elements.

Detection

Making your own elements focusable

boolean
Preferred first focus when its screen or overlay becomes active. Use at most one per scope.
boolean
Remove it from the navigation order.
number
Override the tab order.
The hook returns data-focus and tabIndex. Elements with data-focus get the theme’s focus ring (ring color).

Scopes and Back

boolean
Keep the arrow keys inside this subtree. Use it for overlays.
boolean
Focus the first focusable element on mount.
() => void
Called on Back or Escape while this scope is on top.
The kit’s overlays already use scopes. For custom flows: pushBackHandler(fn) adds a Back handler and returns its removal, focusFirst(root?) moves focus into a container, and startSpatialNav() / stopSpatialNav() control the navigator directly.

Everywhere else

data-focus and the focus ring also make your app keyboard-accessible on web and desktop. On touch devices the ring is not shown, so it is safe to apply everywhere.
Combine useUI().isTV with larger type and spacing, and a Sidebar with expandOnFocus, for a layout that reads from across the room.