compose-focus-navigation

Implements and reviews Jetpack Compose focus navigation for TV, keyboard, and D-pad input.

Updated Jul 1, 2026
One-click install
npx skills add https://github.com/w0lzard/Wolzard-s-Marketplace --skill compose-focus-navigation-w0lzard
Or copy as Structured Prompt for Agent
Please help me install this Agent Skill.
Skill: compose-focus-navigation
Source: https://github.com/w0lzard/Wolzard-s-Marketplace/tree/main/plugins/personal-skills/skills/compose-focus-navigation
Command: npx skills add https://github.com/w0lzard/Wolzard-s-Marketplace --skill compose-focus-navigation-w0lzard

SYSTEM DOCUMENTATION & REQUIREMENTS

What problem does it solve? Focus behavior in Jetpack Compose breaks easily on TV, desktop, and keyboard-first devices: initial focus fires before content loads, focus restoration fails after list refreshes, and key handlers consume events they should not. This Skill provides concrete patterns and review checklists for building correct focus navigation. ## Core Features & Use Cases - Focus target construction: Guidance on when to use FocusRequester, focusRequester, onFocusChanged, and focusable() versus relying on natively focusable components. - Directional navigation and key events: Patterns for focusProperties overrides, onPreviewKeyEvent handlers, and throttling rapid D-pad input at the right boundary. - Focus restoration and testing: Strategies for restoring focus by stable item id in lazy lists, plus Compose UI tests that send key input and assert focused semantics. - Use Case: You are building an Android TV app with a carousel of content rows. Use this Skill to set initial focus after data loads, wire up/down navigation between rows, and write tests that press D-pad keys and assert the correct item is focused. ## Quick Start Review my Compose TV screen and fix the initial focus and D-pad navigation so the first carousel item is focused after loading.

Frequently Asked Questions about compose-focus-navigation

High-intent search queries and answers about installing and using this skill.

FAQPage Schema
How do I set initial focus in Jetpack Compose?

Create a FocusRequester with remember, attach it via Modifier.focusRequester, and call requestFocus() inside a LaunchedEffect rather than the composable body. If the target appears after loading, key the effect to the loaded condition so focus is requested only once the item exists.

How do I handle D-pad and keyboard navigation in Compose for TV?

Use focusable components like Button by default and override directional behavior with Modifier.focusProperties only where spatial search fails. For custom key handling, use Modifier.onPreviewKeyEvent and return true only for keys you actually consume.

Why does focus restoration fail after a lazy list refresh in Compose?

Restoration fails when focus requesters are keyed by list index instead of stable item identity. Track the focused item by id, use stable key values in lazy lists, and re-request focus for the same id after refresh, falling back to a deterministic neighbor if it no longer exists.

How do I test focus navigation in Compose UI tests?

Send real key input with performKeyInput and pressKey, then assert focus with assertIsFocused on the target node. Avoid clicking nodes in TV or keyboard UIs, and reserve screenshot tests for focus appearance rather than focus ownership.

When should I avoid custom focusProperties in Compose?

Avoid focusProperties when default spatial search already produces correct navigation. Hard-coding many directional links creates stale focus graphs when layouts change, so override only the specific broken edges or intentional traps your design requires.