@nextsparkjs/core 0.1.0-beta.187 → 0.1.0-beta.189
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/dist/components/api/keys/ApiKeyDisplay.js +19 -19
- package/dist/components/api/keys/CreateApiKeyDialog.js +21 -21
- package/dist/components/app/layouts/PublicNavbar.d.ts.map +1 -1
- package/dist/components/app/layouts/PublicNavbar.js +34 -16
- package/dist/components/app/misc/ThemeToggle.d.ts.map +1 -1
- package/dist/components/app/misc/ThemeToggle.js +3 -4
- package/dist/components/auth/SessionCookieRefresher.d.ts +5 -0
- package/dist/components/auth/SessionCookieRefresher.d.ts.map +1 -1
- package/dist/components/auth/SessionCookieRefresher.js +7 -1
- package/dist/components/auth/forms/LoginForm.d.ts.map +1 -1
- package/dist/components/auth/forms/LoginForm.js +49 -12
- package/dist/components/auth/forms/SignupForm.d.ts.map +1 -1
- package/dist/components/auth/forms/SignupForm.js +4 -3
- package/dist/components/dashboard/block-editor/block-settings-panel.js +1 -1
- package/dist/components/dashboard/block-editor/floating-block-toolbar.js +1 -1
- package/dist/components/dashboard/block-editor/sortable-block.js +1 -1
- package/dist/components/dashboard/layouts/Sidebar.d.ts.map +1 -1
- package/dist/components/dashboard/layouts/Sidebar.js +8 -6
- package/dist/components/dashboard/layouts/TopNavbar.d.ts.map +1 -1
- package/dist/components/dashboard/layouts/TopNavbar.js +51 -54
- package/dist/components/dashboard/misc/NotificationsDropdown.d.ts.map +1 -1
- package/dist/components/dashboard/misc/NotificationsDropdown.js +17 -15
- package/dist/components/dashboard/misc/SearchDropdown.d.ts.map +1 -1
- package/dist/components/dashboard/misc/SearchDropdown.js +19 -22
- package/dist/components/dashboard/mobile/MobileBottomNav.js +1 -1
- package/dist/components/dashboard/mobile/MobileTopBar.d.ts +10 -1
- package/dist/components/dashboard/mobile/MobileTopBar.d.ts.map +1 -1
- package/dist/components/dashboard/mobile/MobileTopBar.js +4 -3
- package/dist/components/dashboard/navigation/DynamicNavigation.js +5 -5
- package/dist/components/devtools/BlockDetailViewer.js +1 -1
- package/dist/components/devtools/BlocksViewer.js +1 -1
- package/dist/components/entities/EntityChildManager.js +5 -5
- package/dist/components/entities/EntityDetailPage.d.ts.map +1 -1
- package/dist/components/entities/EntityDetailPage.js +16 -15
- package/dist/components/entities/EntityFieldRenderer.d.ts.map +1 -1
- package/dist/components/entities/EntityFieldRenderer.js +12 -7
- package/dist/components/entities/EntityPageHeader.js +5 -5
- package/dist/components/entities/ErrorBoundary.d.ts.map +1 -1
- package/dist/components/entities/ErrorBoundary.js +20 -21
- package/dist/components/entities/wrappers/EntityDetailWrapper.js +5 -5
- package/dist/components/entities/wrappers/EntityFormWrapper.js +2 -2
- package/dist/components/entities/wrappers/EntityListWrapper.js +3 -3
- package/dist/components/permissions/NoPermission.js +10 -10
- package/dist/components/public/pageBuilder/PageRenderer.d.ts.map +1 -1
- package/dist/components/public/pageBuilder/PageRenderer.js +2 -1
- package/dist/components/settings/SettingsPageSkeleton.js +4 -4
- package/dist/components/settings/layouts/SettingsSidebar.js +6 -6
- package/dist/components/shared/MultiSelectFilter.d.ts +3 -1
- package/dist/components/shared/MultiSelectFilter.d.ts.map +1 -1
- package/dist/components/shared/MultiSelectFilter.js +7 -3
- package/dist/components/shared/SearchInput.d.ts +2 -0
- package/dist/components/shared/SearchInput.d.ts.map +1 -1
- package/dist/components/shared/SearchInput.js +64 -6
- package/dist/components/ui/address-input.js +18 -18
- package/dist/components/ui/audio-upload.js +9 -9
- package/dist/components/ui/combobox.d.ts.map +1 -1
- package/dist/components/ui/combobox.js +4 -4
- package/dist/components/ui/country-select.d.ts.map +1 -1
- package/dist/components/ui/country-select.js +3 -3
- package/dist/components/ui/currency-select.d.ts.map +1 -1
- package/dist/components/ui/currency-select.js +3 -3
- package/dist/components/ui/dynamic-icon.d.ts.map +1 -1
- package/dist/components/ui/dynamic-icon.js +3 -2
- package/dist/components/ui/file-upload.js +7 -7
- package/dist/components/ui/image-upload.js +8 -8
- package/dist/components/ui/multi-select.d.ts +2 -1
- package/dist/components/ui/multi-select.d.ts.map +1 -1
- package/dist/components/ui/multi-select.js +4 -3
- package/dist/components/ui/phone-input.d.ts.map +1 -1
- package/dist/components/ui/phone-input.js +3 -3
- package/dist/components/ui/relation-display.js +1 -1
- package/dist/components/ui/simple-relation-select.d.ts +2 -1
- package/dist/components/ui/simple-relation-select.d.ts.map +1 -1
- package/dist/components/ui/simple-relation-select.js +7 -6
- package/dist/components/ui/tags-input.d.ts.map +1 -1
- package/dist/components/ui/tags-input.js +1 -1
- package/dist/components/ui/timezone-select.d.ts.map +1 -1
- package/dist/components/ui/timezone-select.js +3 -3
- package/dist/components/ui/user-display.js +4 -4
- package/dist/components/ui/user-select.d.ts.map +1 -1
- package/dist/components/ui/user-select.js +9 -9
- package/dist/components/ui/video-upload.js +9 -9
- package/dist/contexts/SubscriptionContext.d.ts.map +1 -1
- package/dist/contexts/SubscriptionContext.js +5 -1
- package/dist/contexts/TeamContext.d.ts.map +1 -1
- package/dist/contexts/TeamContext.js +83 -26
- package/dist/emails/otp-verification.d.ts.map +1 -1
- package/dist/emails/otp-verification.js +3 -2
- package/dist/hooks/useAccountPreferencesSync.d.ts +13 -0
- package/dist/hooks/useAccountPreferencesSync.d.ts.map +1 -0
- package/dist/hooks/useAccountPreferencesSync.js +95 -0
- package/dist/hooks/useAuth.d.ts +202 -15
- package/dist/hooks/useAuth.d.ts.map +1 -1
- package/dist/hooks/useAuth.js +49 -13
- package/dist/hooks/useEntityConfig.js +2 -2
- package/dist/hooks/useEntitySearch.js +10 -10
- package/dist/hooks/useNotifications.js +12 -12
- package/dist/hooks/usePrefetch.d.ts.map +1 -1
- package/dist/hooks/usePrefetch.js +6 -2
- package/dist/hooks/useSearch.js +15 -15
- package/dist/hooks/useSessionCookieRefresh.d.ts +18 -1
- package/dist/hooks/useSessionCookieRefresh.d.ts.map +1 -1
- package/dist/hooks/useSessionCookieRefresh.js +17 -4
- package/dist/hooks/useSessionHint.d.ts +12 -0
- package/dist/hooks/useSessionHint.d.ts.map +1 -0
- package/dist/hooks/useSessionHint.js +15 -0
- package/dist/hooks/useTranslationPreload.js +6 -6
- package/dist/i18n.d.ts +13 -0
- package/dist/i18n.d.ts.map +1 -1
- package/dist/i18n.js +2 -27
- package/dist/lib/actions/entity.actions.d.ts.map +1 -1
- package/dist/lib/actions/entity.actions.js +3 -2
- package/dist/lib/api/auth/dual-auth.d.ts +4 -1
- package/dist/lib/api/auth/dual-auth.d.ts.map +1 -1
- package/dist/lib/api/auth/dual-auth.js +5 -16
- package/dist/lib/api/entities.js +33 -33
- package/dist/lib/api/keys.d.ts +27 -27
- package/dist/lib/api/keys.js +27 -27
- package/dist/lib/auth/callback-url.d.ts +11 -0
- package/dist/lib/auth/callback-url.d.ts.map +1 -0
- package/dist/lib/auth/callback-url.js +14 -0
- package/dist/lib/auth/otp-config.d.ts +55 -0
- package/dist/lib/auth/otp-config.d.ts.map +1 -0
- package/dist/lib/auth/otp-config.js +48 -0
- package/dist/lib/auth/registration-helpers.d.ts.map +1 -1
- package/dist/lib/auth/registration-helpers.js +3 -1
- package/dist/lib/auth/session-hint.d.ts +31 -0
- package/dist/lib/auth/session-hint.d.ts.map +1 -0
- package/dist/lib/auth/session-hint.js +37 -0
- package/dist/lib/auth.d.ts.map +1 -1
- package/dist/lib/auth.js +6 -4
- package/dist/lib/blocks/loader.d.ts +3 -11
- package/dist/lib/blocks/loader.d.ts.map +1 -1
- package/dist/lib/blocks/loader.js +1 -9
- package/dist/lib/blocks/loader.server.d.ts +18 -0
- package/dist/lib/blocks/loader.server.d.ts.map +1 -0
- package/dist/lib/blocks/loader.server.js +11 -0
- package/dist/lib/blocks/sanitize-html.d.ts +31 -0
- package/dist/lib/blocks/sanitize-html.d.ts.map +1 -0
- package/dist/lib/blocks/sanitize-html.js +60 -0
- package/dist/lib/config/config-sync.d.ts +1 -0
- package/dist/lib/config/config-sync.d.ts.map +1 -1
- package/dist/lib/config/config-sync.js +4 -1
- package/dist/lib/config/types.d.ts +48 -0
- package/dist/lib/config/types.d.ts.map +1 -1
- package/dist/lib/email/types.d.ts +6 -0
- package/dist/lib/email/types.d.ts.map +1 -1
- package/dist/lib/entities/serialization.d.ts.map +1 -1
- package/dist/lib/entities/serialization.js +3 -6
- package/dist/lib/icons.d.ts +12 -0
- package/dist/lib/icons.d.ts.map +1 -0
- package/dist/lib/icons.js +30 -0
- package/dist/lib/locale.d.ts +25 -1
- package/dist/lib/locale.d.ts.map +1 -1
- package/dist/lib/locale.js +49 -35
- package/dist/lib/mcp/engine.js +1 -1
- package/dist/lib/mcp/errors.js +17 -17
- package/dist/lib/mcp/schema-builder.js +16 -16
- package/dist/lib/mcp/tool-generator.js +18 -18
- package/dist/lib/search-highlighting.d.ts +7 -0
- package/dist/lib/search-highlighting.d.ts.map +1 -1
- package/dist/lib/search-highlighting.js +6 -2
- package/dist/lib/selectors/core-selectors.d.ts +2 -0
- package/dist/lib/selectors/core-selectors.d.ts.map +1 -1
- package/dist/lib/selectors/domains/auth.selectors.d.ts +1 -0
- package/dist/lib/selectors/domains/auth.selectors.d.ts.map +1 -1
- package/dist/lib/selectors/domains/auth.selectors.js +1 -0
- package/dist/lib/selectors/domains/entities.selectors.d.ts +2 -0
- package/dist/lib/selectors/domains/entities.selectors.d.ts.map +1 -1
- package/dist/lib/selectors/domains/entities.selectors.js +2 -0
- package/dist/lib/selectors/selectors.d.ts +4 -0
- package/dist/lib/selectors/selectors.d.ts.map +1 -1
- package/dist/lib/services/block.service.js +1 -1
- package/dist/lib/teams/active-team-cookie.d.ts +24 -0
- package/dist/lib/teams/active-team-cookie.d.ts.map +1 -0
- package/dist/lib/teams/active-team-cookie.js +17 -0
- package/dist/lib/teams/dashboard-team.d.ts +20 -0
- package/dist/lib/teams/dashboard-team.d.ts.map +1 -0
- package/dist/lib/teams/dashboard-team.js +38 -0
- package/dist/lib/teams/schema.d.ts.map +1 -1
- package/dist/lib/teams/schema.js +1 -1
- package/dist/lib/template-resolver.d.ts.map +1 -1
- package/dist/lib/template-resolver.js +0 -1
- package/dist/lib/theme/get-default-theme-mode.d.ts +7 -4
- package/dist/lib/theme/get-default-theme-mode.d.ts.map +1 -1
- package/dist/lib/theme/get-default-theme-mode.js +2 -44
- package/dist/messages/de/auth.json +4 -2
- package/dist/messages/de/common.json +83 -3
- package/dist/messages/de/email.json +1 -1
- package/dist/messages/de/index.d.ts +87 -0
- package/dist/messages/de/index.d.ts.map +1 -1
- package/dist/messages/de/settings.json +5 -0
- package/dist/messages/en/auth.json +4 -2
- package/dist/messages/en/common.json +83 -3
- package/dist/messages/en/email.json +1 -1
- package/dist/messages/en/index.d.ts +86 -0
- package/dist/messages/en/index.d.ts.map +1 -1
- package/dist/messages/en/settings.json +4 -0
- package/dist/messages/es/auth.json +4 -2
- package/dist/messages/es/common.json +83 -3
- package/dist/messages/es/email.json +1 -1
- package/dist/messages/es/index.d.ts +86 -0
- package/dist/messages/es/index.d.ts.map +1 -1
- package/dist/messages/es/settings.json +4 -0
- package/dist/messages/fr/auth.json +4 -2
- package/dist/messages/fr/common.json +83 -3
- package/dist/messages/fr/email.json +1 -1
- package/dist/messages/fr/index.d.ts +87 -0
- package/dist/messages/fr/index.d.ts.map +1 -1
- package/dist/messages/fr/settings.json +5 -0
- package/dist/messages/it/auth.json +4 -2
- package/dist/messages/it/common.json +83 -3
- package/dist/messages/it/email.json +1 -1
- package/dist/messages/it/index.d.ts +87 -0
- package/dist/messages/it/index.d.ts.map +1 -1
- package/dist/messages/it/settings.json +5 -0
- package/dist/messages/pt/auth.json +4 -2
- package/dist/messages/pt/common.json +83 -3
- package/dist/messages/pt/email.json +1 -1
- package/dist/messages/pt/index.d.ts +87 -0
- package/dist/messages/pt/index.d.ts.map +1 -1
- package/dist/messages/pt/settings.json +5 -0
- package/dist/nextspark-registries.d.ts +54 -0
- package/dist/providers/DashboardProviders.d.ts +13 -10
- package/dist/providers/DashboardProviders.d.ts.map +1 -1
- package/dist/providers/DashboardProviders.js +7 -1
- package/dist/templates/app/(auth)/forgot-password/page.tsx +2 -2
- package/dist/templates/app/(auth)/reset-password/page.tsx +6 -6
- package/dist/templates/app/403/page.tsx +6 -6
- package/dist/templates/app/api/v1/teams/switch/route.ts +24 -5
- package/dist/templates/app/dashboard/(main)/[entity]/layout.tsx +9 -7
- package/dist/templates/app/dashboard/(main)/layout.tsx +4 -3
- package/dist/templates/app/dashboard/settings/api-keys/page.tsx +36 -34
- package/dist/templates/app/dashboard/settings/profile/page.tsx +7 -6
- package/dist/templates/app/dashboard/settings/security/page.tsx +5 -4
- package/dist/templates/app/layout.ppr.tsx +8 -8
- package/dist/templates/app/layout.tsx +12 -17
- package/dist/templates/blocks/cta-section/component.tsx +5 -2
- package/dist/templates/blocks/cta-section/config.ts +3 -2
- package/dist/templates/blocks/cta-section/fields.ts +2 -2
- package/dist/templates/blocks/cta-section/schema.ts +2 -2
- package/dist/templates/blocks/features-grid/component.tsx +10 -2
- package/dist/templates/blocks/features-grid/config.ts +3 -2
- package/dist/templates/blocks/features-grid/fields.ts +2 -2
- package/dist/templates/blocks/features-grid/schema.ts +2 -2
- package/dist/templates/blocks/hero/component.tsx +6 -3
- package/dist/templates/blocks/hero/config.ts +3 -2
- package/dist/templates/blocks/hero/fields.ts +2 -2
- package/dist/templates/blocks/hero/schema.ts +2 -2
- package/dist/templates/blocks/testimonials/component.tsx +6 -3
- package/dist/templates/blocks/testimonials/config.ts +3 -2
- package/dist/templates/blocks/testimonials/fields.ts +2 -2
- package/dist/templates/blocks/testimonials/schema.ts +2 -2
- package/dist/templates/blocks/text-content/component.tsx +7 -3
- package/dist/templates/blocks/text-content/config.ts +3 -2
- package/dist/templates/blocks/text-content/fields.ts +2 -2
- package/dist/templates/blocks/text-content/schema.ts +2 -2
- package/dist/templates/contents/themes/starter/blocks/cta-section/component.tsx +102 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/fields.ts +89 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/schema.ts +32 -0
- package/dist/templates/contents/themes/starter/blocks/cta-section/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/component.tsx +119 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/fields.ts +97 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/schema.ts +40 -0
- package/dist/templates/contents/themes/starter/blocks/features-grid/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/hero/component.tsx +105 -0
- package/dist/templates/contents/themes/starter/blocks/hero/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/hero/fields.ts +60 -0
- package/dist/templates/contents/themes/starter/blocks/hero/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/hero/schema.ts +33 -0
- package/dist/templates/contents/themes/starter/blocks/hero/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/component.tsx +116 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/fields.ts +105 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/schema.ts +41 -0
- package/dist/templates/contents/themes/starter/blocks/testimonials/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/component.tsx +100 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/config.ts +11 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/fields.ts +88 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/index.ts +6 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/schema.ts +30 -0
- package/dist/templates/contents/themes/starter/blocks/text-content/thumbnail.png +0 -0
- package/dist/templates/contents/themes/starter/config/app.config.ts +8 -0
- package/dist/templates/contents/themes/starter/entities/tasks/tasks.config.ts +7 -0
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/_utils/devtools/access.cy.ts +9 -1
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/api/entities/tasks/TaskAPIController.js +2 -2
- package/dist/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +45 -38
- package/dist/templates/contents/themes/starter/tests/cypress/fixtures/entities.json +16 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +3 -1
- package/dist/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +3 -3
- package/dist/templates/contents/themes/starter/tests/cypress/src/entities/PagesPOM.ts +137 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +2 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/index.ts +1 -0
- package/dist/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +42 -11
- package/dist/templates/contents/themes/starter/tests/cypress/support/commands.ts +29 -18
- package/dist/templates/features/blog/blocks/post-content/component.tsx +5 -1
- package/dist/templates/features/blog/blocks/post-content/schema.ts +1 -1
- package/dist/templates/features/pages/blocks/hero/component.tsx +3 -0
- package/dist/templates/features/pages/blocks/hero/schema.ts +1 -1
- package/dist/templates/proxy.ts +138 -53
- package/dist/types/blocks.d.ts.map +1 -1
- package/dist/types/blocks.js +1 -1
- package/dist/types/task.types.d.ts +1 -1
- package/dist/types/task.types.js +7 -7
- package/dist/utils/dev/TranslationDebugger.js +2 -2
- package/package.json +14 -5
- package/scripts/build/registry/__tests__/block-registry.test.mjs +73 -0
- package/scripts/build/registry/__tests__/icons-discovery.test.mjs +130 -0
- package/scripts/build/registry/__tests__/identifier.test.mjs +65 -0
- package/scripts/build/registry/__tests__/page-generator.test.mjs +430 -0
- package/scripts/build/registry/__tests__/scheduled-actions-registry.test.mjs +41 -0
- package/scripts/build/registry/__tests__/template-registry.test.mjs +89 -0
- package/scripts/build/registry/discovery/icons.mjs +275 -0
- package/scripts/build/registry/discovery/index.mjs +1 -0
- package/scripts/build/registry/generators/block-registry.mjs +203 -55
- package/scripts/build/registry/generators/feature-registry.mjs +9 -2
- package/scripts/build/registry/generators/icon-registry.mjs +56 -0
- package/scripts/build/registry/generators/identifier.mjs +28 -0
- package/scripts/build/registry/generators/index.mjs +1 -0
- package/scripts/build/registry/generators/plugin-registry.mjs +4 -3
- package/scripts/build/registry/generators/scheduled-actions-registry.mjs +4 -2
- package/scripts/build/registry/generators/template-registry.mjs +49 -41
- package/scripts/build/registry/generators/theme-registry.mjs +6 -7
- package/scripts/build/registry/post-build/page-generator.mjs +380 -59
- package/scripts/build/registry.mjs +9 -1
- package/templates/app/(auth)/forgot-password/page.tsx +2 -2
- package/templates/app/(auth)/reset-password/page.tsx +6 -6
- package/templates/app/403/page.tsx +6 -6
- package/templates/app/api/v1/teams/switch/route.ts +24 -5
- package/templates/app/dashboard/(main)/[entity]/layout.tsx +9 -7
- package/templates/app/dashboard/(main)/layout.tsx +4 -3
- package/templates/app/dashboard/settings/api-keys/page.tsx +36 -34
- package/templates/app/dashboard/settings/profile/page.tsx +7 -6
- package/templates/app/dashboard/settings/security/page.tsx +5 -4
- package/templates/app/layout.ppr.tsx +8 -8
- package/templates/app/layout.tsx +12 -17
- package/templates/blocks/cta-section/component.tsx +5 -2
- package/templates/blocks/cta-section/config.ts +3 -2
- package/templates/blocks/cta-section/fields.ts +2 -2
- package/templates/blocks/cta-section/schema.ts +2 -2
- package/templates/blocks/features-grid/component.tsx +10 -2
- package/templates/blocks/features-grid/config.ts +3 -2
- package/templates/blocks/features-grid/fields.ts +2 -2
- package/templates/blocks/features-grid/schema.ts +2 -2
- package/templates/blocks/hero/component.tsx +6 -3
- package/templates/blocks/hero/config.ts +3 -2
- package/templates/blocks/hero/fields.ts +2 -2
- package/templates/blocks/hero/schema.ts +2 -2
- package/templates/blocks/testimonials/component.tsx +6 -3
- package/templates/blocks/testimonials/config.ts +3 -2
- package/templates/blocks/testimonials/fields.ts +2 -2
- package/templates/blocks/testimonials/schema.ts +2 -2
- package/templates/blocks/text-content/component.tsx +7 -3
- package/templates/blocks/text-content/config.ts +3 -2
- package/templates/blocks/text-content/fields.ts +2 -2
- package/templates/blocks/text-content/schema.ts +2 -2
- package/templates/contents/themes/starter/blocks/cta-section/component.tsx +102 -0
- package/templates/contents/themes/starter/blocks/cta-section/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/cta-section/fields.ts +89 -0
- package/templates/contents/themes/starter/blocks/cta-section/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/cta-section/schema.ts +32 -0
- package/templates/contents/themes/starter/blocks/cta-section/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/features-grid/component.tsx +119 -0
- package/templates/contents/themes/starter/blocks/features-grid/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/features-grid/fields.ts +97 -0
- package/templates/contents/themes/starter/blocks/features-grid/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/features-grid/schema.ts +40 -0
- package/templates/contents/themes/starter/blocks/features-grid/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/hero/component.tsx +105 -0
- package/templates/contents/themes/starter/blocks/hero/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/hero/fields.ts +60 -0
- package/templates/contents/themes/starter/blocks/hero/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/hero/schema.ts +33 -0
- package/templates/contents/themes/starter/blocks/hero/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/testimonials/component.tsx +116 -0
- package/templates/contents/themes/starter/blocks/testimonials/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/testimonials/fields.ts +105 -0
- package/templates/contents/themes/starter/blocks/testimonials/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/testimonials/schema.ts +41 -0
- package/templates/contents/themes/starter/blocks/testimonials/thumbnail.png +0 -0
- package/templates/contents/themes/starter/blocks/text-content/component.tsx +100 -0
- package/templates/contents/themes/starter/blocks/text-content/config.ts +11 -0
- package/templates/contents/themes/starter/blocks/text-content/fields.ts +88 -0
- package/templates/contents/themes/starter/blocks/text-content/index.ts +6 -0
- package/templates/contents/themes/starter/blocks/text-content/schema.ts +30 -0
- package/templates/contents/themes/starter/blocks/text-content/thumbnail.png +0 -0
- package/templates/contents/themes/starter/config/app.config.ts +8 -0
- package/templates/contents/themes/starter/entities/tasks/tasks.config.ts +7 -0
- package/templates/contents/themes/starter/tests/cypress/e2e/_utils/devtools/access.cy.ts +9 -1
- package/templates/contents/themes/starter/tests/cypress/e2e/api/entities/tasks/TaskAPIController.js +2 -2
- package/templates/contents/themes/starter/tests/cypress/e2e/uat/entities/tasks/tasks-crud.cy.ts +45 -38
- package/templates/contents/themes/starter/tests/cypress/fixtures/entities.json +16 -0
- package/templates/contents/themes/starter/tests/cypress/src/components/DevKeyringPOM.ts +3 -1
- package/templates/contents/themes/starter/tests/cypress/src/core/BlockEditorBasePOM.ts +3 -3
- package/templates/contents/themes/starter/tests/cypress/src/entities/PagesPOM.ts +137 -0
- package/templates/contents/themes/starter/tests/cypress/src/entities/index.ts +2 -0
- package/templates/contents/themes/starter/tests/cypress/src/index.ts +1 -0
- package/templates/contents/themes/starter/tests/cypress/src/session-helpers.ts +42 -11
- package/templates/contents/themes/starter/tests/cypress/support/commands.ts +29 -18
- package/templates/features/blog/blocks/post-content/component.tsx +5 -1
- package/templates/features/blog/blocks/post-content/schema.ts +1 -1
- package/templates/features/pages/blocks/hero/component.tsx +3 -0
- package/templates/features/pages/blocks/hero/schema.ts +1 -1
- package/templates/proxy.ts +138 -53
- package/tests/jest/__mocks__/@nextsparkjs/registries/block-registry.client.ts +9 -0
- package/tests/jest/__mocks__/@nextsparkjs/registries/block-registry.lazy.ts +5 -0
- package/tests/jest/__mocks__/@nextsparkjs/registries/icon-registry.ts +42 -0
- package/tests/jest/__mocks__/next-intl-server.js +85 -5
- package/tests/jest/__mocks__/next-server.js +32 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BlockConfig } from '
|
|
1
|
+
import type { BlockConfig } from '@nextsparkjs/core/types/blocks'
|
|
2
2
|
|
|
3
3
|
export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Component' | 'examples'> = {
|
|
4
4
|
slug: 'features-grid',
|
|
@@ -6,5 +6,6 @@ export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Componen
|
|
|
6
6
|
description: 'Grid layout displaying multiple features with icons, titles, and descriptions',
|
|
7
7
|
category: 'content',
|
|
8
8
|
icon: 'Grid',
|
|
9
|
-
thumbnail: '/theme/blocks/features-grid/thumbnail.png'
|
|
9
|
+
thumbnail: '/theme/blocks/features-grid/thumbnail.png',
|
|
10
|
+
scope: ['pages']
|
|
10
11
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { FieldDefinition } from '
|
|
1
|
+
import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
|
|
2
2
|
import {
|
|
3
3
|
baseContentFields,
|
|
4
4
|
baseDesignFields,
|
|
5
5
|
baseAdvancedFields,
|
|
6
|
-
} from '
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Features Grid Block Field Definitions
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
|
-
import { baseBlockSchema } from '
|
|
2
|
+
import { baseBlockSchema } from '@nextsparkjs/core/types/blocks'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Feature Item Schema
|
|
@@ -35,6 +35,6 @@ export const featuresGridSpecificSchema = z.object({
|
|
|
35
35
|
/**
|
|
36
36
|
* Complete Features Grid Block Schema
|
|
37
37
|
*/
|
|
38
|
-
export const schema = baseBlockSchema.
|
|
38
|
+
export const schema = baseBlockSchema.extend(featuresGridSpecificSchema.shape)
|
|
39
39
|
|
|
40
40
|
export type FeaturesGridBlockProps = z.infer<typeof schema>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { Button } from '
|
|
3
|
-
import { cn } from '
|
|
4
|
-
import { buildSectionClasses, resolveMediaUrl } from '
|
|
2
|
+
import { Button } from '@nextsparkjs/core/components/ui/button'
|
|
3
|
+
import { cn } from '@nextsparkjs/core/lib/utils'
|
|
4
|
+
import { buildSectionClasses, resolveMediaUrl } from '@nextsparkjs/core/types/blocks'
|
|
5
5
|
import type { HeroBlockProps } from './schema'
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -100,3 +100,6 @@ export function HeroBlock({
|
|
|
100
100
|
</section>
|
|
101
101
|
)
|
|
102
102
|
}
|
|
103
|
+
|
|
104
|
+
// The generated block registry imports this as the module's default.
|
|
105
|
+
export default HeroBlock
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BlockConfig } from '
|
|
1
|
+
import type { BlockConfig } from '@nextsparkjs/core/types/blocks'
|
|
2
2
|
|
|
3
3
|
export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Component' | 'examples'> = {
|
|
4
4
|
slug: 'hero',
|
|
@@ -6,5 +6,6 @@ export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Componen
|
|
|
6
6
|
description: 'Full-width hero section with title, subtitle, CTA button, and background image',
|
|
7
7
|
category: 'hero',
|
|
8
8
|
icon: 'Rocket',
|
|
9
|
-
thumbnail: '/theme/blocks/hero/thumbnail.png'
|
|
9
|
+
thumbnail: '/theme/blocks/hero/thumbnail.png',
|
|
10
|
+
scope: ['pages', 'posts']
|
|
10
11
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { FieldDefinition } from '
|
|
1
|
+
import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
|
|
2
2
|
import {
|
|
3
3
|
baseContentFields,
|
|
4
4
|
baseDesignFields,
|
|
5
5
|
baseAdvancedFields,
|
|
6
|
-
} from '
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Hero Block Field Definitions
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
baseBlockSchema,
|
|
4
4
|
mediaRefSchema,
|
|
5
5
|
type BaseBlockProps,
|
|
6
|
-
} from '
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Hero Block Schema
|
|
@@ -25,7 +25,7 @@ export const heroSpecificSchema = z.object({
|
|
|
25
25
|
* Complete Hero Block Schema
|
|
26
26
|
* Combines base fields + hero-specific fields
|
|
27
27
|
*/
|
|
28
|
-
export const schema = baseBlockSchema.
|
|
28
|
+
export const schema = baseBlockSchema.extend(heroSpecificSchema.shape)
|
|
29
29
|
|
|
30
30
|
export type HeroBlockProps = z.infer<typeof schema>
|
|
31
31
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
2
|
import { Quote } from 'lucide-react'
|
|
3
|
-
import { Avatar, AvatarFallback, AvatarImage } from '
|
|
4
|
-
import { cn } from '
|
|
5
|
-
import { buildSectionClasses, resolveMediaUrl } from '
|
|
3
|
+
import { Avatar, AvatarFallback, AvatarImage } from '@nextsparkjs/core/components/ui/avatar'
|
|
4
|
+
import { cn } from '@nextsparkjs/core/lib/utils'
|
|
5
|
+
import { buildSectionClasses, resolveMediaUrl } from '@nextsparkjs/core/types/blocks'
|
|
6
6
|
import type { TestimonialsBlockProps, TestimonialItem } from './schema'
|
|
7
7
|
|
|
8
8
|
/**
|
|
@@ -111,3 +111,6 @@ export function TestimonialsBlock({
|
|
|
111
111
|
</section>
|
|
112
112
|
)
|
|
113
113
|
}
|
|
114
|
+
|
|
115
|
+
// The generated block registry imports this as the module's default.
|
|
116
|
+
export default TestimonialsBlock
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BlockConfig } from '
|
|
1
|
+
import type { BlockConfig } from '@nextsparkjs/core/types/blocks'
|
|
2
2
|
|
|
3
3
|
export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Component' | 'examples'> = {
|
|
4
4
|
slug: 'testimonials',
|
|
@@ -6,5 +6,6 @@ export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Componen
|
|
|
6
6
|
description: 'Display customer testimonials with quotes, authors, and avatars',
|
|
7
7
|
category: 'testimonials',
|
|
8
8
|
icon: 'Quote',
|
|
9
|
-
thumbnail: '/theme/blocks/testimonials/thumbnail.png'
|
|
9
|
+
thumbnail: '/theme/blocks/testimonials/thumbnail.png',
|
|
10
|
+
scope: ['pages']
|
|
10
11
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { FieldDefinition } from '
|
|
1
|
+
import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
|
|
2
2
|
import {
|
|
3
3
|
baseContentFields,
|
|
4
4
|
baseDesignFields,
|
|
5
5
|
baseAdvancedFields,
|
|
6
|
-
} from '
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Testimonials Block Field Definitions
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
|
-
import { baseBlockSchema, mediaRefSchema } from '
|
|
2
|
+
import { baseBlockSchema, mediaRefSchema } from '@nextsparkjs/core/types/blocks'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Testimonial Item Schema
|
|
@@ -36,6 +36,6 @@ export const testimonialsSpecificSchema = z.object({
|
|
|
36
36
|
/**
|
|
37
37
|
* Complete Testimonials Block Schema
|
|
38
38
|
*/
|
|
39
|
-
export const schema = baseBlockSchema.
|
|
39
|
+
export const schema = baseBlockSchema.extend(testimonialsSpecificSchema.shape)
|
|
40
40
|
|
|
41
41
|
export type TestimonialsBlockProps = z.infer<typeof schema>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import React from 'react'
|
|
2
|
-
import { cn } from '
|
|
3
|
-
import { buildSectionClasses } from '
|
|
2
|
+
import { cn } from '@nextsparkjs/core/lib/utils'
|
|
3
|
+
import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
|
|
4
|
+
import { sanitizeBlockHtml } from '@nextsparkjs/core/lib/blocks/sanitize-html'
|
|
4
5
|
import type { TextContentBlockProps } from './schema'
|
|
5
6
|
|
|
6
7
|
/**
|
|
@@ -70,7 +71,7 @@ export function TextContentBlock({
|
|
|
70
71
|
maxWidthClasses[maxWidth],
|
|
71
72
|
alignmentClasses[alignment]
|
|
72
73
|
)}
|
|
73
|
-
dangerouslySetInnerHTML={{ __html: content }}
|
|
74
|
+
dangerouslySetInnerHTML={{ __html: sanitizeBlockHtml(content) }}
|
|
74
75
|
/>
|
|
75
76
|
|
|
76
77
|
{/* Optional CTA */}
|
|
@@ -94,3 +95,6 @@ export function TextContentBlock({
|
|
|
94
95
|
</section>
|
|
95
96
|
)
|
|
96
97
|
}
|
|
98
|
+
|
|
99
|
+
// The generated block registry imports this as the module's default.
|
|
100
|
+
export default TextContentBlock
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { BlockConfig } from '
|
|
1
|
+
import type { BlockConfig } from '@nextsparkjs/core/types/blocks'
|
|
2
2
|
|
|
3
3
|
export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Component' | 'examples'> = {
|
|
4
4
|
slug: 'text-content',
|
|
@@ -6,5 +6,6 @@ export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Componen
|
|
|
6
6
|
description: 'Rich text content block for paragraphs, lists, and formatted text',
|
|
7
7
|
category: 'content',
|
|
8
8
|
icon: 'FileText',
|
|
9
|
-
thumbnail: '/theme/blocks/text-content/thumbnail.png'
|
|
9
|
+
thumbnail: '/theme/blocks/text-content/thumbnail.png',
|
|
10
|
+
scope: ['pages']
|
|
10
11
|
}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import type { FieldDefinition } from '
|
|
1
|
+
import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
|
|
2
2
|
import {
|
|
3
3
|
baseContentFields,
|
|
4
4
|
baseDesignFields,
|
|
5
5
|
baseAdvancedFields,
|
|
6
|
-
} from '
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Text Content Block Field Definitions
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from 'zod'
|
|
2
|
-
import { baseBlockSchema } from '
|
|
2
|
+
import { baseBlockSchema } from '@nextsparkjs/core/types/blocks'
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Text Content Block Schema
|
|
@@ -25,6 +25,6 @@ export const textContentSpecificSchema = z.object({
|
|
|
25
25
|
* Complete Text Content Block Schema
|
|
26
26
|
* Note: textContentSpecificSchema.content overrides baseBlockSchema.content
|
|
27
27
|
*/
|
|
28
|
-
export const schema = baseBlockSchema.
|
|
28
|
+
export const schema = baseBlockSchema.extend(textContentSpecificSchema.shape)
|
|
29
29
|
|
|
30
30
|
export type TextContentBlockProps = z.infer<typeof schema>
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
import { Button } from '@nextsparkjs/core/components/ui/button'
|
|
3
|
+
import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
|
|
4
|
+
import type { CTASectionBlockProps } from './schema'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* CTA Section Block Component
|
|
8
|
+
*
|
|
9
|
+
* Props from 3-tab structure:
|
|
10
|
+
* - Content: title, content, cta (primary), secondaryButton
|
|
11
|
+
* - Design: backgroundColor
|
|
12
|
+
* - Advanced: className, id
|
|
13
|
+
*/
|
|
14
|
+
export function CTASectionBlock({
|
|
15
|
+
// Base content props
|
|
16
|
+
title,
|
|
17
|
+
content,
|
|
18
|
+
cta,
|
|
19
|
+
// CTA-specific content
|
|
20
|
+
secondaryButton,
|
|
21
|
+
// Base design props
|
|
22
|
+
backgroundColor,
|
|
23
|
+
// Base advanced props
|
|
24
|
+
className,
|
|
25
|
+
id,
|
|
26
|
+
// Legacy props for backward compatibility
|
|
27
|
+
...legacyProps
|
|
28
|
+
}: CTASectionBlockProps & {
|
|
29
|
+
buttonText?: string
|
|
30
|
+
buttonLink?: string
|
|
31
|
+
primaryButton?: { text: string; link: string; variant?: string }
|
|
32
|
+
description?: string
|
|
33
|
+
}) {
|
|
34
|
+
// Handle legacy format (buttonText/buttonLink or primaryButton)
|
|
35
|
+
const primaryCta = cta || (legacyProps.primaryButton ? {
|
|
36
|
+
text: legacyProps.primaryButton.text,
|
|
37
|
+
link: legacyProps.primaryButton.link,
|
|
38
|
+
target: '_self' as const,
|
|
39
|
+
} : legacyProps.buttonText ? {
|
|
40
|
+
text: legacyProps.buttonText,
|
|
41
|
+
link: legacyProps.buttonLink || '#',
|
|
42
|
+
target: '_self' as const,
|
|
43
|
+
} : undefined)
|
|
44
|
+
|
|
45
|
+
// Handle legacy description prop
|
|
46
|
+
const displayContent = content || (legacyProps as { description?: string }).description
|
|
47
|
+
|
|
48
|
+
// Build section classes with background and custom className
|
|
49
|
+
const sectionClasses = buildSectionClasses(
|
|
50
|
+
'py-16 px-4 @md:py-24',
|
|
51
|
+
{ backgroundColor, className }
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
return (
|
|
55
|
+
<section id={id} className={sectionClasses} data-cy="block-cta-section">
|
|
56
|
+
<div className="container mx-auto max-w-4xl text-center">
|
|
57
|
+
{title && (
|
|
58
|
+
<h2 className="mb-4 text-4xl font-bold @md:text-5xl">{title}</h2>
|
|
59
|
+
)}
|
|
60
|
+
|
|
61
|
+
{displayContent && (
|
|
62
|
+
<p className="mb-8 text-lg @md:text-xl opacity-90">{displayContent}</p>
|
|
63
|
+
)}
|
|
64
|
+
|
|
65
|
+
{(primaryCta || secondaryButton) && (
|
|
66
|
+
<div className="flex flex-col gap-4 @sm:flex-row @sm:justify-center">
|
|
67
|
+
{primaryCta && (
|
|
68
|
+
<Button asChild size="lg">
|
|
69
|
+
<a
|
|
70
|
+
href={primaryCta.link}
|
|
71
|
+
target={primaryCta.target}
|
|
72
|
+
rel={primaryCta.target === '_blank' ? 'noopener noreferrer' : undefined}
|
|
73
|
+
>
|
|
74
|
+
{primaryCta.text}
|
|
75
|
+
</a>
|
|
76
|
+
</Button>
|
|
77
|
+
)}
|
|
78
|
+
|
|
79
|
+
{secondaryButton && (
|
|
80
|
+
<Button
|
|
81
|
+
asChild
|
|
82
|
+
size="lg"
|
|
83
|
+
variant={secondaryButton.variant || 'outline'}
|
|
84
|
+
>
|
|
85
|
+
<a
|
|
86
|
+
href={secondaryButton.link}
|
|
87
|
+
target={secondaryButton.target}
|
|
88
|
+
rel={secondaryButton.target === '_blank' ? 'noopener noreferrer' : undefined}
|
|
89
|
+
>
|
|
90
|
+
{secondaryButton.text}
|
|
91
|
+
</a>
|
|
92
|
+
</Button>
|
|
93
|
+
)}
|
|
94
|
+
</div>
|
|
95
|
+
)}
|
|
96
|
+
</div>
|
|
97
|
+
</section>
|
|
98
|
+
)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// The generated block registry imports this as the module's default.
|
|
102
|
+
export default CTASectionBlock
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BlockConfig } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
|
|
3
|
+
export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Component' | 'examples'> = {
|
|
4
|
+
slug: 'cta-section',
|
|
5
|
+
name: 'CTA Section',
|
|
6
|
+
description: 'Call-to-action section with title, description, and action buttons',
|
|
7
|
+
category: 'cta',
|
|
8
|
+
icon: 'Megaphone',
|
|
9
|
+
thumbnail: '/theme/blocks/cta-section/thumbnail.png',
|
|
10
|
+
scope: ['pages']
|
|
11
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import type { FieldDefinition } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
import {
|
|
3
|
+
baseContentFields,
|
|
4
|
+
baseDesignFields,
|
|
5
|
+
baseAdvancedFields,
|
|
6
|
+
} from '@nextsparkjs/core/types/blocks'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* CTA Section Block Field Definitions
|
|
10
|
+
*
|
|
11
|
+
* Organized into 3 tabs:
|
|
12
|
+
* - Content: title, description, cta (from base) + secondaryButton
|
|
13
|
+
* - Design: backgroundColor (from base)
|
|
14
|
+
* - Advanced: className, id (from base)
|
|
15
|
+
*
|
|
16
|
+
* Note: The base CTA fields serve as the primary button
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
// CTA-specific content fields (secondary button) - grouped in UI
|
|
20
|
+
const ctaContentFields: FieldDefinition[] = [
|
|
21
|
+
{
|
|
22
|
+
name: 'secondaryButton.text',
|
|
23
|
+
label: 'Text',
|
|
24
|
+
type: 'text',
|
|
25
|
+
tab: 'content',
|
|
26
|
+
required: false,
|
|
27
|
+
placeholder: 'Learn More',
|
|
28
|
+
helpText: 'Button text',
|
|
29
|
+
group: 'secondaryButton',
|
|
30
|
+
groupLabel: 'Secondary Button',
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
name: 'secondaryButton.link',
|
|
34
|
+
label: 'Link',
|
|
35
|
+
type: 'url',
|
|
36
|
+
tab: 'content',
|
|
37
|
+
required: false,
|
|
38
|
+
placeholder: '/about or https://...',
|
|
39
|
+
helpText: 'URL the button links to',
|
|
40
|
+
group: 'secondaryButton',
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
name: 'secondaryButton.target',
|
|
44
|
+
label: 'Open in',
|
|
45
|
+
type: 'select',
|
|
46
|
+
tab: 'content',
|
|
47
|
+
required: false,
|
|
48
|
+
default: '_self',
|
|
49
|
+
helpText: 'How the link opens',
|
|
50
|
+
group: 'secondaryButton',
|
|
51
|
+
options: [
|
|
52
|
+
{ label: 'Same window', value: '_self' },
|
|
53
|
+
{ label: 'New tab', value: '_blank' },
|
|
54
|
+
],
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
name: 'secondaryButton.variant',
|
|
58
|
+
label: 'Style',
|
|
59
|
+
type: 'select',
|
|
60
|
+
tab: 'content',
|
|
61
|
+
required: false,
|
|
62
|
+
default: 'outline',
|
|
63
|
+
helpText: 'Visual style of the button',
|
|
64
|
+
group: 'secondaryButton',
|
|
65
|
+
options: [
|
|
66
|
+
{ label: 'Default', value: 'default' },
|
|
67
|
+
{ label: 'Outline', value: 'outline' },
|
|
68
|
+
{ label: 'Ghost', value: 'ghost' },
|
|
69
|
+
],
|
|
70
|
+
},
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Complete field definitions organized by tab
|
|
75
|
+
*/
|
|
76
|
+
export const fieldDefinitions: FieldDefinition[] = [
|
|
77
|
+
// Content tab: base fields + cta-specific
|
|
78
|
+
...baseContentFields,
|
|
79
|
+
...ctaContentFields,
|
|
80
|
+
|
|
81
|
+
// Design tab: base fields only
|
|
82
|
+
...baseDesignFields,
|
|
83
|
+
|
|
84
|
+
// Advanced tab: base fields only
|
|
85
|
+
...baseAdvancedFields,
|
|
86
|
+
]
|
|
87
|
+
|
|
88
|
+
// Alias for compatibility
|
|
89
|
+
export const fields = fieldDefinitions
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { z } from 'zod'
|
|
2
|
+
import { baseBlockSchema, ctaSchema } from '@nextsparkjs/core/types/blocks'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Secondary Button Schema (CTA-specific)
|
|
6
|
+
* Uses same structure as CTA but with outline variant default
|
|
7
|
+
*/
|
|
8
|
+
const secondaryButtonSchema = ctaSchema.extend({
|
|
9
|
+
variant: z.enum(['default', 'outline', 'ghost']).default('outline'),
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
export type SecondaryButton = z.infer<typeof secondaryButtonSchema>
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* CTA Section Block Schema
|
|
16
|
+
*
|
|
17
|
+
* Extends base schema with:
|
|
18
|
+
* - secondaryButton: Optional secondary CTA button
|
|
19
|
+
*
|
|
20
|
+
* Note: Uses base schema title, description, cta (as primary), backgroundColor, className, id
|
|
21
|
+
*/
|
|
22
|
+
export const ctaSectionSpecificSchema = z.object({
|
|
23
|
+
// Content: secondary button option
|
|
24
|
+
secondaryButton: secondaryButtonSchema.optional(),
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Complete CTA Section Block Schema
|
|
29
|
+
*/
|
|
30
|
+
export const schema = baseBlockSchema.extend(ctaSectionSpecificSchema.shape)
|
|
31
|
+
|
|
32
|
+
export type CTASectionBlockProps = z.infer<typeof schema>
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
// Icon names come from page content, so there is no build-time set to import
|
|
3
|
+
// from the way entity and sidebar icons have (see core's lib/icons). lucide's
|
|
4
|
+
// by-name loader resolves them, but it declares a chunk per icon and that map
|
|
5
|
+
// lands in webpack's runtime, which every route in the app pays for — to spare
|
|
6
|
+
// the few that render this block.
|
|
7
|
+
import * as Icons from 'lucide-react'
|
|
8
|
+
import { cn } from '@nextsparkjs/core/lib/utils'
|
|
9
|
+
import { buildSectionClasses } from '@nextsparkjs/core/types/blocks'
|
|
10
|
+
import type { FeaturesGridBlockProps, FeatureItem } from './schema'
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Features Grid Block Component
|
|
14
|
+
*
|
|
15
|
+
* Props from 3-tab structure:
|
|
16
|
+
* - Content: title, content, cta, items
|
|
17
|
+
* - Design: backgroundColor, columns
|
|
18
|
+
* - Advanced: className, id
|
|
19
|
+
*/
|
|
20
|
+
export function FeaturesGridBlock({
|
|
21
|
+
// Base content props
|
|
22
|
+
title,
|
|
23
|
+
content,
|
|
24
|
+
cta,
|
|
25
|
+
// Features-specific content
|
|
26
|
+
items,
|
|
27
|
+
// Base design props
|
|
28
|
+
backgroundColor,
|
|
29
|
+
// Features-specific design
|
|
30
|
+
columns = '3',
|
|
31
|
+
// Base advanced props
|
|
32
|
+
className,
|
|
33
|
+
id,
|
|
34
|
+
// Legacy props for backward compatibility
|
|
35
|
+
...legacyProps
|
|
36
|
+
}: FeaturesGridBlockProps & { features?: FeatureItem[]; description?: string }) {
|
|
37
|
+
// Handle legacy 'features' prop for backward compatibility
|
|
38
|
+
const safeItems = Array.isArray(items)
|
|
39
|
+
? items
|
|
40
|
+
: Array.isArray((legacyProps as { features?: FeatureItem[] }).features)
|
|
41
|
+
? (legacyProps as { features: FeatureItem[] }).features
|
|
42
|
+
: []
|
|
43
|
+
|
|
44
|
+
// Handle legacy description prop
|
|
45
|
+
const displayContent = content || (legacyProps as { description?: string }).description
|
|
46
|
+
|
|
47
|
+
// Build column classes based on columns prop
|
|
48
|
+
const columnClasses: Record<string, string> = {
|
|
49
|
+
'2': '@sm:grid-cols-2',
|
|
50
|
+
'3': '@sm:grid-cols-2 @lg:grid-cols-3',
|
|
51
|
+
'4': '@sm:grid-cols-2 @lg:grid-cols-4',
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
// Build section classes with background and custom className
|
|
55
|
+
const sectionClasses = buildSectionClasses(
|
|
56
|
+
'py-16 px-4 @md:py-24',
|
|
57
|
+
{ backgroundColor, className }
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
return (
|
|
61
|
+
<section id={id} className={sectionClasses} data-cy="block-features-grid">
|
|
62
|
+
<div className="container mx-auto max-w-6xl">
|
|
63
|
+
{/* Section Header */}
|
|
64
|
+
{(title || displayContent) && (
|
|
65
|
+
<div className="mb-12 text-center">
|
|
66
|
+
{title && (
|
|
67
|
+
<h2 className="mb-4 text-4xl font-bold @md:text-5xl">
|
|
68
|
+
{title}
|
|
69
|
+
</h2>
|
|
70
|
+
)}
|
|
71
|
+
{displayContent && (
|
|
72
|
+
<p className="mx-auto max-w-2xl text-lg text-muted-foreground">
|
|
73
|
+
{displayContent}
|
|
74
|
+
</p>
|
|
75
|
+
)}
|
|
76
|
+
</div>
|
|
77
|
+
)}
|
|
78
|
+
|
|
79
|
+
{/* Features Grid */}
|
|
80
|
+
<div className={cn('grid gap-8', columnClasses[columns] || columnClasses['3'])}>
|
|
81
|
+
{safeItems.map((item, index) => {
|
|
82
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
83
|
+
const IconComponent = (Icons as any)[item.icon] || Icons.Circle
|
|
84
|
+
|
|
85
|
+
return (
|
|
86
|
+
<div
|
|
87
|
+
key={index}
|
|
88
|
+
className="flex flex-col items-center text-center p-6 rounded-lg border bg-card"
|
|
89
|
+
>
|
|
90
|
+
<div className="mb-4 rounded-full bg-primary/10 p-4">
|
|
91
|
+
<IconComponent className="h-8 w-8 text-primary" />
|
|
92
|
+
</div>
|
|
93
|
+
<h3 className="mb-2 text-xl font-semibold">{item.title}</h3>
|
|
94
|
+
<p className="text-muted-foreground">{item.description}</p>
|
|
95
|
+
</div>
|
|
96
|
+
)
|
|
97
|
+
})}
|
|
98
|
+
</div>
|
|
99
|
+
|
|
100
|
+
{/* Optional CTA */}
|
|
101
|
+
{cta && (
|
|
102
|
+
<div className="mt-12 text-center">
|
|
103
|
+
<a
|
|
104
|
+
href={cta.link}
|
|
105
|
+
target={cta.target}
|
|
106
|
+
rel={cta.target === '_blank' ? 'noopener noreferrer' : undefined}
|
|
107
|
+
className="inline-flex items-center justify-center rounded-md bg-primary px-8 py-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors"
|
|
108
|
+
>
|
|
109
|
+
{cta.text}
|
|
110
|
+
</a>
|
|
111
|
+
</div>
|
|
112
|
+
)}
|
|
113
|
+
</div>
|
|
114
|
+
</section>
|
|
115
|
+
)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
// The generated block registry imports this as the module's default.
|
|
119
|
+
export default FeaturesGridBlock
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { BlockConfig } from '@nextsparkjs/core/types/blocks'
|
|
2
|
+
|
|
3
|
+
export const config: Omit<BlockConfig, 'schema' | 'fieldDefinitions' | 'Component' | 'examples'> = {
|
|
4
|
+
slug: 'features-grid',
|
|
5
|
+
name: 'Features Grid',
|
|
6
|
+
description: 'Grid layout displaying multiple features with icons, titles, and descriptions',
|
|
7
|
+
category: 'content',
|
|
8
|
+
icon: 'Grid',
|
|
9
|
+
thumbnail: '/theme/blocks/features-grid/thumbnail.png',
|
|
10
|
+
scope: ['pages']
|
|
11
|
+
}
|