Pilot
RN-universal Button pilot
ScaffoldedThe left column renders the existing shadcn/Radix Button (DOM-only). The right column renders a React Native Button authored against View / Text / Pressable, served on the web via react-native-web. Both read from the same tokens and respond to the brand-theme switcher — proof that the RN-universal chain is compatible with the existing Vite + Tailwind v4 showcase.
Side-by-side variants
Variant
shadcn (DOM)
RN (via RN Web)
Primary
Secondary
Outline
Ghost
Destructive
Link
Sizes (primary only)
Size
shadcn (DOM)
RN (via RN Web)
sm
default
lg
Disabled state
shadcn
RN
Accessibility parity
| Concern | shadcn approach | RN approach |
|---|---|---|
| Role | Native <button> | accessibilityRole="button" (→ ARIA on web, native role on iOS/Android) |
| Label | Inline children / aria-label | accessibilityLabel prop (required for icon variant) |
| Disabled | disabled attr + aria-disabled | disabled prop + accessibilityState.disabled |
| Focus ring | focus-visible:ring-[3px] | Same Tailwind class on web; native uses system focus ring in Phase 7 |
| Press/active | :active pseudo-class | Pressable style fn ({ pressed }) — works on web and native |
What this pilot proves
react-nativeresolves toreact-native-webvia the Vite alias, soView/Text/Pressablerender as semantic DOM elements.- Tailwind v4 utilities applied to RN primitives via
className— the existing token bridge (bg-primary,text-foreground, …) works on the right column identically to the left. - Brand switching (navy → orange → coral → teal → purple) re-themes both columns simultaneously, because they share the same semantic tokens.
- The right column's source file is ready to bundle with Metro in Phase 7 to render on iOS and Android.