@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.
- package/CHANGELOG.md +222 -0
- package/LICENSE +21 -0
- package/README.md +513 -0
- package/bin/commands/build.js +232 -0
- package/bin/commands/bundle.js +587 -0
- package/bin/commands/create.js +768 -0
- package/bin/commands/deploy.js +533 -0
- package/bin/commands/generate.js +673 -0
- package/bin/commands/optimize.js +198 -0
- package/bin/commands/prerender.js +306 -0
- package/bin/commands/serve.js +216 -0
- package/bin/templates/fbca/README.md.template +130 -0
- package/bin/templates/fbca/docs/QUICKSTART_FBCA.md +368 -0
- package/bin/templates/fbca/docs/UIKIT_CLI_GUIDE.md +574 -0
- package/bin/templates/fbca/docs/UIKIT_COMPOSITE_UI_SYSTEM.md +649 -0
- package/bin/templates/fbca/docs/UIKIT_LLM_GUIDE.md +2055 -0
- package/bin/templates/fbca/docs/UIKIT_THEME_GUIDE.md +359 -0
- package/bin/templates/fbca/package.json.template +41 -0
- package/bin/templates/fbca/public/favicon.svg +10 -0
- package/bin/templates/fbca/public/hero_fbca.svg +1 -0
- package/bin/templates/fbca/src/utils/asset.ts +6 -0
- package/bin/templates/fbca/src/web/App.tsx.template +20 -0
- package/bin/templates/fbca/src/web/features/auth/pages/index.tsx.template +157 -0
- package/bin/templates/fbca/src/web/features/docs/pages/[...slug].tsx.template +83 -0
- package/bin/templates/fbca/src/web/features/gallery/hooks/useGallery.ts.template +74 -0
- package/bin/templates/fbca/src/web/features/gallery/pages/index.tsx.template +136 -0
- package/bin/templates/fbca/src/web/features/main/components/CTASection.tsx.template +43 -0
- package/bin/templates/fbca/src/web/features/main/pages/About.tsx.template +374 -0
- package/bin/templates/fbca/src/web/features/main/pages/index.tsx.template +214 -0
- package/bin/templates/fbca/src/web/index.html.template +15 -0
- package/bin/templates/fbca/src/web/lib/page-router.tsx.template +134 -0
- package/bin/templates/fbca/src/web/main.tsx.template +14 -0
- package/bin/templates/fbca/src/web/shared/components/Footer.tsx.template +57 -0
- package/bin/templates/fbca/src/web/shared/components/Header.tsx.template +91 -0
- package/bin/templates/fbca/src/web/shared/components/SEO.tsx.template +24 -0
- package/bin/templates/fbca/src/web/shared/components/index.ts.template +3 -0
- package/bin/templates/fbca/src/web/shared/hooks/useSEO.ts.template +85 -0
- package/bin/templates/fbca/src/web/shared/utils/asset.ts +6 -0
- package/bin/templates/fbca/src/web/styles/index.css.template +8 -0
- package/bin/templates/fbca/src/web/utils/asset.ts +6 -0
- package/bin/templates/fbca/tsconfig.json.template +32 -0
- package/bin/templates/fbca/tsconfig.node.json.template +10 -0
- package/bin/templates/fbca/vite.config.ts.template +38 -0
- package/bin/templates/generate/component/component.tsx.template +79 -0
- package/bin/templates/generate/component/index.ts.template +2 -0
- package/bin/templates/generate/component/types.ts.template +58 -0
- package/bin/templates/generate/feature/index.ts.template +14 -0
- package/bin/templates/generate/feature/list-page.tsx.template +34 -0
- package/bin/templates/generate/feature/main-component.tsx.template +37 -0
- package/bin/templates/generate/feature/main-page.tsx.template +30 -0
- package/bin/templates/generate/feature/types.ts.template +34 -0
- package/bin/templates/generate/hook/hook.ts.template +35 -0
- package/bin/templates/generate/index.css.template +10 -0
- package/bin/templates/generate/main.tsx.template +10 -0
- package/bin/templates/generate/page/index.ts.template +2 -0
- package/bin/templates/generate/page/page.tsx.template +86 -0
- package/bin/templates/generate/theme/README.md +31 -0
- package/bin/templates/generate/theme/theme.js.template +155 -0
- package/bin/templates/multi/README.md.template +120 -0
- package/bin/templates/multi/docs/QUICKSTART_MULTI.md +334 -0
- package/bin/templates/multi/docs/UIKIT_CLI_GUIDE.md +574 -0
- package/bin/templates/multi/docs/UIKIT_COMPOSITE_UI_SYSTEM.md +649 -0
- package/bin/templates/multi/docs/UIKIT_LLM_GUIDE.md +2055 -0
- package/bin/templates/multi/docs/UIKIT_THEME_GUIDE.md +359 -0
- package/bin/templates/multi/index.html.template +58 -0
- package/bin/templates/multi/package.json.template +35 -0
- package/bin/templates/multi/public/favicon.svg +10 -0
- package/bin/templates/multi/public/hero_multi.svg +1 -0
- package/bin/templates/multi/src/App.tsx.template +92 -0
- package/bin/templates/multi/src/components/Footer.tsx.template +58 -0
- package/bin/templates/multi/src/components/Header.tsx.template +103 -0
- package/bin/templates/multi/src/components/SEO.tsx.template +19 -0
- package/bin/templates/multi/src/components/index.ts.template +3 -0
- package/bin/templates/multi/src/hooks/useSEO.ts.template +38 -0
- package/bin/templates/multi/src/index.css.template +7 -0
- package/bin/templates/multi/src/main.tsx.template +14 -0
- package/bin/templates/multi/src/pages/About.tsx.template +276 -0
- package/bin/templates/multi/src/pages/Components.tsx.template +288 -0
- package/bin/templates/multi/src/pages/Contact.tsx.template +348 -0
- package/bin/templates/multi/src/pages/Dashboard.tsx.template +306 -0
- package/bin/templates/multi/src/pages/ErrorPage.tsx.template +37 -0
- package/bin/templates/multi/src/pages/Home.tsx.template +201 -0
- package/bin/templates/multi/src/pages/Login.tsx.template +148 -0
- package/bin/templates/multi/src/pages/Themes.tsx.template +207 -0
- package/bin/templates/multi/src/router.tsx.template +34 -0
- package/bin/templates/multi/src/utils/asset.ts +6 -0
- package/bin/templates/multi/tsconfig.json.template +30 -0
- package/bin/templates/multi/tsconfig.node.json +22 -0
- package/bin/templates/multi/vite.config.ts.template +36 -0
- package/bin/templates/single/README.md.template +131 -0
- package/bin/templates/single/docs/QUICKSTART_SINGLE.md +259 -0
- package/bin/templates/single/docs/UIKIT_CLI_GUIDE.md +574 -0
- package/bin/templates/single/docs/UIKIT_COMPOSITE_UI_SYSTEM.md +649 -0
- package/bin/templates/single/docs/UIKIT_LLM_GUIDE.md +2055 -0
- package/bin/templates/single/docs/UIKIT_THEME_GUIDE.md +359 -0
- package/bin/templates/single/index.html.template +37 -0
- package/bin/templates/single/package.json.template +34 -0
- package/bin/templates/single/public/favicon.svg +10 -0
- package/bin/templates/single/public/hero.svg +1 -0
- package/bin/templates/single/src/App.tsx.template +233 -0
- package/bin/templates/single/src/index.css.template +7 -0
- package/bin/templates/single/src/main.tsx.template +14 -0
- package/bin/templates/single/src/styles/fonts.css +99 -0
- package/bin/templates/single/src/utils/asset.ts +6 -0
- package/bin/templates/single/tsconfig.json +31 -0
- package/bin/templates/single/tsconfig.node.json +22 -0
- package/bin/templates/single/vite.config.ts.template +36 -0
- package/bin/templates/spa/README.md.template +105 -0
- package/bin/templates/spa/components/SEO.tsx.template +19 -0
- package/bin/templates/spa/docs/QUICKSTART_SPA.md +300 -0
- package/bin/templates/spa/docs/UIKIT_CLI_GUIDE.md +574 -0
- package/bin/templates/spa/docs/UIKIT_COMPOSITE_UI_SYSTEM.md +649 -0
- package/bin/templates/spa/docs/UIKIT_LLM_GUIDE.md +2055 -0
- package/bin/templates/spa/docs/UIKIT_THEME_GUIDE.md +359 -0
- package/bin/templates/spa/hooks/useSEO.ts.template +38 -0
- package/bin/templates/spa/index.html.template +58 -0
- package/bin/templates/spa/package.json.template +35 -0
- package/bin/templates/spa/public/favicon.svg +15 -0
- package/bin/templates/spa/public/hero_spa.svg +1 -0
- package/bin/templates/spa/src/App.tsx.template +659 -0
- package/bin/templates/spa/src/index.css.template +7 -0
- package/bin/templates/spa/src/main.tsx.template +14 -0
- package/bin/templates/spa/src/utils/asset.ts +6 -0
- package/bin/templates/spa/tsconfig.json.template +30 -0
- package/bin/templates/spa/tsconfig.node.json +22 -0
- package/bin/templates/spa/vite.config.ts.template +36 -0
- package/bin/uikit.js +133 -0
- package/cookbook/README.md +20 -0
- package/cookbook/crud-page.tsx +99 -0
- package/cookbook/dashboard.tsx +89 -0
- package/cookbook/delete-flow.tsx +59 -0
- package/cookbook/login.tsx +85 -0
- package/cookbook/settings.tsx +113 -0
- package/dist/Combination-C0DFrmJW.js +674 -0
- package/dist/Combination-C0DFrmJW.js.map +1 -0
- package/dist/accordion.js +284 -0
- package/dist/accordion.js.map +1 -0
- package/dist/admin.js +429 -0
- package/dist/admin.js.map +1 -0
- package/dist/alert.js +67 -0
- package/dist/alert.js.map +1 -0
- package/dist/auth.js +178 -0
- package/dist/auth.js.map +1 -0
- package/dist/avatar.js +249 -0
- package/dist/avatar.js.map +1 -0
- package/dist/badge.js +40 -0
- package/dist/badge.js.map +1 -0
- package/dist/blank.js +80 -0
- package/dist/blank.js.map +1 -0
- package/dist/breadcrumb.js +104 -0
- package/dist/breadcrumb.js.map +1 -0
- package/dist/button.js +50 -0
- package/dist/button.js.map +1 -0
- package/dist/calendar.js +2785 -0
- package/dist/calendar.js.map +1 -0
- package/dist/card.js +91 -0
- package/dist/card.js.map +1 -0
- package/dist/check-DXouwtzp.js +12 -0
- package/dist/check-DXouwtzp.js.map +1 -0
- package/dist/checkbox.js +268 -0
- package/dist/checkbox.js.map +1 -0
- package/dist/chevron-down-BORJtX8F.js +14 -0
- package/dist/chevron-down-BORJtX8F.js.map +1 -0
- package/dist/chevron-left-C1pkx4AF.js +14 -0
- package/dist/chevron-left-C1pkx4AF.js.map +1 -0
- package/dist/chevron-right-pz9eCjj-.js +14 -0
- package/dist/chevron-right-pz9eCjj-.js.map +1 -0
- package/dist/circle-DHOdTDQh.js +14 -0
- package/dist/circle-DHOdTDQh.js.map +1 -0
- package/dist/collapsible.js +35 -0
- package/dist/collapsible.js.map +1 -0
- package/dist/command.js +481 -0
- package/dist/command.js.map +1 -0
- package/dist/confirm-dialog.js +129 -0
- package/dist/confirm-dialog.js.map +1 -0
- package/dist/container.js +334 -0
- package/dist/container.js.map +1 -0
- package/dist/createLucideIcon-B45kRl5r.js +80 -0
- package/dist/createLucideIcon-B45kRl5r.js.map +1 -0
- package/dist/data-table.js +574 -0
- package/dist/data-table.js.map +1 -0
- package/dist/detail-page.js +454 -0
- package/dist/detail-page.js.map +1 -0
- package/dist/dialog.js +137 -0
- package/dist/dialog.js.map +1 -0
- package/dist/dropdown-menu.js +424 -0
- package/dist/dropdown-menu.js.map +1 -0
- package/dist/ellipsis-BhAoKPVk.js +16 -0
- package/dist/ellipsis-BhAoKPVk.js.map +1 -0
- package/dist/empty-state.js +54 -0
- package/dist/empty-state.js.map +1 -0
- package/dist/errors.js +36 -0
- package/dist/errors.js.map +1 -0
- package/dist/eye-DDKoW0KS.js +46 -0
- package/dist/eye-DDKoW0KS.js.map +1 -0
- package/dist/fonts/caveat-cyrillic-400-normal.woff +0 -0
- package/dist/fonts/caveat-cyrillic-400-normal.woff2 +0 -0
- package/dist/fonts/caveat-cyrillic-700-normal.woff +0 -0
- package/dist/fonts/caveat-cyrillic-700-normal.woff2 +0 -0
- package/dist/fonts/caveat-cyrillic-ext-400-normal.woff +0 -0
- package/dist/fonts/caveat-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/fonts/caveat-cyrillic-ext-700-normal.woff +0 -0
- package/dist/fonts/caveat-cyrillic-ext-700-normal.woff2 +0 -0
- package/dist/fonts/caveat-latin-400-normal.woff +0 -0
- package/dist/fonts/caveat-latin-400-normal.woff2 +0 -0
- package/dist/fonts/caveat-latin-700-normal.woff +0 -0
- package/dist/fonts/caveat-latin-700-normal.woff2 +0 -0
- package/dist/fonts/caveat-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/caveat-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/caveat-latin-ext-700-normal.woff +0 -0
- package/dist/fonts/caveat-latin-ext-700-normal.woff2 +0 -0
- package/dist/fonts/crimson-text-latin-400-normal.woff +0 -0
- package/dist/fonts/crimson-text-latin-400-normal.woff2 +0 -0
- package/dist/fonts/crimson-text-latin-600-normal.woff +0 -0
- package/dist/fonts/crimson-text-latin-600-normal.woff2 +0 -0
- package/dist/fonts/crimson-text-latin-700-normal.woff +0 -0
- package/dist/fonts/crimson-text-latin-700-normal.woff2 +0 -0
- package/dist/fonts/crimson-text-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/crimson-text-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/crimson-text-latin-ext-600-normal.woff +0 -0
- package/dist/fonts/crimson-text-latin-ext-600-normal.woff2 +0 -0
- package/dist/fonts/crimson-text-latin-ext-700-normal.woff +0 -0
- package/dist/fonts/crimson-text-latin-ext-700-normal.woff2 +0 -0
- package/dist/fonts/crimson-text-vietnamese-400-normal.woff +0 -0
- package/dist/fonts/crimson-text-vietnamese-400-normal.woff2 +0 -0
- package/dist/fonts/crimson-text-vietnamese-600-normal.woff +0 -0
- package/dist/fonts/crimson-text-vietnamese-600-normal.woff2 +0 -0
- package/dist/fonts/crimson-text-vietnamese-700-normal.woff +0 -0
- package/dist/fonts/crimson-text-vietnamese-700-normal.woff2 +0 -0
- package/dist/fonts/dm-serif-display-latin-400-normal.woff +0 -0
- package/dist/fonts/dm-serif-display-latin-400-normal.woff2 +0 -0
- package/dist/fonts/dm-serif-display-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/dm-serif-display-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/libre-baskerville-latin-400-normal.woff +0 -0
- package/dist/fonts/libre-baskerville-latin-400-normal.woff2 +0 -0
- package/dist/fonts/libre-baskerville-latin-700-normal.woff +0 -0
- package/dist/fonts/libre-baskerville-latin-700-normal.woff2 +0 -0
- package/dist/fonts/libre-baskerville-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/libre-baskerville-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/libre-baskerville-latin-ext-700-normal.woff +0 -0
- package/dist/fonts/libre-baskerville-latin-ext-700-normal.woff2 +0 -0
- package/dist/fonts/montserrat-cyrillic-400-normal.woff +0 -0
- package/dist/fonts/montserrat-cyrillic-400-normal.woff2 +0 -0
- package/dist/fonts/montserrat-cyrillic-500-normal.woff +0 -0
- package/dist/fonts/montserrat-cyrillic-500-normal.woff2 +0 -0
- package/dist/fonts/montserrat-cyrillic-600-normal.woff +0 -0
- package/dist/fonts/montserrat-cyrillic-600-normal.woff2 +0 -0
- package/dist/fonts/montserrat-cyrillic-ext-400-normal.woff +0 -0
- package/dist/fonts/montserrat-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/fonts/montserrat-cyrillic-ext-500-normal.woff +0 -0
- package/dist/fonts/montserrat-cyrillic-ext-500-normal.woff2 +0 -0
- package/dist/fonts/montserrat-cyrillic-ext-600-normal.woff +0 -0
- package/dist/fonts/montserrat-cyrillic-ext-600-normal.woff2 +0 -0
- package/dist/fonts/montserrat-latin-400-normal.woff +0 -0
- package/dist/fonts/montserrat-latin-400-normal.woff2 +0 -0
- package/dist/fonts/montserrat-latin-500-normal.woff +0 -0
- package/dist/fonts/montserrat-latin-500-normal.woff2 +0 -0
- package/dist/fonts/montserrat-latin-600-normal.woff +0 -0
- package/dist/fonts/montserrat-latin-600-normal.woff2 +0 -0
- package/dist/fonts/montserrat-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/montserrat-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/montserrat-latin-ext-500-normal.woff +0 -0
- package/dist/fonts/montserrat-latin-ext-500-normal.woff2 +0 -0
- package/dist/fonts/montserrat-latin-ext-600-normal.woff +0 -0
- package/dist/fonts/montserrat-latin-ext-600-normal.woff2 +0 -0
- package/dist/fonts/montserrat-vietnamese-400-normal.woff +0 -0
- package/dist/fonts/montserrat-vietnamese-400-normal.woff2 +0 -0
- package/dist/fonts/montserrat-vietnamese-500-normal.woff +0 -0
- package/dist/fonts/montserrat-vietnamese-500-normal.woff2 +0 -0
- package/dist/fonts/montserrat-vietnamese-600-normal.woff +0 -0
- package/dist/fonts/montserrat-vietnamese-600-normal.woff2 +0 -0
- package/dist/fonts/playfair-display-cyrillic-400-normal.woff +0 -0
- package/dist/fonts/playfair-display-cyrillic-400-normal.woff2 +0 -0
- package/dist/fonts/playfair-display-cyrillic-500-normal.woff +0 -0
- package/dist/fonts/playfair-display-cyrillic-500-normal.woff2 +0 -0
- package/dist/fonts/playfair-display-latin-400-normal.woff +0 -0
- package/dist/fonts/playfair-display-latin-400-normal.woff2 +0 -0
- package/dist/fonts/playfair-display-latin-500-normal.woff +0 -0
- package/dist/fonts/playfair-display-latin-500-normal.woff2 +0 -0
- package/dist/fonts/playfair-display-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/playfair-display-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/playfair-display-latin-ext-500-normal.woff +0 -0
- package/dist/fonts/playfair-display-latin-ext-500-normal.woff2 +0 -0
- package/dist/fonts/playfair-display-vietnamese-400-normal.woff +0 -0
- package/dist/fonts/playfair-display-vietnamese-400-normal.woff2 +0 -0
- package/dist/fonts/playfair-display-vietnamese-500-normal.woff +0 -0
- package/dist/fonts/playfair-display-vietnamese-500-normal.woff2 +0 -0
- package/dist/fonts/poppins-devanagari-400-normal.woff +0 -0
- package/dist/fonts/poppins-devanagari-400-normal.woff2 +0 -0
- package/dist/fonts/poppins-devanagari-500-normal.woff +0 -0
- package/dist/fonts/poppins-devanagari-500-normal.woff2 +0 -0
- package/dist/fonts/poppins-devanagari-600-normal.woff +0 -0
- package/dist/fonts/poppins-devanagari-600-normal.woff2 +0 -0
- package/dist/fonts/poppins-latin-400-normal.woff +0 -0
- package/dist/fonts/poppins-latin-400-normal.woff2 +0 -0
- package/dist/fonts/poppins-latin-500-normal.woff +0 -0
- package/dist/fonts/poppins-latin-500-normal.woff2 +0 -0
- package/dist/fonts/poppins-latin-600-normal.woff +0 -0
- package/dist/fonts/poppins-latin-600-normal.woff2 +0 -0
- package/dist/fonts/poppins-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/poppins-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/poppins-latin-ext-500-normal.woff +0 -0
- package/dist/fonts/poppins-latin-ext-500-normal.woff2 +0 -0
- package/dist/fonts/poppins-latin-ext-600-normal.woff +0 -0
- package/dist/fonts/poppins-latin-ext-600-normal.woff2 +0 -0
- package/dist/fonts/rubik-arabic-400-normal.woff +0 -0
- package/dist/fonts/rubik-arabic-400-normal.woff2 +0 -0
- package/dist/fonts/rubik-arabic-500-normal.woff +0 -0
- package/dist/fonts/rubik-arabic-500-normal.woff2 +0 -0
- package/dist/fonts/rubik-cyrillic-400-normal.woff +0 -0
- package/dist/fonts/rubik-cyrillic-400-normal.woff2 +0 -0
- package/dist/fonts/rubik-cyrillic-500-normal.woff +0 -0
- package/dist/fonts/rubik-cyrillic-500-normal.woff2 +0 -0
- package/dist/fonts/rubik-cyrillic-ext-400-normal.woff +0 -0
- package/dist/fonts/rubik-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/fonts/rubik-cyrillic-ext-500-normal.woff +0 -0
- package/dist/fonts/rubik-cyrillic-ext-500-normal.woff2 +0 -0
- package/dist/fonts/rubik-hebrew-400-normal.woff +0 -0
- package/dist/fonts/rubik-hebrew-400-normal.woff2 +0 -0
- package/dist/fonts/rubik-hebrew-500-normal.woff +0 -0
- package/dist/fonts/rubik-hebrew-500-normal.woff2 +0 -0
- package/dist/fonts/rubik-latin-400-normal.woff +0 -0
- package/dist/fonts/rubik-latin-400-normal.woff2 +0 -0
- package/dist/fonts/rubik-latin-500-normal.woff +0 -0
- package/dist/fonts/rubik-latin-500-normal.woff2 +0 -0
- package/dist/fonts/rubik-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/rubik-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/rubik-latin-ext-500-normal.woff +0 -0
- package/dist/fonts/rubik-latin-ext-500-normal.woff2 +0 -0
- package/dist/fonts/source-serif-pro-cyrillic-400-normal.woff +0 -0
- package/dist/fonts/source-serif-pro-cyrillic-400-normal.woff2 +0 -0
- package/dist/fonts/source-serif-pro-cyrillic-ext-400-normal.woff +0 -0
- package/dist/fonts/source-serif-pro-cyrillic-ext-400-normal.woff2 +0 -0
- package/dist/fonts/source-serif-pro-greek-400-normal.woff +0 -0
- package/dist/fonts/source-serif-pro-greek-400-normal.woff2 +0 -0
- package/dist/fonts/source-serif-pro-latin-400-normal.woff +0 -0
- package/dist/fonts/source-serif-pro-latin-400-normal.woff2 +0 -0
- package/dist/fonts/source-serif-pro-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/source-serif-pro-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/source-serif-pro-vietnamese-400-normal.woff +0 -0
- package/dist/fonts/source-serif-pro-vietnamese-400-normal.woff2 +0 -0
- package/dist/fonts/space-grotesk-latin-400-normal.woff +0 -0
- package/dist/fonts/space-grotesk-latin-400-normal.woff2 +0 -0
- package/dist/fonts/space-grotesk-latin-600-normal.woff +0 -0
- package/dist/fonts/space-grotesk-latin-600-normal.woff2 +0 -0
- package/dist/fonts/space-grotesk-latin-700-normal.woff +0 -0
- package/dist/fonts/space-grotesk-latin-700-normal.woff2 +0 -0
- package/dist/fonts/space-grotesk-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/space-grotesk-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/space-grotesk-latin-ext-600-normal.woff +0 -0
- package/dist/fonts/space-grotesk-latin-ext-600-normal.woff2 +0 -0
- package/dist/fonts/space-grotesk-latin-ext-700-normal.woff +0 -0
- package/dist/fonts/space-grotesk-latin-ext-700-normal.woff2 +0 -0
- package/dist/fonts/space-grotesk-vietnamese-400-normal.woff +0 -0
- package/dist/fonts/space-grotesk-vietnamese-400-normal.woff2 +0 -0
- package/dist/fonts/space-grotesk-vietnamese-600-normal.woff +0 -0
- package/dist/fonts/space-grotesk-vietnamese-600-normal.woff2 +0 -0
- package/dist/fonts/space-grotesk-vietnamese-700-normal.woff +0 -0
- package/dist/fonts/space-grotesk-vietnamese-700-normal.woff2 +0 -0
- package/dist/fonts/work-sans-latin-400-normal.woff +0 -0
- package/dist/fonts/work-sans-latin-400-normal.woff2 +0 -0
- package/dist/fonts/work-sans-latin-500-normal.woff +0 -0
- package/dist/fonts/work-sans-latin-500-normal.woff2 +0 -0
- package/dist/fonts/work-sans-latin-ext-400-normal.woff +0 -0
- package/dist/fonts/work-sans-latin-ext-400-normal.woff2 +0 -0
- package/dist/fonts/work-sans-latin-ext-500-normal.woff +0 -0
- package/dist/fonts/work-sans-latin-ext-500-normal.woff2 +0 -0
- package/dist/fonts/work-sans-vietnamese-400-normal.woff +0 -0
- package/dist/fonts/work-sans-vietnamese-400-normal.woff2 +0 -0
- package/dist/fonts/work-sans-vietnamese-500-normal.woff +0 -0
- package/dist/fonts/work-sans-vietnamese-500-normal.woff2 +0 -0
- package/dist/footer.js +308 -0
- package/dist/footer.js.map +1 -0
- package/dist/form-field.js +69 -0
- package/dist/form-field.js.map +1 -0
- package/dist/form.js +732 -0
- package/dist/form.js.map +1 -0
- package/dist/format.js +112 -0
- package/dist/format.js.map +1 -0
- package/dist/fouc.js +28 -0
- package/dist/fouc.js.map +1 -0
- package/dist/header.js +289 -0
- package/dist/header.js.map +1 -0
- package/dist/hooks.js +13 -0
- package/dist/hooks.js.map +1 -0
- package/dist/hover-card.js +210 -0
- package/dist/hover-card.js.map +1 -0
- package/dist/index-0ioNhtNM.js +11 -0
- package/dist/index-0ioNhtNM.js.map +1 -0
- package/dist/index-1QHKgw6D.js +55 -0
- package/dist/index-1QHKgw6D.js.map +1 -0
- package/dist/index-B6sSWi7l.js +747 -0
- package/dist/index-B6sSWi7l.js.map +1 -0
- package/dist/index-BCjJQGh8.js +71 -0
- package/dist/index-BCjJQGh8.js.map +1 -0
- package/dist/index-BGQepRFJ.js +28 -0
- package/dist/index-BGQepRFJ.js.map +1 -0
- package/dist/index-BVRIAMfe.js +37 -0
- package/dist/index-BVRIAMfe.js.map +1 -0
- package/dist/index-BY7PeRJA.js +145 -0
- package/dist/index-BY7PeRJA.js.map +1 -0
- package/dist/index-BZPx6jYI.js +9 -0
- package/dist/index-BZPx6jYI.js.map +1 -0
- package/dist/index-Ba4eHUBD.js +243 -0
- package/dist/index-Ba4eHUBD.js.map +1 -0
- package/dist/index-Bke1qZdk.js +35 -0
- package/dist/index-Bke1qZdk.js.map +1 -0
- package/dist/index-C0UREtMP.js +60 -0
- package/dist/index-C0UREtMP.js.map +1 -0
- package/dist/index-CCKe-Mpx.js +7 -0
- package/dist/index-CCKe-Mpx.js.map +1 -0
- package/dist/index-DFZozV_h.js +69 -0
- package/dist/index-DFZozV_h.js.map +1 -0
- package/dist/index-DFi6WydO.js +180 -0
- package/dist/index-DFi6WydO.js.map +1 -0
- package/dist/index-DQH6odE9.js +83 -0
- package/dist/index-DQH6odE9.js.map +1 -0
- package/dist/index-EO5flKM3.js +119 -0
- package/dist/index-EO5flKM3.js.map +1 -0
- package/dist/index-Lf7yDOXW.js +615 -0
- package/dist/index-Lf7yDOXW.js.map +1 -0
- package/dist/index-dhIqEbxW.js +1541 -0
- package/dist/index-dhIqEbxW.js.map +1 -0
- package/dist/index-pWhlqjff.js +32 -0
- package/dist/index-pWhlqjff.js.map +1 -0
- package/dist/index-rKs9bXHr.js +7 -0
- package/dist/index-rKs9bXHr.js.map +1 -0
- package/dist/index-xqkGMOJ8.js +14 -0
- package/dist/index-xqkGMOJ8.js.map +1 -0
- package/dist/index.js +247 -0
- package/dist/index.js.map +1 -0
- package/dist/input.js +22 -0
- package/dist/input.js.map +1 -0
- package/dist/label.js +36 -0
- package/dist/label.js.map +1 -0
- package/dist/layout-wrapper.js +208 -0
- package/dist/layout-wrapper.js.map +1 -0
- package/dist/llms.txt +1140 -0
- package/dist/menu-DBhEanGo.js +16 -0
- package/dist/menu-DBhEanGo.js.map +1 -0
- package/dist/menubar.js +565 -0
- package/dist/menubar.js.map +1 -0
- package/dist/mobile.js +183 -0
- package/dist/mobile.js.map +1 -0
- package/dist/motion.js +119 -0
- package/dist/motion.js.map +1 -0
- package/dist/page-header.js +47 -0
- package/dist/page-header.js.map +1 -0
- package/dist/page.js +214 -0
- package/dist/page.js.map +1 -0
- package/dist/pagination.js +121 -0
- package/dist/pagination.js.map +1 -0
- package/dist/platform.js +194 -0
- package/dist/platform.js.map +1 -0
- package/dist/popover.js +263 -0
- package/dist/popover.js.map +1 -0
- package/dist/popup.js +335 -0
- package/dist/popup.js.map +1 -0
- package/dist/progress.js +108 -0
- package/dist/progress.js.map +1 -0
- package/dist/radio-group.js +272 -0
- package/dist/radio-group.js.map +1 -0
- package/dist/safe-area.js +42 -0
- package/dist/safe-area.js.map +1 -0
- package/dist/search-CpUwRnG-.js +15 -0
- package/dist/search-CpUwRnG-.js.map +1 -0
- package/dist/select.js +985 -0
- package/dist/select.js.map +1 -0
- package/dist/separator.js +45 -0
- package/dist/separator.js.map +1 -0
- package/dist/sheet.js +127 -0
- package/dist/sheet.js.map +1 -0
- package/dist/skeleton.js +16 -0
- package/dist/skeleton.js.map +1 -0
- package/dist/slider.js +485 -0
- package/dist/slider.js.map +1 -0
- package/dist/sonner.js +52 -0
- package/dist/sonner.js.map +1 -0
- package/dist/styles/fonts.css +253 -0
- package/dist/styles.css +2 -0
- package/dist/switch.js +155 -0
- package/dist/switch.js.map +1 -0
- package/dist/tab-bar.js +110 -0
- package/dist/tab-bar.js.map +1 -0
- package/dist/table.js +115 -0
- package/dist/table.js.map +1 -0
- package/dist/tabs.js +218 -0
- package/dist/tabs.js.map +1 -0
- package/dist/textarea.js +19 -0
- package/dist/textarea.js.map +1 -0
- package/dist/theme-provider.js +154 -0
- package/dist/theme-provider.js.map +1 -0
- package/dist/themes.js +873 -0
- package/dist/themes.js.map +1 -0
- package/dist/toast.js +63 -0
- package/dist/toast.js.map +1 -0
- package/dist/toggle.js +70 -0
- package/dist/toggle.js.map +1 -0
- package/dist/tooltip.js +375 -0
- package/dist/tooltip.js.map +1 -0
- package/dist/types/App.d.ts +3 -0
- package/dist/types/App.d.ts.map +1 -0
- package/dist/types/components/layouts/admin.d.ts +117 -0
- package/dist/types/components/layouts/admin.d.ts.map +1 -0
- package/dist/types/components/layouts/auth.d.ts +17 -0
- package/dist/types/components/layouts/auth.d.ts.map +1 -0
- package/dist/types/components/layouts/blank.d.ts +63 -0
- package/dist/types/components/layouts/blank.d.ts.map +1 -0
- package/dist/types/components/layouts/layout-wrapper.d.ts +130 -0
- package/dist/types/components/layouts/layout-wrapper.d.ts.map +1 -0
- package/dist/types/components/layouts/mobile.d.ts +91 -0
- package/dist/types/components/layouts/mobile.d.ts.map +1 -0
- package/dist/types/components/layouts/page.d.ts +181 -0
- package/dist/types/components/layouts/page.d.ts.map +1 -0
- package/dist/types/components/layouts/popup.d.ts +100 -0
- package/dist/types/components/layouts/popup.d.ts.map +1 -0
- package/dist/types/components/sections/container.d.ts +79 -0
- package/dist/types/components/sections/container.d.ts.map +1 -0
- package/dist/types/components/sections/footer.d.ts +128 -0
- package/dist/types/components/sections/footer.d.ts.map +1 -0
- package/dist/types/components/sections/header.d.ts +72 -0
- package/dist/types/components/sections/header.d.ts.map +1 -0
- package/dist/types/components/sections/safe-area.d.ts +46 -0
- package/dist/types/components/sections/safe-area.d.ts.map +1 -0
- package/dist/types/components/sections/tab-bar.d.ts +61 -0
- package/dist/types/components/sections/tab-bar.d.ts.map +1 -0
- package/dist/types/components/ui/accordion.d.ts +8 -0
- package/dist/types/components/ui/accordion.d.ts.map +1 -0
- package/dist/types/components/ui/alert.d.ts +10 -0
- package/dist/types/components/ui/alert.d.ts.map +1 -0
- package/dist/types/components/ui/avatar.d.ts +7 -0
- package/dist/types/components/ui/avatar.d.ts.map +1 -0
- package/dist/types/components/ui/badge.d.ts +10 -0
- package/dist/types/components/ui/badge.d.ts.map +1 -0
- package/dist/types/components/ui/breadcrumb.d.ts +12 -0
- package/dist/types/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/types/components/ui/button.d.ts +11 -0
- package/dist/types/components/ui/button.d.ts.map +1 -0
- package/dist/types/components/ui/calendar.d.ts +9 -0
- package/dist/types/components/ui/calendar.d.ts.map +1 -0
- package/dist/types/components/ui/card.d.ts +10 -0
- package/dist/types/components/ui/card.d.ts.map +1 -0
- package/dist/types/components/ui/checkbox.d.ts +5 -0
- package/dist/types/components/ui/checkbox.d.ts.map +1 -0
- package/dist/types/components/ui/collapsible.d.ts +6 -0
- package/dist/types/components/ui/collapsible.d.ts.map +1 -0
- package/dist/types/components/ui/command.d.ts +19 -0
- package/dist/types/components/ui/command.d.ts.map +1 -0
- package/dist/types/components/ui/confirm-dialog.d.ts +72 -0
- package/dist/types/components/ui/confirm-dialog.d.ts.map +1 -0
- package/dist/types/components/ui/data-table.d.ts +211 -0
- package/dist/types/components/ui/data-table.d.ts.map +1 -0
- package/dist/types/components/ui/detail-page.d.ts +119 -0
- package/dist/types/components/ui/detail-page.d.ts.map +1 -0
- package/dist/types/components/ui/dialog.d.ts +16 -0
- package/dist/types/components/ui/dialog.d.ts.map +1 -0
- package/dist/types/components/ui/dropdown-menu.d.ts +26 -0
- package/dist/types/components/ui/dropdown-menu.d.ts.map +1 -0
- package/dist/types/components/ui/empty-state.d.ts +30 -0
- package/dist/types/components/ui/empty-state.d.ts.map +1 -0
- package/dist/types/components/ui/form-field.d.ts +57 -0
- package/dist/types/components/ui/form-field.d.ts.map +1 -0
- package/dist/types/components/ui/form.d.ts +185 -0
- package/dist/types/components/ui/form.d.ts.map +1 -0
- package/dist/types/components/ui/hover-card.d.ts +7 -0
- package/dist/types/components/ui/hover-card.d.ts.map +1 -0
- package/dist/types/components/ui/input.d.ts +4 -0
- package/dist/types/components/ui/input.d.ts.map +1 -0
- package/dist/types/components/ui/label.d.ts +5 -0
- package/dist/types/components/ui/label.d.ts.map +1 -0
- package/dist/types/components/ui/menubar.d.ts +27 -0
- package/dist/types/components/ui/menubar.d.ts.map +1 -0
- package/dist/types/components/ui/motion.d.ts +130 -0
- package/dist/types/components/ui/motion.d.ts.map +1 -0
- package/dist/types/components/ui/page-header.d.ts +45 -0
- package/dist/types/components/ui/page-header.d.ts.map +1 -0
- package/dist/types/components/ui/pagination.d.ts +14 -0
- package/dist/types/components/ui/pagination.d.ts.map +1 -0
- package/dist/types/components/ui/popover.d.ts +8 -0
- package/dist/types/components/ui/popover.d.ts.map +1 -0
- package/dist/types/components/ui/progress.d.ts +5 -0
- package/dist/types/components/ui/progress.d.ts.map +1 -0
- package/dist/types/components/ui/radio-group.d.ts +6 -0
- package/dist/types/components/ui/radio-group.d.ts.map +1 -0
- package/dist/types/components/ui/select.d.ts +16 -0
- package/dist/types/components/ui/select.d.ts.map +1 -0
- package/dist/types/components/ui/separator.d.ts +5 -0
- package/dist/types/components/ui/separator.d.ts.map +1 -0
- package/dist/types/components/ui/sheet.d.ts +14 -0
- package/dist/types/components/ui/sheet.d.ts.map +1 -0
- package/dist/types/components/ui/skeleton.d.ts +3 -0
- package/dist/types/components/ui/skeleton.d.ts.map +1 -0
- package/dist/types/components/ui/slider.d.ts +5 -0
- package/dist/types/components/ui/slider.d.ts.map +1 -0
- package/dist/types/components/ui/sonner.d.ts +4 -0
- package/dist/types/components/ui/sonner.d.ts.map +1 -0
- package/dist/types/components/ui/switch.d.ts +5 -0
- package/dist/types/components/ui/switch.d.ts.map +1 -0
- package/dist/types/components/ui/table.d.ts +11 -0
- package/dist/types/components/ui/table.d.ts.map +1 -0
- package/dist/types/components/ui/tabs.d.ts +8 -0
- package/dist/types/components/ui/tabs.d.ts.map +1 -0
- package/dist/types/components/ui/textarea.d.ts +4 -0
- package/dist/types/components/ui/textarea.d.ts.map +1 -0
- package/dist/types/components/ui/toast.d.ts +70 -0
- package/dist/types/components/ui/toast.d.ts.map +1 -0
- package/dist/types/components/ui/toggle.d.ts +10 -0
- package/dist/types/components/ui/toggle.d.ts.map +1 -0
- package/dist/types/components/ui/tooltip.d.ts +8 -0
- package/dist/types/components/ui/tooltip.d.ts.map +1 -0
- package/dist/types/hooks/index.d.ts +14 -0
- package/dist/types/hooks/index.d.ts.map +1 -0
- package/dist/types/hooks/useApi.d.ts +38 -0
- package/dist/types/hooks/useApi.d.ts.map +1 -0
- package/dist/types/hooks/useBreakpoint.d.ts +35 -0
- package/dist/types/hooks/useBreakpoint.d.ts.map +1 -0
- package/dist/types/hooks/useDataTable.d.ts +59 -0
- package/dist/types/hooks/useDataTable.d.ts.map +1 -0
- package/dist/types/hooks/useMediaQuery.d.ts +12 -0
- package/dist/types/hooks/useMediaQuery.d.ts.map +1 -0
- package/dist/types/hooks/useStorage.d.ts +35 -0
- package/dist/types/hooks/useStorage.d.ts.map +1 -0
- package/dist/types/index.d.ts +75 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/lib/errors.d.ts +37 -0
- package/dist/types/lib/errors.d.ts.map +1 -0
- package/dist/types/lib/format.d.ts +80 -0
- package/dist/types/lib/format.d.ts.map +1 -0
- package/dist/types/lib/fouc.d.ts +64 -0
- package/dist/types/lib/fouc.d.ts.map +1 -0
- package/dist/types/lib/platform.d.ts +156 -0
- package/dist/types/lib/platform.d.ts.map +1 -0
- package/dist/types/lib/utils.d.ts +14 -0
- package/dist/types/lib/utils.d.ts.map +1 -0
- package/dist/types/main.d.ts +2 -0
- package/dist/types/main.d.ts.map +1 -0
- package/dist/types/themes/index.d.ts +499 -0
- package/dist/types/themes/index.d.ts.map +1 -0
- package/dist/types/themes/presets/base.d.ts +108 -0
- package/dist/types/themes/presets/base.d.ts.map +1 -0
- package/dist/types/themes/presets/elegant.d.ts +108 -0
- package/dist/types/themes/presets/elegant.d.ts.map +1 -0
- package/dist/types/themes/presets/metro.d.ts +114 -0
- package/dist/types/themes/presets/metro.d.ts.map +1 -0
- package/dist/types/themes/presets/studio.d.ts +115 -0
- package/dist/types/themes/presets/studio.d.ts.map +1 -0
- package/dist/types/themes/presets/vivid.d.ts +115 -0
- package/dist/types/themes/presets/vivid.d.ts.map +1 -0
- package/dist/types/themes/theme-provider.d.ts +122 -0
- package/dist/types/themes/theme-provider.d.ts.map +1 -0
- package/dist/types/types/index.d.ts +813 -0
- package/dist/types/types/index.d.ts.map +1 -0
- package/dist/uikit.css +1 -0
- package/dist/useDataTable-CPiBpEg-.js +254 -0
- package/dist/useDataTable-CPiBpEg-.js.map +1 -0
- package/dist/utils-CwJPJKOE.js +2278 -0
- package/dist/utils-CwJPJKOE.js.map +1 -0
- package/dist/utils.js +5 -0
- package/dist/utils.js.map +1 -0
- package/dist/wrapper.js +13 -0
- package/dist/wrapper.js.map +1 -0
- package/dist/x-BxwubQiM.js +15 -0
- package/dist/x-BxwubQiM.js.map +1 -0
- package/examples/README.md +18 -0
- package/examples/button.tsx +16 -0
- package/examples/confirm-dialog.tsx +44 -0
- package/examples/data-table.tsx +35 -0
- package/examples/dialog.tsx +34 -0
- package/examples/empty-state.tsx +13 -0
- package/examples/form-field.tsx +22 -0
- package/examples/format.tsx +19 -0
- package/examples/page-header.tsx +17 -0
- package/examples/skeleton.tsx +12 -0
- package/examples/theme-provider.tsx +33 -0
- package/examples/toast.tsx +32 -0
- package/examples/use-breakpoint.tsx +17 -0
- package/llms.txt +1140 -0
- package/package.json +430 -0
|
@@ -0,0 +1,216 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview UIKit Serve Command - Development server management
|
|
3
|
+
* @description Smart Vite server with port management and process cleanup
|
|
4
|
+
* @package @bloomneo/uikit
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { spawn, exec } from 'child_process';
|
|
8
|
+
import { promisify } from 'util';
|
|
9
|
+
import fs from 'fs';
|
|
10
|
+
import path from 'path';
|
|
11
|
+
|
|
12
|
+
const execAsync = promisify(exec);
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Start development server with smart port management
|
|
16
|
+
*/
|
|
17
|
+
export async function startServer(options) {
|
|
18
|
+
console.log('🚀 UIKit Development Server\n');
|
|
19
|
+
|
|
20
|
+
try {
|
|
21
|
+
// Check if we're in a valid project
|
|
22
|
+
await validateProject();
|
|
23
|
+
|
|
24
|
+
// Handle port management
|
|
25
|
+
const port = parseInt(options.port) || 5173;
|
|
26
|
+
|
|
27
|
+
if (options.restart) {
|
|
28
|
+
console.log('🔄 Cleaning up existing processes...');
|
|
29
|
+
await killProcessOnPort(port);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
const availablePort = await findAvailablePort(port);
|
|
33
|
+
|
|
34
|
+
if (availablePort !== port) {
|
|
35
|
+
console.log(`⚡ Port ${port} in use, using port ${availablePort}`);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Bundle themes first
|
|
39
|
+
console.log('🎨 Bundling themes...');
|
|
40
|
+
await bundleThemesIfNeeded();
|
|
41
|
+
|
|
42
|
+
// Start Vite server
|
|
43
|
+
console.log(`✅ Starting server on http://localhost:${availablePort}\n`);
|
|
44
|
+
|
|
45
|
+
const viteArgs = [
|
|
46
|
+
'vite',
|
|
47
|
+
'--port', availablePort.toString(),
|
|
48
|
+
'--host', '0.0.0.0'
|
|
49
|
+
];
|
|
50
|
+
|
|
51
|
+
if (options.open) {
|
|
52
|
+
viteArgs.push('--open');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
const viteProcess = spawn('npx', viteArgs, {
|
|
56
|
+
stdio: 'inherit',
|
|
57
|
+
cwd: process.cwd(),
|
|
58
|
+
env: { ...process.env, FORCE_COLOR: '1' }
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Handle process termination
|
|
62
|
+
process.on('SIGINT', () => {
|
|
63
|
+
console.log('\n🛑 Shutting down server...');
|
|
64
|
+
viteProcess.kill();
|
|
65
|
+
process.exit(0);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
process.on('SIGTERM', () => {
|
|
69
|
+
viteProcess.kill();
|
|
70
|
+
process.exit(0);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
viteProcess.on('close', (code) => {
|
|
74
|
+
if (code !== 0) {
|
|
75
|
+
console.error(`❌ Server exited with code ${code}`);
|
|
76
|
+
process.exit(code);
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
viteProcess.on('error', (error) => {
|
|
81
|
+
console.error('❌ Failed to start server:', error.message);
|
|
82
|
+
process.exit(1);
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
} catch (error) {
|
|
86
|
+
console.error('❌ Serve command failed:', error.message);
|
|
87
|
+
process.exit(1);
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Validate that we're in a valid UIKit project
|
|
93
|
+
*/
|
|
94
|
+
async function validateProject() {
|
|
95
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
96
|
+
const indexHtmlPath = path.join(process.cwd(), 'index.html');
|
|
97
|
+
const fbcaIndexHtmlPath = path.join(process.cwd(), 'src/web/index.html');
|
|
98
|
+
|
|
99
|
+
if (!fs.existsSync(packageJsonPath)) {
|
|
100
|
+
throw new Error('No package.json found. Run this command in a project directory.');
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Check for index.html in standard location or FBCA location
|
|
104
|
+
if (!fs.existsSync(indexHtmlPath) && !fs.existsSync(fbcaIndexHtmlPath)) {
|
|
105
|
+
throw new Error('No index.html found. This doesn\'t appear to be a Vite project.');
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Check if it's a UIKit project
|
|
109
|
+
try {
|
|
110
|
+
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
111
|
+
const hasUIKit = packageJson.dependencies?.['@bloomneo/uikit'] ||
|
|
112
|
+
packageJson.devDependencies?.['@bloomneo/uikit'];
|
|
113
|
+
|
|
114
|
+
if (!hasUIKit) {
|
|
115
|
+
console.log('💡 This project doesn\'t use @bloomneo/uikit. Server will start anyway.');
|
|
116
|
+
}
|
|
117
|
+
} catch (error) {
|
|
118
|
+
// Invalid package.json, but let Vite handle it
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Kill process running on specific port
|
|
124
|
+
*/
|
|
125
|
+
async function killProcessOnPort(port) {
|
|
126
|
+
try {
|
|
127
|
+
// For Unix/Linux/macOS
|
|
128
|
+
if (process.platform !== 'win32') {
|
|
129
|
+
await execAsync(`lsof -ti:${port} | xargs kill -9`).catch(() => {
|
|
130
|
+
// No process found, which is fine
|
|
131
|
+
});
|
|
132
|
+
} else {
|
|
133
|
+
// For Windows
|
|
134
|
+
await execAsync(`netstat -ano | findstr :${port}`).then(async (result) => {
|
|
135
|
+
const lines = result.stdout.split('\\n');
|
|
136
|
+
for (const line of lines) {
|
|
137
|
+
const match = line.match(/\\s+(\\d+)$/);
|
|
138
|
+
if (match) {
|
|
139
|
+
const pid = match[1];
|
|
140
|
+
await execAsync(`taskkill /F /PID ${pid}`).catch(() => {
|
|
141
|
+
// Process might already be dead
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}).catch(() => {
|
|
146
|
+
// No process found
|
|
147
|
+
});
|
|
148
|
+
}
|
|
149
|
+
} catch (error) {
|
|
150
|
+
// Ignore errors in process cleanup
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Find available port starting from the given port
|
|
156
|
+
*/
|
|
157
|
+
async function findAvailablePort(startPort) {
|
|
158
|
+
for (let port = startPort; port <= startPort + 10; port++) {
|
|
159
|
+
if (await isPortAvailable(port)) {
|
|
160
|
+
return port;
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
throw new Error(`No available ports found starting from ${startPort}`);
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Check if port is available
|
|
168
|
+
*/
|
|
169
|
+
async function isPortAvailable(port) {
|
|
170
|
+
try {
|
|
171
|
+
if (process.platform !== 'win32') {
|
|
172
|
+
const result = await execAsync(`lsof -i:${port}`);
|
|
173
|
+
return false; // Port is in use
|
|
174
|
+
} else {
|
|
175
|
+
const result = await execAsync(`netstat -an | findstr :${port}`);
|
|
176
|
+
return false; // Port is in use
|
|
177
|
+
}
|
|
178
|
+
} catch (error) {
|
|
179
|
+
return true; // Port is available (command failed = no process using it)
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* Bundle themes if theme files exist
|
|
185
|
+
*/
|
|
186
|
+
async function bundleThemesIfNeeded() {
|
|
187
|
+
const themeDirs = [
|
|
188
|
+
'src/themes/presets',
|
|
189
|
+
'src/web/assets/themes/presets',
|
|
190
|
+
'themes/presets'
|
|
191
|
+
];
|
|
192
|
+
|
|
193
|
+
let hasThemes = false;
|
|
194
|
+
for (const dir of themeDirs) {
|
|
195
|
+
if (fs.existsSync(dir)) {
|
|
196
|
+
const files = fs.readdirSync(dir).filter(f =>
|
|
197
|
+
f.endsWith('.js') || f.endsWith('.ts')
|
|
198
|
+
);
|
|
199
|
+
if (files.length > 0) {
|
|
200
|
+
hasThemes = true;
|
|
201
|
+
break;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (hasThemes) {
|
|
207
|
+
try {
|
|
208
|
+
// Import and run bundle command
|
|
209
|
+
const { bundleThemes } = await import('./bundle.js');
|
|
210
|
+
await bundleThemes({ output: 'src/styles/globals.css' });
|
|
211
|
+
console.log('✅ Themes bundled successfully');
|
|
212
|
+
} catch (error) {
|
|
213
|
+
console.log('⚠️ Theme bundling failed, continuing without themes:', error.message);
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
# {{PROJECT_NAME}}
|
|
2
|
+
|
|
3
|
+
**A modern React FBCA Application built with @bloomneo/uikit**
|
|
4
|
+
|
|
5
|
+
## 🚀 Quick Start
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
# Install dependencies
|
|
9
|
+
npm install
|
|
10
|
+
|
|
11
|
+
# Start development server
|
|
12
|
+
npm run dev
|
|
13
|
+
|
|
14
|
+
# Build for production
|
|
15
|
+
npm run build
|
|
16
|
+
|
|
17
|
+
# Preview production build
|
|
18
|
+
npm run preview
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## 🎨 UIKit FBCA Features
|
|
22
|
+
|
|
23
|
+
This Feature-Based Component Architecture application is built with [@bloomneo/uikit](https://github.com/bloomneo/uikit) featuring:
|
|
24
|
+
|
|
25
|
+
- **37 UI Components** - Forms, tables, navigation, overlays, and more
|
|
26
|
+
- **5 Professional Themes** - Base, Elegant, Metro, Studio, Vivid
|
|
27
|
+
- **5 Layout Systems** - Admin, Auth, Page, Popup, Blank layouts
|
|
28
|
+
- **FBCA Architecture** - Scalable feature-based organization
|
|
29
|
+
- **Theme System** - Light/dark mode with semantic OKLCH colors
|
|
30
|
+
- **TypeScript Support** - Full type safety out of the box
|
|
31
|
+
- **SEO Optimization** - Built-in SEO components and hooks
|
|
32
|
+
|
|
33
|
+
## 🏗️ Project Structure (FBCA)
|
|
34
|
+
|
|
35
|
+
```
|
|
36
|
+
{{PROJECT_NAME}}/
|
|
37
|
+
├── src/web/
|
|
38
|
+
│ ├── App.tsx # Main application component
|
|
39
|
+
│ ├── main.tsx # Application entry point
|
|
40
|
+
│ ├── index.html # HTML entry point
|
|
41
|
+
│ ├── styles/
|
|
42
|
+
│ │ └── index.css # Tailwind CSS v4+ and UIKit styles
|
|
43
|
+
│ ├── lib/
|
|
44
|
+
│ │ └── page-router.tsx # Custom router implementation
|
|
45
|
+
│ ├── features/ # Feature-based organization
|
|
46
|
+
│ │ ├── main/ # Main feature
|
|
47
|
+
│ │ │ ├── pages/ # Feature pages
|
|
48
|
+
│ │ │ └── components/ # Feature components
|
|
49
|
+
│ │ ├── auth/ # Authentication feature
|
|
50
|
+
│ │ ├── gallery/ # Gallery feature
|
|
51
|
+
│ │ └── docs/ # Documentation feature
|
|
52
|
+
│ ├── shared/ # Shared components and utilities
|
|
53
|
+
│ │ ├── components/ # Shared components
|
|
54
|
+
│ │ │ ├── Header.tsx # Navigation header
|
|
55
|
+
│ │ │ ├── Footer.tsx # Footer component
|
|
56
|
+
│ │ │ ├── SEO.tsx # SEO component
|
|
57
|
+
│ │ │ └── index.ts # Component exports
|
|
58
|
+
│ │ └── hooks/ # Shared hooks
|
|
59
|
+
│ │ └── useSEO.ts # SEO hook
|
|
60
|
+
│ └── utils/
|
|
61
|
+
│ └── asset.ts # Asset utility for deployment paths
|
|
62
|
+
├── public/ # Static assets
|
|
63
|
+
├── docs/ # Documentation guides
|
|
64
|
+
├── package.json # Dependencies and scripts
|
|
65
|
+
└── README.md # This file
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## 🎯 Development Commands
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
npm run dev # Start development server (localhost:5173)
|
|
72
|
+
npm run build # Build for production
|
|
73
|
+
npm run preview # Preview production build
|
|
74
|
+
npm run deploy:gh # Deploy to GitHub Pages
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## 🎨 Theme Customization
|
|
78
|
+
|
|
79
|
+
Change your theme by updating the ThemeProvider in `src/web/main.tsx`:
|
|
80
|
+
|
|
81
|
+
```jsx
|
|
82
|
+
<ThemeProvider theme="elegant" mode="light">
|
|
83
|
+
<App />
|
|
84
|
+
</ThemeProvider>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Available themes: `base` | `elegant` | `metro` | `studio` | `vivid`
|
|
88
|
+
Available modes: `light` | `dark`
|
|
89
|
+
|
|
90
|
+
## 📦 Built With
|
|
91
|
+
|
|
92
|
+
- **[React 19](https://react.dev)** - UI library
|
|
93
|
+
- **[TypeScript](https://typescriptlang.org)** - Type safety
|
|
94
|
+
- **[Vite](https://vitejs.dev)** - Build tool and dev server
|
|
95
|
+
- **[Tailwind CSS v4+](https://tailwindcss.com)** - Utility-first CSS framework
|
|
96
|
+
- **[@bloomneo/uikit](https://github.com/bloomneo/uikit)** - UI components and layouts
|
|
97
|
+
- **[Lucide React](https://lucide.dev)** - Icon library
|
|
98
|
+
|
|
99
|
+
## 🏗️ FBCA Architecture
|
|
100
|
+
|
|
101
|
+
The Feature-Based Component Architecture (FBCA) organizes code by features rather than technical layers:
|
|
102
|
+
|
|
103
|
+
- **Features** - Self-contained feature modules
|
|
104
|
+
- **Shared** - Reusable components and utilities
|
|
105
|
+
- **Lib** - Custom libraries and utilities
|
|
106
|
+
- **Scalable** - Easy to add new features and maintain
|
|
107
|
+
|
|
108
|
+
## 🌐 Asset Management
|
|
109
|
+
|
|
110
|
+
Use the included asset utility for deployment-friendly paths:
|
|
111
|
+
|
|
112
|
+
```jsx
|
|
113
|
+
import { asset } from '../utils/asset';
|
|
114
|
+
|
|
115
|
+
// Works in both development and production deployments
|
|
116
|
+
<img src={asset('/images/hero.jpg')} alt="Hero" />
|
|
117
|
+
<link rel="icon" href={asset('/favicon.ico')} />
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
## 📚 Resources
|
|
121
|
+
|
|
122
|
+
- **[UIKit Documentation](https://docs.anthropic.com/en/docs/claude-code/claude_code_docs_map.md)** - Complete component reference
|
|
123
|
+
- **[UIKit LLM Guide](./docs/UIKIT_LLM_GUIDE.md)** - Comprehensive usage guide
|
|
124
|
+
- **[React Documentation](https://react.dev)** - React framework guide
|
|
125
|
+
- **[Vite Documentation](https://vitejs.dev)** - Build tool documentation
|
|
126
|
+
- **[FBCA Guide](./docs/QUICKSTART_FBCA.md)** - Feature-based architecture guide
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
**Built with ❤️ using [@bloomneo/uikit](https://github.com/bloomneo/uikit)** ✨
|
|
@@ -0,0 +1,368 @@
|
|
|
1
|
+
# Quick Start: FBCA Template
|
|
2
|
+
|
|
3
|
+
**Feature-Based Component Architecture with auto-discovery routing - perfect for scalable enterprise applications.**
|
|
4
|
+
|
|
5
|
+
## 🎯 What is FBCA Template?
|
|
6
|
+
|
|
7
|
+
FBCA (Feature-Based Component Architecture) organizes code by business features instead of file types. Each feature is self-contained with its own pages, components, and hooks. Routes are automatically discovered from your file structure - no manual route configuration needed.
|
|
8
|
+
|
|
9
|
+
**Perfect for:**
|
|
10
|
+
- Enterprise applications with multiple features
|
|
11
|
+
- Large teams working on different features
|
|
12
|
+
- Long-term projects that need to scale
|
|
13
|
+
- Applications with 10+ distinct feature areas
|
|
14
|
+
- Projects requiring feature isolation and modularity
|
|
15
|
+
|
|
16
|
+
## ⚡ 30-Second Setup
|
|
17
|
+
|
|
18
|
+
### Step 1: Install UIKit CLI Globally
|
|
19
|
+
```bash
|
|
20
|
+
npm install -g @bloomneo/uikit
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### Step 2: Create FBCA Project
|
|
24
|
+
```bash
|
|
25
|
+
uikit create my-fbca-app --fbca --theme elegant
|
|
26
|
+
cd my-fbca-app && npm run dev
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
### Step 3: Project Structure
|
|
30
|
+
```
|
|
31
|
+
src/
|
|
32
|
+
└── web/
|
|
33
|
+
├── App.tsx # Root app with theme provider
|
|
34
|
+
├── main.tsx # Entry point
|
|
35
|
+
├── index.html # HTML template
|
|
36
|
+
├── lib/
|
|
37
|
+
│ └── page-router.tsx # Auto-discovery routing engine
|
|
38
|
+
├── features/
|
|
39
|
+
│ ├── main/
|
|
40
|
+
│ │ ├── pages/
|
|
41
|
+
│ │ │ ├── index.tsx # Route: / (homepage)
|
|
42
|
+
│ │ │ └── About.tsx # Route: /about
|
|
43
|
+
│ │ └── components/
|
|
44
|
+
│ │ └── CTASection.tsx # Feature-specific components
|
|
45
|
+
│ ├── auth/
|
|
46
|
+
│ │ └── pages/
|
|
47
|
+
│ │ └── index.tsx # Route: /auth (login)
|
|
48
|
+
│ ├── gallery/
|
|
49
|
+
│ │ ├── pages/
|
|
50
|
+
│ │ │ └── index.tsx # Route: /gallery
|
|
51
|
+
│ │ └── hooks/
|
|
52
|
+
│ │ └── useGallery.ts # Feature-specific logic
|
|
53
|
+
│ └── docs/
|
|
54
|
+
│ └── pages/
|
|
55
|
+
│ └── [...slug].tsx # Route: /docs/* (catch-all)
|
|
56
|
+
├── shared/
|
|
57
|
+
│ ├── components/ # Reusable across features
|
|
58
|
+
│ │ ├── Header.tsx # Site header
|
|
59
|
+
│ │ ├── Footer.tsx # Site footer
|
|
60
|
+
│ │ └── SEO.tsx # SEO component
|
|
61
|
+
│ └── hooks/
|
|
62
|
+
│ └── useSEO.ts # Shared logic
|
|
63
|
+
└── styles/
|
|
64
|
+
└── index.css # Global styles
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
## 🧭 How FBCA Works
|
|
68
|
+
|
|
69
|
+
### Auto-Discovery Routing
|
|
70
|
+
**Why:** Zero configuration routing based on file structure
|
|
71
|
+
**When:** Want file-system based routing like Next.js
|
|
72
|
+
**How:** PageRouter scans features/*/pages/ and creates routes automatically
|
|
73
|
+
|
|
74
|
+
```jsx
|
|
75
|
+
// File structure determines URL routes:
|
|
76
|
+
/features/main/pages/index.tsx → / (homepage)
|
|
77
|
+
/features/main/pages/About.tsx → /about
|
|
78
|
+
/features/auth/pages/index.tsx → /auth
|
|
79
|
+
/features/gallery/pages/index.tsx → /gallery
|
|
80
|
+
/features/docs/pages/[...slug].tsx → /docs/* (catch-all)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### App.tsx - Root Configuration
|
|
84
|
+
**Why:** Simple root app with theme provider and router
|
|
85
|
+
**When:** Global app setup
|
|
86
|
+
**How:** Delegates routing to PageRouter
|
|
87
|
+
|
|
88
|
+
```jsx
|
|
89
|
+
function App() {
|
|
90
|
+
return (
|
|
91
|
+
<ThemeProvider theme="base" mode="light" forceConfig={true}>
|
|
92
|
+
<Router>
|
|
93
|
+
<PageRouter />
|
|
94
|
+
</Router>
|
|
95
|
+
</ThemeProvider>
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
### PageRouter - Auto-Discovery Engine
|
|
101
|
+
**Why:** Automatically discovers and configures routes
|
|
102
|
+
**When:** Adding new pages without manual route config
|
|
103
|
+
**How:** Uses Vite glob imports to scan feature pages
|
|
104
|
+
|
|
105
|
+
```jsx
|
|
106
|
+
// Auto-discovers all page files
|
|
107
|
+
const pageFiles = import.meta.glob('../features/*/pages/**/*.{tsx,jsx}', { eager: true });
|
|
108
|
+
|
|
109
|
+
// Converts file paths to routes:
|
|
110
|
+
// features/main/pages/index.tsx → /
|
|
111
|
+
// features/gallery/pages/index.tsx → /gallery
|
|
112
|
+
// features/auth/pages/login.tsx → /auth/login
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 📁 Feature Structure
|
|
116
|
+
|
|
117
|
+
### Feature Organization
|
|
118
|
+
**Why:** Each feature is completely self-contained
|
|
119
|
+
**When:** Building distinct business features
|
|
120
|
+
**How:** Organize by feature, not by file type
|
|
121
|
+
|
|
122
|
+
```jsx
|
|
123
|
+
// ✅ FBCA Way - Organize by feature
|
|
124
|
+
/features/blog/
|
|
125
|
+
├── pages/ # Blog pages
|
|
126
|
+
├── components/ # Blog-specific components
|
|
127
|
+
├── hooks/ # Blog business logic
|
|
128
|
+
└── types/ # Blog type definitions
|
|
129
|
+
|
|
130
|
+
// ❌ Traditional Way - Organize by file type
|
|
131
|
+
/pages/ # All pages mixed together
|
|
132
|
+
/components/ # All components mixed together
|
|
133
|
+
/hooks/ # All hooks mixed together
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
### Page Component Example
|
|
137
|
+
**Why:** Each page handles its own layout and content
|
|
138
|
+
**When:** Creating feature pages
|
|
139
|
+
**How:** Use PageLayout with shared Header/Footer
|
|
140
|
+
|
|
141
|
+
```jsx
|
|
142
|
+
// features/gallery/pages/index.tsx
|
|
143
|
+
import { PageLayout } from '@bloomneo/uikit/page';
|
|
144
|
+
import { Header, Footer, SEO } from '../../../shared/components';
|
|
145
|
+
import { useGallery } from '../hooks/useGallery';
|
|
146
|
+
|
|
147
|
+
export default function GalleryPage() {
|
|
148
|
+
const { images, loading } = useGallery();
|
|
149
|
+
|
|
150
|
+
return (
|
|
151
|
+
<PageLayout>
|
|
152
|
+
<SEO
|
|
153
|
+
title="Gallery - UIKit FBCA Demo"
|
|
154
|
+
description="Browse our image gallery built with Feature-Based Component Architecture and UIKit components"
|
|
155
|
+
keywords="gallery, images, fbca, uikit, react"
|
|
156
|
+
ogTitle="Gallery Feature - UIKit FBCA"
|
|
157
|
+
ogDescription="Explore the gallery feature in our FBCA demo application"
|
|
158
|
+
/>
|
|
159
|
+
<Header />
|
|
160
|
+
|
|
161
|
+
<PageLayout.Content>
|
|
162
|
+
<h1 className="voila-heading text-4xl mb-8">Gallery</h1>
|
|
163
|
+
{loading ? (
|
|
164
|
+
<div>Loading images...</div>
|
|
165
|
+
) : (
|
|
166
|
+
<div className="grid grid-cols-3 gap-4">
|
|
167
|
+
{images.map(image => (
|
|
168
|
+
<img key={image.id} src={image.url} alt={image.title} />
|
|
169
|
+
))}
|
|
170
|
+
</div>
|
|
171
|
+
)}
|
|
172
|
+
</PageLayout.Content>
|
|
173
|
+
|
|
174
|
+
<Footer />
|
|
175
|
+
</PageLayout>
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Shared Components
|
|
181
|
+
**Why:** Reusable components across all features
|
|
182
|
+
**When:** Common UI elements like headers, footers, SEO
|
|
183
|
+
**How:** Place in /shared/components/
|
|
184
|
+
|
|
185
|
+
```jsx
|
|
186
|
+
// shared/components/Header.tsx
|
|
187
|
+
export const Header = () => {
|
|
188
|
+
return (
|
|
189
|
+
<PageLayout.Header
|
|
190
|
+
navigation={[
|
|
191
|
+
{ key: 'home', label: 'Home', href: '/' },
|
|
192
|
+
{ key: 'gallery', label: 'Gallery', href: '/gallery' },
|
|
193
|
+
{ key: 'auth', label: 'Login', href: '/auth' },
|
|
194
|
+
{ key: 'docs', label: 'Docs', href: '/docs' },
|
|
195
|
+
]}
|
|
196
|
+
logo={<div className="font-bold">FBCA Demo</div>}
|
|
197
|
+
/>
|
|
198
|
+
);
|
|
199
|
+
};
|
|
200
|
+
|
|
201
|
+
// shared/components/SEO.tsx
|
|
202
|
+
export const SEO = (props) => {
|
|
203
|
+
useSEO(props);
|
|
204
|
+
return null; // Component doesn't render anything
|
|
205
|
+
};
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
### SEO Management
|
|
209
|
+
**Why:** Each page needs proper SEO meta tags
|
|
210
|
+
**When:** Want search engine optimization and social sharing
|
|
211
|
+
**How:** Use SEO component with useSEO hook
|
|
212
|
+
|
|
213
|
+
```jsx
|
|
214
|
+
// shared/hooks/useSEO.ts - Manages document head
|
|
215
|
+
export const useSEO = ({
|
|
216
|
+
title = 'UIKit FBCA Demo',
|
|
217
|
+
description = 'Feature-Based Component Architecture with UIKit components',
|
|
218
|
+
keywords = 'react, fbca, uikit, components, typescript',
|
|
219
|
+
ogTitle,
|
|
220
|
+
ogDescription,
|
|
221
|
+
ogImage = '/favicon.ico',
|
|
222
|
+
canonical
|
|
223
|
+
}) => {
|
|
224
|
+
useEffect(() => {
|
|
225
|
+
document.title = title;
|
|
226
|
+
// Sets meta description, keywords, Open Graph, Twitter Cards
|
|
227
|
+
}, [title, description, keywords, ogTitle, ogDescription, ogImage, canonical]);
|
|
228
|
+
};
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## 🎯 When to Use FBCA Template
|
|
232
|
+
|
|
233
|
+
**Perfect for:**
|
|
234
|
+
- Enterprise applications with multiple business domains
|
|
235
|
+
- Large teams (5+ developers) working on different features
|
|
236
|
+
- Long-term projects that need to scale over time
|
|
237
|
+
- Applications with distinct feature areas (auth, billing, analytics, etc.)
|
|
238
|
+
- Projects requiring feature isolation for testing/deployment
|
|
239
|
+
|
|
240
|
+
**Key Benefits:**
|
|
241
|
+
- **Feature isolation** - Features don't depend on each other
|
|
242
|
+
- **Team scalability** - Different teams can work on different features
|
|
243
|
+
- **Zero-config routing** - File structure determines URLs
|
|
244
|
+
- **Maintainability** - Easy to find and modify feature code
|
|
245
|
+
- **Testability** - Test features in complete isolation
|
|
246
|
+
|
|
247
|
+
**Not ideal for:**
|
|
248
|
+
- Simple websites (use SPA template)
|
|
249
|
+
- Small teams (use Multi template)
|
|
250
|
+
- Quick prototypes (use Single template)
|
|
251
|
+
- Applications with heavy feature interdependency
|
|
252
|
+
|
|
253
|
+
## ⚡ Adding New Features
|
|
254
|
+
|
|
255
|
+
### Step 1: Create Feature Structure
|
|
256
|
+
**Why:** Follow FBCA conventions for consistency
|
|
257
|
+
**When:** Adding new business functionality
|
|
258
|
+
**How:** Create feature folder with pages, components, hooks
|
|
259
|
+
|
|
260
|
+
```bash
|
|
261
|
+
# Create new feature structure
|
|
262
|
+
mkdir -p src/web/features/blog/pages
|
|
263
|
+
mkdir -p src/web/features/blog/components
|
|
264
|
+
mkdir -p src/web/features/blog/hooks
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
### Step 2: Add Feature Pages
|
|
268
|
+
**Why:** Pages automatically become routes
|
|
269
|
+
**When:** Need URLs for your feature
|
|
270
|
+
**How:** Create .tsx files in pages/ folder
|
|
271
|
+
|
|
272
|
+
```jsx
|
|
273
|
+
// features/blog/pages/index.tsx - Route: /blog
|
|
274
|
+
export default function BlogPage() {
|
|
275
|
+
return (
|
|
276
|
+
<PageLayout>
|
|
277
|
+
<Header />
|
|
278
|
+
<PageLayout.Content>
|
|
279
|
+
<h1>Blog Posts</h1>
|
|
280
|
+
{/* Blog list */}
|
|
281
|
+
</PageLayout.Content>
|
|
282
|
+
<Footer />
|
|
283
|
+
</PageLayout>
|
|
284
|
+
);
|
|
285
|
+
}
|
|
286
|
+
|
|
287
|
+
// features/blog/pages/[id].tsx - Route: /blog/:id
|
|
288
|
+
export default function BlogPostPage() {
|
|
289
|
+
return (
|
|
290
|
+
<PageLayout>
|
|
291
|
+
<Header />
|
|
292
|
+
<PageLayout.Content>
|
|
293
|
+
<h1>Blog Post</h1>
|
|
294
|
+
{/* Individual blog post */}
|
|
295
|
+
</PageLayout.Content>
|
|
296
|
+
<Footer />
|
|
297
|
+
</PageLayout>
|
|
298
|
+
);
|
|
299
|
+
}
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
### Step 3: Add Feature Logic
|
|
303
|
+
**Why:** Keep business logic isolated in feature
|
|
304
|
+
**When:** Need feature-specific functionality
|
|
305
|
+
**How:** Create hooks and components in feature folder
|
|
306
|
+
|
|
307
|
+
```jsx
|
|
308
|
+
// features/blog/hooks/useBlog.ts
|
|
309
|
+
export const useBlog = () => {
|
|
310
|
+
const [posts, setPosts] = useState([]);
|
|
311
|
+
|
|
312
|
+
const fetchPosts = async () => {
|
|
313
|
+
// Blog-specific logic
|
|
314
|
+
};
|
|
315
|
+
|
|
316
|
+
return { posts, fetchPosts };
|
|
317
|
+
};
|
|
318
|
+
|
|
319
|
+
// features/blog/components/BlogCard.tsx
|
|
320
|
+
export const BlogCard = ({ post }) => {
|
|
321
|
+
return (
|
|
322
|
+
<Card>
|
|
323
|
+
<CardHeader>
|
|
324
|
+
<CardTitle>{post.title}</CardTitle>
|
|
325
|
+
</CardHeader>
|
|
326
|
+
<CardContent>
|
|
327
|
+
{post.excerpt}
|
|
328
|
+
</CardContent>
|
|
329
|
+
</Card>
|
|
330
|
+
);
|
|
331
|
+
};
|
|
332
|
+
```
|
|
333
|
+
|
|
334
|
+
## 🔧 Advanced Routing
|
|
335
|
+
|
|
336
|
+
### Dynamic Routes
|
|
337
|
+
**Why:** Handle variable URL segments
|
|
338
|
+
**When:** Need routes like /blog/post-123
|
|
339
|
+
**How:** Use [param].tsx file naming
|
|
340
|
+
|
|
341
|
+
```jsx
|
|
342
|
+
// features/blog/pages/[slug].tsx → /blog/:slug
|
|
343
|
+
// features/user/pages/[id]/settings.tsx → /user/:id/settings
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Catch-All Routes
|
|
347
|
+
**Why:** Handle multiple URL segments
|
|
348
|
+
**When:** Need routes like /docs/guide/getting-started
|
|
349
|
+
**How:** Use [...param].tsx file naming
|
|
350
|
+
|
|
351
|
+
```jsx
|
|
352
|
+
// features/docs/pages/[...slug].tsx → /docs/*
|
|
353
|
+
```
|
|
354
|
+
|
|
355
|
+
### Nested Routes
|
|
356
|
+
**Why:** Organize related pages hierarchically
|
|
357
|
+
**When:** Complex feature with sub-sections
|
|
358
|
+
**How:** Create nested folder structure
|
|
359
|
+
|
|
360
|
+
```jsx
|
|
361
|
+
// features/admin/pages/users/index.tsx → /admin/users
|
|
362
|
+
// features/admin/pages/users/[id].tsx → /admin/users/:id
|
|
363
|
+
// features/admin/pages/settings/billing.tsx → /admin/settings/billing
|
|
364
|
+
```
|
|
365
|
+
|
|
366
|
+
---
|
|
367
|
+
|
|
368
|
+
**Built with @bloomneo/uikit** ✨
|