Core FeaturesShared UI components
Shared UI components are your speed multiplier.
Instead of rebuilding the same buttons, cards, headers, inputs, and layouts in every feature, you keep them in one place and compose them everywhere.
Where they live
Put reusable UI in:
src/shared/ui/
Feature-specific UI stays inside the feature:
src/features/<feature>/components/
Rule: if a component can be used in 2+ features, it belongs in shared/ui.
What “shared” means (and what it doesn’t)
Shared UI components should be:
- App-agnostic (no feature logic)
- Pure UI (props in, UI out)
- Tamagui-first (tokens, variants, themes)
- Composable (small pieces you can stack together)
Shared UI components should not:
- read from Zustand stores directly
- call analytics / purchases / Supabase
- navigate with Router
- depend on a specific feature folder
Keep the UI layer “dumb” so you can copy features safely and refactor fast.
Component catalog (what’s inside shared/ui)
Pressable
A consistent press interaction layer:
- haptics (soft impact)
- press scale animation
- disabled handling
Use it for any tappable UI that is not a full button.
tsx
Button
Your default button primitive, built on Pressable + Tamagui styling.
Supports:
- Variants:
primary|secondary|outline|ghost|danger - Formats:
large|medium|small|square - Subcomponents:
Button.LabelandButton.Icon
tsx
Icon
A wrapper around lucide-react-native with Tamagui theme token support.
Pass name from Lucide icons
Use token colors like "$color" (resolves from the current theme)
tsx
Card
A simple container for “card” layouts.
Supports:
- optional
backgroundImage - subcomponents:
Card.Content,Card.Title,Card.Description
tsx
Empty state
A ready-to-use empty state block.
Props:
iconmessagechildren(usually a CTA button)
tsx
Calendar date picker
A month grid date picker.
Props:
date: DateonSelect(date: Date)
Good for “choose a date” flows (filters, scheduling, onboarding, etc.).
tsx
Horizontal calendar
A horizontal, paged weekly calendar strip.
Props:
selectedDate: DateonSelect(date: Date)
Good for “daily tracking” UX where the user picks a day repeatedly.
tsx
When to add a new shared component
Add a new file in src/shared/ui/ only if:
- you’ll reuse it in 2+ features, or
- it’s a core primitive (input, sheet, modal, header, etc.)
Otherwise, copy into the feature and move it to shared/ui later if it proves reusable.
