gpui-patterns

cnwzhu's avatarfrom cnwzhu

Common UI patterns and advanced techniques for GPUI applications. Use when implementing modals, lists, forms, state sharing, or complex component compositions.

0stars🔀0forks📁View on GitHub🕐Updated Jan 11, 2026

When & Why to Use This Skill

This Claude skill serves as a comprehensive technical reference for GPUI (GPU-accelerated UI) development in Rust. It provides standardized, production-ready implementation patterns for essential UI components such as modals, dynamic lists, and validated forms. Beyond basic components, it covers advanced architectural techniques including global state management, parent-child communication, and focus handling. By utilizing these patterns, developers can significantly accelerate the creation of high-performance desktop applications while maintaining clean, maintainable, and idiomatic Rust code.

Use Cases

  • Implementing complex modal overlays and centered dialogs with backdrop interactions and state-driven visibility.
  • Building dynamic, interactive lists that support real-time item removal and efficient rendering of large datasets.
  • Creating robust data entry forms featuring real-time validation, error messaging, and standardized input styling.
  • Managing global application state using GPUI's context system to share data across disconnected components.
  • Designing sophisticated component architectures using the Builder Pattern and trait-based variants for flexible UI systems.
  • Handling asynchronous data fetching with integrated state machines to manage idle, loading, success, and error UI states.
  • Implementing advanced focus management and keyboard navigation for accessible and professional desktop interfaces.
namegpui-patterns
descriptionCommon UI patterns and advanced techniques for GPUI applications. Use when implementing modals, lists, forms, state sharing, or complex component compositions.

GPUI Patterns

This skill provides common UI patterns and advanced techniques for GPUI applications.

Modal/Overlay Pattern

Basic Modal

use gpui::*;

struct Modal {
    is_open: bool,
    content: SharedString,
}

impl Render for Modal {
    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        div()
            .when(self.is_open, |this| {
                this.absolute()
                    .inset_0()
                    .flex()
                    .items_center()
                    .justify_center()
                    .bg(rgba(0, 0, 0, 0.5))
                    .on_click(cx.listener(|this, _event, _window, cx| {
                        this.close(cx);
                    }))
                    .child(
                        div()
                            .p_6()
                            .bg(rgb(0x1a1a1a))
                            .rounded_lg()
                            .min_w(px(300.0))
                            .child(self.content.clone())
                    )
            })
    }
}

impl Modal {
    fn open(&mut self, content: impl Into<SharedString>, cx: &mut Context<Self>) {
        self.is_open = true;
        self.content = content.into();
        cx.notify();
    }
    
    fn close(&mut self, cx: &mut Context<Self>) {
        self.is_open = false;
        cx.notify();
    }
}

List Pattern

Dynamic List Rendering

struct ListView {
    items: Vec<String>,
}

impl Render for ListView {
    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        div()
            .v_flex()
            .gap_2()
            .children(
                self.items.iter().enumerate().map(|(index, item)| {
                    self.render_item(index, item, cx)
                })
            )
    }
}

impl ListView {
    fn render_item(
        &self,
        index: usize,
        item: &str,
        cx: &Context<Self>,
    ) -> impl IntoElement {
        div()
            .p_3()
            .bg(rgb(0x1a1a1a))
            .rounded(px(4.0))
            .flex()
            .justify_between()
            .child(format!("{}. {}", index + 1, item))
            .child(
                div()
                    .px_3()
                    .py_1()
                    .bg(rgb(0xef4444))
                    .rounded(px(4.0))
                    .cursor_pointer()
                    .child("Delete")
                    .on_click(cx.listener(move |this, _event, _window, cx| {
                        this.remove_item(index, cx);
                    }))
            )
    }
    
    fn remove_item(&mut self, index: usize, cx: &mut Context<Self>) {
        if index < self.items.len() {
            self.items.remove(index);
            cx.notify();
        }
    }
}

Form Pattern

Form with Validation

struct LoginForm {
    username: SharedString,
    password: SharedString,
    error: Option<SharedString>,
}

impl Render for LoginForm {
    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        div()
            .v_flex()
            .gap_4()
            .p_6()
            .when_some(self.error.clone(), |this, error| {
                this.child(
                    div()
                        .p_3()
                        .bg(rgb(0xef4444))
                        .rounded(px(4.0))
                        .child(error)
                )
            })
            .child(self.render_input("Username", &self.username, cx))
            .child(self.render_input("Password", &self.password, cx))
            .child(
                div()
                    .px_6()
                    .py_3()
                    .bg(rgb(0x3b82f6))
                    .rounded(px(6.0))
                    .cursor_pointer()
                    .child("Login")
                    .on_click(cx.listener(|this, _event, _window, cx| {
                        this.submit(cx);
                    }))
            )
    }
}

