@wireservers-ui/react-natives 1.0.0-rc.3 → 1.0.1-rc1

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 (402) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +214 -98
  3. package/bin/cli.js +356 -0
  4. package/package.json +28 -49
  5. package/src/accordion/accordion-content.tsx +30 -30
  6. package/src/accordion/accordion-icon.tsx +54 -54
  7. package/src/accordion/accordion-item.tsx +37 -37
  8. package/src/accordion/accordion-title-text.tsx +24 -24
  9. package/src/accordion/accordion-trigger.tsx +38 -38
  10. package/src/accordion/accordion.tsx +91 -91
  11. package/src/accordion/index.ts +24 -24
  12. package/src/accordion/styles.ts +74 -74
  13. package/src/accordion/types.ts +56 -56
  14. package/src/actionsheet/actionsheet-backdrop.tsx +23 -23
  15. package/src/actionsheet/actionsheet-content.tsx +19 -19
  16. package/src/actionsheet/actionsheet-drag-indicator-wrapper.tsx +19 -19
  17. package/src/actionsheet/actionsheet-drag-indicator.tsx +19 -19
  18. package/src/actionsheet/actionsheet-item-text.tsx +19 -19
  19. package/src/actionsheet/actionsheet-item.tsx +20 -20
  20. package/src/actionsheet/actionsheet-scroll-view.tsx +12 -12
  21. package/src/actionsheet/actionsheet.tsx +45 -45
  22. package/src/actionsheet/index.ts +20 -20
  23. package/src/actionsheet/styles.ts +25 -25
  24. package/src/actionsheet/types.ts +49 -49
  25. package/src/alert/alert-body.tsx +19 -19
  26. package/src/alert/alert-close-button.tsx +23 -23
  27. package/src/alert/alert-icon.tsx +40 -40
  28. package/src/alert/alert-text.tsx +22 -22
  29. package/src/alert/alert.tsx +33 -33
  30. package/src/alert/index.ts +15 -15
  31. package/src/alert/styles.ts +112 -112
  32. package/src/alert/types.ts +36 -36
  33. package/src/alert-dialog/alert-dialog.tsx +54 -54
  34. package/src/alert-dialog/index.ts +2 -2
  35. package/src/alert-dialog/styles.ts +40 -40
  36. package/src/alert-dialog/types.ts +40 -40
  37. package/src/aspect-ratio/aspect-ratio.tsx +20 -20
  38. package/src/aspect-ratio/index.ts +2 -2
  39. package/src/aspect-ratio/styles.ts +6 -6
  40. package/src/aspect-ratio/types.ts +7 -7
  41. package/src/avatar/avatar-badge.tsx +22 -22
  42. package/src/avatar/avatar-fallback-text.tsx +33 -33
  43. package/src/avatar/avatar-group.tsx +53 -53
  44. package/src/avatar/avatar-image.tsx +21 -21
  45. package/src/avatar/avatar.tsx +27 -27
  46. package/src/avatar/index.ts +14 -14
  47. package/src/avatar/styles.ts +94 -94
  48. package/src/avatar/types.ts +35 -35
  49. package/src/badge/badge-icon.tsx +20 -20
  50. package/src/badge/badge-text.tsx +24 -24
  51. package/src/badge/badge.tsx +39 -39
  52. package/src/badge/index.ts +11 -11
  53. package/src/badge/styles.ts +175 -175
  54. package/src/badge/types.ts +37 -37
  55. package/src/blockquote/blockquote.tsx +21 -21
  56. package/src/blockquote/index.ts +2 -2
  57. package/src/blockquote/styles.ts +11 -11
  58. package/src/blockquote/types.ts +6 -6
  59. package/src/box/box.tsx +19 -19
  60. package/src/box/index.ts +2 -2
  61. package/src/box/styles.ts +6 -6
  62. package/src/box/types.ts +6 -6
  63. package/src/breadcrumb/breadcrumb-item.tsx +20 -20
  64. package/src/breadcrumb/breadcrumb-link.tsx +20 -20
  65. package/src/breadcrumb/breadcrumb-text.tsx +19 -19
  66. package/src/breadcrumb/breadcrumb.tsx +43 -43
  67. package/src/breadcrumb/index.ts +12 -12
  68. package/src/breadcrumb/styles.ts +36 -36
  69. package/src/breadcrumb/types.ts +33 -33
  70. package/src/button/button-group.tsx +35 -35
  71. package/src/button/button-icon.tsx +37 -37
  72. package/src/button/button-spinner.tsx +12 -12
  73. package/src/button/button-text.tsx +27 -27
  74. package/src/button/button.tsx +42 -42
  75. package/src/button/index.ts +19 -19
  76. package/src/button/styles.ts +250 -250
  77. package/src/button/types.ts +67 -67
  78. package/src/calendar/calendar-day-cell.tsx +67 -67
  79. package/src/calendar/calendar-day-view.tsx +66 -66
  80. package/src/calendar/calendar-event.tsx +59 -59
  81. package/src/calendar/calendar-header.tsx +60 -60
  82. package/src/calendar/calendar-horizontal-view.tsx +372 -372
  83. package/src/calendar/calendar-legend.tsx +41 -41
  84. package/src/calendar/calendar-month-view.tsx +47 -47
  85. package/src/calendar/calendar-vertical-view.tsx +395 -395
  86. package/src/calendar/calendar-view-switcher.tsx +65 -65
  87. package/src/calendar/calendar-week-view.tsx +52 -52
  88. package/src/calendar/calendar.tsx +74 -74
  89. package/src/calendar/index.ts +27 -27
  90. package/src/calendar/styles.ts +367 -367
  91. package/src/calendar/types.ts +101 -101
  92. package/src/calendar/use-calendar.ts +170 -170
  93. package/src/calendar/utils.ts +278 -278
  94. package/src/card/card-body.tsx +22 -22
  95. package/src/card/card-footer.tsx +19 -19
  96. package/src/card/card-header.tsx +22 -22
  97. package/src/card/card.tsx +27 -27
  98. package/src/card/index.ts +13 -13
  99. package/src/card/styles.ts +54 -54
  100. package/src/card/types.ts +31 -31
  101. package/src/carousel/carousel.tsx +436 -436
  102. package/src/carousel/index.ts +2 -2
  103. package/src/carousel/styles.ts +21 -21
  104. package/src/carousel/types.ts +41 -41
  105. package/src/center/center.tsx +19 -19
  106. package/src/center/index.ts +2 -2
  107. package/src/center/styles.ts +6 -6
  108. package/src/center/types.ts +6 -6
  109. package/src/checkbox/checkbox-group.tsx +63 -63
  110. package/src/checkbox/checkbox-icon.tsx +35 -35
  111. package/src/checkbox/checkbox-indicator.tsx +30 -30
  112. package/src/checkbox/checkbox-label.tsx +24 -24
  113. package/src/checkbox/checkbox.tsx +86 -86
  114. package/src/checkbox/index.ts +14 -14
  115. package/src/checkbox/styles.ts +69 -69
  116. package/src/checkbox/types.ts +55 -55
  117. package/src/circular-progress/circular-progress.tsx +82 -82
  118. package/src/circular-progress/index.ts +2 -2
  119. package/src/circular-progress/styles.ts +31 -31
  120. package/src/circular-progress/types.ts +18 -18
  121. package/src/code/code.tsx +36 -36
  122. package/src/code/index.ts +2 -2
  123. package/src/code/styles.ts +25 -25
  124. package/src/code/types.ts +13 -13
  125. package/src/collapsible/collapsible.tsx +58 -58
  126. package/src/collapsible/index.ts +2 -2
  127. package/src/collapsible/styles.ts +5 -5
  128. package/src/collapsible/types.ts +21 -21
  129. package/src/color-picker/color-picker-box.tsx +115 -115
  130. package/src/color-picker/color-picker-slider.tsx +98 -98
  131. package/src/color-picker/color-picker.tsx +162 -162
  132. package/src/color-picker/color-utils.ts +215 -215
  133. package/src/color-picker/index.ts +34 -34
  134. package/src/color-picker/styles.ts +32 -32
  135. package/src/color-picker/types.ts +49 -49
  136. package/src/color-picker/use-pointer-drag.ts +80 -80
  137. package/src/container/container.tsx +19 -19
  138. package/src/container/index.ts +2 -2
  139. package/src/container/styles.ts +21 -21
  140. package/src/container/types.ts +10 -10
  141. package/src/date-picker/date-picker.tsx +136 -136
  142. package/src/date-picker/index.ts +15 -15
  143. package/src/date-picker/styles.ts +18 -18
  144. package/src/date-picker/types.ts +33 -33
  145. package/src/divider/divider.tsx +21 -21
  146. package/src/divider/index.ts +2 -2
  147. package/src/divider/styles.ts +14 -14
  148. package/src/divider/types.ts +7 -7
  149. package/src/drawer/drawer-backdrop.tsx +23 -23
  150. package/src/drawer/drawer-body.tsx +19 -19
  151. package/src/drawer/drawer-close-button.tsx +29 -29
  152. package/src/drawer/drawer-content.tsx +142 -142
  153. package/src/drawer/drawer-footer.tsx +19 -19
  154. package/src/drawer/drawer-header.tsx +19 -19
  155. package/src/drawer/drawer.tsx +54 -54
  156. package/src/drawer/index.ts +22 -22
  157. package/src/drawer/styles.ts +36 -36
  158. package/src/drawer/types.ts +62 -62
  159. package/src/empty/empty.tsx +53 -53
  160. package/src/empty/index.ts +2 -2
  161. package/src/empty/styles.ts +26 -26
  162. package/src/empty/types.ts +22 -22
  163. package/src/fab/fab-icon.tsx +20 -20
  164. package/src/fab/fab-label.tsx +22 -22
  165. package/src/fab/fab.tsx +45 -45
  166. package/src/fab/index.ts +11 -11
  167. package/src/fab/styles.ts +57 -57
  168. package/src/fab/types.ts +33 -33
  169. package/src/form-control/form-control-error-icon.tsx +25 -25
  170. package/src/form-control/form-control-error-message.tsx +40 -40
  171. package/src/form-control/form-control-helper-text.tsx +25 -25
  172. package/src/form-control/form-control-label-text.tsx +25 -25
  173. package/src/form-control/form-control-label.tsx +36 -36
  174. package/src/form-control/form-control.tsx +46 -46
  175. package/src/form-control/index.ts +20 -20
  176. package/src/form-control/styles.ts +105 -105
  177. package/src/form-control/types.ts +45 -45
  178. package/src/heading/heading.tsx +21 -21
  179. package/src/heading/index.ts +2 -2
  180. package/src/heading/styles.ts +24 -24
  181. package/src/heading/types.ts +19 -19
  182. package/src/icon/icon.tsx +21 -21
  183. package/src/icon/index.ts +2 -2
  184. package/src/icon/styles.ts +18 -18
  185. package/src/icon/types.ts +8 -8
  186. package/src/icon-button/icon-button.tsx +23 -23
  187. package/src/icon-button/index.ts +2 -2
  188. package/src/icon-button/styles.ts +78 -78
  189. package/src/icon-button/types.ts +15 -15
  190. package/src/image/image.tsx +20 -20
  191. package/src/image/index.ts +2 -2
  192. package/src/image/styles.ts +28 -28
  193. package/src/image/types.ts +11 -11
  194. package/src/index.ts +1039 -1039
  195. package/src/input/index.ts +13 -13
  196. package/src/input/input-field.tsx +35 -35
  197. package/src/input/input-icon.tsx +25 -25
  198. package/src/input/input-slot.tsx +24 -24
  199. package/src/input/input.tsx +73 -73
  200. package/src/input/styles.ts +90 -90
  201. package/src/input/types.ts +39 -39
  202. package/src/kbd/index.ts +2 -2
  203. package/src/kbd/kbd.tsx +21 -21
  204. package/src/kbd/styles.ts +11 -11
  205. package/src/kbd/types.ts +7 -7
  206. package/src/link/index.ts +4 -4
  207. package/src/link/link-text.tsx +19 -19
  208. package/src/link/link.tsx +31 -31
  209. package/src/link/styles.ts +19 -19
  210. package/src/link/types.ts +13 -13
  211. package/src/list/index.ts +2 -2
  212. package/src/list/list.tsx +55 -55
  213. package/src/list/styles.ts +8 -8
  214. package/src/list/types.ts +17 -17
  215. package/src/menu/index.ts +2 -2
  216. package/src/menu/menu.tsx +99 -99
  217. package/src/menu/styles.ts +14 -14
  218. package/src/menu/types.ts +30 -30
  219. package/src/modal/index.ts +18 -18
  220. package/src/modal/modal-backdrop.tsx +23 -23
  221. package/src/modal/modal-body.tsx +19 -19
  222. package/src/modal/modal-close-button.tsx +29 -29
  223. package/src/modal/modal-content.tsx +22 -22
  224. package/src/modal/modal-footer.tsx +19 -19
  225. package/src/modal/modal-header.tsx +19 -19
  226. package/src/modal/modal.tsx +50 -50
  227. package/src/modal/styles.ts +37 -37
  228. package/src/modal/types.ts +49 -49
  229. package/src/nativewind-env.d.ts +1 -1
  230. package/src/number-input/index.ts +18 -18
  231. package/src/number-input/number-input.tsx +161 -161
  232. package/src/number-input/styles.ts +35 -35
  233. package/src/number-input/types.ts +44 -44
  234. package/src/overlay/index.ts +2 -2
  235. package/src/overlay/overlay.tsx +21 -21
  236. package/src/overlay/styles.ts +6 -6
  237. package/src/overlay/types.ts +7 -7
  238. package/src/pagination/index.ts +2 -2
  239. package/src/pagination/pagination.tsx +58 -58
  240. package/src/pagination/styles.ts +27 -27
  241. package/src/pagination/types.ts +19 -19
  242. package/src/password-input/index.ts +14 -14
  243. package/src/password-input/password-input.tsx +79 -79
  244. package/src/password-input/styles.ts +25 -25
  245. package/src/password-input/types.ts +24 -24
  246. package/src/pin-input/index.ts +12 -12
  247. package/src/pin-input/pin-input.tsx +96 -96
  248. package/src/pin-input/styles.ts +16 -16
  249. package/src/pin-input/types.ts +26 -26
  250. package/src/popover/index.ts +2 -2
  251. package/src/popover/popover.tsx +98 -98
  252. package/src/popover/styles.ts +31 -31
  253. package/src/popover/types.ts +46 -46
  254. package/src/portal/index.ts +2 -2
  255. package/src/portal/portal.tsx +8 -8
  256. package/src/portal/styles.ts +2 -2
  257. package/src/portal/types.ts +3 -3
  258. package/src/pressable/index.ts +2 -2
  259. package/src/pressable/pressable.tsx +20 -20
  260. package/src/pressable/styles.ts +10 -10
  261. package/src/pressable/types.ts +6 -6
  262. package/src/progress/index.ts +9 -9
  263. package/src/progress/progress-filled-track.tsx +26 -26
  264. package/src/progress/progress.tsx +52 -52
  265. package/src/progress/styles.ts +34 -34
  266. package/src/progress/types.ts +28 -28
  267. package/src/radio/index.ts +14 -14
  268. package/src/radio/radio-group.tsx +61 -61
  269. package/src/radio/radio-icon.tsx +24 -24
  270. package/src/radio/radio-indicator.tsx +30 -30
  271. package/src/radio/radio-label.tsx +24 -24
  272. package/src/radio/radio.tsx +68 -68
  273. package/src/radio/styles.ts +69 -69
  274. package/src/radio/types.ts +51 -51
  275. package/src/rating/index.ts +7 -7
  276. package/src/rating/rating.tsx +93 -93
  277. package/src/rating/styles.ts +13 -13
  278. package/src/rating/types.ts +29 -29
  279. package/src/search-input/index.ts +16 -16
  280. package/src/search-input/search-input.tsx +119 -119
  281. package/src/search-input/styles.ts +28 -28
  282. package/src/search-input/types.ts +31 -31
  283. package/src/segmented-control/index.ts +2 -2
  284. package/src/segmented-control/segmented-control.tsx +34 -34
  285. package/src/segmented-control/styles.ts +22 -22
  286. package/src/segmented-control/types.ts +22 -22
  287. package/src/select/index.ts +28 -28
  288. package/src/select/select-backdrop.tsx +25 -25
  289. package/src/select/select-content.tsx +49 -49
  290. package/src/select/select-drag-indicator.tsx +19 -19
  291. package/src/select/select-icon.tsx +25 -25
  292. package/src/select/select-input.tsx +32 -32
  293. package/src/select/select-item-text.tsx +30 -30
  294. package/src/select/select-item.tsx +72 -72
  295. package/src/select/select-portal.tsx +22 -22
  296. package/src/select/select-scroll-view.tsx +22 -22
  297. package/src/select/select-trigger.tsx +64 -64
  298. package/src/select/select.tsx +101 -101
  299. package/src/select/styles.ts +114 -114
  300. package/src/select/types.ts +92 -92
  301. package/src/skeleton/index.ts +2 -2
  302. package/src/skeleton/skeleton.tsx +29 -29
  303. package/src/skeleton/styles.ts +14 -14
  304. package/src/skeleton/types.ts +12 -12
  305. package/src/slider/index.ts +12 -12
  306. package/src/slider/slider-filled-track.tsx +31 -31
  307. package/src/slider/slider-thumb.tsx +52 -52
  308. package/src/slider/slider-track.tsx +154 -154
  309. package/src/slider/slider.tsx +193 -193
  310. package/src/slider/styles.ts +71 -71
  311. package/src/slider/types.ts +47 -47
  312. package/src/snackbar/index.ts +2 -2
  313. package/src/snackbar/snackbar.tsx +39 -39
  314. package/src/snackbar/styles.ts +29 -29
  315. package/src/snackbar/types.ts +21 -21
  316. package/src/spinner/index.ts +2 -2
  317. package/src/spinner/spinner.tsx +29 -29
  318. package/src/spinner/styles.ts +15 -15
  319. package/src/spinner/types.ts +10 -10
  320. package/src/stack/index.ts +2 -2
  321. package/src/stack/stack.tsx +49 -49
  322. package/src/stack/styles.ts +25 -25
  323. package/src/stack/types.ts +15 -15
  324. package/src/stat/index.ts +2 -2
  325. package/src/stat/stat.tsx +48 -48
  326. package/src/stat/styles.ts +34 -34
  327. package/src/stat/types.ts +24 -24
  328. package/src/stepper/index.ts +2 -2
  329. package/src/stepper/stepper.tsx +95 -95
  330. package/src/stepper/styles.ts +49 -49
  331. package/src/stepper/types.ts +20 -20
  332. package/src/switch/index.ts +2 -2
  333. package/src/switch/styles.ts +24 -24
  334. package/src/switch/switch.tsx +67 -67
  335. package/src/switch/types.ts +23 -23
  336. package/src/table/index.ts +2 -2
  337. package/src/table/styles.ts +12 -12
  338. package/src/table/table.tsx +52 -52
  339. package/src/table/types.ts +10 -10
  340. package/src/tabs/index.ts +18 -18
  341. package/src/tabs/styles.ts +113 -113
  342. package/src/tabs/tab-list.tsx +29 -29
  343. package/src/tabs/tab-panel.tsx +29 -29
  344. package/src/tabs/tab-panels.tsx +21 -21
  345. package/src/tabs/tab-text.tsx +26 -26
  346. package/src/tabs/tab.tsx +56 -56
  347. package/src/tabs/tabs.tsx +71 -71
  348. package/src/tabs/types.ts +53 -53
  349. package/src/tag/index.ts +14 -14
  350. package/src/tag/styles.ts +115 -115
  351. package/src/tag/tag-close-button.tsx +26 -26
  352. package/src/tag/tag-icon.tsx +20 -20
  353. package/src/tag/tag-text.tsx +22 -22
  354. package/src/tag/tag.tsx +40 -40
  355. package/src/tag/types.ts +33 -33
  356. package/src/tags-input/index.ts +18 -18
  357. package/src/tags-input/styles.ts +29 -29
  358. package/src/tags-input/tags-input.tsx +149 -149
  359. package/src/tags-input/types.ts +37 -37
  360. package/src/text/index.ts +2 -2
  361. package/src/text/styles.ts +54 -54
  362. package/src/text/text.tsx +51 -51
  363. package/src/text/types.ts +36 -36
  364. package/src/textarea/index.ts +2 -2
  365. package/src/textarea/styles.ts +37 -37
  366. package/src/textarea/textarea.tsx +68 -68
  367. package/src/textarea/types.ts +14 -14
  368. package/src/timeline/index.ts +2 -2
  369. package/src/timeline/styles.ts +57 -57
  370. package/src/timeline/timeline.tsx +52 -52
  371. package/src/timeline/types.ts +30 -30
  372. package/src/toast/index.ts +17 -17
  373. package/src/toast/styles.ts +118 -118
  374. package/src/toast/toast-description.tsx +22 -22
  375. package/src/toast/toast-provider.tsx +136 -136
  376. package/src/toast/toast-title.tsx +22 -22
  377. package/src/toast/toast.tsx +43 -43
  378. package/src/toast/types.ts +50 -50
  379. package/src/toast/use-toast.ts +7 -7
  380. package/src/toggle/index.ts +2 -2
  381. package/src/toggle/styles.ts +30 -30
  382. package/src/toggle/toggle.tsx +25 -25
  383. package/src/toggle/types.ts +15 -15
  384. package/src/toggle-group/index.ts +2 -2
  385. package/src/toggle-group/styles.ts +35 -35
  386. package/src/toggle-group/toggle-group.tsx +60 -60
  387. package/src/toggle-group/types.ts +29 -29
  388. package/src/tooltip/index.ts +11 -11
  389. package/src/tooltip/styles.ts +9 -9
  390. package/src/tooltip/tooltip-content.tsx +19 -19
  391. package/src/tooltip/tooltip-text.tsx +19 -19
  392. package/src/tooltip/tooltip.tsx +116 -116
  393. package/src/tooltip/types.ts +35 -35
  394. package/src/utils/brand.ts +5 -5
  395. package/src/utils/create-context.ts +17 -17
  396. package/src/utils/index.ts +8 -8
  397. package/src/utils/types.ts +20 -20
  398. package/src/visually-hidden/index.ts +2 -2
  399. package/src/visually-hidden/styles.ts +6 -6
  400. package/src/visually-hidden/types.ts +6 -6
  401. package/src/visually-hidden/visually-hidden.tsx +22 -22
  402. package/tailwind-preset.js +203 -203
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Wireservers
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,98 +1,214 @@
1
- # @wireservers-ui/react-natives
2
-
3
- 70+ production-ready React Native components TypeScript-first, themeable, accessible.
4
-
5
- Built with [NativeWind](https://www.nativewind.dev/) and [Tailwind Variants](https://www.tailwind-variants.org/).
6
-
7
- ## Installation
8
-
9
- ```bash
10
- npm install @wireservers-ui/react-natives
11
- ```
12
-
13
- ### Peer Dependencies
14
-
15
- Make sure you have the following installed in your project:
16
-
17
- ```bash
18
- npm install nativewind tailwind-variants react-native-reanimated react-native-gesture-handler react-native-svg
19
- ```
20
-
21
- `react-native-reanimated`, `react-native-gesture-handler`, and `react-native-svg` are optional only needed if you use components that depend on them.
22
-
23
- ## Setup
24
-
25
- Add the preset to your `tailwind.config.js`:
26
-
27
- ```js
28
- /** @type {import('tailwindcss').Config} */
29
- module.exports = {
30
- content: [
31
- "./app/**/*.{js,jsx,ts,tsx}",
32
- // ...your other content paths
33
- ],
34
- presets: [require("@wireservers-ui/react-natives/tailwind-preset")],
35
- };
36
- ```
37
-
38
- The preset includes the NativeWind preset, the full color/theme system, and automatic content scanning of the component library — no additional configuration needed.
39
-
40
- ### Theme Variables
41
-
42
- Components use CSS variables for theming. Define them in your global CSS to customize colors:
43
-
44
- ```css
45
- @tailwind base;
46
- @tailwind components;
47
- @tailwind utilities;
48
-
49
- :root {
50
- --color-primary-500: 80 70 230;
51
- --color-background-0: 255 255 255;
52
- --color-typography-900: 23 23 23;
53
- /* ... */
54
- }
55
-
56
- .dark {
57
- --color-primary-500: 120 110 255;
58
- --color-background-0: 24 23 25;
59
- --color-typography-900: 245 245 245;
60
- /* ... */
61
- }
62
- ```
63
-
64
- ## Usage
65
-
66
- ```tsx
67
- import { Button, ButtonText } from "@wireservers-ui/react-natives";
68
-
69
- export function MyComponent() {
70
- return (
71
- <Button action="primary" variant="solid" size="md">
72
- <ButtonText>Get Started</ButtonText>
73
- </Button>
74
- );
75
- }
76
- ```
77
-
78
- ## Components
79
-
80
- Includes 70+ components across these categories:
81
-
82
- **Core** — Text, Heading, Icon, Divider, Badge, Spinner, Image, Avatar, Card, Button, Kbd, Code, Blockquote
83
-
84
- **Form Controls** — Input, Textarea, Switch, Checkbox, Radio, Slider, Select, FormControl, NumberInput, PasswordInput, SearchInput, Rating, TagsInput, DatePicker, PinInput, ColorPicker
85
-
86
- **Feedback & Overlay** — Alert, Progress, CircularProgress, Modal, Toast, Tooltip, Drawer, ActionSheet, AlertDialog, Popover, Snackbar, Overlay
87
-
88
- **Navigation** — Tabs, Accordion, Breadcrumb, Menu, Pagination, Stepper, SegmentedControl, Fab, Link
89
-
90
- **Data Display** — Tag, Skeleton, Empty, Stat, Table, List, Timeline, Carousel
91
-
92
- **Layout** — Box, Stack (VStack, HStack), Center, AspectRatio, Container, Pressable, Portal, VisuallyHidden
93
-
94
- **Interactive** — Toggle, ToggleGroup, Collapsible, Calendar
95
-
96
- ## License
97
-
98
- MIT
1
+ # React-Natives
2
+
3
+ **A comprehensive React Native component library built with NativeWind and Tailwind Variants.**
4
+
5
+ > **Note:** This project is in early development (v0.1.0). We're actively building out components, documentation, and tooling. Expect breaking changes as we iterate toward a stable release. Contributions and feedback are welcome!
6
+
7
+ [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
+ [![npm version](https://img.shields.io/npm/v/@wireservers-ui/react-natives.svg)](https://www.npmjs.com/package/@wireservers-ui/react-natives)
9
+
10
+ ---
11
+
12
+ ## What is React-Natives?
13
+
14
+ React-Natives is a collection of 70+ production-ready, accessible React Native components. Every component is TypeScript-first, themeable via CSS variables, and styled with NativeWind (Tailwind CSS for React Native).
15
+
16
+ **Live Demo:** [reactnatives.azurewebsites.net](https://reactnatives.azurewebsites.net)
17
+
18
+ ### Key Features
19
+
20
+ - **70+ Components** — Buttons, forms, modals, tables, calendars, color pickers, and more
21
+ - **TypeScript First**Fully typed with excellent IDE autocomplete
22
+ - **NativeWind + Tailwind Variants** — Utility-first styling with type-safe variant APIs
23
+ - **Themeable** — CSS variable-based color system with light/dark mode support
24
+ - **Accessible** — Built with accessibility in mind
25
+ - **Cross Platform** iOS, Android, and Web via React Native
26
+
27
+ ### Tech Stack
28
+
29
+ | Layer | Technology |
30
+ | --- | --- |
31
+ | Components | React Native |
32
+ | Styling | NativeWind v4, Tailwind CSS 3, Tailwind Variants |
33
+ | Types | TypeScript |
34
+
35
+ ---
36
+
37
+ ## Quick Start
38
+
39
+ ### Install
40
+
41
+ ```bash
42
+ npm install @wireservers-ui/react-natives
43
+ ```
44
+
45
+ ### Peer Dependencies
46
+
47
+ ```bash
48
+ npm install nativewind tailwind-variants react-native-reanimated react-native-gesture-handler react-native-svg
49
+ ```
50
+
51
+ `react-native-reanimated`, `react-native-gesture-handler`, and `react-native-svg` are optional — only required by components that use them.
52
+
53
+ ### Configure Tailwind
54
+
55
+ Add the preset to your `tailwind.config.js`:
56
+
57
+ ```js
58
+ /** @type {import('tailwindcss').Config} */
59
+ module.exports = {
60
+ content: [
61
+ "./app/**/*.{js,jsx,ts,tsx}",
62
+ // ...your content paths
63
+ ],
64
+ presets: [require("@wireservers-ui/react-natives/tailwind-preset")],
65
+ };
66
+ ```
67
+
68
+ The preset includes the NativeWind preset, the full color/theme system, content scanning of the library, and safelist rules — no additional configuration needed.
69
+
70
+ ### Use Components
71
+
72
+ ```tsx
73
+ import { Button, ButtonText, Card, CardHeader, CardBody } from "@wireservers-ui/react-natives";
74
+
75
+ export default function App() {
76
+ return (
77
+ <Card>
78
+ <CardHeader>
79
+ <Text variant="h2">Welcome</Text>
80
+ </CardHeader>
81
+ <CardBody>
82
+ <Button action="primary" variant="solid" size="md">
83
+ <ButtonText>Get Started</ButtonText>
84
+ </Button>
85
+ </CardBody>
86
+ </Card>
87
+ );
88
+ }
89
+ ```
90
+
91
+ ---
92
+
93
+ ## Components
94
+
95
+ ### Core Primitives
96
+
97
+ Text, Heading, Icon, Divider, Badge, Spinner, Image, Avatar, Card, Button, Kbd, Code, Blockquote
98
+
99
+ ### Form Controls
100
+
101
+ Input, Textarea, Switch, Checkbox, Radio, Slider, Select, FormControl, NumberInput, PasswordInput, SearchInput, Rating, TagsInput, DatePicker, PinInput, ColorPicker
102
+
103
+ ### Feedback & Overlay
104
+
105
+ Alert, Progress, CircularProgress, Modal, Toast, Tooltip, Drawer, ActionSheet, AlertDialog, Popover, Snackbar, Overlay
106
+
107
+ ### Navigation & Disclosure
108
+
109
+ Tabs, Accordion, Breadcrumb, Menu, Pagination, Stepper, SegmentedControl, Fab, Link
110
+
111
+ ### Data Display
112
+
113
+ Tag, Skeleton, Empty, Stat, Table, List, Timeline, Carousel
114
+
115
+ ### Layout
116
+
117
+ Box, Stack (VStack, HStack), Center, AspectRatio, Container, Pressable, Portal, VisuallyHidden
118
+
119
+ ### Interactive
120
+
121
+ Toggle, ToggleGroup, Collapsible, Calendar
122
+
123
+ ---
124
+
125
+ ## Theming
126
+
127
+ Components use CSS variables for theming. Define them in your global CSS:
128
+
129
+ ```css
130
+ @tailwind base;
131
+ @tailwind components;
132
+ @tailwind utilities;
133
+
134
+ :root {
135
+ --color-primary-500: 80 70 230;
136
+ --color-background-0: 255 255 255;
137
+ --color-typography-900: 23 23 23;
138
+ /* ... */
139
+ }
140
+
141
+ .dark {
142
+ --color-primary-500: 120 110 255;
143
+ --color-background-0: 24 23 25;
144
+ --color-typography-900: 245 245 245;
145
+ /* ... */
146
+ }
147
+ ```
148
+
149
+ The color system includes semantic scales (`primary`, `secondary`, `error`, `success`, `warning`, `info`) each with shades from 0–950, plus `typography`, `outline`, `background`, and `indicator` tokens.
150
+
151
+ ---
152
+
153
+ ## Repository Structure
154
+
155
+ ```text
156
+ react-natives/
157
+ ├── src/ # TypeScript source — ships as-is (no build step)
158
+ ├── tailwind-preset.js # Tailwind CSS preset for consumers
159
+ ├── tsconfig.json
160
+ └── package.json # npm package definition
161
+ ```
162
+
163
+ ## Development
164
+
165
+ ### Prerequisites
166
+
167
+ - Node.js 18+
168
+
169
+ ### Setup
170
+
171
+ ```bash
172
+ # Clone the repository
173
+ git clone https://github.com/wireservers/wireservers-ui.git
174
+ cd wireservers-ui/packages/react-natives
175
+
176
+ # Install dependencies
177
+ npm install
178
+ ```
179
+
180
+ No build step — the library ships TypeScript source directly.
181
+
182
+ ### Branches
183
+
184
+ | Branch | Purpose |
185
+ | --- | --- |
186
+ | `sot` | Source of truth (main) |
187
+ | `dev` | Development |
188
+ | `prod` | Production |
189
+
190
+ ---
191
+
192
+ ## Roadmap
193
+
194
+ This project just started — here's what's ahead:
195
+
196
+ - [ ] Comprehensive documentation for every component
197
+ - [ ] Prop tables and interactive examples
198
+ - [ ] CLI scaffolding tool (`npx create-react-natives`)
199
+ - [ ] More theme presets (Material, iOS native, etc.)
200
+ - [ ] Component testing suite
201
+ - [ ] Storybook integration
202
+ - [ ] Animation presets with Reanimated
203
+
204
+ ---
205
+
206
+ ## Contributing
207
+
208
+ See [CONTRIBUTING.md](CONTRIBUTING.md) for development setup and guidelines.
209
+
210
+ We're in the early stages and welcome contributions of all kinds — bug reports, component requests, documentation improvements, and code contributions.
211
+
212
+ ## License
213
+
214
+ [MIT](LICENSE) — Copyright (c) 2026 Wireservers
package/bin/cli.js ADDED
@@ -0,0 +1,356 @@
1
+ #!/usr/bin/env node
2
+
3
+ const { execSync } = require("child_process");
4
+ const fs = require("fs");
5
+ const path = require("path");
6
+
7
+ const args = process.argv.slice(2);
8
+ const command = args[0];
9
+
10
+ if (command !== "init") {
11
+ console.error(`Unknown command: ${command}`);
12
+ console.error("Usage: npx @wireservers-ui/react-natives init");
13
+ process.exit(1);
14
+ }
15
+
16
+ const cwd = process.cwd();
17
+
18
+ // ── Detect package manager ─────────────────────────────────────────────────
19
+ function detectPackageManager() {
20
+ if (fs.existsSync(path.join(cwd, "pnpm-lock.yaml"))) return "pnpm";
21
+ if (fs.existsSync(path.join(cwd, "yarn.lock"))) return "yarn";
22
+ if (fs.existsSync(path.join(cwd, "bun.lockb"))) return "bun";
23
+ return "npm";
24
+ }
25
+
26
+ const pm = detectPackageManager();
27
+ const installCmd = pm === "yarn" ? "yarn add" : `${pm} install`;
28
+ let needsReinstall = false;
29
+
30
+ console.log(`\n🚀 Initializing @wireservers-ui/react-natives...\n`);
31
+ console.log(` Package manager: ${pm}`);
32
+
33
+ // ── 0. Create .npmrc for pnpm (Metro needs hoisted modules) ────────────────
34
+ if (pm === "pnpm") {
35
+ const npmrcPath = path.join(cwd, ".npmrc");
36
+ const npmrcLine = "node-linker=hoisted";
37
+ if (fs.existsSync(npmrcPath)) {
38
+ const existing = fs.readFileSync(npmrcPath, "utf8");
39
+ if (!existing.includes("node-linker")) {
40
+ fs.appendFileSync(npmrcPath, `\n${npmrcLine}\n`, "utf8");
41
+ console.log(
42
+ " ✏️ Added node-linker=hoisted to .npmrc (required by Metro)",
43
+ );
44
+ needsReinstall = true;
45
+ }
46
+ } else {
47
+ fs.writeFileSync(npmrcPath, `${npmrcLine}\n`, "utf8");
48
+ console.log(
49
+ " ✏️ Created .npmrc with node-linker=hoisted (required by Metro)",
50
+ );
51
+ needsReinstall = true;
52
+ }
53
+ }
54
+
55
+ // ── 1. Re-install with hoisted layout (pnpm only) ─────────────────────────
56
+ if (needsReinstall) {
57
+ console.log("\n📦 Re-installing with hoisted node_modules...\n");
58
+ try {
59
+ execSync(`${pm} install`, { cwd, stdio: "inherit" });
60
+ } catch {
61
+ console.error("Failed to reinstall. Run `pnpm install` manually.");
62
+ }
63
+ }
64
+
65
+ // ── 2. Install peer dependencies ───────────────────────────────────────────
66
+ console.log("\n📦 Installing peer dependencies...\n");
67
+ const peers = [
68
+ "nativewind@^4",
69
+ "tailwindcss@^3",
70
+ "tailwind-variants",
71
+ "tailwind-merge",
72
+ "react-native-reanimated",
73
+ "react-native-worklets",
74
+ "react-native-svg",
75
+ "react-dom",
76
+ "react-native-web",
77
+ ];
78
+
79
+ try {
80
+ execSync(`${installCmd} ${peers.join(" ")}`, { cwd, stdio: "inherit" });
81
+ } catch {
82
+ console.error(
83
+ "Failed to install peer dependencies. You may need to install them manually:",
84
+ );
85
+ console.error(` ${installCmd} ${peers.join(" ")}`);
86
+ }
87
+
88
+ // ── 3. Create tailwind.config.js ───────────────────────────────────────────
89
+ const tailwindConfig = `/** @type {import('tailwindcss').Config} */
90
+ module.exports = {
91
+ content: [
92
+ "./App.{js,jsx,ts,tsx}",
93
+ "./app/**/*.{js,jsx,ts,tsx}",
94
+ "./components/**/*.{js,jsx,ts,tsx}",
95
+ ],
96
+ presets: [require("@wireservers-ui/react-natives/tailwind-preset")],
97
+ };
98
+ `;
99
+
100
+ writeIfMissing("tailwind.config.js", tailwindConfig);
101
+
102
+ // ── 4. Create global.css ───────────────────────────────────────────────────
103
+ const globalCss = `@tailwind base;
104
+ @tailwind components;
105
+ @tailwind utilities;
106
+
107
+ :root {
108
+ --color-primary-0: 255 255 255;
109
+ --color-primary-50: 238 237 253;
110
+ --color-primary-100: 214 211 249;
111
+ --color-primary-200: 172 166 242;
112
+ --color-primary-300: 132 122 235;
113
+ --color-primary-400: 105 95 233;
114
+ --color-primary-500: 80 70 230;
115
+ --color-primary-600: 63 55 198;
116
+ --color-primary-700: 47 41 163;
117
+ --color-primary-800: 33 29 128;
118
+ --color-primary-900: 22 20 96;
119
+ --color-primary-950: 13 11 64;
120
+
121
+ --color-secondary-0: 255 255 255;
122
+ --color-secondary-50: 241 241 243;
123
+ --color-secondary-100: 220 220 224;
124
+ --color-secondary-200: 186 186 194;
125
+ --color-secondary-300: 152 152 163;
126
+ --color-secondary-400: 121 121 137;
127
+ --color-secondary-500: 92 92 112;
128
+ --color-secondary-600: 72 72 92;
129
+ --color-secondary-700: 54 54 72;
130
+ --color-secondary-800: 38 38 54;
131
+ --color-secondary-900: 24 24 38;
132
+ --color-secondary-950: 14 14 24;
133
+
134
+ --color-tertiary-50: 250 245 255;
135
+ --color-tertiary-100: 243 232 255;
136
+ --color-tertiary-200: 222 200 252;
137
+ --color-tertiary-300: 196 160 246;
138
+ --color-tertiary-400: 168 120 238;
139
+ --color-tertiary-500: 140 80 228;
140
+ --color-tertiary-600: 114 58 200;
141
+ --color-tertiary-700: 90 40 170;
142
+ --color-tertiary-800: 68 28 138;
143
+ --color-tertiary-900: 48 18 106;
144
+ --color-tertiary-950: 30 8 72;
145
+
146
+ --color-error-0: 255 255 255;
147
+ --color-error-50: 254 242 242;
148
+ --color-error-100: 254 226 226;
149
+ --color-error-200: 252 165 165;
150
+ --color-error-300: 248 113 113;
151
+ --color-error-400: 240 82 82;
152
+ --color-error-500: 230 53 53;
153
+ --color-error-600: 204 37 37;
154
+ --color-error-700: 178 24 24;
155
+ --color-error-800: 150 16 16;
156
+ --color-error-900: 122 10 10;
157
+ --color-error-950: 80 5 5;
158
+
159
+ --color-success-0: 255 255 255;
160
+ --color-success-50: 237 252 241;
161
+ --color-success-100: 210 245 221;
162
+ --color-success-200: 147 226 172;
163
+ --color-success-300: 96 207 128;
164
+ --color-success-400: 56 189 92;
165
+ --color-success-500: 34 168 66;
166
+ --color-success-600: 24 140 52;
167
+ --color-success-700: 18 112 40;
168
+ --color-success-800: 14 88 32;
169
+ --color-success-900: 10 64 22;
170
+ --color-success-950: 5 40 12;
171
+
172
+ --color-warning-0: 255 255 255;
173
+ --color-warning-50: 255 249 235;
174
+ --color-warning-100: 255 240 198;
175
+ --color-warning-200: 252 217 119;
176
+ --color-warning-300: 247 195 56;
177
+ --color-warning-400: 240 176 14;
178
+ --color-warning-500: 220 155 6;
179
+ --color-warning-600: 182 123 4;
180
+ --color-warning-700: 145 96 4;
181
+ --color-warning-800: 112 72 5;
182
+ --color-warning-900: 82 52 6;
183
+ --color-warning-950: 48 30 4;
184
+
185
+ --color-info-0: 255 255 255;
186
+ --color-info-50: 240 248 255;
187
+ --color-info-100: 224 240 253;
188
+ --color-info-200: 168 213 248;
189
+ --color-info-300: 110 184 240;
190
+ --color-info-400: 66 158 232;
191
+ --color-info-500: 34 134 220;
192
+ --color-info-600: 22 110 190;
193
+ --color-info-700: 14 88 158;
194
+ --color-info-800: 10 68 126;
195
+ --color-info-900: 6 50 96;
196
+ --color-info-950: 2 32 64;
197
+
198
+ --color-typography-0: 255 255 255;
199
+ --color-typography-50: 245 245 245;
200
+ --color-typography-100: 229 229 229;
201
+ --color-typography-200: 212 212 212;
202
+ --color-typography-300: 163 163 163;
203
+ --color-typography-400: 140 140 140;
204
+ --color-typography-500: 115 115 115;
205
+ --color-typography-600: 82 82 82;
206
+ --color-typography-700: 64 64 64;
207
+ --color-typography-800: 38 38 38;
208
+ --color-typography-900: 23 23 23;
209
+ --color-typography-950: 10 10 10;
210
+
211
+ --color-outline-0: 255 255 255;
212
+ --color-outline-50: 245 245 245;
213
+ --color-outline-100: 229 229 229;
214
+ --color-outline-200: 212 212 212;
215
+ --color-outline-300: 196 196 196;
216
+ --color-outline-400: 163 163 163;
217
+ --color-outline-500: 140 140 140;
218
+ --color-outline-600: 115 115 115;
219
+ --color-outline-700: 82 82 82;
220
+ --color-outline-800: 51 51 51;
221
+ --color-outline-900: 33 33 33;
222
+ --color-outline-950: 18 18 18;
223
+
224
+ --color-background-0: 255 255 255;
225
+ --color-background-50: 249 249 249;
226
+ --color-background-100: 242 242 242;
227
+ --color-background-200: 228 228 228;
228
+ --color-background-300: 212 212 212;
229
+ --color-background-400: 189 189 189;
230
+ --color-background-500: 163 163 163;
231
+ --color-background-600: 115 115 115;
232
+ --color-background-700: 82 82 82;
233
+ --color-background-800: 51 51 51;
234
+ --color-background-900: 33 33 33;
235
+ --color-background-950: 18 18 18;
236
+ --color-background-error: 254 226 226;
237
+ --color-background-warning: 255 243 224;
238
+ --color-background-muted: 245 245 245;
239
+ --color-background-success: 228 247 235;
240
+ --color-background-info: 224 240 253;
241
+
242
+ --color-indicator-primary: 80 70 230;
243
+ --color-indicator-info: 34 134 220;
244
+ --color-indicator-error: 230 53 53;
245
+ }
246
+ `;
247
+
248
+ writeIfMissing("global.css", globalCss);
249
+
250
+ // ── 5. Create nativewind-env.d.ts ──────────────────────────────────────────
251
+ writeIfMissing(
252
+ "nativewind-env.d.ts",
253
+ '/// <reference types="nativewind/types" />\n',
254
+ );
255
+
256
+ // ── 6. Create/update metro.config.js ───────────────────────────────────────
257
+ const metroConfig = `const { getDefaultConfig } = require("expo/metro-config");
258
+ const { withNativeWind } = require("nativewind/metro");
259
+
260
+ const config = getDefaultConfig(__dirname);
261
+
262
+ module.exports = withNativeWind(config, { input: "./global.css" });
263
+ `;
264
+
265
+ writeFile("metro.config.js", metroConfig);
266
+
267
+ // ── 7. Create/update babel.config.js ───────────────────────────────────────
268
+ const babelConfig = `module.exports = function (api) {
269
+ api.cache(true);
270
+ return {
271
+ presets: [
272
+ ["babel-preset-expo", { jsxImportSource: "nativewind" }],
273
+ "nativewind/babel",
274
+ ],
275
+ };
276
+ };
277
+ `;
278
+
279
+ writeFile("babel.config.js", babelConfig);
280
+
281
+ // ── 8. Create the demo App.tsx ─────────────────────────────────────────────
282
+ const appTsx = `import "./global.css";
283
+ import React, { useState } from "react";
284
+ import { View, Text } from "react-native";
285
+ import {
286
+ Slider,
287
+ SliderTrack,
288
+ SliderFilledTrack,
289
+ SliderThumb,
290
+ } from "@wireservers-ui/react-natives";
291
+
292
+ export default function App() {
293
+ const [volume, setVolume] = useState(50);
294
+
295
+ return (
296
+ <View className="flex-1 items-center justify-center bg-background-0 px-8">
297
+ <Text className="text-2xl font-bold text-typography-900 mb-2">
298
+ Volume Control
299
+ </Text>
300
+ <Text className="text-lg text-typography-500 mb-8">
301
+ {volume}%
302
+ </Text>
303
+ <View className="w-full max-w-xs">
304
+ <Slider
305
+ value={volume}
306
+ onValueChange={setVolume}
307
+ min={0}
308
+ max={100}
309
+ size="lg"
310
+ >
311
+ <SliderTrack>
312
+ <SliderFilledTrack />
313
+ </SliderTrack>
314
+ <SliderThumb />
315
+ </Slider>
316
+ </View>
317
+ <Text className="text-sm text-typography-400 mt-6">
318
+ Drag the slider to adjust volume
319
+ </Text>
320
+ </View>
321
+ );
322
+ }
323
+ `;
324
+
325
+ writeFile("App.tsx", appTsx);
326
+
327
+ // ── Done ───────────────────────────────────────────────────────────────────
328
+ console.log("\n✅ Setup complete!\n");
329
+ console.log(" Created/updated:");
330
+ console.log(" • tailwind.config.js");
331
+ console.log(" • global.css (with theme variables)");
332
+ console.log(" • nativewind-env.d.ts");
333
+ console.log(" • metro.config.js");
334
+ console.log(" • babel.config.js");
335
+ console.log(" • App.tsx (volume slider demo)");
336
+ console.log("\n Run your app:\n");
337
+ console.log(" npx expo start --clear\n");
338
+
339
+ // ── Helpers ────────────────────────────────────────────────────────────────
340
+ function writeFile(name, content) {
341
+ const filePath = path.join(cwd, name);
342
+ fs.writeFileSync(filePath, content, "utf8");
343
+ console.log(
344
+ ` ✏️ ${fs.existsSync(filePath) ? "Updated" : "Created"} ${name}`,
345
+ );
346
+ }
347
+
348
+ function writeIfMissing(name, content) {
349
+ const filePath = path.join(cwd, name);
350
+ if (fs.existsSync(filePath)) {
351
+ console.log(` ⏭️ ${name} already exists, skipping`);
352
+ return;
353
+ }
354
+ fs.writeFileSync(filePath, content, "utf8");
355
+ console.log(` ✏️ Created ${name}`);
356
+ }