xertica-ui 2.2.1 → 2.4.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 (708) hide show
  1. package/CHANGELOG.md +564 -525
  2. package/README.md +417 -382
  3. package/bin/cli.ts +1244 -748
  4. package/bin/generate-tokens.ts +262 -262
  5. package/bin/language-config.ts +5 -8
  6. package/components/assets/xertica-orbe-animation.ts +1162 -1162
  7. package/components/assistant/code-block/CodeBlock.tsx +268 -268
  8. package/components/assistant/code-block/code-block.stories.tsx +57 -57
  9. package/components/assistant/code-block/code-block.test.tsx +44 -44
  10. package/components/assistant/code-block/index.ts +1 -1
  11. package/components/assistant/formatted-document/FormattedDocument.tsx +147 -147
  12. package/components/assistant/formatted-document/formatted-document.stories.tsx +51 -51
  13. package/components/assistant/formatted-document/formatted-document.test.tsx +42 -42
  14. package/components/assistant/formatted-document/index.ts +1 -1
  15. package/components/assistant/index.ts +6 -6
  16. package/components/assistant/markdown-message/MarkdownMessage.tsx +152 -152
  17. package/components/assistant/markdown-message/index.ts +1 -1
  18. package/components/assistant/markdown-message/markdown-message.stories.tsx +50 -50
  19. package/components/assistant/markdown-message/markdown-message.test.tsx +33 -33
  20. package/components/assistant/modern-chat-input/ModernChatInput.tsx +17 -7
  21. package/components/assistant/modern-chat-input/index.ts +1 -1
  22. package/components/assistant/modern-chat-input/modern-chat-input.stories.tsx +131 -131
  23. package/components/assistant/modern-chat-input/modern-chat-input.test.tsx +79 -79
  24. package/components/assistant/xertica-assistant/index.ts +3 -3
  25. package/components/assistant/xertica-assistant/parts/AssistantCollapsedView.tsx +99 -99
  26. package/components/assistant/xertica-assistant/parts/AssistantConversationList.tsx +104 -106
  27. package/components/assistant/xertica-assistant/parts/AssistantDocumentEditor.tsx +81 -81
  28. package/components/assistant/xertica-assistant/parts/AssistantFeedbackDialog.tsx +88 -78
  29. package/components/assistant/xertica-assistant/parts/AssistantHeader.tsx +75 -75
  30. package/components/assistant/xertica-assistant/parts/AssistantMessageBubble.tsx +564 -560
  31. package/components/assistant/xertica-assistant/parts/AssistantTabBar.tsx +67 -67
  32. package/components/assistant/xertica-assistant/parts/AssistantTypingIndicator.tsx +41 -41
  33. package/components/assistant/xertica-assistant/parts/AssistantWelcomeScreen.tsx +103 -103
  34. package/components/assistant/xertica-assistant/parts/index.ts +16 -16
  35. package/components/assistant/xertica-assistant/types.ts +134 -134
  36. package/components/assistant/xertica-assistant/use-assistant.ts +615 -615
  37. package/components/assistant/xertica-assistant/xertica-assistant.stories.tsx +407 -407
  38. package/components/assistant/xertica-assistant/xertica-assistant.test.tsx +65 -65
  39. package/components/assistant/xertica-assistant/xertica-assistant.tsx +611 -613
  40. package/components/blocks/card-patterns/ActivityCard.tsx +100 -100
  41. package/components/blocks/card-patterns/FeatureCard.tsx +109 -109
  42. package/components/blocks/card-patterns/FeatureCardSkeleton.tsx +1 -6
  43. package/components/blocks/card-patterns/NotificationCard.tsx +140 -140
  44. package/components/blocks/card-patterns/ProfileCard.tsx +112 -114
  45. package/components/blocks/card-patterns/ProjectCard.tsx +123 -123
  46. package/components/blocks/card-patterns/ProjectCardSkeleton.tsx +1 -6
  47. package/components/blocks/card-patterns/QuickActionCard.tsx +68 -68
  48. package/components/blocks/card-patterns/card-patterns.mdx +123 -123
  49. package/components/blocks/card-patterns/card-patterns.stories.tsx +594 -594
  50. package/components/blocks/card-patterns/index.ts +29 -29
  51. package/components/blocks/index.ts +1 -1
  52. package/components/brand/branding/branding.stories.tsx +57 -57
  53. package/components/brand/index.ts +6 -6
  54. package/components/brand/language-selector/index.ts +1 -1
  55. package/components/brand/language-selector/language-selector.mdx +126 -126
  56. package/components/brand/language-selector/language-selector.stories.tsx +1 -4
  57. package/components/brand/theme-toggle/ThemeToggle.tsx +74 -70
  58. package/components/brand/theme-toggle/index.ts +1 -1
  59. package/components/brand/theme-toggle/theme-toggle.stories.tsx +34 -34
  60. package/components/brand/theme-toggle/theme-toggle.test.tsx +34 -34
  61. package/components/brand/xertica-logo/XerticaLogo.stories.tsx +82 -82
  62. package/components/brand/xertica-logo/XerticaLogo.tsx +104 -104
  63. package/components/brand/xertica-logo/index.ts +1 -1
  64. package/components/brand/xertica-logo/xertica-logo.test.tsx +26 -26
  65. package/components/brand/xertica-orbe/XerticaOrbe.tsx +1927 -1927
  66. package/components/brand/xertica-orbe/index.ts +1 -1
  67. package/components/brand/xertica-orbe/xertica-orbe.stories.tsx +40 -40
  68. package/components/brand/xertica-orbe/xertica-orbe.test.tsx +19 -19
  69. package/components/brand/xertica-provider/XerticaProvider.tsx +1 -4
  70. package/components/brand/xertica-provider/index.ts +1 -1
  71. package/components/brand/xertica-provider/xertica-provider.test.tsx +74 -74
  72. package/components/brand/xertica-xlogo/XerticaXLogo.stories.tsx +79 -79
  73. package/components/brand/xertica-xlogo/XerticaXLogo.tsx +65 -65
  74. package/components/brand/xertica-xlogo/index.ts +1 -1
  75. package/components/brand/xertica-xlogo/xertica-xlogo.test.tsx +16 -16
  76. package/components/examples/ApiKeyMapExample.tsx +71 -71
  77. package/components/examples/DrawingMapExample.tsx +565 -565
  78. package/components/examples/FilterableMapExample.tsx +393 -393
  79. package/components/examples/LocationPickerExample.tsx +348 -348
  80. package/components/examples/MapExamples.tsx +268 -268
  81. package/components/examples/MapGmpExample.tsx +169 -169
  82. package/components/examples/MapShowcase.tsx +471 -471
  83. package/components/examples/RouteMapExamples.tsx +329 -329
  84. package/components/examples/SidebarLogoExample.tsx +65 -65
  85. package/components/examples/SimpleFilterableMap.tsx +219 -219
  86. package/components/examples/index.ts +45 -45
  87. package/components/figma/ImageWithFallback.tsx +27 -27
  88. package/components/hooks/index.ts +13 -13
  89. package/components/hooks/use-layout-shortcuts.ts +43 -43
  90. package/components/index.ts +86 -90
  91. package/components/layout/header/header.stories.tsx +204 -204
  92. package/components/layout/header/header.test.tsx +75 -75
  93. package/components/layout/header/header.tsx +349 -349
  94. package/components/layout/header/index.ts +1 -1
  95. package/components/layout/index.ts +2 -2
  96. package/components/layout/sidebar/index.ts +3 -3
  97. package/components/layout/sidebar/sidebar.stories.tsx +586 -586
  98. package/components/layout/sidebar/sidebar.test.tsx +76 -76
  99. package/components/layout/sidebar/sidebar.tsx +1079 -1073
  100. package/components/layout/sidebar/use-sidebar.ts +104 -104
  101. package/components/media/FloatingMediaWrapper.tsx +371 -371
  102. package/components/media/audio-player/AudioPlayer.stories.tsx +124 -124
  103. package/components/media/audio-player/AudioPlayer.test.tsx +106 -106
  104. package/components/media/audio-player/AudioPlayer.tsx +767 -765
  105. package/components/media/audio-player/index.ts +1 -1
  106. package/components/media/audio-player/use-audio-player.ts +312 -312
  107. package/components/media/index.ts +3 -3
  108. package/components/media/video-player/VideoPlayer.stories.tsx +98 -98
  109. package/components/media/video-player/VideoPlayer.test.tsx +73 -73
  110. package/components/media/video-player/VideoPlayer.tsx +310 -310
  111. package/components/media/video-player/index.ts +1 -1
  112. package/components/pages/forgot-password-page/ForgotPasswordPage.stories.tsx +24 -24
  113. package/components/pages/forgot-password-page/ForgotPasswordPage.tsx +188 -188
  114. package/components/pages/forgot-password-page/forgot-password-page.test.tsx +45 -45
  115. package/components/pages/forgot-password-page/index.ts +1 -1
  116. package/components/pages/home-content/HomeContent.stories.tsx +43 -43
  117. package/components/pages/home-content/HomeContent.tsx +120 -120
  118. package/components/pages/home-content/index.ts +1 -1
  119. package/components/pages/home-page/HomePage.stories.tsx +39 -39
  120. package/components/pages/home-page/HomePage.tsx +78 -74
  121. package/components/pages/home-page/home-page.test.tsx +53 -53
  122. package/components/pages/home-page/index.ts +1 -1
  123. package/components/pages/index.ts +8 -8
  124. package/components/pages/login-page/LoginPage.stories.tsx +39 -39
  125. package/components/pages/login-page/LoginPage.tsx +218 -216
  126. package/components/pages/login-page/index.ts +1 -1
  127. package/components/pages/login-page/login-page.test.tsx +63 -63
  128. package/components/pages/reset-password-page/ResetPasswordPage.stories.tsx +24 -24
  129. package/components/pages/reset-password-page/ResetPasswordPage.tsx +243 -239
  130. package/components/pages/reset-password-page/index.ts +1 -1
  131. package/components/pages/template-content/TemplateContent.stories.tsx +43 -43
  132. package/components/pages/template-content/TemplateContent.tsx +1354 -1235
  133. package/components/pages/template-content/index.ts +1 -1
  134. package/components/pages/template-page/TemplatePage.stories.tsx +39 -39
  135. package/components/pages/template-page/TemplatePage.tsx +62 -62
  136. package/components/pages/template-page/index.ts +1 -1
  137. package/components/pages/template-page/template-page.test.tsx +52 -52
  138. package/components/pages/verify-email-page/VerifyEmailPage.stories.tsx +41 -41
  139. package/components/pages/verify-email-page/VerifyEmailPage.tsx +206 -206
  140. package/components/pages/verify-email-page/index.ts +1 -1
  141. package/components/public-api-smoke.test.tsx +52 -52
  142. package/components/shared/CustomTooltipContent.tsx +48 -48
  143. package/components/shared/assistant-utils.test.ts +16 -16
  144. package/components/shared/assistant-utils.ts +225 -225
  145. package/components/shared/error-boundary.stories.tsx +114 -132
  146. package/components/shared/error-boundary.tsx +150 -154
  147. package/components/shared/error-fallbacks.tsx +222 -226
  148. package/components/shared/layout-constants.ts +8 -8
  149. package/components/shared/navigation.ts +35 -35
  150. package/components/shared/use-mobile.test.ts +16 -16
  151. package/components/shared/use-mobile.ts +36 -36
  152. package/components/shared/utils.test.ts +14 -14
  153. package/components/shared/utils.ts +6 -6
  154. package/components/ui/accordion/accordion.stories.tsx +105 -105
  155. package/components/ui/accordion/accordion.test.tsx +59 -59
  156. package/components/ui/accordion/accordion.tsx +77 -77
  157. package/components/ui/accordion/index.ts +1 -1
  158. package/components/ui/alert/alert.stories.tsx +86 -86
  159. package/components/ui/alert/alert.test.tsx +53 -53
  160. package/components/ui/alert/alert.tsx +93 -93
  161. package/components/ui/alert/index.ts +1 -1
  162. package/components/ui/alert-dialog/alert-dialog.stories.tsx +84 -84
  163. package/components/ui/alert-dialog/alert-dialog.test.tsx +70 -70
  164. package/components/ui/alert-dialog/alert-dialog.tsx +149 -149
  165. package/components/ui/alert-dialog/index.ts +1 -1
  166. package/components/ui/aspect-ratio/aspect-ratio.stories.tsx +46 -46
  167. package/components/ui/aspect-ratio/aspect-ratio.test.tsx +28 -28
  168. package/components/ui/aspect-ratio/aspect-ratio.tsx +20 -20
  169. package/components/ui/aspect-ratio/index.ts +1 -1
  170. package/components/ui/assistant-chart/AssistantChart.tsx +64 -64
  171. package/components/ui/assistant-chart/assistant-chart.stories.tsx +44 -44
  172. package/components/ui/assistant-chart/assistant-chart.test.tsx +46 -46
  173. package/components/ui/assistant-chart/index.ts +1 -1
  174. package/components/ui/avatar/avatar.stories.tsx +86 -86
  175. package/components/ui/avatar/avatar.test.tsx +55 -55
  176. package/components/ui/avatar/avatar.tsx +71 -71
  177. package/components/ui/avatar/index.ts +1 -1
  178. package/components/ui/badge/badge.stories.tsx +72 -72
  179. package/components/ui/badge/badge.test.tsx +40 -40
  180. package/components/ui/badge/badge.tsx +58 -58
  181. package/components/ui/badge/index.ts +1 -1
  182. package/components/ui/breadcrumb/breadcrumb.stories.tsx +123 -123
  183. package/components/ui/breadcrumb/breadcrumb.test.tsx +70 -70
  184. package/components/ui/breadcrumb/breadcrumb.tsx +114 -114
  185. package/components/ui/breadcrumb/index.ts +1 -1
  186. package/components/ui/button/button.stories.tsx +183 -183
  187. package/components/ui/button/button.test.tsx +64 -64
  188. package/components/ui/button/button.tsx +98 -98
  189. package/components/ui/button/index.ts +1 -1
  190. package/components/ui/calendar/calendar.stories.tsx +108 -108
  191. package/components/ui/calendar/calendar.test.tsx +53 -53
  192. package/components/ui/calendar/calendar.tsx +230 -230
  193. package/components/ui/calendar/index.ts +1 -1
  194. package/components/ui/card/card.stories.tsx +301 -301
  195. package/components/ui/card/card.test.tsx +55 -55
  196. package/components/ui/card/card.tsx +83 -83
  197. package/components/ui/card/index.ts +1 -1
  198. package/components/ui/carousel/carousel.stories.tsx +80 -80
  199. package/components/ui/carousel/carousel.test.tsx +75 -75
  200. package/components/ui/carousel/carousel.tsx +242 -242
  201. package/components/ui/carousel/index.ts +1 -1
  202. package/components/ui/chart/chart.stories.tsx +1328 -1328
  203. package/components/ui/chart/chart.test.tsx +178 -178
  204. package/components/ui/chart/chart.tsx +2232 -2232
  205. package/components/ui/chart/index.ts +1 -1
  206. package/components/ui/checkbox/checkbox.stories.tsx +109 -109
  207. package/components/ui/checkbox/checkbox.test.tsx +49 -49
  208. package/components/ui/checkbox/checkbox.tsx +68 -68
  209. package/components/ui/checkbox/index.ts +1 -1
  210. package/components/ui/collapsible/collapsible.stories.tsx +45 -45
  211. package/components/ui/collapsible/collapsible.test.tsx +51 -51
  212. package/components/ui/collapsible/collapsible.tsx +32 -32
  213. package/components/ui/collapsible/index.ts +1 -1
  214. package/components/ui/command/command.stories.tsx +134 -134
  215. package/components/ui/command/command.test.tsx +48 -48
  216. package/components/ui/command/command.tsx +163 -163
  217. package/components/ui/command/index.ts +1 -1
  218. package/components/ui/context-menu/context-menu.stories.tsx +76 -76
  219. package/components/ui/context-menu/context-menu.test.tsx +61 -61
  220. package/components/ui/context-menu/context-menu.tsx +236 -236
  221. package/components/ui/context-menu/index.ts +1 -1
  222. package/components/ui/dialog/dialog.stories.tsx +174 -174
  223. package/components/ui/dialog/dialog.test.tsx +78 -78
  224. package/components/ui/dialog/dialog.tsx +189 -189
  225. package/components/ui/dialog/index.ts +1 -1
  226. package/components/ui/drawer/drawer.stories.tsx +71 -71
  227. package/components/ui/drawer/drawer.test.tsx +67 -67
  228. package/components/ui/drawer/drawer.tsx +146 -146
  229. package/components/ui/drawer/index.ts +1 -1
  230. package/components/ui/dropdown-menu/dropdown-menu.stories.tsx +156 -156
  231. package/components/ui/dropdown-menu/dropdown-menu.test.tsx +62 -62
  232. package/components/ui/dropdown-menu/dropdown-menu.tsx +240 -240
  233. package/components/ui/dropdown-menu/index.ts +1 -1
  234. package/components/ui/empty/empty.stories.tsx +85 -85
  235. package/components/ui/empty/empty.test.tsx +31 -31
  236. package/components/ui/empty/empty.tsx +88 -88
  237. package/components/ui/empty/index.ts +1 -1
  238. package/components/ui/file-upload/file-upload.stories.tsx +144 -144
  239. package/components/ui/file-upload/file-upload.test.tsx +65 -65
  240. package/components/ui/file-upload/file-upload.tsx +142 -142
  241. package/components/ui/file-upload/index.ts +2 -2
  242. package/components/ui/file-upload/use-file-upload.ts +177 -177
  243. package/components/ui/form/form.stories.tsx +85 -85
  244. package/components/ui/form/form.test.tsx +75 -75
  245. package/components/ui/form/form.tsx +163 -163
  246. package/components/ui/form/index.ts +1 -1
  247. package/components/ui/google-maps-loader/google-maps-loader.test.tsx +35 -35
  248. package/components/ui/google-maps-loader/google-maps-loader.tsx +465 -465
  249. package/components/ui/google-maps-loader/index.ts +1 -1
  250. package/components/ui/hover-card/hover-card.stories.tsx +61 -61
  251. package/components/ui/hover-card/hover-card.test.tsx +48 -48
  252. package/components/ui/hover-card/hover-card.tsx +50 -50
  253. package/components/ui/hover-card/index.ts +1 -1
  254. package/components/ui/index.ts +400 -400
  255. package/components/ui/input/index.ts +1 -1
  256. package/components/ui/input/input.stories.tsx +153 -153
  257. package/components/ui/input/input.test.tsx +47 -47
  258. package/components/ui/input/input.tsx +57 -57
  259. package/components/ui/input-otp/index.ts +1 -1
  260. package/components/ui/input-otp/input-otp.stories.tsx +120 -120
  261. package/components/ui/input-otp/input-otp.test.tsx +74 -74
  262. package/components/ui/input-otp/input-otp.tsx +101 -101
  263. package/components/ui/label/index.ts +1 -1
  264. package/components/ui/label/label.stories.tsx +74 -74
  265. package/components/ui/label/label.test.tsx +45 -45
  266. package/components/ui/label/label.tsx +53 -53
  267. package/components/ui/map/index.ts +1 -1
  268. package/components/ui/map/map.stories.tsx +86 -86
  269. package/components/ui/map/map.test.tsx +82 -82
  270. package/components/ui/map/map.tsx +506 -506
  271. package/components/ui/map/mock.test.tsx +13 -13
  272. package/components/ui/map-config/index.ts +1 -1
  273. package/components/ui/map-config/map-config.ts +18 -18
  274. package/components/ui/map-layers/index.ts +1 -1
  275. package/components/ui/map-layers/map-layers.test.tsx +48 -48
  276. package/components/ui/map-layers/map-layers.tsx +126 -126
  277. package/components/ui/map.exports/index.ts +1 -1
  278. package/components/ui/map.exports/map.exports.ts +31 -31
  279. package/components/ui/menubar/index.ts +1 -1
  280. package/components/ui/menubar/menubar.stories.tsx +130 -130
  281. package/components/ui/menubar/menubar.test.tsx +53 -53
  282. package/components/ui/menubar/menubar.tsx +265 -265
  283. package/components/ui/navigation-menu/index.ts +1 -1
  284. package/components/ui/navigation-menu/navigation-menu.stories.tsx +126 -126
  285. package/components/ui/navigation-menu/navigation-menu.test.tsx +47 -47
  286. package/components/ui/navigation-menu/navigation-menu.tsx +165 -165
  287. package/components/ui/notification-badge/index.ts +1 -1
  288. package/components/ui/notification-badge/notification-badge.stories.tsx +66 -66
  289. package/components/ui/notification-badge/notification-badge.test.tsx +61 -61
  290. package/components/ui/notification-badge/notification-badge.tsx +91 -91
  291. package/components/ui/page-header/index.ts +1 -1
  292. package/components/ui/page-header/page-header.stories.tsx +69 -69
  293. package/components/ui/page-header/page-header.test.tsx +37 -37
  294. package/components/ui/page-header/page-header.tsx +124 -124
  295. package/components/ui/pagination/index.ts +3 -3
  296. package/components/ui/pagination/pagination.stories.tsx +210 -210
  297. package/components/ui/pagination/pagination.test.tsx +63 -63
  298. package/components/ui/pagination/pagination.tsx +140 -140
  299. package/components/ui/pagination/use-pagination.ts +173 -173
  300. package/components/ui/popover/index.ts +1 -1
  301. package/components/ui/popover/popover.stories.tsx +73 -73
  302. package/components/ui/popover/popover.test.tsx +48 -48
  303. package/components/ui/popover/popover.tsx +54 -54
  304. package/components/ui/progress/index.ts +1 -1
  305. package/components/ui/progress/progress.stories.tsx +55 -55
  306. package/components/ui/progress/progress.test.tsx +23 -23
  307. package/components/ui/progress/progress.tsx +68 -68
  308. package/components/ui/radio-group/index.ts +1 -1
  309. package/components/ui/radio-group/radio-group.stories.tsx +114 -114
  310. package/components/ui/radio-group/radio-group.test.tsx +78 -78
  311. package/components/ui/radio-group/radio-group.tsx +93 -93
  312. package/components/ui/rating/index.ts +1 -1
  313. package/components/ui/rating/rating.stories.tsx +50 -50
  314. package/components/ui/rating/rating.test.tsx +48 -48
  315. package/components/ui/rating/rating.tsx +145 -145
  316. package/components/ui/resizable/index.ts +1 -1
  317. package/components/ui/resizable/resizable.stories.tsx +88 -88
  318. package/components/ui/resizable/resizable.test.tsx +61 -61
  319. package/components/ui/resizable/resizable.tsx +452 -452
  320. package/components/ui/rich-text-editor/index.ts +7 -7
  321. package/components/ui/rich-text-editor/rich-text-editor.stories.tsx +290 -290
  322. package/components/ui/rich-text-editor/rich-text-editor.test.tsx +86 -86
  323. package/components/ui/rich-text-editor/rich-text-editor.tsx +634 -634
  324. package/components/ui/rich-text-editor/use-rich-text-editor.ts +453 -453
  325. package/components/ui/route-map/index.ts +1 -1
  326. package/components/ui/route-map/route-map.stories.tsx +48 -48
  327. package/components/ui/route-map/route-map.test.tsx +108 -108
  328. package/components/ui/route-map/route-map.tsx +349 -349
  329. package/components/ui/scroll-area/index.ts +1 -1
  330. package/components/ui/scroll-area/scroll-area.stories.tsx +31 -31
  331. package/components/ui/scroll-area/scroll-area.test.tsx +27 -27
  332. package/components/ui/scroll-area/scroll-area.tsx +70 -70
  333. package/components/ui/search/index.ts +1 -1
  334. package/components/ui/search/search.stories.tsx +107 -107
  335. package/components/ui/search/search.test.tsx +67 -67
  336. package/components/ui/search/search.tsx +141 -141
  337. package/components/ui/select/index.ts +1 -1
  338. package/components/ui/select/select.stories.tsx +163 -163
  339. package/components/ui/select/select.test.tsx +99 -99
  340. package/components/ui/select/select.tsx +195 -195
  341. package/components/ui/separator/index.ts +1 -1
  342. package/components/ui/separator/separator.stories.tsx +55 -55
  343. package/components/ui/separator/separator.test.tsx +23 -23
  344. package/components/ui/separator/separator.tsx +39 -39
  345. package/components/ui/sheet/index.ts +1 -1
  346. package/components/ui/sheet/sheet.stories.tsx +93 -93
  347. package/components/ui/sheet/sheet.test.tsx +62 -62
  348. package/components/ui/sheet/sheet.tsx +149 -149
  349. package/components/ui/simple-map/index.ts +1 -1
  350. package/components/ui/simple-map/simple-map.stories.tsx +44 -44
  351. package/components/ui/simple-map/simple-map.test.tsx +36 -36
  352. package/components/ui/simple-map/simple-map.tsx +92 -92
  353. package/components/ui/skeleton/index.ts +1 -1
  354. package/components/ui/skeleton/skeleton.stories.tsx +36 -36
  355. package/components/ui/skeleton/skeleton.test.tsx +19 -19
  356. package/components/ui/skeleton/skeleton.tsx +25 -25
  357. package/components/ui/slider/index.ts +1 -1
  358. package/components/ui/slider/slider.stories.tsx +44 -44
  359. package/components/ui/slider/slider.test.tsx +25 -25
  360. package/components/ui/slider/slider.tsx +66 -66
  361. package/components/ui/sonner/index.ts +1 -1
  362. package/components/ui/sonner/sonner.stories.tsx +41 -41
  363. package/components/ui/sonner/sonner.test.tsx +24 -24
  364. package/components/ui/sonner/sonner.tsx +74 -74
  365. package/components/ui/stats-card/index.ts +2 -2
  366. package/components/ui/stats-card/stats-card-skeleton.tsx +1 -3
  367. package/components/ui/stats-card/stats-card.stories.tsx +99 -99
  368. package/components/ui/stats-card/stats-card.test.tsx +34 -34
  369. package/components/ui/stats-card/stats-card.tsx +93 -93
  370. package/components/ui/stepper/index.ts +3 -3
  371. package/components/ui/stepper/stepper.stories.tsx +171 -171
  372. package/components/ui/stepper/stepper.test.tsx +47 -47
  373. package/components/ui/stepper/stepper.tsx +190 -190
  374. package/components/ui/stepper/use-stepper.ts +139 -139
  375. package/components/ui/switch/index.ts +1 -1
  376. package/components/ui/switch/switch.stories.tsx +93 -93
  377. package/components/ui/switch/switch.test.tsx +44 -44
  378. package/components/ui/switch/switch.tsx +70 -70
  379. package/components/ui/table/index.ts +1 -1
  380. package/components/ui/table/table.stories.tsx +114 -114
  381. package/components/ui/table/table.test.tsx +43 -43
  382. package/components/ui/table/table.tsx +104 -104
  383. package/components/ui/tabs/index.ts +1 -1
  384. package/components/ui/tabs/tabs.stories.tsx +140 -140
  385. package/components/ui/tabs/tabs.test.tsx +50 -50
  386. package/components/ui/tabs/tabs.tsx +66 -66
  387. package/components/ui/textarea/index.ts +1 -1
  388. package/components/ui/textarea/textarea.stories.tsx +69 -69
  389. package/components/ui/textarea/textarea.test.tsx +41 -41
  390. package/components/ui/textarea/textarea.tsx +61 -61
  391. package/components/ui/timeline/index.ts +1 -1
  392. package/components/ui/timeline/timeline.stories.tsx +97 -97
  393. package/components/ui/timeline/timeline.test.tsx +53 -53
  394. package/components/ui/timeline/timeline.tsx +124 -124
  395. package/components/ui/toggle/index.ts +1 -1
  396. package/components/ui/toggle/toggle.stories.tsx +56 -56
  397. package/components/ui/toggle/toggle.test.tsx +32 -32
  398. package/components/ui/toggle/toggle.tsx +55 -55
  399. package/components/ui/toggle-group/index.ts +1 -1
  400. package/components/ui/toggle-group/toggle-group.stories.tsx +66 -66
  401. package/components/ui/toggle-group/toggle-group.test.tsx +47 -47
  402. package/components/ui/toggle-group/toggle-group.tsx +79 -79
  403. package/components/ui/tooltip/index.ts +1 -1
  404. package/components/ui/tooltip/tooltip.stories.tsx +83 -83
  405. package/components/ui/tooltip/tooltip.test.tsx +39 -39
  406. package/components/ui/tooltip/tooltip.tsx +69 -69
  407. package/components/ui/tree-view/index.ts +4 -4
  408. package/components/ui/tree-view/tree-view.stories.tsx +154 -154
  409. package/components/ui/tree-view/tree-view.test.tsx +58 -58
  410. package/components/ui/tree-view/tree-view.tsx +171 -171
  411. package/components/ui/tree-view/use-tree-view.ts +237 -237
  412. package/components.json +892 -892
  413. package/contexts/ApiKeyContext.test.tsx +26 -26
  414. package/contexts/ApiKeyContext.tsx +196 -196
  415. package/contexts/AssistenteContext.test.tsx +17 -17
  416. package/contexts/AssistenteContext.tsx +113 -113
  417. package/contexts/AuthContext.tsx +121 -118
  418. package/contexts/BrandColorsContext.test.tsx +21 -21
  419. package/contexts/BrandColorsContext.tsx +251 -251
  420. package/contexts/LanguageContext.tsx +1 -2
  421. package/contexts/LayoutContext.test.tsx +29 -29
  422. package/contexts/LayoutContext.tsx +140 -140
  423. package/contexts/ThemeContext.test.tsx +38 -38
  424. package/contexts/ThemeContext.tsx +111 -111
  425. package/contexts/index.ts +8 -8
  426. package/contexts/theme-data.ts +340 -340
  427. package/dist/AssistantChart-COGiOV-g.cjs +3541 -0
  428. package/dist/AssistantChart-CWX1OWNM.js +3373 -0
  429. package/dist/AudioPlayer-9psiEucT.cjs +1282 -0
  430. package/dist/AudioPlayer-Dp2bD1Gk.js +1278 -0
  431. package/dist/BrandColorsContext-DZT7JjeD.js +659 -0
  432. package/dist/BrandColorsContext-awnBCmC4.cjs +666 -0
  433. package/dist/CodeBlock-DYkTfR0f.js +221 -0
  434. package/dist/CodeBlock-EOvp9cVu.cjs +223 -0
  435. package/dist/CustomTooltipContent-BhdIeBEg.cjs +54 -0
  436. package/dist/CustomTooltipContent-CNbVB2NS.js +33 -0
  437. package/dist/FeatureCard-BZ4CYxFf.cjs +497 -0
  438. package/dist/FeatureCard-DNycVGwT.js +485 -0
  439. package/dist/FeatureCardSkeleton-DZqc96mt.js +27 -0
  440. package/dist/FeatureCardSkeleton-pTa0YNKP.cjs +29 -0
  441. package/dist/LayoutContext-BEq_-n98.cjs +96 -0
  442. package/dist/LayoutContext-DNl1xSoX.js +92 -0
  443. package/dist/ThemeContext-CMD3z2Dz.cjs +1930 -0
  444. package/dist/ThemeContext-x_F2zsnv.js +1923 -0
  445. package/dist/VerifyEmailPage-BJjAMUTW.js +3223 -0
  446. package/dist/VerifyEmailPage-Bv8Ah_TK.cjs +3235 -0
  447. package/dist/VerifyEmailPage-CkBYfsNy.cjs +3232 -0
  448. package/dist/VerifyEmailPage-Cyl55sJb.js +3226 -0
  449. package/dist/VerifyEmailPage-X14vhdyl.js +3296 -0
  450. package/dist/VerifyEmailPage-u_Dn7t1U.cjs +3305 -0
  451. package/dist/XerticaOrbe-Uk2JML1-.cjs +1927 -0
  452. package/dist/XerticaOrbe-jA5T2iOk.js +1925 -0
  453. package/dist/XerticaProvider-BErr83Bg.js +42 -0
  454. package/dist/XerticaProvider-CwOkHxiT.cjs +44 -0
  455. package/dist/XerticaProvider-DUOJg9iX.js +49 -0
  456. package/dist/XerticaProvider-Dl_b72_l.cjs +51 -0
  457. package/dist/XerticaXLogo-BX3ueACh.js +255 -0
  458. package/dist/XerticaXLogo-mqjoBiLI.js +252 -0
  459. package/dist/XerticaXLogo-qBPhwK3g.cjs +260 -0
  460. package/dist/XerticaXLogo-uQgwns_E.cjs +257 -0
  461. package/dist/alert-dialog-DhwPioBa.cjs +885 -0
  462. package/dist/alert-dialog-DqlRW_An.js +831 -0
  463. package/dist/assistant.cjs.js +8 -4
  464. package/dist/assistant.es.js +5 -11
  465. package/dist/avatar-3kO2Anrp.js +54 -0
  466. package/dist/avatar-BCM7YQRC.cjs +77 -0
  467. package/dist/blocks.cjs.js +9 -4
  468. package/dist/blocks.es.js +2 -16
  469. package/dist/brand.cjs.js +10 -5
  470. package/dist/brand.es.js +3 -11
  471. package/dist/breadcrumb-BKtHF4gk.cjs +98 -0
  472. package/dist/breadcrumb-ifNsA7Zl.js +90 -0
  473. package/dist/button-0BlA47It.cjs +85 -0
  474. package/dist/button-DZHzN1Gd.js +62 -0
  475. package/dist/cli.js +471 -93
  476. package/dist/components/brand/theme-toggle/ThemeToggle.d.ts +1 -1
  477. package/dist/components/index.d.ts +1 -1
  478. package/dist/dropdown-menu-BMcykFDf.cjs +225 -0
  479. package/dist/dropdown-menu-Dn_eV2Xb.js +190 -0
  480. package/dist/google-maps-loader-BCe58h9D.js +308 -0
  481. package/dist/google-maps-loader-casMyxlo.cjs +316 -0
  482. package/dist/hooks.cjs.js +12 -8
  483. package/dist/hooks.es.js +10 -27
  484. package/dist/index-9GWd0qxq.cjs +12 -0
  485. package/dist/index-BabBx2pa.js +6 -0
  486. package/dist/index.cjs.js +37 -32
  487. package/dist/index.es.js +30 -363
  488. package/dist/input-C_UiS2Py.cjs +152 -0
  489. package/dist/input-cc-PTD4R.js +123 -0
  490. package/dist/layout.cjs.js +10 -6
  491. package/dist/layout.es.js +7 -9
  492. package/dist/media.cjs.js +8 -3
  493. package/dist/media.es.js +1 -6
  494. package/dist/pages.cjs.js +8 -3
  495. package/dist/pages.es.js +1 -11
  496. package/dist/progress-C7Lti5wo.js +80 -0
  497. package/dist/progress-Cqwxbqs1.cjs +103 -0
  498. package/dist/rich-text-editor-DqLICivI.js +2832 -0
  499. package/dist/rich-text-editor-DxO1Hz3a.cjs +2903 -0
  500. package/dist/select-CH6v_KcQ.cjs +161 -0
  501. package/dist/select-D-xvCZK2.js +130 -0
  502. package/dist/sidebar-3XyzjVBw.js +792 -0
  503. package/dist/sidebar-B4ZWaMrE.js +792 -0
  504. package/dist/sidebar-BS1p2V7t.cjs +795 -0
  505. package/dist/sidebar-DyYvgyBj.cjs +795 -0
  506. package/dist/skeleton-DjiHerJn.cjs +87 -0
  507. package/dist/skeleton-DtR5tkYe.js +78 -0
  508. package/dist/slider-B00b9SVK.cjs +78 -0
  509. package/dist/slider-DQCNUUMj.js +56 -0
  510. package/dist/sonner-B-jWlik1.cjs +68 -0
  511. package/dist/sonner-C9tiqj4f.js +47 -0
  512. package/dist/tooltip-D8n9UYoU.cjs +72 -0
  513. package/dist/tooltip-RtbSmPYJ.js +48 -0
  514. package/dist/ui.cjs.js +23 -18
  515. package/dist/ui.es.js +16 -303
  516. package/dist/use-audio-player-B78fd2ct.js +188 -0
  517. package/dist/use-audio-player-DGvhPrgR.cjs +190 -0
  518. package/dist/use-mobile-BdXTRb0Z.cjs +51 -0
  519. package/dist/use-mobile-Ce2cBAQe.js +29 -0
  520. package/dist/xertica-assistant-B1NaSFFj.js +2173 -0
  521. package/dist/xertica-assistant-B687qEPU.js +2165 -0
  522. package/dist/xertica-assistant-CIaUlbIt.cjs +2180 -0
  523. package/dist/xertica-assistant-sOHwTgIP.cjs +2172 -0
  524. package/dist/xertica-ui.css +1 -1
  525. package/docs/ai-usage.md +195 -195
  526. package/docs/architecture-improvements.md +456 -456
  527. package/docs/architecture.md +312 -306
  528. package/docs/components/accordion.md +109 -109
  529. package/docs/components/alert-dialog.md +127 -127
  530. package/docs/components/alert.md +106 -106
  531. package/docs/components/aspect-ratio.md +58 -58
  532. package/docs/components/assistant-chart.md +47 -47
  533. package/docs/components/assistant.md +428 -426
  534. package/docs/components/audio-player.md +167 -167
  535. package/docs/components/avatar.md +101 -101
  536. package/docs/components/badge.md +84 -84
  537. package/docs/components/branding.md +252 -252
  538. package/docs/components/breadcrumb.md +104 -104
  539. package/docs/components/button.md +156 -156
  540. package/docs/components/calendar.md +141 -141
  541. package/docs/components/card-patterns.md +447 -445
  542. package/docs/components/card.md +245 -245
  543. package/docs/components/carousel.md +100 -100
  544. package/docs/components/chart.md +638 -638
  545. package/docs/components/checkbox.md +88 -88
  546. package/docs/components/code-block.md +105 -105
  547. package/docs/components/collapsible.md +86 -86
  548. package/docs/components/command.md +113 -113
  549. package/docs/components/context-menu.md +81 -81
  550. package/docs/components/dialog.md +198 -198
  551. package/docs/components/drawer.md +105 -105
  552. package/docs/components/dropdown-menu.md +127 -127
  553. package/docs/components/empty.md +127 -127
  554. package/docs/components/error-boundary.md +201 -191
  555. package/docs/components/file-upload.md +189 -189
  556. package/docs/components/floating-media-wrapper.md +63 -63
  557. package/docs/components/form.md +177 -177
  558. package/docs/components/formatted-document.md +105 -105
  559. package/docs/components/google-maps-loader.md +44 -44
  560. package/docs/components/header.md +177 -177
  561. package/docs/components/hooks.md +432 -430
  562. package/docs/components/hover-card.md +86 -86
  563. package/docs/components/image-with-fallback.md +107 -107
  564. package/docs/components/input-otp.md +95 -95
  565. package/docs/components/input.md +130 -130
  566. package/docs/components/label.md +69 -69
  567. package/docs/components/language-selector.md +20 -16
  568. package/docs/components/map-layers.md +138 -138
  569. package/docs/components/map.md +84 -84
  570. package/docs/components/markdown-message.md +47 -47
  571. package/docs/components/menubar.md +89 -89
  572. package/docs/components/modern-chat-input.md +164 -164
  573. package/docs/components/navigation-menu.md +83 -83
  574. package/docs/components/notification-badge.md +78 -78
  575. package/docs/components/page-header.md +93 -93
  576. package/docs/components/pages.md +323 -309
  577. package/docs/components/pagination.md +334 -334
  578. package/docs/components/popover.md +116 -116
  579. package/docs/components/progress.md +103 -103
  580. package/docs/components/radio-group.md +133 -133
  581. package/docs/components/rating.md +77 -77
  582. package/docs/components/resizable.md +84 -84
  583. package/docs/components/rich-text-editor.md +255 -255
  584. package/docs/components/route-map.md +124 -124
  585. package/docs/components/scroll-area.md +58 -58
  586. package/docs/components/search.md +87 -87
  587. package/docs/components/select.md +144 -144
  588. package/docs/components/separator.md +58 -58
  589. package/docs/components/sheet.md +122 -122
  590. package/docs/components/sidebar.md +314 -314
  591. package/docs/components/simple-map.md +51 -51
  592. package/docs/components/skeleton.md +99 -99
  593. package/docs/components/slider.md +84 -84
  594. package/docs/components/sonner.md +115 -115
  595. package/docs/components/stats-card.md +120 -120
  596. package/docs/components/stepper.md +268 -268
  597. package/docs/components/switch.md +106 -106
  598. package/docs/components/table.md +138 -138
  599. package/docs/components/tabs.md +117 -117
  600. package/docs/components/textarea.md +86 -86
  601. package/docs/components/theme-toggle.md +73 -73
  602. package/docs/components/timeline.md +121 -121
  603. package/docs/components/toggle-group.md +68 -68
  604. package/docs/components/toggle.md +62 -62
  605. package/docs/components/tooltip.md +116 -116
  606. package/docs/components/tree-view.md +238 -238
  607. package/docs/components/use-mobile.md +96 -96
  608. package/docs/components/video-player.md +68 -68
  609. package/docs/components/xertica-logo.md +36 -36
  610. package/docs/components/xertica-orbe.md +35 -35
  611. package/docs/components/xertica-provider.md +65 -65
  612. package/docs/components/xertica-xlogo.md +35 -35
  613. package/docs/decision-tree.md +293 -293
  614. package/docs/doc-audit.md +244 -243
  615. package/docs/form-sizing.md +162 -162
  616. package/docs/getting-started.md +616 -591
  617. package/docs/guidelines.md +330 -328
  618. package/docs/i18n.md +61 -57
  619. package/docs/installation.md +268 -267
  620. package/docs/layout.md +143 -143
  621. package/docs/llms.md +295 -295
  622. package/docs/patterns/analytics.md +194 -194
  623. package/docs/patterns/crud.md +149 -149
  624. package/docs/patterns/dashboard.md +138 -138
  625. package/docs/patterns/detail-page.md +296 -296
  626. package/docs/patterns/form.md +241 -241
  627. package/docs/patterns/login.md +156 -156
  628. package/docs/patterns/settings.md +368 -368
  629. package/docs/patterns/wizard.md +213 -213
  630. package/docs/state-management.md +289 -289
  631. package/guidelines/Guidelines.md +409 -406
  632. package/hooks/useTheme.test.tsx +16 -16
  633. package/hooks/useTheme.ts +4 -4
  634. package/imports/Podcast.tsx +540 -540
  635. package/imports/XerticaAi.tsx +46 -46
  636. package/imports/XerticaX.tsx +15 -15
  637. package/imports/svg-aueiaqngck.ts +20 -20
  638. package/imports/svg-v9krss1ozd.ts +23 -23
  639. package/imports/svg-vhrdofe3qe.ts +6 -6
  640. package/llms-compact.txt +2 -1
  641. package/llms.txt +2 -1
  642. package/mcp/resources.json +22 -22
  643. package/mcp/tools.json +35 -35
  644. package/package.json +219 -213
  645. package/scripts/ai-validator.ts +91 -91
  646. package/scripts/cleanup-case-dupes.ts +62 -62
  647. package/scripts/generate-ai-manifests.ts +107 -107
  648. package/styles/globals.css +13 -13
  649. package/styles/xertica/app-overrides/chat.css +61 -61
  650. package/styles/xertica/app-overrides/scrollbar.css +33 -33
  651. package/styles/xertica/base.css +90 -71
  652. package/styles/xertica/integrations/google-maps.css +76 -76
  653. package/styles/xertica/integrations/sonner.css +73 -73
  654. package/styles/xertica/theme-map.css +102 -99
  655. package/styles/xertica/tokens.css +240 -236
  656. package/templates/CLAUDE.md +16 -1
  657. package/templates/eslint.config.js +26 -26
  658. package/templates/guidelines/Guidelines.md +577 -553
  659. package/templates/package.json +69 -69
  660. package/templates/postcss.config.js +6 -6
  661. package/templates/src/app/App.tsx +46 -46
  662. package/templates/src/app/components/AppLayout.tsx +55 -55
  663. package/templates/src/app/components/AuthGuard.tsx +131 -82
  664. package/templates/src/app/context/AuthContext.tsx +108 -108
  665. package/templates/src/features/assistant/index.ts +5 -5
  666. package/templates/src/features/auth/index.ts +4 -4
  667. package/templates/src/features/auth/ui/AuthPageShell.tsx +32 -32
  668. package/templates/src/features/auth/ui/ForgotPasswordContent.tsx +70 -72
  669. package/templates/src/features/auth/ui/LoginContent.tsx +92 -92
  670. package/templates/src/features/auth/ui/ResetPasswordContent.tsx +6 -2
  671. package/templates/src/features/auth/ui/SocialLoginButtons.tsx +78 -78
  672. package/templates/src/features/auth/ui/VerifyEmailContent.tsx +2 -6
  673. package/templates/src/features/home/data/mock.ts +41 -35
  674. package/templates/src/features/home/index.ts +11 -11
  675. package/templates/src/features/home/store/dashboardStore.ts +25 -25
  676. package/templates/src/features/home/ui/HomeContent.tsx +117 -119
  677. package/templates/src/features/template/index.ts +5 -5
  678. package/templates/src/features/template/ui/CrudTemplate.tsx +1 -4
  679. package/templates/src/features/template/ui/LoginTemplate.tsx +1 -1
  680. package/templates/src/features/template/ui/TemplateContent.tsx +29 -21
  681. package/templates/src/locales/en/pages/templates.json +17 -17
  682. package/templates/src/locales/es/pages/templates.json +17 -17
  683. package/templates/src/locales/pt-BR/pages/templates.json +17 -17
  684. package/templates/src/main.tsx +11 -11
  685. package/templates/src/pages/AssistantPage.tsx +26 -20
  686. package/templates/src/pages/ForgotPasswordPage.tsx +6 -6
  687. package/templates/src/pages/HomePage.tsx +53 -49
  688. package/templates/src/pages/LoginPage.tsx +10 -10
  689. package/templates/src/pages/ResetPasswordPage.tsx +6 -6
  690. package/templates/src/pages/TemplatePage.tsx +28 -28
  691. package/templates/src/pages/VerifyEmailPage.tsx +6 -6
  692. package/templates/src/shared/config/navigation.ts +19 -19
  693. package/templates/src/shared/error-boundary.tsx +150 -154
  694. package/templates/src/shared/error-fallbacks.tsx +222 -226
  695. package/templates/src/shared/lib/auth.ts +20 -20
  696. package/templates/src/shared/types/auth.ts +3 -3
  697. package/templates/src/styles/index.css +95 -95
  698. package/templates/src/styles/xertica/tokens.css +240 -236
  699. package/templates/tsconfig.json +25 -25
  700. package/templates/tsconfig.node.json +12 -12
  701. package/templates/vite-env.d.ts +1 -1
  702. package/templates/vite.config.js +20 -20
  703. package/templates/vite.config.ts +54 -51
  704. package/utils/color-utils.ts +72 -72
  705. package/utils/demo-responses.test.ts +10 -10
  706. package/utils/demo-responses.ts +151 -151
  707. package/utils/gemini.test.ts +25 -25
  708. package/utils/gemini.ts +155 -155
