{"id":51677025,"url":"https://github.com/wess/guise","last_synced_at":"2026-07-24T23:30:37.717Z","repository":{"id":367377161,"uuid":"1279241361","full_name":"wess/guise","owner":"wess","description":"Mantine inspired components for Zed's GPUI library.","archived":false,"fork":false,"pushed_at":"2026-07-17T14:58:35.000Z","size":1488,"stargazers_count":67,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-07-17T16:27:18.193Z","etag":null,"topics":["component-library","cross-platform","design-system","gpui","gui","mantine","rust","theming","ui","ui-components","ui-framework","ui-kit","zed"],"latest_commit_sha":null,"homepage":"https://wess.io/guise","language":"Rust","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wess.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-24T13:57:49.000Z","updated_at":"2026-07-17T14:58:42.000Z","dependencies_parsed_at":null,"dependency_job_id":"f7165c8e-7110-4faf-bed6-1a44d827b5f2","html_url":"https://github.com/wess/guise","commit_stats":null,"previous_names":["wess/guise"],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/wess/guise","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wess%2Fguise","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wess%2Fguise/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wess%2Fguise/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wess%2Fguise/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wess","download_url":"https://codeload.github.com/wess/guise/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wess%2Fguise/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35860101,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-07-20T02:08:10.276Z","status":"online","status_checked_at":"2026-07-24T02:00:07.870Z","response_time":62,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component-library","cross-platform","design-system","gpui","gui","mantine","rust","theming","ui","ui-components","ui-framework","ui-kit","zed"],"created_at":"2026-07-15T08:00:24.753Z","updated_at":"2026-07-24T23:30:37.711Z","avatar_url":"https://github.com/wess.png","language":"Rust","funding_links":["https://github.com/sponsors/wess"],"categories":["Libraries"],"sub_categories":["Demos \u0026 Examples"],"readme":"# guise\n\n[![crates.io](https://img.shields.io/crates/v/guise-ui.svg)](https://crates.io/crates/guise-ui)\n[![docs.rs](https://img.shields.io/docsrs/guise-ui)](https://docs.rs/guise-ui)\n[![CI](https://github.com/wess/guise/actions/workflows/ci.yml/badge.svg)](https://github.com/wess/guise/actions/workflows/ci.yml)\n[![license](https://img.shields.io/crates/l/guise-ui.svg)](https://github.com/wess/guise/blob/main/LICENSE)\n\nA [Mantine](https://mantine.dev)-inspired component library for\n[gpui](https://github.com/zed-industries/zed) — the GPU-accelerated Rust UI\nframework that powers Zed.\n\n`guise` brings Mantine's ergonomics to gpui: a themed palette, sizing tokens,\n120+ composable components, a reactive state layer with two-way bindings, and\nthe full [Lucide](https://lucide.dev) icon set embedded as the default icons —\nno asset pipeline needed.\n\n```rust\nuse guise::prelude::*;\n\nStack::new()\n    .gap(Size::Md)\n    .child(Title::new(\"Welcome\").order(1))\n    .child(\n        Button::new(\"save\", \"Save changes\")\n            .variant(Variant::Filled)\n            .color(ColorName::Blue)\n            .on_click(|_, window, cx| { /* ... */ }),\n    )\n```\n\n## Documentation\n\nFull docs live in [`docs/`](docs/readme.md) (also rendered at\n[wess.github.io/guise](https://wess.github.io/guise/docs.html)):\n\n- **[Tutorial](docs/tutorial.md)** — build a complete app step by step ([web version](https://wess.github.io/guise/tutorial.html))\n- **[App walkthrough](docs/appguide.md)** — a project tracker wired the way a real guise app fits together\n- [Getting started](docs/gettingstarted.md) · [Theming](docs/theming.md) · [Component model](docs/components.md)\n- Components: [Buttons](docs/buttons.md) · [Icons](docs/icons.md) · [Inputs](docs/inputs.md) · [Dates \u0026 times](docs/dates.md) · [File handling](docs/files.md) · [Typography](docs/typography.md) · [Layout](docs/layout.md) · [Panels](docs/panels.md) · [Feedback](docs/feedback.md) · [Data](docs/data.md) · [Charts](docs/charts.md) · [Editor](docs/editor.md) · [Markdown editor](docs/markdowneditor.md) · [Overlays](docs/overlays.md) · [Navigation](docs/navigation.md)\n- Systems: [Flex layout](docs/flex.md) · [Macros](docs/macros.md) · [Transitions \u0026 animation](docs/transitions.md) · [Drag \u0026 drop](docs/dnd.md) · [Reactive state](docs/reactive.md) · [Window menu](docs/windowmenu.md) · [Architecture](docs/architecture.md)\n\n## Workspace\n\n- **`crates/guise`** — the component library.\n- **`crates/gallery`** — a live showcase of every component (the Mantine-docs\n  equivalent). Run it with `cargo run -p gallery`.\n\n## How guise compares\n\nTwo other component libraries target gpui:\n[gpui-component](https://github.com/longbridge/gpui-component) (shadcn-flavored,\nbacks Longbridge Pro) and\n[adabraka-ui](https://github.com/Augani/adabraka-ui). A quick orientation, as\nof July 2026:\n\n|  | **guise** | **gpui-component** | **adabraka-ui** |\n| --- | --- | --- | --- |\n| Design language | Mantine | shadcn/ui | shadcn/ui |\n| Components | 120+ | 60+ | ~140 |\n| Reactive layer | `Signal` / `Binding` / lenses, reactive `Form` | — (entities + subscriptions) | — |\n| Icons | all 1,991 Lucide glyphs as an embedded font, zero setup | 99 Lucide SVGs via an assets crate | ~1,600 SVGs, copied into your app manually |\n| Theming | Mantine palette, JSON theme files, 6 presets, per-slot overrides | ~140 tokens, JSON themes with hot reload, 22 presets | 19 presets, theme behind a global `Mutex` |\n| Code editor | 10-language highlighter + diagnostics API | tree-sitter (~35 languages) + LSP client | tree-sitter (22 languages) |\n| Docking / panels | `PaneGroup` splits-with-tabs + layout persistence | `DockArea` + floating `Tiles` + serialization | resizable/split panels |\n| Charts | 6 types with axes, legends, hover | 6 types incl. candlestick \u0026 Sankey on a plot framework | 11 types |\n| Motion | easing curves, spring physics, exit animations | basic easing | large effects library |\n| Drag \u0026 drop | typed payloads, sortable lists | panel docking | draggable + sortable |\n| Date/time pickers | yes | yes (incl. range presets) | yes |\n| Tests | 300+ incl. gpui entity harness | ~580 incl. render tests | minimal |\n| gpui dependency | crates.io releases | crates.io releases; dev tracks zed main | a custom gpui fork |\n| License | MIT | Apache-2.0 | MIT |\n\nReach for **guise** if you want Mantine's ergonomics, SwiftUI-style two-way\nbindings, and icons that just work with zero asset setup. **gpui-component**\nis the bigger ecosystem — a production code editor with LSP, a full dock\nsystem, and a WASM story. **adabraka-ui** ships the largest effects/animation\ncollection.\n\n## Theme\n\nInstall a theme once at startup; every component reads it from the gpui global:\n\n```rust\nguise::Theme::dark().init(cx);       // or Theme::light()\nguise::Theme::catppuccin().init(cx); // or nord / tokyonight / gruvbox / dracula / solarized_light\n```\n\nThe theme carries the full Mantine / open-color palette (14 colors × 10 shades),\n`xs..xl` scales for spacing, radius and font size, and scheme-aware semantic\ncolors (`body`, `surface`, `text`, `dimmed`, `border`, plus `success` /\n`warning` / `danger` / `info` feedback accents). Themes also load from flat\nJSON files — `Theme::from_json(source)` — with no serde dependency.\n\n### CSS-style colors\n\nWrite colors the CSS way — hex, `rgb`/`rgba`, `hsl`/`hsla`, or named — with the\n`color!` macro (compile-time) or `css(..)` (runtime strings). Both produce a\ngpui `Hsla`, usable in `.bg(..)`/`.text_color(..)`, in any component `.color(..)`,\nand in the theme `with_*` overrides:\n\n```rust\nButton::new(\"go\", \"Go\").color(color!(rgba(112, 72, 232, 1)))\nBadge::new(\"New\").color(color!(\"#e64980\"))\n\nTheme::dark()\n    .with_primary(color!(\"#7048e8\"))\n    .with_body(color!(rgb(11, 11, 15)))\n    .with_text(color!(\"hsl(220, 15%, 92%)\"))\n    .init(cx);                                   // restyles the whole UI\n```\n\n`color!` takes `rgb(..)`/`rgba(..)`/`hsl(..)`/`hsla(..)`/named tokens or a CSS\nstring (hex must be a string — `#228be6` isn't a Rust token). Component\n`.color(..)` accepts a palette `ColorName` *or* an explicit color (the\n`ColorValue` type) and derives variant shades from a single custom color. See\n[Theming](docs/theming.md).\n\n## Components\n\n| Group   | Components                                              |\n| ------- | ------------------------------------------------------- |\n| Layout  | `Stack`, `Group`, `Center`, `SimpleGrid`, `ScrollArea`, `AppShell`, `Container`, `Space`, `Panel`, `SplitPanel`, `Breakpoint`/`Responsive` |\n| Surface | `Paper`, `Card`                                         |\n| Typography | `Text`, `Title`, `Mark`, `Blockquote`, `Spoiler`    |\n| Inputs  | `Button`, `TextInput`, `TextArea`, `NumberInput`, `PasswordInput`, `PinInput`, `Checkbox`, `Switch`, `Radio`, `RadioGroup`, `CheckboxGroup`, `Select`, `Combobox`, `Autocomplete`, `Slider`, `RangeSlider`, `Rating`, `ColorInput`, `TagsInput`, `Transfer`, `Field` |\n| Dates \u0026 files | `Calendar`, `DatePicker`, `TimePicker`, `FileInput`, `Dropzone` (with pure `Date`/`Time` models) |\n| Editor  | `Editor` (highlighting for Rust, SQL, JSON, TOML, Python, JS/TS, Go, C, Markdown; LSP-shaped diagnostics), `MarkdownEditor` (Obsidian-style live preview) |\n| Overlays | `Modal`, `Drawer`, `Menu`, `MenuBar`, `ContextMenu`, `HoverCard`, `LoadingOverlay`, `ConfirmModal`, `Popover`, `Spotlight`, `Tooltip`, `Tour`, `OverlayHost` (window-level modal stack + toasts) |\n| Feedback | `Alert`, `Loader`, `Progress`, `RingProgress`, `Notification`, `ToastStack` |\n| Data    | `Badge`, `Divider`, `Avatar`, `AvatarGroup`, `List`, `VirtualList`, `Table`, `TableView`, `DataView`, `TreeView`, `TabBar`, `Image`, `Timeline`, `Tabs`, `Accordion`, `Carousel` |\n| Charts  | `Sparkline`, `LineChart`, `AreaChart`, `BarChart`, `ScatterChart`, `PieChart` — with optional axes, legends, and hover readouts |\n| Navigation | `Breadcrumbs`, `NavLink`, `NavigationMenu`, `Stepper`, `Pagination`, `StatusBar` |\n| Drag \u0026 drop | `Draggable`, `DropTarget`, `SortableList` — typed payloads |\n| Motion  | `Transition`, `Collapse` (true height animation), `Presence` (exit animations), `Easing` curves + `Spring` physics |\n| Polish  | `Icon` (all of [Lucide](https://lucide.dev) embedded), `ActionIcon`, `ThemeIcon`, `CloseButton`, `CopyButton`, `Anchor`, `Code`, `Kbd`, `Chip`, `Indicator`, `Skeleton`, `SegmentedControl` |\n\nInputs come in two flavors that match how each control behaves in gpui:\n\n- **Controlled** (`Checkbox`, `Switch`, `Radio`, `Rating`, and the `RadioGroup` /\n  `CheckboxGroup` wrappers) are `RenderOnce` builders — the parent view owns the\n  value and passes a change handler via `cx.listener(...)`.\n- **Stateful** (`TextInput`, `TextArea`, `NumberInput`, `PasswordInput`,\n  `PinInput`, `Select`, `Combobox`, `Autocomplete`, `Slider`, `RangeSlider`,\n  `ColorInput`, `TagsInput`, `DatePicker`, `TimePicker`, `FileInput`,\n  `Transfer`) are gpui entities that own their buffer / selection. Create with\n  `cx.new(...)` and subscribe to their events. `Field` is the shared\n  label/description/error chrome these compose.\n\nOverlays paint above the page (a `deferred` layer): `Modal` and `Drawer` are\ncontrolled backdrops, `ConfirmModal` a confirm/cancel dialog, `Menu` a\nkeyboard-navigable action list, `MenuBar` a themed in-window application menu,\n`ContextMenu` opens at the pointer, `Popover` is the anchored-floating\nprimitive, `HoverCard` its hover-triggered sibling, `Spotlight` a command\npalette, `Tour` a step-by-step onboarding walkthrough, and **`OverlayHost`**\nowns a window-level modal stack and toast queue — open dialogs from any\nhandler, focus restores on close.\n\nData display scales from stateless builders (`Avatar`, `List`, `Table`,\n`Timeline`) to virtualized, signal-bound entities: `TableView\u003cT\u003e` (typed rows,\nsorting, selection, virtualized body), `DataView\u003cT\u003e` (list/grid over a\n`Signal\u003cVec\u003cT\u003e\u003e` with filter/sort projections and windowed rendering),\n`TreeView` (expandable hierarchy, virtualizable), and `VirtualList` (100k rows\nrender as cheaply as 20). `PaneGroup` is the Zed-style splits-with-tabs\nworkspace, including drag-to-split and layout snapshots that persist across\nsessions.\n\n## Flex layout (`guise::flex`)\n\nA Flutter-flavored layout kit on top of gpui's flexbox: `Row`, `Column`,\n`Container`, `Padding`, `Align`, `Center`, `Expanded`/`Flexible` (real flex\nweights), `Spacer`, `SizedBox`, `Stack`/`Positioned`, and `Wrap`, with\n`MainAxisAlignment` / `CrossAxisAlignment` / `EdgeInsets`. It is **not**\nglob-exported (names overlap with `guise::layout`); import it as\n`use guise::flex::*`.\n\n## Layout macros\n\nTerse builders, available from the prelude:\n\n```rust\ncol![\n    row![avatar, name, Spacer::new(), actions],   // guise::flex::Row\n    divider,\n    body,\n]\n```\n\n`row!`/`col!`/`zstack!`/`wrap!` build `flex` containers; `vstack!`/`hstack!`\nbuild the themed `layout::Stack`/`Group`. There's also a CSS-like `style!`\nblock for inline styling — see\n[Macros](docs/macros.md#style--css-like-style-blocks).\n\n## Reactive state (`guise::reactive`)\n\nA small React-flavored layer over gpui's reactivity:\n\n```rust\nlet count = use_state(cx, 0i32);      // Signal\u003ci32\u003e\nprovide(cx, count.clone());           // Context.Provider, keyed by type\nwatch(cx, \u0026count);                    // re-render this view on change\ncount.update(cx, |n| *n += 1);        // notifies every watcher\n```\n\n**Bindings** are SwiftUI-style two-way connections: controlled builders take\n`.bind(signal.binding())`, stateful entities bind with\n`X::bind(\u0026entity, \u0026signal, cx)` — the value flows both directions with no\nhand-written change handlers. `signal.lens(get, set)` projects one struct\nfield; `binding.map(from, into)` converts types both ways.\n\n**Forms**: every `Form` field is its own `Signal\u003cString\u003e`, so inputs bind\nstraight to fields; rules (including cross-field like `equals_field`) run on\nsubmit and errored fields re-validate live as they're edited:\n\n```rust\nlet form = Form::new(cx)\n    .field(cx, \"email\", \"\")\n    .rule(\"email\", validators::email());\nTextInput::bind(\u0026email_input, \u0026form.signal(\"email\"), cx);\nif let Some(values) = form.submit(cx) { /* … */ }\n```\n\nSee [Reactive state](docs/reactive.md).\n\n## Motion\n\nEasing curves (including a CSS `cubic-bezier` solver), closed-form `Spring`\nphysics, `Transition` entrances, a `Collapse` that animates real height both\ndirections, and `Presence` for exit animations on conditionals:\n\n```rust\nCollapse::new(\"details\")\n    .open(self.expanded)\n    .height(120.0)\n    .easing(Easing::Spring(Spring::default()))\n    .child(detail_panel())\n```\n\nSee [Transitions \u0026 animation](docs/transitions.md).\n\n## Variants\n\nColored components share Mantine's variant system: `Filled`, `Light`,\n`Outline`, `Subtle`, `Default`, `Transparent`, `White`.\n\n## Installation\n\n`guise` builds against **crates.io gpui 0.2.2** — no git pins, no patch\nsections:\n\n```toml\n[dependencies]\nguise-ui = \"0.10\"\ngpui = \"0.2.2\"\n```\n\n\u003e The crate is named **`guise-ui`** (the `guise` name was taken on crates.io),\n\u003e but its library is named `guise` — so you still write\n\u003e `use guise::prelude::*;`.\n\nPinning via git works too:\n\n```toml\nguise-ui = { git = \"https://github.com/wess/guise\", tag = \"v0.10.0\" }\n```\n\n## Building\n\nRequires Rust stable.\n\n```sh\ncargo run -p gallery     # launch the component gallery\ncargo test -p guise-ui   # run the library's tests (unit + gpui entity harness)\n```\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n♥ [Sponsor this project](https://github.com/sponsors/wess)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwess%2Fguise","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwess%2Fguise","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwess%2Fguise/lists"}