agenta-ai / mobile-shadcn-conventions
How the Agenta mobile app (web/mobile) installs and extends shadcn/ui registry components, themes them via the palette token bridge, and builds chat UI on @agenta/chat. Use when adding UI components under web/mobile, changing theme colors, editing components.json or globals.css, or building chat UI.
Mobile shadcn conventions
web/mobile uses shadcn/ui on Tailwind v4 with CSS variables. No antd, ever.
Installing registry components
Prefer the shared primitive first: if
@agenta/ui/uialready exports it
(Button,Input,Select,Dialog,Sheet,DropdownMenu, ...), import it
from there. Do not install a local copy of a component the kit already has —buttonin particular lives ONLY in@agenta/ui(Nova preset on the sharedcontrol-*scale), so there is one button.Use
Input,SkeletonBlockandSheetfrom@agenta/ui/ui. A localsrc/components/ui/sheet.tsxstill backsChannelsPanelSheetonly; do not import it
anywhere else, and do not add other local duplicates of kit components.Otherwise install via the CLI from
web/mobile/:pnpm dlx shadcn@latest add <component>.Components land in
src/components/ui/(aliases incomponents.json). They
are owned code: you may adapt them, but keep diffs minimal and expressed in
semantic tokens so upstream refreshes stay cheap.The CLI adds any peer deps (e.g.
@radix-ui/react-slot) toweb/mobile/package.json— commit the manifest andweb/pnpm-lock.yaml
changes together with the component.Never copy component source from the shadcn website by hand; the CLI resolves
the Tailwind v4 variant correctly.Installing a shadcn component that references a NEW token (e.g.
bg-sidebar,chart-*) requires extending VARS inscripts/generate-shadcn-tokens.ts+
the@theme inlinemap inglobals.cssfirst — Tailwind v4 silently
generates nothing for unmapped tokens.
Theming — the token bridge
shadcn variables (
--background,--primary, ...) are NOT hand-maintained.
They are generated intosrc/styles/theme.generated.cssfromweb/oss/src/styles/theme/palette.tsbyscripts/generate-shadcn-tokens.ts.
The script also readscontrolScale.tsfrom the same folder. That theme
folder is the one part ofweb/ossstill in use: edit it for color changes,
but touch nothing else inweb/oss.To change a color: edit
palette.ts(if the design-system value is wrong) or
the ROLE MAP in the script (if the mapping is wrong), then runpnpm --filter @agenta/mobile generate:tokensand commit the regenerated CSS.Never edit
theme.generated.cssdirectly; never introduce raw hex values in
components — if a needed role is missing, extend the bridge.Dark mode is the
.darkclass on<html>(@custom-variant darkinglobals.css), set pre-paint by the_document.tsxinit script from the
sharedagenta-themelocalStorage key. Both themes must be checked for every
new surface.
Extending components
Wrap, don't fork: feature-specific variants live in
src/features/*as thin
wrappers overcomponents/ui/*primitives (cva variants where appropriate).- Use the
cnutil from@/lib/utilsfor all class merging.
Chat UI
There are no Vercel AI Elements in the app and no
src/components/ai-elements/.
Chat lives insrc/features/chat/(ChatScreen,Composer,LiveConversation,TranscriptTurns, ...), built on@agenta/chat
(state,model,hooks,components, ... subpaths) and the Lexical-based@agenta/ui/rich-chat-input. Markdown streams throughstreamdown.Behavior comes from
@agenta/chathooks — never re-implement orchestration
inside a rendered component.Icons: both
@phosphor-icons/react(most files) andlucide-react(older
files and shadcn registry output) are in use. Match the surrounding feature.