MCPcopy Index your code
hub / github.com/MeowLynxSea/yororen-ui

github.com/MeowLynxSea/yororen-ui @v0.3.0

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.3.0 ↗ · + Follow
3,232 symbols 7,847 edges 299 files 714 documented · 22% updated 18d agov0.3.0 · 2026-06-18★ 3331 open issues
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Yororen UI

中文版 · English

许可证 Rust 版本 基于 gpui 版本

Yororen UI 是一个 headless 优先的 Rust UI 库,基于 gpui(通过 gpui-ce)构建。按钮不是某种视觉样式,而是一个可聚焦、可点击、可带文本标签和图标的组件;外观由渲染器决定。

主题 JSON  ─▶  渲染器(XxxRenderer)──▶  headless(XxxProps)──▶  gpui-ce
  • Headlessyororen-ui-core)—— 数据、状态、a11y、i18n、RTL、动画、资源。不做任何视觉决策。
  • 渲染器yororen-ui-default-renderer · yororen-ui-brutalism-renderer)—— 负责将 props 转换为样式化的 div。55 个 trait 槽位分别由 Token*Brutal* 实现;更换渲染器,整套应用的视觉就会一并切换。
  • 主题 —— JSON 文件。渲染器按路径(如 action.primary.bg)读取;缺失的路径回退到渲染器的默认值。

聚合 crate yororen-ui 重新导出 core + 默认渲染器 + 三个内置 locale,大多数应用只需要这一个依赖。开启 brutalismxml feature 即可启用备选渲染器或 XML DSL。


特性

能力 说明
55 个组件 按钮、输入框、徽章、工具提示、模态框、浮层、选择器、列表、虚拟化列表、树、表格等
三层架构 headless 原语 + JSON 主题 + 可替换的可视化渲染器(默认 + brutalism)
JSON 主题 一次 install() 调用即可在运行时切换主题配色
动画系统 每个带状态的复合组件都内置 AnimatedVisibility,并附带预设动画与缓动函数
国际化 内置 enzh-CNar 三种 locale;ar 会根据 cx.i18n().text_direction() 自动切换为 RTL 布局
无障碍 焦点管理、键盘导航、点击外部关闭、滚动锁定计数、焦点陷阱
嵌入式资源 通过 rust-embed 内置 20+ 个 SVG 图标
通知系统 NotificationCenter 全局对象,支持自动关闭计时、常驻标志与持久化
可选的 XML DSL 通过 xml! / xml_file! 宏声明式构建界面

快速开始

use gpui::{App, Application, Bounds, WindowBounds, WindowOptions, px, size};
use yororen_ui::assets::UiAsset;
use yororen_ui::locale_en;
use yororen_ui::renderer;

fn main() {
    let app = Application::new().with_assets(UiAsset);

    app.run(|cx: &mut App| {
        // 1) 渲染器 + 主题 —— 根据系统外观选择 system-light 或 system-dark,
        //    安装全局 Theme,并注册 55 个默认渲染器实现。
        renderer::install(cx, cx.window_appearance());

        // 2) 初始化文本输入的键位映射(幂等)。
        yororen_ui::headless::text_input::init(cx);

        // 3) Locale。
        locale_en::install(cx);

        // 4) 主窗口。
        let options = WindowOptions {
            window_bounds: Some(WindowBounds::Windowed(
                Bounds::centered(None, size(px(800.), px(600.)), cx),
            )),
            ..Default::default()
        };
        cx.open_window(options, |_, cx| cx.new(|_| my_app::MyApp));
    });
}

Render::render 中:

use yororen_ui::headless::button::button;
use yororen_ui::headless::label::label;

fn render(&mut self, _w: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
    div().size_full().flex().items_center().justify_center().gap_2()
        .child(label("count", "0", cx).render(cx))
        .child(button("inc", cx).caption("+").render(cx))
}

每个 headless 工厂都同时提供 .apply(div).render(cx) 两种调用方式:前者仅注入无障碍属性,后者则通过已注册的渲染器渲染完整视觉。文本输入的 .render(cx, window) 为双参数调用,并会在 window 上注册 IME 处理器。

切换渲染器或主题(可选)

