@bloomneo/uikit 1.5.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 (678) hide show
  1. package/CHANGELOG.md +222 -0
  2. package/LICENSE +21 -0
  3. package/README.md +513 -0
  4. package/bin/commands/build.js +232 -0
  5. package/bin/commands/bundle.js +587 -0
  6. package/bin/commands/create.js +768 -0
  7. package/bin/commands/deploy.js +533 -0
  8. package/bin/commands/generate.js +673 -0
  9. package/bin/commands/optimize.js +198 -0
  10. package/bin/commands/prerender.js +306 -0
  11. package/bin/commands/serve.js +216 -0
  12. package/bin/templates/fbca/README.md.template +130 -0
  13. package/bin/templates/fbca/docs/QUICKSTART_FBCA.md +368 -0
  14. package/bin/templates/fbca/docs/UIKIT_CLI_GUIDE.md +574 -0
  15. package/bin/templates/fbca/docs/UIKIT_COMPOSITE_UI_SYSTEM.md +649 -0
  16. package/bin/templates/fbca/docs/UIKIT_LLM_GUIDE.md +2055 -0
  17. package/bin/templates/fbca/docs/UIKIT_THEME_GUIDE.md +359 -0
  18. package/bin/templates/fbca/package.json.template +41 -0
  19. package/bin/templates/fbca/public/favicon.svg +10 -0
  20. package/bin/templates/fbca/public/hero_fbca.svg +1 -0
  21. package/bin/templates/fbca/src/utils/asset.ts +6 -0
  22. package/bin/templates/fbca/src/web/App.tsx.template +20 -0
  23. package/bin/templates/fbca/src/web/features/auth/pages/index.tsx.template +157 -0
  24. package/bin/templates/fbca/src/web/features/docs/pages/[...slug].tsx.template +83 -0
  25. package/bin/templates/fbca/src/web/features/gallery/hooks/useGallery.ts.template +74 -0
  26. package/bin/templates/fbca/src/web/features/gallery/pages/index.tsx.template +136 -0
  27. package/bin/templates/fbca/src/web/features/main/components/CTASection.tsx.template +43 -0
  28. package/bin/templates/fbca/src/web/features/main/pages/About.tsx.template +374 -0
  29. package/bin/templates/fbca/src/web/features/main/pages/index.tsx.template +214 -0
  30. package/bin/templates/fbca/src/web/index.html.template +15 -0
  31. package/bin/templates/fbca/src/web/lib/page-router.tsx.template +134 -0
  32. package/bin/templates/fbca/src/web/main.tsx.template +14 -0
  33. package/bin/templates/fbca/src/web/shared/components/Footer.tsx.template +57 -0
  34. package/bin/templates/fbca/src/web/shared/components/Header.tsx.template +91 -0
  35. package/bin/templates/fbca/src/web/shared/components/SEO.tsx.template +24 -0
  36. package/bin/templates/fbca/src/web/shared/components/index.ts.template +3 -0
  37. package/bin/templates/fbca/src/web/shared/hooks/useSEO.ts.template +85 -0
  38. package/bin/templates/fbca/src/web/shared/utils/asset.ts +6 -0
  39. package/bin/templates/fbca/src/web/styles/index.css.template +8 -0
  40. package/bin/templates/fbca/src/web/utils/asset.ts +6 -0
  41. package/bin/templates/fbca/tsconfig.json.template +32 -0
  42. package/bin/templates/fbca/tsconfig.node.json.template +10 -0
  43. package/bin/templates/fbca/vite.config.ts.template +38 -0
  44. package/bin/templates/generate/component/component.tsx.template +79 -0
  45. package/bin/templates/generate/component/index.ts.template +2 -0
  46. package/bin/templates/generate/component/types.ts.template +58 -0
  47. package/bin/templates/generate/feature/index.ts.template +14 -0
  48. package/bin/templates/generate/feature/list-page.tsx.template +34 -0
  49. package/bin/templates/generate/feature/main-component.tsx.template +37 -0
  50. package/bin/templates/generate/feature/main-page.tsx.template +30 -0
  51. package/bin/templates/generate/feature/types.ts.template +34 -0
  52. package/bin/templates/generate/hook/hook.ts.template +35 -0
  53. package/bin/templates/generate/index.css.template +10 -0
  54. package/bin/templates/generate/main.tsx.template +10 -0
  55. package/bin/templates/generate/page/index.ts.template +2 -0
  56. package/bin/templates/generate/page/page.tsx.template +86 -0
  57. package/bin/templates/generate/theme/README.md +31 -0
  58. package/bin/templates/generate/theme/theme.js.template +155 -0
  59. package/bin/templates/multi/README.md.template +120 -0
  60. package/bin/templates/multi/docs/QUICKSTART_MULTI.md +334 -0
  61. package/bin/templates/multi/docs/UIKIT_CLI_GUIDE.md +574 -0
  62. package/bin/templates/multi/docs/UIKIT_COMPOSITE_UI_SYSTEM.md +649 -0
  63. package/bin/templates/multi/docs/UIKIT_LLM_GUIDE.md +2055 -0
  64. package/bin/templates/multi/docs/UIKIT_THEME_GUIDE.md +359 -0
  65. package/bin/templates/multi/index.html.template +58 -0
  66. package/bin/templates/multi/package.json.template +35 -0
  67. package/bin/templates/multi/public/favicon.svg +10 -0
  68. package/bin/templates/multi/public/hero_multi.svg +1 -0
  69. package/bin/templates/multi/src/App.tsx.template +92 -0
  70. package/bin/templates/multi/src/components/Footer.tsx.template +58 -0
  71. package/bin/templates/multi/src/components/Header.tsx.template +103 -0
  72. package/bin/templates/multi/src/components/SEO.tsx.template +19 -0
  73. package/bin/templates/multi/src/components/index.ts.template +3 -0
  74. package/bin/templates/multi/src/hooks/useSEO.ts.template +38 -0
  75. package/bin/templates/multi/src/index.css.template +7 -0
  76. package/bin/templates/multi/src/main.tsx.template +14 -0
  77. package/bin/templates/multi/src/pages/About.tsx.template +276 -0
  78. package/bin/templates/multi/src/pages/Components.tsx.template +288 -0
  79. package/bin/templates/multi/src/pages/Contact.tsx.template +348 -0
  80. package/bin/templates/multi/src/pages/Dashboard.tsx.template +306 -0
  81. package/bin/templates/multi/src/pages/ErrorPage.tsx.template +37 -0
  82. package/bin/templates/multi/src/pages/Home.tsx.template +201 -0
  83. package/bin/templates/multi/src/pages/Login.tsx.template +148 -0
  84. package/bin/templates/multi/src/pages/Themes.tsx.template +207 -0
  85. package/bin/templates/multi/src/router.tsx.template +34 -0
  86. package/bin/templates/multi/src/utils/asset.ts +6 -0
  87. package/bin/templates/multi/tsconfig.json.template +30 -0
  88. package/bin/templates/multi/tsconfig.node.json +22 -0
  89. package/bin/templates/multi/vite.config.ts.template +36 -0
  90. package/bin/templates/single/README.md.template +131 -0
  91. package/bin/templates/single/docs/QUICKSTART_SINGLE.md +259 -0
  92. package/bin/templates/single/docs/UIKIT_CLI_GUIDE.md +574 -0
  93. package/bin/templates/single/docs/UIKIT_COMPOSITE_UI_SYSTEM.md +649 -0
  94. package/bin/templates/single/docs/UIKIT_LLM_GUIDE.md +2055 -0
  95. package/bin/templates/single/docs/UIKIT_THEME_GUIDE.md +359 -0
  96. package/bin/templates/single/index.html.template +37 -0
  97. package/bin/templates/single/package.json.template +34 -0
  98. package/bin/templates/single/public/favicon.svg +10 -0
  99. package/bin/templates/single/public/hero.svg +1 -0
  100. package/bin/templates/single/src/App.tsx.template +233 -0
  101. package/bin/templates/single/src/index.css.template +7 -0
  102. package/bin/templates/single/src/main.tsx.template +14 -0
  103. package/bin/templates/single/src/styles/fonts.css +99 -0
  104. package/bin/templates/single/src/utils/asset.ts +6 -0
  105. package/bin/templates/single/tsconfig.json +31 -0
  106. package/bin/templates/single/tsconfig.node.json +22 -0
  107. package/bin/templates/single/vite.config.ts.template +36 -0
  108. package/bin/templates/spa/README.md.template +105 -0
  109. package/bin/templates/spa/components/SEO.tsx.template +19 -0
  110. package/bin/templates/spa/docs/QUICKSTART_SPA.md +300 -0
  111. package/bin/templates/spa/docs/UIKIT_CLI_GUIDE.md +574 -0
  112. package/bin/templates/spa/docs/UIKIT_COMPOSITE_UI_SYSTEM.md +649 -0
  113. package/bin/templates/spa/docs/UIKIT_LLM_GUIDE.md +2055 -0
  114. package/bin/templates/spa/docs/UIKIT_THEME_GUIDE.md +359 -0
  115. package/bin/templates/spa/hooks/useSEO.ts.template +38 -0
  116. package/bin/templates/spa/index.html.template +58 -0
  117. package/bin/templates/spa/package.json.template +35 -0
  118. package/bin/templates/spa/public/favicon.svg +15 -0
  119. package/bin/templates/spa/public/hero_spa.svg +1 -0
  120. package/bin/templates/spa/src/App.tsx.template +659 -0
  121. package/bin/templates/spa/src/index.css.template +7 -0
  122. package/bin/templates/spa/src/main.tsx.template +14 -0
  123. package/bin/templates/spa/src/utils/asset.ts +6 -0
  124. package/bin/templates/spa/tsconfig.json.template +30 -0
  125. package/bin/templates/spa/tsconfig.node.json +22 -0
  126. package/bin/templates/spa/vite.config.ts.template +36 -0
  127. package/bin/uikit.js +133 -0
  128. package/cookbook/README.md +20 -0
  129. package/cookbook/crud-page.tsx +99 -0
  130. package/cookbook/dashboard.tsx +89 -0
  131. package/cookbook/delete-flow.tsx +59 -0
  132. package/cookbook/login.tsx +85 -0
  133. package/cookbook/settings.tsx +113 -0
  134. package/dist/Combination-C0DFrmJW.js +674 -0
  135. package/dist/Combination-C0DFrmJW.js.map +1 -0
  136. package/dist/accordion.js +284 -0
  137. package/dist/accordion.js.map +1 -0
  138. package/dist/admin.js +429 -0
  139. package/dist/admin.js.map +1 -0
  140. package/dist/alert.js +67 -0
  141. package/dist/alert.js.map +1 -0
  142. package/dist/auth.js +178 -0
  143. package/dist/auth.js.map +1 -0
  144. package/dist/avatar.js +249 -0
  145. package/dist/avatar.js.map +1 -0
  146. package/dist/badge.js +40 -0
  147. package/dist/badge.js.map +1 -0
  148. package/dist/blank.js +80 -0
  149. package/dist/blank.js.map +1 -0
  150. package/dist/breadcrumb.js +104 -0
  151. package/dist/breadcrumb.js.map +1 -0
  152. package/dist/button.js +50 -0
  153. package/dist/button.js.map +1 -0
  154. package/dist/calendar.js +2785 -0
  155. package/dist/calendar.js.map +1 -0
  156. package/dist/card.js +91 -0
  157. package/dist/card.js.map +1 -0
  158. package/dist/check-DXouwtzp.js +12 -0
  159. package/dist/check-DXouwtzp.js.map +1 -0
  160. package/dist/checkbox.js +268 -0
  161. package/dist/checkbox.js.map +1 -0
  162. package/dist/chevron-down-BORJtX8F.js +14 -0
  163. package/dist/chevron-down-BORJtX8F.js.map +1 -0
  164. package/dist/chevron-left-C1pkx4AF.js +14 -0
  165. package/dist/chevron-left-C1pkx4AF.js.map +1 -0
  166. package/dist/chevron-right-pz9eCjj-.js +14 -0
  167. package/dist/chevron-right-pz9eCjj-.js.map +1 -0
  168. package/dist/circle-DHOdTDQh.js +14 -0
  169. package/dist/circle-DHOdTDQh.js.map +1 -0
  170. package/dist/collapsible.js +35 -0
  171. package/dist/collapsible.js.map +1 -0
  172. package/dist/command.js +481 -0
  173. package/dist/command.js.map +1 -0
  174. package/dist/confirm-dialog.js +129 -0
  175. package/dist/confirm-dialog.js.map +1 -0
  176. package/dist/container.js +334 -0
  177. package/dist/container.js.map +1 -0
  178. package/dist/createLucideIcon-B45kRl5r.js +80 -0
  179. package/dist/createLucideIcon-B45kRl5r.js.map +1 -0
  180. package/dist/data-table.js +574 -0
  181. package/dist/data-table.js.map +1 -0
  182. package/dist/detail-page.js +454 -0
  183. package/dist/detail-page.js.map +1 -0
  184. package/dist/dialog.js +137 -0
  185. package/dist/dialog.js.map +1 -0
  186. package/dist/dropdown-menu.js +424 -0
  187. package/dist/dropdown-menu.js.map +1 -0
  188. package/dist/ellipsis-BhAoKPVk.js +16 -0
  189. package/dist/ellipsis-BhAoKPVk.js.map +1 -0
  190. package/dist/empty-state.js +54 -0
  191. package/dist/empty-state.js.map +1 -0
  192. package/dist/errors.js +36 -0
  193. package/dist/errors.js.map +1 -0
  194. package/dist/eye-DDKoW0KS.js +46 -0
  195. package/dist/eye-DDKoW0KS.js.map +1 -0
  196. package/dist/fonts/caveat-cyrillic-400-normal.woff +0 -0
  197. package/dist/fonts/caveat-cyrillic-400-normal.woff2 +0 -0
  198. package/dist/fonts/caveat-cyrillic-700-normal.woff +0 -0
  199. package/dist/fonts/caveat-cyrillic-700-normal.woff2 +0 -0
  200. package/dist/fonts/caveat-cyrillic-ext-400-normal.woff +0 -0
  201. package/dist/fonts/caveat-cyrillic-ext-400-normal.woff2 +0 -0
  202. package/dist/fonts/caveat-cyrillic-ext-700-normal.woff +0 -0
  203. package/dist/fonts/caveat-cyrillic-ext-700-normal.woff2 +0 -0
  204. package/dist/fonts/caveat-latin-400-normal.woff +0 -0
  205. package/dist/fonts/caveat-latin-400-normal.woff2 +0 -0
  206. package/dist/fonts/caveat-latin-700-normal.woff +0 -0
  207. package/dist/fonts/caveat-latin-700-normal.woff2 +0 -0
  208. package/dist/fonts/caveat-latin-ext-400-normal.woff +0 -0
  209. package/dist/fonts/caveat-latin-ext-400-normal.woff2 +0 -0
  210. package/dist/fonts/caveat-latin-ext-700-normal.woff +0 -0
  211. package/dist/fonts/caveat-latin-ext-700-normal.woff2 +0 -0
  212. package/dist/fonts/crimson-text-latin-400-normal.woff +0 -0
  213. package/dist/fonts/crimson-text-latin-400-normal.woff2 +0 -0
  214. package/dist/fonts/crimson-text-latin-600-normal.woff +0 -0
  215. package/dist/fonts/crimson-text-latin-600-normal.woff2 +0 -0
  216. package/dist/fonts/crimson-text-latin-700-normal.woff +0 -0
  217. package/dist/fonts/crimson-text-latin-700-normal.woff2 +0 -0
  218. package/dist/fonts/crimson-text-latin-ext-400-normal.woff +0 -0
  219. package/dist/fonts/crimson-text-latin-ext-400-normal.woff2 +0 -0
  220. package/dist/fonts/crimson-text-latin-ext-600-normal.woff +0 -0
  221. package/dist/fonts/crimson-text-latin-ext-600-normal.woff2 +0 -0
  222. package/dist/fonts/crimson-text-latin-ext-700-normal.woff +0 -0
  223. package/dist/fonts/crimson-text-latin-ext-700-normal.woff2 +0 -0
  224. package/dist/fonts/crimson-text-vietnamese-400-normal.woff +0 -0
  225. package/dist/fonts/crimson-text-vietnamese-400-normal.woff2 +0 -0
  226. package/dist/fonts/crimson-text-vietnamese-600-normal.woff +0 -0
  227. package/dist/fonts/crimson-text-vietnamese-600-normal.woff2 +0 -0
  228. package/dist/fonts/crimson-text-vietnamese-700-normal.woff +0 -0
  229. package/dist/fonts/crimson-text-vietnamese-700-normal.woff2 +0 -0
  230. package/dist/fonts/dm-serif-display-latin-400-normal.woff +0 -0
  231. package/dist/fonts/dm-serif-display-latin-400-normal.woff2 +0 -0
  232. package/dist/fonts/dm-serif-display-latin-ext-400-normal.woff +0 -0
  233. package/dist/fonts/dm-serif-display-latin-ext-400-normal.woff2 +0 -0
  234. package/dist/fonts/libre-baskerville-latin-400-normal.woff +0 -0
  235. package/dist/fonts/libre-baskerville-latin-400-normal.woff2 +0 -0
  236. package/dist/fonts/libre-baskerville-latin-700-normal.woff +0 -0
  237. package/dist/fonts/libre-baskerville-latin-700-normal.woff2 +0 -0
  238. package/dist/fonts/libre-baskerville-latin-ext-400-normal.woff +0 -0
  239. package/dist/fonts/libre-baskerville-latin-ext-400-normal.woff2 +0 -0
  240. package/dist/fonts/libre-baskerville-latin-ext-700-normal.woff +0 -0
  241. package/dist/fonts/libre-baskerville-latin-ext-700-normal.woff2 +0 -0
  242. package/dist/fonts/montserrat-cyrillic-400-normal.woff +0 -0
  243. package/dist/fonts/montserrat-cyrillic-400-normal.woff2 +0 -0
  244. package/dist/fonts/montserrat-cyrillic-500-normal.woff +0 -0
  245. package/dist/fonts/montserrat-cyrillic-500-normal.woff2 +0 -0
  246. package/dist/fonts/montserrat-cyrillic-600-normal.woff +0 -0
  247. package/dist/fonts/montserrat-cyrillic-600-normal.woff2 +0 -0
  248. package/dist/fonts/montserrat-cyrillic-ext-400-normal.woff +0 -0
  249. package/dist/fonts/montserrat-cyrillic-ext-400-normal.woff2 +0 -0
  250. package/dist/fonts/montserrat-cyrillic-ext-500-normal.woff +0 -0
  251. package/dist/fonts/montserrat-cyrillic-ext-500-normal.woff2 +0 -0
  252. package/dist/fonts/montserrat-cyrillic-ext-600-normal.woff +0 -0
  253. package/dist/fonts/montserrat-cyrillic-ext-600-normal.woff2 +0 -0
  254. package/dist/fonts/montserrat-latin-400-normal.woff +0 -0
  255. package/dist/fonts/montserrat-latin-400-normal.woff2 +0 -0
  256. package/dist/fonts/montserrat-latin-500-normal.woff +0 -0
  257. package/dist/fonts/montserrat-latin-500-normal.woff2 +0 -0
  258. package/dist/fonts/montserrat-latin-600-normal.woff +0 -0
  259. package/dist/fonts/montserrat-latin-600-normal.woff2 +0 -0
  260. package/dist/fonts/montserrat-latin-ext-400-normal.woff +0 -0
  261. package/dist/fonts/montserrat-latin-ext-400-normal.woff2 +0 -0
  262. package/dist/fonts/montserrat-latin-ext-500-normal.woff +0 -0
  263. package/dist/fonts/montserrat-latin-ext-500-normal.woff2 +0 -0
  264. package/dist/fonts/montserrat-latin-ext-600-normal.woff +0 -0
  265. package/dist/fonts/montserrat-latin-ext-600-normal.woff2 +0 -0
  266. package/dist/fonts/montserrat-vietnamese-400-normal.woff +0 -0
  267. package/dist/fonts/montserrat-vietnamese-400-normal.woff2 +0 -0
  268. package/dist/fonts/montserrat-vietnamese-500-normal.woff +0 -0
  269. package/dist/fonts/montserrat-vietnamese-500-normal.woff2 +0 -0
  270. package/dist/fonts/montserrat-vietnamese-600-normal.woff +0 -0
  271. package/dist/fonts/montserrat-vietnamese-600-normal.woff2 +0 -0
  272. package/dist/fonts/playfair-display-cyrillic-400-normal.woff +0 -0
  273. package/dist/fonts/playfair-display-cyrillic-400-normal.woff2 +0 -0
  274. package/dist/fonts/playfair-display-cyrillic-500-normal.woff +0 -0
  275. package/dist/fonts/playfair-display-cyrillic-500-normal.woff2 +0 -0
  276. package/dist/fonts/playfair-display-latin-400-normal.woff +0 -0
  277. package/dist/fonts/playfair-display-latin-400-normal.woff2 +0 -0
  278. package/dist/fonts/playfair-display-latin-500-normal.woff +0 -0
  279. package/dist/fonts/playfair-display-latin-500-normal.woff2 +0 -0
  280. package/dist/fonts/playfair-display-latin-ext-400-normal.woff +0 -0
  281. package/dist/fonts/playfair-display-latin-ext-400-normal.woff2 +0 -0
  282. package/dist/fonts/playfair-display-latin-ext-500-normal.woff +0 -0
  283. package/dist/fonts/playfair-display-latin-ext-500-normal.woff2 +0 -0
  284. package/dist/fonts/playfair-display-vietnamese-400-normal.woff +0 -0
  285. package/dist/fonts/playfair-display-vietnamese-400-normal.woff2 +0 -0
  286. package/dist/fonts/playfair-display-vietnamese-500-normal.woff +0 -0
  287. package/dist/fonts/playfair-display-vietnamese-500-normal.woff2 +0 -0
  288. package/dist/fonts/poppins-devanagari-400-normal.woff +0 -0
  289. package/dist/fonts/poppins-devanagari-400-normal.woff2 +0 -0
  290. package/dist/fonts/poppins-devanagari-500-normal.woff +0 -0
  291. package/dist/fonts/poppins-devanagari-500-normal.woff2 +0 -0
  292. package/dist/fonts/poppins-devanagari-600-normal.woff +0 -0
  293. package/dist/fonts/poppins-devanagari-600-normal.woff2 +0 -0
  294. package/dist/fonts/poppins-latin-400-normal.woff +0 -0
  295. package/dist/fonts/poppins-latin-400-normal.woff2 +0 -0
  296. package/dist/fonts/poppins-latin-500-normal.woff +0 -0
  297. package/dist/fonts/poppins-latin-500-normal.woff2 +0 -0
  298. package/dist/fonts/poppins-latin-600-normal.woff +0 -0
  299. package/dist/fonts/poppins-latin-600-normal.woff2 +0 -0
  300. package/dist/fonts/poppins-latin-ext-400-normal.woff +0 -0
  301. package/dist/fonts/poppins-latin-ext-400-normal.woff2 +0 -0
  302. package/dist/fonts/poppins-latin-ext-500-normal.woff +0 -0
  303. package/dist/fonts/poppins-latin-ext-500-normal.woff2 +0 -0
  304. package/dist/fonts/poppins-latin-ext-600-normal.woff +0 -0
  305. package/dist/fonts/poppins-latin-ext-600-normal.woff2 +0 -0
  306. package/dist/fonts/rubik-arabic-400-normal.woff +0 -0
  307. package/dist/fonts/rubik-arabic-400-normal.woff2 +0 -0
  308. package/dist/fonts/rubik-arabic-500-normal.woff +0 -0
  309. package/dist/fonts/rubik-arabic-500-normal.woff2 +0 -0
  310. package/dist/fonts/rubik-cyrillic-400-normal.woff +0 -0
  311. package/dist/fonts/rubik-cyrillic-400-normal.woff2 +0 -0
  312. package/dist/fonts/rubik-cyrillic-500-normal.woff +0 -0
  313. package/dist/fonts/rubik-cyrillic-500-normal.woff2 +0 -0
  314. package/dist/fonts/rubik-cyrillic-ext-400-normal.woff +0 -0
  315. package/dist/fonts/rubik-cyrillic-ext-400-normal.woff2 +0 -0
  316. package/dist/fonts/rubik-cyrillic-ext-500-normal.woff +0 -0
  317. package/dist/fonts/rubik-cyrillic-ext-500-normal.woff2 +0 -0
  318. package/dist/fonts/rubik-hebrew-400-normal.woff +0 -0
  319. package/dist/fonts/rubik-hebrew-400-normal.woff2 +0 -0
  320. package/dist/fonts/rubik-hebrew-500-normal.woff +0 -0
  321. package/dist/fonts/rubik-hebrew-500-normal.woff2 +0 -0
  322. package/dist/fonts/rubik-latin-400-normal.woff +0 -0
  323. package/dist/fonts/rubik-latin-400-normal.woff2 +0 -0
  324. package/dist/fonts/rubik-latin-500-normal.woff +0 -0
  325. package/dist/fonts/rubik-latin-500-normal.woff2 +0 -0
  326. package/dist/fonts/rubik-latin-ext-400-normal.woff +0 -0
  327. package/dist/fonts/rubik-latin-ext-400-normal.woff2 +0 -0
  328. package/dist/fonts/rubik-latin-ext-500-normal.woff +0 -0
  329. package/dist/fonts/rubik-latin-ext-500-normal.woff2 +0 -0
  330. package/dist/fonts/source-serif-pro-cyrillic-400-normal.woff +0 -0
  331. package/dist/fonts/source-serif-pro-cyrillic-400-normal.woff2 +0 -0
  332. package/dist/fonts/source-serif-pro-cyrillic-ext-400-normal.woff +0 -0
  333. package/dist/fonts/source-serif-pro-cyrillic-ext-400-normal.woff2 +0 -0
  334. package/dist/fonts/source-serif-pro-greek-400-normal.woff +0 -0
  335. package/dist/fonts/source-serif-pro-greek-400-normal.woff2 +0 -0
  336. package/dist/fonts/source-serif-pro-latin-400-normal.woff +0 -0
  337. package/dist/fonts/source-serif-pro-latin-400-normal.woff2 +0 -0
  338. package/dist/fonts/source-serif-pro-latin-ext-400-normal.woff +0 -0
  339. package/dist/fonts/source-serif-pro-latin-ext-400-normal.woff2 +0 -0
  340. package/dist/fonts/source-serif-pro-vietnamese-400-normal.woff +0 -0
  341. package/dist/fonts/source-serif-pro-vietnamese-400-normal.woff2 +0 -0
  342. package/dist/fonts/space-grotesk-latin-400-normal.woff +0 -0
  343. package/dist/fonts/space-grotesk-latin-400-normal.woff2 +0 -0
  344. package/dist/fonts/space-grotesk-latin-600-normal.woff +0 -0
  345. package/dist/fonts/space-grotesk-latin-600-normal.woff2 +0 -0
  346. package/dist/fonts/space-grotesk-latin-700-normal.woff +0 -0
  347. package/dist/fonts/space-grotesk-latin-700-normal.woff2 +0 -0
  348. package/dist/fonts/space-grotesk-latin-ext-400-normal.woff +0 -0
  349. package/dist/fonts/space-grotesk-latin-ext-400-normal.woff2 +0 -0
  350. package/dist/fonts/space-grotesk-latin-ext-600-normal.woff +0 -0
  351. package/dist/fonts/space-grotesk-latin-ext-600-normal.woff2 +0 -0
  352. package/dist/fonts/space-grotesk-latin-ext-700-normal.woff +0 -0
  353. package/dist/fonts/space-grotesk-latin-ext-700-normal.woff2 +0 -0
  354. package/dist/fonts/space-grotesk-vietnamese-400-normal.woff +0 -0
  355. package/dist/fonts/space-grotesk-vietnamese-400-normal.woff2 +0 -0
  356. package/dist/fonts/space-grotesk-vietnamese-600-normal.woff +0 -0
  357. package/dist/fonts/space-grotesk-vietnamese-600-normal.woff2 +0 -0
  358. package/dist/fonts/space-grotesk-vietnamese-700-normal.woff +0 -0
  359. package/dist/fonts/space-grotesk-vietnamese-700-normal.woff2 +0 -0
  360. package/dist/fonts/work-sans-latin-400-normal.woff +0 -0
  361. package/dist/fonts/work-sans-latin-400-normal.woff2 +0 -0
  362. package/dist/fonts/work-sans-latin-500-normal.woff +0 -0
  363. package/dist/fonts/work-sans-latin-500-normal.woff2 +0 -0
  364. package/dist/fonts/work-sans-latin-ext-400-normal.woff +0 -0
  365. package/dist/fonts/work-sans-latin-ext-400-normal.woff2 +0 -0
  366. package/dist/fonts/work-sans-latin-ext-500-normal.woff +0 -0
  367. package/dist/fonts/work-sans-latin-ext-500-normal.woff2 +0 -0
  368. package/dist/fonts/work-sans-vietnamese-400-normal.woff +0 -0
  369. package/dist/fonts/work-sans-vietnamese-400-normal.woff2 +0 -0
  370. package/dist/fonts/work-sans-vietnamese-500-normal.woff +0 -0
  371. package/dist/fonts/work-sans-vietnamese-500-normal.woff2 +0 -0
  372. package/dist/footer.js +308 -0
  373. package/dist/footer.js.map +1 -0
  374. package/dist/form-field.js +69 -0
  375. package/dist/form-field.js.map +1 -0
  376. package/dist/form.js +732 -0
  377. package/dist/form.js.map +1 -0
  378. package/dist/format.js +112 -0
  379. package/dist/format.js.map +1 -0
  380. package/dist/fouc.js +28 -0
  381. package/dist/fouc.js.map +1 -0
  382. package/dist/header.js +289 -0
  383. package/dist/header.js.map +1 -0
  384. package/dist/hooks.js +13 -0
  385. package/dist/hooks.js.map +1 -0
  386. package/dist/hover-card.js +210 -0
  387. package/dist/hover-card.js.map +1 -0
  388. package/dist/index-0ioNhtNM.js +11 -0
  389. package/dist/index-0ioNhtNM.js.map +1 -0
  390. package/dist/index-1QHKgw6D.js +55 -0
  391. package/dist/index-1QHKgw6D.js.map +1 -0
  392. package/dist/index-B6sSWi7l.js +747 -0
  393. package/dist/index-B6sSWi7l.js.map +1 -0
  394. package/dist/index-BCjJQGh8.js +71 -0
  395. package/dist/index-BCjJQGh8.js.map +1 -0
  396. package/dist/index-BGQepRFJ.js +28 -0
  397. package/dist/index-BGQepRFJ.js.map +1 -0
  398. package/dist/index-BVRIAMfe.js +37 -0
  399. package/dist/index-BVRIAMfe.js.map +1 -0
  400. package/dist/index-BY7PeRJA.js +145 -0
  401. package/dist/index-BY7PeRJA.js.map +1 -0
  402. package/dist/index-BZPx6jYI.js +9 -0
  403. package/dist/index-BZPx6jYI.js.map +1 -0
  404. package/dist/index-Ba4eHUBD.js +243 -0
  405. package/dist/index-Ba4eHUBD.js.map +1 -0
  406. package/dist/index-Bke1qZdk.js +35 -0
  407. package/dist/index-Bke1qZdk.js.map +1 -0
  408. package/dist/index-C0UREtMP.js +60 -0
  409. package/dist/index-C0UREtMP.js.map +1 -0
  410. package/dist/index-CCKe-Mpx.js +7 -0
  411. package/dist/index-CCKe-Mpx.js.map +1 -0
  412. package/dist/index-DFZozV_h.js +69 -0
  413. package/dist/index-DFZozV_h.js.map +1 -0
  414. package/dist/index-DFi6WydO.js +180 -0
  415. package/dist/index-DFi6WydO.js.map +1 -0
  416. package/dist/index-DQH6odE9.js +83 -0
  417. package/dist/index-DQH6odE9.js.map +1 -0
  418. package/dist/index-EO5flKM3.js +119 -0
  419. package/dist/index-EO5flKM3.js.map +1 -0
  420. package/dist/index-Lf7yDOXW.js +615 -0
  421. package/dist/index-Lf7yDOXW.js.map +1 -0
  422. package/dist/index-dhIqEbxW.js +1541 -0
  423. package/dist/index-dhIqEbxW.js.map +1 -0
  424. package/dist/index-pWhlqjff.js +32 -0
  425. package/dist/index-pWhlqjff.js.map +1 -0
  426. package/dist/index-rKs9bXHr.js +7 -0
  427. package/dist/index-rKs9bXHr.js.map +1 -0
  428. package/dist/index-xqkGMOJ8.js +14 -0
  429. package/dist/index-xqkGMOJ8.js.map +1 -0
  430. package/dist/index.js +247 -0
  431. package/dist/index.js.map +1 -0
  432. package/dist/input.js +22 -0
  433. package/dist/input.js.map +1 -0
  434. package/dist/label.js +36 -0
  435. package/dist/label.js.map +1 -0
  436. package/dist/layout-wrapper.js +208 -0
  437. package/dist/layout-wrapper.js.map +1 -0
  438. package/dist/llms.txt +1140 -0
  439. package/dist/menu-DBhEanGo.js +16 -0
  440. package/dist/menu-DBhEanGo.js.map +1 -0
  441. package/dist/menubar.js +565 -0
  442. package/dist/menubar.js.map +1 -0
  443. package/dist/mobile.js +183 -0
  444. package/dist/mobile.js.map +1 -0
  445. package/dist/motion.js +119 -0
  446. package/dist/motion.js.map +1 -0
  447. package/dist/page-header.js +47 -0
  448. package/dist/page-header.js.map +1 -0
  449. package/dist/page.js +214 -0
  450. package/dist/page.js.map +1 -0
  451. package/dist/pagination.js +121 -0
  452. package/dist/pagination.js.map +1 -0
  453. package/dist/platform.js +194 -0
  454. package/dist/platform.js.map +1 -0
  455. package/dist/popover.js +263 -0
  456. package/dist/popover.js.map +1 -0
  457. package/dist/popup.js +335 -0
  458. package/dist/popup.js.map +1 -0
  459. package/dist/progress.js +108 -0
  460. package/dist/progress.js.map +1 -0
  461. package/dist/radio-group.js +272 -0
  462. package/dist/radio-group.js.map +1 -0
  463. package/dist/safe-area.js +42 -0
  464. package/dist/safe-area.js.map +1 -0
  465. package/dist/search-CpUwRnG-.js +15 -0
  466. package/dist/search-CpUwRnG-.js.map +1 -0
  467. package/dist/select.js +985 -0
  468. package/dist/select.js.map +1 -0
  469. package/dist/separator.js +45 -0
  470. package/dist/separator.js.map +1 -0
  471. package/dist/sheet.js +127 -0
  472. package/dist/sheet.js.map +1 -0
  473. package/dist/skeleton.js +16 -0
  474. package/dist/skeleton.js.map +1 -0
  475. package/dist/slider.js +485 -0
  476. package/dist/slider.js.map +1 -0
  477. package/dist/sonner.js +52 -0
  478. package/dist/sonner.js.map +1 -0
  479. package/dist/styles/fonts.css +253 -0
  480. package/dist/styles.css +2 -0
  481. package/dist/switch.js +155 -0
  482. package/dist/switch.js.map +1 -0
  483. package/dist/tab-bar.js +110 -0
  484. package/dist/tab-bar.js.map +1 -0
  485. package/dist/table.js +115 -0
  486. package/dist/table.js.map +1 -0
  487. package/dist/tabs.js +218 -0
  488. package/dist/tabs.js.map +1 -0
  489. package/dist/textarea.js +19 -0
  490. package/dist/textarea.js.map +1 -0
  491. package/dist/theme-provider.js +154 -0
  492. package/dist/theme-provider.js.map +1 -0
  493. package/dist/themes.js +873 -0
  494. package/dist/themes.js.map +1 -0
  495. package/dist/toast.js +63 -0
  496. package/dist/toast.js.map +1 -0
  497. package/dist/toggle.js +70 -0
  498. package/dist/toggle.js.map +1 -0
  499. package/dist/tooltip.js +375 -0
  500. package/dist/tooltip.js.map +1 -0
  501. package/dist/types/App.d.ts +3 -0
  502. package/dist/types/App.d.ts.map +1 -0
  503. package/dist/types/components/layouts/admin.d.ts +117 -0
  504. package/dist/types/components/layouts/admin.d.ts.map +1 -0
  505. package/dist/types/components/layouts/auth.d.ts +17 -0
  506. package/dist/types/components/layouts/auth.d.ts.map +1 -0
  507. package/dist/types/components/layouts/blank.d.ts +63 -0
  508. package/dist/types/components/layouts/blank.d.ts.map +1 -0
  509. package/dist/types/components/layouts/layout-wrapper.d.ts +130 -0
  510. package/dist/types/components/layouts/layout-wrapper.d.ts.map +1 -0
  511. package/dist/types/components/layouts/mobile.d.ts +91 -0
  512. package/dist/types/components/layouts/mobile.d.ts.map +1 -0
  513. package/dist/types/components/layouts/page.d.ts +181 -0
  514. package/dist/types/components/layouts/page.d.ts.map +1 -0
  515. package/dist/types/components/layouts/popup.d.ts +100 -0
  516. package/dist/types/components/layouts/popup.d.ts.map +1 -0
  517. package/dist/types/components/sections/container.d.ts +79 -0
  518. package/dist/types/components/sections/container.d.ts.map +1 -0
  519. package/dist/types/components/sections/footer.d.ts +128 -0
  520. package/dist/types/components/sections/footer.d.ts.map +1 -0
  521. package/dist/types/components/sections/header.d.ts +72 -0
  522. package/dist/types/components/sections/header.d.ts.map +1 -0
  523. package/dist/types/components/sections/safe-area.d.ts +46 -0
  524. package/dist/types/components/sections/safe-area.d.ts.map +1 -0
  525. package/dist/types/components/sections/tab-bar.d.ts +61 -0
  526. package/dist/types/components/sections/tab-bar.d.ts.map +1 -0
  527. package/dist/types/components/ui/accordion.d.ts +8 -0
  528. package/dist/types/components/ui/accordion.d.ts.map +1 -0
  529. package/dist/types/components/ui/alert.d.ts +10 -0
  530. package/dist/types/components/ui/alert.d.ts.map +1 -0
  531. package/dist/types/components/ui/avatar.d.ts +7 -0
  532. package/dist/types/components/ui/avatar.d.ts.map +1 -0
  533. package/dist/types/components/ui/badge.d.ts +10 -0
  534. package/dist/types/components/ui/badge.d.ts.map +1 -0
  535. package/dist/types/components/ui/breadcrumb.d.ts +12 -0
  536. package/dist/types/components/ui/breadcrumb.d.ts.map +1 -0
  537. package/dist/types/components/ui/button.d.ts +11 -0
  538. package/dist/types/components/ui/button.d.ts.map +1 -0
  539. package/dist/types/components/ui/calendar.d.ts +9 -0
  540. package/dist/types/components/ui/calendar.d.ts.map +1 -0
  541. package/dist/types/components/ui/card.d.ts +10 -0
  542. package/dist/types/components/ui/card.d.ts.map +1 -0
  543. package/dist/types/components/ui/checkbox.d.ts +5 -0
  544. package/dist/types/components/ui/checkbox.d.ts.map +1 -0
  545. package/dist/types/components/ui/collapsible.d.ts +6 -0
  546. package/dist/types/components/ui/collapsible.d.ts.map +1 -0
  547. package/dist/types/components/ui/command.d.ts +19 -0
  548. package/dist/types/components/ui/command.d.ts.map +1 -0
  549. package/dist/types/components/ui/confirm-dialog.d.ts +72 -0
  550. package/dist/types/components/ui/confirm-dialog.d.ts.map +1 -0
  551. package/dist/types/components/ui/data-table.d.ts +211 -0
  552. package/dist/types/components/ui/data-table.d.ts.map +1 -0
  553. package/dist/types/components/ui/detail-page.d.ts +119 -0
  554. package/dist/types/components/ui/detail-page.d.ts.map +1 -0
  555. package/dist/types/components/ui/dialog.d.ts +16 -0
  556. package/dist/types/components/ui/dialog.d.ts.map +1 -0
  557. package/dist/types/components/ui/dropdown-menu.d.ts +26 -0
  558. package/dist/types/components/ui/dropdown-menu.d.ts.map +1 -0
  559. package/dist/types/components/ui/empty-state.d.ts +30 -0
  560. package/dist/types/components/ui/empty-state.d.ts.map +1 -0
  561. package/dist/types/components/ui/form-field.d.ts +57 -0
  562. package/dist/types/components/ui/form-field.d.ts.map +1 -0
  563. package/dist/types/components/ui/form.d.ts +185 -0
  564. package/dist/types/components/ui/form.d.ts.map +1 -0
  565. package/dist/types/components/ui/hover-card.d.ts +7 -0
  566. package/dist/types/components/ui/hover-card.d.ts.map +1 -0
  567. package/dist/types/components/ui/input.d.ts +4 -0
  568. package/dist/types/components/ui/input.d.ts.map +1 -0
  569. package/dist/types/components/ui/label.d.ts +5 -0
  570. package/dist/types/components/ui/label.d.ts.map +1 -0
  571. package/dist/types/components/ui/menubar.d.ts +27 -0
  572. package/dist/types/components/ui/menubar.d.ts.map +1 -0
  573. package/dist/types/components/ui/motion.d.ts +130 -0
  574. package/dist/types/components/ui/motion.d.ts.map +1 -0
  575. package/dist/types/components/ui/page-header.d.ts +45 -0
  576. package/dist/types/components/ui/page-header.d.ts.map +1 -0
  577. package/dist/types/components/ui/pagination.d.ts +14 -0
  578. package/dist/types/components/ui/pagination.d.ts.map +1 -0
  579. package/dist/types/components/ui/popover.d.ts +8 -0
  580. package/dist/types/components/ui/popover.d.ts.map +1 -0
  581. package/dist/types/components/ui/progress.d.ts +5 -0
  582. package/dist/types/components/ui/progress.d.ts.map +1 -0
  583. package/dist/types/components/ui/radio-group.d.ts +6 -0
  584. package/dist/types/components/ui/radio-group.d.ts.map +1 -0
  585. package/dist/types/components/ui/select.d.ts +16 -0
  586. package/dist/types/components/ui/select.d.ts.map +1 -0
  587. package/dist/types/components/ui/separator.d.ts +5 -0
  588. package/dist/types/components/ui/separator.d.ts.map +1 -0
  589. package/dist/types/components/ui/sheet.d.ts +14 -0
  590. package/dist/types/components/ui/sheet.d.ts.map +1 -0
  591. package/dist/types/components/ui/skeleton.d.ts +3 -0
  592. package/dist/types/components/ui/skeleton.d.ts.map +1 -0
  593. package/dist/types/components/ui/slider.d.ts +5 -0
  594. package/dist/types/components/ui/slider.d.ts.map +1 -0
  595. package/dist/types/components/ui/sonner.d.ts +4 -0
  596. package/dist/types/components/ui/sonner.d.ts.map +1 -0
  597. package/dist/types/components/ui/switch.d.ts +5 -0
  598. package/dist/types/components/ui/switch.d.ts.map +1 -0
  599. package/dist/types/components/ui/table.d.ts +11 -0
  600. package/dist/types/components/ui/table.d.ts.map +1 -0
  601. package/dist/types/components/ui/tabs.d.ts +8 -0
  602. package/dist/types/components/ui/tabs.d.ts.map +1 -0
  603. package/dist/types/components/ui/textarea.d.ts +4 -0
  604. package/dist/types/components/ui/textarea.d.ts.map +1 -0
  605. package/dist/types/components/ui/toast.d.ts +70 -0
  606. package/dist/types/components/ui/toast.d.ts.map +1 -0
  607. package/dist/types/components/ui/toggle.d.ts +10 -0
  608. package/dist/types/components/ui/toggle.d.ts.map +1 -0
  609. package/dist/types/components/ui/tooltip.d.ts +8 -0
  610. package/dist/types/components/ui/tooltip.d.ts.map +1 -0
  611. package/dist/types/hooks/index.d.ts +14 -0
  612. package/dist/types/hooks/index.d.ts.map +1 -0
  613. package/dist/types/hooks/useApi.d.ts +38 -0
  614. package/dist/types/hooks/useApi.d.ts.map +1 -0
  615. package/dist/types/hooks/useBreakpoint.d.ts +35 -0
  616. package/dist/types/hooks/useBreakpoint.d.ts.map +1 -0
  617. package/dist/types/hooks/useDataTable.d.ts +59 -0
  618. package/dist/types/hooks/useDataTable.d.ts.map +1 -0
  619. package/dist/types/hooks/useMediaQuery.d.ts +12 -0
  620. package/dist/types/hooks/useMediaQuery.d.ts.map +1 -0
  621. package/dist/types/hooks/useStorage.d.ts +35 -0
  622. package/dist/types/hooks/useStorage.d.ts.map +1 -0
  623. package/dist/types/index.d.ts +75 -0
  624. package/dist/types/index.d.ts.map +1 -0
  625. package/dist/types/lib/errors.d.ts +37 -0
  626. package/dist/types/lib/errors.d.ts.map +1 -0
  627. package/dist/types/lib/format.d.ts +80 -0
  628. package/dist/types/lib/format.d.ts.map +1 -0
  629. package/dist/types/lib/fouc.d.ts +64 -0
  630. package/dist/types/lib/fouc.d.ts.map +1 -0
  631. package/dist/types/lib/platform.d.ts +156 -0
  632. package/dist/types/lib/platform.d.ts.map +1 -0
  633. package/dist/types/lib/utils.d.ts +14 -0
  634. package/dist/types/lib/utils.d.ts.map +1 -0
  635. package/dist/types/main.d.ts +2 -0
  636. package/dist/types/main.d.ts.map +1 -0
  637. package/dist/types/themes/index.d.ts +499 -0
  638. package/dist/types/themes/index.d.ts.map +1 -0
  639. package/dist/types/themes/presets/base.d.ts +108 -0
  640. package/dist/types/themes/presets/base.d.ts.map +1 -0
  641. package/dist/types/themes/presets/elegant.d.ts +108 -0
  642. package/dist/types/themes/presets/elegant.d.ts.map +1 -0
  643. package/dist/types/themes/presets/metro.d.ts +114 -0
  644. package/dist/types/themes/presets/metro.d.ts.map +1 -0
  645. package/dist/types/themes/presets/studio.d.ts +115 -0
  646. package/dist/types/themes/presets/studio.d.ts.map +1 -0
  647. package/dist/types/themes/presets/vivid.d.ts +115 -0
  648. package/dist/types/themes/presets/vivid.d.ts.map +1 -0
  649. package/dist/types/themes/theme-provider.d.ts +122 -0
  650. package/dist/types/themes/theme-provider.d.ts.map +1 -0
  651. package/dist/types/types/index.d.ts +813 -0
  652. package/dist/types/types/index.d.ts.map +1 -0
  653. package/dist/uikit.css +1 -0
  654. package/dist/useDataTable-CPiBpEg-.js +254 -0
  655. package/dist/useDataTable-CPiBpEg-.js.map +1 -0
  656. package/dist/utils-CwJPJKOE.js +2278 -0
  657. package/dist/utils-CwJPJKOE.js.map +1 -0
  658. package/dist/utils.js +5 -0
  659. package/dist/utils.js.map +1 -0
  660. package/dist/wrapper.js +13 -0
  661. package/dist/wrapper.js.map +1 -0
  662. package/dist/x-BxwubQiM.js +15 -0
  663. package/dist/x-BxwubQiM.js.map +1 -0
  664. package/examples/README.md +18 -0
  665. package/examples/button.tsx +16 -0
  666. package/examples/confirm-dialog.tsx +44 -0
  667. package/examples/data-table.tsx +35 -0
  668. package/examples/dialog.tsx +34 -0
  669. package/examples/empty-state.tsx +13 -0
  670. package/examples/form-field.tsx +22 -0
  671. package/examples/format.tsx +19 -0
  672. package/examples/page-header.tsx +17 -0
  673. package/examples/skeleton.tsx +12 -0
  674. package/examples/theme-provider.tsx +33 -0
  675. package/examples/toast.tsx +32 -0
  676. package/examples/use-breakpoint.tsx +17 -0
  677. package/llms.txt +1140 -0
  678. package/package.json +430 -0
