orn-ui 0.1.0

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 (407) hide show
  1. package/README.md +107 -0
  2. package/bin/orn-ui.mjs +228 -0
  3. package/lib/commonjs/atoms/Avatar.js +42 -0
  4. package/lib/commonjs/atoms/Avatar.js.map +1 -0
  5. package/lib/commonjs/atoms/Badge.js +82 -0
  6. package/lib/commonjs/atoms/Badge.js.map +1 -0
  7. package/lib/commonjs/atoms/Button.js +222 -0
  8. package/lib/commonjs/atoms/Button.js.map +1 -0
  9. package/lib/commonjs/atoms/Card.js +33 -0
  10. package/lib/commonjs/atoms/Card.js.map +1 -0
  11. package/lib/commonjs/atoms/Checkbox.js +107 -0
  12. package/lib/commonjs/atoms/Checkbox.js.map +1 -0
  13. package/lib/commonjs/atoms/Divider.js +27 -0
  14. package/lib/commonjs/atoms/Divider.js.map +1 -0
  15. package/lib/commonjs/atoms/EmptyState.js +69 -0
  16. package/lib/commonjs/atoms/EmptyState.js.map +1 -0
  17. package/lib/commonjs/atoms/Fab.js +62 -0
  18. package/lib/commonjs/atoms/Fab.js.map +1 -0
  19. package/lib/commonjs/atoms/IconButton.js +60 -0
  20. package/lib/commonjs/atoms/IconButton.js.map +1 -0
  21. package/lib/commonjs/atoms/Image.js +113 -0
  22. package/lib/commonjs/atoms/Image.js.map +1 -0
  23. package/lib/commonjs/atoms/Input.js +173 -0
  24. package/lib/commonjs/atoms/Input.js.map +1 -0
  25. package/lib/commonjs/atoms/KeyValueRow.js +60 -0
  26. package/lib/commonjs/atoms/KeyValueRow.js.map +1 -0
  27. package/lib/commonjs/atoms/PressableScale.js +60 -0
  28. package/lib/commonjs/atoms/PressableScale.js.map +1 -0
  29. package/lib/commonjs/atoms/Spinner.js +156 -0
  30. package/lib/commonjs/atoms/Spinner.js.map +1 -0
  31. package/lib/commonjs/atoms/Text.js +63 -0
  32. package/lib/commonjs/atoms/Text.js.map +1 -0
  33. package/lib/commonjs/atoms/index.js +135 -0
  34. package/lib/commonjs/atoms/index.js.map +1 -0
  35. package/lib/commonjs/icons/Icon.js +40 -0
  36. package/lib/commonjs/icons/Icon.js.map +1 -0
  37. package/lib/commonjs/icons/defaultIcons.js +386 -0
  38. package/lib/commonjs/icons/defaultIcons.js.map +1 -0
  39. package/lib/commonjs/icons/index.js +20 -0
  40. package/lib/commonjs/icons/index.js.map +1 -0
  41. package/lib/commonjs/icons/types.js +6 -0
  42. package/lib/commonjs/icons/types.js.map +1 -0
  43. package/lib/commonjs/index.js +61 -0
  44. package/lib/commonjs/index.js.map +1 -0
  45. package/lib/commonjs/molecules/AvatarHeader.js +87 -0
  46. package/lib/commonjs/molecules/AvatarHeader.js.map +1 -0
  47. package/lib/commonjs/molecules/FormActions.js +47 -0
  48. package/lib/commonjs/molecules/FormActions.js.map +1 -0
  49. package/lib/commonjs/molecules/InfoRow.js +83 -0
  50. package/lib/commonjs/molecules/InfoRow.js.map +1 -0
  51. package/lib/commonjs/molecules/OptionCard.js +98 -0
  52. package/lib/commonjs/molecules/OptionCard.js.map +1 -0
  53. package/lib/commonjs/molecules/Stepper.js +104 -0
  54. package/lib/commonjs/molecules/Stepper.js.map +1 -0
  55. package/lib/commonjs/molecules/Steps.js +220 -0
  56. package/lib/commonjs/molecules/Steps.js.map +1 -0
  57. package/lib/commonjs/molecules/ThemeToggle.js +91 -0
  58. package/lib/commonjs/molecules/ThemeToggle.js.map +1 -0
  59. package/lib/commonjs/molecules/index.js +55 -0
  60. package/lib/commonjs/molecules/index.js.map +1 -0
  61. package/lib/commonjs/organisms/Alert.js +223 -0
  62. package/lib/commonjs/organisms/Alert.js.map +1 -0
  63. package/lib/commonjs/organisms/AlertProvider.js +109 -0
  64. package/lib/commonjs/organisms/AlertProvider.js.map +1 -0
  65. package/lib/commonjs/organisms/BottomSheet.js +154 -0
  66. package/lib/commonjs/organisms/BottomSheet.js.map +1 -0
  67. package/lib/commonjs/organisms/DateField.js +147 -0
  68. package/lib/commonjs/organisms/DateField.js.map +1 -0
  69. package/lib/commonjs/organisms/DatePicker.js +253 -0
  70. package/lib/commonjs/organisms/DatePicker.js.map +1 -0
  71. package/lib/commonjs/organisms/List.js +143 -0
  72. package/lib/commonjs/organisms/List.js.map +1 -0
  73. package/lib/commonjs/organisms/Modal.js +286 -0
  74. package/lib/commonjs/organisms/Modal.js.map +1 -0
  75. package/lib/commonjs/organisms/Screen.js +75 -0
  76. package/lib/commonjs/organisms/Screen.js.map +1 -0
  77. package/lib/commonjs/organisms/SearchList.js +180 -0
  78. package/lib/commonjs/organisms/SearchList.js.map +1 -0
  79. package/lib/commonjs/organisms/Select.js +178 -0
  80. package/lib/commonjs/organisms/Select.js.map +1 -0
  81. package/lib/commonjs/organisms/Toast.js +157 -0
  82. package/lib/commonjs/organisms/Toast.js.map +1 -0
  83. package/lib/commonjs/organisms/ToastProvider.js +131 -0
  84. package/lib/commonjs/organisms/ToastProvider.js.map +1 -0
  85. package/lib/commonjs/organisms/Wizard.js +116 -0
  86. package/lib/commonjs/organisms/Wizard.js.map +1 -0
  87. package/lib/commonjs/organisms/index.js +127 -0
  88. package/lib/commonjs/organisms/index.js.map +1 -0
  89. package/lib/commonjs/package.json +1 -0
  90. package/lib/commonjs/theme/UIProvider.js +110 -0
  91. package/lib/commonjs/theme/UIProvider.js.map +1 -0
  92. package/lib/commonjs/theme/createStyles.js +42 -0
  93. package/lib/commonjs/theme/createStyles.js.map +1 -0
  94. package/lib/commonjs/theme/createTheme.js +50 -0
  95. package/lib/commonjs/theme/createTheme.js.map +1 -0
  96. package/lib/commonjs/theme/index.js +151 -0
  97. package/lib/commonjs/theme/index.js.map +1 -0
  98. package/lib/commonjs/theme/insets.js +15 -0
  99. package/lib/commonjs/theme/insets.js.map +1 -0
  100. package/lib/commonjs/theme/labels.js +18 -0
  101. package/lib/commonjs/theme/labels.js.map +1 -0
  102. package/lib/commonjs/theme/palettes.js +42 -0
  103. package/lib/commonjs/theme/palettes.js.map +1 -0
  104. package/lib/commonjs/theme/tokens.js +120 -0
  105. package/lib/commonjs/theme/tokens.js.map +1 -0
  106. package/lib/commonjs/theme/types.js +6 -0
  107. package/lib/commonjs/theme/types.js.map +1 -0
  108. package/lib/module/atoms/Avatar.js +37 -0
  109. package/lib/module/atoms/Avatar.js.map +1 -0
  110. package/lib/module/atoms/Badge.js +77 -0
  111. package/lib/module/atoms/Badge.js.map +1 -0
  112. package/lib/module/atoms/Button.js +217 -0
  113. package/lib/module/atoms/Button.js.map +1 -0
  114. package/lib/module/atoms/Card.js +28 -0
  115. package/lib/module/atoms/Card.js.map +1 -0
  116. package/lib/module/atoms/Checkbox.js +102 -0
  117. package/lib/module/atoms/Checkbox.js.map +1 -0
  118. package/lib/module/atoms/Divider.js +22 -0
  119. package/lib/module/atoms/Divider.js.map +1 -0
  120. package/lib/module/atoms/EmptyState.js +64 -0
  121. package/lib/module/atoms/EmptyState.js.map +1 -0
  122. package/lib/module/atoms/Fab.js +57 -0
  123. package/lib/module/atoms/Fab.js.map +1 -0
  124. package/lib/module/atoms/IconButton.js +55 -0
  125. package/lib/module/atoms/IconButton.js.map +1 -0
  126. package/lib/module/atoms/Image.js +108 -0
  127. package/lib/module/atoms/Image.js.map +1 -0
  128. package/lib/module/atoms/Input.js +168 -0
  129. package/lib/module/atoms/Input.js.map +1 -0
  130. package/lib/module/atoms/KeyValueRow.js +55 -0
  131. package/lib/module/atoms/KeyValueRow.js.map +1 -0
  132. package/lib/module/atoms/PressableScale.js +55 -0
  133. package/lib/module/atoms/PressableScale.js.map +1 -0
  134. package/lib/module/atoms/Spinner.js +151 -0
  135. package/lib/module/atoms/Spinner.js.map +1 -0
  136. package/lib/module/atoms/Text.js +58 -0
  137. package/lib/module/atoms/Text.js.map +1 -0
  138. package/lib/module/atoms/index.js +18 -0
  139. package/lib/module/atoms/index.js.map +1 -0
  140. package/lib/module/icons/Icon.js +35 -0
  141. package/lib/module/icons/Icon.js.map +1 -0
  142. package/lib/module/icons/defaultIcons.js +381 -0
  143. package/lib/module/icons/defaultIcons.js.map +1 -0
  144. package/lib/module/icons/index.js +5 -0
  145. package/lib/module/icons/index.js.map +1 -0
  146. package/lib/module/icons/types.js +4 -0
  147. package/lib/module/icons/types.js.map +1 -0
  148. package/lib/module/index.js +8 -0
  149. package/lib/module/index.js.map +1 -0
  150. package/lib/module/molecules/AvatarHeader.js +82 -0
  151. package/lib/module/molecules/AvatarHeader.js.map +1 -0
  152. package/lib/module/molecules/FormActions.js +42 -0
  153. package/lib/module/molecules/FormActions.js.map +1 -0
  154. package/lib/module/molecules/InfoRow.js +78 -0
  155. package/lib/module/molecules/InfoRow.js.map +1 -0
  156. package/lib/module/molecules/OptionCard.js +93 -0
  157. package/lib/module/molecules/OptionCard.js.map +1 -0
  158. package/lib/module/molecules/Stepper.js +99 -0
  159. package/lib/module/molecules/Stepper.js.map +1 -0
  160. package/lib/module/molecules/Steps.js +215 -0
  161. package/lib/module/molecules/Steps.js.map +1 -0
  162. package/lib/module/molecules/ThemeToggle.js +86 -0
  163. package/lib/module/molecules/ThemeToggle.js.map +1 -0
  164. package/lib/module/molecules/index.js +10 -0
  165. package/lib/module/molecules/index.js.map +1 -0
  166. package/lib/module/organisms/Alert.js +218 -0
  167. package/lib/module/organisms/Alert.js.map +1 -0
  168. package/lib/module/organisms/AlertProvider.js +103 -0
  169. package/lib/module/organisms/AlertProvider.js.map +1 -0
  170. package/lib/module/organisms/BottomSheet.js +149 -0
  171. package/lib/module/organisms/BottomSheet.js.map +1 -0
  172. package/lib/module/organisms/DateField.js +142 -0
  173. package/lib/module/organisms/DateField.js.map +1 -0
  174. package/lib/module/organisms/DatePicker.js +247 -0
  175. package/lib/module/organisms/DatePicker.js.map +1 -0
  176. package/lib/module/organisms/List.js +138 -0
  177. package/lib/module/organisms/List.js.map +1 -0
  178. package/lib/module/organisms/Modal.js +281 -0
  179. package/lib/module/organisms/Modal.js.map +1 -0
  180. package/lib/module/organisms/Screen.js +70 -0
  181. package/lib/module/organisms/Screen.js.map +1 -0
  182. package/lib/module/organisms/SearchList.js +175 -0
  183. package/lib/module/organisms/SearchList.js.map +1 -0
  184. package/lib/module/organisms/Select.js +173 -0
  185. package/lib/module/organisms/Select.js.map +1 -0
  186. package/lib/module/organisms/Toast.js +152 -0
  187. package/lib/module/organisms/Toast.js.map +1 -0
  188. package/lib/module/organisms/ToastProvider.js +125 -0
  189. package/lib/module/organisms/ToastProvider.js.map +1 -0
  190. package/lib/module/organisms/Wizard.js +111 -0
  191. package/lib/module/organisms/Wizard.js.map +1 -0
  192. package/lib/module/organisms/index.js +16 -0
  193. package/lib/module/organisms/index.js.map +1 -0
  194. package/lib/module/package.json +1 -0
  195. package/lib/module/theme/UIProvider.js +97 -0
  196. package/lib/module/theme/UIProvider.js.map +1 -0
  197. package/lib/module/theme/createStyles.js +38 -0
  198. package/lib/module/theme/createStyles.js.map +1 -0
  199. package/lib/module/theme/createTheme.js +45 -0
  200. package/lib/module/theme/createTheme.js.map +1 -0
  201. package/lib/module/theme/index.js +10 -0
  202. package/lib/module/theme/index.js.map +1 -0
  203. package/lib/module/theme/insets.js +11 -0
  204. package/lib/module/theme/insets.js.map +1 -0
  205. package/lib/module/theme/labels.js +14 -0
  206. package/lib/module/theme/labels.js.map +1 -0
  207. package/lib/module/theme/palettes.js +38 -0
  208. package/lib/module/theme/palettes.js.map +1 -0
  209. package/lib/module/theme/tokens.js +117 -0
  210. package/lib/module/theme/tokens.js.map +1 -0
  211. package/lib/module/theme/types.js +4 -0
  212. package/lib/module/theme/types.js.map +1 -0
  213. package/lib/typescript/atoms/Avatar.d.ts +15 -0
  214. package/lib/typescript/atoms/Avatar.d.ts.map +1 -0
  215. package/lib/typescript/atoms/Badge.d.ts +19 -0
  216. package/lib/typescript/atoms/Badge.d.ts.map +1 -0
  217. package/lib/typescript/atoms/Button.d.ts +30 -0
  218. package/lib/typescript/atoms/Button.d.ts.map +1 -0
  219. package/lib/typescript/atoms/Card.d.ts +8 -0
  220. package/lib/typescript/atoms/Card.d.ts.map +1 -0
  221. package/lib/typescript/atoms/Checkbox.d.ts +11 -0
  222. package/lib/typescript/atoms/Checkbox.d.ts.map +1 -0
  223. package/lib/typescript/atoms/Divider.d.ts +8 -0
  224. package/lib/typescript/atoms/Divider.d.ts.map +1 -0
  225. package/lib/typescript/atoms/EmptyState.d.ts +12 -0
  226. package/lib/typescript/atoms/EmptyState.d.ts.map +1 -0
  227. package/lib/typescript/atoms/Fab.d.ts +22 -0
  228. package/lib/typescript/atoms/Fab.d.ts.map +1 -0
  229. package/lib/typescript/atoms/IconButton.d.ts +23 -0
  230. package/lib/typescript/atoms/IconButton.d.ts.map +1 -0
  231. package/lib/typescript/atoms/Image.d.ts +45 -0
  232. package/lib/typescript/atoms/Image.d.ts.map +1 -0
  233. package/lib/typescript/atoms/Input.d.ts +24 -0
  234. package/lib/typescript/atoms/Input.d.ts.map +1 -0
  235. package/lib/typescript/atoms/KeyValueRow.d.ts +17 -0
  236. package/lib/typescript/atoms/KeyValueRow.d.ts.map +1 -0
  237. package/lib/typescript/atoms/PressableScale.d.ts +15 -0
  238. package/lib/typescript/atoms/PressableScale.d.ts.map +1 -0
  239. package/lib/typescript/atoms/Spinner.d.ts +20 -0
  240. package/lib/typescript/atoms/Spinner.d.ts.map +1 -0
  241. package/lib/typescript/atoms/Text.d.ts +13 -0
  242. package/lib/typescript/atoms/Text.d.ts.map +1 -0
  243. package/lib/typescript/atoms/index.d.ts +31 -0
  244. package/lib/typescript/atoms/index.d.ts.map +1 -0
  245. package/lib/typescript/icons/Icon.d.ts +18 -0
  246. package/lib/typescript/icons/Icon.d.ts.map +1 -0
  247. package/lib/typescript/icons/defaultIcons.d.ts +5 -0
  248. package/lib/typescript/icons/defaultIcons.d.ts.map +1 -0
  249. package/lib/typescript/icons/index.d.ts +5 -0
  250. package/lib/typescript/icons/index.d.ts.map +1 -0
  251. package/lib/typescript/icons/types.d.ts +10 -0
  252. package/lib/typescript/icons/types.d.ts.map +1 -0
  253. package/lib/typescript/index.d.ts +6 -0
  254. package/lib/typescript/index.d.ts.map +1 -0
  255. package/lib/typescript/molecules/AvatarHeader.d.ts +20 -0
  256. package/lib/typescript/molecules/AvatarHeader.d.ts.map +1 -0
  257. package/lib/typescript/molecules/FormActions.d.ts +21 -0
  258. package/lib/typescript/molecules/FormActions.d.ts.map +1 -0
  259. package/lib/typescript/molecules/InfoRow.d.ts +17 -0
  260. package/lib/typescript/molecules/InfoRow.d.ts.map +1 -0
  261. package/lib/typescript/molecules/OptionCard.d.ts +20 -0
  262. package/lib/typescript/molecules/OptionCard.d.ts.map +1 -0
  263. package/lib/typescript/molecules/Stepper.d.ts +15 -0
  264. package/lib/typescript/molecules/Stepper.d.ts.map +1 -0
  265. package/lib/typescript/molecules/Steps.d.ts +29 -0
  266. package/lib/typescript/molecules/Steps.d.ts.map +1 -0
  267. package/lib/typescript/molecules/ThemeToggle.d.ts +15 -0
  268. package/lib/typescript/molecules/ThemeToggle.d.ts.map +1 -0
  269. package/lib/typescript/molecules/index.d.ts +15 -0
  270. package/lib/typescript/molecules/index.d.ts.map +1 -0
  271. package/lib/typescript/organisms/Alert.d.ts +29 -0
  272. package/lib/typescript/organisms/Alert.d.ts.map +1 -0
  273. package/lib/typescript/organisms/AlertProvider.d.ts +32 -0
  274. package/lib/typescript/organisms/AlertProvider.d.ts.map +1 -0
  275. package/lib/typescript/organisms/BottomSheet.d.ts +15 -0
  276. package/lib/typescript/organisms/BottomSheet.d.ts.map +1 -0
  277. package/lib/typescript/organisms/DateField.d.ts +26 -0
  278. package/lib/typescript/organisms/DateField.d.ts.map +1 -0
  279. package/lib/typescript/organisms/DatePicker.d.ts +49 -0
  280. package/lib/typescript/organisms/DatePicker.d.ts.map +1 -0
  281. package/lib/typescript/organisms/List.d.ts +35 -0
  282. package/lib/typescript/organisms/List.d.ts.map +1 -0
  283. package/lib/typescript/organisms/Modal.d.ts +25 -0
  284. package/lib/typescript/organisms/Modal.d.ts.map +1 -0
  285. package/lib/typescript/organisms/Screen.d.ts +26 -0
  286. package/lib/typescript/organisms/Screen.d.ts.map +1 -0
  287. package/lib/typescript/organisms/SearchList.d.ts +40 -0
  288. package/lib/typescript/organisms/SearchList.d.ts.map +1 -0
  289. package/lib/typescript/organisms/Select.d.ts +25 -0
  290. package/lib/typescript/organisms/Select.d.ts.map +1 -0
  291. package/lib/typescript/organisms/Toast.d.ts +28 -0
  292. package/lib/typescript/organisms/Toast.d.ts.map +1 -0
  293. package/lib/typescript/organisms/ToastProvider.d.ts +36 -0
  294. package/lib/typescript/organisms/ToastProvider.d.ts.map +1 -0
  295. package/lib/typescript/organisms/Wizard.d.ts +40 -0
  296. package/lib/typescript/organisms/Wizard.d.ts.map +1 -0
  297. package/lib/typescript/organisms/index.d.ts +27 -0
  298. package/lib/typescript/organisms/index.d.ts.map +1 -0
  299. package/lib/typescript/theme/UIProvider.d.ts +47 -0
  300. package/lib/typescript/theme/UIProvider.d.ts.map +1 -0
  301. package/lib/typescript/theme/createStyles.d.ts +21 -0
  302. package/lib/typescript/theme/createStyles.d.ts.map +1 -0
  303. package/lib/typescript/theme/createTheme.d.ts +9 -0
  304. package/lib/typescript/theme/createTheme.d.ts.map +1 -0
  305. package/lib/typescript/theme/index.d.ts +14 -0
  306. package/lib/typescript/theme/index.d.ts.map +1 -0
  307. package/lib/typescript/theme/insets.d.ts +9 -0
  308. package/lib/typescript/theme/insets.d.ts.map +1 -0
  309. package/lib/typescript/theme/labels.d.ts +13 -0
  310. package/lib/typescript/theme/labels.d.ts.map +1 -0
  311. package/lib/typescript/theme/palettes.d.ts +24 -0
  312. package/lib/typescript/theme/palettes.d.ts.map +1 -0
  313. package/lib/typescript/theme/tokens.d.ts +41 -0
  314. package/lib/typescript/theme/tokens.d.ts.map +1 -0
  315. package/lib/typescript/theme/types.d.ts +24 -0
  316. package/lib/typescript/theme/types.d.ts.map +1 -0
  317. package/package.json +311 -0
  318. package/registry/alert-provider.json +21 -0
  319. package/registry/alert.json +19 -0
  320. package/registry/avatar-header.json +18 -0
  321. package/registry/avatar.json +18 -0
  322. package/registry/badge.json +18 -0
  323. package/registry/bottom-sheet.json +18 -0
  324. package/registry/button.json +18 -0
  325. package/registry/card.json +18 -0
  326. package/registry/checkbox.json +18 -0
  327. package/registry/core.json +64 -0
  328. package/registry/date-field.json +24 -0
  329. package/registry/date-picker.json +23 -0
  330. package/registry/divider.json +18 -0
  331. package/registry/empty-state.json +18 -0
  332. package/registry/fab.json +19 -0
  333. package/registry/form-actions.json +19 -0
  334. package/registry/icon-button.json +19 -0
  335. package/registry/image.json +20 -0
  336. package/registry/index.json +465 -0
  337. package/registry/info-row.json +19 -0
  338. package/registry/input.json +18 -0
  339. package/registry/key-value-row.json +18 -0
  340. package/registry/list.json +20 -0
  341. package/registry/manifest.json +263 -0
  342. package/registry/modal.json +21 -0
  343. package/registry/option-card.json +18 -0
  344. package/registry/pressable-scale.json +18 -0
  345. package/registry/screen.json +18 -0
  346. package/registry/search-list.json +23 -0
  347. package/registry/select.json +18 -0
  348. package/registry/spinner.json +18 -0
  349. package/registry/stepper.json +18 -0
  350. package/registry/steps.json +18 -0
  351. package/registry/theme-toggle.json +18 -0
  352. package/registry/title.json +21 -0
  353. package/registry/toast-provider.json +20 -0
  354. package/registry/toast.json +18 -0
  355. package/registry/wizard.json +20 -0
  356. package/src/atoms/Avatar.tsx +40 -0
  357. package/src/atoms/Badge.tsx +55 -0
  358. package/src/atoms/Button.tsx +186 -0
  359. package/src/atoms/Card.tsx +27 -0
  360. package/src/atoms/Checkbox.tsx +75 -0
  361. package/src/atoms/Divider.tsx +14 -0
  362. package/src/atoms/EmptyState.tsx +60 -0
  363. package/src/atoms/Fab.tsx +63 -0
  364. package/src/atoms/IconButton.tsx +53 -0
  365. package/src/atoms/Image.tsx +137 -0
  366. package/src/atoms/Input.tsx +166 -0
  367. package/src/atoms/KeyValueRow.tsx +48 -0
  368. package/src/atoms/PressableScale.tsx +52 -0
  369. package/src/atoms/Spinner.tsx +127 -0
  370. package/src/atoms/Text.tsx +58 -0
  371. package/src/atoms/index.ts +30 -0
  372. package/src/icons/Icon.tsx +27 -0
  373. package/src/icons/defaultIcons.tsx +292 -0
  374. package/src/icons/index.ts +4 -0
  375. package/src/icons/types.ts +27 -0
  376. package/src/index.ts +5 -0
  377. package/src/molecules/AvatarHeader.tsx +69 -0
  378. package/src/molecules/FormActions.tsx +52 -0
  379. package/src/molecules/InfoRow.tsx +52 -0
  380. package/src/molecules/OptionCard.tsx +82 -0
  381. package/src/molecules/Stepper.tsx +76 -0
  382. package/src/molecules/Steps.tsx +198 -0
  383. package/src/molecules/ThemeToggle.tsx +67 -0
  384. package/src/molecules/index.ts +14 -0
  385. package/src/organisms/Alert.tsx +162 -0
  386. package/src/organisms/AlertProvider.tsx +125 -0
  387. package/src/organisms/BottomSheet.tsx +95 -0
  388. package/src/organisms/DateField.tsx +134 -0
  389. package/src/organisms/DatePicker.tsx +255 -0
  390. package/src/organisms/List.tsx +154 -0
  391. package/src/organisms/Modal.tsx +251 -0
  392. package/src/organisms/Screen.tsx +84 -0
  393. package/src/organisms/SearchList.tsx +186 -0
  394. package/src/organisms/Select.tsx +156 -0
  395. package/src/organisms/Toast.tsx +135 -0
  396. package/src/organisms/ToastProvider.tsx +166 -0
  397. package/src/organisms/Wizard.tsx +137 -0
  398. package/src/organisms/index.ts +26 -0
  399. package/src/theme/UIProvider.tsx +129 -0
  400. package/src/theme/createStyles.ts +40 -0
  401. package/src/theme/createTheme.ts +49 -0
  402. package/src/theme/index.ts +22 -0
  403. package/src/theme/insets.ts +9 -0
  404. package/src/theme/labels.ts +23 -0
  405. package/src/theme/palettes.ts +53 -0
  406. package/src/theme/tokens.ts +113 -0
  407. package/src/theme/types.ts +27 -0
