@lt-three/love3 0.0.0 → 0.1.1

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 (377) hide show
  1. package/README.md +85 -1
  2. package/dist/native/analytics/animation.d.ts +4 -0
  3. package/dist/native/analytics/animation.js +6 -0
  4. package/dist/native/analytics/chart.types.d.ts +25 -0
  5. package/dist/native/analytics/chart.types.js +0 -0
  6. package/dist/native/analytics/line-chart.d.ts +4 -0
  7. package/dist/native/analytics/line-chart.ios.d.ts +4 -0
  8. package/dist/native/analytics/line-chart.ios.js +24 -0
  9. package/dist/native/analytics/line-chart.js +33 -0
  10. package/dist/native/analytics/metric-card.d.ts +10 -0
  11. package/dist/native/analytics/metric-card.js +29 -0
  12. package/dist/native/analytics/multi-line-chart.d.ts +18 -0
  13. package/dist/native/analytics/multi-line-chart.js +216 -0
  14. package/dist/native/analytics/pie-chart.d.ts +15 -0
  15. package/dist/native/analytics/pie-chart.ios.d.ts +4 -0
  16. package/dist/native/analytics/pie-chart.ios.js +24 -0
  17. package/dist/native/analytics/pie-chart.js +92 -0
  18. package/dist/native/analytics/single-number.d.ts +19 -0
  19. package/dist/native/analytics/single-number.js +101 -0
  20. package/dist/native/atom/avatar.d.ts +21 -0
  21. package/dist/native/atom/avatar.js +46 -0
  22. package/dist/native/atom/badge.d.ts +28 -0
  23. package/dist/native/atom/badge.js +51 -0
  24. package/dist/native/atom/button.d.ts +46 -0
  25. package/dist/native/atom/button.js +109 -0
  26. package/dist/native/atom/checkbox.d.ts +21 -0
  27. package/dist/native/atom/checkbox.js +47 -0
  28. package/dist/native/atom/colored-value.d.ts +12 -0
  29. package/dist/native/atom/colored-value.js +24 -0
  30. package/dist/native/atom/image.d.ts +21 -0
  31. package/dist/native/atom/image.js +72 -0
  32. package/dist/native/atom/label.d.ts +18 -0
  33. package/dist/native/atom/label.js +33 -0
  34. package/dist/native/atom/link.d.ts +18 -0
  35. package/dist/native/atom/link.js +25 -0
  36. package/dist/native/atom/readout.d.ts +22 -0
  37. package/dist/native/atom/readout.js +39 -0
  38. package/dist/native/atom/search-input.d.ts +12 -0
  39. package/dist/native/atom/search-input.js +36 -0
  40. package/dist/native/atom/select.d.ts +54 -0
  41. package/dist/native/atom/select.js +200 -0
  42. package/dist/native/atom/separator.d.ts +12 -0
  43. package/dist/native/atom/separator.js +16 -0
  44. package/dist/native/atom/skeleton.d.ts +12 -0
  45. package/dist/native/atom/skeleton.js +39 -0
  46. package/dist/native/atom/slider.d.ts +32 -0
  47. package/dist/native/atom/slider.js +75 -0
  48. package/dist/native/atom/spinner.d.ts +15 -0
  49. package/dist/native/atom/spinner.js +25 -0
  50. package/dist/native/atom/switch.d.ts +18 -0
  51. package/dist/native/atom/switch.js +52 -0
  52. package/dist/native/atom/symbol.d.ts +16 -0
  53. package/dist/native/atom/symbol.js +38 -0
  54. package/dist/native/atom/symbol.types.d.ts +25 -0
  55. package/dist/native/atom/symbol.types.js +49 -0
  56. package/dist/native/atom/text-field.d.ts +49 -0
  57. package/dist/native/atom/text-field.js +56 -0
  58. package/dist/native/atom/text.d.ts +2 -0
  59. package/dist/native/atom/text.js +3 -0
  60. package/dist/native/atom/theme-toggle.d.ts +21 -0
  61. package/dist/native/atom/theme-toggle.js +36 -0
  62. package/dist/native/atom/timezone-select.d.ts +16 -0
  63. package/dist/native/atom/timezone-select.js +28 -0
  64. package/dist/native/atom/typography.d.ts +13 -0
  65. package/dist/native/atom/typography.js +28 -0
  66. package/dist/native/base/button.d.ts +61 -0
  67. package/dist/native/base/button.js +92 -0
  68. package/dist/native/base/form.d.ts +72 -0
  69. package/dist/native/base/form.js +113 -0
  70. package/dist/native/base/glass-card.d.ts +15 -0
  71. package/dist/native/base/glass-card.js +38 -0
  72. package/dist/native/base/input.d.ts +29 -0
  73. package/dist/native/base/input.js +27 -0
  74. package/dist/native/base/sheet.d.ts +71 -0
  75. package/dist/native/base/sheet.js +187 -0
  76. package/dist/native/base/text.d.ts +14 -0
  77. package/dist/native/base/text.js +53 -0
  78. package/dist/native/form/checkbox.d.ts +13 -0
  79. package/dist/native/form/checkbox.js +55 -0
  80. package/dist/native/form/date-picker.d.ts +23 -0
  81. package/dist/native/form/date-picker.js +119 -0
  82. package/dist/native/form/form.d.ts +22 -0
  83. package/dist/native/form/form.js +44 -0
  84. package/dist/native/form/radio-group.d.ts +23 -0
  85. package/dist/native/form/radio-group.js +88 -0
  86. package/dist/native/form/select.d.ts +13 -0
  87. package/dist/native/form/select.js +45 -0
  88. package/dist/native/form/slider.d.ts +14 -0
  89. package/dist/native/form/slider.js +42 -0
  90. package/dist/native/form/switch.d.ts +9 -0
  91. package/dist/native/form/switch.js +59 -0
  92. package/dist/native/form/text-area.d.ts +11 -0
  93. package/dist/native/form/text-area.js +50 -0
  94. package/dist/native/form/text-input.d.ts +18 -0
  95. package/dist/native/form/text-input.js +90 -0
  96. package/dist/native/index.d.ts +1 -0
  97. package/dist/native/index.js +0 -0
  98. package/dist/native/layout/accordion.d.ts +25 -0
  99. package/dist/native/layout/accordion.js +54 -0
  100. package/dist/native/layout/card.d.ts +47 -0
  101. package/dist/native/layout/card.js +57 -0
  102. package/dist/native/layout/description.d.ts +16 -0
  103. package/dist/native/layout/description.js +32 -0
  104. package/dist/native/layout/error.d.ts +21 -0
  105. package/dist/native/layout/error.js +44 -0
  106. package/dist/native/layout/information.d.ts +25 -0
  107. package/dist/native/layout/information.js +35 -0
  108. package/dist/native/layout/locked.d.ts +38 -0
  109. package/dist/native/layout/locked.js +94 -0
  110. package/dist/native/layout/modal.d.ts +25 -0
  111. package/dist/native/layout/modal.js +93 -0
  112. package/dist/native/layout/not-found.d.ts +17 -0
  113. package/dist/native/layout/not-found.js +30 -0
  114. package/dist/native/layout/page-frame.d.ts +23 -0
  115. package/dist/native/layout/page-frame.js +46 -0
  116. package/dist/native/layout/panel.d.ts +18 -0
  117. package/dist/native/layout/panel.js +23 -0
  118. package/dist/native/layout/reorderable-list.d.ts +42 -0
  119. package/dist/native/layout/reorderable-list.js +52 -0
  120. package/dist/native/layout/sheet.d.ts +30 -0
  121. package/dist/native/layout/sheet.js +46 -0
  122. package/dist/native/layout/simple-dialog.d.ts +16 -0
  123. package/dist/native/layout/simple-dialog.js +20 -0
  124. package/dist/native/layout/simple-table.d.ts +50 -0
  125. package/dist/native/layout/simple-table.js +75 -0
  126. package/dist/native/layout/tab-bar.d.ts +33 -0
  127. package/dist/native/layout/tab-bar.js +48 -0
  128. package/dist/native/layout/tabs.d.ts +28 -0
  129. package/dist/native/layout/tabs.js +54 -0
  130. package/dist/native/layout/tuning-panel.d.ts +24 -0
  131. package/dist/native/layout/tuning-panel.js +246 -0
  132. package/dist/native/lib/autocomplete.d.ts +7 -0
  133. package/dist/native/lib/autocomplete.js +34 -0
  134. package/dist/native/lib/breakpoints.d.ts +14 -0
  135. package/dist/native/lib/breakpoints.js +17 -0
  136. package/dist/native/lib/chart-palette.d.ts +8 -0
  137. package/dist/native/lib/chart-palette.js +20 -0
  138. package/dist/native/lib/confirm.d.ts +48 -0
  139. package/dist/native/lib/confirm.js +69 -0
  140. package/dist/native/lib/control.d.ts +24 -0
  141. package/dist/native/lib/control.js +0 -0
  142. package/dist/native/lib/external-store.d.ts +16 -0
  143. package/dist/native/lib/external-store.js +30 -0
  144. package/dist/native/lib/keyboard.d.ts +15 -0
  145. package/dist/native/lib/keyboard.js +24 -0
  146. package/dist/native/lib/labels.d.ts +15 -0
  147. package/dist/native/lib/labels.js +17 -0
  148. package/dist/native/lib/loading.d.ts +10 -0
  149. package/dist/native/lib/loading.js +15 -0
  150. package/dist/native/lib/network.d.ts +11 -0
  151. package/dist/native/lib/network.js +20 -0
  152. package/dist/native/lib/scheme.d.ts +18 -0
  153. package/dist/native/lib/scheme.js +22 -0
  154. package/dist/native/lib/snackbar.d.ts +45 -0
  155. package/dist/native/lib/snackbar.js +59 -0
  156. package/dist/native/lib/theme.d.ts +34 -0
  157. package/dist/native/lib/theme.js +53 -0
  158. package/dist/native/lib/timezone.d.ts +26 -0
  159. package/dist/native/lib/timezone.js +95 -0
  160. package/dist/native/lib/token-color.d.ts +5 -0
  161. package/dist/native/lib/token-color.js +13 -0
  162. package/dist/native/lib/token-color.web.d.ts +4 -0
  163. package/dist/native/lib/token-color.web.js +7 -0
  164. package/dist/native/lib/tuning-context.d.ts +9 -0
  165. package/dist/native/lib/tuning-context.js +7 -0
  166. package/dist/native/lib/tuning.d.ts +24 -0
  167. package/dist/native/lib/tuning.js +42 -0
  168. package/dist/native/lib/typography.d.ts +10 -0
  169. package/dist/native/lib/typography.js +11 -0
  170. package/dist/native/lib/utils.d.ts +11 -0
  171. package/dist/native/lib/utils.js +21 -0
  172. package/dist/native/once/confirm.d.ts +7 -0
  173. package/dist/native/once/confirm.js +60 -0
  174. package/dist/native/once/error-boundary.d.ts +28 -0
  175. package/dist/native/once/error-boundary.js +55 -0
  176. package/dist/native/once/loading-lock.d.ts +8 -0
  177. package/dist/native/once/loading-lock.js +28 -0
  178. package/dist/native/once/offline-banner.d.ts +15 -0
  179. package/dist/native/once/offline-banner.js +35 -0
  180. package/dist/native/once/snackbar.d.ts +17 -0
  181. package/dist/native/once/snackbar.js +106 -0
  182. package/dist/native/styles.css +46 -0
  183. package/dist/shared/analytics.d.ts +71 -0
  184. package/dist/shared/analytics.js +0 -0
  185. package/dist/shared/button.d.ts +7 -0
  186. package/dist/shared/button.js +23 -0
  187. package/dist/shared/form.d.ts +45 -0
  188. package/dist/shared/form.js +46 -0
  189. package/dist/shared/index.d.ts +3 -0
  190. package/dist/shared/index.js +3 -0
  191. package/dist/tokens/contrast-pairs.d.ts +30 -0
  192. package/dist/tokens/contrast-pairs.js +404 -0
  193. package/dist/tokens/index.d.ts +6 -0
  194. package/dist/tokens/index.js +10 -0
  195. package/dist/tokens/styles.gen.css +250 -0
  196. package/dist/tokens/tokens.gen.d.ts +141 -0
  197. package/dist/tokens/tokens.gen.js +206 -0
  198. package/dist/tuning/catalog.d.ts +27 -0
  199. package/dist/tuning/catalog.gen.d.ts +4 -0
  200. package/dist/tuning/catalog.gen.js +397 -0
  201. package/dist/tuning/catalog.js +128 -0
  202. package/dist/tuning/color.d.ts +20 -0
  203. package/dist/tuning/color.js +80 -0
  204. package/dist/tuning/css.d.ts +35 -0
  205. package/dist/tuning/css.js +147 -0
  206. package/dist/tuning/index.d.ts +8 -0
  207. package/dist/tuning/index.js +9 -0
  208. package/dist/tuning/model.d.ts +33 -0
  209. package/dist/tuning/model.js +154 -0
  210. package/dist/tuning/native.d.ts +35 -0
  211. package/dist/tuning/native.js +80 -0
  212. package/dist/tuning/schema.d.ts +69 -0
  213. package/dist/tuning/schema.js +247 -0
  214. package/dist/tuning/types.d.ts +75 -0
  215. package/dist/tuning/types.js +39 -0
  216. package/dist/web/analytics/line-chart.d.ts +20 -0
  217. package/dist/web/analytics/line-chart.js +28 -0
  218. package/dist/web/analytics/metric-card.d.ts +18 -0
  219. package/dist/web/analytics/metric-card.js +40 -0
  220. package/dist/web/analytics/multi-line-chart.d.ts +39 -0
  221. package/dist/web/analytics/multi-line-chart.js +345 -0
  222. package/dist/web/atom/avatar.d.ts +11 -0
  223. package/dist/web/atom/avatar.js +24 -0
  224. package/dist/web/atom/badge.d.ts +2 -0
  225. package/dist/web/atom/badge.js +3 -0
  226. package/dist/web/atom/button.d.ts +23 -0
  227. package/dist/web/atom/button.js +35 -0
  228. package/dist/web/atom/checkbox.d.ts +19 -0
  229. package/dist/web/atom/checkbox.js +33 -0
  230. package/dist/web/atom/colored-value.d.ts +13 -0
  231. package/dist/web/atom/colored-value.js +24 -0
  232. package/dist/web/atom/help.d.ts +10 -0
  233. package/dist/web/atom/help.js +18 -0
  234. package/dist/web/atom/label.d.ts +2 -0
  235. package/dist/web/atom/label.js +3 -0
  236. package/dist/web/atom/segmented-control.d.ts +39 -0
  237. package/dist/web/atom/segmented-control.js +42 -0
  238. package/dist/web/atom/select.d.ts +43 -0
  239. package/dist/web/atom/select.js +93 -0
  240. package/dist/web/atom/separator.d.ts +2 -0
  241. package/dist/web/atom/separator.js +3 -0
  242. package/dist/web/atom/skeleton.d.ts +2 -0
  243. package/dist/web/atom/skeleton.js +3 -0
  244. package/dist/web/atom/slider.d.ts +33 -0
  245. package/dist/web/atom/slider.js +70 -0
  246. package/dist/web/atom/spinner.d.ts +8 -0
  247. package/dist/web/atom/spinner.js +14 -0
  248. package/dist/web/atom/switch.d.ts +11 -0
  249. package/dist/web/atom/switch.js +10 -0
  250. package/dist/web/atom/text-area.d.ts +23 -0
  251. package/dist/web/atom/text-area.js +27 -0
  252. package/dist/web/atom/text-field.d.ts +18 -0
  253. package/dist/web/atom/text-field.js +22 -0
  254. package/dist/web/atom/toggle-chip.d.ts +22 -0
  255. package/dist/web/atom/toggle-chip.js +28 -0
  256. package/dist/web/atom/tooltip.d.ts +23 -0
  257. package/dist/web/atom/tooltip.js +26 -0
  258. package/dist/web/atom/typography.d.ts +6 -0
  259. package/dist/web/atom/typography.js +23 -0
  260. package/dist/web/base/accordion.d.ts +9 -0
  261. package/dist/web/base/accordion.js +44 -0
  262. package/dist/web/base/alert.d.ts +11 -0
  263. package/dist/web/base/alert.js +37 -0
  264. package/dist/web/base/avatar.d.ts +8 -0
  265. package/dist/web/base/avatar.js +29 -0
  266. package/dist/web/base/badge.d.ts +12 -0
  267. package/dist/web/base/badge.js +26 -0
  268. package/dist/web/base/breadcrumb.d.ts +16 -0
  269. package/dist/web/base/breadcrumb.js +72 -0
  270. package/dist/web/base/button.d.ts +12 -0
  271. package/dist/web/base/button.js +47 -0
  272. package/dist/web/base/card.d.ts +19 -0
  273. package/dist/web/base/card.js +74 -0
  274. package/dist/web/base/checkbox.d.ts +6 -0
  275. package/dist/web/base/checkbox.js +21 -0
  276. package/dist/web/base/dialog.d.ts +20 -0
  277. package/dist/web/base/dialog.js +92 -0
  278. package/dist/web/base/dropdown-menu.d.ts +29 -0
  279. package/dist/web/base/dropdown-menu.js +125 -0
  280. package/dist/web/base/field.d.ts +27 -0
  281. package/dist/web/base/field.js +118 -0
  282. package/dist/web/base/form.d.ts +38 -0
  283. package/dist/web/base/form.js +110 -0
  284. package/dist/web/base/input.d.ts +9 -0
  285. package/dist/web/base/input.js +23 -0
  286. package/dist/web/base/label.d.ts +6 -0
  287. package/dist/web/base/label.js +15 -0
  288. package/dist/web/base/pagination.d.ts +34 -0
  289. package/dist/web/base/pagination.js +90 -0
  290. package/dist/web/base/popover.d.ts +11 -0
  291. package/dist/web/base/popover.js +37 -0
  292. package/dist/web/base/radio-group.d.ts +7 -0
  293. package/dist/web/base/radio-group.js +27 -0
  294. package/dist/web/base/scroll-area.d.ts +10 -0
  295. package/dist/web/base/scroll-area.js +41 -0
  296. package/dist/web/base/select.d.ts +17 -0
  297. package/dist/web/base/select.js +96 -0
  298. package/dist/web/base/separator.d.ts +6 -0
  299. package/dist/web/base/separator.js +17 -0
  300. package/dist/web/base/sheet.d.ts +19 -0
  301. package/dist/web/base/sheet.js +88 -0
  302. package/dist/web/base/skeleton.d.ts +5 -0
  303. package/dist/web/base/skeleton.js +14 -0
  304. package/dist/web/base/slider.d.ts +9 -0
  305. package/dist/web/base/slider.js +39 -0
  306. package/dist/web/base/sonner.d.ts +9 -0
  307. package/dist/web/base/sonner.js +25 -0
  308. package/dist/web/base/spinner.d.ts +5 -0
  309. package/dist/web/base/spinner.js +17 -0
  310. package/dist/web/base/switch.d.ts +6 -0
  311. package/dist/web/base/switch.js +19 -0
  312. package/dist/web/base/table.d.ts +14 -0
  313. package/dist/web/base/table.js +68 -0
  314. package/dist/web/base/tabs.d.ts +9 -0
  315. package/dist/web/base/tabs.js +36 -0
  316. package/dist/web/base/textarea.d.ts +9 -0
  317. package/dist/web/base/textarea.js +23 -0
  318. package/dist/web/base/tooltip.d.ts +9 -0
  319. package/dist/web/base/tooltip.js +36 -0
  320. package/dist/web/form/checkbox.d.ts +35 -0
  321. package/dist/web/form/checkbox.js +91 -0
  322. package/dist/web/form/radio-group.d.ts +24 -0
  323. package/dist/web/form/radio-group.js +75 -0
  324. package/dist/web/form/select.d.ts +16 -0
  325. package/dist/web/form/select.js +44 -0
  326. package/dist/web/form/slider.d.ts +19 -0
  327. package/dist/web/form/slider.js +51 -0
  328. package/dist/web/form/switch.d.ts +11 -0
  329. package/dist/web/form/switch.js +50 -0
  330. package/dist/web/form/text-area.d.ts +10 -0
  331. package/dist/web/form/text-area.js +31 -0
  332. package/dist/web/form/text-input.d.ts +10 -0
  333. package/dist/web/form/text-input.js +42 -0
  334. package/dist/web/index.d.ts +1 -0
  335. package/dist/web/index.js +0 -0
  336. package/dist/web/layout/accordion.d.ts +26 -0
  337. package/dist/web/layout/accordion.js +29 -0
  338. package/dist/web/layout/alert-modal.d.ts +41 -0
  339. package/dist/web/layout/alert-modal.js +71 -0
  340. package/dist/web/layout/card.d.ts +17 -0
  341. package/dist/web/layout/card.js +35 -0
  342. package/dist/web/layout/description.d.ts +12 -0
  343. package/dist/web/layout/description.js +20 -0
  344. package/dist/web/layout/information.d.ts +36 -0
  345. package/dist/web/layout/information.js +53 -0
  346. package/dist/web/layout/modal.d.ts +16 -0
  347. package/dist/web/layout/modal.js +37 -0
  348. package/dist/web/layout/page-frame.d.ts +37 -0
  349. package/dist/web/layout/page-frame.js +79 -0
  350. package/dist/web/layout/scroll-area.d.ts +10 -0
  351. package/dist/web/layout/scroll-area.js +13 -0
  352. package/dist/web/layout/sheet.d.ts +32 -0
  353. package/dist/web/layout/sheet.js +68 -0
  354. package/dist/web/layout/simple-dialog.d.ts +11 -0
  355. package/dist/web/layout/simple-dialog.js +24 -0
  356. package/dist/web/layout/simple-table.d.ts +49 -0
  357. package/dist/web/layout/simple-table.js +58 -0
  358. package/dist/web/layout/tabs.d.ts +26 -0
  359. package/dist/web/layout/tabs.js +42 -0
  360. package/dist/web/layout/titled-modal.d.ts +32 -0
  361. package/dist/web/layout/titled-modal.js +58 -0
  362. package/dist/web/lib/css-vars.d.ts +14 -0
  363. package/dist/web/lib/css-vars.js +18 -0
  364. package/dist/web/lib/dialog.d.ts +13 -0
  365. package/dist/web/lib/dialog.js +0 -0
  366. package/dist/web/lib/form.d.ts +2 -0
  367. package/dist/web/lib/form.js +3 -0
  368. package/dist/web/lib/labels.d.ts +27 -0
  369. package/dist/web/lib/labels.js +29 -0
  370. package/dist/web/lib/modal-open-focus.d.ts +17 -0
  371. package/dist/web/lib/modal-open-focus.js +44 -0
  372. package/dist/web/lib/restore-focus.d.ts +12 -0
  373. package/dist/web/lib/restore-focus.js +32 -0
  374. package/dist/web/lib/utils.d.ts +4 -0
  375. package/dist/web/lib/utils.js +10 -0
  376. package/dist/web/styles.css +162 -0
  377. package/package.json +203 -4
