@delacour/react-native-ui 0.1.0-alpha.4 → 0.2.0-alpha.20261010061731

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (493) hide show
  1. package/README.md +10 -6
  2. package/package.json +49 -5
  3. package/src/components/accordion/AGENTS.md +21 -9
  4. package/src/components/accordion/accordion-content.tsx +7 -4
  5. package/src/components/accordion/accordion-item.tsx +15 -13
  6. package/src/components/accordion/accordion.context.tsx +11 -5
  7. package/src/components/accordion/accordion.variants.test.ts +64 -3
  8. package/src/components/accordion/accordion.variants.ts +33 -9
  9. package/src/components/alert/AGENTS.md +102 -0
  10. package/src/components/alert/alert-action.tsx +17 -0
  11. package/src/components/alert/alert-close-button.tsx +50 -0
  12. package/src/components/alert/alert-content.tsx +15 -0
  13. package/src/components/alert/alert-description.tsx +16 -0
  14. package/src/components/alert/alert-glyphs.ts +25 -0
  15. package/src/components/alert/alert-indicator.tsx +40 -0
  16. package/src/components/alert/alert-title.tsx +18 -0
  17. package/src/components/alert/alert.context.tsx +69 -0
  18. package/src/components/alert/alert.tsx +160 -0
  19. package/src/components/alert/alert.types.ts +10 -0
  20. package/src/components/alert/alert.variants.test.ts +218 -0
  21. package/src/components/alert/alert.variants.ts +180 -0
  22. package/src/components/alert/index.ts +23 -0
  23. package/src/components/avatar/AGENTS.md +106 -0
  24. package/src/components/avatar/avatar-badge.tsx +51 -0
  25. package/src/components/avatar/avatar-group.tsx +139 -0
  26. package/src/components/avatar/avatar.context.tsx +93 -0
  27. package/src/components/avatar/avatar.tsx +201 -0
  28. package/src/components/avatar/avatar.utils.test.ts +174 -0
  29. package/src/components/avatar/avatar.utils.ts +141 -0
  30. package/src/components/avatar/avatar.variants.test.ts +251 -0
  31. package/src/components/avatar/avatar.variants.ts +270 -0
  32. package/src/components/avatar/index.ts +39 -0
  33. package/src/components/badge/AGENTS.md +10 -0
  34. package/src/components/badge/badge-close-button.tsx +2 -2
  35. package/src/components/badge/badge.context.tsx +2 -1
  36. package/src/components/badge/badge.tsx +13 -4
  37. package/src/components/badge/badge.variants.test.ts +26 -0
  38. package/src/components/badge/badge.variants.ts +21 -0
  39. package/src/components/bottom-sheet/AGENTS.md +186 -231
  40. package/src/components/bottom-sheet/bottom-sheet-background.tsx +31 -22
  41. package/src/components/bottom-sheet/bottom-sheet-close.tsx +23 -30
  42. package/src/components/bottom-sheet/bottom-sheet-container.tsx +54 -208
  43. package/src/components/bottom-sheet/bottom-sheet-content.tsx +25 -48
  44. package/src/components/bottom-sheet/bottom-sheet-description.tsx +8 -2
  45. package/src/components/bottom-sheet/bottom-sheet-flat-list.tsx +65 -0
  46. package/src/components/bottom-sheet/bottom-sheet-footer.tsx +53 -122
  47. package/src/components/bottom-sheet/bottom-sheet-handle.tsx +31 -26
  48. package/src/components/bottom-sheet/bottom-sheet-legend-list.tsx +69 -0
  49. package/src/components/bottom-sheet/bottom-sheet-overlay.tsx +25 -147
  50. package/src/components/bottom-sheet/bottom-sheet-provider.tsx +42 -0
  51. package/src/components/bottom-sheet/bottom-sheet-scroll-view.tsx +38 -62
  52. package/src/components/bottom-sheet/bottom-sheet-section-list.tsx +58 -0
  53. package/src/components/bottom-sheet/bottom-sheet-steps.tsx +88 -0
  54. package/src/components/bottom-sheet/bottom-sheet-text-input.tsx +44 -0
  55. package/src/components/bottom-sheet/bottom-sheet-title.tsx +12 -8
  56. package/src/components/bottom-sheet/bottom-sheet-trigger.tsx +19 -37
  57. package/src/components/bottom-sheet/bottom-sheet.tsx +113 -60
  58. package/src/components/bottom-sheet/bottom-sheet.variants.test.ts +47 -87
  59. package/src/components/bottom-sheet/bottom-sheet.variants.ts +50 -126
  60. package/src/components/bottom-sheet/index.ts +39 -17
  61. package/src/components/bottom-sheet/use-bottom-sheet-input.ts +16 -115
  62. package/src/components/button/AGENTS.md +51 -11
  63. package/src/components/button/button-group.tsx +44 -8
  64. package/src/components/button/button.context.tsx +10 -0
  65. package/src/components/button/button.tsx +7 -1
  66. package/src/components/button/button.variants.test.ts +190 -0
  67. package/src/components/button/button.variants.ts +87 -6
  68. package/src/components/button/index.ts +2 -0
  69. package/src/components/calendar/AGENTS.md +142 -0
  70. package/src/components/calendar/calendar-caption.tsx +116 -0
  71. package/src/components/calendar/calendar-day.tsx +103 -0
  72. package/src/components/calendar/calendar-grid.tsx +183 -0
  73. package/src/components/calendar/calendar-header.tsx +34 -0
  74. package/src/components/calendar/calendar-nav.tsx +51 -0
  75. package/src/components/calendar/calendar-picker.tsx +128 -0
  76. package/src/components/calendar/calendar-weekdays.tsx +48 -0
  77. package/src/components/calendar/calendar.context.tsx +108 -0
  78. package/src/components/calendar/calendar.date.test.ts +456 -0
  79. package/src/components/calendar/calendar.date.ts +584 -0
  80. package/src/components/calendar/calendar.tsx +389 -0
  81. package/src/components/calendar/calendar.types.ts +87 -0
  82. package/src/components/calendar/calendar.variants.test.ts +363 -0
  83. package/src/components/calendar/calendar.variants.ts +426 -0
  84. package/src/components/calendar/index.ts +96 -0
  85. package/src/components/card/AGENTS.md +92 -0
  86. package/src/components/card/card-action.tsx +16 -0
  87. package/src/components/card/card-content.tsx +12 -0
  88. package/src/components/card/card-description.tsx +12 -0
  89. package/src/components/card/card-footer.tsx +30 -0
  90. package/src/components/card/card-header.tsx +45 -0
  91. package/src/components/card/card-title.tsx +25 -0
  92. package/src/components/card/card.context.tsx +64 -0
  93. package/src/components/card/card.tsx +100 -0
  94. package/src/components/card/card.types.ts +13 -0
  95. package/src/components/card/card.variants.test.ts +240 -0
  96. package/src/components/card/card.variants.ts +177 -0
  97. package/src/components/card/index.ts +15 -0
  98. package/src/components/chart/AGENTS.md +8 -0
  99. package/src/components/chart/chart.tsx +8 -1
  100. package/src/components/chip/AGENTS.md +113 -0
  101. package/src/components/chip/chip-close-button.tsx +48 -0
  102. package/src/components/chip/chip-end-content.tsx +15 -0
  103. package/src/components/chip/chip-label.tsx +21 -0
  104. package/src/components/chip/chip-start-content.tsx +16 -0
  105. package/src/components/chip/chip.context.tsx +66 -0
  106. package/src/components/chip/chip.tsx +268 -0
  107. package/src/components/chip/chip.types.ts +10 -0
  108. package/src/components/chip/chip.variants.test.ts +335 -0
  109. package/src/components/chip/chip.variants.ts +321 -0
  110. package/src/components/chip/index.ts +24 -0
  111. package/src/components/collapsible/AGENTS.md +97 -0
  112. package/src/components/collapsible/collapsible-content.tsx +97 -0
  113. package/src/components/collapsible/collapsible-description.tsx +17 -0
  114. package/src/components/collapsible/collapsible-indicator.tsx +92 -0
  115. package/src/components/collapsible/collapsible-title.tsx +17 -0
  116. package/src/components/collapsible/collapsible-trigger.tsx +133 -0
  117. package/src/components/collapsible/collapsible.context.tsx +91 -0
  118. package/src/components/collapsible/collapsible.tsx +167 -0
  119. package/src/components/collapsible/collapsible.types.ts +9 -0
  120. package/src/components/collapsible/collapsible.variants.test.ts +338 -0
  121. package/src/components/collapsible/collapsible.variants.ts +228 -0
  122. package/src/components/collapsible/index.ts +32 -0
  123. package/src/components/context-menu/AGENTS.md +103 -0
  124. package/src/components/context-menu/context-menu-content.tsx +64 -0
  125. package/src/components/context-menu/context-menu-item.tsx +22 -0
  126. package/src/components/context-menu/context-menu-preview.tsx +60 -0
  127. package/src/components/context-menu/context-menu-trigger.tsx +160 -0
  128. package/src/components/context-menu/context-menu.context.tsx +91 -0
  129. package/src/components/context-menu/context-menu.tsx +90 -0
  130. package/src/components/context-menu/context-menu.variants.test.ts +266 -0
  131. package/src/components/context-menu/context-menu.variants.ts +147 -0
  132. package/src/components/context-menu/index.ts +18 -0
  133. package/src/components/dialog/AGENTS.md +97 -0
  134. package/src/components/dialog/dialog-body.tsx +21 -0
  135. package/src/components/dialog/dialog-close.tsx +82 -0
  136. package/src/components/dialog/dialog-content.tsx +153 -0
  137. package/src/components/dialog/dialog-description.tsx +23 -0
  138. package/src/components/dialog/dialog-footer.tsx +32 -0
  139. package/src/components/dialog/dialog-header.tsx +20 -0
  140. package/src/components/dialog/dialog-title.tsx +42 -0
  141. package/src/components/dialog/dialog-trigger.tsx +54 -0
  142. package/src/components/dialog/dialog.context.tsx +90 -0
  143. package/src/components/dialog/dialog.tsx +119 -0
  144. package/src/components/dialog/dialog.variants.test.ts +224 -0
  145. package/src/components/dialog/dialog.variants.ts +173 -0
  146. package/src/components/dialog/index.ts +30 -0
  147. package/src/components/drawer/AGENTS.md +123 -0
  148. package/src/components/drawer/drawer-body.tsx +46 -0
  149. package/src/components/drawer/drawer-close.tsx +76 -0
  150. package/src/components/drawer/drawer-content.tsx +186 -0
  151. package/src/components/drawer/drawer-description.tsx +23 -0
  152. package/src/components/drawer/drawer-footer.tsx +21 -0
  153. package/src/components/drawer/drawer-header.tsx +42 -0
  154. package/src/components/drawer/drawer-title.tsx +35 -0
  155. package/src/components/drawer/drawer-trigger.tsx +54 -0
  156. package/src/components/drawer/drawer.context.tsx +114 -0
  157. package/src/components/drawer/drawer.tsx +119 -0
  158. package/src/components/drawer/drawer.variants.test.ts +392 -0
  159. package/src/components/drawer/drawer.variants.ts +244 -0
  160. package/src/components/drawer/index.ts +41 -0
  161. package/src/components/drawer/use-drawer-pan.ts +108 -0
  162. package/src/components/empty-state/AGENTS.md +90 -0
  163. package/src/components/empty-state/empty-state-content.tsx +17 -0
  164. package/src/components/empty-state/empty-state-description.tsx +12 -0
  165. package/src/components/empty-state/empty-state-header.tsx +17 -0
  166. package/src/components/empty-state/empty-state-media.tsx +56 -0
  167. package/src/components/empty-state/empty-state-title.tsx +18 -0
  168. package/src/components/empty-state/empty-state.context.tsx +65 -0
  169. package/src/components/empty-state/empty-state.tsx +84 -0
  170. package/src/components/empty-state/empty-state.types.ts +14 -0
  171. package/src/components/empty-state/empty-state.variants.test.ts +245 -0
  172. package/src/components/empty-state/empty-state.variants.ts +132 -0
  173. package/src/components/empty-state/index.ts +20 -0
  174. package/src/components/fab/AGENTS.md +119 -0
  175. package/src/components/fab/fab-action.tsx +118 -0
  176. package/src/components/fab/fab-group.tsx +214 -0
  177. package/src/components/fab/fab-label.tsx +18 -0
  178. package/src/components/fab/fab.context.tsx +125 -0
  179. package/src/components/fab/fab.tsx +156 -0
  180. package/src/components/fab/fab.types.ts +17 -0
  181. package/src/components/fab/fab.variants.test.ts +274 -0
  182. package/src/components/fab/fab.variants.ts +234 -0
  183. package/src/components/fab/index.ts +37 -0
  184. package/src/components/feedback/AGENTS.md +95 -0
  185. package/src/components/feedback/feedback-action.tsx +16 -0
  186. package/src/components/feedback/feedback-cancel.tsx +34 -0
  187. package/src/components/feedback/feedback-close.tsx +21 -0
  188. package/src/components/feedback/feedback-content.tsx +24 -0
  189. package/src/components/feedback/feedback-field.tsx +70 -0
  190. package/src/components/feedback/feedback-footer.tsx +21 -0
  191. package/src/components/feedback/feedback-panel.tsx +54 -0
  192. package/src/components/feedback/feedback-submit.tsx +74 -0
  193. package/src/components/feedback/feedback-title.tsx +34 -0
  194. package/src/components/feedback/feedback-trigger.tsx +20 -0
  195. package/src/components/feedback/feedback.context.tsx +73 -0
  196. package/src/components/feedback/feedback.tsx +135 -0
  197. package/src/components/feedback/feedback.variants.test.ts +185 -0
  198. package/src/components/feedback/feedback.variants.ts +128 -0
  199. package/src/components/feedback/index.ts +24 -0
  200. package/src/components/field/AGENTS.md +19 -0
  201. package/src/components/field/field-label.tsx +19 -5
  202. package/src/components/field/field.context.tsx +17 -0
  203. package/src/components/field/field.tsx +15 -2
  204. package/src/components/field/field.variants.test.ts +24 -0
  205. package/src/components/field/field.variants.ts +20 -0
  206. package/src/components/field/index.ts +1 -0
  207. package/src/components/input/AGENTS.md +5 -0
  208. package/src/components/input/input.variants.test.ts +32 -0
  209. package/src/components/input/input.variants.ts +13 -1
  210. package/src/components/item/AGENTS.md +92 -0
  211. package/src/components/item/index.ts +25 -0
  212. package/src/components/item/item-actions.tsx +28 -0
  213. package/src/components/item/item-content.tsx +15 -0
  214. package/src/components/item/item-description.tsx +12 -0
  215. package/src/components/item/item-footer.tsx +13 -0
  216. package/src/components/item/item-group.tsx +32 -0
  217. package/src/components/item/item-header.tsx +13 -0
  218. package/src/components/item/item-media.tsx +37 -0
  219. package/src/components/item/item-separator.tsx +13 -0
  220. package/src/components/item/item-title.tsx +17 -0
  221. package/src/components/item/item.context.tsx +66 -0
  222. package/src/components/item/item.tsx +218 -0
  223. package/src/components/item/item.types.ts +12 -0
  224. package/src/components/item/item.variants.test.ts +263 -0
  225. package/src/components/item/item.variants.ts +200 -0
  226. package/src/components/kpi/AGENTS.md +125 -0
  227. package/src/components/kpi/index.ts +45 -0
  228. package/src/components/kpi/kpi-action.tsx +12 -0
  229. package/src/components/kpi/kpi-content.tsx +35 -0
  230. package/src/components/kpi/kpi-footer.tsx +52 -0
  231. package/src/components/kpi/kpi-group.tsx +70 -0
  232. package/src/components/kpi/kpi-header.tsx +25 -0
  233. package/src/components/kpi/kpi-icon.tsx +28 -0
  234. package/src/components/kpi/kpi-sparkline.tsx +145 -0
  235. package/src/components/kpi/kpi-stat.tsx +20 -0
  236. package/src/components/kpi/kpi-title.tsx +19 -0
  237. package/src/components/kpi/kpi-trend.tsx +105 -0
  238. package/src/components/kpi/kpi-value.tsx +32 -0
  239. package/src/components/kpi/kpi.context.tsx +111 -0
  240. package/src/components/kpi/kpi.tsx +154 -0
  241. package/src/components/kpi/kpi.types.ts +9 -0
  242. package/src/components/kpi/kpi.variants.test.ts +428 -0
  243. package/src/components/kpi/kpi.variants.ts +347 -0
  244. package/src/components/label/AGENTS.md +89 -0
  245. package/src/components/label/index.ts +10 -0
  246. package/src/components/label/label.tsx +97 -0
  247. package/src/components/label/label.variants.test.ts +176 -0
  248. package/src/components/label/label.variants.ts +123 -0
  249. package/src/components/menu/AGENTS.md +176 -0
  250. package/src/components/menu/index.ts +44 -0
  251. package/src/components/menu/menu-background.tsx +17 -0
  252. package/src/components/menu/menu-checkbox-item.tsx +57 -0
  253. package/src/components/menu/menu-content.tsx +303 -0
  254. package/src/components/menu/menu-item.tsx +162 -0
  255. package/src/components/menu/menu-label.tsx +14 -0
  256. package/src/components/menu/menu-radio-group.tsx +50 -0
  257. package/src/components/menu/menu-radio-item.tsx +57 -0
  258. package/src/components/menu/menu-separator.tsx +11 -0
  259. package/src/components/menu/menu-sub-content.tsx +72 -0
  260. package/src/components/menu/menu-sub-trigger.tsx +50 -0
  261. package/src/components/menu/menu-sub.tsx +75 -0
  262. package/src/components/menu/menu-trigger.tsx +57 -0
  263. package/src/components/menu/menu.context.tsx +214 -0
  264. package/src/components/menu/menu.tsx +88 -0
  265. package/src/components/menu/menu.types.ts +33 -0
  266. package/src/components/menu/menu.variants.test.ts +400 -0
  267. package/src/components/menu/menu.variants.ts +353 -0
  268. package/src/components/meter/AGENTS.md +135 -0
  269. package/src/components/meter/index.ts +43 -0
  270. package/src/components/meter/meter-fill.tsx +19 -0
  271. package/src/components/meter/meter-header.tsx +17 -0
  272. package/src/components/meter/meter-label.tsx +18 -0
  273. package/src/components/meter/meter-output.tsx +42 -0
  274. package/src/components/meter/meter-segments.tsx +83 -0
  275. package/src/components/meter/meter-track.tsx +16 -0
  276. package/src/components/meter/meter.context.tsx +62 -0
  277. package/src/components/meter/meter.tsx +286 -0
  278. package/src/components/meter/meter.types.ts +30 -0
  279. package/src/components/meter/meter.variants.test.ts +430 -0
  280. package/src/components/meter/meter.variants.ts +347 -0
  281. package/src/components/overlay/AGENTS.md +89 -0
  282. package/src/components/overlay/index.ts +27 -0
  283. package/src/components/overlay/overlay-portal.tsx +84 -0
  284. package/src/components/overlay/overlay-presence.test.ts +46 -0
  285. package/src/components/overlay/overlay-presence.ts +49 -0
  286. package/src/components/overlay/overlay-registry.test.ts +96 -0
  287. package/src/components/overlay/overlay-registry.ts +99 -0
  288. package/src/components/overlay/overlay-scrim.tsx +49 -0
  289. package/src/components/overlay/overlay.context.tsx +48 -0
  290. package/src/components/overlay/overlay.tsx +118 -0
  291. package/src/components/overlay/overlay.variants.test.ts +37 -0
  292. package/src/components/overlay/overlay.variants.ts +33 -0
  293. package/src/components/overlay/use-overlay-back-handler.ts +34 -0
  294. package/src/components/overlay/use-overlay-presence.ts +87 -0
  295. package/src/components/popover/AGENTS.md +138 -0
  296. package/src/components/popover/index.ts +48 -0
  297. package/src/components/popover/popover-anchor.tsx +49 -0
  298. package/src/components/popover/popover-arrow.tsx +89 -0
  299. package/src/components/popover/popover-close.tsx +73 -0
  300. package/src/components/popover/popover-content.tsx +235 -0
  301. package/src/components/popover/popover-description.tsx +18 -0
  302. package/src/components/popover/popover-title.tsx +33 -0
  303. package/src/components/popover/popover-trigger.tsx +56 -0
  304. package/src/components/popover/popover.context.tsx +71 -0
  305. package/src/components/popover/popover.position.test.ts +354 -0
  306. package/src/components/popover/popover.position.ts +286 -0
  307. package/src/components/popover/popover.tsx +123 -0
  308. package/src/components/popover/popover.variants.test.ts +135 -0
  309. package/src/components/popover/popover.variants.ts +85 -0
  310. package/src/components/popover/use-anchor-measure.ts +76 -0
  311. package/src/components/popover/use-anchored-content.ts +219 -0
  312. package/src/components/pressable/AGENTS.md +11 -1
  313. package/src/components/pressable/pressable.tsx +7 -2
  314. package/src/components/pressable/pressable.variants.test.ts +29 -0
  315. package/src/components/pressable/pressable.variants.ts +17 -0
  316. package/src/components/progress/AGENTS.md +120 -0
  317. package/src/components/progress/index.ts +40 -0
  318. package/src/components/progress/progress-fill.tsx +152 -0
  319. package/src/components/progress/progress-header.tsx +19 -0
  320. package/src/components/progress/progress-label.tsx +27 -0
  321. package/src/components/progress/progress-output.tsx +47 -0
  322. package/src/components/progress/progress-track.tsx +38 -0
  323. package/src/components/progress/progress.context.tsx +79 -0
  324. package/src/components/progress/progress.tsx +171 -0
  325. package/src/components/progress/progress.types.ts +23 -0
  326. package/src/components/progress/progress.variants.test.ts +335 -0
  327. package/src/components/progress/progress.variants.ts +284 -0
  328. package/src/components/progress-button/AGENTS.md +116 -0
  329. package/src/components/progress-button/index.ts +36 -0
  330. package/src/components/progress-button/progress-button-done.tsx +33 -0
  331. package/src/components/progress-button/progress-button-label.tsx +27 -0
  332. package/src/components/progress-button/progress-button.context.tsx +93 -0
  333. package/src/components/progress-button/progress-button.tsx +414 -0
  334. package/src/components/progress-button/progress-button.variants.test.ts +314 -0
  335. package/src/components/progress-button/progress-button.variants.ts +236 -0
  336. package/src/components/provider/AGENTS.md +38 -25
  337. package/src/components/provider/provider.tsx +38 -11
  338. package/src/components/radio/AGENTS.md +8 -10
  339. package/src/components/radio/radio.variants.test.ts +5 -6
  340. package/src/components/radio/radio.variants.ts +6 -7
  341. package/src/components/rating/AGENTS.md +143 -0
  342. package/src/components/rating/index.ts +43 -0
  343. package/src/components/rating/rating-output.tsx +39 -0
  344. package/src/components/rating/rating-star.tsx +70 -0
  345. package/src/components/rating/rating-stars.tsx +219 -0
  346. package/src/components/rating/rating.context.tsx +79 -0
  347. package/src/components/rating/rating.tsx +163 -0
  348. package/src/components/rating/rating.variants.test.ts +347 -0
  349. package/src/components/rating/rating.variants.ts +354 -0
  350. package/src/components/selection-mode/AGENTS.md +155 -0
  351. package/src/components/selection-mode/index.ts +43 -0
  352. package/src/components/selection-mode/selection-mode-action.tsx +65 -0
  353. package/src/components/selection-mode/selection-mode-bar.tsx +79 -0
  354. package/src/components/selection-mode/selection-mode-group.tsx +123 -0
  355. package/src/components/selection-mode/selection-mode-header.tsx +85 -0
  356. package/src/components/selection-mode/selection-mode-indicator.tsx +118 -0
  357. package/src/components/selection-mode/selection-mode-item.tsx +182 -0
  358. package/src/components/selection-mode/selection-mode.context.tsx +89 -0
  359. package/src/components/selection-mode/selection-mode.tsx +207 -0
  360. package/src/components/selection-mode/selection-mode.types.ts +36 -0
  361. package/src/components/selection-mode/selection-mode.variants.test.ts +292 -0
  362. package/src/components/selection-mode/selection-mode.variants.ts +329 -0
  363. package/src/components/skeleton/AGENTS.md +120 -0
  364. package/src/components/skeleton/index.ts +15 -0
  365. package/src/components/skeleton/skeleton-clock.ts +48 -0
  366. package/src/components/skeleton/skeleton-group.tsx +64 -0
  367. package/src/components/skeleton/skeleton-shimmer.tsx +80 -0
  368. package/src/components/skeleton/skeleton.context.tsx +45 -0
  369. package/src/components/skeleton/skeleton.tsx +227 -0
  370. package/src/components/skeleton/skeleton.variants.test.ts +245 -0
  371. package/src/components/skeleton/skeleton.variants.ts +222 -0
  372. package/src/components/slide-button/AGENTS.md +122 -0
  373. package/src/components/slide-button/index.ts +43 -0
  374. package/src/components/slide-button/slide-button-label.tsx +70 -0
  375. package/src/components/slide-button/slide-button-thumb.tsx +93 -0
  376. package/src/components/slide-button/slide-button.context.tsx +76 -0
  377. package/src/components/slide-button/slide-button.tsx +457 -0
  378. package/src/components/slide-button/slide-button.variants.test.ts +288 -0
  379. package/src/components/slide-button/slide-button.variants.ts +324 -0
  380. package/src/components/slider/index.ts +2 -0
  381. package/src/components/slider/slider-thumb.tsx +33 -1
  382. package/src/components/slider/slider.variants.test.ts +52 -0
  383. package/src/components/slider/slider.variants.ts +56 -2
  384. package/src/components/stack-card/AGENTS.md +169 -0
  385. package/src/components/stack-card/index.ts +37 -0
  386. package/src/components/stack-card/stack-card-action.tsx +66 -0
  387. package/src/components/stack-card/stack-card-actions.tsx +18 -0
  388. package/src/components/stack-card/stack-card-card.tsx +71 -0
  389. package/src/components/stack-card/stack-card-empty.tsx +30 -0
  390. package/src/components/stack-card/stack-card-slot.tsx +90 -0
  391. package/src/components/stack-card/stack-card-stamp.tsx +76 -0
  392. package/src/components/stack-card/stack-card.context.tsx +117 -0
  393. package/src/components/stack-card/stack-card.tsx +557 -0
  394. package/src/components/stack-card/stack-card.types.ts +26 -0
  395. package/src/components/stack-card/stack-card.variants.test.ts +355 -0
  396. package/src/components/stack-card/stack-card.variants.ts +360 -0
  397. package/src/components/steps/AGENTS.md +153 -0
  398. package/src/components/steps/index.ts +45 -0
  399. package/src/components/steps/steps-connector.tsx +31 -0
  400. package/src/components/steps/steps-description.tsx +26 -0
  401. package/src/components/steps/steps-indicator.tsx +106 -0
  402. package/src/components/steps/steps-item.tsx +225 -0
  403. package/src/components/steps/steps-panel.tsx +41 -0
  404. package/src/components/steps/steps-title.tsx +32 -0
  405. package/src/components/steps/steps-track.tsx +59 -0
  406. package/src/components/steps/steps.context.tsx +123 -0
  407. package/src/components/steps/steps.tsx +166 -0
  408. package/src/components/steps/steps.variants.test.ts +388 -0
  409. package/src/components/steps/steps.variants.ts +468 -0
  410. package/src/components/surface/AGENTS.md +82 -0
  411. package/src/components/surface/index.ts +15 -0
  412. package/src/components/surface/surface.context.tsx +56 -0
  413. package/src/components/surface/surface.tsx +87 -0
  414. package/src/components/surface/surface.variants.test.ts +227 -0
  415. package/src/components/surface/surface.variants.ts +165 -0
  416. package/src/components/swipe/AGENTS.md +140 -0
  417. package/src/components/swipe/index.ts +31 -0
  418. package/src/components/swipe/swipe-action.tsx +99 -0
  419. package/src/components/swipe/swipe-end.tsx +14 -0
  420. package/src/components/swipe/swipe-group.tsx +55 -0
  421. package/src/components/swipe/swipe-panel.tsx +55 -0
  422. package/src/components/swipe/swipe-start.tsx +15 -0
  423. package/src/components/swipe/swipe.context.tsx +135 -0
  424. package/src/components/swipe/swipe.tsx +393 -0
  425. package/src/components/swipe/swipe.types.ts +7 -0
  426. package/src/components/swipe/swipe.variants.test.ts +337 -0
  427. package/src/components/swipe/swipe.variants.ts +290 -0
  428. package/src/components/switch/switch.variants.ts +2 -2
  429. package/src/components/tabs/AGENTS.md +4 -3
  430. package/src/components/tabs/tabs.variants.test.ts +1 -1
  431. package/src/components/tabs/tabs.variants.ts +4 -6
  432. package/src/components/text/AGENTS.md +8 -2
  433. package/src/components/text/text.tsx +7 -0
  434. package/src/components/text/text.variants.test.ts +24 -1
  435. package/src/components/text/text.variants.ts +5 -0
  436. package/src/components/textarea/AGENTS.md +89 -0
  437. package/src/components/textarea/index.ts +16 -0
  438. package/src/components/textarea/textarea.tsx +157 -0
  439. package/src/components/textarea/textarea.variants.test.ts +219 -0
  440. package/src/components/textarea/textarea.variants.ts +171 -0
  441. package/src/components/toast/AGENTS.md +140 -0
  442. package/src/components/toast/index.ts +74 -0
  443. package/src/components/toast/toast-action.tsx +59 -0
  444. package/src/components/toast/toast-api.ts +32 -0
  445. package/src/components/toast/toast-close.tsx +44 -0
  446. package/src/components/toast/toast-content.tsx +11 -0
  447. package/src/components/toast/toast-description.tsx +11 -0
  448. package/src/components/toast/toast-indicator.tsx +34 -0
  449. package/src/components/toast/toast-item.tsx +308 -0
  450. package/src/components/toast/toast-title.tsx +13 -0
  451. package/src/components/toast/toast-viewport.tsx +135 -0
  452. package/src/components/toast/toast.context.tsx +69 -0
  453. package/src/components/toast/toast.store.test.ts +259 -0
  454. package/src/components/toast/toast.store.ts +338 -0
  455. package/src/components/toast/toast.timer.test.ts +64 -0
  456. package/src/components/toast/toast.timer.ts +51 -0
  457. package/src/components/toast/toast.tsx +132 -0
  458. package/src/components/toast/toast.variants.test.ts +393 -0
  459. package/src/components/toast/toast.variants.ts +304 -0
  460. package/src/components/toggle-button/AGENTS.md +106 -0
  461. package/src/components/toggle-button/index.ts +30 -0
  462. package/src/components/toggle-button/toggle-button-group.tsx +156 -0
  463. package/src/components/toggle-button/toggle-button-label.tsx +19 -0
  464. package/src/components/toggle-button/toggle-button.context.tsx +130 -0
  465. package/src/components/toggle-button/toggle-button.tsx +172 -0
  466. package/src/components/toggle-button/toggle-button.variants.test.ts +189 -0
  467. package/src/components/toggle-button/toggle-button.variants.ts +160 -0
  468. package/src/components/tooltip/AGENTS.md +133 -0
  469. package/src/components/tooltip/index.ts +28 -0
  470. package/src/components/tooltip/tooltip-arrow.tsx +40 -0
  471. package/src/components/tooltip/tooltip-content.tsx +179 -0
  472. package/src/components/tooltip/tooltip-description.tsx +19 -0
  473. package/src/components/tooltip/tooltip-text.tsx +21 -0
  474. package/src/components/tooltip/tooltip-title.tsx +20 -0
  475. package/src/components/tooltip/tooltip-trigger.tsx +103 -0
  476. package/src/components/tooltip/tooltip.context.tsx +68 -0
  477. package/src/components/tooltip/tooltip.tsx +213 -0
  478. package/src/components/tooltip/tooltip.variants.test.ts +231 -0
  479. package/src/components/tooltip/tooltip.variants.ts +177 -0
  480. package/src/hooks/use-calm-motion.tsx +31 -0
  481. package/src/lib/calm-motion.test.ts +17 -0
  482. package/src/lib/calm-motion.ts +23 -0
  483. package/src/lib/cn.parity.test.ts +62 -0
  484. package/src/lib/cn.test.ts +14 -0
  485. package/src/lib/cn.ts +11 -6
  486. package/src/no-gorhom.test.ts +54 -0
  487. package/src/styles/geometry.test.ts +1 -0
  488. package/src/styles/theme.css +4 -0
  489. package/src/styles/tokens.css +44 -0
  490. package/src/styles/tokens.test.ts +56 -0
  491. package/src/styles/tokens.ts +29 -1
  492. package/src/components/bottom-sheet/bottom-sheet-portal.tsx +0 -72
  493. package/src/components/bottom-sheet/bottom-sheet.context.tsx +0 -135
