Gpui Focus Handle
Build keyboard-navigable interfaces with proper focus management
✨ The solution you've been looking for
Focus management and keyboard navigation in GPUI. Use when handling focus, focus handles, or keyboard navigation.
See It In Action
Interactive preview & real-world examples
AI Conversation Simulator
See how users interact with this skill
User Prompt
I need to create a modal dialog that traps focus inside it when Tab is pressed and automatically focuses the first input field when opened
Skill Processing
Analyzing request...
Agent Response
Complete implementation with focus trap logic, auto-focus behavior, and proper keyboard navigation within the modal
Quick Start (3 Steps)
Get up and running in minutes
Install
claude-code skill install gpui-focus-handle
claude-code skill install gpui-focus-handleConfig
First Trigger
@gpui-focus-handle helpCommands
| Command | Description | Required Args |
|---|---|---|
| @gpui-focus-handle modal-dialog-with-focus-trap | Create a modal that keeps keyboard focus within its boundaries and auto-focuses the first input | None |
| @gpui-focus-handle form-with-sequential-focus-navigation | Build a form where users can navigate between inputs using Tab/Shift-Tab with visual focus indicators | None |
| @gpui-focus-handle searchable-list-with-dynamic-focus | Implement a search interface that focuses the input when activated and manages focus states | None |
Typical Use Cases
Modal Dialog with Focus Trap
Create a modal that keeps keyboard focus within its boundaries and auto-focuses the first input
Form with Sequential Focus Navigation
Build a form where users can navigate between inputs using Tab/Shift-Tab with visual focus indicators
Searchable List with Dynamic Focus
Implement a search interface that focuses the input when activated and manages focus states
Overview
Overview
GPUI’s focus system enables keyboard navigation and focus management.
Key Concepts:
- FocusHandle: Reference to focusable element
- Focus tracking: Current focused element
- Keyboard navigation: Tab/Shift-Tab between elements
- Focus events: on_focus, on_blur
Quick Start
Creating Focus Handles
1struct FocusableComponent {
2 focus_handle: FocusHandle,
3}
4
5impl FocusableComponent {
6 fn new(cx: &mut Context<Self>) -> Self {
7 Self {
8 focus_handle: cx.focus_handle(),
9 }
10 }
11}
Making Elements Focusable
1impl Render for FocusableComponent {
2 fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
3 div()
4 .track_focus(&self.focus_handle)
5 .on_action(cx.listener(Self::on_enter))
6 .child("Focusable content")
7 }
8
9 fn on_enter(&mut self, _: &Enter, cx: &mut Context<Self>) {
10 // Handle Enter key when focused
11 cx.notify();
12 }
13}
Focus Management
1impl MyComponent {
2 fn focus(&mut self, cx: &mut Context<Self>) {
3 self.focus_handle.focus(cx);
4 }
5
6 fn is_focused(&self, cx: &App) -> bool {
7 self.focus_handle.is_focused(cx)
8 }
9
10 fn blur(&mut self, cx: &mut Context<Self>) {
11 cx.blur();
12 }
13}
Focus Events
Handling Focus Changes
1impl Render for MyInput {
2 fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
3 let is_focused = self.focus_handle.is_focused(cx);
4
5 div()
6 .track_focus(&self.focus_handle)
7 .on_focus(cx.listener(|this, _event, cx| {
8 this.on_focus(cx);
9 }))
10 .on_blur(cx.listener(|this, _event, cx| {
11 this.on_blur(cx);
12 }))
13 .when(is_focused, |el| {
14 el.bg(cx.theme().focused_background)
15 })
16 .child(self.render_content())
17 }
18}
19
20impl MyInput {
21 fn on_focus(&mut self, cx: &mut Context<Self>) {
22 // Handle focus gained
23 cx.notify();
24 }
25
26 fn on_blur(&mut self, cx: &mut Context<Self>) {
27 // Handle focus lost
28 cx.notify();
29 }
30}
Keyboard Navigation
Tab Order
Elements with track_focus() automatically participate in Tab navigation.
1div()
2 .child(
3 input1.track_focus(&focus1) // Tab order: 1
4 )
5 .child(
6 input2.track_focus(&focus2) // Tab order: 2
7 )
8 .child(
9 input3.track_focus(&focus3) // Tab order: 3
10 )
Focus Within Containers
1impl Container {
2 fn focus_first(&mut self, cx: &mut Context<Self>) {
3 if let Some(first) = self.children.first() {
4 first.update(cx, |child, cx| {
5 child.focus_handle.focus(cx);
6 });
7 }
8 }
9
10 fn focus_next(&mut self, cx: &mut Context<Self>) {
11 // Custom focus navigation logic
12 }
13}
Common Patterns
1. Auto-focus on Mount
1impl MyDialog {
2 fn new(cx: &mut Context<Self>) -> Self {
3 let focus_handle = cx.focus_handle();
4
5 // Focus when created
6 focus_handle.focus(cx);
7
8 Self { focus_handle }
9 }
10}
2. Focus Trap (Modal)
1impl Modal {
2 fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
3 div()
4 .track_focus(&self.focus_handle)
5 .on_key_down(cx.listener(|this, event: &KeyDownEvent, cx| {
6 if event.key == Key::Tab {
7 // Keep focus within modal
8 this.focus_next_in_modal(cx);
9 cx.stop_propagation();
10 }
11 }))
12 .child(self.render_content())
13 }
14}
3. Conditional Focus
1impl Searchable {
2 fn render(&mut self, _: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
3 div()
4 .track_focus(&self.focus_handle)
5 .when(self.search_active, |el| {
6 el.on_mount(cx.listener(|this, _, cx| {
7 this.focus_handle.focus(cx);
8 }))
9 })
10 .child(self.search_input())
11 }
12}
Best Practices
✅ Track Focus on Interactive Elements
1// ✅ Good: Track focus for keyboard interaction
2input()
3 .track_focus(&self.focus_handle)
4 .on_action(cx.listener(Self::on_enter))
✅ Provide Visual Focus Indicators
1let is_focused = self.focus_handle.is_focused(cx);
2
3div()
4 .when(is_focused, |el| {
5 el.border_color(cx.theme().focused_border)
6 })
❌ Don’t: Forget to Track Focus
1// ❌ Bad: No track_focus, keyboard navigation won't work
2div()
3 .on_action(cx.listener(Self::on_enter))
Reference Documentation
- API Reference: See api-reference.md
- FocusHandle API, focus management
- Events, keyboard navigation
- Best practices
What Users Are Saying
Real feedback from the community
Environment Matrix
Dependencies
Framework Support
Context Window
Security & Privacy
Information
- Author
- longbridge
- Updated
- 2026-01-30
- Category
- frontend
Related Skills
Gpui Focus Handle
Focus management and keyboard navigation in GPUI. Use when handling focus, focus handles, or …
View Details →Generate Component Story
Create story examples for components. Use when writing stories, creating examples, or demonstrating …
View Details →Generate Component Story
Create story examples for components. Use when writing stories, creating examples, or demonstrating …
View Details →