-
Notifications
You must be signed in to change notification settings - Fork 9
Guide Quick Start
Note: This page assumes Yororen UI v0.3, the headless-API rewrite. Every primitive is a headless factory that returns a props builder (
button,text_input,virtual_list,modal, …). The visual layer is chosen separately viarenderer::install(cx, …). The defaults work out of the box; the brutalism renderer is a one-line swap; and you can author your own by registering renderers against themarkers::*trait slots (see Guide-Theming).
This page walks through the 6-step bootstrap that every v0.3 app
converges on, then ends with a complete main.rs you can copy.
Icons ship as embedded SVG via UiAsset. Register once when
constructing Application:
use gpui::Application;
use yororen_ui::assets::UiAsset;
let app = Application::new().with_assets(UiAsset);If you ship your own icon set, implement AssetSource (or
compose multiple sources with CompositeAssetSource) and pass
that to with_assets instead.
One call. This loads system-light.json or system-dark.json
(chosen by cx.window_appearance()), installs the global
Theme, and registers the 54 default XxxRenderer impls
(one per headless component) against the core RendererRegistry.
use gpui::App;
use yororen_ui::renderer;
fn init_renderer(cx: &mut App) {
renderer::install(cx, cx.window_appearance());
}Swap to brutalism (sharp corners, hard shadows, monospace)
with yororen_ui::brutalism_renderer::install(cx). Pass your
own JSON theme with default_renderer::install_with(cx, my_theme). See Guide-Theming for both.
If your app uses any text input — text_input,
password_input, search_input, number_input,
file_path_input, text_area, keybinding_input, or
combo_box — call this once at boot, before opening any
window that contains a text input. It's idempotent
(via a OnceLock).
yororen_ui::headless::text_input::init(cx);The keymap binds Backspace, Delete, Enter, Escape, Left, Right,
Shift+Left, Shift+Right, Cmd-A/V/C/X, Home, End, and
Ctrl-Cmd-Space (character palette) to the "UITextInput"
context. Skip it if your app has its own global keymap that
conflicts — the inputs still render, you just lose the
default key bindings.
Three locales ship out of the box:
| Locale | Crate | Short form |
|---|---|---|
| English | yororen-ui-locale-en |
yororen_ui::locale_en::install(cx) |
| Simplified Chinese | yororen-ui-locale-zh-CN |
yororen_ui::locale_zh_cn::install(cx) |
| Arabic (RTL) | yororen-ui-locale-ar |
yororen_ui::locale_ar::install(cx) |
Use yororen_ui::locale::install_locale(cx, "en" \| "zh-CN" \| "ar")
if you'd rather drive it from a string.
For your app's own strings, layer them on top with
locale::install_with_translations(cx, "en", app_map) — see
codex-skills/yororen-ui-app-core §5.
Only set this if your app shows toasts:
use yororen_ui::notification::center::NotificationCenter;
cx.set_global(NotificationCenter::new());The center is a thin state machine — it owns the queue,
schedules auto-dismiss timers, and exposes items() for the
renderer to paint. Your app is still responsible for wiring
the toast host into the render tree (see
Guide-Notification).
Yororen UI apps use gpui::Entity<T> for state. Wrap it in a
Global so any render closure can read it via
cx.global::<AppState>():
use gpui::{App, AppContext, Entity, Global};
#[derive(Default)]
pub struct Counter { pub value: i32 }
pub struct AppState { pub counter: Entity<Counter> }
impl AppState {
pub fn new(cx: &mut App) -> Self {
Self { counter: cx.new(|_| Counter::default()) }
}
}
impl Global for AppState {}Then cx.set_global(AppState::new(cx)). Skip this step if your
app is small enough to read everything off the root
Entity<MyApp>.
use gpui::{App, AppContext, Application, WindowBounds, WindowOptions, size, px};
let options = WindowOptions {
window_bounds: Some(WindowBounds::Windowed(
gpui::Bounds::centered(None, size(px(800.0), px(600.0)), cx)
)),
..Default::default()
};
let _ = cx.open_window(options, |_, cx| cx.new(|_cx| my_app::MyApp));The third argument to cx.new is the root
Entity<MyApp> — MyApp: Render is the type whose
Render::render paints the window. cx.entity() (called from
inside its render closure) gives you the Entity<MyApp> you
can clone into every move closure.
A complete, copy-pasteable bootstrap — wired exactly the way
crates/yororen-ui-demos/counter/ does it:
use gpui::{App, AppContext, Application, WindowBounds, WindowOptions, size, px};
use yororen_ui::assets::UiAsset;
use yororen_ui::locale_en;
use yororen_ui::notification::center::NotificationCenter;
use yororen_ui::renderer;
mod my_app;
mod state;
fn main() {
let app = Application::new().with_assets(UiAsset);
app.run(|cx: &mut App| {
// 1) Renderer + theme (54 default XxxRenderer impls — see
// crates/yororen-ui-core/src/renderer/markers.rs for the
// canonical list).
renderer::install(cx, cx.window_appearance());
// 2) Text-input keymap (idempotent — safe to call twice).
yororen_ui::headless::text_input::init(cx);
// 3) Locale.
locale_en::install(cx);
// 4) Notification center (only if your app uses toasts).
cx.set_global(NotificationCenter::new());
// 5) App global state (skip if not needed).
cx.set_global(state::AppState::new(cx));
// 6) Main window.
let options = WindowOptions {
window_bounds: Some(WindowBounds::Windowed(
gpui::Bounds::centered(None, size(px(800.0), px(600.0)), cx)
)),
..Default::default()
};
let _ = cx.open_window(options, |_, cx| {
cx.new(|_cx| my_app::MyApp)
});
});
}The corresponding minimal state.rs and my_app.rs are in the
counter demo (crates/yororen-ui-demos/counter/). Use it as
your template.
After wiring, run through this list before moving on:
-
cargo checkis clean - The window opens at the expected size
- A simple
headless::buttonwith.render(cx)shows up with the default colors (proves renderer + theme are wired) -
cx.theme().get_color("surface.base")returnsSome(_)(proves the theme is loaded) -
cx.t("common.save")returns the expected string (proves i18n is loaded) - If using text inputs,
init(cx)was called and the first keystroke inserts text (proves the keymap is bound)
If any of these fail, the issue is almost always out-of-order
init — themed component rendered before install ran, or
cx.set_global called after the first Render.
-
Demos — complete working examples in
crates/yororen-ui-demos/ - Guide-Theming — JSON-backed theme authoring, custom renderers
- Guide-Composing-UI — common screen patterns
- Guide-Recommended-Practices — the 6–10 rules every app converges on
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.