@@ -0,0 +1,72 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/native/base/form.d.ts
3
+ /**
4
+ * The set of chrome ids and the errors. Use it inside `FormItem`. It does not crash outside a field (controlled mode) either.
5
+ *
6
+ * **The errors to display are decided in one place here** (the field's errors + the `errors` of `FormItem`). The `FormLabel` color, the `FormMessage` text and
7
+ * the `FormControl` `aria-invalid` / `aria-describedby` all read from it, so mismatches such as a message being shown without `aria-invalid` cannot occur.
8
+ */
9
+ export declare function useFormField(): {
10
+ id: string;
11
+ formItemId: string;
12
+ formLabelId: string;
13
+ formDescriptionId: string;
14
+ formMessageId: string;
15
+ errors: readonly unknown[];
16
+ };
17
+ export declare function FormItem({ children, className, errors }: {
18
+ children: ReactNode;
19
+ className?: string;
20
+ /**
21
+ * Errors **added to** the field's (TanStack Form) errors. Use it outside a field, or inside a field when you want to show an error
22
+ * owned by the input component itself (such as "not readable as a number" on a numeric field). It affects the input's `aria-invalid` and `aria-describedby`,
23
+ * the label color and the `FormMessage` display alike. Passing an empty array does not hide the field's errors.
24
+ */
25
+ errors?: readonly unknown[];
26
+ }): import("react").JSX.Element;
27
+ export declare function FormLabel({ children, required, helpText, className }: {
28
+ children: ReactNode;
29
+ required?: boolean;
30
+ helpText?: ReactNode;
31
+ className?: string;
32
+ }): import("react").JSX.Element;
33
+ /** The props `FormControl` passes to the input component (the same shape as the component's `ControlA11yProps`). */
34
+ export type FormControlProps = {
35
+ id: string;
36
+ "aria-labelledby": string | undefined;
37
+ "aria-describedby": string | undefined;
38
+ "aria-invalid": boolean;
39
+ };
40
+ /**
41
+ * Passes `id`, `aria-labelledby`, `aria-describedby` and `aria-invalid` to the input component. The child is received as a function.
42
+ *
43
+ * ```tsx
44
+ * <FormControl labelled={Boolean(label)} described={Boolean(description)}>
45
+ * {control => <TextField {...control} value={value} onChangeText={setValue} />}
46
+ * </FormControl>
47
+ * ```
48
+ *
49
+ * - `labelled`: when a `FormLabel` is placed. Makes the label text the input's name (`aria-labelledby`). When none is placed,
50
+ * it is not set so it never points to a nonexistent id. Inputs that carry their own label on the right (checkbox, radio) do not set it, because their own text is the name
51
+ * - `described`: when a `FormDescription` is placed. Adds the description to `aria-describedby`. When there is an error, the error text is added too
52
+ * - `id`: defaults to `formItemId` (when a field has one input). **When a field has several inputs** (radio options),
53
+ * pass one per option so the same id does not collide
54
+ */
55
+ export declare function FormControl({ children, id, labelled, described }: {
56
+ children: (control: FormControlProps) => ReactNode;
57
+ id?: string;
58
+ labelled?: boolean;
59
+ described?: boolean;
60
+ }): ReactNode;
61
+ export declare function FormDescription({ children, className }: {
62
+ children: ReactNode;
63
+ className?: string;
64
+ }): import("react").JSX.Element;
65
+ /**
66
+ * The error text. The only errors shown are the single set from `useFormField` (add more via the `errors` of `FormItem`).
67
+ * It does not have the web `FormMessage`'s "errors shown only in this message" (`errors`), because changing only the text would disagree with `aria-invalid`.
68
+ */
69
+ export declare function FormMessage({ className }: {
70
+ className?: string;
71
+ }): import("react").JSX.Element | null;
72
+ //#endregion
@@ -0,0 +1,113 @@
1
+ import { useOptionalFieldContext } from "../../shared/form.js";
2
+ import { cn } from "../lib/utils.js";
3
+ import { Text as Text$1 } from "./text.js";
4
+ import { createContext, useContext, useId } from "react";
5
+ import { View } from "react-native";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+
8
+ //#region src/native/base/form.tsx
9
+ const FormItemContext = createContext({ id: "" });
10
+ /**
11
+ * The set of chrome ids and the errors. Use it inside `FormItem`. It does not crash outside a field (controlled mode) either.
12
+ *
13
+ * **The errors to display are decided in one place here** (the field's errors + the `errors` of `FormItem`). The `FormLabel` color, the `FormMessage` text and
14
+ * the `FormControl` `aria-invalid` / `aria-describedby` all read from it, so mismatches such as a message being shown without `aria-invalid` cannot occur.
15
+ */
16
+ function useFormField() {
17
+ const itemContext = useContext(FormItemContext);
18
+ const errors = [...useOptionalFieldContext()?.state.meta.errors ?? [], ...itemContext.extraErrors ?? []];
19
+ const { id } = itemContext;
20
+ return {
21
+ id,
22
+ formItemId: `${id}-form-item`,
23
+ formLabelId: `${id}-form-item-label`,
24
+ formDescriptionId: `${id}-form-item-description`,
25
+ formMessageId: `${id}-form-item-message`,
26
+ errors
27
+ };
28
+ }
29
+ function FormItem({ children, className, errors }) {
30
+ const id = useId();
31
+ return /* @__PURE__ */ jsx(FormItemContext.Provider, {
32
+ value: {
33
+ id,
34
+ extraErrors: errors
35
+ },
36
+ children: /* @__PURE__ */ jsx(View, {
37
+ className: cn("gap-2", className),
38
+ children
39
+ })
40
+ });
41
+ }
42
+ function FormLabel({ children, required, helpText, className }) {
43
+ const { errors, formLabelId } = useFormField();
44
+ return /* @__PURE__ */ jsxs(View, {
45
+ className: "flex-row items-center gap-1",
46
+ children: [
47
+ /* @__PURE__ */ jsx(Text$1, {
48
+ id: formLabelId,
49
+ className: cn("text-xs font-semibold opacity-80", errors.length > 0 && "text-destructive opacity-100", className),
50
+ children
51
+ }),
52
+ required ? /* @__PURE__ */ jsx(Text$1, {
53
+ className: "text-destructive text-sm",
54
+ children: "*"
55
+ }) : null,
56
+ helpText ? /* @__PURE__ */ jsx(Text$1, {
57
+ className: "text-muted-foreground text-xs font-normal",
58
+ children: helpText
59
+ }) : null
60
+ ]
61
+ });
62
+ }
63
+ /**
64
+ * Passes `id`, `aria-labelledby`, `aria-describedby` and `aria-invalid` to the input component. The child is received as a function.
65
+ *
66
+ * ```tsx
67
+ * <FormControl labelled={Boolean(label)} described={Boolean(description)}>
68
+ * {control => <TextField {...control} value={value} onChangeText={setValue} />}
69
+ * </FormControl>
70
+ * ```
71
+ *
72
+ * - `labelled`: when a `FormLabel` is placed. Makes the label text the input's name (`aria-labelledby`). When none is placed,
73
+ * it is not set so it never points to a nonexistent id. Inputs that carry their own label on the right (checkbox, radio) do not set it, because their own text is the name
74
+ * - `described`: when a `FormDescription` is placed. Adds the description to `aria-describedby`. When there is an error, the error text is added too
75
+ * - `id`: defaults to `formItemId` (when a field has one input). **When a field has several inputs** (radio options),
76
+ * pass one per option so the same id does not collide
77
+ */
78
+ function FormControl({ children, id, labelled = false, described = false }) {
79
+ const { errors, formItemId, formLabelId, formDescriptionId, formMessageId } = useFormField();
80
+ const invalid = errors.length > 0;
81
+ const describedBy = [described ? formDescriptionId : void 0, invalid ? formMessageId : void 0].filter(Boolean).join(" ");
82
+ return children({
83
+ id: id ?? formItemId,
84
+ "aria-labelledby": labelled ? formLabelId : void 0,
85
+ "aria-describedby": describedBy === "" ? void 0 : describedBy,
86
+ "aria-invalid": invalid
87
+ });
88
+ }
89
+ function FormDescription({ children, className }) {
90
+ const { formDescriptionId } = useFormField();
91
+ return /* @__PURE__ */ jsx(Text$1, {
92
+ id: formDescriptionId,
93
+ className: cn("text-muted-foreground text-sm", className),
94
+ children
95
+ });
96
+ }
97
+ /**
98
+ * The error text. The only errors shown are the single set from `useFormField` (add more via the `errors` of `FormItem`).
99
+ * It does not have the web `FormMessage`'s "errors shown only in this message" (`errors`), because changing only the text would disagree with `aria-invalid`.
100
+ */
101
+ function FormMessage({ className }) {
102
+ const { errors: list, formMessageId } = useFormField();
103
+ if (list.length === 0) return null;
104
+ return /* @__PURE__ */ jsx(Text$1, {
105
+ id: formMessageId,
106
+ role: "alert",
107
+ className: cn("text-destructive text-sm", className),
108
+ children: list.map((error) => String(error)).join("\n")
109
+ });
110
+ }
111
+
112
+ //#endregion
113
+ export { FormControl, FormDescription, FormItem, FormLabel, FormMessage, useFormField };
@@ -0,0 +1,15 @@
1
+ import { ReactNode } from "react";
2
+ import { ViewStyle } from "react-native";
3
+ //#region src/native/base/glass-card.d.ts
4
+ type GlassCardProps = {
5
+ children: ReactNode;
6
+ style?: ViewStyle;
7
+ };
8
+ /**
9
+ * A Liquid Glass card surface. On iOS 26 and later it uses `GlassView` (`UIGlassEffect`)
10
+ * for a glass look that blurs what is behind it; on unsupported environments (below iOS 26, Android, web) it falls back to a plain View with a border.
11
+ * The fallback border uses the token's line color (`--line`).
12
+ */
13
+ declare function GlassCard({ children, style }: GlassCardProps): import("react").JSX.Element;
14
+ //#endregion
15
+ export { GlassCard, type GlassCardProps };
@@ -0,0 +1,38 @@
1
+ import { useTokenColor } from "../lib/token-color.js";
2
+ import { View } from "react-native";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { GlassView, isLiquidGlassAvailable } from "expo-glass-effect";
5
+
6
+ //#region src/native/base/glass-card.tsx
7
+ const BASE = {
8
+ borderRadius: 10,
9
+ padding: 16,
10
+ overflow: "hidden"
11
+ };
12
+ /**
13
+ * A Liquid Glass card surface. On iOS 26 and later it uses `GlassView` (`UIGlassEffect`)
14
+ * for a glass look that blurs what is behind it; on unsupported environments (below iOS 26, Android, web) it falls back to a plain View with a border.
15
+ * The fallback border uses the token's line color (`--line`).
16
+ */
17
+ function GlassCard({ children, style }) {
18
+ const line = useTokenColor("--line");
19
+ if (isLiquidGlassAvailable()) return /* @__PURE__ */ jsx(GlassView, {
20
+ glassEffectStyle: "regular",
21
+ style: [BASE, style],
22
+ children
23
+ });
24
+ return /* @__PURE__ */ jsx(View, {
25
+ style: [
26
+ BASE,
27
+ {
28
+ borderWidth: 1,
29
+ borderColor: line
30
+ },
31
+ style
32
+ ],
33
+ children
34
+ });
35
+ }
36
+
37
+ //#endregion
38
+ export { GlassCard };
@@ -0,0 +1,29 @@
1
+ import { KeyboardTypeOptions } from "react-native";
2
+ //#region src/native/base/input.d.ts
3
+ type InputProps = {
4
+ placeholder?: string;
5
+ /** The value to display. Pass it when syncing with external state (internally it is driven uncontrolled). */
6
+ value?: string;
7
+ onChangeText?: (text: string) => void;
8
+ secureTextEntry?: boolean;
9
+ editable?: boolean;
10
+ autoFocus?: boolean;
11
+ autoCapitalize?: "none" | "sentences" | "words" | "characters";
12
+ keyboardType?: KeyboardTypeOptions;
13
+ returnKeyType?: "done" | "go" | "next" | "search" | "send";
14
+ onSubmitEditing?: (text: string) => void;
15
+ };
16
+ /**
17
+ * The native text input (the OS control layer). Renders SwiftUI's `TextField` / `SecureField` on iOS
18
+ * and Jetpack Compose's `TextField` on Android (via `@expo/ui` universal).
19
+ *
20
+ * The **OS-native base layer** counterpart of `atom/text-field` (an RN `TextInput`, an input frame painted with tokens).
21
+ * It **cannot be painted with tokens**, so for inputs that should look the same as the web use `atom/text-field` (or `form/text-input` in a form).
22
+ *
23
+ * The universal `value` is an `ObservableState` type, so to handle a plain string it is driven by
24
+ * `defaultValue` (uncontrolled) + `onChangeText`. External state is
25
+ * synced through `onChangeText`.
26
+ */
27
+ declare function Input({ value, ...props }: InputProps): import("react").JSX.Element;
28
+ //#endregion
29
+ export { Input, type InputProps };
@@ -0,0 +1,27 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Host, TextInput } from "@expo/ui";
3
+
4
+ //#region src/native/base/input.tsx
5
+ /**
6
+ * The native text input (the OS control layer). Renders SwiftUI's `TextField` / `SecureField` on iOS
7
+ * and Jetpack Compose's `TextField` on Android (via `@expo/ui` universal).
8
+ *
9
+ * The **OS-native base layer** counterpart of `atom/text-field` (an RN `TextInput`, an input frame painted with tokens).
10
+ * It **cannot be painted with tokens**, so for inputs that should look the same as the web use `atom/text-field` (or `form/text-input` in a form).
11
+ *
12
+ * The universal `value` is an `ObservableState` type, so to handle a plain string it is driven by
13
+ * `defaultValue` (uncontrolled) + `onChangeText`. External state is
14
+ * synced through `onChangeText`.
15
+ */
16
+ function Input({ value, ...props }) {
17
+ return /* @__PURE__ */ jsx(Host, {
18
+ style: { minHeight: 44 },
19
+ children: /* @__PURE__ */ jsx(TextInput, {
20
+ defaultValue: value,
21
+ ...props
22
+ })
23
+ });
24
+ }
25
+
26
+ //#endregion
27
+ export { Input };
@@ -0,0 +1,71 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/native/base/sheet.d.ts
3
+ export type SheetShellProps = {
4
+ open: boolean;
5
+ onOpenChange: (open: boolean) => void;
6
+ /** Whether tapping the backdrop closes it (default true). */
7
+ dismissOnBackdropPress?: boolean;
8
+ /** The maximum height as a ratio of the screen height (default 0.85). */
9
+ maxHeightRatio?: number;
10
+ /**
11
+ * Called **exactly once** after it has fully closed and the `Modal` has been dismissed (not called if it was never opened, nor on every re-render).
12
+ * **Open the next sheet from here.**
13
+ * If another sheet is opened right after setting `open` to false, two `Modal`s coexist for the duration of the
14
+ * closing animation, and iOS does not present the later one (it looks like nothing happens).
15
+ *
16
+ * **A confirm dialog (`once/confirm`) is also a `Modal`.** When showing a confirmation from inside a sheet,
17
+ * use this for the same reason.
18
+ */
19
+ onClosed?: () => void;
20
+ /**
21
+ * The `id` of the heading that names the dialog (the same value as `SheetHeader`'s `titleId`). Practically required when there is no `aria-label`
22
+ * (a dialog without a name is conveyed to assistive technology only as "dialog").
23
+ */
24
+ "aria-labelledby"?: string;
25
+ /** The dialog's name when the heading is not a string or no heading is shown. */
26
+ "aria-label"?: string;
27
+ /** The `id` of the supplementary text (the same value as `SheetHeader`'s `descriptionId`). */
28
+ "aria-describedby"?: string;
29
+ children: ReactNode;
30
+ };
31
+ /**
32
+ * Do not use `Modal`'s `animationType="slide"`. It slides up **together with the scrim**,
33
+ * so the dark overlay appears to grow from the bottom and looks cheap. Here the scrim's fade and the panel's
34
+ * slide are driven by separate curves.
35
+ *
36
+ * The dialog role (`role="dialog"`, `aria-modal`), focus trapping and Esc (`onRequestClose`) are provided by `Modal`
37
+ * (react-native-web's `Modal` emits the role and the trap. It has no name of its own, so pass `aria-label(ledby)`).
38
+ */
39
+ export declare function SheetShell({ open, onOpenChange, dismissOnBackdropPress, maxHeightRatio, onClosed, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, children }: SheetShellProps): import("react").JSX.Element | null;
40
+ export type SheetHeaderProps = {
41
+ title?: ReactNode;
42
+ description?: ReactNode;
43
+ /** Screen reader name of the close button (the default is the Japanese "close" label). */
44
+ closeLabel?: string;
45
+ onClose: () => void;
46
+ /** The `id` of the heading. Pass the same value to `SheetShell`'s `aria-labelledby` and the heading becomes the dialog's name. */
47
+ titleId?: string;
48
+ /** The `id` of the supplementary text. Pass the same value to `SheetShell`'s `aria-describedby`. */
49
+ descriptionId?: string;
50
+ };
51
+ /** The grab cue (grabber), the heading and the close button. */
52
+ export declare function SheetHeader({ title, description, closeLabel, onClose, titleId, descriptionId }: SheetHeaderProps): import("react").JSX.Element;
53
+ export type SheetScrollProps = {
54
+ /** Whether to pad the content (default true). Use false for a row list that fills edge to edge. */
55
+ padded?: boolean;
56
+ /** Whether there is a footer. When there is none, the content's bottom edge absorbs the safe area. */
57
+ hasFooter?: boolean;
58
+ children: ReactNode;
59
+ };
60
+ /**
61
+ * The sheet body.
62
+ *
63
+ * `contentContainerClassName` **does not work** with react-native-css (the padding silently disappears and
64
+ * text gets clipped at the edge). Always write padding in `contentContainerStyle`.
65
+ */
66
+ export declare function SheetScroll({ padded, hasFooter, children }: SheetScrollProps): import("react").JSX.Element;
67
+ /** The sheet footer. Adds the safe area so it does not slip under the home indicator. */
68
+ export declare function SheetFooter({ children }: {
69
+ children: ReactNode;
70
+ }): import("react").JSX.Element;
71
+ //#endregion
@@ -0,0 +1,187 @@
1
+ import { useTokenColor } from "../lib/token-color.js";
2
+ import { isBlankNode } from "../lib/utils.js";
3
+ import { Text as Text$1 } from "./text.js";
4
+ import { CLOSE_LABEL } from "../lib/labels.js";
5
+ import { useEffect, useRef, useState } from "react";
6
+ import { KeyboardAvoidingView, Modal, Platform, Pressable, ScrollView, StyleSheet, View, useWindowDimensions } from "react-native";
7
+ import { Fragment as Fragment$1, jsx, jsxs } from "react/jsx-runtime";
8
+ import Feather from "@expo/vector-icons/Feather";
9
+ import Animated$1, { Easing as Easing$1, useAnimatedStyle, useSharedValue, withSpring, withTiming } from "react-native-reanimated";
10
+ import { useSafeAreaInsets } from "react-native-safe-area-context";
11
+ import { scheduleOnRN } from "react-native-worklets";
12
+
13
+ //#region src/native/base/sheet.tsx
14
+ /**
15
+ * The base for a bottom sheet. Mirrors the web base/sheet (a wrapper around Radix Dialog).
16
+ *
17
+ * This holds only "how the surface appears"; conventions for headings and body are decided by `layout/sheet`.
18
+ * Things that want their own content, such as the `atom/select` picker, cannot go through `layout/`
19
+ * (the dependency would run backwards), so, as on the web, the base lives in base and both use it.
20
+ */
21
+ /** The content padding. Even when `padded` is false, the bottom safe area is always secured. */
22
+ const GUTTER = 16;
23
+ /**
24
+ * Do not use `Modal`'s `animationType="slide"`. It slides up **together with the scrim**,
25
+ * so the dark overlay appears to grow from the bottom and looks cheap. Here the scrim's fade and the panel's
26
+ * slide are driven by separate curves.
27
+ *
28
+ * The dialog role (`role="dialog"`, `aria-modal`), focus trapping and Esc (`onRequestClose`) are provided by `Modal`
29
+ * (react-native-web's `Modal` emits the role and the trap. It has no name of its own, so pass `aria-label(ledby)`).
30
+ */
31
+ function SheetShell({ open, onOpenChange, dismissOnBackdropPress = true, maxHeightRatio = .85, onClosed, "aria-labelledby": ariaLabelledBy, "aria-label": ariaLabel, "aria-describedby": ariaDescribedBy, children }) {
32
+ const { height: windowHeight } = useWindowDimensions();
33
+ const [mounted, setMounted] = useState(open);
34
+ const [panelHeight, setPanelHeight] = useState(0);
35
+ if (open && !mounted) setMounted(true);
36
+ if (!open && !mounted && panelHeight !== 0) setPanelHeight(0);
37
+ const progress = useSharedValue(0);
38
+ useEffect(() => {
39
+ if (open) return;
40
+ progress.set(withTiming(0, {
41
+ duration: 180,
42
+ easing: Easing$1.in(Easing$1.cubic)
43
+ }, (finished) => {
44
+ "worklet";
45
+ if (finished) scheduleOnRN(setMounted, false);
46
+ }));
47
+ }, [open, progress]);
48
+ useEffect(() => {
49
+ if (!open || panelHeight === 0) return;
50
+ progress.set(withSpring(1, {
51
+ damping: 26,
52
+ stiffness: 260,
53
+ mass: .9
54
+ }));
55
+ }, [
56
+ open,
57
+ panelHeight,
58
+ progress
59
+ ]);
60
+ const wasMounted = useRef(false);
61
+ const onClosedRef = useRef(onClosed);
62
+ useEffect(() => {
63
+ onClosedRef.current = onClosed;
64
+ });
65
+ useEffect(() => {
66
+ if (mounted) {
67
+ wasMounted.current = true;
68
+ return;
69
+ }
70
+ if (!wasMounted.current) return;
71
+ wasMounted.current = false;
72
+ onClosedRef.current?.();
73
+ }, [mounted]);
74
+ const scrimStyle = useAnimatedStyle(() => ({ opacity: progress.get() }), [progress]);
75
+ const panelStyle = useAnimatedStyle(() => ({
76
+ opacity: panelHeight === 0 ? 0 : 1,
77
+ transform: [{ translateY: (1 - progress.get()) * panelHeight }]
78
+ }), [progress, panelHeight]);
79
+ if (!mounted) return null;
80
+ return /* @__PURE__ */ jsx(Modal, {
81
+ visible: true,
82
+ transparent: true,
83
+ statusBarTranslucent: true,
84
+ animationType: "none",
85
+ onRequestClose: () => onOpenChange(false),
86
+ "aria-labelledby": ariaLabelledBy,
87
+ "aria-label": ariaLabel,
88
+ "aria-describedby": ariaDescribedBy,
89
+ children: /* @__PURE__ */ jsxs(View, {
90
+ style: { flex: 1 },
91
+ children: [/* @__PURE__ */ jsx(Animated$1.View, {
92
+ style: [StyleSheet.absoluteFill, scrimStyle],
93
+ children: /* @__PURE__ */ jsx(Pressable, {
94
+ accessible: false,
95
+ style: StyleSheet.absoluteFill,
96
+ className: "bg-scrim",
97
+ onPress: dismissOnBackdropPress ? () => onOpenChange(false) : void 0
98
+ })
99
+ }), /* @__PURE__ */ jsx(KeyboardAvoidingView, {
100
+ style: {
101
+ flex: 1,
102
+ justifyContent: "flex-end"
103
+ },
104
+ pointerEvents: "box-none",
105
+ behavior: Platform.OS === "ios" ? "padding" : "height",
106
+ children: /* @__PURE__ */ jsx(Animated$1.View, {
107
+ style: panelStyle,
108
+ onLayout: (event) => setPanelHeight(event.nativeEvent.layout.height),
109
+ children: /* @__PURE__ */ jsx(View, {
110
+ className: "rounded-t-surface bg-popover shadow-lg",
111
+ style: { maxHeight: windowHeight * maxHeightRatio },
112
+ children: /* @__PURE__ */ jsx(View, {
113
+ className: "overflow-hidden rounded-t-surface",
114
+ style: { flexShrink: 1 },
115
+ children
116
+ })
117
+ })
118
+ })
119
+ })]
120
+ })
121
+ });
122
+ }
123
+ /** The grab cue (grabber), the heading and the close button. */
124
+ function SheetHeader({ title, description, closeLabel = CLOSE_LABEL, onClose, titleId, descriptionId }) {
125
+ const ink = useTokenColor("--ink-500");
126
+ return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsx(View, {
127
+ className: "items-center pt-2 pb-1",
128
+ children: /* @__PURE__ */ jsx(View, { className: "h-1 w-9 bg-line" })
129
+ }), /* @__PURE__ */ jsxs(View, {
130
+ className: "flex-row items-start justify-between gap-2 border-b border-line px-4 pt-1 pb-3",
131
+ children: [/* @__PURE__ */ jsxs(View, {
132
+ className: "shrink gap-1",
133
+ children: [!isBlankNode(title) ? /* @__PURE__ */ jsx(Text$1, {
134
+ id: titleId,
135
+ role: "heading",
136
+ "aria-level": "2",
137
+ className: "text-base font-semibold",
138
+ children: title
139
+ }) : null, !isBlankNode(description) ? /* @__PURE__ */ jsx(Text$1, {
140
+ id: descriptionId,
141
+ className: "text-muted-foreground text-sm",
142
+ children: description
143
+ }) : null]
144
+ }), /* @__PURE__ */ jsx(Pressable, {
145
+ accessibilityRole: "button",
146
+ accessibilityLabel: closeLabel,
147
+ hitSlop: 12,
148
+ onPress: onClose,
149
+ children: /* @__PURE__ */ jsx(Feather, {
150
+ name: "x",
151
+ size: 16,
152
+ color: ink
153
+ })
154
+ })]
155
+ })] });
156
+ }
157
+ /**
158
+ * The sheet body.
159
+ *
160
+ * `contentContainerClassName` **does not work** with react-native-css (the padding silently disappears and
161
+ * text gets clipped at the edge). Always write padding in `contentContainerStyle`.
162
+ */
163
+ function SheetScroll({ padded = true, hasFooter = false, children }) {
164
+ const insets = useSafeAreaInsets();
165
+ return /* @__PURE__ */ jsx(ScrollView, {
166
+ style: { flexShrink: 1 },
167
+ contentContainerStyle: {
168
+ gap: padded ? GUTTER : 0,
169
+ paddingHorizontal: padded ? GUTTER : 0,
170
+ paddingTop: padded ? GUTTER : 0,
171
+ paddingBottom: (padded ? GUTTER : 0) + (hasFooter ? 0 : insets.bottom)
172
+ },
173
+ children
174
+ });
175
+ }
176
+ /** The sheet footer. Adds the safe area so it does not slip under the home indicator. */
177
+ function SheetFooter({ children }) {
178
+ const insets = useSafeAreaInsets();
179
+ return /* @__PURE__ */ jsx(View, {
180
+ className: "flex-row justify-end gap-2 border-t border-line px-4 pt-3",
181
+ style: { paddingBottom: 12 + insets.bottom },
182
+ children
183
+ });
184
+ }
185
+
186
+ //#endregion
187
+ export { SheetFooter, SheetHeader, SheetScroll, SheetShell };
@@ -0,0 +1,14 @@
1
+ import * as React$1 from "react";
2
+ import { Text as Text$1 } from "react-native";
3
+ import { VariantProps } from "class-variance-authority";
4
+ //#region src/native/base/text.d.ts
5
+ declare const textVariants: (props?: ({
6
+ variant?: "blockquote" | "code" | "default" | "h1" | "h2" | "h3" | "h4" | "large" | "lead" | "muted" | "p" | "small" | null | undefined;
7
+ } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
+ type TextVariantProps = VariantProps<typeof textVariants>;
9
+ declare const TextClassContext: React$1.Context<string | undefined>;
10
+ declare function Text({ className, asChild, variant, ...props }: React$1.ComponentProps<typeof Text$1> & TextVariantProps & React$1.RefAttributes<Text$1> & {
11
+ asChild?: boolean;
12
+ }): React$1.JSX.Element;
13
+ //#endregion
14
+ export { Text, TextClassContext };
@@ -0,0 +1,53 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import * as React$1 from "react";
3
+ import { Platform, Text as Text$1 } from "react-native";
4
+ import { jsx } from "react/jsx-runtime";
5
+ import * as Slot from "@rn-primitives/slot";
6
+ import { cva } from "class-variance-authority";
7
+
8
+ //#region src/native/base/text.tsx
9
+ const textVariants = cva(cn("text-foreground font-sans text-base", Platform.select({ web: "select-text" })), {
10
+ variants: { variant: {
11
+ default: "",
12
+ h1: cn("text-center text-4xl font-extrabold tracking-tight", Platform.select({ web: "scroll-m-20 text-balance" })),
13
+ h2: cn("border-line border-b pb-2 text-3xl font-semibold tracking-tight", Platform.select({ web: "scroll-m-20 first:mt-0" })),
14
+ h3: cn("text-2xl font-semibold tracking-tight", Platform.select({ web: "scroll-m-20" })),
15
+ h4: cn("text-xl font-semibold tracking-tight", Platform.select({ web: "scroll-m-20" })),
16
+ p: "mt-3 leading-7 sm:mt-6",
17
+ blockquote: "mt-4 border-l-2 pl-3 italic sm:mt-6 sm:pl-6",
18
+ code: cn("bg-muted rounded-control relative px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold"),
19
+ lead: "text-muted-foreground text-xl",
20
+ large: "text-lg font-semibold",
21
+ small: "text-sm font-medium leading-none",
22
+ muted: "text-muted-foreground text-sm"
23
+ } },
24
+ defaultVariants: { variant: "default" }
25
+ });
26
+ const ROLE = {
27
+ h1: "heading",
28
+ h2: "heading",
29
+ h3: "heading",
30
+ h4: "heading",
31
+ blockquote: Platform.select({ web: "blockquote" }),
32
+ code: Platform.select({ web: "code" })
33
+ };
34
+ const ARIA_LEVEL = {
35
+ h1: "1",
36
+ h2: "2",
37
+ h3: "3",
38
+ h4: "4"
39
+ };
40
+ const TextClassContext = React$1.createContext(void 0);
41
+ function Text({ className, asChild = false, variant = "default", ...props }) {
42
+ const textClass = React$1.useContext(TextClassContext);
43
+ const Component = asChild ? Slot.Text : Text$1;
44
+ return /* @__PURE__ */ jsx(Component, {
45
+ className: cn(textVariants({ variant }), textClass, className),
46
+ role: variant ? ROLE[variant] : void 0,
47
+ "aria-level": variant ? ARIA_LEVEL[variant] : void 0,
48
+ ...props
49
+ });
50
+ }
51
+
52
+ //#endregion
53
+ export { Text, TextClassContext };
@@ -0,0 +1,13 @@
1
+ import { BaseInputProps } from "../../shared/form.js";
2
+ import { ReactNode } from "react";
3
+ //#region src/native/form/checkbox.d.ts
4
+ export type CheckboxProps = BaseInputProps<boolean> & {
5
+ /** Label placed to the right of the checkbox. Distinct from the field's `label` (this one becomes the checkbox's name). */
6
+ checkboxLabel: ReactNode;
7
+ };
8
+ /**
9
+ * Checkbox integrated with TanStack Form. Like the web `form/checkbox`,
10
+ * pass `value` / `onValueChange` for controlled mode (the field is not used); omit them to read from the field context.
11
+ */
12
+ export declare function Checkbox(props: CheckboxProps): import("react").JSX.Element;
13
+ //#endregion