Browse all of Kata

Shared UI components

Source .claude/skills/design/references/components.mdMarkdown

Shared UI components

35 components are exported from src/components/ui/index.ts. Check this list before you build anything. If something close already exists, extend it — a second implementation of a row, a sheet or an empty state is the most common way this codebase drifts. Import from the barrel:

import { Button, Card, Stack, Text } from '../../components/ui';
Component What it is
ActionMenu a sheet of actions behind a ⋯, with ActionRow as its row
ActionRow a sheet of actions behind a ⋯, with ActionRow as its row
Avatar circular user image with initials fallback
Badge the generic status pill
BeltDot colored circle representing a belt rank
BeltStateBadge small pill that captions a non-verified BeltDisplay state
BottomSheet thin wrapper around @gorhom/bottom-sheet's BottomSheetModal
Button the app's button
Card a white block sitting on the tinted page
Checkbox a decision about a thing that is already there
ChildHeader the shared child-screen header: back chevron, no title
EmptyState shared empty-state primitive for list screens
FeedRow one row in the Social feed
Field label, control, helper, error
Hero the full-bleed loud block that replaces the retired DiagonalBand
InlineComposer the "Share something…" tap target sitting above the Social feed
Input the typed field
ListFadeIn one-shot first-load fade for the tab-home lists
MediaThumbnail 12px-radius image with optional play overlay
PrimaryCTACard the full-width red CTA used for "Log a session" on the Train tab home and "Save session" at the bottom of post-class capture
RankPicker choose a rank from the dojo's own ladder
RankPickerSheet The dojo's own rank ladder, in a modal sheet
Row the generic list row: leading slot, title, optional subtitle, trailing slot, chevron
SearchField the search input twenty files were each building alone
SectionLabel a section header in the eyebrow register
SegmentedControl generic, theme-aware segmented toggle
SelectTrigger the control that opens a sheet
SessionRow one history row on the Train tab home / history list
Skeleton the shape of the thing that is coming
Stack vertical or horizontal flow with exactly one spacing decision
StatPill small rounded pill showing a value + label
TagChip multi-purpose pill
Text the typography primitive
ToastProvider + useToast() — minimal imperative toast primitive
ValidationBanner inline banner replacing single-button Alert.alert() validation/error popups

Ships, but read this first

Component The catch
SectionLabel renders typography.eyebrow — it is the eyebrow register, not a second one. Pass sentence-case children; the style uppercases them.

Retired — exported, but never in new work

Component Why
BeltRankPicker hardcodes the nineteen Cuong Nhu ranks from a constant, which foundations/rank.md forbids — a screen renders whatever ladder the dojo has. Use RankPicker inline, or RankPickerSheet for a modal. Five consumers remain; migrating one also means deciding what users.belt_rank holds for a dojo that is not Cuong Nhu (product-facts.md, "Not yet decided")