Brutalism 渲染器

use yororen_ui::brutalism_renderer;

brutalism_renderer::install(cx);   // 直角、硬阴影、等宽字体

自定义 JSON 主题

use yororen_ui_default_renderer::{Theme, install_with};

const MY_THEME: &str = include_str!("../themes/my-brand.json");
install_with(cx, Theme::from_json(MY_THEME).expect("valid JSON"));

运行时主题切换

Render 实现中调用 yororen_ui::theme::install(cx, new_theme)——可在每帧渲染时调用,也可在用户切换主题时调用。调用是幂等且廉价的。

impl Render for MyApp {
    fn render(&mut self, _w: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
        yororen_ui::theme::install(cx, self.current_theme());
        // … 渲染剩余部分 …
    }
}

示例应用

**`counter`** —— 最小启动模板:仅使用一个全局 Entity<T> 和三个按钮。 Counter 示例
cargo run -p counter-demo
**`gallery_demo`** —— 全面的组件参考示例:涵盖全部组件、主题切换、i18n、通知与虚拟化列表。 Gallery 示例
cargo run -p gallery-demo
**`inputs_demo`** —— 全套七个文本输入,采用 cx.entity().clone() 模式。处理 Tab / Enter / Esc / ⌘VInputs 示例
cargo run -p inputs-demo
**`layers_demo`** —— 三种渲染路径并排展示,外加手写的 Material 涟漪动画。 Layers 示例
cargo run -p layers-demo
**`theme_showcase`** —— 通过 theme::install 在每帧渲染时切换主题,循环展示四种主题。 Theme showcase 示例
cargo run -p theme-showcase-demo
**`variant_showcase`** —— ActionVariantKind 视觉对比(Neutral / Primary / Danger),使用同一个 headless::button 工厂。 Variant showcase 示例
cargo run -p variant-showcase-demo
**`gallery_xml`** —— 使用 XML DSL 重新实现的 gallery。 Gallery XML 示例
cargo run -p gallery-xml-demo
**`showcase_xml`** —— 小规模的 XML DSL 基础测试。 Showcase XML 示例
cargo run -p showcase-xml-demo

包含内容

