UI Components
Use and customize the React Native component system.
The template ships a compact React Native Reusables-style component layer. The goal is not to mirror every shadcn/ui primitive; it is to provide the core mobile building blocks, show them live in the Component tab, and keep new screens easy to compose.
Primitive inventory
| File | Provides |
|---|---|
components/ui/button.tsx | Button, haptic press support, CVA variants, matching text variants |
components/ui/card.tsx | Card, CardHeader, CardTitle, CardDescription, CardContent, CardFooter |
components/ui/dialog.tsx | Dialog overlay/content/header/footer/title/description/trigger/close wrappers |
components/ui/icon.tsx | Lucide icon wrapper with NativeWind interop |
components/ui/input.tsx | Styled TextInput |
components/ui/keyboard-aware-screen.tsx | Keyboard-safe screen wrapper |
components/ui/label.tsx | Label primitive backed by rn-primitives |
components/ui/native-only-animated-view.tsx | Native-only animated wrapper with web fallback |
components/ui/separator.tsx | Horizontal or vertical hairline separator |
components/ui/sheet.tsx | Bottom sheet wrapper around @gorhom/bottom-sheet |
components/ui/skeleton.tsx | Loading placeholder blocks |
components/ui/text.tsx | Text variants and TextClassContext |
For additional React Native Reusables primitives, use the RNR CLI from the template root:
pnpm dlx @react-native-reusables/cli@latest add <component>Review the generated file before committing. The template intentionally keeps
components/ui/* out of ESLint because those files are mostly vendor-style
primitives.
Live Component tab
The Component tab is a built-in reference app:
component-catalog.ts groups entries into Controls, Inputs, Containers, and
Feedback. The list screen renders those entries, and /component/[slug] switches
over the slug to render demos for buttons, theme toggle, text fields, cards,
separator, skeleton, UI states, offline banner, toast, dialog, and bottom sheet.
The gallery is English-only by design and should be treated as a developer
reference. Product screens should use useI18n() for user-facing copy.
App-level helpers
| Helper | File | Use |
|---|---|---|
| Toasts | lib/toast.tsx | showToast({ message, variant }); success and error trigger haptics |
| Haptics | lib/haptics.ts | Selection, impact, and notification haptics; native-only no-op on web |
| Animated splash | components/animated-splash.tsx | Lottie overlay that fades after readiness |
| Offline banner | components/offline-banner.tsx | Reads NetworkStatusProvider; mount globally if your app wants a persistent banner |
| Premium gate | components/premium-gate.tsx | Locks paid UI using useEntitlement().isEntitled |
| Sign-in gate | components/sign-in-gate.tsx | Shows a signed-out prompt inside public screens |
Compose a screen
Start from the route
Create app/your-screen.tsx. Use ScrollView, FlashList, or a focused native
layout depending on the feature, and set navigation options with Stack.Screen
when the screen needs a title or custom close action.
Pull data from lib/
Call feature modules through TanStack Query or provider hooks. Keep Supabase queries, upload logic, and URL building out of JSX.
Use primitives first
Compose with Text, Button, Card, Input, Separator, Dialog, Sheet,
and the iOS grouped color classes. Add a new primitive only when two or more
screens need the same behavior.
Handle states
Show loading with Skeleton or a spinner, empty/error states with simple grouped
surfaces, feedback with showToast, and offline behavior with TanStack Query
cache plus OfflineBanner when mounted.
