UI 组件
使用并自定义 React Native 组件系统。
模板随附一层紧凑的 React Native Reusables-style components。目标不是复制所有 shadcn/ui primitives,而是提供核心 mobile building blocks,在 Component tab 中 现场展示,并让新 screens 容易组合。
Primitive inventory
| 文件 | 提供 |
|---|---|
components/ui/button.tsx | Button、haptic press support、CVA variants、配套 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 | 带 NativeWind interop 的 Lucide icon wrapper |
components/ui/input.tsx | 样式化 TextInput |
components/ui/keyboard-aware-screen.tsx | 避让键盘的 screen wrapper |
components/ui/label.tsx | 基于 rn-primitives 的 Label primitive |
components/ui/native-only-animated-view.tsx | Native-only animated wrapper,web fallback |
components/ui/separator.tsx | 水平或垂直 hairline separator |
components/ui/sheet.tsx | 基于 @gorhom/bottom-sheet 的 bottom sheet wrapper |
components/ui/skeleton.tsx | Loading placeholder blocks |
components/ui/text.tsx | Text variants 与 TextClassContext |
如需更多 React Native Reusables primitives,在模板根目录运行 RNR CLI:
pnpm dlx @react-native-reusables/cli@latest add <component>提交前检查生成文件。模板刻意让 components/ui/* 跳过 ESLint,因为这些文件多是
vendor-style primitives。
Live Component tab
Component tab 是内置参考 app:
component-catalog.ts 把 entries 分为 Controls、Inputs、Containers、Feedback。
列表页直接渲染这些 entries,/component/[slug] 根据 slug 切换并展示 buttons、
theme toggle、text fields、cards、separator、skeleton、UI states、offline banner、
toast、dialog、bottom sheet demos。
Gallery 是刻意 English-only,应视为 developer reference。产品 screens 的用户可见文案
应使用 useI18n()。
App-level helpers
| Helper | 文件 | 用途 |
|---|---|---|
| Toasts | lib/toast.tsx | showToast({ message, variant });success/error 会触发 haptics |
| Haptics | lib/haptics.ts | Selection、impact、notification haptics;web 上 native-only no-op |
| Animated splash | components/animated-splash.tsx | readiness 后淡出的 Lottie overlay |
| Offline banner | components/offline-banner.tsx | 读取 NetworkStatusProvider;如果需要全局横幅,可挂在根部 |
| Premium gate | components/premium-gate.tsx | 使用 useEntitlement().isEntitled 锁定 paid UI |
| Sign-in gate | components/sign-in-gate.tsx | 在 public screens 中展示未登录提示 |
组合 screen
从 route 开始
创建 app/your-screen.tsx。根据功能选择 ScrollView、FlashList 或专门的
native layout,并在需要标题或自定义关闭行为时用 Stack.Screen 设置 navigation options。
从 lib/ 取数据
通过 TanStack Query 或 provider hooks 调用 feature modules。不要把 Supabase queries、 upload logic、URL building 直接写进 JSX。
优先使用 primitives
用 Text、Button、Card、Input、Separator、Dialog、Sheet 和 iOS grouped
color classes 组合界面。只有当两个以上 screens 需要同样行为时,再新增 primitive。
处理 states
用 Skeleton 或 spinner 表示 loading,用简单 grouped surface 表示 empty/error,
用 showToast 做反馈;离线场景依靠 TanStack Query cache,必要时挂载 OfflineBanner。
