tawasuyu

tawasuyu/brahman

Rust 492TOML 194Markdown 53JSON 176939 Definiciones

feat(yahweh-widget-meta-form): paleta del chrome migrada a Theme::global(cx)

Iter 5 de integración. MetaApp::render tenía 7 vars con colors
hardcoded (bg/panel/border/text/text_dim/accent/accent_active);
ahora salen de Theme::global(cx) que el shell instala al boot.
confirm_delete_banner usa themed_colors(Warning/Error) para sus
colors base.

render:
- 7 let X = rgb(0x...) → theme.bg_app/bg_panel/border/fg_text/
  fg_muted/accent/accent_strong.
- toast_div / error_banner: banner() → banner_themed(cx).

Firmas internas:
- render_sidebar/main/list/entity_ref_selector/form cambian
  Rgba → Hsla (Background donde aplica para panel). gpui::Div
  acepta ambos via Into, uso interno no cambia.

confirm_delete_banner:
- 6 colors hardcoded → themed_colors(Warning) para banner base,
  themed_colors(Error) para Confirm, theme.bg_panel_alt+fg_text
  para Cancel.

NO migra esta iter (ornament hardcoded para una pasada futura):
row hovers, bordes sutiles entre filas, bg de inputs custom,
bg de botones del EntityRef selector, color del icon ✕ de delete.

Smoke test del binario verificado: bootstrap completo OK, panic
esperado en open_window sin display. 115 tests verdes (sin
cambio: los tests del widget no acceden al render).

Beneficio: theme switcher (cuando llegue) cambia toda la paleta
con 1 sola llamada Theme::set(cx, ...).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

58854576280421e6660104946117f5fea9d5c7b5 · por Sergio · (hace 5 meses) · padre 9632d8c4a · ver el árbol en este commit

Delta semántico · 7

crates/modules/ui_engine/widgets/meta-form/src/lib.rs

2 archivos · +118 −39

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 2fc90ff..c91679a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -6,6 +6,72 @@ ratio/diff ver `git show <sha>`.
 
 ## 2026-05-10
 
+### feat(yahweh-widget-meta-form): paleta del chrome migrada a `Theme::global(cx)`
+Iter 5 de integración. El `MetaApp::render` tenía 7 vars locales
+con colors hardcoded (`bg/panel/border/text/text_dim/accent/
+accent_active`) que se pasaban a las funciones internas
+(`render_sidebar`/`render_main`/`render_list`/`render_form`/
+`render_entity_ref_selector`). Ahora salen del `Theme::global(cx)`
+que el binario shell instala al boot. El `confirm_delete_banner`
+también usa `themed_colors(Banner::Warning)` / `themed_colors(Banner::Error)`
+para sus colors base.
+
+Cambios en `MetaApp::render`:
+- 7 `let X = gpui::rgb(0x...)` → derive del theme:
+  - `bg` ← `theme.bg_app` (Background, soporta gradientes).
+  - `panel` ← `theme.bg_panel`.
+  - `border` ← `theme.border` (Hsla).
+  - `text` ← `theme.fg_text`.
+  - `text_dim` ← `theme.fg_muted`.
+  - `accent` ← `theme.accent`.
+  - `accent_active` ← `theme.accent_strong`.
+- `toast_div` y `error_banner`: `banner(...)` → `banner_themed(cx, ...)`.
+
+Cambios de firma (internas, no API público):
+- `render_sidebar` / `render_main` / `render_list` /
+  `render_entity_ref_selector` / `render_form` cambian Rgba →
+  Hsla en sus parámetros de color (Background donde aplica para
+  `panel`). Los métodos `bg/text_color/border_color` de gpui::Div
+  aceptan ambos via `Into`, así que el uso interno no cambia.
+
+Cambios en `render_confirm_delete_banner`:
+- 6 colors hardcoded amber/red/gray → `themed_colors(Warning)` para
+  banner base, `themed_colors(Error)` para botón Confirm,
+  `theme.bg_panel_alt + fg_text` para botón Cancel.
+- Cambiar de Theme ahora cambia toda la paleta del modal.
+
+Lo que **NO** migra esta iter (queda como ornament hardcoded; iter
+futura si emerge la necesidad):
+- Row hovers misceláneos en `render_list` (px 0x232a36 / 0x1f2630
+  para selected/hover de filas).
+- Borders sutiles entre filas (px 0x232a36).
+- Bg de inputs custom (px 0x171a20).
+- Bg de botones en `render_entity_ref_selector` (px 0x2c3540).
+- Color rojo del icon `✕` de delete (px 0xd07070) y su hover
+  (px 0x4a2020).
+
+Estos son detalles ornamentales que un theme switcher real
+querría integrar; los aislo para una pasada futura cuando esté
+claro qué slots semánticos del theme conviene agregar (ej.
+`bg_row_selected` distinto de `bg_row_hover`, `accent_destructive`,
+etc.).
+
+`nakui-ui` shell ya instalaba `Theme::install_default(cx)` desde la
+iter pasada — sigue siendo el contract entre el shell y el widget.
+Smoke test del binario verificado: bootstrap completo OK, panic
+esperado en open_window sin display.
+
+Tests stack: 115 verdes (sin cambio — los tests del widget no
+acceden al render).
+
+Beneficio operativo:
+- El theme switcher (cuando llegue) cambia toda la paleta principal
+  de `MetaApp` con 1 sola llamada `Theme::set(cx, ...)`.
+- `MetaApp` y `nakui-explorer` comparten el mismo theme global en
+  un mismo proceso (si llegan a vivir juntos).
+- Los `confirm_delete_banner` y los toasts del MetaApp respetan
+  is_dark: el contrast ajusta automatic.
+
 ### feat(yahweh): theme integration en `banner` + `card` + `nakui-explorer` consume themed
 Iter 4 de la integración. Los widgets `banner` y `card` ahora
 ofrecen variants `_themed(cx, ...)` que leen `Theme::global(cx)`.
