@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,90 @@
1
+ import { useFieldValue } from "../../shared/form.js";
2
+ import { NUMBER_INVALID_LABEL } from "../lib/labels.js";
3
+ import { TextField } from "../atom/text-field.js";
4
+ import { FormControl, FormDescription, FormItem, FormLabel, FormMessage } from "../base/form.js";
5
+ import { useState } from "react";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+
8
+ //#region src/native/form/text-input.tsx
9
+ const DECIMAL = /^[+-]?(?:\d+\.?\d*|\.\d+)$/;
10
+ /**
11
+ * Parses the text typed into a number field.
12
+ * - Leading and trailing whitespace is ignored, and empty input (including `" "`) means "no value" (null)
13
+ * - Full-width digits and symbols are normalized to half-width (`12.5` → `12.5`). `,` is accepted as the decimal point (`1,5` → 1.5; locale).
14
+ * Thousands separators (`1,000`) cannot be told apart (read as 1); digit grouping is assumed not to be entered
15
+ * - Unreadable text (`abc`, `-`, `0x10`, `Infinity`, overflow) yields `ok: false`
16
+ */
17
+ function parseNumber(text) {
18
+ const normalized = text.normalize("NFKC").replaceAll("−", "-").replace(",", ".").trim();
19
+ if (normalized === "") return {
20
+ ok: true,
21
+ value: null
22
+ };
23
+ if (!DECIMAL.test(normalized)) return { ok: false };
24
+ const parsed = Number(normalized);
25
+ return Number.isFinite(parsed) ? {
26
+ ok: true,
27
+ value: parsed
28
+ } : { ok: false };
29
+ }
30
+ /**
31
+ * Text input integrated with TanStack Form. Corresponds to the web `form/text-input`.
32
+ * The value comes from the field context, and `debounce` handling is delegated to the shared `useFieldValue`.
33
+ * The input frame itself uses `atom/text-field` (the counterpart of web's `base/input`).
34
+ */
35
+ function TextInput({ label, required, description, helpText, placeholder, disabled, debounce, className, wrapperClassName, type = "text", autoComplete, autoCapitalize, multiline, "data-testid": testID }) {
36
+ const [value, setValue, field] = useFieldValue({ debounce });
37
+ const [draft, setDraft] = useState(null);
38
+ const parsed = draft === null ? null : parseNumber(draft);
39
+ const draftValue = parsed === null ? void 0 : parsed.ok ? parsed.value : null;
40
+ const touched = field.state.meta.isTouched;
41
+ const [wasTouched, setWasTouched] = useState(touched);
42
+ if (touched !== wasTouched) {
43
+ setWasTouched(touched);
44
+ if (!touched && draft !== null) setDraft(null);
45
+ }
46
+ const draftActive = draft !== null && draftValue === (value ?? null);
47
+ if (draft !== null && !draftActive) setDraft(null);
48
+ const numberUnreadable = type === "number" && draftActive && parsed !== null && !parsed.ok;
49
+ const shown = type === "number" && draftActive ? draft : value === null || value === void 0 ? "" : String(value);
50
+ return /* @__PURE__ */ jsxs(FormItem, {
51
+ className: wrapperClassName,
52
+ errors: numberUnreadable ? [NUMBER_INVALID_LABEL] : void 0,
53
+ children: [
54
+ label ? /* @__PURE__ */ jsx(FormLabel, {
55
+ required,
56
+ helpText,
57
+ children: label
58
+ }) : null,
59
+ /* @__PURE__ */ jsx(FormControl, {
60
+ labelled: Boolean(label),
61
+ described: Boolean(description),
62
+ children: (control) => /* @__PURE__ */ jsx(TextField, {
63
+ ...control,
64
+ accessibilityLabel: typeof label === "string" ? label : void 0,
65
+ accessibilityHint: description,
66
+ value: shown,
67
+ onChangeText: (text) => {
68
+ if (type !== "number") return setValue(text);
69
+ setDraft(text);
70
+ const next = parseNumber(text);
71
+ setValue(next.ok ? next.value : null);
72
+ },
73
+ placeholder,
74
+ type,
75
+ disabled,
76
+ autoComplete,
77
+ autoCapitalize,
78
+ multiline,
79
+ testID,
80
+ className
81
+ })
82
+ }),
83
+ description ? /* @__PURE__ */ jsx(FormDescription, { children: description }) : null,
84
+ /* @__PURE__ */ jsx(FormMessage, {})
85
+ ]
86
+ });
87
+ }
88
+
89
+ //#endregion
90
+ export { TextInput };
@@ -0,0 +1 @@
1
+ export {}
File without changes
@@ -0,0 +1,25 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/native/layout/accordion.d.ts
3
+ export type AccordionEntry = {
4
+ /** Item identifier. */
5
+ value: string;
6
+ trigger: ReactNode;
7
+ content: ReactNode;
8
+ };
9
+ export type AccordionProps = {
10
+ items: AccordionEntry[];
11
+ /** `single` opens one item at a time; `multiple` allows several open at once. */
12
+ type?: "single" | "multiple";
13
+ defaultValue?: string[];
14
+ className?: string;
15
+ itemClassName?: string;
16
+ /** Extra classes for the open/close row (the trigger). */
17
+ triggerClassName?: string;
18
+ contentClassName?: string;
19
+ };
20
+ /**
21
+ * A data-driven accordion, like the web `layout/accordion`: just pass `items`.
22
+ * Dividers are 1px hairlines only, and only the open/close chevron animates.
23
+ */
24
+ export declare function Accordion({ items, type, defaultValue, className, itemClassName, triggerClassName, contentClassName }: AccordionProps): import("react").JSX.Element;
25
+ //#endregion
@@ -0,0 +1,54 @@
1
+ import { useTokenColor } from "../lib/token-color.js";
2
+ import { cn } from "../lib/utils.js";
3
+ import { Text as Text$1 } from "../base/text.js";
4
+ import { useState } from "react";
5
+ import { LayoutAnimation, Platform, Pressable, UIManager, View } from "react-native";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import Feather from "@expo/vector-icons/Feather";
8
+
9
+ //#region src/native/layout/accordion.tsx
10
+ if (Platform.OS === "android" && UIManager.setLayoutAnimationEnabledExperimental) UIManager.setLayoutAnimationEnabledExperimental(true);
11
+ /**
12
+ * A data-driven accordion, like the web `layout/accordion`: just pass `items`.
13
+ * Dividers are 1px hairlines only, and only the open/close chevron animates.
14
+ */
15
+ function Accordion({ items, type = "single", defaultValue = [], className, itemClassName, triggerClassName, contentClassName }) {
16
+ const [open, setOpen] = useState(defaultValue);
17
+ const ink = useTokenColor("--ink-500");
18
+ const toggle = (value) => {
19
+ LayoutAnimation.configureNext(LayoutAnimation.Presets.easeInEaseOut);
20
+ setOpen((prev) => {
21
+ if (prev.includes(value)) return prev.filter((v) => v !== value);
22
+ return type === "single" ? [value] : [...prev, value];
23
+ });
24
+ };
25
+ return /* @__PURE__ */ jsx(View, {
26
+ className,
27
+ children: items.map((item) => {
28
+ const isOpen = open.includes(item.value);
29
+ return /* @__PURE__ */ jsxs(View, {
30
+ className: cn("border-b border-line", itemClassName),
31
+ children: [/* @__PURE__ */ jsxs(Pressable, {
32
+ accessibilityRole: "button",
33
+ "aria-expanded": isOpen,
34
+ onPress: () => toggle(item.value),
35
+ className: cn("flex-row items-center justify-between gap-2 py-4", triggerClassName),
36
+ children: [typeof item.trigger === "string" ? /* @__PURE__ */ jsx(Text$1, {
37
+ className: "text-sm font-medium",
38
+ children: item.trigger
39
+ }) : item.trigger, /* @__PURE__ */ jsx(Feather, {
40
+ name: isOpen ? "chevron-up" : "chevron-down",
41
+ size: 16,
42
+ color: ink
43
+ })]
44
+ }), isOpen ? /* @__PURE__ */ jsx(View, {
45
+ className: cn("pb-4", contentClassName),
46
+ children: item.content
47
+ }) : null]
48
+ }, item.value);
49
+ })
50
+ });
51
+ }
52
+
53
+ //#endregion
54
+ export { Accordion };
@@ -0,0 +1,47 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/native/layout/card.d.ts
3
+ /** A text or number action (it serves as its own spoken name). */
4
+ type TextAction = string | number;
5
+ /**
6
+ * The action at the right end of the header. **When the tappable action (`actionOnPress`) is not text (an icon, for example),
7
+ * a spoken name (`actionLabel`) is required** (otherwise the button would have no name).
8
+ */
9
+ type CardActionProps = {
10
+ action?: undefined;
11
+ actionOnPress?: undefined;
12
+ actionLabel?: undefined;
13
+ } | {
14
+ action: ReactNode;
15
+ actionOnPress?: undefined;
16
+ actionLabel?: string;
17
+ } | {
18
+ action: TextAction;
19
+ actionOnPress: () => void;
20
+ actionLabel?: string;
21
+ } | {
22
+ action: Exclude<ReactNode, TextAction | null | undefined>;
23
+ actionOnPress: () => void;
24
+ actionLabel: string;
25
+ };
26
+ export type CardProps = CardActionProps & {
27
+ title?: ReactNode;
28
+ /**
29
+ * Makes the title a heading (`role="heading"` and `aria-level`). Pass it when the title should be part of the screen's heading structure.
30
+ * When omitted it is plain text (same meaning as web's `headingLevel`).
31
+ */
32
+ headingLevel?: 2 | 3 | 4 | 5 | 6;
33
+ description?: ReactNode;
34
+ content: ReactNode;
35
+ footer?: ReactNode;
36
+ className?: string;
37
+ contentClassName?: string;
38
+ };
39
+ /**
40
+ * The same "title, description, action, body, footer" structure as the web `layout/card`.
41
+ * The shell (surface radius, a very faint 1px rule, raised surface) belongs to `Panel`.
42
+ *
43
+ * If you only want to lay out your own spacing and dividers inside, use `Panel`, the bare surface, directly.
44
+ */
45
+ export declare function Card({ title, headingLevel, description, action, actionOnPress, actionLabel, content, footer, className, contentClassName }: CardProps): import("react").JSX.Element;
46
+ //#endregion
47
+ export {};
@@ -0,0 +1,57 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Text as Text$1 } from "../base/text.js";
3
+ import { Panel } from "./panel.js";
4
+ import { Pressable, View } from "react-native";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+
7
+ //#region src/native/layout/card.tsx
8
+ /**
9
+ * The same "title, description, action, body, footer" structure as the web `layout/card`.
10
+ * The shell (surface radius, a very faint 1px rule, raised surface) belongs to `Panel`.
11
+ *
12
+ * If you only want to lay out your own spacing and dividers inside, use `Panel`, the bare surface, directly.
13
+ */
14
+ function Card({ title, headingLevel, description, action, actionOnPress, actionLabel, content, footer, className, contentClassName }) {
15
+ const hasHeader = !!title || !!description || !!action;
16
+ const actionNode = typeof action === "string" || typeof action === "number" ? /* @__PURE__ */ jsx(Text$1, {
17
+ className: "text-sm",
18
+ children: action
19
+ }) : action;
20
+ return /* @__PURE__ */ jsxs(Panel, {
21
+ className,
22
+ children: [
23
+ hasHeader ? /* @__PURE__ */ jsxs(View, {
24
+ className: "flex-row items-start justify-between gap-2 border-b border-line px-4 py-3",
25
+ children: [/* @__PURE__ */ jsxs(View, {
26
+ className: "shrink gap-1",
27
+ children: [title ? /* @__PURE__ */ jsx(Text$1, {
28
+ role: headingLevel ? "heading" : void 0,
29
+ "aria-level": headingLevel ? String(headingLevel) : void 0,
30
+ className: "text-base font-semibold leading-none",
31
+ children: title
32
+ }) : null, description ? /* @__PURE__ */ jsx(Text$1, {
33
+ className: "text-muted-foreground text-sm",
34
+ children: description
35
+ }) : null]
36
+ }), action ? actionOnPress ? /* @__PURE__ */ jsx(Pressable, {
37
+ accessibilityRole: "button",
38
+ accessibilityLabel: actionLabel,
39
+ onPress: actionOnPress,
40
+ hitSlop: 12,
41
+ children: actionNode
42
+ }) : actionNode : null]
43
+ }) : null,
44
+ /* @__PURE__ */ jsx(View, {
45
+ className: cn("grow gap-4 p-4", contentClassName),
46
+ children: content
47
+ }),
48
+ footer ? /* @__PURE__ */ jsx(View, {
49
+ className: "flex-row justify-end gap-4 border-t border-line px-4 py-3",
50
+ children: footer
51
+ }) : null
52
+ ]
53
+ });
54
+ }
55
+
56
+ //#endregion
57
+ export { Card };
@@ -0,0 +1,16 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/native/layout/description.d.ts
3
+ export type DescriptionSection = {
4
+ title: string;
5
+ titleIcon?: ReactNode;
6
+ description: ReactNode;
7
+ };
8
+ export type DescriptionProps = {
9
+ sections: DescriptionSection[];
10
+ };
11
+ /**
12
+ * Stacks heading + body sections separated by 1px rules.
13
+ * Corresponds to the web `layout/description` (terms of service, explanation screens, etc.).
14
+ */
15
+ export declare function Description({ sections }: DescriptionProps): import("react").JSX.Element;
16
+ //#endregion
@@ -0,0 +1,32 @@
1
+ import { Text as Text$1 } from "../base/text.js";
2
+ import { Separator } from "../atom/separator.js";
3
+ import { Fragment } from "react";
4
+ import { View } from "react-native";
5
+ import { jsx, jsxs } from "react/jsx-runtime";
6
+
7
+ //#region src/native/layout/description.tsx
8
+ /**
9
+ * Stacks heading + body sections separated by 1px rules.
10
+ * Corresponds to the web `layout/description` (terms of service, explanation screens, etc.).
11
+ */
12
+ function Description({ sections }) {
13
+ return /* @__PURE__ */ jsx(View, {
14
+ className: "gap-8",
15
+ children: sections.map((section, index) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs(View, { children: [/* @__PURE__ */ jsxs(View, {
16
+ className: "mb-2 flex-row items-center gap-2",
17
+ children: [section.titleIcon, /* @__PURE__ */ jsx(Text$1, {
18
+ className: "font-bold",
19
+ children: section.title
20
+ })]
21
+ }), /* @__PURE__ */ jsx(View, {
22
+ className: "gap-4",
23
+ children: typeof section.description === "string" ? /* @__PURE__ */ jsx(Text$1, {
24
+ className: "text-sm",
25
+ children: section.description
26
+ }) : section.description
27
+ })] }), index < sections.length - 1 ? /* @__PURE__ */ jsx(Separator, {}) : null] }, section.title))
28
+ });
29
+ }
30
+
31
+ //#endregion
32
+ export { Description };
@@ -0,0 +1,21 @@
1
+ //#region src/native/layout/error.d.ts
2
+ export type ErrorViewProps = {
3
+ /** Display text. This is a shared package, so the caller owns it (no i18n is brought in). */
4
+ labels: {
5
+ title: string;
6
+ description?: string;
7
+ retry: string;
8
+ };
9
+ onRetry: () => void;
10
+ /**
11
+ * By default it fills the screen and centers its content. When inserted as part of scrolling content,
12
+ * `h-full` cannot be resolved, so override the height with `className`.
13
+ */
14
+ className?: string;
15
+ };
16
+ /**
17
+ * The screen shown on error.
18
+ * It is also used as the content of `once/error-boundary`.
19
+ */
20
+ export declare function ErrorView({ labels, onRetry, className }: ErrorViewProps): import("react").JSX.Element;
21
+ //#endregion
@@ -0,0 +1,44 @@
1
+ import { useTokenColor } from "../lib/token-color.js";
2
+ import { cn } from "../lib/utils.js";
3
+ import { Text as Text$1 } from "../base/text.js";
4
+ import { Button } from "../atom/button.js";
5
+ import { View } from "react-native";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import Feather from "@expo/vector-icons/Feather";
8
+
9
+ //#region src/native/layout/error.tsx
10
+ /**
11
+ * The screen shown on error.
12
+ * It is also used as the content of `once/error-boundary`.
13
+ */
14
+ function ErrorView({ labels, onRetry, className }) {
15
+ const ink = useTokenColor("--ink-1000");
16
+ return /* @__PURE__ */ jsxs(View, {
17
+ className: cn("h-full w-full items-center justify-center gap-4 p-6", className),
18
+ children: [
19
+ /* @__PURE__ */ jsx(Feather, {
20
+ name: "alert-octagon",
21
+ size: 20,
22
+ color: ink
23
+ }),
24
+ /* @__PURE__ */ jsx(Text$1, {
25
+ className: "text-base font-semibold",
26
+ children: labels.title
27
+ }),
28
+ labels.description ? /* @__PURE__ */ jsx(Text$1, {
29
+ className: "text-muted-foreground text-center text-sm",
30
+ children: labels.description
31
+ }) : null,
32
+ /* @__PURE__ */ jsx(Button, {
33
+ className: "self-center",
34
+ variant: "outline",
35
+ size: "sm",
36
+ onPress: onRetry,
37
+ children: labels.retry
38
+ })
39
+ ]
40
+ });
41
+ }
42
+
43
+ //#endregion
44
+ export { ErrorView };
@@ -0,0 +1,25 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/native/layout/information.d.ts
3
+ export type InformationField = {
4
+ label: string;
5
+ value: ReactNode;
6
+ separator?: never;
7
+ } | {
8
+ label?: never;
9
+ value?: never;
10
+ separator: true;
11
+ };
12
+ export type InformationProps = {
13
+ fields: InformationField[];
14
+ /** Shows values larger (for a detail screen header, etc.). */
15
+ highlighted?: boolean;
16
+ className?: string;
17
+ };
18
+ /**
19
+ * A definition list that lays out labels and values. Corresponds to the web `layout/information`.
20
+ *
21
+ * Web has room to split into several columns, but native lacks the width, so it
22
+ * **always renders a single column** (rows with the label on the left and the value on the right).
23
+ */
24
+ export declare function Information({ fields, highlighted, className }: InformationProps): import("react").JSX.Element;
25
+ //#endregion
@@ -0,0 +1,35 @@
1
+ import { cn } from "../lib/utils.js";
2
+ import { Text as Text$1 } from "../base/text.js";
3
+ import { Separator } from "../atom/separator.js";
4
+ import { Fragment } from "react";
5
+ import { View } from "react-native";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+
8
+ //#region src/native/layout/information.tsx
9
+ /**
10
+ * A definition list that lays out labels and values. Corresponds to the web `layout/information`.
11
+ *
12
+ * Web has room to split into several columns, but native lacks the width, so it
13
+ * **always renders a single column** (rows with the label on the left and the value on the right).
14
+ */
15
+ function Information({ fields, highlighted, className }) {
16
+ return /* @__PURE__ */ jsx(View, {
17
+ className: cn("gap-3", className),
18
+ children: fields.map((field, index) => field.separator ? /* @__PURE__ */ jsx(Separator, {}, `separator-${index}`) : /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(View, {
19
+ className: "flex-row items-center justify-between gap-4",
20
+ children: [/* @__PURE__ */ jsx(Text$1, {
21
+ className: "text-muted-foreground shrink-0 text-xs font-semibold",
22
+ children: field.label
23
+ }), /* @__PURE__ */ jsx(View, {
24
+ className: cn("min-h-7 shrink flex-row items-center justify-end gap-2"),
25
+ children: typeof field.value === "string" || typeof field.value === "number" ? /* @__PURE__ */ jsx(Text$1, {
26
+ className: cn(highlighted ? "text-lg" : "text-sm"),
27
+ children: field.value
28
+ }) : field.value
29
+ })]
30
+ }) }, field.label))
31
+ });
32
+ }
33
+
34
+ //#endregion
35
+ export { Information };
@@ -0,0 +1,38 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/native/layout/locked.d.ts
3
+ export type LockedProps = {
4
+ /**
5
+ * The shape of what lies behind the lock. Pass a **sample that is not meant to be read**.
6
+ * Never pass real data (the cover is a visual treatment, not a barrier).
7
+ */
8
+ children: ReactNode;
9
+ /** Short text overlaid on the surface. Example: "Available with Pro". */
10
+ label: string;
11
+ /** Note stating that the content is a sample. Example: "Sample". Not shown when omitted. */
12
+ sampleLabel?: string;
13
+ /** Makes the whole surface pressable. A lock invites pressing, so pass this in most cases. */
14
+ onPress?: () => void;
15
+ accessibilityLabel?: string;
16
+ /**
17
+ * The destination placed under the cover (an explanation and an exit button). **Keeping it inside the same surface**
18
+ * puts "what you can't see" and "how to unlock it" on a single card.
19
+ */
20
+ footer?: ReactNode;
21
+ /** Height of the sample. Defaults to 160. */
22
+ height?: number;
23
+ className?: string;
24
+ };
25
+ /**
26
+ * A locked surface. **Shows the shape of the content but makes it unreadable.**
27
+ *
28
+ * Replacing the content wholesale communicates "absence" rather than "locked", and it is unclear what is being missed.
29
+ * Keeping the shape and covering it shows what is there while conveying that it is out of reach.
30
+ *
31
+ * It is built as **distinct from the loading Skeleton**. A Skeleton means "it will appear if you wait",
32
+ * so the same look must not be used for a lock (waiting will not reveal anything).
33
+ *
34
+ * The cover is a `GlassView` (glass that blurs what is behind it) on iOS 26 and later, and a card-colored cover where that is unsupported (below iOS 26, Android, web).
35
+ * **The sample is a dummy, so the strength of the cover has no confidentiality requirement.** Choose it as a visual treatment.
36
+ */
37
+ export declare function Locked({ children, label, sampleLabel, onPress, accessibilityLabel, footer, height, className }: LockedProps): import("react").JSX.Element;
38
+ //#endregion
@@ -0,0 +1,94 @@
1
+ import { useTokenColor } from "../lib/token-color.js";
2
+ import { cn } from "../lib/utils.js";
3
+ import { Text as Text$1 } from "../base/text.js";
4
+ import { Panel } from "./panel.js";
5
+ import { Pressable, View } from "react-native";
6
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import Feather from "@expo/vector-icons/Feather";
8
+ import { GlassView, isLiquidGlassAvailable } from "expo-glass-effect";
9
+
10
+ //#region src/native/layout/locked.tsx
11
+ const FILL = {
12
+ position: "absolute",
13
+ top: 0,
14
+ right: 0,
15
+ bottom: 0,
16
+ left: 0,
17
+ alignItems: "center",
18
+ justifyContent: "center",
19
+ gap: 8,
20
+ padding: 16
21
+ };
22
+ /**
23
+ * A locked surface. **Shows the shape of the content but makes it unreadable.**
24
+ *
25
+ * Replacing the content wholesale communicates "absence" rather than "locked", and it is unclear what is being missed.
26
+ * Keeping the shape and covering it shows what is there while conveying that it is out of reach.
27
+ *
28
+ * It is built as **distinct from the loading Skeleton**. A Skeleton means "it will appear if you wait",
29
+ * so the same look must not be used for a lock (waiting will not reveal anything).
30
+ *
31
+ * The cover is a `GlassView` (glass that blurs what is behind it) on iOS 26 and later, and a card-colored cover where that is unsupported (below iOS 26, Android, web).
32
+ * **The sample is a dummy, so the strength of the cover has no confidentiality requirement.** Choose it as a visual treatment.
33
+ */
34
+ function Locked({ children, label, sampleLabel, onPress, accessibilityLabel, footer, height = 160, className }) {
35
+ const ink = useTokenColor("--ink-900");
36
+ const cover = /* @__PURE__ */ jsxs(View, {
37
+ style: { height },
38
+ children: [
39
+ /* @__PURE__ */ jsx(View, {
40
+ pointerEvents: "none",
41
+ style: { height },
42
+ children
43
+ }),
44
+ isLiquidGlassAvailable() ? /* @__PURE__ */ jsx(GlassView, {
45
+ glassEffectStyle: "regular",
46
+ style: FILL
47
+ }) : /* @__PURE__ */ jsx(View, {
48
+ style: FILL,
49
+ className: "bg-card/85"
50
+ }),
51
+ /* @__PURE__ */ jsx(View, {
52
+ pointerEvents: "none",
53
+ style: FILL,
54
+ children: /* @__PURE__ */ jsx(LockBody, {
55
+ label,
56
+ sampleLabel,
57
+ ink
58
+ })
59
+ })
60
+ ]
61
+ });
62
+ return /* @__PURE__ */ jsxs(Panel, {
63
+ className: cn("overflow-hidden", className),
64
+ children: [onPress ? /* @__PURE__ */ jsx(Pressable, {
65
+ onPress,
66
+ accessible: false,
67
+ accessibilityLabel: accessibilityLabel ?? label,
68
+ children: cover
69
+ }) : cover, footer ? /* @__PURE__ */ jsx(View, {
70
+ className: "border-t border-line",
71
+ children: footer
72
+ }) : null]
73
+ });
74
+ }
75
+ function LockBody({ label, sampleLabel, ink }) {
76
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
77
+ /* @__PURE__ */ jsx(Feather, {
78
+ name: "lock",
79
+ size: 20,
80
+ color: ink
81
+ }),
82
+ /* @__PURE__ */ jsx(Text$1, {
83
+ className: "text-foreground text-center text-[13px] font-semibold leading-[19px]",
84
+ children: label
85
+ }),
86
+ sampleLabel ? /* @__PURE__ */ jsx(Text$1, {
87
+ className: "text-muted-foreground text-center text-[11px] font-semibold tracking-widest",
88
+ children: sampleLabel
89
+ }) : null
90
+ ] });
91
+ }
92
+
93
+ //#endregion
94
+ export { Locked };
@@ -0,0 +1,25 @@
1
+ import { ReactNode } from "react";
2
+ //#region src/native/layout/modal.d.ts
3
+ export type ModalProps = {
4
+ open: boolean;
5
+ onOpenChange: (open: boolean) => void;
6
+ /** Heading. Becomes the dialog's name. */
7
+ title: ReactNode;
8
+ description?: ReactNode;
9
+ content: ReactNode;
10
+ footer?: ReactNode;
11
+ /** Whether tapping the backdrop closes it (default false = require an explicit close). Esc and Android's back action close it regardless of this setting. */
12
+ dismissOnBackdropPress?: boolean;
13
+ /** Spoken name of the close button (default "閉じる", i.e. "Close"). This is a shared package, so pass other languages here. */
14
+ closeLabel?: string;
15
+ };
16
+ /**
17
+ * A confirmation/editing dialog shown at the center of the screen. Corresponds to the web `layout/modal`.
18
+ * The shell is an overlay surface (surface radius, shadow-lg; no border), and only the body scrolls.
19
+ *
20
+ * The heading is the dialog's name (`aria-labelledby`), and the supplementary text is its description (`aria-describedby`).
21
+ * The role (`role="dialog"`, `aria-modal`), focus trapping, and Esc are handled by `Modal`.
22
+ * The web `layout/modal` takes open/close through `dialog` (`DialogController`), whereas native uses `open` / `onOpenChange`.
23
+ */
24
+ export declare function Modal({ open, onOpenChange, title, description, content, footer, dismissOnBackdropPress, closeLabel }: ModalProps): import("react").JSX.Element;
25
+ //#endregion