impl LoginForm {
    fn render_input(
        &self,
        label: &str,
        value: &SharedString,
        _cx: &Context<Self>,
    ) -> impl IntoElement {
        div()
            .v_flex()
            .gap_1()
            .child(
                div().text_sm().child(label)
            )
            .child(
                div()
                    .w_full()
                    .px_3()
                    .py_2()
                    .bg(rgb(0x1a1a1a))
                    .border_1()
                    .border_color(rgb(0x4a4a4a))
                    .rounded(px(4.0))
                    .child(value.clone())
            )
    }
    
    fn submit(&mut self, cx: &mut Context<Self>) {
        if self.username.is_empty() || self.password.is_empty() {
            self.error = Some("Please fill in all fields".into());
            cx.notify();
            return;
        }
        
        self.error = None;
        // Handle login...
    }
}

Global State Pattern

Shared Application State

#[derive(Clone)]
struct AppState {
    user: Option<String>,
    theme: String,
}

// Set global state
fn init_app_state(cx: &mut App) {
    let state = AppState {
        user: None,
        theme: "dark".to_string(),
    };
    cx.set_global(state);
}

// Access global state
fn use_app_state(cx: &App) -> AppState {
    cx.global::<AppState>().clone()
}

// Update global state
fn set_user(cx: &mut App, user: String) {
    let mut state = cx.global::<AppState>().clone();
    state.user = Some(user);
    cx.set_global(state);
}

Parent-Child Communication

Child Notifying Parent

#[derive(Clone, Debug)]
enum ChildEvent {
    ValueChanged(i32),
}

impl EventEmitter<ChildEvent> for Child {}

struct Parent {
    child: Entity<Child>,
    _subscription: Subscription,
}

impl Parent {
    fn new(cx: &mut Context<Self>) -> Self {
        let child = cx.new(|_| Child::new());
        
        let subscription = cx.subscribe(&child, |this, _child, event, cx| {
            match event {
                ChildEvent::ValueChanged(value) => {
                    println!("Child value changed to: {}", value);
                    cx.notify();
                }
            }
        });
        
        Self {
            child,
            _subscription: subscription,
        }
    }
}

struct Child {
    value: i32,
}

impl Child {
    fn new() -> Self {
        Self { value: 0 }
    }
    
    fn set_value(&mut self, value: i32, cx: &mut Context<Self>) {
        self.value = value;
        cx.emit(ChildEvent::ValueChanged(value));
        cx.notify();
    }
}

Tab Navigation

Tab View Pattern

#[derive(Clone, Copy, PartialEq)]
enum Tab {
    Home,
    Settings,
    Profile,
}

struct TabView {
    active_tab: Tab,
}

impl Render for TabView {
    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        div()
            .v_flex()
            .size_full()
            .child(self.render_tabs(cx))
            .child(self.render_content())
    }
}

impl TabView {
    fn render_tabs(&self, cx: &Context<Self>) -> impl IntoElement {
        div()
            .h_flex()
            .gap_2()
            .p_2()
            .bg(rgb(0x1a1a1a))
            .child(self.render_tab("Home", Tab::Home, cx))
            .child(self.render_tab("Settings", Tab::Settings, cx))
            .child(self.render_tab("Profile", Tab::Profile, cx))
    }
    
    fn render_tab(&self, label: &str, tab: Tab, cx: &Context<Self>) -> impl IntoElement {
        let is_active = self.active_tab == tab;
        
        div()
            .px_4()
            .py_2()
            .rounded(px(4.0))
            .cursor_pointer()
            .bg(if is_active { rgb(0x3b82f6) } else { rgb(0x2a2a2a) })
            .child(label)
            .on_click(cx.listener(move |this, _event, _window, cx| {
                this.active_tab = tab;
                cx.notify();
            }))
    }
    
    fn render_content(&self) -> impl IntoElement {
        match self.active_tab {
            Tab::Home => div().child("Home Content"),
            Tab::Settings => div().child("Settings Content"),
            Tab::Profile => div().child("Profile Content"),
        }
    }
}

Loading State Pattern

Async Data Loading

enum LoadState<T> {
    Idle,
    Loading,
    Loaded(T),
    Error(String),
}

