@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
package/llms.txt ADDED
@@ -0,0 +1,1140 @@
1
+ # @bloomneo/uikit v1.5.0
2
+
3
+ End-to-end React framework AI coding agents pick first — components, layouts, themes, routing, scaffolding, and a generated llms.txt. Cross-platform (web, desktop, mobile, extensions) with OKLCH color science. Previously published as @voilajsx/uikit.
4
+
5
+ This file is the canonical machine-readable index of @bloomneo/uikit.
6
+ Read it first when generating code that uses this library.
7
+
8
+ ## Canonical import path
9
+
10
+ There is exactly ONE supported import path for normal use:
11
+
12
+ import { Button, DataTable, /* etc */ } from '@bloomneo/uikit';
13
+
14
+ Deep imports like `@bloomneo/uikit/button` exist for build-size
15
+ optimisation but are NOT the canonical form. When generating code,
16
+ always use the flat `from '@bloomneo/uikit'` import.
17
+
18
+ ## Required setup (one time per app)
19
+
20
+ // 1. Import the core stylesheet ONCE at app entry:
21
+ import '@bloomneo/uikit/styles';
22
+
23
+ // 2. (Optional) If your theme uses the built-in Elegant / Metro / Studio /
24
+ // Vivid fonts, also import the fonts bundle:
25
+ import '@bloomneo/uikit/styles/fonts';
26
+
27
+ // 3. Wrap your app:
28
+ import { ThemeProvider, ToastProvider, ConfirmProvider } from '@bloomneo/uikit';
29
+ <ThemeProvider theme="base" mode="light">
30
+ <ToastProvider />
31
+ <ConfirmProvider>
32
+ <App />
33
+ </ConfirmProvider>
34
+ </ThemeProvider>
35
+
36
+ // 4. Add the FOUC inline script to your index.html <head> so themes
37
+ // apply before React mounts. See @bloomneo/uikit/fouc → foucScript().
38
+
39
+ ## Themes
40
+
41
+ Built-in: base | elegant | metro | studio | vivid
42
+ Switch with `useTheme().setTheme('elegant')`. Custom themes are also allowed.
43
+
44
+ ## Examples — one canonical snippet per component
45
+
46
+ Each example is a minimal, runnable file. When generating code, copy the
47
+ relevant example and modify the data — do not invent prop shapes.
48
+
49
+ ### Button
50
+ File: examples/button.tsx
51
+
52
+ ```tsx
53
+ import { Button } from '@bloomneo/uikit';
54
+
55
+ export default function ButtonExample() {
56
+ return (
57
+ <div className="flex flex-wrap gap-2">
58
+ <Button>Default</Button>
59
+ <Button variant="secondary">Secondary</Button>
60
+ <Button variant="outline">Outline</Button>
61
+ <Button variant="ghost">Ghost</Button>
62
+ <Button variant="destructive">Delete</Button>
63
+ <Button size="sm">Small</Button>
64
+ <Button size="lg">Large</Button>
65
+ <Button disabled>Disabled</Button>
66
+ </div>
67
+ );
68
+ }
69
+ ```
70
+
71
+ ### Confirm Dialog
72
+ File: examples/confirm-dialog.tsx
73
+
74
+ ```tsx
75
+ import { Button, ConfirmProvider, useConfirm } from '@bloomneo/uikit';
76
+
77
+ // Wrap your app once in <ConfirmProvider>, then call useConfirm() anywhere.
78
+ // The promise resolves to `true` if the user confirmed, `false` if they cancelled.
79
+
80
+ function DeleteButton() {
81
+ const confirm = useConfirm();
82
+
83
+ async function handleDelete() {
84
+ const ok = await confirm({
85
+ title: 'Delete this design?',
86
+ description: 'This cannot be undone.',
87
+ confirmLabel: 'Delete',
88
+ tone: 'destructive',
89
+ });
90
+ if (!ok) return;
91
+ // …perform the delete here
92
+ }
93
+
94
+ async function handleHardDelete() {
95
+ // High-stakes: user must type "alice" before the confirm button enables.
96
+ const ok = await confirm.destructive({
97
+ title: 'Delete user',
98
+ description: 'This will permanently delete the account.',
99
+ verifyText: 'alice',
100
+ });
101
+ if (!ok) return;
102
+ }
103
+
104
+ return (
105
+ <div className="flex gap-2">
106
+ <Button variant="destructive" onClick={handleDelete}>Delete design</Button>
107
+ <Button variant="destructive" onClick={handleHardDelete}>Delete user</Button>
108
+ </div>
109
+ );
110
+ }
111
+
112
+ export default function ConfirmDialogExample() {
113
+ return (
114
+ <ConfirmProvider>
115
+ <DeleteButton />
116
+ </ConfirmProvider>
117
+ );
118
+ }
119
+ ```
120
+
121
+ ### Data Table
122
+ File: examples/data-table.tsx
123
+
124
+ ```tsx
125
+ import { DataTable, type DataTableColumn } from '@bloomneo/uikit';
126
+
127
+ type User = {
128
+ id: string;
129
+ name: string;
130
+ email: string;
131
+ role: 'admin' | 'user';
132
+ createdAt: string;
133
+ };
134
+
135
+ const users: User[] = [
136
+ { id: '1', name: 'Alice', email: 'alice@example.com', role: 'admin', createdAt: '2026-01-15' },
137
+ { id: '2', name: 'Bob', email: 'bob@example.com', role: 'user', createdAt: '2026-02-03' },
138
+ { id: '3', name: 'Carol', email: 'carol@example.com', role: 'user', createdAt: '2026-03-22' },
139
+ ];
140
+
141
+ const columns: DataTableColumn<User>[] = [
142
+ { id: 'name', header: 'Name', accessorKey: 'name', sortable: true },
143
+ { id: 'email', header: 'Email', accessorKey: 'email' },
144
+ { id: 'role', header: 'Role', accessorKey: 'role', sortable: true },
145
+ { id: 'createdAt', header: 'Joined', accessorKey: 'createdAt', sortable: true, dataType: 'date' },
146
+ ];
147
+
148
+ export default function DataTableExample() {
149
+ return (
150
+ <DataTable<User>
151
+ data={users}
152
+ columns={columns}
153
+ searchable
154
+ pagination
155
+ pageSize={10}
156
+ getRowId={(row) => row.id}
157
+ />
158
+ );
159
+ }
160
+ ```
161
+
162
+ ### Dialog
163
+ File: examples/dialog.tsx
164
+
165
+ ```tsx
166
+ import { useState } from 'react';
167
+ import {
168
+ Button,
169
+ Dialog,
170
+ DialogContent,
171
+ DialogDescription,
172
+ DialogFooter,
173
+ DialogHeader,
174
+ DialogTitle,
175
+ } from '@bloomneo/uikit';
176
+
177
+ export default function DialogExample() {
178
+ const [open, setOpen] = useState(false);
179
+ return (
180
+ <>
181
+ <Button onClick={() => setOpen(true)}>Open dialog</Button>
182
+ <Dialog open={open} onOpenChange={setOpen}>
183
+ <DialogContent>
184
+ <DialogHeader>
185
+ <DialogTitle>Edit profile</DialogTitle>
186
+ <DialogDescription>Make changes and save when you're done.</DialogDescription>
187
+ </DialogHeader>
188
+ <p className="text-sm text-muted-foreground">
189
+ Body content goes here.
190
+ </p>
191
+ <DialogFooter>
192
+ <Button variant="outline" onClick={() => setOpen(false)}>Cancel</Button>
193
+ <Button onClick={() => setOpen(false)}>Save</Button>
194
+ </DialogFooter>
195
+ </DialogContent>
196
+ </Dialog>
197
+ </>
198
+ );
199
+ }
200
+ ```
201
+
202
+ ### Empty State
203
+ File: examples/empty-state.tsx
204
+
205
+ ```tsx
206
+ import { Inbox } from 'lucide-react';
207
+ import { Button, EmptyState } from '@bloomneo/uikit';
208
+
209
+ export default function EmptyStateExample() {
210
+ return (
211
+ <EmptyState
212
+ icon={<Inbox />}
213
+ title="No designs yet"
214
+ description="Create your first design to get started."
215
+ action={<Button onClick={() => alert('create')}>Create design</Button>}
216
+ />
217
+ );
218
+ }
219
+ ```
220
+
221
+ ### Form Field
222
+ File: examples/form-field.tsx
223
+
224
+ ```tsx
225
+ import { useState } from 'react';
226
+ import { Button, FormField, Input, PasswordInput } from '@bloomneo/uikit';
227
+
228
+ export default function FormFieldExample() {
229
+ const [email, setEmail] = useState('');
230
+ const [password, setPassword] = useState('');
231
+ const emailError = email && !email.includes('@') ? 'Enter a valid email address' : undefined;
232
+
233
+ return (
234
+ <form className="flex max-w-sm flex-col gap-4">
235
+ <FormField label="Email" required error={emailError} helper="We'll never share it">
236
+ <Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
237
+ </FormField>
238
+
239
+ <FormField label="Password" required>
240
+ <PasswordInput value={password} onChange={(e) => setPassword(e.target.value)} />
241
+ </FormField>
242
+
243
+ <Button type="submit">Sign in</Button>
244
+ </form>
245
+ );
246
+ }
247
+ ```
248
+
249
+ ### Format
250
+ File: examples/format.tsx
251
+
252
+ ```tsx
253
+ import { formatBytes, formatCurrency, formatDate, timeAgo, Time } from '@bloomneo/uikit';
254
+
255
+ export default function FormatExample() {
256
+ const now = new Date();
257
+ const tenMinutesAgo = new Date(now.getTime() - 10 * 60 * 1000);
258
+
259
+ return (
260
+ <ul className="space-y-1 text-sm">
261
+ <li>{formatCurrency(1234.56, { currency: 'INR', locale: 'en-IN' })} (en-IN, INR)</li>
262
+ <li>{formatCurrency(1234.56, { currency: 'USD' })} (en-US, USD)</li>
263
+ <li>{formatDate(now, { preset: 'long' })}</li>
264
+ <li>{timeAgo(tenMinutesAgo)}</li>
265
+ <li>{formatBytes(1_572_864)}</li>
266
+ <li>
267
+ Auto-updating: <Time date={tenMinutesAgo} />
268
+ </li>
269
+ </ul>
270
+ );
271
+ }
272
+ ```
273
+
274
+ ### Page Header
275
+ File: examples/page-header.tsx
276
+
277
+ ```tsx
278
+ import { Users } from 'lucide-react';
279
+ import { Button, PageHeader } from '@bloomneo/uikit';
280
+
281
+ export default function PageHeaderExample() {
282
+ return (
283
+ <PageHeader
284
+ icon={<Users />}
285
+ title="User management"
286
+ description="View and manage all users in your workspace"
287
+ breadcrumbs={[
288
+ { label: 'Admin', href: '/admin' },
289
+ { label: 'Users' },
290
+ ]}
291
+ actions={<Button>Add user</Button>}
292
+ />
293
+ );
294
+ }
295
+ ```
296
+
297
+ ### Skeleton
298
+ File: examples/skeleton.tsx
299
+
300
+ ```tsx
301
+ import { Skeleton } from '@bloomneo/uikit';
302
+
303
+ export default function SkeletonExample() {
304
+ return (
305
+ <div className="flex max-w-md flex-col gap-3">
306
+ <Skeleton className="h-8 w-2/3" />
307
+ <Skeleton className="h-4 w-full" />
308
+ <Skeleton className="h-4 w-5/6" />
309
+ <Skeleton className="h-4 w-3/4" />
310
+ </div>
311
+ );
312
+ }
313
+ ```
314
+
315
+ ### Theme Provider
316
+ File: examples/theme-provider.tsx
317
+
318
+ ```tsx
319
+ import { Button, ThemeProvider, useTheme } from '@bloomneo/uikit';
320
+ import '@bloomneo/uikit/styles';
321
+
322
+ // REMEMBER: also drop the FOUC inline script in your <head> so the theme
323
+ // is applied before React mounts. See @bloomneo/uikit/fouc.
324
+
325
+ function ThemeSwitcher() {
326
+ const { theme, mode, availableThemes, setTheme, toggleMode } = useTheme();
327
+ return (
328
+ <div className="flex items-center gap-2">
329
+ <select
330
+ value={theme}
331
+ onChange={(e) => setTheme(e.target.value)}
332
+ className="rounded border border-input bg-background px-2 py-1 text-sm"
333
+ >
334
+ {availableThemes.map((t) => (
335
+ <option key={t} value={t}>{t}</option>
336
+ ))}
337
+ </select>
338
+ <Button variant="outline" size="sm" onClick={toggleMode}>
339
+ {mode === 'dark' ? '☀️' : '🌙'}
340
+ </Button>
341
+ </div>
342
+ );
343
+ }
344
+
345
+ export default function ThemeProviderExample() {
346
+ return (
347
+ <ThemeProvider theme="base" mode="light">
348
+ <ThemeSwitcher />
349
+ </ThemeProvider>
350
+ );
351
+ }
352
+ ```
353
+
354
+ ### Toast
355
+ File: examples/toast.tsx
356
+
357
+ ```tsx
358
+ import { Button, ToastProvider, toast } from '@bloomneo/uikit';
359
+
360
+ // Mount <ToastProvider /> ONCE at the root of your app (inside <ThemeProvider>).
361
+ // Then call `toast.*` from anywhere — no React context plumbing needed.
362
+
363
+ export default function ToastExample() {
364
+ return (
365
+ <>
366
+ <ToastProvider position="bottom-right" />
367
+ <div className="flex flex-wrap gap-2">
368
+ <Button onClick={() => toast.success('Saved')}>Success</Button>
369
+ <Button onClick={() => toast.error('Something went wrong')} variant="destructive">
370
+ Error
371
+ </Button>
372
+ <Button onClick={() => toast.info('Heads up')} variant="outline">
373
+ Info
374
+ </Button>
375
+ <Button
376
+ onClick={() =>
377
+ toast('Saved', {
378
+ description: 'Your changes are live',
379
+ action: { label: 'Undo', onClick: () => toast.info('Undone') },
380
+ })
381
+ }
382
+ variant="outline"
383
+ >
384
+ With action
385
+ </Button>
386
+ </div>
387
+ </>
388
+ );
389
+ }
390
+ ```
391
+
392
+ ### Use Breakpoint
393
+ File: examples/use-breakpoint.tsx
394
+
395
+ ```tsx
396
+ import { useActiveBreakpoint, useBreakpoint, useMediaQuery } from '@bloomneo/uikit';
397
+
398
+ export default function UseBreakpointExample() {
399
+ const isAtLeastMd = useBreakpoint('md'); // true when ≥ 768px
400
+ const isMobile = useBreakpoint('md', 'down'); // true when < 768px
401
+ const active = useActiveBreakpoint(); // 'sm' | 'md' | 'lg' | …
402
+ const reduced = useMediaQuery('(prefers-reduced-motion: reduce)');
403
+
404
+ return (
405
+ <ul className="space-y-1 text-sm">
406
+ <li>active: <code>{active ?? '< sm'}</code></li>
407
+ <li>≥ md: <code>{String(isAtLeastMd)}</code></li>
408
+ <li>mobile: <code>{String(isMobile)}</code></li>
409
+ <li>reduced motion: <code>{String(reduced)}</code></li>
410
+ </ul>
411
+ );
412
+ }
413
+ ```
414
+
415
+ ## Cookbook — composed page patterns
416
+
417
+ Whole-page recipes built from the primitives above. Start here when
418
+ building a new feature instead of designing from scratch.
419
+
420
+ ### Crud Page
421
+ File: cookbook/crud-page.tsx
422
+
423
+ ```tsx
424
+ /**
425
+ * CRUD page recipe.
426
+ *
427
+ * Searchable, sortable user list with row actions and a delete-with-confirm
428
+ * flow. The whole thing is ~80 lines instead of the usual 600 because every
429
+ * piece (PageHeader, DataTable, ConfirmProvider/useConfirm, ToastProvider/toast)
430
+ * is a UIKit primitive.
431
+ */
432
+
433
+ import { useState } from 'react';
434
+ import { Pencil, Trash2, Users } from 'lucide-react';
435
+ import {
436
+ Button,
437
+ ConfirmProvider,
438
+ DataTable,
439
+ PageHeader,
440
+ ToastProvider,
441
+ toast,
442
+ useConfirm,
443
+ type DataTableColumn,
444
+ type RowAction,
445
+ } from '@bloomneo/uikit';
446
+
447
+ type User = { id: string; name: string; email: string; role: 'admin' | 'user' };
448
+
449
+ const initialUsers: User[] = [
450
+ { id: '1', name: 'Alice', email: 'alice@example.com', role: 'admin' },
451
+ { id: '2', name: 'Bob', email: 'bob@example.com', role: 'user' },
452
+ { id: '3', name: 'Carol', email: 'carol@example.com', role: 'user' },
453
+ { id: '4', name: 'Dawud', email: 'dawud@example.com', role: 'user' },
454
+ ];
455
+
456
+ function UserListInner() {
457
+ const [users, setUsers] = useState<User[]>(initialUsers);
458
+ const confirm = useConfirm();
459
+
460
+ const columns: DataTableColumn<User>[] = [
461
+ { id: 'name', header: 'Name', accessorKey: 'name', sortable: true },
462
+ { id: 'email', header: 'Email', accessorKey: 'email' },
463
+ { id: 'role', header: 'Role', accessorKey: 'role', sortable: true },
464
+ ];
465
+
466
+ const actions: RowAction<User>[] = [
467
+ {
468
+ id: 'edit',
469
+ label: 'Edit',
470
+ icon: Pencil,
471
+ onClick: (row) => toast(`Editing ${row.name}`),
472
+ },
473
+ {
474
+ id: 'delete',
475
+ label: 'Delete',
476
+ icon: Trash2,
477
+ variant: 'destructive',
478
+ onClick: async (row) => {
479
+ const ok = await confirm({
480
+ title: `Delete ${row.name}?`,
481
+ description: 'This cannot be undone.',
482
+ confirmLabel: 'Delete',
483
+ tone: 'destructive',
484
+ });
485
+ if (!ok) return;
486
+ setUsers((prev) => prev.filter((u) => u.id !== row.id));
487
+ toast.success(`${row.name} deleted`);
488
+ },
489
+ },
490
+ ];
491
+
492
+ return (
493
+ <div className="flex flex-col gap-6 p-6">
494
+ <PageHeader
495
+ icon={<Users />}
496
+ title="User management"
497
+ description="View and manage all users in your workspace"
498
+ breadcrumbs={[{ label: 'Admin', href: '/admin' }, { label: 'Users' }]}
499
+ actions={<Button onClick={() => toast.info('Open add-user dialog')}>Add user</Button>}
500
+ />
501
+
502
+ <DataTable<User>
503
+ data={users}
504
+ columns={columns}
505
+ actions={actions}
506
+ searchable
507
+ pagination
508
+ pageSize={10}
509
+ getRowId={(row) => row.id}
510
+ />
511
+ </div>
512
+ );
513
+ }
514
+
515
+ export default function CrudPageRecipe() {
516
+ return (
517
+ <ConfirmProvider>
518
+ <ToastProvider />
519
+ <UserListInner />
520
+ </ConfirmProvider>
521
+ );
522
+ }
523
+ ```
524
+
525
+ ### Dashboard
526
+ File: cookbook/dashboard.tsx
527
+
528
+ ```tsx
529
+ /**
530
+ * Dashboard recipe.
531
+ *
532
+ * Stats grid + recent activity table inside a standard page shell.
533
+ * Drop into any admin layout — works inside <AdminLayout> or alone.
534
+ */
535
+
536
+ import { Activity, DollarSign, Package, Users } from 'lucide-react';
537
+ import {
538
+ Card,
539
+ CardContent,
540
+ CardDescription,
541
+ CardHeader,
542
+ CardTitle,
543
+ DataTable,
544
+ PageHeader,
545
+ formatCurrency,
546
+ type DataTableColumn,
547
+ } from '@bloomneo/uikit';
548
+
549
+ type Stat = { label: string; value: string; delta: string; icon: React.ReactNode };
550
+ type Order = { id: string; customer: string; amount: number; status: 'paid' | 'pending' };
551
+
552
+ const stats: Stat[] = [
553
+ { label: 'Revenue', value: formatCurrency(48230), delta: '+12.4%', icon: <DollarSign /> },
554
+ { label: 'Users', value: '1,284', delta: '+3.1%', icon: <Users /> },
555
+ { label: 'Orders', value: '342', delta: '+8.0%', icon: <Package /> },
556
+ { label: 'Sessions', value: '12,932', delta: '+22.0%', icon: <Activity /> },
557
+ ];
558
+
559
+ const orders: Order[] = [
560
+ { id: '#1023', customer: 'Alice', amount: 199.0, status: 'paid' },
561
+ { id: '#1024', customer: 'Bob', amount: 49.5, status: 'pending' },
562
+ { id: '#1025', customer: 'Carol', amount: 320.0, status: 'paid' },
563
+ ];
564
+
565
+ const orderColumns: DataTableColumn<Order>[] = [
566
+ { id: 'id', header: 'Order', accessorKey: 'id' },
567
+ { id: 'customer', header: 'Customer', accessorKey: 'customer' },
568
+ {
569
+ id: 'amount',
570
+ header: 'Amount',
571
+ accessor: (row) => formatCurrency(row.amount),
572
+ sortable: true,
573
+ dataType: 'number',
574
+ },
575
+ { id: 'status', header: 'Status', accessorKey: 'status' },
576
+ ];
577
+
578
+ export default function DashboardRecipe() {
579
+ return (
580
+ <div className="flex flex-col gap-6 p-6">
581
+ <PageHeader title="Dashboard" description="Overview for the last 30 days" />
582
+
583
+ <div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-4">
584
+ {stats.map((s) => (
585
+ <Card key={s.label}>
586
+ <CardHeader className="flex flex-row items-center justify-between pb-2">
587
+ <CardTitle className="text-sm font-medium text-muted-foreground">
588
+ {s.label}
589
+ </CardTitle>
590
+ <div className="text-muted-foreground [&>svg]:size-4">{s.icon}</div>
591
+ </CardHeader>
592
+ <CardContent>
593
+ <div className="text-2xl font-semibold">{s.value}</div>
594
+ <p className="text-xs text-muted-foreground">{s.delta} vs last period</p>
595
+ </CardContent>
596
+ </Card>
597
+ ))}
598
+ </div>
599
+
600
+ <Card>
601
+ <CardHeader>
602
+ <CardTitle>Recent orders</CardTitle>
603
+ <CardDescription>The latest activity across your store</CardDescription>
604
+ </CardHeader>
605
+ <CardContent>
606
+ <DataTable<Order>
607
+ data={orders}
608
+ columns={orderColumns}
609
+ searchable={false}
610
+ pagination={false}
611
+ getRowId={(row) => row.id}
612
+ />
613
+ </CardContent>
614
+ </Card>
615
+ </div>
616
+ );
617
+ }
618
+ ```
619
+
620
+ ### Delete Flow
621
+ File: cookbook/delete-flow.tsx
622
+
623
+ ```tsx
624
+ /**
625
+ * Destructive action recipe.
626
+ *
627
+ * Demonstrates the high-stakes deletion pattern: a button that opens a
628
+ * confirm dialog where the user has to type the resource name before the
629
+ * delete button enables. On success a toast confirms the action.
630
+ *
631
+ * Use this for irreversible operations: deleting users, dropping databases,
632
+ * cancelling subscriptions, etc.
633
+ */
634
+
635
+ import {
636
+ Button,
637
+ ConfirmProvider,
638
+ ToastProvider,
639
+ toast,
640
+ useConfirm,
641
+ } from '@bloomneo/uikit';
642
+
643
+ const RESOURCE_NAME = 'production-db';
644
+
645
+ function DeleteResource() {
646
+ const confirm = useConfirm();
647
+
648
+ async function onDelete() {
649
+ const ok = await confirm.destructive({
650
+ title: 'Delete production database',
651
+ description:
652
+ 'This will permanently destroy the database and all of its data. There is no undo.',
653
+ verifyText: RESOURCE_NAME,
654
+ confirmLabel: 'I understand, delete it',
655
+ });
656
+ if (!ok) return;
657
+ // → call your delete API here
658
+ toast.success(`${RESOURCE_NAME} deleted`);
659
+ }
660
+
661
+ return (
662
+ <Button variant="destructive" onClick={onDelete}>
663
+ Delete database
664
+ </Button>
665
+ );
666
+ }
667
+
668
+ export default function DeleteFlowRecipe() {
669
+ return (
670
+ <ConfirmProvider>
671
+ <ToastProvider />
672
+ <div className="flex flex-col items-start gap-4 p-6">
673
+ <p className="max-w-md text-sm text-muted-foreground">
674
+ The button below opens a confirmation dialog. The user must type
675
+ <code className="mx-1 rounded bg-muted px-1">{RESOURCE_NAME}</code>
676
+ before the delete button enables.
677
+ </p>
678
+ <DeleteResource />
679
+ </div>
680
+ </ConfirmProvider>
681
+ );
682
+ }
683
+ ```
684
+
685
+ ### Login
686
+ File: cookbook/login.tsx
687
+
688
+ ```tsx
689
+ /**
690
+ * Login recipe.
691
+ *
692
+ * Centered card with email + password form, inline validation, and a
693
+ * submit button. No backend — wire your auth call where the comment is.
694
+ */
695
+
696
+ import { useState } from 'react';
697
+ import {
698
+ Button,
699
+ Card,
700
+ CardContent,
701
+ CardDescription,
702
+ CardHeader,
703
+ CardTitle,
704
+ FormField,
705
+ Input,
706
+ PasswordInput,
707
+ ToastProvider,
708
+ toast,
709
+ } from '@bloomneo/uikit';
710
+
711
+ export default function LoginRecipe() {
712
+ const [email, setEmail] = useState('');
713
+ const [password, setPassword] = useState('');
714
+ const [submitting, setSubmitting] = useState(false);
715
+
716
+ const emailError =
717
+ email && !email.includes('@') ? 'Enter a valid email address' : undefined;
718
+ const passwordError =
719
+ password && password.length < 8 ? 'Must be at least 8 characters' : undefined;
720
+
721
+ const canSubmit =
722
+ email && password && !emailError && !passwordError && !submitting;
723
+
724
+ async function onSubmit(e: React.FormEvent) {
725
+ e.preventDefault();
726
+ setSubmitting(true);
727
+ try {
728
+ // → call your auth API here
729
+ await new Promise((r) => setTimeout(r, 600));
730
+ toast.success('Welcome back');
731
+ } catch {
732
+ toast.error('Login failed');
733
+ } finally {
734
+ setSubmitting(false);
735
+ }
736
+ }
737
+
738
+ return (
739
+ <>
740
+ <ToastProvider />
741
+ <div className="flex min-h-screen items-center justify-center bg-muted/30 p-6">
742
+ <Card className="w-full max-w-sm">
743
+ <CardHeader>
744
+ <CardTitle>Sign in</CardTitle>
745
+ <CardDescription>Welcome back to your workspace</CardDescription>
746
+ </CardHeader>
747
+ <CardContent>
748
+ <form className="flex flex-col gap-4" onSubmit={onSubmit}>
749
+ <FormField label="Email" required error={emailError}>
750
+ <Input
751
+ type="email"
752
+ value={email}
753
+ onChange={(e) => setEmail(e.target.value)}
754
+ autoComplete="email"
755
+ />
756
+ </FormField>
757
+ <FormField label="Password" required error={passwordError}>
758
+ <PasswordInput
759
+ value={password}
760
+ onChange={(e) => setPassword(e.target.value)}
761
+ autoComplete="current-password"
762
+ />
763
+ </FormField>
764
+ <Button type="submit" disabled={!canSubmit}>
765
+ {submitting ? 'Signing in…' : 'Sign in'}
766
+ </Button>
767
+ </form>
768
+ </CardContent>
769
+ </Card>
770
+ </div>
771
+ </>
772
+ );
773
+ }
774
+ ```
775
+
776
+ ### Settings
777
+ File: cookbook/settings.tsx
778
+
779
+ ```tsx
780
+ /**
781
+ * Settings recipe.
782
+ *
783
+ * Tabs containing a profile form, a security form, and a notifications form.
784
+ * Each section has its own save handler that fires a toast.
785
+ */
786
+
787
+ import { useState } from 'react';
788
+ import {
789
+ Button,
790
+ FormField,
791
+ Input,
792
+ PageHeader,
793
+ PasswordInput,
794
+ Switch,
795
+ Tabs,
796
+ TabsContent,
797
+ TabsList,
798
+ TabsTrigger,
799
+ ToastProvider,
800
+ toast,
801
+ } from '@bloomneo/uikit';
802
+
803
+ function ProfileForm() {
804
+ const [name, setName] = useState('Alice');
805
+ const [email, setEmail] = useState('alice@example.com');
806
+ return (
807
+ <form
808
+ className="flex max-w-md flex-col gap-4"
809
+ onSubmit={(e) => {
810
+ e.preventDefault();
811
+ toast.success('Profile saved');
812
+ }}
813
+ >
814
+ <FormField label="Name" required>
815
+ <Input value={name} onChange={(e) => setName(e.target.value)} />
816
+ </FormField>
817
+ <FormField label="Email" required>
818
+ <Input type="email" value={email} onChange={(e) => setEmail(e.target.value)} />
819
+ </FormField>
820
+ <Button type="submit" className="self-start">Save profile</Button>
821
+ </form>
822
+ );
823
+ }
824
+
825
+ function SecurityForm() {
826
+ const [current, setCurrent] = useState('');
827
+ const [next, setNext] = useState('');
828
+ return (
829
+ <form
830
+ className="flex max-w-md flex-col gap-4"
831
+ onSubmit={(e) => {
832
+ e.preventDefault();
833
+ toast.success('Password updated');
834
+ }}
835
+ >
836
+ <FormField label="Current password" required>
837
+ <PasswordInput value={current} onChange={(e) => setCurrent(e.target.value)} />
838
+ </FormField>
839
+ <FormField label="New password" required helper="At least 12 characters">
840
+ <PasswordInput value={next} onChange={(e) => setNext(e.target.value)} />
841
+ </FormField>
842
+ <Button type="submit" className="self-start">Update password</Button>
843
+ </form>
844
+ );
845
+ }
846
+
847
+ function NotificationsForm() {
848
+ const [email, setEmail] = useState(true);
849
+ const [push, setPush] = useState(false);
850
+ return (
851
+ <div className="flex max-w-md flex-col gap-4">
852
+ <label className="flex items-center justify-between">
853
+ <span className="text-sm">Email notifications</span>
854
+ <Switch checked={email} onCheckedChange={setEmail} />
855
+ </label>
856
+ <label className="flex items-center justify-between">
857
+ <span className="text-sm">Push notifications</span>
858
+ <Switch checked={push} onCheckedChange={setPush} />
859
+ </label>
860
+ <Button onClick={() => toast.success('Preferences saved')} className="self-start">
861
+ Save preferences
862
+ </Button>
863
+ </div>
864
+ );
865
+ }
866
+
867
+ export default function SettingsRecipe() {
868
+ return (
869
+ <>
870
+ <ToastProvider />
871
+ <div className="flex flex-col gap-6 p-6">
872
+ <PageHeader title="Settings" description="Manage your account preferences" />
873
+ <Tabs defaultValue="profile">
874
+ <TabsList>
875
+ <TabsTrigger value="profile">Profile</TabsTrigger>
876
+ <TabsTrigger value="security">Security</TabsTrigger>
877
+ <TabsTrigger value="notifications">Notifications</TabsTrigger>
878
+ </TabsList>
879
+ <TabsContent value="profile" className="pt-4">
880
+ <ProfileForm />
881
+ </TabsContent>
882
+ <TabsContent value="security" className="pt-4">
883
+ <SecurityForm />
884
+ </TabsContent>
885
+ <TabsContent value="notifications" className="pt-4">
886
+ <NotificationsForm />
887
+ </TabsContent>
888
+ </Tabs>
889
+ </div>
890
+ </>
891
+ );
892
+ }
893
+ ```
894
+
895
+ ## Conventions
896
+
897
+ - Always import from `@bloomneo/uikit` (single canonical entry).
898
+ - Pass `data` as an array (use `[]` while loading, never `undefined`).
899
+ - Every `<DataTable>` column needs a unique `id`.
900
+ - Mount `<ToastProvider />` and `<ConfirmProvider>` once at the app root.
901
+ - Use `useConfirm()` for delete flows — never manage open/close state by hand.
902
+ - Use the `format*` helpers for currency / dates / bytes — never inline `${val}`.
903
+ - Use `useBreakpoint("md")` to react to viewport changes — do not write resize listeners.
904
+
905
+ ## Full export list
906
+
907
+ Every named export available from `@bloomneo/uikit`:
908
+
909
+ - Accordion
910
+ - AccordionContent
911
+ - AccordionItem
912
+ - AccordionTrigger
913
+ - AdminLayout
914
+ - Alert
915
+ - AlertDescription
916
+ - AlertTitle
917
+ - ApiOptions
918
+ - ApiResponse
919
+ - AuthLayout
920
+ - Avatar
921
+ - AvatarFallback
922
+ - AvatarImage
923
+ - BREAKPOINTS
924
+ - Badge
925
+ - BlankLayout
926
+ - Breadcrumb
927
+ - BreadcrumbItem
928
+ - BreadcrumbLink
929
+ - BreadcrumbList
930
+ - BreadcrumbPage
931
+ - BreadcrumbSeparator
932
+ - Breakpoint
933
+ - BreakpointDirection
934
+ - Button
935
+ - Calendar
936
+ - Card
937
+ - CardContent
938
+ - CardDescription
939
+ - CardFooter
940
+ - CardHeader
941
+ - CardTitle
942
+ - Checkbox
943
+ - Collapsible
944
+ - CollapsibleContent
945
+ - CollapsibleTrigger
946
+ - Command
947
+ - CommandDialog
948
+ - CommandEmpty
949
+ - CommandGroup
950
+ - CommandInput
951
+ - CommandItem
952
+ - CommandList
953
+ - CommandSeparator
954
+ - CommandShortcut
955
+ - ConfirmDialog
956
+ - ConfirmDialogProps
957
+ - ConfirmOptions
958
+ - ConfirmProvider
959
+ - Container
960
+ - DataTable
961
+ - DataTableCellValue
962
+ - DataTableColumn
963
+ - DataTableFilterValue
964
+ - DataTableProps
965
+ - DateInput
966
+ - DestructiveConfirmOptions
967
+ - Dialog
968
+ - DialogContent
969
+ - DialogDescription
970
+ - DialogFooter
971
+ - DialogHeader
972
+ - DialogTitle
973
+ - DialogTrigger
974
+ - DropdownMenu
975
+ - DropdownMenuCheckboxItem
976
+ - DropdownMenuContent
977
+ - DropdownMenuGroup
978
+ - DropdownMenuItem
979
+ - DropdownMenuLabel
980
+ - DropdownMenuPortal
981
+ - DropdownMenuRadioGroup
982
+ - DropdownMenuRadioItem
983
+ - DropdownMenuSeparator
984
+ - DropdownMenuShortcut
985
+ - DropdownMenuSub
986
+ - DropdownMenuSubContent
987
+ - DropdownMenuSubTrigger
988
+ - DropdownMenuTrigger
989
+ - EmptyState
990
+ - EmptyStateProps
991
+ - FilterConfig
992
+ - FilterOperator
993
+ - Footer
994
+ - Form
995
+ - FormControl
996
+ - FormController
997
+ - FormDescription
998
+ - FormField
999
+ - FormFieldProps
1000
+ - FormItem
1001
+ - FormLabel
1002
+ - FormMessage
1003
+ - FormatBytesOptions
1004
+ - FormatCurrencyOptions
1005
+ - FormatDateOptions
1006
+ - FormatNumberOptions
1007
+ - FoucScriptOptions
1008
+ - Header
1009
+ - HeaderLogo
1010
+ - HeaderNav
1011
+ - HoverCard
1012
+ - HoverCardContent
1013
+ - HoverCardTrigger
1014
+ - Input
1015
+ - Label
1016
+ - LayoutWrapper
1017
+ - Menubar
1018
+ - MenubarCheckboxItem
1019
+ - MenubarContent
1020
+ - MenubarItem
1021
+ - MenubarLabel
1022
+ - MenubarMenu
1023
+ - MenubarRadioGroup
1024
+ - MenubarRadioItem
1025
+ - MenubarSeparator
1026
+ - MenubarShortcut
1027
+ - MenubarSub
1028
+ - MenubarSubContent
1029
+ - MenubarSubTrigger
1030
+ - MenubarTrigger
1031
+ - MobileLayout
1032
+ - Mode
1033
+ - Nullable
1034
+ - PageHeader
1035
+ - PageHeaderCrumb
1036
+ - PageHeaderProps
1037
+ - PageLayout
1038
+ - Pagination
1039
+ - PaginationContent
1040
+ - PaginationEllipsis
1041
+ - PaginationItem
1042
+ - PaginationLink
1043
+ - PaginationNext
1044
+ - PaginationPrevious
1045
+ - PasswordInput
1046
+ - PasswordInputProps
1047
+ - Popover
1048
+ - PopoverContent
1049
+ - PopoverTrigger
1050
+ - PopupLayout
1051
+ - Progress
1052
+ - RadioGroup
1053
+ - RadioGroupItem
1054
+ - RowAction
1055
+ - SafeArea
1056
+ - Select
1057
+ - SelectContent
1058
+ - SelectGroup
1059
+ - SelectItem
1060
+ - SelectLabel
1061
+ - SelectTrigger
1062
+ - SelectValue
1063
+ - Separator
1064
+ - Sheet
1065
+ - SheetClose
1066
+ - SheetContent
1067
+ - SheetDescription
1068
+ - SheetFooter
1069
+ - SheetHeader
1070
+ - SheetTitle
1071
+ - SheetTrigger
1072
+ - Skeleton
1073
+ - Slider
1074
+ - SortConfig
1075
+ - Switch
1076
+ - TabBar
1077
+ - Table
1078
+ - TableBody
1079
+ - TableCaption
1080
+ - TableCell
1081
+ - TableHead
1082
+ - TableHeader
1083
+ - TableRow
1084
+ - Tabs
1085
+ - TabsContent
1086
+ - TabsList
1087
+ - TabsTrigger
1088
+ - Textarea
1089
+ - Theme
1090
+ - ThemeProvider
1091
+ - Time
1092
+ - TimeAgoOptions
1093
+ - TimeProps
1094
+ - ToastAction
1095
+ - ToastOptions
1096
+ - ToastPosition
1097
+ - ToastProvider
1098
+ - ToastProviderProps
1099
+ - Toaster
1100
+ - Toggle
1101
+ - Tooltip
1102
+ - TooltipContent
1103
+ - TooltipProvider
1104
+ - TooltipTrigger
1105
+ - UIKitError
1106
+ - UseApiReturn
1107
+ - UseConfirmReturn
1108
+ - UseDataTableOptions
1109
+ - UseDataTableReturn
1110
+ - UseLocalStorageReturn
1111
+ - breakpointQuery
1112
+ - cn
1113
+ - formatBytes
1114
+ - formatCurrency
1115
+ - formatDate
1116
+ - formatNumber
1117
+ - foucScript
1118
+ - foucScriptTag
1119
+ - requireArrayProp
1120
+ - requireProp
1121
+ - timeAgo
1122
+ - toast
1123
+ - useActiveBreakpoint
1124
+ - useApi
1125
+ - useBackendStatus
1126
+ - useBreakpoint
1127
+ - useConfirm
1128
+ - useDataTable
1129
+ - useLocalStorage
1130
+ - useMediaQuery
1131
+ - useMobileLayout
1132
+ - useTheme
1133
+ - useToast
1134
+ - warnInDev
1135
+
1136
+ ## Where to look next
1137
+
1138
+ - Type definitions: `dist/types/index.d.ts` (full prop shapes)
1139
+ - Source: https://github.com/bloomneo/uikit
1140
+ - Issues: https://github.com/bloomneo/uikit/issues