Styling¶
Rezi styling is:
- explicit
- deterministic
- theme-aware
- composable through inheritance and scoped overrides
Inline styles¶
Use inline style props for one-off presentation.
import { resolveColorToken, type ThemeDefinition, ui } from "@rezi-ui/core";
function warningPanel(activeTheme: ThemeDefinition) {
return ui.box(
{
border: "rounded",
p: 1,
style: { bg: resolveColorToken(activeTheme, "bg.elevated") },
},
[ui.text("Warning", { style: { fg: resolveColorToken(activeTheme, "warning"), bold: true } })],
);
}
Container style inherits to descendants unless a child overrides it.
Theme-based styling¶
Themes are semantic ThemeDefinition objects.
import { ui, darkTheme, lightTheme } from "@rezi-ui/core";
import { createNodeApp } from "@rezi-ui/node";
const app = createNodeApp({ initialState: {}, theme: darkTheme });
app.view(() => ui.text("Hello"));
await app.start();
Switching themes at runtime:
Design-system defaults¶
Built-in semantic themes automatically enable recipe styling for core widgets.
- You do not need
dsVariantordsTonefor baseline polished styling. - Manual widget styles merge on top of recipe output.
app.setTheme(...)and scoped overrides use the same semantic token model.
Validation and extension¶
Theme hardening APIs:
validateTheme(theme)extendTheme(base, overrides)contrastRatio(fg, bg)
import { darkTheme, extendTheme, rgb, validateTheme } from "@rezi-ui/core";
const brandTheme = extendTheme(darkTheme, {
colors: {
accent: {
primary: rgb(255, 180, 84),
},
},
focusIndicator: {
bold: true,
underline: false,
},
});
validateTheme(brandTheme);
Theme colors use packed Rgb24 values, so author them with rgb(...) or
color(...), not { r, g, b } objects.
Scoped theme overrides¶
Use ui.themed(...) for subtree-specific theme changes:
import { rgb, ui } from "@rezi-ui/core";
ui.column({}, [
ui.text("parent"),
ui.themed(
{
colors: {
accent: {
primary: rgb(255, 140, 90),
},
},
},
[ui.text("scoped")],
),
ui.text("parent restored"),
]);
Scoped overrides:
- compose predictably
- inherit unspecified values
- can override
colors,spacing,focusIndicator, andwidgetpalettes
box, row, column, and grid also accept a theme prop for scoped
overrides when that is more convenient than wrapping with ui.themed(...).
Dynamic styles¶
Compute styles from state, but keep view(state) pure.
import { resolveColorToken, type ThemeDefinition, ui } from "@rezi-ui/core";
function connectionStatus(activeTheme: ThemeDefinition, state: { connected: boolean }) {
return ui.text(state.connected ? "Online" : "Offline", {
style: {
fg: resolveColorToken(activeTheme, state.connected ? "success" : "error"),
},
});
}