@@ -1,37 +1,31 @@
1
- import { BottomSheetScrollView as GorhomBottomSheetScrollView } from "@gorhom/bottom-sheet";
2
- import type { ComponentProps, ReactElement, ReactNode } from "react";
1
+ import {
2
+ BottomSheet as Headless,
3
+ type BottomSheetScrollViewProps as HeadlessProps,
4
+ useBottomSheetInternal,
5
+ } from "@delacour/react-native-bottom-sheet";
6
+ import type { ReactElement, ReactNode } from "react";
3
7
  import { View } from "react-native";
4
- import { useAnimatedStyle } from "react-native-reanimated";
5
- import { useSafeAreaInsets } from "react-native-safe-area-context";
6
8
  import { withUniwind } from "uniwind";
7
9
  import { cn } from "../../lib/cn";
8
- import { useBottomSheetContainerContext } from "./bottom-sheet.context";
9
- import { bottomSheetVariants, resolveSheetScrollEndPadding } from "./bottom-sheet.variants";
10
-
11
- type GorhomScrollViewProps = ComponentProps<typeof GorhomBottomSheetScrollView>;
10
+ import { BOTTOM_SHEET_FOOTER_GAP, bottomSheetVariants } from "./bottom-sheet.variants";
12
11
 
13
12
  /**
14
13
  * The one class prop this file uses, restated so the props survive the wrapper.
15
14
  *
16
15
  * `withUniwind`'s return type maps over a component's props, and over a
17
- * scrollable's animated ones it collapses to a single entry — `data`,
18
- * `contentContainerStyle` and the rest would all check against nothing. Writing
19
- * the signature out keeps them, the way `Screen.LegendList` already has to.
16
+ * scrollable's animated ones it collapses to a single entry. Writing the
17
+ * signature out keeps them, the way `Screen.LegendList` already has to.
20
18
  *
21
- * `contentContainerClassName` is deliberately absent even though the wrapper adds
22
- * one at runtime: passing it would put a second writer on `contentContainerStyle`
23
- * and cost the safe-area band — see the component's doc comment.
19
+ * `contentContainerClassName` is deliberately absent even though the wrapper
20
+ * adds one at runtime — see the component's doc comment.
24
21
  */
