Phase 9d · Tier B (final)
RN-universal Resizable pilot — closes Tier B 10/10
ScaffoldedTwo-panel resizable layout with draggable divider. PanResponder-driven (same as RnSlider). With this primitive, every Tier B PR shipped with zero new runtime dependencies.
Horizontal — sidebar + main
Drag the divider left or right. The first panel constrained to 20–60 % width.
Vertical — header + body
Drag the divider up or down.
Library decision
Per Phase 9 Q2, every Tier B primitive must record its library choice. RnResizable ships with no new runtime dependency.
- react-resizable-panels (~3 M/wk, MIT) — shadcn's choice; web-only. Same
.web/.nativeblocker as cmdk / sonner / react-day-picker. - react-native-reanimated@4.3.0 (~3.96 M/wk, MIT) — 9a inventory's recommendation. Rejected for the same reason as
RnSlider(usesPanResponder) andRnCarousel(usespagingEnabled): we've consistently avoided pulling reanimated for primitives where the RN-core gesture API suffices. - This implementation — pure RN core.
View+PanResponderdrag tracking + flex-based layout. ~250 LOC.
Phase 9d Tier B — complete
With this primitive, all 10 Tier B primitives are shipped:
| # | Primitive | Version | Library decision |
|---|---|---|---|
| 1 | RnCommand | 0.2.3 | cmdk rejected (web-only) |
| 2 | RnCombobox | 0.2.4 | composes RnPopover + RnCommand |
| 3 | RnToaster | 0.2.5 | sonner / RNTM / burnt rejected |
| 4 | RnInputOTP | 0.2.6 | input-otp / RNCCF rejected |
| 5 | RnPhoneInput | 0.3.1 | libphonenumber-js rejected (140 KB) |
| 6 | RnFileUpload | 0.3.2 | expo-document-picker rejected (peer dep) |
| 7 | RnCalendar | 0.3.3 | react-day-picker / RN-calendars rejected |
| 8 | RnCarousel | 0.3.4 | embla / RN-reanimated-carousel rejected |
| 9 | RnChart | 0.3.5 | recharts / victory-native rejected |
| 10 | RnResizable | 0.3.6 | react-resizable-panels / reanimated rejected |
Zero new runtime dependencies across the entire phase. Phase 9 next steps: Phase 9e (Tier C pattern compositions), then Phase 10 (sunset @radix-ui/* from the web bundle).