Crate 角色
yororen-ui-core Headless 原语、主题 JSON 访问、i18n、a11y、RTL、动画、资源、通知中心
yororen-ui-default-renderer 55 个 TokenXxxRenderer 默认实现 + 内置 system-light.json / system-dark.json 主题 + renderer::install 引导函数
yororen-ui-brutalism-renderer (可选,feature brutalism 直角、粗黑边框、硬偏移阴影、等宽字体
yororen-ui-xml + yororen-ui-xml-macro (可选,feature xml,默认开启) XML DSL:xml!xml_file!register_xml_component!bind
yororen-ui-locale-{en, zh-CN, ar} 内置 JSON 翻译目录
yororen-ui (聚合 crate) 重新导出上述所有内容,大多数应用只需要这一个

三层架构

主题 JSON  ─▶  渲染器(XxxRenderer)──▶  headless(XxxProps)──▶  gpui-ce
  • Headless —— 数据 + 控制 + a11y。无视觉。
  • 渲染器 —— 每个组件一个 trait,读取主题并生成样式化 div。
  • 主题 —— 一个 serde_json::Value,可在运行时切换。

55 个组件标记(yororen-ui-core::renderer::markers)是全局 RendererRegistry 的键。默认渲染器和 brutalism 渲染器各实现全部 55 个 trait 槽位。

自定义渲染器只需要实现 55 个 XxxRenderer trait——完全不需要触碰 headless 层。


安装

从 crates.io 使用(推荐)

[dependencies]
yororen_ui = "0.3"

xml feature 默认开启,xml! / xml_file! 开箱即用。如需关闭:

[dependencies]
yororen_ui = { version = "0.3", default-features = false }

按需启用 feature:

[dependencies]
yororen_ui = { version = "0.3", default-features = false, features = ["xml", "brutalism"] }

从 GitHub 使用(最新开发版)

[dependencies]
yororen_ui = { git = "https://github.com/MeowLynxSea/yororen-ui.git", tag = "v0.3.0" }

从本地路径使用(开发时)

[dependencies]
yororen_ui = { path = "../yororen-ui" }

gpui 依赖

gpui 通过 crates.io 上的 gpui-ce crate 提供。请确保您的应用程序使用兼容的版本:

[dependencies]
gpui = { package = "gpui-ce", version = "0.3" }

在本仓库中,gpui-ce 已在 Cargo.toml 中指定。


环境要求

  • Rust edition: 2024
  • 平台: macOS、Linux、Windows(与 gpui-ce 支持的范围一致)

许可证

采用 Apache License, Version 2.0 授权。本项目基于 gpui(Zed Industries)构建,同样采用 Apache-2.0。归属详情请参见 LICENSENOTICE


贡献

欢迎提交 Issue 和 PR。修改视觉效果时:

  • 请附上截图或简短录屏
  • 代码请保持 rustfmt 格式

Wiki

参见 Yororen UI Wiki 获取详细指南、配方和组件参考。


Star History

Star History Chart


Yoro.ren 维护

Yororen — Maintained with care

Extension points exported contracts — how you extend this code

ListNavigable (Interface)
Shared keyboard-navigation algorithm for option-list states. `select`, `combo_box`, `menu`, and `listbox` all store a ` [6 …
crates/yororen-ui-core/src/headless/list_navigable.rs
RenderState (Interface)
Marker trait that every component's `XxxRenderState` implements. Used as the keying type in `RendererRegistry`'s intern [1 …
crates/yororen-ui-default-renderer/src/renderers/spec.rs
AnimatedPresenceState (Interface)
Trait for state entities that own an [`AnimatedVisibility`]. Implemented by the headless state structs (`ModalState`, ` [5 …
crates/yororen-ui-core/src/animation/visibility.rs
VariantStyle (Interface)
The visual contract for an action variant (button, icon-button, toggle-button, split-button, ...). Implementations are [3 …
crates/yororen-ui-core/src/renderer/variant.rs
TextInputActionHandler (Interface)
The state-machine contract that the text-input keymap wires to. `wire_input_keyboard` calls each method via the `action_ [2 …
crates/yororen-ui-core/src/headless/text_input.rs
TextInputPainterHost (Interface)
What the [`TextInputElement`] painter needs to read / write on the state. The painter is generic over `T: TextInputPaint [2 …
crates/yororen-ui-core/src/headless/text_input_element.rs

Core symbols most depended-on inside this repo

child
called by 553
crates/yororen-ui-core/src/headless/modal.rs
get_color
called by 484
crates/yororen-ui-core/src/theme/mod.rs
get_number
called by 340
crates/yororen-ui-core/src/theme/mod.rs
update
called by 250
crates/yororen-ui-core/src/animation/config.rs
t
called by 213
crates/yororen-ui-core/src/i18n/runtime.rs
render
called by 171
crates/yororen-ui-demos/gallery_demo/src/gallery_app.rs
push
called by 161
crates/yororen-ui-core/src/a11y/keyboard_nav.rs
len
called by 158
crates/yororen-ui-core/src/renderer/registry.rs

Shape

Method 1,789
Function 924
Class 388
Interface 77
Enum 54

Languages

Rust100%

Modules by API surface

crates/yororen-ui-xml/src/codegen/tests.rs121 symbols
crates/yororen-ui-demos/gallery_xml/src/controller.rs110 symbols
crates/yororen-ui-core/src/headless/text_input.rs99 symbols
crates/yororen-ui-core/src/headless/combo_box.rs71 symbols
crates/yororen-ui-core/src/animation/easing.rs69 symbols
crates/yororen-ui-brutalism-renderer/src/renderers/display.rs57 symbols
crates/yororen-ui-xml/src/bin/gen_schema.rs52 symbols
crates/yororen-ui-core/src/rtl.rs43 symbols
crates/yororen-ui-brutalism-renderer/src/renderers/controls.rs42 symbols
crates/yororen-ui-core/src/i18n/runtime.rs41 symbols
crates/yororen-ui-core/src/renderer/variant.rs39 symbols
crates/yororen-ui-core/src/notification/center.rs38 symbols

For agents

$ claude mcp add yororen-ui \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page