@@ -0,0 +1,137 @@
1
+ import React, { memo, useCallback, useEffect, useState } from 'react';
2
+ import {
3
+ Image as RNImage,
4
+ Platform,
5
+ StyleSheet,
6
+ View,
7
+ type ImageErrorEventData,
8
+ type ImageResizeMode,
9
+ type ImageSourcePropType,
10
+ type NativeSyntheticEvent,
11
+ type StyleProp,
12
+ type ViewStyle,
13
+ } from 'react-native';
14
+ import { createStyles } from '../theme/createStyles';
15
+ import { Spinner } from './Spinner';
16
+
17
+ export interface ImageProps {
18
+ source: ImageSourcePropType;
19
+ width?: number;
20
+ height?: number;
21
+ /** @default 'cover' */
22
+ resizeMode?: ImageResizeMode;
23
+ /** Radio de las esquinas, mismo patrón que Avatar/Card. @default 0 */
24
+ radius?: number;
25
+ /** Qué mostrar mientras carga. `false` para no mostrar nada. @default true (spinner chico) */
26
+ loading?: React.ReactNode | boolean;
27
+ /** Qué mostrar si la carga falla. @default un placeholder gris, sin contenido */
28
+ fallback?: React.ReactNode;
29
+ /**
30
+ * 'high' dispara Image.prefetch() al montar, antes de que <Image> arranque
31
+ * su propio ciclo de carga — pensado para la imagen above-the-fold de una
32
+ * pantalla (la primera que el usuario ve). Sin costo si ya está en caché.
33
+ * @default 'normal'
34
+ */
35
+ priority?: 'low' | 'normal' | 'high';
36
+ style?: StyleProp<ViewStyle>;
37
+ onLoadEnd?: () => void;
38
+ onError?: (error: NativeSyntheticEvent<ImageErrorEventData>) => void;
39
+ testID?: string;
40
+ }
41
+
42
+ const useStyles = createStyles((theme) => ({
43
+ container: { overflow: 'hidden', backgroundColor: theme.colors.border + '30' },
44
+ overlay: { alignItems: 'center', justifyContent: 'center' },
45
+ fallback: { flex: 1, backgroundColor: theme.colors.border + '30' },
46
+ }));
47
+
48
+ function sourceUri(source: ImageSourcePropType): string | undefined {
49
+ return typeof source === 'object' && source !== null && 'uri' in source ? source.uri : undefined;
50
+ }
51
+
52
+ /**
53
+ * Image
54
+ * Wrapper cero-dependencias sobre <Image> de RN: agrega estado de carga y
55
+ * error (con los mismos placeholders que el resto de la librería), y expone
56
+ * `priority="high"` para adelantar la descarga vía Image.prefetch(). El
57
+ * cache real (disco/memoria) lo maneja el motor de imágenes nativo de RN —
58
+ * esto no lo reimplementa, solo no lo deja apagado por accidente: en iOS
59
+ * fuerza `cache="force-cache"` (usa el disco aunque el header HTTP no lo
60
+ * pida); en Android el cache de disco de la imagen nativa ya está siempre
61
+ * activo, no hay knob equivalente que tocar.
62
+ */
63
+ export const Image = memo(
64
+ ({
65
+ source,
66
+ width,
67
+ height,
68
+ resizeMode = 'cover',
69
+ radius = 0,
70
+ loading = true,
71
+ fallback,
72
+ priority = 'normal',
73
+ style,
74
+ onLoadEnd,
75
+ onError,
76
+ testID,
77
+ }: ImageProps) => {
78
+ const styles = useStyles();
79
+ const [status, setStatus] = useState<'loading' | 'loaded' | 'error'>('loading');
80
+ const uri = sourceUri(source);
81
+
82
+ useEffect(() => {
83
+ // Resetea el estado si cambia la imagen (misma instancia de Image,
84
+ // source distinto: p.ej. avatar de un usuario a otro en la misma fila).
85
+ setStatus('loading');
86
+ }, [uri ?? source]);
87
+
88
+ useEffect(() => {
89
+ if (priority === 'high' && uri) {
90
+ RNImage.prefetch(uri).catch(() => {});
91
+ }
92
+ }, [priority, uri]);
93
+
94
+ const handleError = useCallback(
95
+ (e: NativeSyntheticEvent<ImageErrorEventData>) => {
96
+ setStatus('error');
97
+ onError?.(e);
98
+ },
99
+ [onError]
100
+ );
101
+
102
+ const handleLoadEnd = useCallback(() => {
103
+ setStatus('loaded');
104
+ onLoadEnd?.();
105
+ }, [onLoadEnd]);
106
+
107
+ return (
108
+ <View style={[styles.container, { width, height, borderRadius: radius }, style]} testID={testID}>
109
+ {status !== 'error' && (
110
+ <RNImage
111
+ source={source}
112
+ resizeMode={resizeMode}
113
+ style={StyleSheet.absoluteFill}
114
+ fadeDuration={Platform.OS === 'android' ? 150 : undefined}
115
+ {...(Platform.OS === 'ios' ? { cache: 'force-cache' as const } : null)}
116
+ onLoadEnd={handleLoadEnd}
117
+ onError={handleError}
118
+ />
119
+ )}
120
+ {status === 'loading' && loading !== false && (
121
+ <View style={[StyleSheet.absoluteFill, styles.overlay]}>
122
+ {loading === true ? <Spinner size="small" fullscreen={false} /> : loading}
123
+ </View>
124
+ )}
125
+ {status === 'error' && (fallback ?? <View style={styles.fallback} />)}
126
+ </View>
127
+ );
128
+ }
129
+ );
130
+ Image.displayName = 'Image';
131
+
132
+ /**
133
+ * Precarga una URL antes de montar el componente (p.ej. al recibir la
134
+ * respuesta de un listado, antes de navegar al detalle). Re-exporta
135
+ * Image.prefetch de RN — no hay nada zero-dep que agregarle encima.
136
+ */
137
+ export const prefetchImage = RNImage.prefetch;
@@ -0,0 +1,166 @@
1
+ import React, { memo, useRef, useState } from 'react';
2
+ import {
3
+ ActivityIndicator,
4
+ Animated,
5
+ Text,
6
+ TextInput,
7
+ TouchableOpacity,
8
+ View,
9
+ type StyleProp,
10
+ type TextInputProps,
11
+ type ViewStyle,
12
+ } from 'react-native';
13
+ import { createStyles } from '../theme/createStyles';
14
+ import { useAllowFontScaling, useColors } from '../theme/UIProvider';
15
+ import { Icon } from '../icons/Icon';
16
+ import type { IconName } from '../icons/types';
17
+
18
+ export interface InputProps extends Omit<TextInputProps, 'style'> {
19
+ label?: string;
20
+ /** Muestra un asterisco junto al label. Puramente visual, no valida nada. */
21
+ required?: boolean;
22
+ error?: string;
23
+ containerStyle?: StyleProp<ViewStyle>;
24
+ style?: TextInputProps['style'];
25
+ leftIconName?: IconName;
26
+ rightIconName?: IconName;
27
+ onRightIconPress?: () => void;
28
+ isPassword?: boolean;
29
+ isLoading?: boolean;
30
+ }
31
+
32
+ const useStyles = createStyles((theme) => ({
33
+ container: { marginBottom: theme.tokens.spacing.lg, width: '100%' },
34
+ label: {
35
+ marginBottom: theme.tokens.spacing.sm,
36
+ fontSize: theme.tokens.fontSize.md,
37
+ fontWeight: theme.tokens.fontWeight.medium,
38
+ color: theme.colors.text,
39
+ },
40
+ required: { color: theme.colors.error },
41
+ inputWrapper: {
42
+ flexDirection: 'row',
43
+ alignItems: 'center',
44
+ backgroundColor: theme.colors.inputBackground,
45
+ borderRadius: theme.tokens.radius.lg,
46
+ borderWidth: 2,
47
+ minHeight: 50,
48
+ },
49
+ input: {
50
+ flex: 1,
51
+ paddingVertical: theme.tokens.spacing.md,
52
+ paddingHorizontal: theme.tokens.spacing.lg,
53
+ fontSize: theme.tokens.fontSize.lg,
54
+ color: theme.colors.text,
55
+ },
56
+ leftIcon: { marginLeft: theme.tokens.spacing.lg, marginRight: -theme.tokens.spacing.xs },
57
+ rightIcon: { padding: theme.tokens.spacing.sm + 2, marginRight: theme.tokens.spacing.xs },
58
+ errorText: { marginTop: theme.tokens.spacing.xs, fontSize: theme.tokens.fontSize.sm, color: theme.colors.error },
59
+ }));
60
+
61
+ /**
62
+ * Input
63
+ * El borde anima color entre border/primary/error con Animated (no
64
+ * useNativeDriver: los navegadores de color en RN sin Fabric solo son
65
+ * confiables en el hilo de JS; el costo es despreciable, se anima un borde).
66
+ */
67
+ export const Input = memo(
68
+ ({
69
+ label,
70
+ required = false,
71
+ error,
72
+ containerStyle,
73
+ leftIconName,
74
+ rightIconName,
75
+ onRightIconPress,
76
+ isPassword = false,
77
+ isLoading = false,
78
+ style,
79
+ onFocus,
80
+ onBlur,
81
+ testID,
82
+ ...props
83
+ }: InputProps) => {
84
+ const colors = useColors();
85
+ const styles = useStyles();
86
+ const allowFontScaling = useAllowFontScaling();
87
+ const [isFocused, setIsFocused] = useState(false);
88
+ const [showPassword, setShowPassword] = useState(false);
89
+ const focusProgress = useRef(new Animated.Value(0)).current;
90
+
91
+ const handleFocus: TextInputProps['onFocus'] = (e) => {
92
+ setIsFocused(true);
93
+ Animated.timing(focusProgress, { toValue: 1, duration: 200, useNativeDriver: false }).start();
94
+ onFocus?.(e);
95
+ };
96
+
97
+ const handleBlur: TextInputProps['onBlur'] = (e) => {
98
+ setIsFocused(false);
99
+ Animated.timing(focusProgress, { toValue: 0, duration: 200, useNativeDriver: false }).start();
100
+ onBlur?.(e);
101
+ };
102
+
103
+ const borderColor = error
104
+ ? colors.error
105
+ : focusProgress.interpolate({ outputRange: [colors.border, colors.primary], inputRange: [0, 1] });
106
+
107
+ return (
108
+ <View style={[styles.container, containerStyle]} testID={testID}>
109
+ {label && (
110
+ <Text allowFontScaling={allowFontScaling} style={styles.label}>
111
+ {label}
112
+ {required && <Text style={styles.required}> *</Text>}
113
+ </Text>
114
+ )}
115
+
116
+ <Animated.View style={[styles.inputWrapper, { borderColor }]}>
117
+ {leftIconName && <Icon name={leftIconName} size={20} color={colors.textLight} style={styles.leftIcon} />}
118
+
119
+ <TextInput
120
+ style={[styles.input, style]}
121
+ placeholderTextColor={colors.textLight}
122
+ onFocus={handleFocus}
123
+ onBlur={handleBlur}
124
+ secureTextEntry={isPassword && !showPassword}
125
+ allowFontScaling={allowFontScaling}
126
+ textAlignVertical="center"
127
+ accessibilityLabel={label ?? props.placeholder}
128
+ {...props}
129
+ />
130
+
131
+ {isLoading ? (
132
+ <View style={styles.rightIcon}>
133
+ <ActivityIndicator size="small" color={colors.primary} />
134
+ </View>
135
+ ) : isPassword ? (
136
+ <TouchableOpacity
137
+ onPress={() => setShowPassword((v) => !v)}
138
+ style={styles.rightIcon}
139
+ accessibilityRole="button"
140
+ accessibilityLabel={showPassword ? 'Hide password' : 'Show password'}
141
+ >
142
+ <Icon name={showPassword ? 'eye-off' : 'eye'} size={20} color={colors.textLight} />
143
+ </TouchableOpacity>
144
+ ) : rightIconName ? (
145
+ <TouchableOpacity
146
+ onPress={onRightIconPress}
147
+ style={styles.rightIcon}
148
+ disabled={!onRightIconPress}
149
+ accessibilityRole="button"
150
+ accessibilityLabel="Clear"
151
+ >
152
+ <Icon name={rightIconName} size={20} color={colors.textLight} />
153
+ </TouchableOpacity>
154
+ ) : null}
155
+ </Animated.View>
156
+
157
+ {!!error && (
158
+ <Text allowFontScaling={allowFontScaling} style={styles.errorText}>
159
+ {error}
160
+ </Text>
161
+ )}
162
+ </View>
163
+ );
164
+ }
165
+ );
166
+ Input.displayName = 'Input';
@@ -0,0 +1,48 @@
1
+ import React, { memo } from 'react';
2
+ import { Text, View, type StyleProp, type TextStyle, type ViewStyle } from 'react-native';
3
+ import { createStyles } from '../theme/createStyles';
4
+ import { useAllowFontScaling } from '../theme/UIProvider';
5
+
6
+ export interface KeyValueRowProps {
7
+ label: React.ReactNode;
8
+ value: React.ReactNode;
9
+ style?: StyleProp<ViewStyle>;
10
+ labelStyle?: StyleProp<TextStyle>;
11
+ valueStyle?: StyleProp<TextStyle>;
12
+ }
13
+
14
+ const useStyles = createStyles((theme) => ({
15
+ row: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center' },
16
+ label: { fontSize: theme.tokens.fontSize.sm, fontWeight: theme.tokens.fontWeight.semibold, color: theme.colors.textLight },
17
+ value: { fontSize: theme.tokens.fontSize.sm, textAlign: 'right', color: theme.colors.text },
18
+ }));
19
+
20
+ /**
21
+ * KeyValueRow
22
+ * Fila label (izquierda) / value (derecha). Si label/value son string o
23
+ * number, se renderizan con el estilo default; si ya vienen envueltos en un
24
+ * componente de texto propio, se respetan tal cual.
25
+ */
26
+ export const KeyValueRow = memo(({ label, value, style, labelStyle, valueStyle }: KeyValueRowProps) => {
27
+ const styles = useStyles();
28
+ const allowFontScaling = useAllowFontScaling();
29
+ return (
30
+ <View style={[styles.row, style]}>
31
+ {typeof label === 'string' || typeof label === 'number' ? (
32
+ <Text allowFontScaling={allowFontScaling} style={[styles.label, labelStyle]}>
33
+ {label}
34
+ </Text>
35
+ ) : (
36
+ label
37
+ )}
38
+ {typeof value === 'string' || typeof value === 'number' ? (
39
+ <Text allowFontScaling={allowFontScaling} style={[styles.value, valueStyle]}>
40
+ {value}
41
+ </Text>
42
+ ) : (
43
+ value
44
+ )}
45
+ </View>
46
+ );
47
+ });
48
+ KeyValueRow.displayName = 'KeyValueRow';
@@ -0,0 +1,52 @@
1
+ import React, { memo, useRef } from 'react';
2
+ import { Animated, Pressable, type PressableProps, type GestureResponderEvent } from 'react-native';
3
+
4
+ export interface PressableScaleProps extends PressableProps {
5
+ /** Escala objetivo al presionar. @default 0.96 */
6
+ scaleTo?: number;
7
+ children: React.ReactNode;
8
+ }
9
+
10
+ /**
11
+ * PressableScale
12
+ * Feedback táctil de "achicarse" al presionar, con Animated.spring de RN
13
+ * (useNativeDriver: true — corre en el hilo nativo, sin coste de JS por frame).
14
+ * No depende de reanimated: la librería entera es cero-dependencias.
15
+ */
16
+ export const PressableScale = memo(
17
+ ({ scaleTo = 0.96, style, children, onPressIn, onPressOut, disabled, ...props }: PressableScaleProps) => {
18
+ const scale = useRef(new Animated.Value(1)).current;
19
+
20
+ const animateTo = (value: number) => {
21
+ Animated.spring(scale, {
22
+ toValue: value,
23
+ useNativeDriver: true,
24
+ speed: 50,
25
+ bounciness: 6,
26
+ }).start();
27
+ };
28
+
29
+ const handlePressIn = (e: GestureResponderEvent) => {
30
+ if (!disabled) animateTo(scaleTo);
31
+ onPressIn?.(e);
32
+ };
33
+
34
+ const handlePressOut = (e: GestureResponderEvent) => {
35
+ if (!disabled) animateTo(1);
36
+ onPressOut?.(e);
37
+ };
38
+
39
+ return (
40
+ <Pressable
41
+ {...props}
42
+ disabled={disabled}
43
+ onPressIn={handlePressIn}
44
+ onPressOut={handlePressOut}
45
+ style={style}
46
+ >
47
+ <Animated.View style={{ transform: [{ scale }] }}>{children}</Animated.View>
48
+ </Pressable>
49
+ );
50
+ }
51
+ );
52
+ PressableScale.displayName = 'PressableScale';
@@ -0,0 +1,127 @@
1
+ import React, { memo, useEffect, useRef } from 'react';
2
+ import { ActivityIndicator, Animated, Easing, Text, View } from 'react-native';
3
+ import { createStyles } from '../theme/createStyles';
4
+ import { useAllowFontScaling, useColors } from '../theme/UIProvider';
5
+
6
+ export type SpinnerVariant = 'native' | 'dots' | 'ring';
7
+
8
+ export interface SpinnerProps {
9
+ size?: 'small' | 'large';
10
+ color?: string;
11
+ text?: string;
12
+ /** @default true. En false, no ocupa flex:1 (útil inline, dentro de un botón/fila). */
13
+ fullscreen?: boolean;
14
+ /**
15
+ * 'native' usa el ActivityIndicator del sistema; 'dots' y 'ring' son
16
+ * indicadores propios, iguales en iOS y Android.
17
+ * @default 'native'
18
+ */
19
+ variant?: SpinnerVariant;
20
+ /** Indicador totalmente propio. Gana sobre `variant`. */
21
+ indicator?: React.ReactNode;
22
+ testID?: string;
23
+ }
24
+
25
+ const useStyles = createStyles((theme) => ({
26
+ container: { justifyContent: 'center', alignItems: 'center', padding: theme.tokens.spacing.xl },
27
+ text: { marginTop: theme.tokens.spacing.md, color: theme.colors.textLight, fontSize: theme.tokens.fontSize.md },
28
+ dots: { flexDirection: 'row', gap: theme.tokens.spacing.sm },
29
+ }));
30
+
31
+ /** Tres puntos que laten en secuencia. Animated + useNativeDriver: corre en el hilo nativo. */
32
+ const DotsIndicator = memo(({ color, dotSize }: { color: string; dotSize: number }) => {
33
+ const dots = [useRef(new Animated.Value(0)).current, useRef(new Animated.Value(0)).current, useRef(new Animated.Value(0)).current];
34
+
35
+ useEffect(() => {
36
+ const animations = dots.map((dot, i) =>
37
+ Animated.loop(
38
+ Animated.sequence([
39
+ Animated.delay(i * 140),
40
+ Animated.timing(dot, { toValue: 1, duration: 320, useNativeDriver: true, easing: Easing.out(Easing.quad) }),
41
+ Animated.timing(dot, { toValue: 0, duration: 320, useNativeDriver: true, easing: Easing.in(Easing.quad) }),
42
+ Animated.delay((2 - i) * 140),
43
+ ])
44
+ )
45
+ );
46
+ animations.forEach((a) => a.start());
47
+ // Sin stop() los loops siguen corriendo tras desmontar y mantienen vivo
48
+ // el árbol de Animated.
49
+ return () => animations.forEach((a) => a.stop());
50
+ }, []);
51
+
52
+ return (
53
+ <View style={{ flexDirection: 'row', gap: dotSize * 0.6 }}>
54
+ {dots.map((dot, i) => (
55
+ <Animated.View
56
+ key={i}
57
+ style={{
58
+ width: dotSize,
59
+ height: dotSize,
60
+ borderRadius: dotSize / 2,
61
+ backgroundColor: color,
62
+ opacity: dot.interpolate({ inputRange: [0, 1], outputRange: [0.3, 1] }),
63
+ transform: [{ scale: dot.interpolate({ inputRange: [0, 1], outputRange: [0.75, 1] }) }],
64
+ }}
65
+ />
66
+ ))}
67
+ </View>
68
+ );
69
+ });
70
+ DotsIndicator.displayName = 'DotsIndicator';
71
+
72
+ /** Anillo que gira: un borde con un solo lado coloreado. */
73
+ const RingIndicator = memo(({ color, diameter }: { color: string; diameter: number }) => {
74
+ const spin = useRef(new Animated.Value(0)).current;
75
+
76
+ useEffect(() => {
77
+ const animation = Animated.loop(
78
+ Animated.timing(spin, { toValue: 1, duration: 900, useNativeDriver: true, easing: Easing.linear })
79
+ );
80
+ animation.start();
81
+ return () => animation.stop();
82
+ }, []);
83
+
84
+ return (
85
+ <Animated.View
86
+ style={{
87
+ width: diameter,
88
+ height: diameter,
89
+ borderRadius: diameter / 2,
90
+ borderWidth: Math.max(2, diameter / 10),
91
+ borderColor: color + '33',
92
+ borderTopColor: color,
93
+ transform: [{ rotate: spin.interpolate({ inputRange: [0, 1], outputRange: ['0deg', '360deg'] }) }],
94
+ }}
95
+ />
96
+ );
97
+ });
98
+ RingIndicator.displayName = 'RingIndicator';
99
+
100
+ export const Spinner = memo(
101
+ ({ size = 'large', color, text, fullscreen = true, variant = 'native', indicator, testID }: SpinnerProps) => {
102
+ const colors = useColors();
103
+ const styles = useStyles();
104
+ const allowFontScaling = useAllowFontScaling();
105
+ const resolvedColor = color || colors.primary;
106
+ const scale = size === 'small' ? 8 : 12;
107
+
108
+ const renderIndicator = () => {
109
+ if (indicator) return indicator;
110
+ if (variant === 'dots') return <DotsIndicator color={resolvedColor} dotSize={scale} />;
111
+ if (variant === 'ring') return <RingIndicator color={resolvedColor} diameter={scale * 3} />;
112
+ return <ActivityIndicator size={size} color={resolvedColor} />;
113
+ };
114
+
115
+ return (
116
+ <View style={[styles.container, fullscreen && { flex: 1 }]} testID={testID}>
117
+ {renderIndicator()}
118
+ {text && (
119
+ <Text allowFontScaling={allowFontScaling} style={styles.text}>
120
+ {text}
121
+ </Text>
122
+ )}
123
+ </View>
124
+ );
125
+ }
126
+ );
127
+ Spinner.displayName = 'Spinner';
@@ -0,0 +1,58 @@
1
+ import React, { memo } from 'react';
2
+ import { Text as RNText, type StyleProp, type TextProps, type TextStyle } from 'react-native';
3
+ import { createStyles } from '../theme/createStyles';
4
+ import { useAllowFontScaling, useColors } from '../theme/UIProvider';
5
+
6
+ export interface TypographyProps extends TextProps {
7
+ children?: React.ReactNode;
8
+ style?: StyleProp<TextStyle>;
9
+ color?: string;
10
+ align?: 'left' | 'center' | 'right';
11
+ }
12
+
13
+ const useStyles = createStyles((theme) => ({
14
+ title: {
15
+ fontSize: theme.tokens.fontSize.xxl,
16
+ fontWeight: theme.tokens.fontWeight.bold,
17
+ letterSpacing: -0.5,
18
+ color: theme.colors.text,
19
+ },
20
+ subtitle: {
21
+ fontSize: theme.tokens.fontSize.lg,
22
+ fontWeight: theme.tokens.fontWeight.medium,
23
+ color: theme.colors.text,
24
+ },
25
+ body: {
26
+ fontSize: theme.tokens.fontSize.md,
27
+ lineHeight: theme.tokens.lineHeight.md,
28
+ color: theme.colors.text,
29
+ },
30
+ caption: {
31
+ fontSize: theme.tokens.fontSize.sm,
32
+ color: theme.colors.textLight,
33
+ },
34
+ }));
35
+
36
+ function makeVariant(variant: keyof ReturnType<typeof useStyles>, defaultColor: 'text' | 'textLight') {
37
+ const Component = memo(({ children, style, color, align = 'left', ...props }: TypographyProps) => {
38
+ const styles = useStyles();
39
+ const colors = useColors();
40
+ const allowFontScaling = useAllowFontScaling();
41
+ return (
42
+ <RNText
43
+ allowFontScaling={allowFontScaling}
44
+ style={[styles[variant], { color: color || colors[defaultColor], textAlign: align }, style]}
45
+ {...props}
46
+ >
47
+ {children}
48
+ </RNText>
49
+ );
50
+ });
51
+ Component.displayName = variant;
52
+ return Component;
53
+ }
54
+
55
+ export const Title = makeVariant('title', 'text');
56
+ export const Subtitle = makeVariant('subtitle', 'text');
57
+ export const Body = makeVariant('body', 'text');
58
+ export const Caption = makeVariant('caption', 'textLight');
@@ -0,0 +1,30 @@
1
+ export { Title, Subtitle, Body, Caption } from './Text';
2
+ export type { TypographyProps } from './Text';
3
+ export { Button } from './Button';
4
+ export type { ButtonProps, ButtonVariant, ButtonSize } from './Button';
5
+ export { IconButton } from './IconButton';
6
+ export type { IconButtonProps } from './IconButton';
7
+ export { Input } from './Input';
8
+ export type { InputProps } from './Input';
9
+ export { Checkbox } from './Checkbox';
10
+ export type { CheckboxProps } from './Checkbox';
11
+ export { Badge } from './Badge';
12
+ export type { BadgeProps, BadgeVariant } from './Badge';
13
+ export { Card } from './Card';
14
+ export type { CardProps } from './Card';
15
+ export { Divider } from './Divider';
16
+ export type { DividerProps } from './Divider';
17
+ export { Avatar } from './Avatar';
18
+ export type { AvatarProps } from './Avatar';
19
+ export { Image, prefetchImage } from './Image';
20
+ export type { ImageProps } from './Image';
21
+ export { Spinner } from './Spinner';
22
+ export type { SpinnerProps, SpinnerVariant } from './Spinner';
23
+ export { EmptyState } from './EmptyState';
24
+ export type { EmptyStateProps } from './EmptyState';
25
+ export { KeyValueRow } from './KeyValueRow';
26
+ export type { KeyValueRowProps } from './KeyValueRow';
27
+ export { Fab } from './Fab';
28
+ export type { FabProps } from './Fab';
29
+ export { PressableScale } from './PressableScale';
30
+ export type { PressableScaleProps } from './PressableScale';
@@ -0,0 +1,27 @@
1
+ import React, { memo } from 'react';
2
+ import { View, type StyleProp, type ViewStyle } from 'react-native';
3
+ import { useColors, useIcons } from '../theme/UIProvider';
4
+ import type { IconName } from './types';
5
+
6
+ export interface IconProps {
7
+ name: IconName;
8
+ size?: number;
9
+ color?: string;
10
+ style?: StyleProp<ViewStyle>;
11
+ }
12
+
13
+ /**
14
+ * Icon
15
+ * Resuelve el glifo vía el renderer activo (UIProvider.icons, default zero-dep
16
+ * si no se configuró ninguno). Uso interno de la librería — los componentes
17
+ * públicos exponen `icon?: ReactNode` además de esto, para que el consumidor
18
+ * pueda inyectar cualquier ícono sin pasar por el sistema de nombres.
19
+ */
20
+ export const Icon = memo(({ name, size = 20, color, style }: IconProps) => {
21
+ const colors = useColors();
22
+ const render = useIcons();
23
+ const glyph = render(name, { size, color: color ?? colors.text });
24
+ if (!style) return <>{glyph}</>;
25
+ return <View style={style}>{glyph}</View>;
26
+ });
27
+ Icon.displayName = 'Icon';