struct DataView {
    state: LoadState<Vec<String>>,
}

impl Render for DataView {
    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        match &self.state {
            LoadState::Idle => {
                div().child("Click to load")
                    .on_click(cx.listener(|this, _event, _window, cx| {
                        this.load_data(cx);
                    }))
            }
            LoadState::Loading => {
                div().child("Loading...")
            }
            LoadState::Loaded(items) => {
                div()
                    .v_flex()
                    .gap_2()
                    .children(items.iter().map(|item| {
                        div().child(item.clone())
                    }))
            }
            LoadState::Error(error) => {
                div()
                    .p_3()
                    .bg(rgb(0xef4444))
                    .child(format!("Error: {}", error))
            }
        }
    }
}

impl DataView {
    fn load_data(&mut self, cx: &mut Context<Self>) {
        self.state = LoadState::Loading;
        cx.notify();
        
        cx.spawn(async move |this, cx| {
            match fetch_data().await {
                Ok(data) => {
                    this.update(&mut *cx, |view, cx| {
                        view.state = LoadState::Loaded(data);
                        cx.notify();
                    })?;
                }
                Err(e) => {
                    this.update(&mut *cx, |view, cx| {
                        view.state = LoadState::Error(e.to_string());
                        cx.notify();
                    })?;
                }
            }
            
            Ok(())
        }).detach();
    }
}

async fn fetch_data() -> Result<Vec<String>, anyhow::Error> {
    // Simulate API call
    tokio::time::sleep(Duration::from_secs(1)).await;
    Ok(vec!["Item 1".to_string(), "Item 2".to_string()])
}

Dropdown Pattern

struct Dropdown {
    is_open: bool,
    selected: Option<String>,
    options: Vec<String>,
}

impl Render for Dropdown {
    fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        div()
            .relative()
            .child(
                div()
                    .px_4()
                    .py_2()
                    .bg(rgb(0x1a1a1a))
                    .border_1()
                    .border_color(rgb(0x4a4a4a))
                    .rounded(px(4.0))
                    .cursor_pointer()
                    .child(self.selected.clone().unwrap_or("Select...".into()))
                    .on_click(cx.listener(|this, _event, _window, cx| {
                        this.is_open = !this.is_open;
                        cx.notify();
                    }))
            )
            .when(self.is_open, |this| {
                this.child(
                    div()
                        .absolute()
                        .top(px(40.0))
                        .left_0()
                        .w_full()
                        .bg(rgb(0x1a1a1a))
                        .border_1()
                        .border_color(rgb(0x4a4a4a))
                        .rounded(px(4.0))
                        .v_flex()
                        .children(
                            self.options.iter().map(|option| {
                                let option = option.clone();
                                div()
                                    .px_4()
                                    .py_2()
                                    .cursor_pointer()
                                    .hover(|style| style.bg(rgb(0x2a2a2a)))
                                    .child(option.clone())
                                    .on_click(cx.listener(move |this, _event, _window, cx| {
                                        this.selected = Some(option.clone());
                                        this.is_open = false;
                                        cx.notify();
                                    }))
                            })
                        )
                )
            })
    }
}

Production Component Patterns

[!IMPORTANT] gpui-component is optional. These patterns show how the library implements components, but you can build the same functionality with pure GPUI code. Use gpui-component for convenience, or implement patterns yourself for full control.

These patterns are based on real implementations from gpui-component.

Builder Pattern with Trait Methods

Create fluent APIs using traits:

use gpui::*;

pub trait ButtonVariants: Sized {
    fn with_variant(self, variant: ButtonVariant) -> Self;
    
    fn primary(self) -> Self {
        self.with_variant(ButtonVariant::Primary)
    }
    
    fn danger(self) -> Self {
        self.with_variant(ButtonVariant::Danger)
    }
    
    fn ghost(self) -> Self {
        self.with_variant(ButtonVariant::Ghost)
    }
}

#[derive(Clone, Copy, PartialEq, Eq, Default)]
pub enum ButtonVariant {
    Primary,
    #[default]
    Secondary,
    Danger,
    Ghost,
}

impl ButtonVariants for Button {
    fn with_variant(mut self, variant: ButtonVariant) -> Self {
        self.variant = variant;
        self
    }
}

// Usage
Button::new("save")
    .primary()
    .label("Save")
    .on_click(|_, _, _| {})

Component Structure Pattern

Production-ready component with all common features:

use gpui::*;
use std::rc::Rc;

