
Gpui Component
Build new GPUI controls in Rust with the same structure, traits, and checklist Longbridge uses for Button, Input, and Select-style components.
Install
npx skills add https://github.com/longbridge/gpui-component --skill gpui-componentWhat is this skill?
- Documents standard stateless GPUI component anatomy (identity, config, content, callbacks)
- Requires and optional traits: Sizable, Disableable, StyledExt, FluentBuilder conditionals
- Variants pattern and callback signatures aligned with crates/ui components
- Checklist for new components including theme colors and user style overrides
- Import organization and doc-comment conventions for RenderOnce GPUI elements
Adoption & trust: 1 installs on skills.sh; 11.6k GitHub stars; trending (+100% hot-view momentum).
Recommended Skills
Rust Async Patternswshobson/agents
Rust Best Practicesapollographql/skills
Memory Safety Patternswshobson/agents
Tauri V2nodnarbnitram/claude-code-extensions
Rust Testingaffaan-m/everything-claude-code
Rust Patternsaffaan-m/everything-claude-code
Journey fit
Primary fit
The skill is a component authoring style guide for active product UI work, which maps to the Build phase when you are implementing desktop UI in GPUI. It defines layout, traits, variants, callbacks, and theme sizing for visual elements—classic frontend component engineering, not infra or APIs.
SKILL.md
READMESKILL.md - Gpui Component
# GPUI Component Code Style Guide Based on analysis of `Button`, `Checkbox`, `Input`, `Select`, and other components in `crates/ui/src`. **Contents:** [Component Structure](#component-structure) · [Required Traits](#required-trait-implementations) · [Optional Traits](#optional-traits) · [Variants Pattern](#variants-pattern) · [Callback Signatures](#callback-signatures) · [Import Organization](#import-organization) · [Doc Comments](#doc-comments) · [Applying User Style Overrides](#applying-user-style-overrides) · [FluentBuilder Conditionals](#fluentbuilder-for-conditionals) · [Theme Colors](#theme-colors) · [Size Handling](#size-handling) · [Checklist](#checklist-for-new-components) ## Component Structure ### Standard Stateless Component ```rust use std::rc::Rc; use crate::{ActiveTheme, Disableable, Sizable, Size, StyledExt as _, /* ... */}; use gpui::{ AnyElement, App, Div, ElementId, InteractiveElement, IntoElement, ParentElement, RenderOnce, SharedString, StatefulInteractiveElement, StyleRefinement, Styled, Window, div, prelude::FluentBuilder as _, }; /// A MyComponent element. #[derive(IntoElement)] pub struct MyComponent { // 1. Identity id: ElementId, base: Div, style: StyleRefinement, // 2. Configuration size: Size, disabled: bool, selected: bool, tab_stop: bool, tab_index: isize, // 3. Content label: Option<SharedString>, children: Vec<AnyElement>, // 4. Callbacks (last) on_click: Option<Rc<dyn Fn(&bool, &mut Window, &mut App) + 'static>>, } impl MyComponent { /// Create a new MyComponent with the given id. pub fn new(id: impl Into<ElementId>) -> Self { Self { id: id.into(), base: div(), style: StyleRefinement::default(), size: Size::default(), disabled: false, selected: false, tab_stop: true, tab_index: 0, label: None, children: Vec::new(), on_click: None, } } /// Set the label. pub fn label(mut self, label: impl Into<SharedString>) -> Self { self.label = Some(label.into()); self } /// Set the click handler. pub fn on_click(mut self, handler: impl Fn(&bool, &mut Window, &mut App) + 'static) -> Self { self.on_click = Some(Rc::new(handler)); self } } ``` ### Stateful Component (Interactive, Needs `.id()`) Components with mouse interactions (hover, click tracking) use `Stateful<Div>`: ```rust use gpui::{Stateful, StatefulInteractiveElement as _, /* ... */}; #[derive(IntoElement)] pub struct Button { id: ElementId, base: Stateful<Div>, // Not Div — needs stateful for interaction tracking // ... } impl Button { pub fn new(id: impl Into<ElementId>) -> Self { let id = id.into(); Self { id: id.clone(), base: div().flex_shrink_0().id(id), // .id() makes it Stateful<Div> // ... } } } impl InteractiveElement for Button { fn interactivity(&mut self) -> &mut Interactivity { self.base.interactivity() } } ``` --- ## Required Trait Implementations ```rust // All components that accept children impl ParentElement for MyComponent { fn extend(&mut self, elements: impl IntoIterator<Item = AnyElement>) { self.children.extend(elements) } } // All components with styleable outer div impl Styled for MyComponent { fn style(&mut self) -> &mut StyleRefinement { &mut self.style } } // For interactive components (mouse events, hover, click) impl InteractiveElement for MyComponent { fn interactivity(&mut self) -> &mut Interactivity { self.base.interactivity() } } // Required if InteractiveElement is implemented impl StatefulInteractiveElement for MyComponent {} // Rendering impl RenderOnce for MyComponent { fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement { self.b