25
- type StyledScrollViewComponent = (props: GorhomScrollViewProps & { className?: string }) => ReactElement | null;
22
+ type StyledScrollViewComponent = (props: HeadlessProps & { className?: string }) => ReactElement | null;
26
23
 
27
- // Third-party, so `className` needs the wrapper — and it has to be built at
28
- // module scope or every render mints a new component type and remounts the list.
29
- const StyledScrollView = withUniwind(GorhomBottomSheetScrollView) as unknown as StyledScrollViewComponent;
24
+ // Third-party to Uniwind, so `className` needs the wrapper — built at module
25
+ // scope or every render mints a new component type and remounts the list.
26
+ const StyledScrollView = withUniwind(Headless.ScrollView) as unknown as StyledScrollViewComponent;
30
27
 
31
- export type BottomSheetScrollViewProps = Omit<
32
- GorhomScrollViewProps,
33
- "children" | "contentContainerStyle" | "enableFooterMarginAdjustment"
34
- > & {
28
+ export type BottomSheetScrollViewProps = Omit<HeadlessProps, "children"> & {
35
29
  className?: string;
36
30
  /** Classes for the padded box the children sit in. */
37
31
  contentContainerClassName?: string;
@@ -39,64 +33,46 @@ export type BottomSheetScrollViewProps = Omit<
39
33
  };
40
34
 
41
35
  /**
42
- * A scrolling body for a sheet taller than its snap point.
43
- *
44
- * Use this rather than a plain `ScrollView`: gorhom's scrollable and the sheet's
45
- * pan negotiate with each other, so dragging a list that is already at its top
46
- * moves the sheet instead of fighting it. A React Native `ScrollView` in here has
47
- * no such arrangement, and the sheet stops responding to a drag over the list.
36
+ * A scrolling body.
48
37
  *
49
- * **It needs a height to scroll within.** With `enableDynamicSizing` left on, the
50
- * sheet grows to whatever the content measures and there is nothing to scroll —
51
- * pass `enableDynamicSizing={false}` and explicit `snapPoints` on the
52
- * `BottomSheet.Container` around it.
38
+ * Use this rather than a plain `ScrollView`: the engine's scrollable and the
39
+ * sheet's pan share a finger — below the highest snap point the list is held and
40
+ * the drag moves the sheet, at the highest the list scrolls, and a drag down
41
+ * from the top hands back to the sheet. A React Native `ScrollView` in here has
42
+ * no such arrangement.
53
43
  *
54
- * The classes go on an inner `View`, not on gorhom's own content container, and
55
- * that is not tidiness: uniwind compiles a `contentContainerClassName` into an
56
- * *array* alongside any `contentContainerStyle`, and the two then fight over the
57
- * one style this component has to own — the safe-area band. One writer for it.
44
+ * **It needs no `snapPoints` and no `dynamicSizing={false}`.** The list
45
+ * reports its content size, and that is the dynamic snap point: six rows make a
46
+ * short sheet, forty make one capped at `maxDynamicContentSize` that scrolls
47
+ * inside the cap. Explicit `snapPoints` on the root still work, for a height
48
+ * that is a decision rather than a measurement.
58
49
  *
59
- * **A pinned footer shortens the scroll view; it is not reserved inside it.**
60
- * The footer draws over the sheet, so a scroll view that ran the sheet's full
61
- * height would carry its indicator and its overscroll bounce on underneath the
62
- * footer, the bottom of the track hidden behind the buttons. So the frame gives
63
- * up the footer's measured height as a `marginBottom` and ends at the footer's
64
- * hairline, and the content keeps only the gap
65
- * ({@link resolveSheetScrollEndPadding}). The margin is an animated style off
66
- * the footer's shared value, never gorhom's `enableFooterMarginAdjustment`,
67
- * which routes that height through React state and would commit a render on
68
- * every frame of the keyboard animation — see `BottomSheet.Content`.
50
+ * The classes go on an inner `View`, not on the engine's content container,
51
+ * so the one style this component writes there — the gap that holds the last
52
+ * row off a pinned footer's hairline — has a single writer. The engine already
53
+ * clamps the list above a sticky footer and the safe-area band, so nothing
54
+ * else is reserved here.
69
55
  *
70
56
  * @example
71
- * <BottomSheet.Container enableDynamicSizing={false} snapPoints={["60%", "90%"]}>
57
+ * <BottomSheet maxDynamicContentSize={420}>
58
+ * …
72
59
  * <BottomSheet.ScrollView>{rows}</BottomSheet.ScrollView>
73
- * </BottomSheet.Container>
60
+ * </BottomSheet>
74
61
  */
75
62
  export function BottomSheetScrollView({
76
63
  className,
77
64
  contentContainerClassName,
65
+ contentContainerStyle,
78
66
  children,
79
- style,
80
67
  ...props
81
68
  }: BottomSheetScrollViewProps): ReactElement {
82
- const container = useBottomSheetContainerContext();
83
- const { bottom } = useSafeAreaInsets();
84
- const hasStickyFooter = container?.hasStickyFooter ?? false;
85
- const footerHeight = container?.footerHeight;
86
-
87
- // The footer's height, band included, as the frame's own margin — so the
88
- // indicator's track ends where the footer begins and follows it as the
89
- // keyboard takes the band back.
90
- const aboveFooter = useAnimatedStyle(() => ({
91
- marginBottom: hasStickyFooter && footerHeight !== undefined ? footerHeight.value : 0,
92
- }));
69
+ const { hasFooter } = useBottomSheetInternal();
93
70
 
94
71
  return (
95
72
  <StyledScrollView
96
73
  className={cn(className)}
97
- contentContainerStyle={{ paddingBottom: resolveSheetScrollEndPadding({ bottom, hasStickyFooter }) }}
74
+ contentContainerStyle={[{ paddingBottom: hasFooter ? BOTTOM_SHEET_FOOTER_GAP : 0 }, contentContainerStyle]}
98
75
  {...props}
99
- style={[aboveFooter, style]}
100
76
  >
101
77
  <View className={bottomSheetVariants().scrollContent({ className: contentContainerClassName })}>{children}</View>
102
78
  </StyledScrollView>
@@ -0,0 +1,58 @@
1
+ import {
2
+ BottomSheet as Headless,
3
+ type BottomSheetSectionListProps as HeadlessProps,
4
+ useBottomSheetInternal,
5
+ } from "@delacour/react-native-bottom-sheet";
6
+ import type { ReactElement, Ref } from "react";
7
+ import type { SectionList } from "react-native";
8
+ import { withUniwind } from "uniwind";
9
+ import { cn } from "../../lib/cn";
10
+ import { BOTTOM_SHEET_FOOTER_GAP, bottomSheetVariants } from "./bottom-sheet.variants";
11
+
12
+ /** The class props restated so `<ItemT, SectionT>` survive `withUniwind` — see `bottom-sheet-flat-list.tsx`. */
13
+ type StyledSectionListComponent = <ItemT, SectionT>(
14
+ props: HeadlessProps<ItemT, SectionT> & {
15
+ ref?: Ref<SectionList<ItemT, SectionT>>;
16
+ className?: string;
17
+ contentContainerClassName?: string;
18
+ }
19
+ ) => ReactElement | null;
20
+
21
+ // Built at module scope, or every render mints a new component type and
22
+ // remounts the list.
23
+ const StyledSectionList = withUniwind(Headless.SectionList) as unknown as StyledSectionListComponent;
24
+
25
+ export type BottomSheetSectionListProps<ItemT, SectionT> = HeadlessProps<ItemT, SectionT> & {
26
+ ref?: Ref<SectionList<ItemT, SectionT>>;
27
+ className?: string;
28
+ /** Classes for the content container. Same gutter and gap as `Content`. */
29
+ contentContainerClassName?: string;
30
+ };
31
+
32
+ /**
33
+ * A virtualised body with sticky section headers.
34
+ *
35
+ * The engine's `SectionList` with the library's gutter on the content
36
+ * container, for the same reasons `BottomSheet.FlatList` gives.
37
+ *
38
+ * @example
39
+ * <BottomSheet.SectionList sections={sections} renderItem={renderRow} renderSectionHeader={renderHeader} />
40
+ */
41
+ export function BottomSheetSectionList<ItemT, SectionT>({
42
+ className,
43
+ contentContainerClassName,
44
+ contentContainerStyle,
45
+ ...props
46
+ }: BottomSheetSectionListProps<ItemT, SectionT>): ReactElement {
47
+ const { hasFooter } = useBottomSheetInternal();
48
+
49
+ return (
50
+ <StyledSectionList
51
+ className={cn(className)}
52
+ contentContainerClassName={bottomSheetVariants().scrollContent({ className: contentContainerClassName })}
53
+ contentContainerStyle={[{ paddingBottom: hasFooter ? BOTTOM_SHEET_FOOTER_GAP : 0 }, contentContainerStyle]}
54
+ {...props}
55
+ />
56
+ );
57
+ }
58
+ BottomSheetSectionList.displayName = "DelacourUI.BottomSheet.SectionList";
@@ -0,0 +1,88 @@
1
+ import {
2
+ BottomSheet as Headless,
3
+ type BottomSheetStepProps as HeadlessStepProps,
4
+ type BottomSheetStepsProps as HeadlessStepsProps,
5
+ type SheetEvent,
6
+ } from "@delacour/react-native-bottom-sheet";
7
+ import type { ReactElement } from "react";
8
+ import { withUniwind } from "uniwind";
9
+ import { BOTTOM_SHEET_FOOTER_GAP, bottomSheetVariants } from "./bottom-sheet.variants";
10
+
11
+ /** The class prop restated so `<S, C, E>` survive `withUniwind` — see `bottom-sheet-flat-list.tsx`. */
12
+ type StyledStepsComponent = <S extends string, C, E extends SheetEvent>(
13
+ props: HeadlessStepsProps<S, C, E> & { className?: string }
14
+ ) => ReactElement | null;
15
+
16
+ type StyledStepComponent = <S extends string>(
17
+ props: HeadlessStepProps<S> & { className?: string }
18
+ ) => ReactElement | null;
19
+
20
+ // Both built at module scope, or every render mints a new component type and
21
+ // the step stack remounts mid-transition.
22
+ const StyledSteps = withUniwind(Headless.Steps) as unknown as StyledStepsComponent;
23
+ const StyledStep = withUniwind(Headless.Step) as unknown as StyledStepComponent;
24
+
25
+ export type BottomSheetStepsProps<S extends string, C, E extends SheetEvent> = HeadlessStepsProps<S, C, E> & {
26
+ className?: string;
27
+ };
28
+
29
+ export type BottomSheetStepProps<S extends string = string> = HeadlessStepProps<S> & {
30
+ className?: string;
31
+ };
32
+
33
+ /**
34
+ * A body whose contents follow a step machine and whose height glides between
35
+ * them.
36
+ *
37
+ * The engine's `Steps` — `Content` with an animated-height stack inside — with
38
+ * the library's gutter on the box around the stack. Only the gutter: the
39
+ * engine measures each `Step`, not the box, so vertical padding here would be
40
+ * height the sheet never counts. `Step` carries that instead.
41
+ *
42
+ * A `Footer` written beside it reads the same controller through
43
+ * `useSheetStep()`, which is how a Next button outside the body knows what it
44
+ * can send.
45
+ *
46
+ * @example
47
+ * const machine = defineSheetMachine<Step, Context, Event>({ … });
48
+ *
49
+ * function Form() {
50
+ * const controller = useSheetMachine(machine);
51
+ * return (
52
+ * <BottomSheet.Steps controller={controller}>
53
+ * <BottomSheet.Step name="details">…</BottomSheet.Step>
54
+ * <BottomSheet.Step name="confirm">…</BottomSheet.Step>
55
+ * </BottomSheet.Steps>
56
+ * );
57
+ * }
58
+ */
59
+ export function BottomSheetSteps<S extends string, C, E extends SheetEvent>({
60
+ className,
61
+ footerGap = BOTTOM_SHEET_FOOTER_GAP,
62
+ ...props
63
+ }: BottomSheetStepsProps<S, C, E>): ReactElement {
64
+ return <StyledSteps className={bottomSheetVariants().steps({ className })} footerGap={footerGap} {...props} />;
65
+ }
66
+ BottomSheetSteps.displayName = "DelacourUI.BottomSheet.Steps";
67
+
68
+ /**
69
+ * One step of a `Steps` body — a key of the machine's `states`.
70
+ *
71
+ * Reads like `Content`: the same gap and top padding, less the gutter `Steps`
72
+ * already carries. The engine positions it across the top of the stack,
73
+ * measures it while it is current, and fades or slides it against its
74
+ * neighbour.
75
+ *
76
+ * @example
77
+ * <BottomSheet.Step name="details">
78
+ * <BottomSheet.Title>Your details</BottomSheet.Title>
79
+ * {fields}
80
+ * </BottomSheet.Step>
81
+ */
82
+ export function BottomSheetStep<S extends string = string>({
83
+ className,
84
+ ...props
85
+ }: BottomSheetStepProps<S>): ReactElement {
86
+ return <StyledStep className={bottomSheetVariants().step({ className })} {...props} />;
87
+ }
88
+ BottomSheetStep.displayName = "DelacourUI.BottomSheet.Step";
@@ -0,0 +1,44 @@
1
+ import { useBottomSheetTextInput } from "@delacour/react-native-bottom-sheet";
2
+ import { type ReactElement, useCallback, useMemo } from "react";
3
+ import type { BlurEvent, FocusEvent, TextInput } from "react-native";
4
+ import { composeRefs } from "../../lib/compose-refs";
5
+ import { Input, type InputProps } from "../input";
6
+
7
+ export type BottomSheetTextInputProps = InputProps;
8
+
9
+ /**
10
+ * An `Input` registered with the sheet.
11
+ *
12
+ * The library's `Input` — variant, size, `Input.Group` and all — with the
13
+ * engine's `useBottomSheetTextInput()` spread onto it, so the keyboard it
14
+ * raises is the sheet's to lift for under any `keyboardScope`, including
15
+ * `registered`. A caller's own `ref`, `onFocus` and `onBlur` still run.
16
+ *
17
+ * A field of your own takes `useBottomSheetInput()` instead and keeps its
18
+ * component; this is the plain case.
19
+ *
20
+ * @example
21
+ * <BottomSheet.TextInput placeholder="Name" value={name} onChangeText={setName} />
22
+ */
23
+ export function BottomSheetTextInput({ ref, onFocus, onBlur, ...props }: BottomSheetTextInputProps): ReactElement {
24
+ const handlers = useBottomSheetTextInput();
25
+ const composed = useMemo(() => composeRefs<TextInput | null>(ref, handlers.ref), [ref, handlers.ref]);
26
+
27
+ const handleFocus = useCallback(
28
+ (event: FocusEvent) => {
29
+ handlers.onFocus();
30
+ onFocus?.(event);
31
+ },
32
+ [handlers.onFocus, onFocus]
33
+ );
34
+ const handleBlur = useCallback(
35
+ (event: BlurEvent) => {
36
+ handlers.onBlur();
37
+ onBlur?.(event);
38
+ },
39
+ [handlers.onBlur, onBlur]
40
+ );
41
+
42
+ return <Input onBlur={handleBlur} onFocus={handleFocus} ref={composed} {...props} />;
43
+ }
44
+ BottomSheetTextInput.displayName = "DelacourUI.BottomSheet.TextInput";
@@ -1,3 +1,4 @@
1
+ import { BottomSheet as Headless } from "@delacour/react-native-bottom-sheet";
1
2
  import type { ReactElement } from "react";
2
3
  import { Text, type TextPresetProps } from "../text";
3
4
  import { bottomSheetVariants } from "./bottom-sheet.variants";
@@ -7,18 +8,21 @@ export type BottomSheetTitleProps = TextPresetProps;
7
8
  /**
8
9
  * The sheet's heading.
9
10
  *
10
- * *Is* a `Text.Header` — it renders the preset and adds layout, never a size or a
11
- * weight of its own, the same trade `Field.Label` makes with `Text.Label`. A
12
- * `text-lg font-semibold` here would be a second definition of that preset which
13
- * could drift from it, and the tests assert the slot carries neither.
14
- *
15
- * The preset already announces itself as a heading, so a screen reader reaches
16
- * the sheet's purpose first with nothing said at the call site.
11
+ * *Is* a `Text.Header` — the engine's `Title asChild` hands it the `nativeID`
12
+ * the panel is labelled by, so focus entering the sheet announces its purpose
13
+ * first, and the preset supplies the type. This adds layout, never a size or a
14
+ * weight of its own, the same trade `Field.Label` makes with `Text.Label`; a
15
+ * `text-lg font-semibold` here would be a second definition of that preset
16
+ * which could drift from it, and the tests assert the slot carries neither.
17
17
  *
18
18
  * @example
19
19
  * <BottomSheet.Title>Keep yourself safe</BottomSheet.Title>
20
20
  */
21
21
  export function BottomSheetTitle({ className, ...props }: BottomSheetTitleProps): ReactElement {
22
- return <Text.Header className={bottomSheetVariants().title({ className })} {...props} />;
22
+ return (
23
+ <Headless.Title asChild>
24
+ <Text.Header className={bottomSheetVariants().title({ className })} {...props} />
25
+ </Headless.Title>
26
+ );
23
27
  }
24
28
  BottomSheetTitle.displayName = "DelacourUI.BottomSheet.Title";
@@ -1,32 +1,27 @@
1
- import { type ReactElement, useCallback } from "react";
1
+ import { BottomSheet as Headless } from "@delacour/react-native-bottom-sheet";
2
+ import type { ReactElement } from "react";
2
3
  import { Slot } from "../../lib/slot";
3
4
  import { Pressable, type PressableProps } from "../pressable";
4
- import { useBottomSheetPart } from "./bottom-sheet.context";
5
5
 
6
6
  export type BottomSheetTriggerProps = PressableProps;
7
7
 
8
8
  /**
9
9
  * The control that opens the sheet.
10
10
  *
11
- * On its own it is a `Pressable`, so `feedback`, `haptic` and the rest are
12
- * inherited rather than restated. It opens through the same state a controlled
13
- * `isOpen` drives, so a sheet can be opened from here and from elsewhere on the
14
- * same screen without the two disagreeing, and a caller's own `onPress` still
15
- * runs after the open.
11
+ * On its own it is this library's `Pressable`, so `feedback`, `haptic` and the
12
+ * rest are inherited rather than restated. It opens through the same state a
13
+ * controlled `isOpen` drives, and a caller's own `onPress` still runs after
14
+ * the open.
16
15
  *
17
- * **`asChild` donates the press rather than wrapping the child**, which is where
18
- * it differs from `Pressable`'s own. `Pressable asChild` keeps its gesture and
19
- * renders the child inside it — correct for a child that is not itself a
20
- * control, and wrong here, because the thing anyone wraps in a trigger is a
21
- * `Button`. Two tap gestures in an ancestor/descendant pair are not
22
- * simultaneous, so Gesture Handler gives the press to the DESCENDANT: the
23
- * button's own detector wins, fires the `onPress` it does not have, and the
24
- * sheet never opens. Nothing announces this — the press simply does nothing.
25
- *
26
- * So the trigger hands its `onPress` down as a prop instead, through `Slot`,
27
- * which chains it ahead of any the child already had. The child keeps its own
28
- * gesture, its own feedback and its own haptic, and there is still no extra view
29
- * in the tree.
16
+ * **`asChild` donates the press rather than wrapping the child**, which is
17
+ * where it differs from `Pressable`'s own. Two tap gestures in an
18
+ * ancestor/descendant pair are not simultaneous: Gesture Handler gives the
19
+ * press to the DESCENDANT, so a `Button` wrapped in a pressable trigger would
20
+ * win the touch, fire the `onPress` it does not have, and the sheet would never
21
+ * open. The engine's `Trigger asChild` hands `onPress` down as a prop instead,
22
+ * chained ahead of any the child already had — the child keeps its own
23
+ * gesture, feedback and haptic, and there is no extra view in the tree. The
24
+ * remaining props reach the child through this library's `Slot`, one layer in.
30
25
  *
31
26
  * The corollary: **the child has to be something that handles `onPress`.** A
32
27
  * `View` or a `Text` takes the prop and ignores it. Wrap a `Button`, a
@@ -49,25 +44,12 @@ export function BottomSheetTrigger({
49
44
  onPress,
50
45
  ...props
51
46
  }: BottomSheetTriggerProps): ReactElement {
52
- const { open } = useBottomSheetPart("BottomSheet.Trigger");
53
-
54
- const handlePress = useCallback(() => {
55
- open();
56
- onPress?.();
57
- }, [onPress, open]);
58
-
59
- if (asChild) {
60
- return (
61
- <Slot onPress={handlePress} {...props}>
62
- {children}
63
- </Slot>
64
- );
65
- }
47
+ const child = asChild ? <Slot {...props}>{children}</Slot> : <Pressable {...props}>{children}</Pressable>;
66
48
 
67
49
  return (
68
- <Pressable onPress={handlePress} {...props}>
69
- {children}
70
- </Pressable>
50
+ <Headless.Trigger asChild onPress={onPress}>
51
+ {child}
52
+ </Headless.Trigger>
71
53
  );
72
54
  }
73
55
  BottomSheetTrigger.displayName = "DelacourUI.BottomSheet.Trigger";