compose-focus-navigation

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

Updated May 21, 2025
One-click install
npx skills add https://github.com/albertmartorell1975/MeteoMartoCompose --skill compose-focus-navigation-albertmartorell1975
Or copy as Structured Prompt for Agent▼
Please help me install this Agent Skill.
Skill: compose-focus-navigation
Source: https://github.com/albertmartorell1975/MeteoMartoCompose/tree/main/.agents/skills/compose-focus-navigation
Command: npx skills add https://github.com/albertmartorell1975/MeteoMartoCompose --skill compose-focus-navigation-albertmartorell1975

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, directional navigation jumps to the wrong element, and focus is lost after list refreshes. This Skill provides concrete patterns and review criteria for building correct, testable focus behavior. ## 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, back/escape behavior, and D-pad throttling. - Focus restoration and testing: Strategies for restoring focus by stable item id after refresh, plus Compose UI tests that send key input and assert focused nodes. - Use Case: You are building an Android TV app with a carousel of content rows. Use this Skill to set initial focus on the first item after loading, wire up/down navigation between rows, and write tests that press D-pad keys and assert the correct item is focused. ## Quick Start Ask the AI to review your Compose TV screen for focus navigation issues, or to add initial focus and D-pad navigation to a lazy list using FocusRequester and focusProperties.

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, then call requestFocus() inside a LaunchedEffect. If the target appears after loading, key the effect to the loaded condition rather than Unit so focus is requested only after composition succeeds.

How to handle D-pad navigation in Compose for Android TV?▼

Use natively focusable components like Button and clickable surfaces, then override directional behavior with Modifier.focusProperties only where default spatial search fails. Handle special keys with onPreviewKeyEvent, returning true only for consumed keys.

Why does requestFocus crash or fail in Compose?▼

requestFocus fails when called before the target is composed, such as directly in the composable body or when content has not loaded yet. Move the call into a LaunchedEffect keyed to the condition that guarantees the focus target exists.

How do I test focus behavior in Compose UI tests?▼

Use performKeyInput with pressKey to send real key events like Key.DirectionDown, then assert the expected node with assertIsFocused. Prefer asserting focused semantics over visual styling, and avoid simulating clicks for keyboard or TV interfaces.

When should I use focusProperties in Compose?▼

Use focusProperties only when default spatial focus search produces wrong navigation, such as jumping between a header and a grid row. Overusing hard-coded focus links creates stale focus graphs when layouts change, so prefer natural focus order.

How do I restore focus after a lazy list refresh in Compose?▼

Track the focused item by stable id rather than index, and use stable key values in lazy lists. After refresh, re-request focus for the same id if it still exists, otherwise fall back deterministically to a neighbor, first item, or parent container.