From 3f70cd1b2836140c806d8ab9b40daf8e09f766fb Mon Sep 17 00:00:00 2001 From: anishamalde Date: Mon, 11 May 2026 13:43:15 +0100 Subject: [PATCH] Create rn-tv-ui-best-practices agent skill --- vega-multi-tv-migration/LICENSE => LICENSE | 2 +- README.md | 2 + rn-tv-ui-best-practices/README.md | 16 ++ rn-tv-ui-best-practices/SKILL.md | 77 ++++++ .../references/keyboard-handling.md | 130 ++++++++++ .../references/layout-patterns.md | 203 +++++++++++++++ .../references/navigation-and-focus.md | 236 ++++++++++++++++++ .../references/ten-foot-experience.md | 55 ++++ .../references/typography-and-color.md | 132 ++++++++++ 9 files changed, 852 insertions(+), 1 deletion(-) rename vega-multi-tv-migration/LICENSE => LICENSE (97%) create mode 100644 rn-tv-ui-best-practices/README.md create mode 100644 rn-tv-ui-best-practices/SKILL.md create mode 100644 rn-tv-ui-best-practices/references/keyboard-handling.md create mode 100644 rn-tv-ui-best-practices/references/layout-patterns.md create mode 100644 rn-tv-ui-best-practices/references/navigation-and-focus.md create mode 100644 rn-tv-ui-best-practices/references/ten-foot-experience.md create mode 100644 rn-tv-ui-best-practices/references/typography-and-color.md diff --git a/vega-multi-tv-migration/LICENSE b/LICENSE similarity index 97% rename from vega-multi-tv-migration/LICENSE rename to LICENSE index ed3afcb..e957867 100644 --- a/vega-multi-tv-migration/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2025 Vega Skills +Copyright (c) 2025 Amazon Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 499af7e..1703969 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ A collection of **Agent Skills** — structured knowledge packages that give AI | Skill | Description | |-------|-------------| | [vega-multi-tv-migration](vega-multi-tv-migration/SKILL.md) | Migrate Vega OS (Fire TV) apps to multi-platform React Native monorepo supporting Android TV, Apple TV, and more | +| [rn-tv-ui-best-practices](rn-tv-ui-best-practices/SKILL.md) | React Native TV UI best practices for tvOS, Android TV, Fire TV, and Vega OS — focus management, layouts, typography, and remote/D-pad navigation | ## Installation @@ -24,6 +25,7 @@ Install a specific skill: ```bash npx skills add AmazonAppDev/devices-agent-skills --skill vega-multi-tv-migration +npx skills add AmazonAppDev/devices-agent-skills --skill rn-tv-ui-best-practices ``` For more options, see the [skills CLI documentation](https://skills.sh/docs/cli). diff --git a/rn-tv-ui-best-practices/README.md b/rn-tv-ui-best-practices/README.md new file mode 100644 index 0000000..1bd9459 --- /dev/null +++ b/rn-tv-ui-best-practices/README.md @@ -0,0 +1,16 @@ +# rn-tv-ui-best-practices + +An agent skill for building React Native TV applications with best-practice UI patterns covering focus management, navigation, layout, typography, color, and keyboard handling. + +## Attribution + +Based on "The Ultimate Guide to React Native TV Development" (2025), co-authored by Amazon and Callstack. + +Book: https://reactnativetv.com + +## Authors + +- Giovanni Laquidara — [@giolaq](https://github.com/giolaq) +- Karol Latusek — [@Zahoq](https://github.com/Zahoq) +- Anisha Malde — [@anishamalde](https://github.com/anishamalde) +- Michal Pierzchala — [@thymikee](https://github.com/thymikee) diff --git a/rn-tv-ui-best-practices/SKILL.md b/rn-tv-ui-best-practices/SKILL.md new file mode 100644 index 0000000..98cebde --- /dev/null +++ b/rn-tv-ui-best-practices/SKILL.md @@ -0,0 +1,77 @@ +--- +name: rn-tv-ui-best-practices +description: React Native TV UI best practices for tvOS, Android TV, Fire TV, and Vega OS (including react-native-tvos). Use whenever building, reviewing, or debugging a TV / set-top box / streaming (OTT) app. Covers focus management (TVFocusGuideView, hasTVPreferredFocus, trapFocus, requestTVFocus, useTVEventHandler, focus loss/jumping); D-pad / RCU / spatial navigation; swimlanes, hero banners, drawers, tabs, modals, overscan/safe zones; TV typography, contrast, HDR; remote-driven text or voice input. +--- + +# React Native TV UI Best Practices + +Build polished React Native TV apps across tvOS, Android TV, Fire TV, Vega OS. + +## When to Apply + +Use when user is: +- Building or reviewing TV UI components +- Debugging focus/navigation issues +- Designing layouts for TV (10-foot experience) +- Choosing typography or color for TV displays +- Implementing keyboard/text input on TV + +## When NOT to Apply + +- Mobile-only React Native apps (no TV target) +- Web apps not targeting TV platforms +- General React Native performance issues unrelated to TV UX + +## Quick Decision Tree + +``` +Starting a new TV app or doing a broad design review? +└─ Read in order: references/ten-foot-experience.md → references/layout-patterns.md → references/typography-and-color.md + +Focus / navigation issue? +├─ Not sure which approach to use → references/navigation-and-focus.md (Focus Management Hierarchy) +├─ Focus doesn't start where expected → references/navigation-and-focus.md (hasTVPreferredFocus) +├─ Focus jumps unexpectedly → references/navigation-and-focus.md (Debugging Focus Issues + Common Focus Problems) +├─ Focus disappears (loader/empty/error state) → references/navigation-and-focus.md (Gotchas) +├─ Need modal/overlay focus trap → references/navigation-and-focus.md (Focus Traps) +├─ Back button not restoring focus → references/navigation-and-focus.md (Back Navigation and Focus Restoration) +├─ Need to move focus programmatically → references/navigation-and-focus.md (Imperative Focus) +└─ Cross-platform differences (tvOS vs Android TV vs Vega) → references/navigation-and-focus.md (Platform Focus Engines) + +Building screens/components? +├─ Drawer / tabs / modals → references/layout-patterns.md (Navigation Patterns) +├─ Cards / rows / swimlanes / hero banners → references/layout-patterns.md (Common Components) +├─ Buttons / overlays / details panels → references/layout-patterns.md (Common Components) +└─ Safe zones / overscan / multi-aspect-ratio → references/layout-patterns.md (Layout and Safe Zones) + +Visual design? +├─ Font sizes / line height / letter spacing → references/typography-and-color.md (Typography) +├─ Color / contrast / accessibility → references/typography-and-color.md (Color and Contrast) +├─ HDR / bright vs dim vs dark room → references/typography-and-color.md (HDR Considerations + Ambient Light Adaptation) +├─ Text over images or video → references/typography-and-color.md (Text Over Images) +└─ Animation / motion / feedback timing → references/ten-foot-experience.md (Feedback, Motion, and Rhythm) + +Text input / search / auth? +├─ Reduce typing burden → references/keyboard-handling.md (Input Minimization) +├─ System keyboard + RCU events → references/keyboard-handling.md (Built-In System Keyboard) +├─ Custom keyboard UI → references/keyboard-handling.md (Custom Keyboard) +├─ Voice input → references/keyboard-handling.md (Voice Input) +└─ Phone-as-input / QR auth → references/keyboard-handling.md (Mobile Companion Apps) + +Pre-ship review / sanity check? +├─ Focus traps & back navigation → references/navigation-and-focus.md (Verify before ship) +├─ Safe zones & aspect ratios → references/layout-patterns.md (Verify before ship) +├─ Typography sizes & contrast → references/typography-and-color.md (Verify before ship) +├─ Animation timing & input latency → references/ten-foot-experience.md (Verify before ship) +└─ Couch test (real device, real distance, real remote) → references/ten-foot-experience.md (Couch Sanity Checks) +``` + +## References + +| File | When to Load | +|------|--------------| +| [ten-foot-experience.md](references/ten-foot-experience.md) | UX design decisions, remote interaction patterns, animation/motion | +| [layout-patterns.md](references/layout-patterns.md) | Building screens, navigation structure, component patterns, safe zones | +| [typography-and-color.md](references/typography-and-color.md) | Setting font sizes, choosing colors, ensuring readability at distance | +| [navigation-and-focus.md](references/navigation-and-focus.md) | Focus bugs, TVFocusGuideView, focus traps, back navigation, platform differences | +| [keyboard-handling.md](references/keyboard-handling.md) | Search screens, login forms, any text input UI | diff --git a/rn-tv-ui-best-practices/references/keyboard-handling.md b/rn-tv-ui-best-practices/references/keyboard-handling.md new file mode 100644 index 0000000..b6ffaa6 --- /dev/null +++ b/rn-tv-ui-best-practices/references/keyboard-handling.md @@ -0,0 +1,130 @@ +# Keyboard Handling + +Input patterns for React Native TV apps. D-pad typing is the slowest interaction on TV — minimize it first, then optimize what remains. + +## Input Minimization (Priority #1) + +Before building keyboard UI, reduce the need for typing: + +- Pre-filled options and smart defaults (past searches, popular searches). +- Voice input via system dictation or `react-native-voice`. +- Real-time validation to minimize corrections. +- Maintain input history so users don't retype. +- QR code authentication (TV shows QR, phone scans to authenticate). +- Mobile companion apps for complex input (auth, casting, search). + +## Built-In System Keyboard + +Trigger by rendering a standard `TextInput`. Keyboard appears automatically on focus. + +### Platform Differences + +- **Android TV (Gboard)**: Grid-based, arrow-navigated. Pops up center/bottom, covers UI beneath. +- **Apple tvOS**: Row-based, Siri Remote swipe-friendly. Also supports iOS Remote app and dictation. + +### Keyboard Types + +Use the appropriate type to minimize friction: + +- `default`: Full autocomplete & autocorrect +- `email-address`: @, ., .com shortcuts; autocorrect off +- `numeric`: Numbers only +- `number-pad`: Digits only (PINs, codes) +- `decimal-pad`: Numeric with decimal point +- `phone-pad`: Digits + #, + +- `url`: Includes /, ., .com shortcuts +- Password: Use `secureTextEntry` prop (not a keyboardType) + +**iOS-only types:** `ascii-capable`, `ascii-capable-number-pad`, `name-phone-pad`, `numbers-and-punctuation`, `twitter`, `web-search` + +**Android-only:** `visible-password` + +### Enhancing with RCU Events + +Map remote buttons to keyboard actions using `useTVEventHandler`: + +```jsx +import { useTVEventHandler } from 'react-native'; + +const SearchScreen = () => { + const inputRef = useRef(null); + const inputValueRef = useRef(''); + + const handleSearch = () => { + // Call search API with inputValueRef.current + }; + + useTVEventHandler((evt) => { + if (evt.eventType === 'play') { + handleSearch(); // "play" button = submit search + } + }); + + return ( + + { inputValueRef.current = text; }} + onSubmitEditing={handleSearch} + /> + + ); +}; +``` + +`onSubmitEditing` fires when the text input's submit button is pressed, which is the most common trigger. Depending on your UI, you may also want `onBlur` (submit when focus leaves the field) or to listen for events from surrounding `Pressable` / `Touchable` components (e.g., a dedicated "Search" button next to the input). Pick whichever matches how users actually complete the action in your flow. + +## Custom Keyboard + +When the system keyboard covers important UI or you need more control: + +### Implementation Pattern + +```jsx +const [showKeyboard, setShowKeyboard] = useState(false); + +return ( + + + setShowKeyboard(true)} + showSoftInputOnFocus={false} // Suppress default keyboard + /> + + {showKeyboard && } + +); +``` + +### Custom Keyboard Considerations + +- Set `showSoftInputOnFocus={false}` to suppress the default keyboard. +- Each key button needs two states: **focused** and **selected** (user skips over buttons to reach target letter). +- Wire each button's output to the TextInput value. +- Focus management within the keyboard grid follows standard TV navigation rules. + +### Tradeoff + +Custom keyboards give full UI control but users must learn your specific layout. The system keyboard is familiar even if less pretty. Only build custom when the system keyboard genuinely blocks critical UI (like YouTube's search with results visible below). + +## Voice Input + +- **With system keyboard**: Already handles dictation. Just wait for system to fill the TextInput. +- **With custom keyboard**: Need native code. Use `react-native-voice` library. +- Remember: adding voice requires microphone + speech recognition permissions. + +## Mobile Companion Apps + +Companion apps (YouTube, Netflix, Spotify pattern) offload input to the phone: +- Authentication via QR code (TV shows code, phone scans, backend binds devices via shared token). +- Search input typed on phone keyboard, sent to TV over local network. +- Media casting from phone to TV (no TV-side login needed). + +## Key Rules + +1. Prioritize input minimization — every keystroke saved is UX gained. +2. Use appropriate keyboard types (don't show full keyboard for a PIN). +3. Maintain input history. +4. Enable voice input where possible. +5. Consider companion app flows for complex authentication. diff --git a/rn-tv-ui-best-practices/references/layout-patterns.md b/rn-tv-ui-best-practices/references/layout-patterns.md new file mode 100644 index 0000000..843b8fb --- /dev/null +++ b/rn-tv-ui-best-practices/references/layout-patterns.md @@ -0,0 +1,203 @@ +# Layout Patterns and Common Components + +Structural patterns for TV interfaces: navigation, components, safe zones, and spacing. + +## Why Structure Matters + +Layout patterns reduce cognitive effort. Users focus on content rather than figuring out navigation. Every button press on a remote takes deliberate time, so predictability is a valuable feature. + +A well-designed layout provides three things: +1. **Orientation**: Where am I? +2. **Context**: What can I do here? +3. **Momentum**: Where can I go next? + +These patterns also create shared vocabulary for teams — designers, developers, and testers can communicate using the same terms (hero, swimlane, drawer, focus trap), turning complex interfaces into manageable, reusable systems. + +## Gotchas + +- Many TVs still apply **overscan** (5-10% cropped from edges). Keep all interactive elements inside a 5-10% safe zone margin. Only backgrounds/hero images extend to edge. +- Drawer open/close transitions must complete in **under 200ms**. Modal transitions ~150ms. Longer = sluggish. + +## Critical Values (Guidelines) + +Recommended starting points — adapt to your app's specific needs and user testing. + +``` +Safe Zone: 5-10% margin on all sides +Card Focus Scale: 3-5% larger +Row Vertical Padding: 1.5x card height +Drawer Items: 5-7 maximum +Tabs: 3-5 maximum +Animation Timing: Drawer < 200ms | Modal ~150ms +``` + +## Navigation Patterns + +### Drawer Navigation (Global) + +Left-edge menu for main sections. Acts as the app's structural backbone. + +**Behavior:** +- Opens when user presses left from leftmost focusable area (or menu/back shortcut). +- Dims the rest of the screen slightly to signal context shift. +- Focus trapped inside until user exits or selects. +- On close, restore focus to previously active element. + +**Rules:** +- 5-7 items maximum. +- Clear labels (icons + text for clarity). +- Open/close transition: under 200ms. + +```jsx + + navigate('home')} /> + navigate('movies')} /> + navigate('settings')} /> + +``` + +### Tab Navigation (Local) + +Organizes content within a single section (not between sections). Place beneath hero banner or above first content row. + +**Rules:** +- 3-5 tabs maximum. +- Current tab visually obvious (bold, underline, highlight). +- Left/right to switch tabs, down to enter content rows below. +- Tabs as primary navigation only works for apps with limited sections. Complex apps need a drawer. + +```jsx + + setCategory('popular')} /> + setCategory('new')} /> + setCategory('favorites')} /> + +``` + +### Modal Navigation + +Temporary focused interruptions (confirmations, playback controls, detail views). + +**Rules:** +- Trap focus inside. Dim/blur background. +- Restore focus to triggering element on close. +- Transitions ~150ms. Never stack multiple modals. +- Consistent placement: fade or scale from center. + +```jsx + + Are you sure you want to remove this item? +