@@ -0,0 +1,673 @@
1
+ /**
2
+ * @fileoverview UIKit Generate Command - Frontend feature scaffolding
3
+ * @description Generates new frontend features using FBCA pattern with UIKit components
4
+ */
5
+
6
+ import fs from 'fs/promises';
7
+ import path from 'path';
8
+ import { fileURLToPath } from 'url';
9
+
10
+ const __filename = fileURLToPath(import.meta.url);
11
+ const __dirname = path.dirname(__filename);
12
+
13
+ /**
14
+ * Generate a new frontend feature using TypeScript templates
15
+ */
16
+ export async function generateFeature(type, name, options) {
17
+ const theme = options && options.theme || 'base';
18
+ console.log(`šŸŽØ Generating ${type}: "${name}" with ${theme} theme...\n`);
19
+
20
+ try {
21
+ // Handle theme generation separately (doesn't need features directory)
22
+ if (type === 'theme') {
23
+ await generateThemeFeature(name, options);
24
+ console.log(`āœ… Generated ${type} "${name}" successfully!`);
25
+ return;
26
+ }
27
+
28
+ // Validate feature name (allow forward slashes for nested paths)
29
+ if (!name || !/^[a-zA-Z0-9-_/]+$/.test(name)) {
30
+ console.error('āŒ Invalid feature name. Use only letters, numbers, hyphens, underscores, and forward slashes.');
31
+ process.exit(1);
32
+ }
33
+
34
+ // Check if we're in a project directory
35
+ const currentDir = process.cwd();
36
+ const packageJsonPath = path.join(currentDir, 'package.json');
37
+
38
+ try {
39
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
40
+ if (!packageJson.dependencies || !packageJson.dependencies['@bloomneo/uikit']) {
41
+ console.error('āŒ Not in a UIKit project directory. Run this from project root.');
42
+ process.exit(1);
43
+ }
44
+ } catch {
45
+ console.error('āŒ No package.json found. Run this from project root.');
46
+ process.exit(1);
47
+ }
48
+
49
+ // Check if we're in FBCA structure (src/web/features or src/features)
50
+ let featuresPath = path.join(currentDir, 'src/web/features');
51
+ let isFBCA = true;
52
+
53
+ try {
54
+ await fs.access(featuresPath);
55
+ } catch {
56
+ // Try alternative path
57
+ featuresPath = path.join(currentDir, 'src/features');
58
+ try {
59
+ await fs.access(featuresPath);
60
+ } catch {
61
+ // Create features directory in preferred location
62
+ featuresPath = path.join(currentDir, 'src/web/features');
63
+ await fs.mkdir(featuresPath, { recursive: true });
64
+ console.log(`šŸ“ Created features directory: ${featuresPath}`);
65
+ }
66
+ }
67
+
68
+ // Check if feature already exists
69
+ const featurePath = path.join(featuresPath, name);
70
+ try {
71
+ await fs.access(featurePath);
72
+ console.error(`āŒ Feature "${name}" already exists.`);
73
+ process.exit(1);
74
+ } catch {
75
+ // Feature doesn't exist, good to proceed
76
+ }
77
+
78
+ // Generate feature based on type
79
+ if (type === 'page') {
80
+ await generatePageFeature(featuresPath, name, options);
81
+ } else if (type === 'component') {
82
+ await generateComponentFeature(featuresPath, name, options);
83
+ } else if (type === 'hook') {
84
+ await generateHookFeature(featuresPath, name, options);
85
+ } else if (type === 'feature') {
86
+ await generateFullFeature(featuresPath, name, options);
87
+ } else {
88
+ console.error(`āŒ Unknown type "${type}". Use: page, component, hook, feature, or theme`);
89
+ process.exit(1);
90
+ }
91
+
92
+ console.log(`āœ… Generated ${type} "${name}" successfully!`);
93
+
94
+ } catch (error) {
95
+ console.error('āŒ Failed to generate feature:', error.message);
96
+ process.exit(1);
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Generate a page component following FBCA convention with nested path support
102
+ */
103
+ async function generatePageFeature(featuresPath, name, options) {
104
+ // Parse feature name and nested path
105
+ // Examples: "dashboard" → feature: dashboard, path: index.tsx
106
+ // "dashboard/new" → feature: dashboard, path: new.tsx
107
+ // "dashboard/new/apple" → feature: dashboard, path: new/apple.tsx
108
+
109
+ const pathParts = name.split('/');
110
+ const featureName = pathParts[0];
111
+ const nestedPath = pathParts.slice(1);
112
+
113
+ let targetDir;
114
+
115
+ if (nestedPath.length === 0) {
116
+ // Simple page goes to main feature - don't create the original feature directory
117
+ targetDir = path.join(featuresPath, 'main', 'pages');
118
+ } else {
119
+ // Nested path creates its own feature
120
+ const featurePath = path.join(featuresPath, featureName);
121
+ const pagesPath = path.join(featurePath, 'pages');
122
+
123
+ // Create the full nested directory structure
124
+ targetDir = pagesPath;
125
+ if (nestedPath.length > 1) {
126
+ // Create nested directories for deep paths like "new/apple"
127
+ const nestedDirs = nestedPath.slice(0, -1).join('/');
128
+ targetDir = path.join(pagesPath, nestedDirs);
129
+ }
130
+ }
131
+
132
+ await fs.mkdir(targetDir, { recursive: true });
133
+
134
+ const templatesPath = path.join(__dirname, '../templates/generate/page');
135
+
136
+ try {
137
+ // Determine the page file name
138
+ let pageFileName;
139
+ if (nestedPath.length === 0) {
140
+ // Simple feature name like "dashboard" → goes to main/pages/dashboard.tsx
141
+ pageFileName = `${featureName}.tsx`;
142
+ } else {
143
+ // Nested path like "dashboard/new" → new.tsx or "dashboard/new/apple" → apple.tsx
144
+ pageFileName = `${nestedPath[nestedPath.length - 1]}.tsx`;
145
+ }
146
+
147
+ // Generate the page component
148
+ await generateFromTemplate(templatesPath, 'page.tsx.template', targetDir, pageFileName, featureName, options);
149
+
150
+ const relativePath = nestedPath.length === 0
151
+ ? `main/pages/${featureName}.tsx`
152
+ : `${featureName}/pages/${nestedPath.join('/')}.tsx`;
153
+
154
+ console.log(`šŸ“ Created: src/web/features/${relativePath}`);
155
+ } catch (error) {
156
+ console.error(`āŒ Failed to generate page: ${error.message}`);
157
+ throw error;
158
+ }
159
+ }
160
+
161
+ /**
162
+ * Generate a reusable component with shared/feature logic
163
+ */
164
+ async function generateComponentFeature(featuresPath, name, options) {
165
+ // Parse component name and feature path
166
+ // Examples: "button" → shared/components/Button.tsx
167
+ // "blog/post-card" → blog/components/PostCard.tsx
168
+
169
+ const pathParts = name.split('/');
170
+ const isFeatureSpecific = pathParts.length > 1;
171
+
172
+ let targetDir;
173
+ let componentName;
174
+ let relativePath;
175
+
176
+ if (isFeatureSpecific) {
177
+ // Feature-specific component like "blog/post-card"
178
+ const featureName = pathParts[0];
179
+ const componentBaseName = pathParts[pathParts.length - 1];
180
+ componentName = componentBaseName.split('-').map(part =>
181
+ part.charAt(0).toUpperCase() + part.slice(1)
182
+ ).join('');
183
+
184
+ const featurePath = path.join(featuresPath, featureName);
185
+ targetDir = path.join(featurePath, 'components');
186
+ relativePath = `${featureName}/components/${componentName}.tsx`;
187
+ } else {
188
+ // Shared component like "button"
189
+ componentName = name.split('-').map(part =>
190
+ part.charAt(0).toUpperCase() + part.slice(1)
191
+ ).join('');
192
+
193
+ // Go up from features to web, then to shared/components
194
+ const webPath = path.dirname(featuresPath);
195
+ targetDir = path.join(webPath, 'shared', 'components');
196
+ relativePath = `shared/components/${componentName}.tsx`;
197
+ }
198
+
199
+ await fs.mkdir(targetDir, { recursive: true });
200
+
201
+ const templatesPath = path.join(__dirname, '../templates/generate/component');
202
+
203
+ try {
204
+ // Generate component only - pass componentName as the feature name for template replacement
205
+ const templateOptions = { ...options, componentName: componentName };
206
+ await generateComponentFromTemplate(templatesPath, 'component.tsx.template', targetDir, `${componentName}.tsx`, componentName, templateOptions);
207
+
208
+ const displayPath = isFeatureSpecific
209
+ ? `src/web/features/${relativePath}`
210
+ : `src/web/${relativePath}`;
211
+
212
+ console.log(`šŸ“ Created: ${displayPath}`);
213
+ } catch (error) {
214
+ console.error(`āŒ Failed to generate component: ${error.message}`);
215
+ throw error;
216
+ }
217
+ }
218
+
219
+ /**
220
+ * Generate a custom hook with shared/feature logic
221
+ */
222
+ async function generateHookFeature(featuresPath, name, options) {
223
+ // Parse hook name and feature path
224
+ // Examples: "sample" → shared/hooks/useSharedSample.ts
225
+ // "greeting/welcome" → greeting/hooks/useWelcome.ts
226
+
227
+ const pathParts = name.split('/');
228
+ const isFeatureSpecific = pathParts.length > 1;
229
+
230
+ let targetDir;
231
+ let hookName;
232
+ let relativePath;
233
+
234
+ if (isFeatureSpecific) {
235
+ // Feature-specific hook like "greeting/welcome"
236
+ const featureName = pathParts[0];
237
+ const hookBaseName = pathParts[pathParts.length - 1];
238
+ hookName = 'use' + hookBaseName.split('-').map(part =>
239
+ part.charAt(0).toUpperCase() + part.slice(1)
240
+ ).join('');
241
+
242
+ const featurePath = path.join(featuresPath, featureName);
243
+ targetDir = path.join(featurePath, 'hooks');
244
+ relativePath = `${featureName}/hooks/${hookName}.ts`;
245
+ } else {
246
+ // Shared hook like "sample"
247
+ hookName = 'useShared' + name.split('-').map(part =>
248
+ part.charAt(0).toUpperCase() + part.slice(1)
249
+ ).join('');
250
+
251
+ // Go up from features to web, then to shared/hooks
252
+ const webPath = path.dirname(featuresPath);
253
+ targetDir = path.join(webPath, 'shared', 'hooks');
254
+ relativePath = `shared/hooks/${hookName}.ts`;
255
+ }
256
+
257
+ await fs.mkdir(targetDir, { recursive: true });
258
+
259
+ const templatesPath = path.join(__dirname, '../templates/generate/hook');
260
+
261
+ try {
262
+ // Generate hook only - pass hookName for template replacement
263
+ const templateOptions = { ...options, hookName: hookName };
264
+ await generateHookFromTemplate(templatesPath, 'hook.ts.template', targetDir, `${hookName}.ts`, hookName, templateOptions);
265
+
266
+ const displayPath = isFeatureSpecific
267
+ ? `src/web/features/${relativePath}`
268
+ : `src/web/${relativePath}`;
269
+
270
+ console.log(`šŸ“ Created: ${displayPath}`);
271
+ } catch (error) {
272
+ console.error(`āŒ Failed to generate hook: ${error.message}`);
273
+ throw error;
274
+ }
275
+ }
276
+
277
+ /**
278
+ * Generate a complete feature with hook, component, and page
279
+ */
280
+ async function generateFullFeature(featuresPath, name, options) {
281
+ const featurePath = path.join(featuresPath, name);
282
+ await fs.mkdir(featurePath, { recursive: true });
283
+
284
+ try {
285
+ // Create directory structure
286
+ const pagesPath = path.join(featurePath, 'pages');
287
+ const componentsPath = path.join(featurePath, 'components');
288
+ const hooksPath = path.join(featurePath, 'hooks');
289
+
290
+ await fs.mkdir(pagesPath, { recursive: true });
291
+ await fs.mkdir(componentsPath, { recursive: true });
292
+ await fs.mkdir(hooksPath, { recursive: true });
293
+
294
+ // Component and hook names
295
+ const componentName = name.charAt(0).toUpperCase() + name.slice(1);
296
+ const hookName = `use${componentName}`;
297
+
298
+ // Generate hook
299
+ const hookTemplatesPath = path.join(__dirname, '../templates/generate/hook');
300
+ const hookOptions = { ...options, hookName: hookName };
301
+ await generateHookFromTemplate(hookTemplatesPath, 'hook.ts.template', hooksPath, `${hookName}.ts`, hookName, hookOptions);
302
+
303
+ // Generate component
304
+ const componentTemplatesPath = path.join(__dirname, '../templates/generate/component');
305
+ const componentOptions = { ...options, componentName: componentName };
306
+ await generateComponentFromTemplate(componentTemplatesPath, 'component.tsx.template', componentsPath, `${componentName}.tsx`, componentName, componentOptions);
307
+
308
+ // Generate page (index page for the feature)
309
+ const pageTemplatesPath = path.join(__dirname, '../templates/generate/page');
310
+ await generateFromTemplate(pageTemplatesPath, 'page.tsx.template', pagesPath, 'index.tsx', name, options);
311
+
312
+ console.log(`šŸ“ Created: src/web/features/${name}/hooks/${hookName}.ts`);
313
+ console.log(`šŸ“ Created: src/web/features/${name}/components/${componentName}.tsx`);
314
+ console.log(`šŸ“ Created: src/web/features/${name}/pages/index.tsx`);
315
+ } catch (error) {
316
+ console.error(`āŒ Failed to generate feature: ${error.message}`);
317
+ throw error;
318
+ }
319
+ }
320
+
321
+ /**
322
+ * Generate component file from template with proper variable replacement
323
+ */
324
+ async function generateComponentFromTemplate(templatesPath, templateFile, outputPath, outputFile, componentName, options) {
325
+ try {
326
+ // Read template file
327
+ const templatePath = path.join(templatesPath, templateFile);
328
+ const templateContent = await fs.readFile(templatePath, 'utf8');
329
+
330
+ // Get project name from package.json
331
+ const currentDir = process.cwd();
332
+ const packageJsonPath = path.join(currentDir, 'package.json');
333
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
334
+ const projectName = packageJson.name || 'my-uikit-project';
335
+
336
+ // Determine theme
337
+ const theme = options && options.theme || 'base';
338
+
339
+ // Convert component name for different cases
340
+ const componentBaseName = componentName.toLowerCase().replace(/([A-Z])/g, '-$1').toLowerCase();
341
+
342
+ // Replace template variables
343
+ const processedContent = templateContent
344
+ .replace(/\{\{componentName\}\}/g, componentBaseName)
345
+ .replace(/\{\{ComponentName\}\}/g, componentName)
346
+ .replace(/\{\{projectName\}\}/g, projectName)
347
+ .replace(/\{\{theme\}\}/g, theme);
348
+
349
+ // Write output file
350
+ const outputFilePath = path.join(outputPath, outputFile);
351
+ await fs.writeFile(outputFilePath, processedContent, 'utf8');
352
+ } catch (error) {
353
+ console.error(`āŒ Failed to generate ${outputFile} from template ${templateFile}:`, error.message);
354
+ throw error;
355
+ }
356
+ }
357
+
358
+ /**
359
+ * Generate hook file from template with proper variable replacement
360
+ */
361
+ async function generateHookFromTemplate(templatesPath, templateFile, outputPath, outputFile, hookName, options) {
362
+ try {
363
+ // Read template file
364
+ const templatePath = path.join(templatesPath, templateFile);
365
+ const templateContent = await fs.readFile(templatePath, 'utf8');
366
+
367
+ // Get project name from package.json
368
+ const currentDir = process.cwd();
369
+ const packageJsonPath = path.join(currentDir, 'package.json');
370
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
371
+ const projectName = packageJson.name || 'my-uikit-project';
372
+
373
+ // Determine theme
374
+ const theme = options && options.theme || 'base';
375
+
376
+ // Replace template variables
377
+ const processedContent = templateContent
378
+ .replace(/\{\{hookName\}\}/g, hookName)
379
+ .replace(/\{\{projectName\}\}/g, projectName)
380
+ .replace(/\{\{theme\}\}/g, theme);
381
+
382
+ // Write output file
383
+ const outputFilePath = path.join(outputPath, outputFile);
384
+ await fs.writeFile(outputFilePath, processedContent, 'utf8');
385
+ } catch (error) {
386
+ console.error(`āŒ Failed to generate ${outputFile} from template ${templateFile}:`, error.message);
387
+ throw error;
388
+ }
389
+ }
390
+
391
+ /**
392
+ * Generate file from template with variable replacement
393
+ */
394
+ async function generateFromTemplate(templatesPath, templateFile, outputPath, outputFile, featureName, options) {
395
+ try {
396
+ // Read template file
397
+ const templatePath = path.join(templatesPath, templateFile);
398
+ const templateContent = await fs.readFile(templatePath, 'utf8');
399
+
400
+ // Get project name from package.json
401
+ const currentDir = process.cwd();
402
+ const packageJsonPath = path.join(currentDir, 'package.json');
403
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
404
+ const projectName = packageJson.name || 'my-uikit-project';
405
+
406
+ // Determine theme
407
+ const theme = options && options.theme || 'base';
408
+
409
+ // Replace template variables
410
+ const processedContent = templateContent
411
+ .replace(/\{\{featureName\}\}/g, featureName)
412
+ .replace(/\{\{FeatureName\}\}/g, featureName.charAt(0).toUpperCase() + featureName.slice(1))
413
+ .replace(/\{\{FEATURE_NAME\}\}/g, featureName.toUpperCase())
414
+ .replace(/\{\{componentName\}\}/g, featureName)
415
+ .replace(/\{\{ComponentName\}\}/g, featureName.charAt(0).toUpperCase() + featureName.slice(1))
416
+ .replace(/\{\{projectName\}\}/g, projectName)
417
+ .replace(/\{\{theme\}\}/g, theme);
418
+
419
+ // Write output file
420
+ const outputFilePath = path.join(outputPath, outputFile);
421
+ await fs.writeFile(outputFilePath, processedContent, 'utf8');
422
+ } catch (error) {
423
+ console.error(`āŒ Failed to generate ${outputFile} from template ${templateFile}:`, error.message);
424
+ throw error;
425
+ }
426
+ }
427
+ /**
428
+ * Generate a custom theme file
429
+ */
430
+ async function generateThemeFeature(name, options) {
431
+ // Validate theme name
432
+ if (!name || !/^[a-zA-Z0-9-_]+$/.test(name)) {
433
+ console.error('āŒ Invalid theme name. Use only letters, numbers, hyphens, and underscores.');
434
+ process.exit(1);
435
+ }
436
+
437
+ // Check if we're in a project directory
438
+ const currentDir = process.cwd();
439
+ const packageJsonPath = path.join(currentDir, 'package.json');
440
+
441
+ try {
442
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
443
+ if (!packageJson.dependencies || !packageJson.dependencies['@bloomneo/uikit']) {
444
+ console.error('āŒ Not in a UIKit project directory. Run this from project root.');
445
+ process.exit(1);
446
+ }
447
+ } catch {
448
+ console.error('āŒ No package.json found. Run this from project root.');
449
+ process.exit(1);
450
+ }
451
+
452
+ // Determine theme directory based on project structure
453
+ let themesPath;
454
+ const isWebStructure = await fs.access(path.join(currentDir, 'src/web')).then(() => true).catch(() => false);
455
+
456
+ if (isWebStructure) {
457
+ // FBCA structure - check for existing themes in web directory
458
+ const possiblePaths = [
459
+ 'src/web/themes/presets',
460
+ 'src/web/assets/themes/presets',
461
+ ];
462
+
463
+ // Try to find existing themes directory
464
+ for (const possiblePath of possiblePaths) {
465
+ const fullPath = path.join(currentDir, possiblePath);
466
+ try {
467
+ await fs.access(fullPath);
468
+ themesPath = fullPath;
469
+ break;
470
+ } catch {
471
+ // Directory doesn't exist, continue searching
472
+ }
473
+ }
474
+
475
+ // If no existing themes directory, create the preferred one for FBCA
476
+ if (!themesPath) {
477
+ themesPath = path.join(currentDir, 'src/web/themes/presets');
478
+ await fs.mkdir(themesPath, { recursive: true });
479
+ console.log(`šŸ“ Created themes directory: ${themesPath}`);
480
+ }
481
+ } else {
482
+ // SPA/Multi structure - check for existing themes in src directory
483
+ const possiblePaths = [
484
+ 'src/themes/presets',
485
+ 'themes/presets',
486
+ ];
487
+
488
+ // Try to find existing themes directory
489
+ for (const possiblePath of possiblePaths) {
490
+ const fullPath = path.join(currentDir, possiblePath);
491
+ try {
492
+ await fs.access(fullPath);
493
+ themesPath = fullPath;
494
+ break;
495
+ } catch {
496
+ // Directory doesn't exist, continue searching
497
+ }
498
+ }
499
+
500
+ // If no existing themes directory, create the preferred one for SPA/Multi
501
+ if (!themesPath) {
502
+ themesPath = path.join(currentDir, 'src/themes/presets');
503
+ await fs.mkdir(themesPath, { recursive: true });
504
+ console.log(`šŸ“ Created themes directory: ${themesPath}`);
505
+ }
506
+ }
507
+
508
+ // Check if theme already exists
509
+ const themeFileName = `theme-${name}.js`;
510
+ const themeFilePath = path.join(themesPath, themeFileName);
511
+
512
+ try {
513
+ await fs.access(themeFilePath);
514
+ console.error(`āŒ Theme "${name}" already exists at ${themeFilePath}`);
515
+ process.exit(1);
516
+ } catch {
517
+ // Theme doesn't exist, good to proceed
518
+ }
519
+
520
+ try {
521
+ // Generate theme from template
522
+ const templatesPath = path.join(__dirname, '../templates/generate/theme');
523
+ await generateThemeFromTemplate(templatesPath, 'theme.js.template', themesPath, themeFileName, name, options);
524
+
525
+ // Get relative path for display
526
+ const relativePath = path.relative(currentDir, themeFilePath);
527
+ console.log(`šŸ“ Created: ${relativePath}`);
528
+
529
+ // Auto-update main.tsx with CSS import and theme setting
530
+ // Use the same project structure detection from above
531
+ let stylesGlobalPath, mainTsxPath;
532
+
533
+ if (isWebStructure) {
534
+ // FBCA structure
535
+ stylesGlobalPath = path.join(currentDir, 'src/web/styles/globals.css');
536
+ mainTsxPath = path.join(currentDir, 'src/web/main.tsx');
537
+ } else {
538
+ // SPA/Multi structure
539
+ stylesGlobalPath = path.join(currentDir, 'src/styles/globals.css');
540
+ mainTsxPath = path.join(currentDir, 'src/main.tsx');
541
+ }
542
+
543
+ const hasStylesGlobal = await fs.access(stylesGlobalPath).then(() => true).catch(() => false);
544
+
545
+ try {
546
+ // Read main.tsx
547
+ let mainContent = await fs.readFile(mainTsxPath, 'utf8');
548
+ let updated = false;
549
+
550
+ // Add CSS import for globals.css (will be created by bundle command)
551
+ const cssImportPath = './styles/globals.css';
552
+ if (!mainContent.includes(cssImportPath)) {
553
+ // Simple approach: find the index.css import line and add globals.css after it
554
+ const indexCssImport = "import './styles/index.css';";
555
+ if (mainContent.includes(indexCssImport)) {
556
+ mainContent = mainContent.replace(
557
+ indexCssImport,
558
+ `${indexCssImport}\nimport '${cssImportPath}';`
559
+ );
560
+ console.log(`āœ… Added import '${cssImportPath}' to main.tsx`);
561
+ updated = true;
562
+ } else {
563
+ // Fallback: add after any CSS import
564
+ const cssImportRegex = /(import\s+['"'][^'"]*\.css['"];)/;
565
+ if (cssImportRegex.test(mainContent)) {
566
+ mainContent = mainContent.replace(
567
+ cssImportRegex,
568
+ `$1\nimport '${cssImportPath}';`
569
+ );
570
+ console.log(`āœ… Added import '${cssImportPath}' to main.tsx`);
571
+ updated = true;
572
+ }
573
+ }
574
+ }
575
+
576
+ // Update theme in ThemeProvider if it exists
577
+ if (mainContent.includes('ThemeProvider')) {
578
+ const oldThemeMatch = mainContent.match(/theme="([^"]+)"/);
579
+ if (oldThemeMatch) {
580
+ const oldTheme = oldThemeMatch[1];
581
+
582
+ // Update theme
583
+ mainContent = mainContent.replace(
584
+ /theme="[^"]+"/,
585
+ `theme="${name}"`
586
+ );
587
+
588
+ // Add forceConfig if not present
589
+ if (!mainContent.includes('forceConfig')) {
590
+ mainContent = mainContent.replace(
591
+ /<ThemeProvider([^>]+)>/,
592
+ `<ThemeProvider$1 forceConfig={true}>`
593
+ );
594
+ }
595
+
596
+ console.log(`āœ… Updated theme from "${oldTheme}" to "${name}" in main.tsx`);
597
+ updated = true;
598
+ }
599
+ } else {
600
+ // Add ThemeProvider if it doesn't exist
601
+ if (!mainContent.includes('ThemeProvider')) {
602
+ // Add import
603
+ mainContent = mainContent.replace(
604
+ /(import.*from.*;\n)$/m,
605
+ `$1import { ThemeProvider } from '@bloomneo/uikit/theme-provider';\n`
606
+ );
607
+
608
+ // Wrap App with ThemeProvider (with forceConfig to override storage)
609
+ mainContent = mainContent.replace(
610
+ /(<React\.StrictMode>\s*<App[^>]*\/>\s*<\/React\.StrictMode>)/,
611
+ `<React.StrictMode>\n <ThemeProvider theme="${name}" mode="light" forceConfig={true}>\n <App />\n </ThemeProvider>\n </React.StrictMode>`
612
+ );
613
+ console.log(`āœ… Added ThemeProvider with theme "${name}" to main.tsx`);
614
+ updated = true;
615
+ }
616
+ }
617
+
618
+ // Write updated content if changes were made
619
+ if (updated) {
620
+ await fs.writeFile(mainTsxPath, mainContent);
621
+ }
622
+
623
+ } catch (error) {
624
+ console.log(`āš ļø Could not auto-update main.tsx: ${error.message}`);
625
+ }
626
+
627
+ console.log(`\nšŸŽØ Next steps:`);
628
+ console.log(` 1. Customize colors in ${relativePath}`);
629
+ console.log(` 2. Run "npx uikit bundle" to generate CSS`);
630
+ console.log(`\nšŸŽ‰ Theme "${name}" is now active!`);
631
+
632
+ } catch (error) {
633
+ console.error(`āŒ Failed to generate theme: ${error.message}`);
634
+ throw error;
635
+ }
636
+ }
637
+
638
+ /**
639
+ * Generate theme file from template with proper variable replacement
640
+ */
641
+ async function generateThemeFromTemplate(templatesPath, templateFile, outputPath, outputFile, themeName, options) {
642
+ try {
643
+ // Read template file
644
+ const templatePath = path.join(templatesPath, templateFile);
645
+ const templateContent = await fs.readFile(templatePath, 'utf8');
646
+
647
+ // Get project name from package.json
648
+ const currentDir = process.cwd();
649
+ const packageJsonPath = path.join(currentDir, 'package.json');
650
+ const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
651
+ const projectName = packageJson.name || 'my-uikit-project';
652
+
653
+ // Determine theme
654
+ const theme = options && options.theme || 'base';
655
+
656
+ // Create theme name variations
657
+ const ThemeName = themeName.charAt(0).toUpperCase() + themeName.slice(1);
658
+
659
+ // Replace template variables
660
+ const processedContent = templateContent
661
+ .replace(/\{\{themeName\}\}/g, themeName)
662
+ .replace(/\{\{ThemeName\}\}/g, ThemeName)
663
+ .replace(/\{\{projectName\}\}/g, projectName)
664
+ .replace(/\{\{theme\}\}/g, theme);
665
+
666
+ // Write output file
667
+ const outputFilePath = path.join(outputPath, outputFile);
668
+ await fs.writeFile(outputFilePath, processedContent, 'utf8');
669
+ } catch (error) {
670
+ console.error(`āŒ Failed to generate ${outputFile} from template ${templateFile}:`, error.message);
671
+ throw error;
672
+ }
673
+ }