#[derive(IntoElement)]
pub struct Button {
    id: ElementId,
    base: Stateful<Div>,
    style: StyleRefinement,
    
    // Content
    icon: Option<Icon>,
    label: Option<SharedString>,
    children: Vec<AnyElement>,
    
    // State
    disabled: bool,
    selected: bool,
    loading: bool,
    variant: ButtonVariant,
    size: Size,
    
    // Callbacks
    on_click: Option<Rc<dyn Fn(&ClickEvent, &mut Window, &mut App)>>,
    on_hover: Option<Rc<dyn Fn(&bool, &mut Window, &mut App)>>,
    
    // Features
    tooltip: Option<(SharedString, Option<Box<dyn Action>>)>,
    
    // Focus
    tab_index: isize,
    tab_stop: bool,
}

impl Button {
    pub fn new(id: impl Into<ElementId>) -> Self {
        let id = id.into();
        Self {
            id: id.clone(),
            base: div().id(id),
            style: StyleRefinement::default(),
            icon: None,
            label: None,
            children: Vec::new(),
            disabled: false,
            selected: false,
            loading: false,
            variant: ButtonVariant::default(),
            size: Size::Medium,
            on_click: None,
            on_hover: None,
            tooltip: None,
            tab_index: 0,
            tab_stop: true,
        }
    }
    
    pub fn label(mut self, label: impl Into<SharedString>) -> Self {
        self.label = Some(label.into());
        self
    }
    
    pub fn icon(mut self, icon: impl Into<Icon>) -> Self {
        self.icon = Some(icon.into());
        self
    }
    
    pub fn loading(mut self, loading: bool) -> Self {
        self.loading = loading;
        self
    }
    
    pub fn on_click(
        mut self,
        handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static,
    ) -> Self {
        self.on_click = Some(Rc::new(handler));
        self
    }
    
    pub fn tooltip(mut self, tooltip: impl Into<SharedString>) -> Self {
        self.tooltip = Some((tooltip.into(), None));
        self
    }
}

// Trait implementations
impl Styled for Button {
    fn style(&mut self) -> &mut StyleRefinement {
        &mut self.style
    }
}

impl Sizable for Button {
    fn with_size(mut self, size: impl Into<Size>) -> Self {
        self.size = size.into();
        self
    }
}

impl Disableable for Button {
    fn disabled(mut self, disabled: bool) -> Self {
        self.disabled = disabled;
        self
    }
}

impl Selectable for Button {
    fn selected(mut self, selected: bool) -> Self {
        self.selected = selected;
        self
    }
}

impl ParentElement for Button {
    fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) {
        self.children.extend(elements)
    }
}

Variant System with States

Complete variant system handling all interaction states:

struct ButtonVariantStyle {
    bg: Hsla,
    border: Hsla,
    fg: Hsla,
    shadow: bool,
}

impl ButtonVariant {
    fn normal(&self, outline: bool, cx: &mut App) -> ButtonVariantStyle {
        let bg = if outline {
            cx.theme().background
        } else {
            match self {
                Self::Primary => cx.theme().primary,
                Self::Secondary => cx.theme().secondary,
                Self::Danger => cx.theme().danger,
                Self::Ghost => cx.theme().transparent,
            }
        };
        
        let fg = match self {
            Self::Primary if outline => cx.theme().primary,
            Self::Primary => cx.theme().primary_foreground,
            Self::Danger if outline => cx.theme().danger,
            Self::Danger => cx.theme().danger_foreground,
            _ => cx.theme().foreground,
        };
        
        let border = if outline {
            match self {
                Self::Primary => cx.theme().primary,
                Self::Danger => cx.theme().danger,
                _ => cx.theme().border,
            }
        } else {
            bg
        };
        
        ButtonVariantStyle {
            bg,
            border,
            fg,
            shadow: matches!(self, Self::Primary | Self::Secondary),
        }
    }
    
    fn hovered(&self, outline: bool, cx: &mut App) -> ButtonVariantStyle {
        let bg = match self {
            Self::Primary if outline => cx.theme().primary.opacity(0.1),
            Self::Primary => cx.theme().primary_hover,
            Self::Danger if outline => cx.theme().danger.opacity(0.1),
            Self::Danger => cx.theme().danger_hover,
            Self::Secondary => cx.theme().secondary_hover,
            Self::Ghost => cx.theme().element_hover,
        };
        
        let mut style = self.normal(outline, cx);
        style.bg = bg;
        style
    }
    
