UI Design — Native
Inline styles, shadows, and animation library priority → see react-native-styling skill.
Web design rules → see ui-design-web skill.
Touch Interaction (CRITICAL)
- Minimum touch target: 44×44pt (iOS) / 48×48dp (Android)
- Use
hitSlop to extend tap area when the visual element is smaller than the minimum
- Minimum gap between touch targets: 8pt/8dp
- All interactive elements provide press feedback within 80–150ms (ripple, opacity change, or elevation shift)
- Scale feedback:
scale(0.95–1.05) on press, restore on release
- Never rely on hover-only interactions — use tap/press for all primary actions
Incorrect — small icon without hit area expansion:
<Pressable
<Icon name="close" size={16} /> {/* ✗ 16pt is too small */}
</Pressable>
Correct:
<Pressable hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}>
<Icon name="close" size={16} /> {/* ✓ effective tap area is 40pt+ */}
</Pressable>
Safe Areas
- All fixed headers, tab bars, and bottom CTA bars must respect safe zones
contentInsetAdjustmentBehavior="automatic" handles this on ScrollView/FlatList
- Keep primary touch targets away from notch, Dynamic Island, gesture bar, screen edges
- Never block system gestures: Control Center swipe, iOS back swipe, Android predictive back
Platform Conventions
iOS:
- Bottom Tab Bar for top-level navigation (Apple HIG)
- Bottom nav max 5 items, always show both icon and text label
- Support iOS swipe-back gesture — never conflict with it
- Support Dynamic Type — test at largest accessibility text size, avoid truncation
- Haptic feedback for confirmations and important actions via
expo-haptics — iOS only, avoid overuse
Android:
- Support Android predictive back gesture
- Material ripple effect on press for interactive elements
Both platforms:
- Back navigation must be predictable — never silently reset the navigation stack
- Preserve scroll position when navigating back
- Deep-link all key screens
Accessibility (Mobile)
accessibilityLabel on all icon-only buttons and meaningful images
accessibilityRole set on all interactive elements (button, link, header, etc.)
accessibilityState set for dynamic states: { selected: true }, { disabled: true }, { expanded: false }
- Logical VoiceOver/TalkBack reading order — matches visual order
- Don't convey information by color alone — always include icon or text alongside color
Animation & Motion
- Micro-interactions: 150–300ms, complex transitions ≤400ms
- Spring/physics-based curves over linear easing —
type: "spring" in moti, withSpring in reanimated
- Exit animations shorter than enter (~60–70% of enter duration) — feels more responsive
- All animations must be interruptible — user tap immediately cancels in-progress animation
- Respect
Reduce Motion accessibility setting — provide static alternatives
For which animation library to use (reanimated → moti → built-in priority order) → see react-native-styling skill.
Pre-Delivery Checklist
1---2name: ui-design-native3description: React Native / iOS / Android design and UX rules — touch targets, safe areas, platform conventions, accessibility, and motion. Use when designing or reviewing React Native UI, handling touch interactions, implementing platform-specific patterns, or ensuring accessibility on mobile. For inline styles and animation library priority → see react-native-styling skill.4---56# UI Design — Native78> Inline styles, shadows, and animation library priority → see `react-native-styling` skill.9> Web design rules → see `ui-design-web` skill.1011## Touch Interaction (CRITICAL)1213- **Minimum touch target:** 44×44pt (iOS) / 48×48dp (Android)14- Use `hitSlop` to extend tap area when the visual element is smaller than the minimum15- **Minimum gap** between touch targets: 8pt/8dp16- All interactive elements provide **press feedback within 80–150ms** (ripple, opacity change, or elevation shift)17- Scale feedback: `scale(0.95–1.05)` on press, restore on release18- Never rely on hover-only interactions — use tap/press for all primary actions1920**Incorrect — small icon without hit area expansion:**21```tsx22<Pressable onPress={handleClose}>23 <Icon name="close" size={16} /> {/* ✗ 16pt is too small */}24</Pressable>25```2627**Correct:**28```tsx29<Pressable onPress={handleClose} hitSlop={{ top: 12, bottom: 12, left: 12, right: 12 }}>30 <Icon name="close" size={16} /> {/* ✓ effective tap area is 40pt+ */}31</Pressable>32```3334## Safe Areas3536- All fixed headers, tab bars, and bottom CTA bars must respect safe zones37- `contentInsetAdjustmentBehavior="automatic"` handles this on ScrollView/FlatList38- Keep primary touch targets away from notch, Dynamic Island, gesture bar, screen edges39- Never block system gestures: Control Center swipe, iOS back swipe, Android predictive back4041## Platform Conventions4243**iOS:**44- Bottom Tab Bar for top-level navigation (Apple HIG)45- Bottom nav max 5 items, always show both icon and text label46- Support iOS swipe-back gesture — never conflict with it47- Support Dynamic Type — test at largest accessibility text size, avoid truncation48- Haptic feedback for confirmations and important actions via `expo-haptics` — iOS only, avoid overuse4950**Android:**51- Support Android predictive back gesture52- Material ripple effect on press for interactive elements5354**Both platforms:**55- Back navigation must be predictable — never silently reset the navigation stack56- Preserve scroll position when navigating back57- Deep-link all key screens5859## Accessibility (Mobile)6061- `accessibilityLabel` on all icon-only buttons and meaningful images62- `accessibilityRole` set on all interactive elements (`button`, `link`, `header`, etc.)63- `accessibilityState` set for dynamic states: `{ selected: true }`, `{ disabled: true }`, `{ expanded: false }`64- Logical VoiceOver/TalkBack reading order — matches visual order65- Don't convey information by color alone — always include icon or text alongside color6667## Animation & Motion6869- Micro-interactions: 150–300ms, complex transitions ≤400ms70- Spring/physics-based curves over linear easing — `type: "spring"` in moti, `withSpring` in reanimated71- Exit animations shorter than enter (~60–70% of enter duration) — feels more responsive72- All animations must be interruptible — user tap immediately cancels in-progress animation73- Respect `Reduce Motion` accessibility setting — provide static alternatives7475> For which animation library to use (reanimated → moti → built-in priority order) → see `react-native-styling` skill.7677## Pre-Delivery Checklist7879- [ ] All tap areas ≥44×44pt (iOS) or ≥48×48dp (Android)80- [ ] Press feedback appears within 80–150ms on all interactive elements81- [ ] Safe areas respected on all fixed/sticky bars82- [ ] System gestures (swipe-back, home bar) not blocked83- [ ] `accessibilityLabel` on icon-only buttons and images84- [ ] Dynamic Type tested at largest size — no truncation85- [ ] Haptics iOS-only and conditionally applied86- [ ] Animations are interruptible and respect Reduce Motion