Phase 9d · Tier B
RN-universal Carousel pilot
ScaffoldedHorizontal paging carousel with optional auto-play, loop, dot indicators, and prev/next buttons. Built on ScrollView + pagingEnabled (native) / CSS scroll-snap (web). No new runtime dep.
Default — manual nav with dots
Slide #1
Slide 1
Drag, swipe, or use the chevron buttons.
Slide #2
Slide 2
Dot indicators sync with the active slide.
Slide #3
Slide 3
Auto-play pauses on user interaction.
Slide #4
Slide 4
CSS scroll-snap on web; pagingEnabled on native.
Slide #5
Slide 5
No `embla-carousel`, no `react-native-reanimated-carousel`.
Auto-play (4 s) with loop
Auto-advances every 4 seconds; pauses for one tick when the user uses prev/next or taps a dot.
Slide #1
Slide 1
Drag, swipe, or use the chevron buttons.
Slide #2
Slide 2
Dot indicators sync with the active slide.
Slide #3
Slide 3
Auto-play pauses on user interaction.
Library decision
Per Phase 9 Q2, every Tier B primitive must record its library choice. RnCarousel ships with no new runtime dependency.
- embla-carousel-react (~5 M/wk, MIT) — shadcn's choice; web-only. Same
.web/.nativeblocker as cmdk / sonner / react-day-picker. - react-native-reanimated-carousel@4.0.3 (~412 k/wk, MIT) — RN-only; pulls
react-native-reanimatedas a peer dep. We've consistently rejected reanimated (RnSlider usesPanResponderfor the same reason). - react-native-snap-carousel — deprecated; no React 18+ support.
- This implementation — pure RN core.
ScrollViewwithpagingEnabled(native) / CSSscroll-snap(RN-Web). ~250 LOC.
Semantics
| Aspect | shadcn (embla) | RN | Notes |
|---|---|---|---|
| Compound API | Carousel / Content / Item / Previous / Next | RnCarousel / Content / Item / Previous / Next / Dots | Plus a Dots primitive (shadcn leaves this to consumers) |
| Paging | embla snap | pagingEnabled + scroll-snap | Same swipe UX |
| Auto-play | plugin | autoplayMs prop | Pauses on user interaction for one tick |
| Loop | plugin | loop prop | Same behaviour |
| Orientation | horizontal default | horizontal default; vertical via prop | Horizontal more battle-tested |
| Slides per view | slidesToScroll / slidesToShow | fullWidth (1 per page) only in v1 | Multi-per-view is 0.3.x |
| Keyboard nav | arrow keys | tap (prev/next, dots) | 0.3.x candidate |