When to use
Use this skill when:
- •Adding a new screen or page to a Rezi application
- •Setting up a view function for an app route
- •Scaffolding a new section of a TUI
Source of truth
- •
packages/core/src/widgets/ui.ts— allui.*factory functions - •
packages/core/src/widgets/composition.ts—defineWidget()and animation hooks - •
packages/core/src/router/— router and route definitions - •
packages/core/src/keybindings/— keybinding system - •
packages/create-rezi/templates/animation-lab/— canonical animation screen pattern - •
docs/guide/widget-authoring.md— design system integration patterns
Steps
- •
Create screen file at
src/screens/{screen-name}.ts:typescriptimport { ui } from "@rezi-ui/core"; import type { AppState } from "../state.js"; export function MyScreen(state: AppState) { return ui.column({ gap: 1 }, [ ui.text("Screen Title", { style: { bold: true } }), // screen content ]); }Prefer intent-based DS styling for simple cases (
intent: "primary","danger","secondary","link"):typescriptui.button({ id: "action", label: "Go", intent: "primary", onPress: handleAction, })Use
dsVariant,dsTone, ordsSizeonly when you need finer control. - •
Use
ui.column()orui.row()as the root container - •
If the screen needs motion, prefer declarative hooks inside
defineWidget:typescriptimport { defineWidget, ui, useSpring, useTransition } from "@rezi-ui/core"; const AnimatedScreen = defineWidget<{ target: number }>((props, ctx) => { const drift = useTransition(ctx, props.target, { duration: 180, easing: "easeOutCubic", }); const spring = useSpring(ctx, props.target, { stiffness: 190, damping: 22, }); return ui.box( { width: Math.round(20 + drift), opacity: Math.max(0.35, Math.min(1, spring / 100)), transition: { duration: 180, easing: "easeInOutCubic", properties: ["size", "opacity"] }, }, [ui.text("Animated screen")], ); }); - •
If using router, add a route definition (see
rezi-routingskill) - •
Add keybindings for screen-specific actions in the app's key handler
- •
Wire into main via router or view switch:
typescriptview: (state) => { if (state.screen === "my-screen") return MyScreen(state); return HomeScreen(state); }
Verification
- •Screen renders without errors
- •Navigation keybindings work
- •State types include any new fields
- •For animated screens: transitions retarget smoothly and no timer leaks occur on unmount