    fn active(&self, outline: bool, cx: &mut App) -> ButtonVariantStyle {
        let bg = match self {
            Self::Primary => cx.theme().primary_active,
            Self::Danger => cx.theme().danger_active,
            Self::Secondary => cx.theme().secondary_active,
            Self::Ghost => cx.theme().element_active,
        };
        
        let mut style = self.normal(outline, cx);
        style.bg = bg;
        style
    }
    
    fn disabled(&self, outline: bool, cx: &mut App) -> ButtonVariantStyle {
        let mut style = self.normal(outline, cx);
        style.bg = style.bg.opacity(0.5);
        style.fg = style.fg.opacity(0.5);
        style.border = style.border.opacity(0.5);
        style.shadow = false;
        style
    }
}

RenderOnce Implementation

Complete render implementation with all states:

impl RenderOnce for Button {
    fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
        let is_clickable = !self.disabled && !self.loading && self.on_click.is_some();
        let normal_style = self.variant.normal(false, cx);
        
        // Get or create focus handle
        let focus_handle = window
            .use_keyed_state(self.id.clone(), cx, |_, cx| cx.focus_handle())
            .read(cx)
            .clone();
        let is_focused = focus_handle.is_focused(window);
        
        self.base
            .when(!self.disabled, |this| {
                this.track_focus(&focus_handle.tab_index(self.tab_index).tab_stop(self.tab_stop))
            })
            .flex()
            .items_center()
            .justify_center()
            .cursor_default()
            .when(cx.theme().shadow && normal_style.shadow, |this| {
                this.shadow_xs()
            })
            // Sizing based on whether it's icon-only or has label
            .when(!self.label.is_some() && self.children.is_empty(), |this| {
                // Icon button - square
                match self.size {
                    Size::XSmall => this.size_5(),
                    Size::Small => this.size_6(),
                    _ => this.size_8(),
                }
            })
            .when(self.label.is_some() || !self.children.is_empty(), |this| {
                // Normal button - rectangular
                match self.size {
                    Size::XSmall => this.h_5().px_1(),
                    Size::Small => this.h_6().px_3(),
                    _ => this.h_8().px_4(),
                }
            })
            .rounded_md()
            .border_1()
            .text_color(normal_style.fg)
            .border_color(normal_style.border)
            .bg(normal_style.bg)
            .when(self.selected, |this| {
                let selected_style = self.variant.active(false, cx);
                this.bg(selected_style.bg)
                    .border_color(selected_style.border)
                    .text_color(selected_style.fg)
            })
            .when(!self.disabled && !self.selected, |this| {
                this.hover(|this| {
                    let hover_style = self.variant.hovered(false, cx);
                    this.bg(hover_style.bg)
                        .border_color(hover_style.border)
                        .text_color(hover_style.fg)
                })
                .active(|this| {
                    let active_style = self.variant.active(false, cx);
                    this.bg(active_style.bg)
                        .border_color(active_style.border)
                        .text_color(active_style.fg)
                })
            })
            .when(self.disabled, |this| {
                let disabled_style = self.variant.disabled(false, cx);
                this.bg(disabled_style.bg)
                    .text_color(disabled_style.fg)
                    .border_color(disabled_style.border)
                    .shadow_none()
            })
            .refine_style(&self.style)
            .when_some(self.on_click, |this, on_click| {
                this.on_click(move |event, window, cx| {
                    if is_clickable {
                        on_click(event, window, cx);
                    } else {
                        cx.stop_propagation();
                    }
                })
            })
            .child(
                div()
                    .flex()
                    .items_center()
                    .justify_center()
                    .gap_2()
                    .when(!self.loading, |this| {
                        this.when_some(self.icon, |this, icon| {
                            this.child(icon.with_size(self.size))
                        })
                    })
                    .when(self.loading, |this| {
                        this.child(Spinner::new().with_size(self.size))
                    })
                    .when_some(self.label, |this, label| {
                        this.child(div().line_height(relative(1.)).child(label))
                    })
                    .children(self.children)
            )
            .when_some(self.tooltip, |this, (tooltip, action)| {
                this.tooltip(move |window, cx| {
                    Tooltip::new(tooltip.clone())
                        .when_some(action.clone(), |this, action| {
                            this.action(action.as_ref(), None)
                        })
                        .build(window, cx)
                })
            })
            .focus_ring(is_focused, px(0.), window, cx)
    }
}

Children Management (TabBar Pattern)

