3.6 KiB
3.6 KiB
AGENTS.md
Ely GPUI Component. A component library for GPUI, in light and dark.
Stack
- Rust 1.95, edition 2024. One crate:
ely-gpui-component. - gpui 0.2.2 from crates.io. Feature
runtime_shadersis on by default: machines without Xcode lack the Metal compiler. - Assets, embedded with
rust-embed: Lucide 1.48.0 icons (ISC), Inter 4.1 and JetBrains Mono 2.304 (OFL). - Gallery:
examples/gallery. Website:frontend/(Vite 8, pnpm), built after the components.
Commands
cargo run --example galleryopens the gallery.-- --page <slug>starts on a page.cargo run --example gallery -- --capture <dir>writes PNGs of every page, light and dark, top to bottom, then each page's scripted states. macOS only.cargo test --lib,cargo clippy --all-targets -- -D warnings,cargo fmt --check.rm -rf target/debug/incrementalafter each task item keeps the disk lean.scripts/icons.sh <lucide-name>...adds icons. Then add a line toIconNameinsrc/primitives/icon.rs.
Layout
src/<chapter>/: one folder per chapter ofgpui-components.md.src/theme: palettes, tokens,ActiveTheme.src/motion: durations, easings, spring.examples/gallery/pages/<chapter>.rs: one page per chapter, in PRD order.TASKS.mdandtasks/: progress. Every PRD entry has a line and a tag.
Rules
- Colors, control and icon sizes, text sizes, radii, shadows come from
cx.theme(). No rawpx()literals inside components. - Gaps and padding use gpui's rem scale helpers (
gap_2,px_3). That scale is the spacing system. - Borders use gpui's fixed-pixel helpers (
border_1is 1px). Hairlines do not scale. - One component, one home. Duplicates point to it.
- Fail fast. No silent fallbacks. Log state changes with
log. - Files stay at or under 500 lines. Comments are one short line, and rare.
motion::duration()honors reduced motion. Springs overshoot: use them inside animators, never as gpui easings, because gpui asserts eased values stay in0..=1.svg()paints only with its owntext_color.Iconalways sets one.- Buttons stay out of focus on click (
prevent_defaulton mouse down). Tab still reaches them. - The focus ring is a 1px focus-colored border (
FocusRing). gpui paints shadows under the element, so a shadow ring floods transparent elements. Focusable elements keep a 1px border, transparent at rest. ely_gpui_component::initbinds Tab and Shift-Tab toFocusNextandFocusPrev. Wrap the root inFocusScopeand focus its handle.- gpui's
Window::dispatch_eventreturns a private type, so the gallery scripts mouse input by postingNSEvents to its own queue. hover()needs an element id.- Set an explicit line height on any box that clips text. gpui's default leading is taller than a tight box, and the clip eats descenders.
img()keeps loading state only with an id. Content masks are rectangles, so rounded corners survive only when the image fills its box without cropping.
Decisions
- 2026-09-24: official gpui 0.2.2 over the
gpui-presnapshot. Older API, first-party publisher. - 2026-09-24: one crate. Revisit if an incremental check passes 90 seconds.
- 2026-09-24: gpui 0.2.2 has no accessibility tree and no tray, badge, or notification API. Those entries carry
blockedorprove. - 2026-09-24: the gallery photographs its own window with
CGWindowListCreateImage. No Screen Recording permission needed. - 2026-09-24: license MIT OR Apache-2.0.
- 2026-09-25: layouts persist as versioned JSON through serde. Unknown fields are ignored. Newer versions, unknown panels and bad pane trees are refused, and restore is all or nothing.