Smithery Logo
MCPsSkillsDocsPricing
Login
NewFlame, an assistant that learns and improves. Available onTelegramSlack
    cnwzhu

    gpui-elements

    cnwzhu/gpui-elements
    Design
    5
    2 installs

    About

    SKILL.md

    Install

    • Telegram
      Telegram
    • Slack
      Slack
    • Claude Code
      Claude Code
    • Codex
      Codex
    • OpenClaw
      OpenClaw
    • Cursor
      Cursor
    • Amp
      Amp
    • GitHub Copilot
      GitHub Copilot
    • Gemini CLI
      Gemini CLI
    • Kilo Code
      Kilo Code
    • Junie
      Junie
    • Replit
      Replit
    • Windsurf
      Windsurf
    • Cline
      Cline
    • Continue
      Continue
    • OpenCode
      OpenCode
    • OpenHands
      OpenHands
    • Roo Code
      Roo Code
    • Augment
      Augment
    • Goose
      Goose
    • Trae
      Trae
    • Zencoder
      Zencoder
    • Antigravity
      Antigravity
    • Download skill
    ├─
    ├─
    └─
    Smithery Logo

    Give agents more agency

    Resources

    DocumentationPrivacy PolicySystem Status

    Company

    PricingAboutBlog

    Connect

    © 2026 Smithery. All rights reserved.

    About

    UI element creation and composition with GPUI. Use when building element trees, creating custom components, implementing layouts, or working with conditional rendering.

    SKILL.md

    GPUI Elements

    This skill covers creating and composing UI elements in GPUI applications.

    Overview

    Elements are the building blocks of GPUI UIs:

    • Built with div() as the base element
    • Styled with chainable methods
    • Composed with .child() and .children()
    • Support conditional rendering with .when()
    • Use flexbox for layout

    Basic Element Creation

    div() Element

    use gpui::*;
    
    impl Render for MyView {
        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
            div()
                .child("Hello, GPUI!")
        }
    }
    

    Adding Children

    div()
        .child("First child")
        .child(
            div()
                .child("Nested child")
        )
        .child("Third child")
    

    Multiple Children with Vector

    let items = vec!["One", "Two", "Three"];
    
    div().children(
        items.into_iter().map(|text| {
            div().child(text)
        })
    )
    

    Text Elements

    String Types

    use gpui::*;
    
    impl Render for MyView {
        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
            div()
                // &str
                .child("Static text")
                // String
                .child(format!("Count: {}", self.count))
                // SharedString (most efficient)
                .child(self.title.clone())
        }
    }
    

    SharedString

    use gpui::*;
    
    struct MyView {
        title: SharedString,
    }
    
    impl MyView {
        fn new() -> Self {
            Self {
                title: "Default Title".into(),
            }
        }
        
        fn set_title(&mut self, title: impl Into<SharedString>) {
            self.title = title.into();
        }
    }
    
    // SharedString implements IntoElement
    impl Render for MyView {
        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
            div().child(self.title.clone())
        }
    }
    

    Conditional Rendering

    when() Method

    div()
        .when(condition, |this| {
            this.bg(rgb(0x3b82f6))
                .child("Condition is true")
        })
    

    when_some() for Options

    div()
        .when_some(maybe_text, |this, text| {
            this.child(text)
        })
    

    Practical Example

    struct MyView {
        is_active: bool,
        error: Option<String>,
    }
    
    impl Render for MyView {
        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
            div()
                .when(self.is_active, |this| {
                    this.bg(rgb(0x22c55e))
                })
                .when_some(self.error.clone(), |this, error| {
                    this.child(
                        div()
                            .p_2()
                            .bg(rgb(0xef4444))
                            .text_color(rgb(0xffffff))
                            .child(error)
                    )
                })
        }
    }
    

    Custom Components

    RenderOnce Components

    use gpui::*;
    
    #[derive(IntoElement)]
    struct Button {
        label: SharedString,
        on_click: Option<Box<dyn Fn(&mut App) + 'static>>,
    }
    
    impl Button {
        fn new(label: impl Into<SharedString>) -> Self {
            Self {
                label: label.into(),
                on_click: None,
            }
        }
        
        fn on_click(mut self, handler: impl Fn(&mut App) + 'static) -> Self {
            self.on_click = Some(Box::new(handler));
            self
        }
    }
    
    impl RenderOnce for Button {
        fn render(self, _window: &mut Window, _cx: &mut App) -> impl IntoElement {
            let mut element = div()
                .px_4()
                .py_2()
                .bg(rgb(0x3b82f6))
                .text_color(rgb(0xffffff))
                .rounded(px(6.0))
                .cursor_pointer()
                .child(self.label);
            
            if let Some(handler) = self.on_click {
                element = element.on_click(move |_event, _window, cx| {
                    handler(cx);
                });
            }
            
            element
        }
    }
    
    // Usage
    impl Render for MyView {
        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
            div().child(
                Button::new("Click Me")
                    .on_click(|cx| {
                        println!("Button clicked!");
                    })
            )
        }
    }
    

    Render Components

    struct Card {
        title: SharedString,
        content: SharedString,
    }
    
    impl Render for Card {
        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
            div()
                .p_4()
                .bg(rgb(0x1a1a1a))
                .rounded(px(8.0))
                .flex()
                .flex_col()
                .gap_2()
                .child(
                    div()
                        .text_lg()
                        .font_bold()
                        .child(self.title.clone())
                )
                .child(
                    div()
                        .text_sm()
                        .child(self.content.clone())
                )
        }
    }
    

    Layout Patterns

    Vertical Stack

    div()
        .flex()
        .flex_col()
        .gap_4()
        .child("Item 1")
        .child("Item 2")
        .child("Item 3")
    

    Horizontal Row

    div()
        .flex()
        .flex_row()
        .gap_4()
        .items_center()
        .child("Left")
        .child("Center")
        .child("Right")
    

    Grid-like Layout

    div()
        .flex()
        .flex_wrap()
        .gap_4()
        .children((0..12).map(|i| {
            div()
                .w(px(100.0))
                .h(px(100.0))
                .bg(rgb(0x3b82f6))
                .child(format!("Item {}", i))
        }))
    

    Centering

    div()
        .flex()
        .items_center()
        .justify_center()
        .size_full()
        .child("Centered content")
    

    Dynamic Lists

    Simple List

    struct ListView {
        items: Vec<String>,
    }
    
    impl Render for ListView {
        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
            div()
                .flex()
                .flex_col()
                .gap_2()
                .children(
                    self.items.iter().map(|item| {
                        div()
                            .p_2()
                            .bg(rgb(0x1a1a1a))
                            .rounded(px(4.0))
                            .child(item.clone())
                    })
                )
        }
    }
    

    List with Index

    div()
        .children(
            self.items.iter().enumerate().map(|(i, item)| {
                div()
                    .child(format!("{}. {}", i + 1, item))
            })
        )
    

    Nested Components

    Component Composition

    struct Header;
    impl Render for Header {
        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
            div()
                .h(px(64.0))
                .bg(rgb(0x1a1a1a))
                .child("Header")
        }
    }
    
    struct Sidebar;
    impl Render for Sidebar {
        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
            div()
                .w(px(250.0))
                .bg(rgb(0x2a2a2a))
                .child("Sidebar")
        }
    }
    
    struct AppLayout {
        header: Entity<Header>,
        sidebar: Entity<Sidebar>,
    }
    
    impl Render for AppLayout {
        fn render(&mut self, _window: &mut Window, _cx: &mut Context<Self>) -> impl IntoElement {
            div()
                .size_full()
                .flex()
                .flex_col()
                .child(self.header.clone())
                .child(
                    div()
                        .flex()
                        .flex_1()
                        .child(self.sidebar.clone())
                        .child(
                            div()
                                .flex_1()
                                .child("Main content")
                        )
                )
        }
    }
    

    Element Patterns

    Clickable Card

    div()
        .p_4()
        .bg(rgb(0x1a1a1a))
        .rounded(px(8.0))
        .cursor_pointer()
        .hover(|style| style.bg(rgb(0x2a2a2a)))
        .on_click(|_event, _window, cx| {
            println!("Card clicked");
        })
        .child("Click me")
    

    Input Field

    struct InputField {
        value: SharedString,
    }
    
    impl Render for InputField {
        fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
            div()
                .px_3()
                .py_2()
                .bg(rgb(0x1a1a1a))
                .border_1()
                .border_color(rgb(0x4a4a4a))
                .rounded(px(4.0))
                .child(self.value.clone())
                .on_click(cx.listener(|this, _event, _window, cx| {
                    // Handle focus
                }))
        }
    }
    

    Toggle Switch

    struct Toggle {
        enabled: bool,
    }
    
    impl Render for Toggle {
        fn render(&mut self, _window: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
            div()
                .w(px(44.0))
                .h(px(24.0))
                .rounded(px(12.0))
                .bg(if self.enabled { 
                    rgb(0x22c55e) 
                } else { 
                    rgb(0x4a4a4a) 
                })
                .cursor_pointer()
                .on_click(cx.listener(|this, _event, _window, cx| {
                    this.enabled = !this.enabled;
                    cx.notify();
                }))
        }
    }
    

    Best Practices

    1. Use SharedString for text: Avoids unnecessary string copies
    2. Use .when() for conditions: More readable than if/else in render
    3. Extract reusable components: Create RenderOnce components for common patterns
    4. Keep render pure: Don't mutate state directly in render() method
    5. Use children() for lists: More efficient than multiple .child() calls
    6. Chain methods: Build elements with method chaining for clarity

    Common Mistakes

    Mistake Problem Solution
    Mutating state in render Race conditions Use event handlers to mutate
    Not using SharedString Extra allocations Use SharedString for text
    Deep nesting Hard to read Extract into components
    Missing IntoElement Compile error Ensure types implement IntoElement
    Forgetting .clone() Borrow errors Clone SharedString when using multiple times

    Summary

    • Use div() as the base element
    • Add children with .child() or .children()
    • Use .when() for conditional rendering
    • Create components with RenderOnce or Render
    • Use SharedString for efficient text handling
    • Compose with flexbox layout methods

    References

    • GPUI Elements Documentation
    • gpui-component Library
    Recommended Servers
    Excalidraw
    Excalidraw
    Browserbase
    Browserbase
    Browser tool
    Browser tool
    Repository
    cnwzhu/gpui-skills
    Files