-
Notifications
You must be signed in to change notification settings - Fork 9
Design Logic
MeowLynxSea edited this page Jun 18, 2026
·
4 revisions
The big mental shifts in v0.3.
-
Component — a primitive or composite that produces a single element. Returns a
XxxPropsbuilder fromyororen-ui-core::headless::*. Stateless (pure data) or composite (owns anEntity<XxxState>). - Widget — orchestrates many elements: scrolling, virtualization, or wires multiple components together. Currently VirtualList is the only shipped widget.
gpui-ce tracks which entities a render closure reads. Mutating an entity + cx.notify() invalidates the window automatically.
Every UI primitive is split into two crates:
| You want | Use |
|---|---|
| Default rounded look |
headless::button::button(...).render(cx) after renderer::install(cx, ...)
|
| Brutalism look | Same call, after brutalism_renderer::install(cx)
|
| Full visual control | headless::button::button(...).apply(div().bg(...)) |
| Brand-new animation / look | Implement a custom XxxRenderer, register via cx.register_renderer_arc::<m::Button, dyn ButtonRenderer>(...)
|
factory(id, cx) → XxxProps
│
├── .apply(div) → Stateful<Div> (a11y only)
├── .render(cx) → Stateful<Div> (a11y + themed visual)
└── .render(cx, window) → AnyElement (text inputs only — IME handler)
-
Default look, fastest path:
.render(cx). The renderer paints bg / border / padding / radius / hover / active from the theme. -
Caller controls every visual:
.apply(div())...child("Save"). The headless layer only contributes the focus handle and click handler. -
Bespoke animation / brand identity: hand-roll a
gpui::Elementand callprops.apply(...)for the a11y side. TheMaterialRippleElementincrates/yororen-ui-demos/layers_demo/src/material_button.rsis the canonical example.
The factory always returns the same XxxProps — the choice is which terminal method you call.
use yororen_ui::headless::button::button;
// Path 1: default look, painted by the registered renderer.
let themed = button("save", cx).caption("Save").on_click(|_, _, _| { /* … */ }).render(cx);
// Path 2: caller-controlled visual; only a11y from the headless layer.
let custom = div()
.bg(gpui::red()).rounded(px(8.)).p_2()
.apply(button("danger", cx).on_click(|_, _, _| { /* … */ }))
.child("Delete");Same factory. Same state. Same a11y. Different pixels.
- 3-layer architecture — the canonical mental model.
- Layout rules — what the headless layer doesn't decide.
- Keyed state — stable ids and virtualization.
- Virtualization.
Yororen UI v0.3.0 · repository · Apache-2.0 · This wiki documents Yororen UI v0.3.0.
This wiki documents Yororen UI v0.3.0 — the headless-core, swappable-renderer build.