diff --git a/crates/modules/ui_engine/widgets/meta-form/src/lib.rs b/crates/modules/ui_engine/widgets/meta-form/src/lib.rs
index 5f60583..1c8f2fa 100644
--- a/crates/modules/ui_engine/widgets/meta-form/src/lib.rs
+++ b/crates/modules/ui_engine/widgets/meta-form/src/lib.rs
@@ -34,7 +34,8 @@ use yahweh_meta_runtime::{
     MetaBackend, WriteOutcome,
 };
 use yahweh_meta_schema::{Action, FieldKind, FieldSpec, FormView, ListView, Module, View};
-use yahweh_widget_banner::{banner, Banner};
+use yahweh_theme::Theme;
+use yahweh_widget_banner::{banner_themed, themed_colors, Banner};
 use yahweh_widget_text_input::TextInput;
 
 /// Estado del runtime de UI. Toda la persistencia/ejecución está
@@ -440,25 +441,34 @@ fn lookup_field<'a>(v: &'a Value, path: &str) -> Option<&'a Value> {
 
 impl<B: MetaBackend> Render for MetaApp<B> {
     fn render(&mut self, _w: &mut Window, cx: &mut Context<Self>) -> impl IntoElement {
-        let bg = gpui::rgb(0x14171c);
-        let panel = gpui::rgb(0x1d2128);
-        let border = gpui::rgb(0x2a2f38);
-        let text = gpui::rgb(0xe6e8ec);
-        let text_dim = gpui::rgb(0x9ba1ad);
-        let accent = gpui::rgb(0x88c0d0);
-        let accent_active = gpui::rgb(0xa3be8c);
-
-        let sidebar = self.render_sidebar(cx, panel, border, text, text_dim, accent_active);
+        // Paleta del chrome viene del Theme global. Derivamos los
+        // 7 slots que las funciones render_* usan; las firmas
+        // siguen tomando los colors individuales (Hsla / Background)
+        // para preservar el shape del API interno.
+        //
+        // Si el caller no instaló un Theme, `Theme::global` panicea.
+        // Convención: el binario shell instala el theme en main.
+        let theme = Theme::global(cx).clone();
+        let bg = theme.bg_app.clone();
+        let panel = theme.bg_panel.clone();
+        let border = theme.border;
+        let text = theme.fg_text;
+        let text_dim = theme.fg_muted;
+        let accent = theme.accent;
+        let accent_active = theme.accent_strong;
+
+        let sidebar =
+            self.render_sidebar(cx, panel.clone(), border, text, text_dim, accent_active);
         let main_panel = self.render_main(cx, panel, border, text, text_dim, accent);
         let confirm_banner = self.render_confirm_delete_banner(cx);
         let toast_div = self
             .toast
             .as_ref()
-            .map(|t| banner(Banner::Success, t.clone()));
+            .map(|t| banner_themed(cx, Banner::Success, t.clone()));
         let error_banner = self
             .load_error
             .as_ref()
-            .map(|e| banner(Banner::Error, e.clone()));
+            .map(|e| banner_themed(cx, Banner::Error, e.clone()));
 
         div()
             .flex()
@@ -511,12 +521,15 @@ impl<B: MetaBackend> MetaApp<B> {
         let id_short = short_uuid(&id_owned);
         let entity_for_confirm = entity_owned.clone();
 
-        let banner_bg = gpui::rgb(0x4a3a1a);
-        let banner_text = gpui::rgb(0xf0e0a0);
-        let confirm_bg = gpui::rgb(0x6a2222);
-        let confirm_text = gpui::rgb(0xffd0d0);
-        let cancel_bg = gpui::rgb(0x2a2f38);
-        let cancel_text = gpui::rgb(0xc0c8d0);
+        // Banner base usa los colors themed del kind Warning (amber
+        // que sigue is_dark del theme actual). Los buttons confirm
+        // (rojo) y cancel (gris) usan los colors themed del Error
+        // y un derivative del border respectivamente.
+        let theme = Theme::global(cx);
+        let (banner_bg, banner_text) = themed_colors(Banner::Warning, theme);
+        let (confirm_bg, confirm_text) = themed_colors(Banner::Error, theme);
+        let cancel_bg: gpui::Background = theme.bg_panel_alt.clone();
+        let cancel_text = theme.fg_text;
 
         Some(
             div()
@@ -605,11 +618,11 @@ impl<B: MetaBackend> MetaApp<B> {
     fn render_sidebar(
         &self,
         cx: &mut Context<Self>,
-        panel: gpui::Rgba,
-        border: gpui::Rgba,
-        text: gpui::Rgba,
-        text_dim: gpui::Rgba,
-        accent_active: gpui::Rgba,
+        panel: gpui::Background,
+        border: gpui::Hsla,
+        text: gpui::Hsla,
+        text_dim: gpui::Hsla,
+        accent_active: gpui::Hsla,
     ) -> gpui::Div {
         let mut sidebar = div()
             .w(px(240.))
@@ -694,11 +707,11 @@ impl<B: MetaBackend> MetaApp<B> {
     fn render_main(
         &mut self,
         cx: &mut Context<Self>,
-        panel: gpui::Rgba,
-        border: gpui::Rgba,
-        text: gpui::Rgba,
-        text_dim: gpui::Rgba,
-        accent: gpui::Rgba,
+        panel: gpui::Background,
+        border: gpui::Hsla,
+        text: gpui::Hsla,
+        text_dim: gpui::Hsla,
+        accent: gpui::Hsla,
     ) -> gpui::Div {
         let main = div()
             .flex_grow()
@@ -747,10 +760,10 @@ impl<B: MetaBackend> MetaApp<B> {
         mut main: gpui::Div,
         lv: &ListView,
         mod_idx: usize,
-        border: gpui::Rgba,
-        text: gpui::Rgba,
-        text_dim: gpui::Rgba,
-        accent: gpui::Rgba,
+        border: gpui::Hsla,
+        text: gpui::Hsla,
+        text_dim: gpui::Hsla,
+        accent: gpui::Hsla,
     ) -> gpui::Div {
         let mut header = div()
             .flex()
@@ -927,9 +940,9 @@ impl<B: MetaBackend> MetaApp<B> {
         cx: &mut Context<Self>,
         field_name: String,
         target_entity: String,
-        text: gpui::Rgba,
-        text_dim: gpui::Rgba,
-        accent: gpui::Rgba,
+        text: gpui::Hsla,
+        text_dim: gpui::Hsla,
+        accent: gpui::Hsla,
     ) -> gpui::Div {
         let _ = text;
         let rows = self.list_rows(&target_entity);
@@ -1004,10 +1017,10 @@ impl<B: MetaBackend> MetaApp<B> {
         mut main: gpui::Div,
         fv: &FormView,
         mod_idx: usize,
-        _border: gpui::Rgba,
-        text: gpui::Rgba,
-        text_dim: gpui::Rgba,
-        accent: gpui::Rgba,
+        _border: gpui::Hsla,
+        text: gpui::Hsla,
+        text_dim: gpui::Hsla,
+        accent: gpui::Hsla,
     ) -> gpui::Div {
         // En modo edit, el título refleja eso para que el user no
         // se confunda creyendo que hace alta nueva.