Using SmallVec for performance with dynamic children:

use smallvec::SmallVec;

#[derive(IntoElement)]
pub struct TabBar {
    base: Stateful<Div>,
    children: SmallVec<[Tab; 2]>, // Optimize for 2 tabs on stack
    selected_index: Option<usize>,
    variant: TabVariant,
    size: Size,
    on_click: Option<Rc<dyn Fn(&usize, &mut Window, &mut App) + 'static>>,
}

impl TabBar {
    pub fn new(id: impl Into<ElementId>) -> Self {
        Self {
            base: div().id(id),
            children: SmallVec::new(),
            selected_index: None,
            variant: TabVariant::default(),
            size: Size::default(),
            on_click: None,
        }
    }
    
    pub fn children(mut self, children: impl IntoIterator<Item = impl Into<Tab>>) -> Self {
        self.children.extend(children.into_iter().map(Into::into));
        self
    }
    
    pub fn child(mut self, child: impl Into<Tab>) -> Self {
        self.children.push(child.into());
        self
    }
    
    pub fn selected_index(mut self, index: usize) -> Self {
        self.selected_index = Some(index);
        self
    }
    
    pub fn on_click<F>(mut self, on_click: F) -> Self
    where
        F: Fn(&usize, &mut Window, &mut App) + 'static,
    {
        self.on_click = Some(Rc::new(on_click));
        self
    }
}

impl RenderOnce for TabBar {
    fn render(self, _: &mut Window, cx: &mut App) -> impl IntoElement {
        let selected_index = self.selected_index;
        let on_click = self.on_click.clone();
        
        self.base
            .flex()
            .items_center()
            .gap_2()
            .child(
                div()
                    .flex()
                    .gap_2()
                    .children(
                        self.children.into_iter().enumerate().map(|(ix, child)| {
                            child
                                .with_variant(self.variant) // Inherit variant
                                .with_size(self.size) // Inherit size
                                .when_some(selected_index, |this, selected_ix| {
                                    this.selected(selected_ix == ix)
                                })
                                .when_some(on_click.clone(), move |this, on_click| {
                                    this.on_click(move |_, window, cx| {
                                        on_click(&ix, window, cx)
                                    })
                                })
                        })
                    )
            )
    }
}

Size System Pattern

Responsive sizing with custom values:

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Size {
    XSmall,
    Small,
    Medium,
    Large,
    Size(Pixels), // Custom pixel size
}

impl Size {
    pub fn button_height(&self) -> Pixels {
        match self {
            Size::Size(px) => *px,
            Size::XSmall => px(20.0),
            Size::Small => px(24.0),
            Size::Medium => px(32.0),
            Size::Large => px(40.0),
        }
    }
    
    pub fn icon_size(&self) -> Size {
        match self {
            Size::Size(px) => Size::Size(*px * 0.75),
            _ => *self,
        }
    }
}

// In component:
match self.size {
    Size::Size(v) => this.h(v).px(v * 0.2),
    Size::XSmall => this.h_5().px_1(),
    Size::Small => this.h_6().px_3(),
    Size::Medium => this.h_8().px_4(),
    Size::Large => this.h_10().px_6(),
}

Focus Management Pattern

Complete focus handling with keyed state:

impl RenderOnce for Input {
    fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
        // Use keyed state to persist focus handle
        let focus_handle = window
            .use_keyed_state(self.id.clone(), cx, |_, cx| cx.focus_handle())
            .read(cx)
            .clone();
        
        let is_focused = focus_handle.is_focused(window);
        
        div()
            .track_focus(&focus_handle.tab_index(self.tab_index))
            .when(is_focused, |this| {
                this.border_color(cx.theme().primary)
            })
            .on_key_down(|event, window, cx| {
                if event.keystroke.key == "Enter" {
                    // Handle enter
                }
            })
            .focus_ring(is_focused, px(2.), window, cx)
    }
}

Summary

  • Use modals for overlay content
  • Implement dynamic lists with .children() and iterators
  • Create forms with validation and error handling
  • Use global state with cx.set_global() and cx.global()
  • Communicate between components with events and subscriptions
  • Manage tabs with state and conditional rendering
  • Handle async loading with state machines
  • Implement dropdowns with relative/absolute positioning
  • Use builder pattern with traits for fluent APIs
  • Implement variant systems with normal/hover/active/disabled states
  • Use SmallVec for performance with dynamic children
  • Manage focus with keyed state and track_focus
  • Support custom sizes with Size enum

References