package/dist/cli.js CHANGED
@@ -691,9 +691,11 @@ export function registerLanguageResource(
691
691
  export default i18n;
692
692
  `;
693
693
  }
694
- function generateAppTsx(selectedCodes) {
694
+ function generateAppTsx(selectedCodes, disableDarkMode = false) {
695
695
  const selectedLangs = SUPPORTED_LANGUAGES.filter((l) => selectedCodes.includes(l.code));
696
696
  const isMonolingual = selectedLangs.length === 1;
697
+ const disableDarkModeProp = disableDarkMode ? `
698
+ disableDarkMode={true}` : "";
697
699
  const isAllDefaults = selectedLangs.length === SUPPORTED_LANGUAGES.length && selectedLangs.every((l) => DEFAULT_SELECTION.includes(l.code));
698
700
  const languagesArrayLiteral = selectedLangs.map(
699
701
  (l) => ` { code: '${l.code}', label: '${l.label}', shortLabel: '${l.shortLabel}' },`
@@ -737,7 +739,7 @@ export default function App() {
737
739
  <QueryClientProvider client={queryClient}>
738
740
  <XerticaProvider
739
741
  apiKey={geminiApiKey}
740
- googleMapsApiKey={googleMapsApiKey}${availableLanguagesProp}
742
+ googleMapsApiKey={googleMapsApiKey}${availableLanguagesProp}${disableDarkModeProp}
741
743
  >
742
744
  <Router>
743
745
  {/* AuthProvider must be inside Router (needs useNavigate) */}
@@ -761,17 +763,222 @@ function toJsIdent(code) {
761
763
  }
762
764
 
763
765
  // bin/cli.ts
766
+ var XERTICA_CONFIG_FILE = ".xertica.json";
767
+ async function readXerticaConfig(targetDir) {
768
+ const configPath = path2.join(targetDir, XERTICA_CONFIG_FILE);
769
+ if (!await fs2.pathExists(configPath)) return null;
770
+ try {
771
+ return await fs2.readJson(configPath);
772
+ } catch {
773
+ return null;
774
+ }
775
+ }
776
+ async function writeXerticaConfig(targetDir, config) {
777
+ const configPath = path2.join(targetDir, XERTICA_CONFIG_FILE);
778
+ const existing = await readXerticaConfig(targetDir) ?? {
779
+ version: 1,
780
+ hasAssistant: false
781
+ };
782
+ await fs2.writeJson(configPath, { ...existing, ...config, version: 1 }, { spaces: 2 });
783
+ }
764
784
  var __filename = fileURLToPath(import.meta.url);
765
785
  var __dirname = path2.dirname(__filename);
766
786
  var pkgJson = JSON.parse(
767
787
  fs2.readFileSync(path2.resolve(__dirname, "../package.json"), "utf-8")
768
788
  );
789
+ function generateAuthGuard({
790
+ hasLogin,
791
+ hasHome,
792
+ hasTemplate,
793
+ hasAssistant,
794
+ firstProtectedPath
795
+ }) {
796
+ return `import React from 'react';
797
+ import { Routes, Route, Navigate } from 'react-router-dom';
798
+ import { useAuth } from '../context/AuthContext';
799
+
800
+ // \u2500\u2500\u2500 Lazy page imports \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
801
+
802
+ ${hasLogin ? `const LoginPage = React.lazy(() => import('../../pages/LoginPage').then(m => ({ default: m.LoginPage })));
803
+ const ForgotPasswordPage = React.lazy(() => import('../../pages/ForgotPasswordPage').then(m => ({ default: m.ForgotPasswordPage })));
804
+ const VerifyEmailPage = React.lazy(() => import('../../pages/VerifyEmailPage').then(m => ({ default: m.VerifyEmailPage })));
805
+ const ResetPasswordPage = React.lazy(() => import('../../pages/ResetPasswordPage').then(m => ({ default: m.ResetPasswordPage })));` : ""}
806
+
807
+ ${hasHome ? `const HomePage = React.lazy(() => import('../../pages/HomePage').then(m => ({ default: m.HomePage })));` : ""}
808
+ ${hasTemplate ? `const TemplatePage = React.lazy(() => import('../../pages/TemplatePage').then(m => ({ default: m.TemplatePage })));` : ""}
809
+ ${hasAssistant ? `const AssistantPage = React.lazy(() => import('../../pages/AssistantPage').then(m => ({ default: m.AssistantPage })));` : ""}
810
+
811
+ // \u2500\u2500\u2500 Route guards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
812
+
813
+ function ProtectedRoute({ children }: { children: React.ReactNode }) {
814
+ const { user, isLoading } = useAuth();
815
+ if (isLoading) return null;
816
+ if (!user) return <Navigate to="${hasLogin ? "/login" : firstProtectedPath}" replace />;
817
+ return <>{children}</>;
818
+ }
819
+
820
+ ${hasLogin ? `function GuestRoute({ children }: { children: React.ReactNode }) {
821
+ const { user, isLoading } = useAuth();
822
+ if (isLoading) return null;
823
+ if (user) return <Navigate to="${firstProtectedPath}" replace />;
824
+ return <>{children}</>;
825
+ }
826
+
827
+ function LoginPageWithAuth() {
828
+ const { login } = useAuth();
829
+ return <LoginPage onLogin={login} />;
830
+ }` : ""}
831
+
832
+ // \u2500\u2500\u2500 Route tree \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
833
+
834
+ export function AuthGuard() {
835
+ const { user } = useAuth();
836
+
837
+ return (
838
+ <div className="min-h-screen bg-muted overflow-x-hidden max-w-full">
839
+ <Routes>
840
+ ${hasLogin ? ` <Route path="/login" element={<GuestRoute><LoginPageWithAuth /></GuestRoute>} />
841
+ <Route path="/forgot-password" element={<GuestRoute><ForgotPasswordPage /></GuestRoute>} />
842
+ <Route path="/verify-email" element={<GuestRoute><VerifyEmailPage /></GuestRoute>} />
843
+ <Route path="/reset-password" element={<GuestRoute><ResetPasswordPage /></GuestRoute>} />` : ""}
844
+
845
+ ${hasHome ? ` <Route path="/home" element={<ProtectedRoute><HomePage /></ProtectedRoute>} />` : ""}
846
+ ${hasTemplate ? ` <Route path="/template" element={<ProtectedRoute><TemplatePage /></ProtectedRoute>} />` : ""}
847
+ ${hasAssistant ? ` <Route path="/assistente" element={<ProtectedRoute><AssistantPage /></ProtectedRoute>} />` : ""}
848
+
849
+ <Route path="/" element={<Navigate to={user ? '${firstProtectedPath}' : '${hasLogin ? "/login" : firstProtectedPath}'} replace />} />
850
+ <Route path="*" element={<Navigate to={user ? '${firstProtectedPath}' : '${hasLogin ? "/login" : firstProtectedPath}'} replace />} />
851
+ </Routes>
852
+ </div>
853
+ );
854
+ }
855
+ `;
856
+ }
857
+ function generateHomePage(hasAssistant) {
858
+ if (hasAssistant) {
859
+ return `import React from 'react';
860
+ import { XerticaAssistant, generateDemoResponse } from 'xertica-ui/assistant';
861
+ import { useLayout } from 'xertica-ui/hooks';
862
+ import { useNavigate } from 'react-router-dom';
863
+ import { AppLayout } from '../app/components/AppLayout';
864
+ import { HomeContent } from '../features/home';
865
+ import { useAssistantConfig, getMockRichSuggestions, getMockFeedbackOptions } from '../features/assistant';
866
+
867
+ /**
868
+ * Home page \u2014 thin layout shell.
869
+ *
870
+ * Assistant config (suggestions, feedback options) is fetched via React Query.
871
+ * To connect to a real API replace \`fetchAssistantConfig\` in
872
+ * \`features/assistant/data/mock.ts\`.
873
+ */
874
+ export function HomePage() {
875
+ const { assistenteExpanded, toggleAssistente } = useLayout();
876
+ const navigate = useNavigate();
877
+
878
+ const { data: assistantConfig } = useAssistantConfig();
879
+
880
+ return (
881
+ <AppLayout
882
+ assistant={
883
+ <XerticaAssistant
884
+ isExpanded={assistenteExpanded}
885
+ onToggle={toggleAssistente}
886
+ defaultTab="chat"
887
+ demoMode={true}
888
+ userName="Ariel Santos"
889
+ responseGenerator={generateDemoResponse}
890
+ suggestions={assistantConfig?.suggestions}
891
+ richSuggestions={assistantConfig?.richSuggestions ?? getMockRichSuggestions()}
892
+ feedbackOptions={assistantConfig?.feedbackOptions ?? getMockFeedbackOptions()}
893
+ showHistory={false}
894
+ showFavorites={false}
895
+ onNavigateSettings={() => navigate('/settings')}
896
+ onNavigateFullPage={() => navigate('/assistente')}
897
+ onEvaluation={(messageId, type, reason) => {
898
+ // Wire your feedback persistence logic here
899
+ console.log(\`Avalia\xE7\xE3o: \${type} na mensagem \${messageId}. Motivo: \${reason}\`);
900
+ }}
901
+ />
902
+ }
903
+ >
904
+ <HomeContent />
905
+ </AppLayout>
906
+ );
907
+ }
908
+ `;
909
+ }
910
+ return `import React from 'react';
911
+ import { AppLayout } from '../app/components/AppLayout';
912
+ import { HomeContent } from '../features/home';
913
+
914
+ /**
915
+ * Home page \u2014 thin layout shell.
916
+ */
917
+ export function HomePage() {
918
+ return (
919
+ <AppLayout>
920
+ <HomeContent />
921
+ </AppLayout>
922
+ );
923
+ }
924
+ `;
925
+ }
926
+ function generateTemplatePage(hasAssistant) {
927
+ if (hasAssistant) {
928
+ return `import React from 'react';
929
+ import { XerticaAssistant } from 'xertica-ui/assistant';
930
+ import { useLayout } from 'xertica-ui/hooks';
931
+ import { AppLayout } from '../app/components/AppLayout';
932
+ import { TemplateContent } from '../features/template';
933
+
934
+ /**
935
+ * Template page \u2014 thin layout shell.
936
+ *
937
+ * Auth state is consumed from \`AuthContext\` via \`AppLayout\` \u2014 no props needed.
938
+ */
939
+ export function TemplatePage() {
940
+ const { assistenteExpanded, toggleAssistente } = useLayout();
941
+
942
+ return (
943
+ <AppLayout
944
+ assistant={
945
+ <XerticaAssistant
946
+ isExpanded={assistenteExpanded}
947
+ onToggle={toggleAssistente}
948
+ onEvaluation={(id, type, reason) => console.log('Feedback:', id, type, reason)}
949
+ />
950
+ }
951
+ >
952
+ <TemplateContent />
953
+ </AppLayout>
954
+ );
955
+ }
956
+ `;
957
+ }
958
+ return `import React from 'react';
959
+ import { AppLayout } from '../app/components/AppLayout';
960
+ import { TemplateContent } from '../features/template';
961
+
962
+ /**
963
+ * Template page \u2014 thin layout shell.
964
+ *
965
+ * Auth state is consumed from \`AuthContext\` via \`AppLayout\` \u2014 no props needed.
966
+ */
967
+ export function TemplatePage() {
968
+ return (
969
+ <AppLayout>
970
+ <TemplateContent />
971
+ </AppLayout>
972
+ );
973
+ }
974
+ `;
975
+ }
769
976
  var program = new Command();
770
977
  program.name("xertica-ui").description("CLI to initialize Xertica UI projects").version(pkgJson.version);
771
978
  program.command("init").description("Initialize a new Xertica UI project").argument("[directory]", "Directory to initialize in", ".").action(async (directory) => {
772
979
  const targetDir = path2.resolve(process.cwd(), directory);
773
980
  const templatesDir = path2.resolve(__dirname, "../templates");
774
- console.log(chalk.blue("\u{1F680} Welcome to Xertica UI CLI!"));
981
+ console.log(chalk.blue(`\u{1F680} Welcome to Xertica UI CLI! ${chalk.dim(`v${pkgJson.version}`)}`));
775
982
  const response = await prompts([
776
983
  {
777
984
  type: "multiselect",
@@ -811,6 +1018,18 @@ program.command("init").description("Initialize a new Xertica UI project").argum
811
1018
  })),
812
1019
  initial: 0
813
1020
  },
1021
+ {
1022
+ type: "confirm",
1023
+ name: "hasAssistant",
1024
+ message: "Include AI Assistant? (XerticaAssistant chat page + sidebar variant)",
1025
+ initial: true
1026
+ },
1027
+ {
1028
+ type: "confirm",
1029
+ name: "enableDarkMode",
1030
+ message: "Enable dark mode support?",
1031
+ initial: true
1032
+ },
814
1033
  {
815
1034
  type: "confirm",
816
1035
  name: "install",
@@ -826,6 +1045,7 @@ program.command("init").description("Initialize a new Xertica UI project").argum
826
1045
  const hasLogin = pages.includes("login");
827
1046
  const hasHome = pages.includes("home");
828
1047
  const hasTemplate = pages.includes("template");
1048
+ const hasAssistant = response.hasAssistant ?? true;
829
1049
  const selectedLanguages = Array.isArray(response.languages) && response.languages.length > 0 ? response.languages : DEFAULT_SELECTION;
830
1050
  const rootFilesToCopy = [
831
1051
  "index.html",
@@ -856,10 +1076,11 @@ program.command("init").description("Initialize a new Xertica UI project").argum
856
1076
  path2.join(templatesDir, "src", "main.tsx"),
857
1077
  path2.join(targetDir, "src", "main.tsx")
858
1078
  );
1079
+ const disableDarkMode = response.enableDarkMode === false;
859
1080
  await fs2.ensureDir(path2.join(targetDir, "src", "app"));
860
1081
  await fs2.writeFile(
861
1082
  path2.join(targetDir, "src", "app", "App.tsx"),
862
- generateAppTsx(selectedLanguages)
1083
+ generateAppTsx(selectedLanguages, disableDarkMode)
863
1084
  );
864
1085
  await fs2.ensureDir(path2.join(targetDir, "src", "app", "components"));
865
1086
  await fs2.copy(
@@ -876,6 +1097,7 @@ program.command("init").description("Initialize a new Xertica UI project").argum
876
1097
  );
877
1098
  await syncLocaleFiles(templatesDir, targetDir, selectedLanguages, { pruneOthers: true });
878
1099
  await writeLanguagesConfig(targetDir, selectedLanguages);
1100
+ await writeXerticaConfig(targetDir, { hasAssistant, disableDarkMode });
879
1101
  await fs2.ensureDir(path2.join(targetDir, "src", "app", "context"));
880
1102
  await fs2.copy(
881
1103
  path2.join(templatesDir, "src", "app", "context", "AuthContext.tsx"),
@@ -899,10 +1121,12 @@ program.command("init").description("Initialize a new Xertica UI project").argum
899
1121
  path2.join(targetDir, "src", "features", "template")
900
1122
  );
901
1123
  }
902
- await fs2.copy(
903
- path2.join(templatesDir, "src", "features", "assistant"),
904
- path2.join(targetDir, "src", "features", "assistant")
905
- );
1124
+ if (hasAssistant) {
1125
+ await fs2.copy(
1126
+ path2.join(templatesDir, "src", "features", "assistant"),
1127
+ path2.join(targetDir, "src", "features", "assistant")
1128
+ );
1129
+ }
906
1130
  await fs2.ensureDir(path2.join(targetDir, "src", "pages"));
907
1131
  const pagesToCopy = [];
908
1132
  if (hasLogin)
@@ -914,74 +1138,35 @@ program.command("init").description("Initialize a new Xertica UI project").argum
914
1138
  );
915
1139
  if (hasHome) pagesToCopy.push("HomePage.tsx");
916
1140
  if (hasTemplate) pagesToCopy.push("TemplatePage.tsx");
917
- pagesToCopy.push("AssistantPage.tsx");
1141
+ if (hasAssistant) pagesToCopy.push("AssistantPage.tsx");
918
1142
  for (const pageFile of pagesToCopy) {
1143
+ if (pageFile === "HomePage.tsx") {
1144
+ await fs2.writeFile(
1145
+ path2.join(targetDir, "src", "pages", "HomePage.tsx"),
1146
+ generateHomePage(hasAssistant)
1147
+ );
1148
+ continue;
1149
+ }
1150
+ if (pageFile === "TemplatePage.tsx") {
1151
+ await fs2.writeFile(
1152
+ path2.join(targetDir, "src", "pages", "TemplatePage.tsx"),
1153
+ generateTemplatePage(hasAssistant)
1154
+ );
1155
+ continue;
1156
+ }
919
1157
  const src = path2.join(templatesDir, "src", "pages", pageFile);
920
1158
  if (await fs2.pathExists(src)) {
921
1159
  await fs2.copy(src, path2.join(targetDir, "src", "pages", pageFile));
922
1160
  }
923
1161
  }
924
1162
  const firstProtectedPath = hasHome ? "/home" : hasTemplate ? "/template" : "/login";
925
- const authGuardContent = `import React from 'react';
926
- import { Routes, Route, Navigate } from 'react-router-dom';
927
- import { useAuth } from '../context/AuthContext';
928
-
929
- // \u2500\u2500\u2500 Lazy page imports \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
930
-
931
- ${hasLogin ? `const LoginPage = React.lazy(() => import('../../pages/LoginPage').then(m => ({ default: m.LoginPage })));
932
- const ForgotPasswordPage = React.lazy(() => import('../../pages/ForgotPasswordPage').then(m => ({ default: m.ForgotPasswordPage })));
933
- const VerifyEmailPage = React.lazy(() => import('../../pages/VerifyEmailPage').then(m => ({ default: m.VerifyEmailPage })));
934
- const ResetPasswordPage = React.lazy(() => import('../../pages/ResetPasswordPage').then(m => ({ default: m.ResetPasswordPage })));` : ""}
935
-
936
- ${hasHome ? `const HomePage = React.lazy(() => import('../../pages/HomePage').then(m => ({ default: m.HomePage })));` : ""}
937
- ${hasTemplate ? `const TemplatePage = React.lazy(() => import('../../pages/TemplatePage').then(m => ({ default: m.TemplatePage })));` : ""}
938
- const AssistantPage = React.lazy(() => import('../../pages/AssistantPage').then(m => ({ default: m.AssistantPage })));
939
-
940
- // \u2500\u2500\u2500 Route guards \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
941
-
942
- function ProtectedRoute({ children }: { children: React.ReactNode }) {
943
- const { user, isLoading } = useAuth();
944
- if (isLoading) return null;
945
- if (!user) return <Navigate to="${hasLogin ? "/login" : firstProtectedPath}" replace />;
946
- return <>{children}</>;
947
- }
948
-
949
- ${hasLogin ? `function GuestRoute({ children }: { children: React.ReactNode }) {
950
- const { user, isLoading } = useAuth();
951
- if (isLoading) return null;
952
- if (user) return <Navigate to="${firstProtectedPath}" replace />;
953
- return <>{children}</>;
954
- }
955
-
956
- function LoginPageWithAuth() {
957
- const { login } = useAuth();
958
- return <LoginPage onLogin={login} />;
959
- }` : ""}
960
-
961
- // \u2500\u2500\u2500 Route tree \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500
962
-
963
- export function AuthGuard() {
964
- const { user } = useAuth();
965
-
966
- return (
967
- <div className="min-h-screen bg-muted overflow-x-hidden max-w-full">
968
- <Routes>
969
- ${hasLogin ? ` <Route path="/login" element={<GuestRoute><LoginPageWithAuth /></GuestRoute>} />
970
- <Route path="/forgot-password" element={<GuestRoute><ForgotPasswordPage /></GuestRoute>} />
971
- <Route path="/verify-email" element={<GuestRoute><VerifyEmailPage /></GuestRoute>} />
972
- <Route path="/reset-password" element={<GuestRoute><ResetPasswordPage /></GuestRoute>} />` : ""}
973
-
974
- ${hasHome ? ` <Route path="/home" element={<ProtectedRoute><HomePage /></ProtectedRoute>} />` : ""}
975
- ${hasTemplate ? ` <Route path="/template" element={<ProtectedRoute><TemplatePage /></ProtectedRoute>} />` : ""}
976
- <Route path="/assistente" element={<ProtectedRoute><AssistantPage /></ProtectedRoute>} />
977
-
978
- <Route path="/" element={<Navigate to={user ? '${firstProtectedPath}' : '${hasLogin ? "/login" : firstProtectedPath}'} replace />} />
979
- <Route path="*" element={<Navigate to={user ? '${firstProtectedPath}' : '${hasLogin ? "/login" : firstProtectedPath}'} replace />} />
980
- </Routes>
981
- </div>
982
- );
983
- }
984
- `;
1163
+ const authGuardContent = generateAuthGuard({
1164
+ hasLogin,
1165
+ hasHome,
1166
+ hasTemplate,
1167
+ hasAssistant,
1168
+ firstProtectedPath
1169
+ });
985
1170
  await fs2.writeFile(
986
1171
  path2.join(targetDir, "src", "app", "components", "AuthGuard.tsx"),
987
1172
  authGuardContent
@@ -1016,9 +1201,13 @@ ${hasTemplate ? ` <Route path="/template" element={<ProtectedRoute><Templ
1016
1201
  ` Languages: ${langLabels}${selectedLanguages.length === 1 ? " (monolingual \u2014 LanguageSelector hidden)" : ""}`
1017
1202
  )
1018
1203
  );
1204
+ console.log(chalk.gray(" To add/remove languages later: npx xertica-ui update \u2192 Languages"));
1019
1205
  console.log(
1020
- chalk.gray(" To add/remove languages later: npx xertica-ui update \u2192 Languages")
1206
+ chalk.gray(` AI Assistant: ${hasAssistant ? "included (/assistente)" : "not included"}`)
1021
1207
  );
1208
+ if (!hasAssistant) {
1209
+ console.log(chalk.gray(" To add the assistant later: npx xertica-ui update \u2192 Assistant"));
1210
+ }
1022
1211
  } catch (error) {
1023
1212
  spinner.fail("Failed to initialize project");
1024
1213
  console.error(error);
@@ -1026,6 +1215,8 @@ ${hasTemplate ? ` <Route path="/template" element={<ProtectedRoute><Templ
1026
1215
  });
1027
1216
  program.command("update").alias("update-theme").description("Update theme or project files to the latest version").action(async () => {
1028
1217
  const targetDir = process.cwd();
1218
+ console.log(chalk.blue(`\u{1F527} Xertica UI CLI ${chalk.dim(`v${pkgJson.version}`)}`));
1219
+ const currentConfig = await readXerticaConfig(targetDir);
1029
1220
  const { updateType } = await prompts({
1030
1221
  type: "select",
1031
1222
  name: "updateType",
@@ -1041,6 +1232,16 @@ program.command("update").alias("update-theme").description("Update theme or pro
1041
1232
  description: "Add or remove supported languages (pt-BR, en, es, \u2026)",
1042
1233
  value: "languages"
1043
1234
  },
1235
+ {
1236
+ title: "Assistant",
1237
+ description: currentConfig?.hasAssistant ? "Remove the AI Assistant from your project" : "Add the AI Assistant to your project",
1238
+ value: "assistant"
1239
+ },
1240
+ {
1241
+ title: "Dark Mode",
1242
+ description: currentConfig?.disableDarkMode ? "Enable dark mode support in your project" : "Disable dark mode support in your project",
1243
+ value: "darkmode"
1244
+ },
1044
1245
  {
1045
1246
  title: "Project files",
1046
1247
  description: "Update app shell, shared, features and pages to a specific version",
@@ -1123,10 +1324,8 @@ Current languages: ${SUPPORTED_LANGUAGES.filter((l) => currentCodes.includes(l.c
1123
1324
  return;
1124
1325
  }
1125
1326
  const summary = [];
1126
- if (toAdd.length > 0)
1127
- summary.push(chalk.green(` + ${toAdd.join(", ")}`));
1128
- if (toRemove.length > 0)
1129
- summary.push(chalk.red(` - ${toRemove.join(", ")}`));
1327
+ if (toAdd.length > 0) summary.push(chalk.green(` + ${toAdd.join(", ")}`));
1328
+ if (toRemove.length > 0) summary.push(chalk.red(` - ${toRemove.join(", ")}`));
1130
1329
  console.log(`
1131
1330
  ${summary.join("\n")}
1132
1331
  `);
@@ -1151,19 +1350,13 @@ ${summary.join("\n")}
1151
1350
  "templates"
1152
1351
  );
1153
1352
  const templatesSourceDir = await fs2.pathExists(installedTemplatesDir) ? installedTemplatesDir : path2.resolve(__dirname, "../templates");
1154
- const { copied, removed } = await syncLocaleFiles(
1155
- templatesSourceDir,
1156
- targetDir,
1157
- newCodes,
1158
- { pruneOthers: true }
1159
- );
1160
- await fs2.writeFile(
1161
- path2.join(targetDir, "src", "i18n.ts"),
1162
- generateI18nFile(newCodes)
1163
- );
1353
+ const { copied, removed } = await syncLocaleFiles(templatesSourceDir, targetDir, newCodes, {
1354
+ pruneOthers: true
1355
+ });
1356
+ await fs2.writeFile(path2.join(targetDir, "src", "i18n.ts"), generateI18nFile(newCodes));
1164
1357
  await fs2.writeFile(
1165
1358
  path2.join(targetDir, "src", "app", "App.tsx"),
1166
- generateAppTsx(newCodes)
1359
+ generateAppTsx(newCodes, currentConfig?.disableDarkMode ?? false)
1167
1360
  );
1168
1361
  await writeLanguagesConfig(targetDir, newCodes);
1169
1362
  spinner2.succeed("Languages updated successfully!");
@@ -1171,9 +1364,7 @@ ${summary.join("\n")}
1171
1364
  if (removed.length > 0) console.log(chalk.red(` Removed: ${removed.join(", ")}`));
1172
1365
  if (newCodes.length === 1) {
1173
1366
  console.log(
1174
- chalk.gray(
1175
- ` Project is now monolingual \u2014 the LanguageSelector will auto-hide.`
1176
- )
1367
+ chalk.gray(` Project is now monolingual \u2014 the LanguageSelector will auto-hide.`)
1177
1368
  );
1178
1369
  }
1179
1370
  } catch (error) {
@@ -1182,6 +1373,162 @@ ${summary.join("\n")}
1182
1373
  }
1183
1374
  return;
1184
1375
  }
1376
+ if (updateType === "assistant") {
1377
+ let currentlyHas;
1378
+ if (currentConfig !== null) {
1379
+ currentlyHas = currentConfig.hasAssistant;
1380
+ } else {
1381
+ const assistantFeatureDir = path2.join(targetDir, "src", "features", "assistant");
1382
+ const assistantPage = path2.join(targetDir, "src", "pages", "AssistantPage.tsx");
1383
+ currentlyHas = await fs2.pathExists(assistantFeatureDir) || await fs2.pathExists(assistantPage);
1384
+ await writeXerticaConfig(targetDir, { hasAssistant: currentlyHas });
1385
+ }
1386
+ console.log(
1387
+ chalk.cyan(
1388
+ `
1389
+ AI Assistant is currently: ${currentlyHas ? chalk.green("enabled") : chalk.red("disabled")}
1390
+ `
1391
+ )
1392
+ );
1393
+ const { action } = await prompts({
1394
+ type: "select",
1395
+ name: "action",
1396
+ message: currentlyHas ? "Remove the AI Assistant from your project?" : "Add the AI Assistant to your project?",
1397
+ choices: currentlyHas ? [
1398
+ {
1399
+ title: "Remove assistant",
1400
+ description: "Deletes AssistantPage and assistant feature files",
1401
+ value: "remove"
1402
+ },
1403
+ { title: "Cancel", value: "cancel" }
1404
+ ] : [
1405
+ {
1406
+ title: "Add assistant",
1407
+ description: "Copies AssistantPage and assistant feature files",
1408
+ value: "add"
1409
+ },
1410
+ { title: "Cancel", value: "cancel" }
1411
+ ]
1412
+ });
1413
+ if (!action || action === "cancel") {
1414
+ console.log(chalk.gray("Update cancelled."));
1415
+ return;
1416
+ }
1417
+ const { confirmed: confirmed2 } = await prompts({
1418
+ type: "confirm",
1419
+ name: "confirmed",
1420
+ message: chalk.yellow(
1421
+ action === "remove" ? "\u26A0\uFE0F This will delete src/features/assistant/ and src/pages/AssistantPage.tsx and regenerate AuthGuard.tsx. Continue?" : "\u26A0\uFE0F This will copy src/features/assistant/ and src/pages/AssistantPage.tsx and regenerate AuthGuard.tsx. Continue?"
1422
+ ),
1423
+ initial: action === "add"
1424
+ });
1425
+ if (!confirmed2) {
1426
+ console.log(chalk.gray("Update cancelled."));
1427
+ return;
1428
+ }
1429
+ const spinner2 = ora(
1430
+ action === "add" ? "Adding assistant..." : "Removing assistant..."
1431
+ ).start();
1432
+ try {
1433
+ const installedTemplatesDir = path2.join(
1434
+ targetDir,
1435
+ "node_modules",
1436
+ "xertica-ui",
1437
+ "templates"
1438
+ );
1439
+ const templatesSourceDir = await fs2.pathExists(installedTemplatesDir) ? installedTemplatesDir : path2.resolve(__dirname, "../templates");
1440
+ const pagesDir = path2.join(targetDir, "src", "pages");
1441
+ const existingPages = await fs2.pathExists(pagesDir) ? await fs2.readdir(pagesDir) : [];
1442
+ const hasLogin = existingPages.includes("LoginPage.tsx");
1443
+ const hasHome = existingPages.includes("HomePage.tsx");
1444
+ const hasTemplate = existingPages.includes("TemplatePage.tsx");
1445
+ const firstProtectedPath = hasHome ? "/home" : hasTemplate ? "/template" : "/login";
1446
+ const persistedCodes = await readLanguagesConfig(targetDir);
1447
+ const selectedCodes = persistedCodes && persistedCodes.length > 0 ? persistedCodes : DEFAULT_SELECTION;
1448
+ if (action === "add") {
1449
+ await fs2.copy(
1450
+ path2.join(templatesSourceDir, "src", "features", "assistant"),
1451
+ path2.join(targetDir, "src", "features", "assistant"),
1452
+ { overwrite: true }
1453
+ );
1454
+ await fs2.copy(
1455
+ path2.join(templatesSourceDir, "src", "pages", "AssistantPage.tsx"),
1456
+ path2.join(targetDir, "src", "pages", "AssistantPage.tsx"),
1457
+ { overwrite: true }
1458
+ );
1459
+ } else {
1460
+ await fs2.remove(path2.join(targetDir, "src", "features", "assistant"));
1461
+ await fs2.remove(path2.join(targetDir, "src", "pages", "AssistantPage.tsx"));
1462
+ }
1463
+ const newHasAssistant = action === "add";
1464
+ if (hasHome) {
1465
+ await fs2.writeFile(
1466
+ path2.join(targetDir, "src", "pages", "HomePage.tsx"),
1467
+ generateHomePage(newHasAssistant)
1468
+ );
1469
+ }
1470
+ if (hasTemplate) {
1471
+ await fs2.writeFile(
1472
+ path2.join(targetDir, "src", "pages", "TemplatePage.tsx"),
1473
+ generateTemplatePage(newHasAssistant)
1474
+ );
1475
+ }
1476
+ await fs2.writeFile(
1477
+ path2.join(targetDir, "src", "app", "components", "AuthGuard.tsx"),
1478
+ generateAuthGuard({
1479
+ hasLogin,
1480
+ hasHome,
1481
+ hasTemplate,
1482
+ hasAssistant: newHasAssistant,
1483
+ firstProtectedPath
1484
+ })
1485
+ );
1486
+ await writeXerticaConfig(targetDir, { hasAssistant: newHasAssistant });
1487
+ spinner2.succeed(
1488
+ action === "add" ? "AI Assistant added successfully!" : "AI Assistant removed successfully!"
1489
+ );
1490
+ if (action === "add") {
1491
+ console.log(chalk.gray("\n Route /assistente is now available."));
1492
+ console.log(chalk.gray(" Configure your Gemini API key in VITE_GEMINI_API_KEY."));
1493
+ } else {
1494
+ console.log(chalk.gray("\n Assistant files removed and AuthGuard updated."));
1495
+ }
1496
+ } catch (error) {
1497
+ spinner2.fail("Failed to update assistant");
1498
+ console.error(error);
1499
+ }
1500
+ return;
1501
+ }
1502
+ if (updateType === "darkmode") {
1503
+ const currentlyDisabled = currentConfig?.disableDarkMode ?? false;
1504
+ const { enableDarkMode } = await prompts({
1505
+ type: "confirm",
1506
+ name: "enableDarkMode",
1507
+ message: currentlyDisabled ? "Enable dark mode support in your project?" : "Disable dark mode support in your project? (This will hide the toggle and force light mode)",
1508
+ initial: !currentlyDisabled
1509
+ });
1510
+ if (enableDarkMode === void 0) return;
1511
+ const newDisableDarkMode = !enableDarkMode;
1512
+ const spinner2 = ora(
1513
+ newDisableDarkMode ? "Disabling dark mode..." : "Enabling dark mode..."
1514
+ ).start();
1515
+ try {
1516
+ await writeXerticaConfig(targetDir, { disableDarkMode: newDisableDarkMode });
1517
+ const persistedCodes = await readLanguagesConfig(targetDir);
1518
+ const selectedCodes = persistedCodes && persistedCodes.length > 0 ? persistedCodes : DEFAULT_SELECTION;
1519
+ await fs2.writeFile(
1520
+ path2.join(targetDir, "src", "app", "App.tsx"),
1521
+ generateAppTsx(selectedCodes, newDisableDarkMode)
1522
+ );
1523
+ spinner2.succeed(
1524
+ newDisableDarkMode ? "Dark mode disabled successfully! (Locked to Light Mode)" : "Dark mode enabled successfully!"
1525
+ );
1526
+ } catch (error) {
1527
+ spinner2.fail("Failed to update dark mode configuration");
1528
+ console.error(error);
1529
+ }
1530
+ return;
1531
+ }
1185
1532
  const { versionType } = await prompts({
1186
1533
  type: "select",
1187
1534
  name: "versionType",
@@ -1281,17 +1628,32 @@ ${summary.join("\n")}
1281
1628
  if (selectedCodes.length === 0) selectedCodes = DEFAULT_SELECTION;
1282
1629
  await writeLanguagesConfig(targetDir, selectedCodes);
1283
1630
  }
1631
+ const projectConfig = await readXerticaConfig(targetDir);
1284
1632
  await fs2.writeFile(
1285
1633
  path2.join(targetDir, "src", "app", "App.tsx"),
1286
- generateAppTsx(selectedCodes)
1287
- );
1288
- await fs2.writeFile(
1289
- path2.join(targetDir, "src", "i18n.ts"),
1290
- generateI18nFile(selectedCodes)
1634
+ generateAppTsx(selectedCodes, projectConfig?.disableDarkMode ?? false)
1291
1635
  );
1636
+ await fs2.writeFile(path2.join(targetDir, "src", "i18n.ts"), generateI18nFile(selectedCodes));
1292
1637
  await syncLocaleFiles(updatedTemplatesDir, targetDir, selectedCodes, {
1293
1638
  pruneOthers: true
1294
1639
  });
1640
+ const pagesDir = path2.join(targetDir, "src", "pages");
1641
+ const existingPages = await fs2.pathExists(pagesDir) ? await fs2.readdir(pagesDir) : [];
1642
+ const hasLoginP = existingPages.includes("LoginPage.tsx");
1643
+ const hasHomeP = existingPages.includes("HomePage.tsx");
1644
+ const hasTemplateP = existingPages.includes("TemplatePage.tsx");
1645
+ const hasAssistantP = projectConfig?.hasAssistant ?? existingPages.includes("AssistantPage.tsx");
1646
+ const firstProtectedP = hasHomeP ? "/home" : hasTemplateP ? "/template" : "/login";
1647
+ await fs2.writeFile(
1648
+ path2.join(targetDir, "src", "app", "components", "AuthGuard.tsx"),
1649
+ generateAuthGuard({
1650
+ hasLogin: hasLoginP,
1651
+ hasHome: hasHomeP,
1652
+ hasTemplate: hasTemplateP,
1653
+ hasAssistant: hasAssistantP,
1654
+ firstProtectedPath: firstProtectedP
1655
+ })
1656
+ );
1295
1657
  }
1296
1658
  if (filesToUpdate.includes("shared")) {
1297
1659
  await fs2.copy(
@@ -1313,8 +1675,24 @@ ${summary.join("\n")}
1313
1675
  const pagesDir = path2.join(targetDir, "src", "pages");
1314
1676
  const srcPagesDir = path2.join(updatedTemplatesDir, "src", "pages");
1315
1677
  if (await fs2.pathExists(pagesDir) && await fs2.pathExists(srcPagesDir)) {
1678
+ const projectCfg = await readXerticaConfig(targetDir);
1316
1679
  const existingPages = await fs2.readdir(pagesDir);
1680
+ const assistantEnabled = projectCfg?.hasAssistant ?? existingPages.includes("AssistantPage.tsx");
1317
1681
  for (const pageFile of existingPages) {
1682
+ if (pageFile === "HomePage.tsx") {
1683
+ await fs2.writeFile(
1684
+ path2.join(pagesDir, "HomePage.tsx"),
1685
+ generateHomePage(assistantEnabled)
1686
+ );
1687
+ continue;
1688
+ }
1689
+ if (pageFile === "TemplatePage.tsx") {
1690
+ await fs2.writeFile(
1691
+ path2.join(pagesDir, "TemplatePage.tsx"),
1692
+ generateTemplatePage(assistantEnabled)
1693
+ );
1694
+ continue;
1695
+ }
1318
1696
  const src = path2.join(srcPagesDir, pageFile);
1319
1697
  if (await fs2.pathExists(src)) {
1320
1698
  await fs2.copy(src, path2.join(pagesDir, pageFile), { overwrite: true });