Delegate independent tasks to specialized agents working concurrently with isolated context.
Gpui Style Guide
gpui-style-guide
GPUI Component project style guide based on gpui-component code patterns. Use when writing new components, reviewing code, or ensuring consistency with existing gpui-component implementations. Covers component structure, trait implementations, naming conventions, and API patterns observed in the ...
SKILL.md
Full skill instructions
Overview
Code style guide derived from gpui-component implementation patterns.
Based on: Analysis of Button, Checkbox, Input, Select, and other components in crates/ui
Component Structure
Basic Component Pattern
use gpui::{
div, prelude::FluentBuilder as _, AnyElement, App, Div, ElementId,
InteractiveElement, IntoElement, ParentElement, RenderOnce,
StatefulInteractiveElement, StyleRefinement, Styled, Window,
};
#[derive(IntoElement)]
pub struct MyComponent {
id: ElementId,
base: Div,
style: StyleRefinement,
// Configuration fields
size: Size,
disabled: bool,
selected: bool,
// Content fields
label: Option<Text>,
children: Vec<AnyElement>,
// Callbacks (use Rc for Clone)
on_click: Option<Rc<dyn Fn(&ClickEvent, &mut Window, &mut App) + 'static>>,
}
impl MyComponent {
pub fn new(id: impl Into<ElementId>) -> Self {
Self {
id: id.into(),
base: div(),
style: StyleRefinement::default(),
size: Size::default(),
disabled: false,
selected: false,
label: None,
children: Vec::new(),
on_click: None,
}
}
// Builder methods
pub fn label(mut self, label: impl Into<Text>) -> Self {
self.label = Some(label.into());
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
}
}
impl InteractiveElement for MyComponent {
fn interactivity(&mut self) -> &mut gpui::Interactivity {
self.base.interactivity()
}
}
impl StatefulInteractiveElement for MyComponent {}
impl Styled for MyComponent {
fn style(&mut self) -> &mut StyleRefinement {
&mut self.style
}
}
impl RenderOnce for MyComponent {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
// Implementation
self.base
}
}
Stateful Component Pattern
#[derive(IntoElement)]
pub struct Select {
state: Entity<SelectState>,
style: StyleRefinement,
size: Size,
// ...
}
pub struct SelectState {
open: bool,
selected_index: Option<usize>,
// ...
}
impl Select {
pub fn new(state: &Entity<SelectState>) -> Self {
Self {
state: state.clone(),
size: Size::default(),
style: StyleRefinement::default(),
}
}
}
Trait Implementations
Sizable
impl Sizable for MyComponent {
fn with_size(mut self, size: impl Into<Size>) -> Self {
self.size = size.into();
self
}
}
Selectable
impl Selectable for MyComponent {
fn selected(mut self, selected: bool) -> Self {
self.selected = selected;
self
}
fn is_selected(&self) -> bool {
self.selected
}
}
Disableable
impl Disableable for MyComponent {
fn disabled(mut self, disabled: bool) -> Self {
self.disabled = disabled;
self
}
fn is_disabled(&self) -> bool {
self.disabled
}
}
Variant Patterns
Enum Variants
#[derive(Clone, Copy, PartialEq, Eq, Default, Debug)]
pub enum ButtonVariant {
Primary,
#[default]
Secondary,
Danger,
Success,
Warning,
Ghost,
Link,
}
Trait-Based Variant API
pub trait ButtonVariants: Sized {
fn with_variant(self, variant: ButtonVariant) -> Self;
/// With the primary style for the Button.
fn primary(self) -> Self {
self.with_variant(ButtonVariant::Primary)
}
/// With the danger style for the Button.
fn danger(self) -> Self {
self.with_variant(ButtonVariant::Danger)
}
// ... more variants
}
Custom Variant Pattern
#[derive(Clone, Copy, PartialEq, Eq, Debug)]
pub struct ButtonCustomVariant {
color: Hsla,
foreground: Hsla,
border: Hsla,
hover: Hsla,
active: Hsla,
shadow: bool,
}
impl ButtonCustomVariant {
pub fn new(cx: &App) -> Self {
Self {
color: cx.theme().transparent,
foreground: cx.theme().foreground,
// ...
shadow: false,
}
}
pub fn color(mut self, color: Hsla) -> Self {
self.color = color;
self
}
// ... more builder methods
}
Action and Keybinding Patterns
Context Constant
const CONTEXT: &str = "Select";
Init Function
pub(crate) fn init(cx: &mut App) {
cx.bind_keys([
KeyBinding::new("up", SelectUp, Some(CONTEXT)),
KeyBinding::new("down", SelectDown, Some(CONTEXT)),
KeyBinding::new("enter", Confirm { secondary: false }, Some(CONTEXT)),
KeyBinding::new("escape", Cancel, Some(CONTEXT)),
])
}
Action Usage
use crate::actions::{Cancel, Confirm, SelectDown, SelectUp};
div()
.key_context(CONTEXT)
.on_action(cx.listener(Self::on_action_select_up))
.on_action(cx.listener(Self::on_action_confirm))
Trait Definitions
Item Traits
pub trait SelectItem: Clone {
type Value: Clone;
fn title(&self) -> SharedString;
fn display_title(&self) -> Option<AnyElement> {
None
}
fn render(&self, _: &mut Window, _: &mut App) -> impl IntoElement {
self.title().into_element()
}
fn value(&self) -> &Self::Value;
fn matches(&self, query: &str) -> bool {
self.title().to_lowercase().contains(&query.to_lowercase())
}
}
Implement for Common Types
impl SelectItem for String {
type Value = Self;
fn title(&self) -> SharedString {
SharedString::from(self.to_string())
}
fn value(&self) -> &Self::Value {
&self
}
}
impl SelectItem for SharedString { /* ... */ }
impl SelectItem for &'static str { /* ... */ }
Icon Pattern
IconNamed Trait
pub trait IconNamed {
fn path(self) -> SharedString;
}
impl<T: IconNamed> From<T> for Icon {
fn from(value: T) -> Self {
Icon::build(value)
}
}
IconName Enum
#[derive(IntoElement, Clone)]
pub enum IconName {
ArrowDown,
ArrowUp,
Check,
Close,
// ... all icon names
}
Documentation Patterns
Component Documentation
/// A Checkbox element.
#[derive(IntoElement)]
pub struct Checkbox { }
Method Documentation
impl Checkbox {
/// Create a new Checkbox with the given id.
pub fn new(id: impl Into<ElementId>) -> Self { }
/// Set the label for the checkbox.
pub fn label(mut self, label: impl Into<Text>) -> Self { }
/// Set the click handler for the checkbox.
///
/// The `&bool` parameter indicates the new checked state after the click.
pub fn on_click(mut self, handler: impl Fn(&bool, &mut Window, &mut App) + 'static) -> Self { }
}
Import Organization Pattern
// 1. External crate imports
use std::rc::Rc;
// 2. Crate imports
use crate::{
ActiveTheme, Disableable, FocusableExt, Icon, IconName,
Selectable, Sizable, Size, StyledExt,
};
// 3. GPUI imports
use gpui::{
div, prelude::FluentBuilder as _, px, relative, rems,
AnyElement, App, Div, ElementId, InteractiveElement,
IntoElement, ParentElement, RenderOnce,
StatefulInteractiveElement, StyleRefinement, Styled, Window,
};
Field Organization
pub struct Component {
// 1. Identity
id: ElementId,
base: Div,
style: StyleRefinement,
// 2. Configuration
size: Size,
disabled: bool,
selected: bool,
tab_stop: bool,
tab_index: isize,
// 3. Content/children
label: Option<Text>,
children: Vec<AnyElement>,
prefix: Option<AnyElement>,
suffix: Option<AnyElement>,
// 4. Callbacks (last)
on_click: Option<Rc<dyn Fn(Args, &mut Window, &mut App) + 'static>>,
}
Common Patterns
Optional Elements
pub fn prefix(mut self, prefix: impl IntoElement) -> Self {
self.prefix = Some(prefix.into_any_element());
self
}
Callback Patterns
// Pattern 1: Event parameter first
pub fn on_click(mut self, handler: impl Fn(&ClickEvent, &mut Window, &mut App) + 'static) -> Self {
self.on_click = Some(Rc::new(handler));
self
}
// Pattern 2: State parameter
pub fn on_change(mut self, handler: impl Fn(&bool, &mut Window, &mut App) + 'static) -> Self {
self.on_change = Some(Rc::new(handler));
self
}
Static Handler Functions
fn handle_click(
on_click: &Option<Rc<dyn Fn(&bool, &mut Window, &mut App) + 'static>>,
checked: bool,
window: &mut Window,
cx: &mut App,
) {
let new_checked = !checked;
if let Some(f) = on_click {
(f)(&new_checked, window, cx);
}
}
Boolean Methods
// Enable/disable patterns
pub fn cleanable(mut self, cleanable: bool) -> Self {
self.cleanable = cleanable;
self
}
// Toggle methods (no parameter)
pub fn mask_toggle(mut self) -> Self {
self.mask_toggle = true;
self
}
Size Methods
Size Trait
impl Sizable for Component {
fn with_size(mut self, size: impl Into<Size>) -> Self {
self.size = size.into();
self
}
}
Convenience Size Methods (from StyleSized trait)
Components get .xsmall(), .small(), .medium(), .large() automatically via StyleSized trait.
Rendering Patterns
RenderOnce Pattern
impl RenderOnce for MyComponent {
fn render(self, window: &mut Window, cx: &mut App) -> impl IntoElement {
let (width, height) = self.size.input_size();
self.base
.id(self.id)
.flex()
.items_center()
.gap(px(8.))
.min_w(width)
.h(height)
.when(self.disabled, |this| {
this.opacity(0.5).cursor_not_allowed()
})
.children(self.children)
}
}
Theme Usage
// Access theme colors
cx.theme().surface
cx.theme().foreground
cx.theme().border
cx.theme().primary
cx.theme().transparent
// Use in components
div()
.bg(cx.theme().surface)
.text_color(cx.theme().foreground)
.border_color(cx.theme().border)
Reference Documentation
-
Component Examples: See component-examples.md
- Full component implementations
- Common patterns in action
-
Trait Patterns: See trait-patterns.md
- Detailed trait implementation guides
- Custom trait design patterns
Quick Checklist
When creating a new component in crates/ui:
-
#[derive(IntoElement)]on struct - Include
id: ElementId,base: Div,style: StyleRefinement - Implement
InteractiveElement,StatefulInteractiveElement,Styled - Implement
RenderOncetrait - Implement
Sizableif component has sizes - Implement
Selectableif component can be selected - Implement
Disableableif component can be disabled - Use
Rc<dyn Fn>for callbacks - Use
Option<AnyElement>for optional child elements - Import
prelude::FluentBuilder as _ - Use theme colors via
cx.theme() - Follow field organization pattern
More Other skills
brand-guidelines
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
theme-factory
Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.
internal-comms
A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).
Fundamental design principles for writing maintainable, testable Python code.
responsive-design
Modern responsive layouts using container queries, fluid typography, CSS Grid, and mobile-first strategies.
Generate Playwright tests from scenarios using interactive browser exploration and validation.
Automated website exploration and test case generation using Playwright.
Modern React state management with Redux Toolkit, Zustand, Jotai, and React Query for every state category.
gdpr-data-handling
GDPR-compliant data handling with consent management, data subject rights, and privacy controls.
Python error handling patterns including input validation, exception hierarchies, and partial failure handling. Use when implementing validation logic, designing exception strategies, handling batch processing failures, or building robust APIs.
refactor-plan
Detailed multi-file refactor planning with safety checks and rollback guidance.
