@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,768 @@
1
+ /**
2
+ * @fileoverview UIKit Create Command - Project scaffolding
3
+ * @description Creates new UIKit projects from templates
4
+ * @package @bloomneo/uikit
5
+ */
6
+
7
+ import fs from 'fs/promises';
8
+ import path from 'path';
9
+ import { spawn } from 'child_process';
10
+ import { fileURLToPath } from 'url';
11
+
12
+ const __filename = fileURLToPath(import.meta.url);
13
+ const __dirname = path.dirname(__filename);
14
+
15
+ /**
16
+ * Create a new UIKit project
17
+ */
18
+ export async function createProject(name, options) {
19
+ const isCurrentDir = name === '.';
20
+ const displayName = isCurrentDir ? 'current directory' : `"${name}"`;
21
+ console.log(`🎨 Creating UIKit project in ${displayName}...\n`);
22
+
23
+ try {
24
+ // Determine template type
25
+ const templateType = options.spa ? 'spa' : options.multi ? 'multi' : options.fbca ? 'fbca' : 'single';
26
+
27
+ let projectPath;
28
+
29
+ if (isCurrentDir) {
30
+ // Use current directory
31
+ projectPath = process.cwd();
32
+ console.log(`✅ Using current directory`);
33
+ } else {
34
+ // Validate project name
35
+ if (!name || !/^[a-zA-Z0-9-_]+$/.test(name)) {
36
+ console.error('❌ Invalid project name. Use only letters, numbers, hyphens, and underscores.');
37
+ process.exit(1);
38
+ }
39
+
40
+ // Check if directory exists
41
+ projectPath = path.resolve(process.cwd(), name);
42
+ try {
43
+ await fs.access(projectPath);
44
+ console.error(`❌ Directory "${name}" already exists.`);
45
+ process.exit(1);
46
+ } catch {
47
+ // Directory doesn't exist, good to proceed
48
+ }
49
+
50
+ // Create project directory
51
+ await fs.mkdir(projectPath, { recursive: true });
52
+ console.log(`✅ Created ${name}/`);
53
+ }
54
+
55
+ // Generate project files based on template
56
+ await generateTemplate(projectPath, templateType, options, isCurrentDir);
57
+
58
+ // All templates now handle their own config files, package.json, and README.md
59
+
60
+ // Generate .gitignore file
61
+ await generateGitignore(projectPath);
62
+
63
+ console.log('✅ Generated project files');
64
+
65
+ // Install dependencies
66
+ console.log('\n📦 Installing dependencies...');
67
+ await installDependencies(projectPath);
68
+ console.log('✅ Installed dependencies');
69
+
70
+ // Success message
71
+ console.log(`\n🎉 Successfully created "${name}"!`);
72
+ console.log('\n🚀 Next steps:');
73
+ console.log(` cd ${name}`);
74
+ console.log(' npx uikit serve');
75
+ console.log('\n💡 Or run individual commands:');
76
+ console.log(' npx uikit bundle # Bundle themes');
77
+ console.log(' npx uikit serve # Start dev server');
78
+ console.log(' npx uikit build # Production build');
79
+
80
+ } catch (error) {
81
+ console.error('❌ Failed to create project:', error.message);
82
+ process.exit(1);
83
+ }
84
+ }
85
+
86
+ /**
87
+ * Generate template files based on type
88
+ */
89
+ async function generateTemplate(projectPath, templateType, options, isCurrentDir = false) {
90
+ const srcPath = path.join(projectPath, 'src');
91
+ await fs.mkdir(srcPath, { recursive: true });
92
+
93
+ switch (templateType) {
94
+ case 'single':
95
+ await generateSinglePageTemplate(srcPath, options.theme, isCurrentDir);
96
+ break;
97
+ case 'spa':
98
+ await generateSPATemplate(srcPath, options.theme, isCurrentDir);
99
+ break;
100
+ case 'multi':
101
+ await generateMultiPageTemplate(srcPath, options.theme, isCurrentDir);
102
+ break;
103
+ case 'fbca':
104
+ await generateFBCATemplate(srcPath, options.theme, isCurrentDir);
105
+ break;
106
+ }
107
+ }
108
+
109
+ /**
110
+ * Generate single-page theme showcase template
111
+ */
112
+ async function generateSinglePageTemplate(srcPath, theme = 'base', isCurrentDir = false) {
113
+ const templatesPath = path.join(__dirname, '../templates/single');
114
+ const projectName = path.basename(path.dirname(srcPath));
115
+
116
+ // Read and process App.tsx template
117
+ const appTemplate = await fs.readFile(path.join(templatesPath, 'src/App.tsx.template'), 'utf8');
118
+ await fs.writeFile(path.join(srcPath, 'App.tsx'), appTemplate);
119
+
120
+ // Read and process main.tsx template
121
+ const mainTemplate = await fs.readFile(path.join(templatesPath, 'src/main.tsx.template'), 'utf8');
122
+ const mainContent = mainTemplate.replace(/{{THEME}}/g, theme);
123
+ await fs.writeFile(path.join(srcPath, 'main.tsx'), mainContent);
124
+
125
+ // Read and copy index.css template
126
+ const cssTemplate = await fs.readFile(path.join(templatesPath, 'src/index.css.template'), 'utf8');
127
+ await fs.writeFile(path.join(srcPath, 'index.css'), cssTemplate);
128
+
129
+ // Copy utils folder
130
+ const utilsPath = path.join(srcPath, 'utils');
131
+ await fs.mkdir(utilsPath, { recursive: true });
132
+ const assetUtilTemplate = await fs.readFile(path.join(templatesPath, 'src/utils/asset.ts'), 'utf8');
133
+ await fs.writeFile(path.join(utilsPath, 'asset.ts'), assetUtilTemplate);
134
+
135
+ // Read and process index.html template
136
+ const indexTemplate = await fs.readFile(path.join(templatesPath, 'index.html.template'), 'utf8');
137
+ const indexContent = indexTemplate.replace(/{{PROJECT_NAME}}/g, projectName);
138
+ await fs.writeFile(path.join(srcPath, '../index.html'), indexContent);
139
+
140
+ // Copy public assets
141
+ const publicTargetPath = path.join(srcPath, '../public');
142
+ await fs.mkdir(publicTargetPath, { recursive: true });
143
+
144
+ try {
145
+ // Copy favicon.svg
146
+ const faviconSourcePath = path.join(templatesPath, 'public/favicon.svg');
147
+ await fs.copyFile(faviconSourcePath, path.join(publicTargetPath, 'favicon.svg'));
148
+
149
+ // Copy hero.svg if it exists
150
+ const heroSourcePath = path.join(templatesPath, 'public/hero.svg');
151
+ await fs.copyFile(heroSourcePath, path.join(publicTargetPath, 'hero.svg'));
152
+ } catch (error) {
153
+ // Assets don't exist, skip copying
154
+ }
155
+
156
+
157
+ // Copy documentation
158
+ const docsSourcePath = path.join(templatesPath, 'docs');
159
+ const docsTargetPath = path.join(srcPath, '../docs');
160
+ try {
161
+ await fs.access(docsSourcePath);
162
+ await fs.mkdir(docsTargetPath, { recursive: true });
163
+ const docsFiles = await fs.readdir(docsSourcePath);
164
+ for (const file of docsFiles) {
165
+ await fs.copyFile(path.join(docsSourcePath, file), path.join(docsTargetPath, file));
166
+ }
167
+ } catch (error) {
168
+ // Docs directory doesn't exist, skip copying
169
+ }
170
+
171
+ // Copy config files
172
+ const projectPath = path.dirname(srcPath);
173
+
174
+ // Copy vite.config.ts
175
+ const viteConfigTemplate = await fs.readFile(path.join(templatesPath, 'vite.config.ts.template'), 'utf8');
176
+ await fs.writeFile(path.join(projectPath, 'vite.config.ts'), viteConfigTemplate);
177
+
178
+ // Copy tsconfig.json
179
+ const tsConfigTemplate = await fs.readFile(path.join(templatesPath, 'tsconfig.json'), 'utf8');
180
+ await fs.writeFile(path.join(projectPath, 'tsconfig.json'), tsConfigTemplate);
181
+
182
+ // Copy tsconfig.node.json
183
+ const tsNodeConfigTemplate = await fs.readFile(path.join(templatesPath, 'tsconfig.node.json'), 'utf8');
184
+ await fs.writeFile(path.join(projectPath, 'tsconfig.node.json'), tsNodeConfigTemplate);
185
+
186
+ // Copy package.json
187
+ const packageTemplate = await fs.readFile(path.join(templatesPath, 'package.json.template'), 'utf8');
188
+ const packageContent = packageTemplate.replace(/{{PROJECT_NAME}}/g, projectName);
189
+ await fs.writeFile(path.join(projectPath, 'package.json'), packageContent);
190
+
191
+ // Copy README.md
192
+ const readmeTemplate = await fs.readFile(path.join(templatesPath, 'README.md.template'), 'utf8');
193
+ const readmeContent = readmeTemplate.replace(/{{PROJECT_NAME}}/g, projectName);
194
+ await fs.writeFile(path.join(projectPath, 'README.md'), readmeContent);
195
+
196
+ }
197
+
198
+ /**
199
+ * Generate SPA template with routing
200
+ */
201
+ async function generateSPATemplate(srcPath, theme = 'base', isCurrentDir = false) {
202
+ const templatesPath = path.join(__dirname, '../templates/spa');
203
+
204
+ // Copy src folder structure recursively
205
+ const srcTemplatePath = path.join(templatesPath, 'src');
206
+ try {
207
+ await fs.access(srcTemplatePath);
208
+ const entries = await fs.readdir(srcTemplatePath, { withFileTypes: true });
209
+
210
+ for (const entry of entries) {
211
+ const sourcePath = path.join(srcTemplatePath, entry.name);
212
+ const targetPath = path.join(srcPath, entry.name);
213
+
214
+ if (entry.isDirectory()) {
215
+ // Copy directory recursively
216
+ await fs.mkdir(targetPath, { recursive: true });
217
+ const dirFiles = await fs.readdir(sourcePath);
218
+ for (const file of dirFiles) {
219
+ const sourceFile = path.join(sourcePath, file);
220
+ const targetFile = path.join(targetPath, file);
221
+ if (file.endsWith('.template')) {
222
+ const content = await fs.readFile(sourceFile, 'utf8');
223
+ const processedContent = content.replace(/{{THEME}}/g, theme);
224
+ await fs.writeFile(targetFile.replace('.template', ''), processedContent);
225
+ } else {
226
+ await fs.copyFile(sourceFile, targetFile);
227
+ }
228
+ }
229
+ } else if (entry.name.endsWith('.template')) {
230
+ // Process template file
231
+ const template = await fs.readFile(sourcePath, 'utf8');
232
+ const content = template.replace(/{{THEME}}/g, theme);
233
+ await fs.writeFile(targetPath.replace('.template', ''), content);
234
+ } else {
235
+ // Copy non-template files as-is
236
+ await fs.copyFile(sourcePath, targetPath);
237
+ }
238
+ }
239
+ } catch (error) {
240
+ console.warn('⚠️ No src folder found in SPA template, using legacy file structure');
241
+
242
+ // Fallback to old method if src folder doesn't exist
243
+ const appTemplate = await fs.readFile(path.join(templatesPath, 'App.tsx.template'), 'utf8');
244
+ const appContent = appTemplate.replace(/{{THEME}}/g, theme);
245
+ await fs.writeFile(path.join(srcPath, 'App.tsx'), appContent);
246
+
247
+ const mainTemplate = await fs.readFile(path.join(templatesPath, 'main.tsx.template'), 'utf8');
248
+ await fs.writeFile(path.join(srcPath, 'main.tsx'), mainTemplate);
249
+
250
+ const cssTemplate = await fs.readFile(path.join(templatesPath, 'index.css.template'), 'utf8');
251
+ await fs.writeFile(path.join(srcPath, 'index.css'), cssTemplate);
252
+ }
253
+
254
+ // Read and copy index.html template
255
+ const indexTemplate = await fs.readFile(path.join(templatesPath, 'index.html.template'), 'utf8');
256
+ await fs.writeFile(path.join(srcPath, '../index.html'), indexTemplate);
257
+
258
+ // Copy public assets
259
+ const publicSourcePath = path.join(templatesPath, 'public');
260
+ const publicTargetPath = path.join(srcPath, '../public');
261
+ try {
262
+ await fs.access(publicSourcePath);
263
+ await fs.mkdir(publicTargetPath, { recursive: true });
264
+ const publicFiles = await fs.readdir(publicSourcePath);
265
+ for (const file of publicFiles) {
266
+ await fs.copyFile(path.join(publicSourcePath, file), path.join(publicTargetPath, file));
267
+ }
268
+ } catch (error) {
269
+ // Public directory doesn't exist, skip copying
270
+ }
271
+
272
+ // Copy documentation
273
+ const docsSourcePath = path.join(templatesPath, 'docs');
274
+ const docsTargetPath = path.join(srcPath, '../docs');
275
+ try {
276
+ await fs.access(docsSourcePath);
277
+ await fs.mkdir(docsTargetPath, { recursive: true });
278
+ const docsFiles = await fs.readdir(docsSourcePath);
279
+ for (const file of docsFiles) {
280
+ await fs.copyFile(path.join(docsSourcePath, file), path.join(docsTargetPath, file));
281
+ }
282
+ } catch (error) {
283
+ // Docs directory doesn't exist, skip copying
284
+ }
285
+
286
+ // Copy hooks directory
287
+ const hooksSourcePath = path.join(templatesPath, 'hooks');
288
+ const hooksTargetPath = path.join(srcPath, 'hooks');
289
+ try {
290
+ await fs.access(hooksSourcePath);
291
+ await fs.mkdir(hooksTargetPath, { recursive: true });
292
+ const hookFiles = await fs.readdir(hooksSourcePath);
293
+ for (const file of hookFiles) {
294
+ const content = await fs.readFile(path.join(hooksSourcePath, file), 'utf8');
295
+ const targetFile = file.replace('.template', '');
296
+ await fs.writeFile(path.join(hooksTargetPath, targetFile), content);
297
+ }
298
+ } catch (error) {
299
+ // Hooks directory doesn't exist, skip copying
300
+ }
301
+
302
+ // Copy components directory
303
+ const componentsSourcePath = path.join(templatesPath, 'components');
304
+ const componentsTargetPath = path.join(srcPath, 'components');
305
+ try {
306
+ await fs.access(componentsSourcePath);
307
+ await fs.mkdir(componentsTargetPath, { recursive: true });
308
+ const componentFiles = await fs.readdir(componentsSourcePath);
309
+ for (const file of componentFiles) {
310
+ const content = await fs.readFile(path.join(componentsSourcePath, file), 'utf8');
311
+ const targetFile = file.replace('.template', '');
312
+ await fs.writeFile(path.join(componentsTargetPath, targetFile), content);
313
+ }
314
+ } catch (error) {
315
+ // Components directory doesn't exist, skip copying
316
+ }
317
+
318
+ // Copy config files
319
+ const projectPath = path.dirname(srcPath);
320
+ const projectName = path.basename(projectPath);
321
+
322
+ // Copy vite.config.ts
323
+ const viteConfigTemplate = await fs.readFile(path.join(templatesPath, 'vite.config.ts.template'), 'utf8');
324
+ await fs.writeFile(path.join(projectPath, 'vite.config.ts'), viteConfigTemplate);
325
+
326
+ // Copy tsconfig.json
327
+ const tsConfigTemplate = await fs.readFile(path.join(templatesPath, 'tsconfig.json.template'), 'utf8');
328
+ await fs.writeFile(path.join(projectPath, 'tsconfig.json'), tsConfigTemplate);
329
+
330
+ // Copy tsconfig.node.json
331
+ const tsNodeConfigTemplate = await fs.readFile(path.join(templatesPath, 'tsconfig.node.json'), 'utf8');
332
+ await fs.writeFile(path.join(projectPath, 'tsconfig.node.json'), tsNodeConfigTemplate);
333
+
334
+ // Copy package.json
335
+ const packageTemplate = await fs.readFile(path.join(templatesPath, 'package.json.template'), 'utf8');
336
+ const packageContent = packageTemplate.replace(/{{PROJECT_NAME}}/g, projectName);
337
+ await fs.writeFile(path.join(projectPath, 'package.json'), packageContent);
338
+
339
+ // Copy README.md
340
+ const readmeTemplate = await fs.readFile(path.join(templatesPath, 'README.md.template'), 'utf8');
341
+ const readmeContent = readmeTemplate.replace(/{{PROJECT_NAME}}/g, projectName);
342
+ await fs.writeFile(path.join(projectPath, 'README.md'), readmeContent);
343
+
344
+ console.log('✅ Generated SPA template with React Router navigation');
345
+ }
346
+
347
+ /**
348
+ * Generate multi-page template
349
+ */
350
+ async function generateMultiPageTemplate(srcPath, theme = 'elegant', isCurrentDir = false) {
351
+ const templatesPath = path.join(__dirname, '../templates/multi');
352
+ const projectName = path.basename(path.dirname(srcPath));
353
+
354
+ // Helper function to recursively copy directory structure
355
+ async function copyDirectory(sourceDir, targetDir) {
356
+ await fs.mkdir(targetDir, { recursive: true });
357
+ const entries = await fs.readdir(sourceDir, { withFileTypes: true });
358
+
359
+ for (const entry of entries) {
360
+ const sourcePath = path.join(sourceDir, entry.name);
361
+ const targetPath = path.join(targetDir, entry.name);
362
+
363
+ if (entry.isDirectory()) {
364
+ await copyDirectory(sourcePath, targetPath);
365
+ } else if (entry.name.endsWith('.template')) {
366
+ // Process template file
367
+ const template = await fs.readFile(sourcePath, 'utf8');
368
+ const content = template
369
+ .replace(/{{DEFAULT_THEME}}/g, theme)
370
+ .replace(/{{DEFAULT_MODE}}/g, 'light')
371
+ .replace(/{{PROJECT_NAME}}/g, projectName)
372
+ .replace(/{{CURRENT_YEAR}}/g, new Date().getFullYear().toString())
373
+ .replace(/{{THEME}}/g, theme);
374
+
375
+ const outputFileName = entry.name.replace('.template', '');
376
+ await fs.writeFile(targetPath.replace('.template', ''), content);
377
+ } else {
378
+ // Copy non-template files as-is
379
+ await fs.copyFile(sourcePath, targetPath);
380
+ }
381
+ }
382
+ }
383
+
384
+ // Copy src folder structure recursively
385
+ const srcTemplatePath = path.join(templatesPath, 'src');
386
+ try {
387
+ await fs.access(srcTemplatePath);
388
+ await copyDirectory(srcTemplatePath, srcPath);
389
+ } catch (error) {
390
+ console.warn('⚠️ No src folder found in multi template, using legacy file structure');
391
+
392
+ // Fallback to old method if src folder doesn't exist
393
+ const appTemplate = await fs.readFile(path.join(templatesPath, 'App.tsx.template'), 'utf8');
394
+ const appContent = appTemplate
395
+ .replace(/{{DEFAULT_THEME}}/g, theme)
396
+ .replace(/{{DEFAULT_MODE}}/g, 'light');
397
+ await fs.writeFile(path.join(srcPath, 'App.tsx'), appContent);
398
+
399
+ const routerTemplate = await fs.readFile(path.join(templatesPath, 'router.tsx.template'), 'utf8');
400
+ await fs.writeFile(path.join(srcPath, 'router.tsx'), routerTemplate);
401
+
402
+ const mainTemplate = await fs.readFile(path.join(templatesPath, 'main.tsx.template'), 'utf8');
403
+ await fs.writeFile(path.join(srcPath, 'main.tsx'), mainTemplate);
404
+
405
+ const cssTemplate = await fs.readFile(path.join(templatesPath, 'index.css.template'), 'utf8');
406
+ await fs.writeFile(path.join(srcPath, 'index.css'), cssTemplate);
407
+
408
+ // Create pages directory and copy all page templates
409
+ const pagesPath = path.join(srcPath, 'pages');
410
+ await fs.mkdir(pagesPath, { recursive: true });
411
+
412
+ const pageFiles = ['Home.tsx.template', 'Components.tsx.template', 'Themes.tsx.template', 'About.tsx.template', 'Contact.tsx.template', 'Login.tsx.template', 'Dashboard.tsx.template', 'ErrorPage.tsx.template'];
413
+
414
+ for (const pageFile of pageFiles) {
415
+ const pageTemplate = await fs.readFile(path.join(templatesPath, 'pages', pageFile), 'utf8');
416
+ const pageContent = pageTemplate.replace(/{{THEME}}/g, theme);
417
+ const outputFileName = pageFile.replace('.template', '');
418
+ await fs.writeFile(path.join(pagesPath, outputFileName), pageContent);
419
+ }
420
+
421
+ // Create components directory and copy header/footer components
422
+ const componentsPath = path.join(srcPath, 'components');
423
+ await fs.mkdir(componentsPath, { recursive: true });
424
+
425
+ const componentFiles = ['Header.tsx.template', 'Footer.tsx.template', 'SEO.tsx.template', 'index.ts.template'];
426
+
427
+ for (const componentFile of componentFiles) {
428
+ try {
429
+ const componentTemplate = await fs.readFile(path.join(templatesPath, 'components', componentFile), 'utf8');
430
+ const componentContent = componentTemplate
431
+ .replace(/{{PROJECT_NAME}}/g, projectName)
432
+ .replace(/{{CURRENT_YEAR}}/g, new Date().getFullYear().toString())
433
+ .replace(/{{THEME}}/g, theme);
434
+ const outputFileName = componentFile.replace('.template', '');
435
+ await fs.writeFile(path.join(componentsPath, outputFileName), componentContent);
436
+ } catch (error) {
437
+ console.warn(`⚠️ Warning: Could not find component template ${componentFile}`);
438
+ }
439
+ }
440
+ }
441
+
442
+ // Copy index.html template
443
+ const indexTemplate = await fs.readFile(path.join(templatesPath, 'index.html.template'), 'utf8');
444
+ await fs.writeFile(path.join(srcPath, '../index.html'), indexTemplate);
445
+
446
+ // Copy public assets
447
+ const publicSourcePath = path.join(templatesPath, 'public');
448
+ const publicTargetPath = path.join(srcPath, '../public');
449
+ try {
450
+ await fs.access(publicSourcePath);
451
+ await fs.mkdir(publicTargetPath, { recursive: true });
452
+ const publicFiles = await fs.readdir(publicSourcePath);
453
+ for (const file of publicFiles) {
454
+ await fs.copyFile(path.join(publicSourcePath, file), path.join(publicTargetPath, file));
455
+ }
456
+ } catch (error) {
457
+ // Public directory doesn't exist, skip copying
458
+ }
459
+
460
+ // Copy documentation
461
+ const docsSourcePath = path.join(templatesPath, 'docs');
462
+ const docsTargetPath = path.join(srcPath, '../docs');
463
+ try {
464
+ await fs.access(docsSourcePath);
465
+ await fs.mkdir(docsTargetPath, { recursive: true });
466
+ const docsFiles = await fs.readdir(docsSourcePath);
467
+ for (const file of docsFiles) {
468
+ await fs.copyFile(path.join(docsSourcePath, file), path.join(docsTargetPath, file));
469
+ }
470
+ } catch (error) {
471
+ // Docs directory doesn't exist, skip copying
472
+ }
473
+
474
+ // Copy hooks directory
475
+ const hooksSourcePath = path.join(templatesPath, 'hooks');
476
+ const hooksTargetPath = path.join(srcPath, 'hooks');
477
+ try {
478
+ await fs.access(hooksSourcePath);
479
+ await fs.mkdir(hooksTargetPath, { recursive: true });
480
+ const hookFiles = await fs.readdir(hooksSourcePath);
481
+ for (const file of hookFiles) {
482
+ const content = await fs.readFile(path.join(hooksSourcePath, file), 'utf8');
483
+ const targetFile = file.replace('.template', '');
484
+ await fs.writeFile(path.join(hooksTargetPath, targetFile), content);
485
+ }
486
+ } catch (error) {
487
+ // Hooks directory doesn't exist, skip copying
488
+ }
489
+
490
+ // Copy config files
491
+ const projectPath = path.dirname(srcPath);
492
+
493
+ // Copy vite.config.ts
494
+ const viteConfigTemplate = await fs.readFile(path.join(templatesPath, 'vite.config.ts.template'), 'utf8');
495
+ await fs.writeFile(path.join(projectPath, 'vite.config.ts'), viteConfigTemplate);
496
+
497
+ // Copy tsconfig.json
498
+ const tsConfigTemplate = await fs.readFile(path.join(templatesPath, 'tsconfig.json.template'), 'utf8');
499
+ await fs.writeFile(path.join(projectPath, 'tsconfig.json'), tsConfigTemplate);
500
+
501
+ // Copy tsconfig.node.json
502
+ const tsNodeConfigTemplate = await fs.readFile(path.join(templatesPath, 'tsconfig.node.json'), 'utf8');
503
+ await fs.writeFile(path.join(projectPath, 'tsconfig.node.json'), tsNodeConfigTemplate);
504
+
505
+ // Copy package.json
506
+ const packageTemplate = await fs.readFile(path.join(templatesPath, 'package.json.template'), 'utf8');
507
+ const packageContent = packageTemplate.replace(/{{PROJECT_NAME}}/g, projectName);
508
+ await fs.writeFile(path.join(projectPath, 'package.json'), packageContent);
509
+
510
+ // Copy README.md
511
+ const readmeTemplate = await fs.readFile(path.join(templatesPath, 'README.md.template'), 'utf8');
512
+ const readmeContent = readmeTemplate.replace(/{{PROJECT_NAME}}/g, projectName);
513
+ await fs.writeFile(path.join(projectPath, 'README.md'), readmeContent);
514
+
515
+ console.log('✅ Generated multi-page template with ultra-simple App.tsx, routing, pages, and configurable components');
516
+ }
517
+
518
+ /**
519
+ * Generate FBCA template with auto-discovery routing
520
+ */
521
+ async function generateFBCATemplate(srcPath, theme = 'elegant', isCurrentDir = false) {
522
+ const templatesPath = path.join(__dirname, '../templates/fbca');
523
+ const projectPath = path.dirname(srcPath); // Get project root instead of src
524
+ const projectName = path.basename(projectPath);
525
+
526
+ // Helper function to recursively copy directory structure
527
+ async function copyDirectory(sourceDir, targetDir, excludeDirs = [], excludeFiles = []) {
528
+ await fs.mkdir(targetDir, { recursive: true });
529
+ const entries = await fs.readdir(sourceDir, { withFileTypes: true });
530
+
531
+ for (const entry of entries) {
532
+ // Skip excluded directories
533
+ if (entry.isDirectory() && excludeDirs.includes(entry.name)) {
534
+ continue;
535
+ }
536
+
537
+ // Skip excluded files
538
+ if (entry.isFile() && excludeFiles.includes(entry.name)) {
539
+ continue;
540
+ }
541
+
542
+ const sourcePath = path.join(sourceDir, entry.name);
543
+ const targetPath = path.join(targetDir, entry.name);
544
+
545
+ if (entry.isDirectory()) {
546
+ await copyDirectory(sourcePath, targetPath, excludeDirs, excludeFiles);
547
+ } else if (entry.name.endsWith('.template')) {
548
+ // Process template file
549
+ const template = await fs.readFile(sourcePath, 'utf8');
550
+ const content = template
551
+ .replace(/{{DEFAULT_THEME}}/g, theme)
552
+ .replace(/{{DEFAULT_MODE}}/g, 'light')
553
+ .replace(/{{PROJECT_NAME}}/g, projectName)
554
+ .replace(/{{CURRENT_YEAR}}/g, new Date().getFullYear().toString())
555
+ .replace(/{{THEME}}/g, theme);
556
+
557
+ const outputFileName = entry.name.replace('.template', '');
558
+ await fs.writeFile(targetPath.replace('.template', ''), content);
559
+ } else {
560
+ // Copy non-template files as-is
561
+ await fs.copyFile(sourcePath, targetPath);
562
+ }
563
+ }
564
+ }
565
+
566
+ // First, copy root-level config files directly to project root
567
+ let rootConfigFiles = [
568
+ 'package.json.template',
569
+ 'tsconfig.json.template',
570
+ 'tsconfig.node.json.template',
571
+ 'vite.config.ts.template'
572
+ ];
573
+
574
+ // Handle package.json for current directory
575
+ if (isCurrentDir) {
576
+ const packageJsonPath = path.join(projectPath, 'package.json');
577
+ try {
578
+ await fs.access(packageJsonPath);
579
+ // package.json exists, skip it from rootConfigFiles and update it separately
580
+ rootConfigFiles = rootConfigFiles.filter(file => file !== 'package.json.template');
581
+ console.log('🔄 Updating existing package.json with UIKit dependencies and scripts');
582
+ await updateExistingPackageJson(projectPath, templatesPath, theme, projectName);
583
+ } catch {
584
+ // package.json doesn't exist, keep it in rootConfigFiles so it gets created
585
+ console.log('📦 Creating package.json from template (no existing file found)');
586
+ }
587
+ }
588
+
589
+ for (const configFile of rootConfigFiles) {
590
+ try {
591
+ const sourcePath = path.join(templatesPath, configFile);
592
+ const template = await fs.readFile(sourcePath, 'utf8');
593
+ const content = template
594
+ .replace(/{{DEFAULT_THEME}}/g, theme)
595
+ .replace(/{{DEFAULT_MODE}}/g, 'light')
596
+ .replace(/{{PROJECT_NAME}}/g, projectName);
597
+
598
+ const outputFileName = configFile.replace('.template', '');
599
+ await fs.writeFile(path.join(projectPath, outputFileName), content);
600
+ } catch (error) {
601
+ console.warn(`⚠️ Warning: Could not copy root config file ${configFile}`);
602
+ }
603
+ }
604
+
605
+ // Copy the web directory contents to src/web, excluding root config files
606
+ const webTemplatesPath = path.join(templatesPath, 'src', 'web');
607
+ const webTargetPath = path.join(srcPath, 'web');
608
+ try {
609
+ await copyDirectory(webTemplatesPath, webTargetPath, ['docs'], rootConfigFiles);
610
+
611
+ // index.html stays in src/web - it's handled by copyDirectory above
612
+ } catch (error) {
613
+ console.warn('⚠️ Warning: Could not copy web directory structure');
614
+ }
615
+
616
+ // Copy the api directory if it exists
617
+ const apiTemplatesPath = path.join(templatesPath, 'src', 'api');
618
+ const apiTargetPath = path.join(srcPath, 'api');
619
+ try {
620
+ await fs.access(apiTemplatesPath);
621
+ await copyDirectory(apiTemplatesPath, apiTargetPath);
622
+ } catch (error) {
623
+ // API directory doesn't exist, skip copying
624
+ }
625
+
626
+ // Copy public directory if it exists
627
+ const publicSourcePath = path.join(templatesPath, 'public');
628
+ const publicTargetPath = path.join(projectPath, 'public');
629
+ try {
630
+ await fs.access(publicSourcePath);
631
+ await copyDirectory(publicSourcePath, publicTargetPath);
632
+ } catch (error) {
633
+ // Public directory doesn't exist, skip copying
634
+ }
635
+
636
+ // Copy documentation to project root
637
+ const docsSourcePath = path.join(templatesPath, 'docs');
638
+ const docsTargetPath = path.join(projectPath, 'docs');
639
+ try {
640
+ await fs.access(docsSourcePath);
641
+ await fs.mkdir(docsTargetPath, { recursive: true });
642
+ const docsFiles = await fs.readdir(docsSourcePath);
643
+ for (const file of docsFiles) {
644
+ await fs.copyFile(path.join(docsSourcePath, file), path.join(docsTargetPath, file));
645
+ }
646
+ } catch (error) {
647
+ // Docs directory doesn't exist, skip copying
648
+ }
649
+
650
+ console.log('✅ Generated FBCA template with auto-discovery routing, feature organization, and SEO support');
651
+ }
652
+
653
+ /**
654
+ * Update existing package.json with UIKit dependencies and scripts
655
+ */
656
+ async function updateExistingPackageJson(projectPath, templatesPath, theme, projectName) {
657
+ const packageJsonPath = path.join(projectPath, 'package.json');
658
+ const templatePath = path.join(templatesPath, 'package.json.template');
659
+
660
+ try {
661
+ // Read existing package.json
662
+ const existingPackage = JSON.parse(await fs.readFile(packageJsonPath, 'utf8'));
663
+
664
+ // Read template package.json
665
+ const templateContent = await fs.readFile(templatePath, 'utf8');
666
+ const templatePackage = JSON.parse(templateContent
667
+ .replace(/{{DEFAULT_THEME}}/g, theme)
668
+ .replace(/{{DEFAULT_MODE}}/g, 'light')
669
+ .replace(/{{PROJECT_NAME}}/g, projectName));
670
+
671
+ // Merge dependencies (only add missing ones)
672
+ if (!existingPackage.dependencies) existingPackage.dependencies = {};
673
+ if (!existingPackage.devDependencies) existingPackage.devDependencies = {};
674
+ if (!existingPackage.scripts) existingPackage.scripts = {};
675
+
676
+ // Add missing dependencies
677
+ for (const [dep, version] of Object.entries(templatePackage.dependencies || {})) {
678
+ if (!existingPackage.dependencies[dep]) {
679
+ existingPackage.dependencies[dep] = version;
680
+ }
681
+ }
682
+
683
+ // Add missing devDependencies
684
+ for (const [dep, version] of Object.entries(templatePackage.devDependencies || {})) {
685
+ if (!existingPackage.devDependencies[dep]) {
686
+ existingPackage.devDependencies[dep] = version;
687
+ }
688
+ }
689
+
690
+ // Add missing scripts
691
+ for (const [script, command] of Object.entries(templatePackage.scripts || {})) {
692
+ if (!existingPackage.scripts[script]) {
693
+ existingPackage.scripts[script] = command;
694
+ }
695
+ }
696
+
697
+ // Ensure type: "module" is set (override if needed)
698
+ existingPackage.type = 'module';
699
+
700
+ // Write updated package.json
701
+ await fs.writeFile(packageJsonPath, JSON.stringify(existingPackage, null, 2) + '\n');
702
+ console.log('✅ Updated package.json with UIKit dependencies and scripts');
703
+
704
+ } catch (error) {
705
+ console.warn('⚠️ Warning: Could not update package.json:', error.message);
706
+ }
707
+ }
708
+
709
+ /**
710
+ * Generate .gitignore file for new projects
711
+ */
712
+ async function generateGitignore(projectPath) {
713
+ // Always generate .gitignore (moved outside try/catch to ensure it runs)
714
+ console.log('🔧 Generating .gitignore...');
715
+
716
+ // Read .gitignore template from shared templates directory
717
+ try {
718
+ const gitignoreTemplatePath = path.join(__dirname, '../templates/.gitignore');
719
+ const gitignoreContent = await fs.readFile(gitignoreTemplatePath, 'utf8');
720
+ await fs.writeFile(path.join(projectPath, '.gitignore'), gitignoreContent);
721
+ } catch (error) {
722
+ console.warn('⚠️ Warning: Could not copy .gitignore template, using fallback');
723
+
724
+ // Fallback to minimal .gitignore if template is not available
725
+ const fallbackGitignore = `# Dependencies
726
+ node_modules/
727
+
728
+ # Build outputs
729
+ dist/
730
+ build/
731
+
732
+ # Environment variables
733
+ .env
734
+ .env.local
735
+
736
+ # Logs
737
+ *.log
738
+
739
+ # IDE files
740
+ .vscode/
741
+ .idea/
742
+ .DS_Store
743
+ `;
744
+ await fs.writeFile(path.join(projectPath, '.gitignore'), fallbackGitignore);
745
+ }
746
+ }
747
+
748
+ /**
749
+ * Install dependencies using npm
750
+ */
751
+ async function installDependencies(projectPath) {
752
+ return new Promise((resolve, reject) => {
753
+ const npm = spawn('npm', ['install'], {
754
+ cwd: projectPath,
755
+ stdio: 'pipe'
756
+ });
757
+
758
+ npm.on('close', (code) => {
759
+ if (code === 0) {
760
+ resolve();
761
+ } else {
762
+ reject(new Error(`npm install failed with code ${code}`));
763
+ }
764
+ });
765
+
766
+ npm.on('error', reject);
767
+ });
768
+ }