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.Label and Button.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:

  • icon
  • message
  • children (usually a CTA button)

tsx

Calendar date picker

A month grid date picker.

Props:

  • date: Date
  • onSelect(date: Date)

Good for “choose a date” flows (filters, scheduling, onboarding, etc.).

tsx

Horizontal calendar

A horizontal, paged weekly calendar strip.

Props:

  • selectedDate: Date
  • onSelect(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.