@xiwebdesign/xicms-core 4.17.1
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/XiCMSProvider.d.ts +58 -0
- package/dist/XiCMSProvider.js +165 -0
- package/dist/XiCMSProvider.js.map +1 -0
- package/dist/admin/AdminApp.d.ts +4 -0
- package/dist/admin/AdminApp.js +62 -0
- package/dist/admin/AdminApp.js.map +1 -0
- package/dist/admin/AdminHelp.d.ts +2 -0
- package/dist/admin/AdminHelp.js +65 -0
- package/dist/admin/AdminHelp.js.map +1 -0
- package/dist/admin/NewsEditor.d.ts +2 -0
- package/dist/admin/NewsEditor.js +171 -0
- package/dist/admin/NewsEditor.js.map +1 -0
- package/dist/admin/SuperadminPanel.d.ts +4 -0
- package/dist/admin/SuperadminPanel.js +101 -0
- package/dist/admin/SuperadminPanel.js.map +1 -0
- package/dist/admin/blockEditors/StyleEditor.d.ts +10 -0
- package/dist/admin/blockEditors/StyleEditor.js +78 -0
- package/dist/admin/blockEditors/StyleEditor.js.map +1 -0
- package/dist/admin/blockEditors/index.d.ts +16 -0
- package/dist/admin/blockEditors/index.js +1602 -0
- package/dist/admin/blockEditors/index.js.map +1 -0
- package/dist/admin/editors/RichTextEditor.d.ts +10 -0
- package/dist/admin/editors/RichTextEditor.js +86 -0
- package/dist/admin/editors/RichTextEditor.js.map +1 -0
- package/dist/admin/forms/FormsPanel.d.ts +3 -0
- package/dist/admin/forms/FormsPanel.js +203 -0
- package/dist/admin/forms/FormsPanel.js.map +1 -0
- package/dist/admin/index.d.ts +21 -0
- package/dist/admin/index.js +38 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/lib/compressImage.d.ts +12 -0
- package/dist/admin/lib/compressImage.js +53 -0
- package/dist/admin/lib/compressImage.js.map +1 -0
- package/dist/admin/lib/mediaUsage.d.ts +9 -0
- package/dist/admin/lib/mediaUsage.js +25 -0
- package/dist/admin/lib/mediaUsage.js.map +1 -0
- package/dist/admin/lib/pagesClient.d.ts +38 -0
- package/dist/admin/lib/pagesClient.js +143 -0
- package/dist/admin/lib/pagesClient.js.map +1 -0
- package/dist/admin/lib/slugify.d.ts +2 -0
- package/dist/admin/lib/slugify.js +7 -0
- package/dist/admin/lib/slugify.js.map +1 -0
- package/dist/admin/lib/upload.d.ts +13 -0
- package/dist/admin/lib/upload.js +40 -0
- package/dist/admin/lib/upload.js.map +1 -0
- package/dist/admin/lib/zodFields.d.ts +27 -0
- package/dist/admin/lib/zodFields.js +48 -0
- package/dist/admin/lib/zodFields.js.map +1 -0
- package/dist/admin/media/MediaManager.d.ts +3 -0
- package/dist/admin/media/MediaManager.js +132 -0
- package/dist/admin/media/MediaManager.js.map +1 -0
- package/dist/admin/media/MediaPicker.d.ts +24 -0
- package/dist/admin/media/MediaPicker.js +93 -0
- package/dist/admin/media/MediaPicker.js.map +1 -0
- package/dist/admin/pages/PageEditor.d.ts +5 -0
- package/dist/admin/pages/PageEditor.js +239 -0
- package/dist/admin/pages/PageEditor.js.map +1 -0
- package/dist/admin/pages/PagesPanel.d.ts +3 -0
- package/dist/admin/pages/PagesPanel.js +92 -0
- package/dist/admin/pages/PagesPanel.js.map +1 -0
- package/dist/admin/panelRegistry.d.ts +20 -0
- package/dist/admin/panelRegistry.js +23 -0
- package/dist/admin/panelRegistry.js.map +1 -0
- package/dist/admin/patterns/PatternInserter.d.ts +10 -0
- package/dist/admin/patterns/PatternInserter.js +58 -0
- package/dist/admin/patterns/PatternInserter.js.map +1 -0
- package/dist/admin/settings/SettingsPanel.d.ts +3 -0
- package/dist/admin/settings/SettingsPanel.js +304 -0
- package/dist/admin/settings/SettingsPanel.js.map +1 -0
- package/dist/admin/settings/moduleSettingsForm.d.ts +12 -0
- package/dist/admin/settings/moduleSettingsForm.js +45 -0
- package/dist/admin/settings/moduleSettingsForm.js.map +1 -0
- package/dist/admin/stats/StatsPanel.d.ts +4 -0
- package/dist/admin/stats/StatsPanel.js +80 -0
- package/dist/admin/stats/StatsPanel.js.map +1 -0
- package/dist/admin/ui/ArrayEditor.d.ts +16 -0
- package/dist/admin/ui/ArrayEditor.js +38 -0
- package/dist/admin/ui/ArrayEditor.js.map +1 -0
- package/dist/admin/ui/ConfirmDialog.d.ts +22 -0
- package/dist/admin/ui/ConfirmDialog.js +47 -0
- package/dist/admin/ui/ConfirmDialog.js.map +1 -0
- package/dist/admin/ui/cn.d.ts +3 -0
- package/dist/admin/ui/cn.js +9 -0
- package/dist/admin/ui/cn.js.map +1 -0
- package/dist/admin/ui/dialog.d.ts +9 -0
- package/dist/admin/ui/dialog.js +47 -0
- package/dist/admin/ui/dialog.js.map +1 -0
- package/dist/admin/ui/index.d.ts +7 -0
- package/dist/admin/ui/index.js +29 -0
- package/dist/admin/ui/index.js.map +1 -0
- package/dist/admin/ui/primitives.d.ts +37 -0
- package/dist/admin/ui/primitives.js +137 -0
- package/dist/admin/ui/primitives.js.map +1 -0
- package/dist/admin/ui/select.d.ts +11 -0
- package/dist/admin/ui/select.js +27 -0
- package/dist/admin/ui/select.js.map +1 -0
- package/dist/admin/ui/switch.d.ts +6 -0
- package/dist/admin/ui/switch.js +22 -0
- package/dist/admin/ui/switch.js.map +1 -0
- package/dist/admin/ui/tabs.d.ts +5 -0
- package/dist/admin/ui/tabs.js +36 -0
- package/dist/admin/ui/tabs.js.map +1 -0
- package/dist/admin/ui/toast.d.ts +19 -0
- package/dist/admin/ui/toast.js +24 -0
- package/dist/admin/ui/toast.js.map +1 -0
- package/dist/admin/visual/VisualEditor.d.ts +10 -0
- package/dist/admin/visual/VisualEditor.js +597 -0
- package/dist/admin/visual/VisualEditor.js.map +1 -0
- package/dist/admin/visual/reorder.d.ts +6 -0
- package/dist/admin/visual/reorder.js +12 -0
- package/dist/admin/visual/reorder.js.map +1 -0
- package/dist/admin.css +1 -0
- package/dist/auth/AuthProvider.d.ts +30 -0
- package/dist/auth/AuthProvider.js +110 -0
- package/dist/auth/AuthProvider.js.map +1 -0
- package/dist/auth/LoginForm.d.ts +4 -0
- package/dist/auth/LoginForm.js +122 -0
- package/dist/auth/LoginForm.js.map +1 -0
- package/dist/auth/roles.d.ts +15 -0
- package/dist/auth/roles.js +21 -0
- package/dist/auth/roles.js.map +1 -0
- package/dist/blocks/BlockErrorBoundary.d.ts +32 -0
- package/dist/blocks/BlockErrorBoundary.js +39 -0
- package/dist/blocks/BlockErrorBoundary.js.map +1 -0
- package/dist/blocks/BlockRenderer.d.ts +15 -0
- package/dist/blocks/BlockRenderer.js +24 -0
- package/dist/blocks/BlockRenderer.js.map +1 -0
- package/dist/blocks/blockStyle.d.ts +14 -0
- package/dist/blocks/blockStyle.js +14 -0
- package/dist/blocks/blockStyle.js.map +1 -0
- package/dist/blocks/builtins/Accordion.d.ts +2 -0
- package/dist/blocks/builtins/Accordion.js +45 -0
- package/dist/blocks/builtins/Accordion.js.map +1 -0
- package/dist/blocks/builtins/Agenda.d.ts +23 -0
- package/dist/blocks/builtins/Agenda.js +102 -0
- package/dist/blocks/builtins/Agenda.js.map +1 -0
- package/dist/blocks/builtins/Banner.d.ts +2 -0
- package/dist/blocks/builtins/Banner.js +45 -0
- package/dist/blocks/builtins/Banner.js.map +1 -0
- package/dist/blocks/builtins/BeforeAfter.d.ts +2 -0
- package/dist/blocks/builtins/BeforeAfter.js +44 -0
- package/dist/blocks/builtins/BeforeAfter.js.map +1 -0
- package/dist/blocks/builtins/Booking.d.ts +2 -0
- package/dist/blocks/builtins/Booking.js +27 -0
- package/dist/blocks/builtins/Booking.js.map +1 -0
- package/dist/blocks/builtins/Breadcrumbs.d.ts +10 -0
- package/dist/blocks/builtins/Breadcrumbs.js +73 -0
- package/dist/blocks/builtins/Breadcrumbs.js.map +1 -0
- package/dist/blocks/builtins/Cards.d.ts +2 -0
- package/dist/blocks/builtins/Cards.js +94 -0
- package/dist/blocks/builtins/Cards.js.map +1 -0
- package/dist/blocks/builtins/Columns.d.ts +2 -0
- package/dist/blocks/builtins/Columns.js +22 -0
- package/dist/blocks/builtins/Columns.js.map +1 -0
- package/dist/blocks/builtins/Contact.d.ts +7 -0
- package/dist/blocks/builtins/Contact.js +121 -0
- package/dist/blocks/builtins/Contact.js.map +1 -0
- package/dist/blocks/builtins/Countdown.d.ts +18 -0
- package/dist/blocks/builtins/Countdown.js +65 -0
- package/dist/blocks/builtins/Countdown.js.map +1 -0
- package/dist/blocks/builtins/Cta.d.ts +2 -0
- package/dist/blocks/builtins/Cta.js +52 -0
- package/dist/blocks/builtins/Cta.js.map +1 -0
- package/dist/blocks/builtins/Downloads.d.ts +2 -0
- package/dist/blocks/builtins/Downloads.js +32 -0
- package/dist/blocks/builtins/Downloads.js.map +1 -0
- package/dist/blocks/builtins/Elements.d.ts +4 -0
- package/dist/blocks/builtins/Elements.js +64 -0
- package/dist/blocks/builtins/Elements.js.map +1 -0
- package/dist/blocks/builtins/Embed.d.ts +2 -0
- package/dist/blocks/builtins/Embed.js +30 -0
- package/dist/blocks/builtins/Embed.js.map +1 -0
- package/dist/blocks/builtins/Faq.d.ts +6 -0
- package/dist/blocks/builtins/Faq.js +110 -0
- package/dist/blocks/builtins/Faq.js.map +1 -0
- package/dist/blocks/builtins/FormBlock.d.ts +2 -0
- package/dist/blocks/builtins/FormBlock.js +221 -0
- package/dist/blocks/builtins/FormBlock.js.map +1 -0
- package/dist/blocks/builtins/Gallery.d.ts +23 -0
- package/dist/blocks/builtins/Gallery.js +177 -0
- package/dist/blocks/builtins/Gallery.js.map +1 -0
- package/dist/blocks/builtins/Hero.d.ts +2 -0
- package/dist/blocks/builtins/Hero.js +47 -0
- package/dist/blocks/builtins/Hero.js.map +1 -0
- package/dist/blocks/builtins/ImageBlock.d.ts +2 -0
- package/dist/blocks/builtins/ImageBlock.js +24 -0
- package/dist/blocks/builtins/ImageBlock.js.map +1 -0
- package/dist/blocks/builtins/Jobs.d.ts +8 -0
- package/dist/blocks/builtins/Jobs.js +65 -0
- package/dist/blocks/builtins/Jobs.js.map +1 -0
- package/dist/blocks/builtins/Layout.d.ts +3 -0
- package/dist/blocks/builtins/Layout.js +67 -0
- package/dist/blocks/builtins/Layout.js.map +1 -0
- package/dist/blocks/builtins/MapBlock.d.ts +2 -0
- package/dist/blocks/builtins/MapBlock.js +31 -0
- package/dist/blocks/builtins/MapBlock.js.map +1 -0
- package/dist/blocks/builtins/NewsListBlock.d.ts +2 -0
- package/dist/blocks/builtins/NewsListBlock.js +24 -0
- package/dist/blocks/builtins/NewsListBlock.js.map +1 -0
- package/dist/blocks/builtins/Newsletter.d.ts +2 -0
- package/dist/blocks/builtins/Newsletter.js +84 -0
- package/dist/blocks/builtins/Newsletter.js.map +1 -0
- package/dist/blocks/builtins/OpenNowBadge.d.ts +9 -0
- package/dist/blocks/builtins/OpenNowBadge.js +20 -0
- package/dist/blocks/builtins/OpenNowBadge.js.map +1 -0
- package/dist/blocks/builtins/OpeningHours.d.ts +2 -0
- package/dist/blocks/builtins/OpeningHours.js +47 -0
- package/dist/blocks/builtins/OpeningHours.js.map +1 -0
- package/dist/blocks/builtins/PdfBlock.d.ts +2 -0
- package/dist/blocks/builtins/PdfBlock.js +97 -0
- package/dist/blocks/builtins/PdfBlock.js.map +1 -0
- package/dist/blocks/builtins/Portfolio.d.ts +2 -0
- package/dist/blocks/builtins/Portfolio.js +94 -0
- package/dist/blocks/builtins/Portfolio.js.map +1 -0
- package/dist/blocks/builtins/Pricing.d.ts +6 -0
- package/dist/blocks/builtins/Pricing.js +77 -0
- package/dist/blocks/builtins/Pricing.js.map +1 -0
- package/dist/blocks/builtins/RichTextBlock.d.ts +2 -0
- package/dist/blocks/builtins/RichTextBlock.js +18 -0
- package/dist/blocks/builtins/RichTextBlock.js.map +1 -0
- package/dist/blocks/builtins/Search.d.ts +2 -0
- package/dist/blocks/builtins/Search.js +99 -0
- package/dist/blocks/builtins/Search.js.map +1 -0
- package/dist/blocks/builtins/Sections.d.ts +5 -0
- package/dist/blocks/builtins/Sections.js +183 -0
- package/dist/blocks/builtins/Sections.js.map +1 -0
- package/dist/blocks/builtins/Slider.d.ts +2 -0
- package/dist/blocks/builtins/Slider.js +131 -0
- package/dist/blocks/builtins/Slider.js.map +1 -0
- package/dist/blocks/builtins/Spacer.d.ts +2 -0
- package/dist/blocks/builtins/Spacer.js +19 -0
- package/dist/blocks/builtins/Spacer.js.map +1 -0
- package/dist/blocks/builtins/Team.d.ts +2 -0
- package/dist/blocks/builtins/Team.js +70 -0
- package/dist/blocks/builtins/Team.js.map +1 -0
- package/dist/blocks/builtins/Testimonials.d.ts +8 -0
- package/dist/blocks/builtins/Testimonials.js +82 -0
- package/dist/blocks/builtins/Testimonials.js.map +1 -0
- package/dist/blocks/builtins/Video.d.ts +9 -0
- package/dist/blocks/builtins/Video.js +77 -0
- package/dist/blocks/builtins/Video.js.map +1 -0
- package/dist/blocks/builtins/WhatsappChat.d.ts +8 -0
- package/dist/blocks/builtins/WhatsappChat.js +51 -0
- package/dist/blocks/builtins/WhatsappChat.js.map +1 -0
- package/dist/blocks/builtins/Widgets.d.ts +13 -0
- package/dist/blocks/builtins/Widgets.js +308 -0
- package/dist/blocks/builtins/Widgets.js.map +1 -0
- package/dist/blocks/builtins/consentEmbed.d.ts +17 -0
- package/dist/blocks/builtins/consentEmbed.js +31 -0
- package/dist/blocks/builtins/consentEmbed.js.map +1 -0
- package/dist/blocks/builtins/index.d.ts +46 -0
- package/dist/blocks/builtins/index.js +121 -0
- package/dist/blocks/builtins/index.js.map +1 -0
- package/dist/blocks/builtins/lib/bookingUrl.d.ts +8 -0
- package/dist/blocks/builtins/lib/bookingUrl.js +50 -0
- package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -0
- package/dist/blocks/builtins/lib/fileIcon.d.ts +2 -0
- package/dist/blocks/builtins/lib/fileIcon.js +45 -0
- package/dist/blocks/builtins/lib/fileIcon.js.map +1 -0
- package/dist/blocks/builtins/lib/ics.d.ts +17 -0
- package/dist/blocks/builtins/lib/ics.js +50 -0
- package/dist/blocks/builtins/lib/ics.js.map +1 -0
- package/dist/blocks/builtins/lib/openingHours.d.ts +20 -0
- package/dist/blocks/builtins/lib/openingHours.js +79 -0
- package/dist/blocks/builtins/lib/openingHours.js.map +1 -0
- package/dist/blocks/builtins/lib/searchRank.d.ts +22 -0
- package/dist/blocks/builtins/lib/searchRank.js +45 -0
- package/dist/blocks/builtins/lib/searchRank.js.map +1 -0
- package/dist/blocks/builtins/lib/submitForm.d.ts +6 -0
- package/dist/blocks/builtins/lib/submitForm.js +14 -0
- package/dist/blocks/builtins/lib/submitForm.js.map +1 -0
- package/dist/blocks/context.d.ts +8 -0
- package/dist/blocks/context.js +20 -0
- package/dist/blocks/context.js.map +1 -0
- package/dist/blocks/index.d.ts +9 -0
- package/dist/blocks/index.js +21 -0
- package/dist/blocks/index.js.map +1 -0
- package/dist/blocks/registry.d.ts +75 -0
- package/dist/blocks/registry.js +71 -0
- package/dist/blocks/registry.js.map +1 -0
- package/dist/blocks/ui/index.d.ts +35 -0
- package/dist/blocks/ui/index.js +48 -0
- package/dist/blocks/ui/index.js.map +1 -0
- package/dist/components/EditBar.d.ts +2 -0
- package/dist/components/EditBar.js +20 -0
- package/dist/components/EditBar.js.map +1 -0
- package/dist/components/EditableImage.d.ts +18 -0
- package/dist/components/EditableImage.js +62 -0
- package/dist/components/EditableImage.js.map +1 -0
- package/dist/components/EditableRichText.d.ts +14 -0
- package/dist/components/EditableRichText.js +26 -0
- package/dist/components/EditableRichText.js.map +1 -0
- package/dist/components/EditableText.d.ts +21 -0
- package/dist/components/EditableText.js +25 -0
- package/dist/components/EditableText.js.map +1 -0
- package/dist/components/News.d.ts +38 -0
- package/dist/components/News.js +128 -0
- package/dist/components/News.js.map +1 -0
- package/dist/components/PageView.d.ts +8 -0
- package/dist/components/PageView.js +28 -0
- package/dist/components/PageView.js.map +1 -0
- package/dist/components/ResponsiveImage.d.ts +16 -0
- package/dist/components/ResponsiveImage.js +39 -0
- package/dist/components/ResponsiveImage.js.map +1 -0
- package/dist/components/site/SiteFooter.d.ts +12 -0
- package/dist/components/site/SiteFooter.js +34 -0
- package/dist/components/site/SiteFooter.js.map +1 -0
- package/dist/config.d.ts +8 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/content/ContentProvider.d.ts +23 -0
- package/dist/content/ContentProvider.js +86 -0
- package/dist/content/ContentProvider.js.map +1 -0
- package/dist/content/types.d.ts +41 -0
- package/dist/content/types.js +1 -0
- package/dist/content/types.js.map +1 -0
- package/dist/demo/DemoStudio.d.ts +7 -0
- package/dist/demo/DemoStudio.js +54 -0
- package/dist/demo/DemoStudio.js.map +1 -0
- package/dist/demo/demoStore.d.ts +26 -0
- package/dist/demo/demoStore.js +115 -0
- package/dist/demo/demoStore.js.map +1 -0
- package/dist/editor/EditorProvider.d.ts +12 -0
- package/dist/editor/EditorProvider.js +22 -0
- package/dist/editor/EditorProvider.js.map +1 -0
- package/dist/firebase/admin.d.ts +7 -0
- package/dist/firebase/admin.js +31 -0
- package/dist/firebase/admin.js.map +1 -0
- package/dist/firebase/appcheck.d.ts +6 -0
- package/dist/firebase/appcheck.js +23 -0
- package/dist/firebase/appcheck.js.map +1 -0
- package/dist/firebase/client.d.ts +9 -0
- package/dist/firebase/client.js +44 -0
- package/dist/firebase/client.js.map +1 -0
- package/dist/firebase/region.d.ts +5 -0
- package/dist/firebase/region.js +7 -0
- package/dist/firebase/region.js.map +1 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +172 -0
- package/dist/index.js.map +1 -0
- package/dist/layers.css +13 -0
- package/dist/lock/DemoLock.d.ts +5 -0
- package/dist/lock/DemoLock.js +35 -0
- package/dist/lock/DemoLock.js.map +1 -0
- package/dist/media/ImageContext.d.ts +41 -0
- package/dist/media/ImageContext.js +74 -0
- package/dist/media/ImageContext.js.map +1 -0
- package/dist/modules/builtins.d.ts +46 -0
- package/dist/modules/builtins.js +462 -0
- package/dist/modules/builtins.js.map +1 -0
- package/dist/modules/consent/ConsentBanner.d.ts +42 -0
- package/dist/modules/consent/ConsentBanner.js +119 -0
- package/dist/modules/consent/ConsentBanner.js.map +1 -0
- package/dist/modules/consent/useConsent.d.ts +28 -0
- package/dist/modules/consent/useConsent.js +52 -0
- package/dist/modules/consent/useConsent.js.map +1 -0
- package/dist/modules/context.d.ts +20 -0
- package/dist/modules/context.js +31 -0
- package/dist/modules/context.js.map +1 -0
- package/dist/modules/contract.d.ts +9 -0
- package/dist/modules/contract.js +38 -0
- package/dist/modules/contract.js.map +1 -0
- package/dist/modules/defineModule.d.ts +11 -0
- package/dist/modules/defineModule.js +7 -0
- package/dist/modules/defineModule.js.map +1 -0
- package/dist/modules/index.d.ts +13 -0
- package/dist/modules/index.js +44 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/overrides.d.ts +17 -0
- package/dist/modules/overrides.js +25 -0
- package/dist/modules/overrides.js.map +1 -0
- package/dist/modules/registry.d.ts +40 -0
- package/dist/modules/registry.js +79 -0
- package/dist/modules/registry.js.map +1 -0
- package/dist/modules/types.d.ts +66 -0
- package/dist/modules/types.js +1 -0
- package/dist/modules/types.js.map +1 -0
- package/dist/patterns/builtins.d.ts +31 -0
- package/dist/patterns/builtins.js +415 -0
- package/dist/patterns/builtins.js.map +1 -0
- package/dist/patterns/index.d.ts +6 -0
- package/dist/patterns/index.js +9 -0
- package/dist/patterns/index.js.map +1 -0
- package/dist/patterns/patterns.d.ts +28 -0
- package/dist/patterns/patterns.js +53 -0
- package/dist/patterns/patterns.js.map +1 -0
- package/dist/render/PageRenderer.d.ts +13 -0
- package/dist/render/PageRenderer.js +14 -0
- package/dist/render/PageRenderer.js.map +1 -0
- package/dist/render/PublishedPage.d.ts +13 -0
- package/dist/render/PublishedPage.js +16 -0
- package/dist/render/PublishedPage.js.map +1 -0
- package/dist/schema/blocks.d.ts +15052 -0
- package/dist/schema/blocks.js +794 -0
- package/dist/schema/blocks.js.map +1 -0
- package/dist/schema/forms.d.ts +111 -0
- package/dist/schema/forms.js +47 -0
- package/dist/schema/forms.js.map +1 -0
- package/dist/schema/index.d.ts +11 -0
- package/dist/schema/index.js +16 -0
- package/dist/schema/index.js.map +1 -0
- package/dist/schema/pages.d.ts +674 -0
- package/dist/schema/pages.js +37 -0
- package/dist/schema/pages.js.map +1 -0
- package/dist/schema/seo.d.ts +29 -0
- package/dist/schema/seo.js +17 -0
- package/dist/schema/seo.js.map +1 -0
- package/dist/schema/settings.d.ts +1126 -0
- package/dist/schema/settings.js +128 -0
- package/dist/schema/settings.js.map +1 -0
- package/dist/schema/siteConfig.d.ts +722 -0
- package/dist/schema/siteConfig.js +39 -0
- package/dist/schema/siteConfig.js.map +1 -0
- package/dist/server/env.d.ts +10 -0
- package/dist/server/env.js +36 -0
- package/dist/server/env.js.map +1 -0
- package/dist/server/index.d.ts +10 -0
- package/dist/server/index.js +51 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/pages.d.ts +15 -0
- package/dist/server/pages.js +99 -0
- package/dist/server/pages.js.map +1 -0
- package/dist/server/sanitize.d.ts +2 -0
- package/dist/server/sanitize.js +55 -0
- package/dist/server/sanitize.js.map +1 -0
- package/dist/server/seo.d.ts +116 -0
- package/dist/server/seo.js +179 -0
- package/dist/server/seo.js.map +1 -0
- package/dist/settings/useSiteSettings.d.ts +25 -0
- package/dist/settings/useSiteSettings.js +68 -0
- package/dist/settings/useSiteSettings.js.map +1 -0
- package/dist/styles.css +2495 -0
- package/dist/theme/presets.d.ts +12 -0
- package/dist/theme/presets.js +147 -0
- package/dist/theme/presets.js.map +1 -0
- package/package.json +112 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/builtins.ts"],"sourcesContent":["/**\n * Ingebouwde modules (XiCMS 3.0). Elke \"feature\" van 2.x is hier een first-class module geworden,\n * zodat hij per site aan/uit kan en los te verbeteren is. De bijbehorende admin-panelen staan in\n * `@xiwebdesign/xicms-core/admin` (paneel-registry), gekoppeld via dezelfde `id`/`featureKey`.\n *\n * Backward compatible: zonder `SiteConfig.modules`/`features` zijn alle modules actief — identiek\n * aan 2.x. De `content`-module is `core: true` en kan niet uitgezet worden (de basis-bouwstenen).\n */\nimport { z } from \"zod\";\nimport { defineModule } from \"./defineModule\";\nimport type { ModuleDefinition } from \"./types\";\n\nimport { heroBlock } from \"../blocks/builtins/Hero\";\nimport { richTextBlock } from \"../blocks/builtins/RichTextBlock\";\nimport { imageBlock } from \"../blocks/builtins/ImageBlock\";\nimport { ctaBlock } from \"../blocks/builtins/Cta\";\nimport { columnsBlock } from \"../blocks/builtins/Columns\";\nimport { spacerBlock } from \"../blocks/builtins/Spacer\";\nimport { galleryBlock } from \"../blocks/builtins/Gallery\";\nimport { faqBlock } from \"../blocks/builtins/Faq\";\nimport { openingHoursBlock } from \"../blocks/builtins/OpeningHours\";\nimport { pricingBlock } from \"../blocks/builtins/Pricing\";\nimport { newsListBlock } from \"../blocks/builtins/NewsListBlock\";\nimport { formBlock } from \"../blocks/builtins/FormBlock\";\nimport { testimonialsBlock } from \"../blocks/builtins/Testimonials\";\nimport { teamBlock } from \"../blocks/builtins/Team\";\nimport { agendaBlock } from \"../blocks/builtins/Agenda\";\nimport { searchBlock } from \"../blocks/builtins/Search\";\nimport { featureBlock, countersBlock, logosBlock, timelineBlock } from \"../blocks/builtins/Sections\";\nimport { videoBlock } from \"../blocks/builtins/Video\";\nimport { bannerBlock } from \"../blocks/builtins/Banner\";\nimport { contactBlock, socialBlock } from \"../blocks/builtins/Contact\";\nimport { mapBlock } from \"../blocks/builtins/MapBlock\";\nimport { newsletterBlock } from \"../blocks/builtins/Newsletter\";\nimport { bookingBlock } from \"../blocks/builtins/Booking\";\nimport { buttonsBlock, quoteBlock, dividerBlock } from \"../blocks/builtins/Elements\";\nimport { accordionBlock } from \"../blocks/builtins/Accordion\";\nimport { embedBlock } from \"../blocks/builtins/Embed\";\nimport { withSidebarBlock, tabsBlock } from \"../blocks/builtins/Layout\";\nimport { cardsBlock } from \"../blocks/builtins/Cards\";\nimport { downloadsBlock } from \"../blocks/builtins/Downloads\";\nimport { pdfBlock } from \"../blocks/builtins/PdfBlock\";\nimport { countdownBlock } from \"../blocks/builtins/Countdown\";\nimport { sliderBlock } from \"../blocks/builtins/Slider\";\nimport { whatsappChatBlock } from \"../blocks/builtins/WhatsappChat\";\nimport { beforeAfterBlock } from \"../blocks/builtins/BeforeAfter\";\nimport { portfolioBlock } from \"../blocks/builtins/Portfolio\";\nimport { jobsBlock } from \"../blocks/builtins/Jobs\";\nimport { breadcrumbsBlock } from \"../blocks/builtins/Breadcrumbs\";\nimport {\n newsWidget,\n agendaWidget,\n openingHoursWidget,\n contactWidget,\n socialWidget as socialWidgetBlock,\n newsletterWidget,\n ctaWidget,\n galleryWidget,\n testimonialsWidget,\n cardsWidget,\n downloadsWidget,\n countdownWidget,\n} from \"../blocks/builtins/Widgets\";\n\nconst CORE_VERSION = \"4.17.1\";\n\n/**\n * Basis-bouwstenen — altijd aanwezig (niet uit te zetten). Bevat ook de indelingsblokken\n * (kolommen, \"Met zijbalk\") waarmee je widgets naast je hoofdinhoud plaatst, plus de\n * compacte CTA-widget.\n */\nexport const contentModule = defineModule({\n id: \"content\",\n version: CORE_VERSION,\n label: \"Basisinhoud\",\n description: \"Kern-bouwstenen: hero, tekst, afbeelding, CTA, kolommen, zijbalk, witruimte.\",\n core: true,\n blocks: [heroBlock, richTextBlock, imageBlock, ctaBlock, columnsBlock, withSidebarBlock, spacerBlock, buttonsBlock, quoteBlock, dividerBlock, ctaWidget],\n});\n\nexport const galleryModule = defineModule({\n id: \"gallery\",\n version: CORE_VERSION,\n label: \"Fotogalerij\",\n description: \"Galerij-block met grid en (optioneel) lightbox + compacte fotostrip-widget.\",\n blocks: [galleryBlock, galleryWidget],\n // Per-site instelbaar door de agent/klant (modules.gallery.config) zonder core te forken.\n // `.describe()` = het label dat de klant in /beheer ziet.\n settingsSchema: z.object({\n columns: z.number().int().min(1).max(6).default(3).describe(\"Kolommen\"),\n lightbox: z.boolean().default(true).describe(\"Lightbox bij klikken\"),\n }),\n defaultSettings: { columns: 3, lightbox: true },\n});\n\nexport const faqModule = defineModule({\n id: \"faq\",\n version: CORE_VERSION,\n label: \"FAQ\",\n description: \"Veelgestelde vragen (accordeon) met optionele zoek + FAQ-JSON-LD.\",\n blocks: [faqBlock],\n});\n\nexport const openingHoursModule = defineModule({\n id: \"openingHours\",\n version: CORE_VERSION,\n label: \"Openingstijden\",\n description: \"Openingstijden-tabel + compacte widget met 'vandaag' gemarkeerd.\",\n blocks: [openingHoursBlock, openingHoursWidget],\n});\n\nexport const pricingModule = defineModule({\n id: \"pricing\",\n version: CORE_VERSION,\n label: \"Prijzen\",\n blocks: [pricingBlock],\n});\n\nexport const pagesModule = defineModule({\n id: \"pages\",\n version: CORE_VERSION,\n label: \"Pagina's\",\n featureKey: \"pages\",\n description: \"Paginabouwer (draft → publish + versiegeschiedenis).\",\n});\n\nexport const newsModule = defineModule({\n id: \"news\",\n version: CORE_VERSION,\n label: \"Nieuws\",\n featureKey: \"news\",\n description: \"Nieuwsartikelen + nieuwslijst-block + 'laatste nieuws'-widget voor de zijbalk.\",\n blocks: [newsListBlock, newsWidget],\n});\n\nexport const mediaModule = defineModule({\n id: \"media\",\n version: CORE_VERSION,\n label: \"Media\",\n featureKey: \"media\",\n description: \"Mediabeheer met compressie + webp/srcset-varianten.\",\n requires: [{ kind: \"function\", name: \"onMediaUpload\" }, { kind: \"storage\", prefix: \"sites/\" }],\n});\n\nexport const formsModule = defineModule({\n id: \"forms\",\n version: CORE_VERSION,\n label: \"Formulieren\",\n featureKey: \"forms\",\n description: \"Formulierbouwer + inzendingen + e-mailnotificatie.\",\n blocks: [formBlock],\n requires: [\n { kind: \"function\", name: \"submitForm\" },\n { kind: \"firestore\", collection: \"forms\" },\n ],\n});\n\nexport const statsModule = defineModule({\n id: \"stats\",\n version: CORE_VERSION,\n label: \"Statistieken\",\n featureKey: \"stats\",\n description: \"Privacy-vriendelijke bezoekersstatistieken (geen cookies).\",\n requires: [{ kind: \"function\", name: \"trackView\" }],\n});\n\nexport const settingsModule = defineModule({\n id: \"settings\",\n version: CORE_VERSION,\n label: \"Instellingen\",\n core: true,\n description: \"Site-instellingen (nav, thema, SEO, formulier-afzender) — alleen siteadmin.\",\n});\n\n// Opt-in modules (defaultEnabled: false): worden bij installatie of later aangezet via\n// `modules: { <id>: true }`. Geen extra backend nodig — data leeft in de page-blocks.\nexport const testimonialsModule = defineModule({\n id: \"testimonials\",\n version: CORE_VERSION,\n label: \"Reviews\",\n description: \"Klantquotes/reviews met sterren, optionele Review-JSON-LD + compacte review-widget.\",\n defaultEnabled: false,\n blocks: [testimonialsBlock, testimonialsWidget],\n});\n\nexport const teamModule = defineModule({\n id: \"team\",\n version: CORE_VERSION,\n label: \"Team\",\n description: \"Team-/medewerkersoverzicht met foto, functie en bio.\",\n defaultEnabled: false,\n blocks: [teamBlock],\n});\n\nexport const agendaModule = defineModule({\n id: \"agenda\",\n version: CORE_VERSION,\n label: \"Agenda\",\n description: \"Evenementen/agenda (chronologisch) met Event-JSON-LD + 'komende agenda'-widget.\",\n defaultEnabled: false,\n blocks: [agendaBlock, agendaWidget],\n});\n\nexport const searchModule = defineModule({\n id: \"search\",\n version: CORE_VERSION,\n label: \"Zoeken\",\n description: \"Site-zoekblok dat gepubliceerde pagina's (en nieuws) client-side doorzoekt.\",\n defaultEnabled: false,\n blocks: [searchBlock],\n});\n\nexport const featureModule = defineModule({\n id: \"feature\",\n version: CORE_VERSION,\n label: \"Beeld + tekst\",\n description: \"Feature-sectie met afbeelding links/rechts en tekst.\",\n defaultEnabled: false,\n blocks: [featureBlock],\n});\n\nexport const countersModule = defineModule({\n id: \"counters\",\n version: CORE_VERSION,\n label: \"Tellers\",\n description: \"Statistiek-tellers (bv. “100+ klanten”).\",\n defaultEnabled: false,\n blocks: [countersBlock],\n});\n\nexport const logosModule = defineModule({\n id: \"logos\",\n version: CORE_VERSION,\n label: \"Logo's\",\n description: \"Partner-/klantlogo-strip.\",\n defaultEnabled: false,\n blocks: [logosBlock],\n});\n\nexport const timelineModule = defineModule({\n id: \"timeline\",\n version: CORE_VERSION,\n label: \"Tijdlijn\",\n description: \"Stappen/proces als tijdlijn.\",\n defaultEnabled: false,\n blocks: [timelineBlock],\n});\n\nexport const videoModule = defineModule({\n id: \"video\",\n version: CORE_VERSION,\n label: \"Video\",\n description: \"YouTube/Vimeo/MP4-embed (consent-gated).\",\n defaultEnabled: false,\n blocks: [videoBlock],\n});\n\nexport const bannerModule = defineModule({\n id: \"banner\",\n version: CORE_VERSION,\n label: \"Aankondiging\",\n description: \"Aankondigingsbalk, optioneel sluitbaar.\",\n defaultEnabled: false,\n blocks: [bannerBlock],\n});\n\nexport const contactModule = defineModule({\n id: \"contact\",\n version: CORE_VERSION,\n label: \"Contact + kaart + social\",\n description: \"Contactgegevens (JSON-LD), kaart (consent-gated), social-links + compacte widgets.\",\n defaultEnabled: false,\n blocks: [contactBlock, mapBlock, socialBlock, contactWidget, socialWidgetBlock],\n});\n\nexport const newsletterModule = defineModule({\n id: \"newsletter\",\n version: CORE_VERSION,\n label: \"Nieuwsbrief\",\n description: \"Aanmeldformulier via een externe provider-URL + compacte nieuwsbrief-widget.\",\n defaultEnabled: false,\n blocks: [newsletterBlock, newsletterWidget],\n});\n\nexport const bookingModule = defineModule({\n id: \"booking\",\n version: CORE_VERSION,\n label: \"Afspraak/booking\",\n description: \"Boekings-embed (bv. Calendly), consent-gated.\",\n defaultEnabled: false,\n blocks: [bookingBlock],\n});\n\nexport const accordionModule = defineModule({\n id: \"accordion\",\n version: CORE_VERSION,\n label: \"Accordeon\",\n description: \"Generieke in-/uitklapbare panelen.\",\n defaultEnabled: false,\n blocks: [accordionBlock],\n});\n\nexport const embedModule = defineModule({\n id: \"embed\",\n version: CORE_VERSION,\n label: \"Embed\",\n description: \"Generieke responsive iframe-embed (consent-gated).\",\n defaultEnabled: false,\n blocks: [embedBlock],\n});\n\n/* ── Nieuwe modules (3.1) — veelgebruikt op websites, volwaardig + widget waar zinvol ── */\n\nexport const cardsModule = defineModule({\n id: \"cards\",\n version: CORE_VERSION,\n label: \"Diensten / kaarten\",\n description: \"Diensten-/featurekaarten in een grid (icoon of beeld) + compacte 'uitgelicht'-widget.\",\n defaultEnabled: false,\n blocks: [cardsBlock, cardsWidget],\n});\n\nexport const tabsModule = defineModule({\n id: \"tabs\",\n version: CORE_VERSION,\n label: \"Tabbladen\",\n description: \"Tabblad-indeling: per tab een eigen set blokken (bv. beschrijving / specificaties).\",\n defaultEnabled: false,\n blocks: [tabsBlock],\n});\n\nexport const downloadsModule = defineModule({\n id: \"downloads\",\n version: CORE_VERSION,\n label: \"Downloads\",\n description: \"Lijst met downloadbare documenten (brochures, prijslijsten) + compacte widget.\",\n defaultEnabled: false,\n blocks: [downloadsBlock, downloadsWidget],\n});\n\nexport const pdfModule = defineModule({\n id: \"pdf\",\n version: CORE_VERSION,\n label: \"PDF-lezer\",\n description: \"Inline PDF-lezer voor menukaarten/documenten; meerdere PDF's met tabs, zelf te vervangen.\",\n defaultEnabled: false,\n blocks: [pdfBlock],\n});\n\nexport const countdownModule = defineModule({\n id: \"countdown\",\n version: CORE_VERSION,\n label: \"Aftelteller\",\n description: \"Tikkende countdown naar een datum (lancering, evenement, aanbieding) + widget.\",\n defaultEnabled: false,\n blocks: [countdownBlock, countdownWidget],\n});\n\nexport const sliderModule = defineModule({\n id: \"slider\",\n version: CORE_VERSION,\n label: \"Carrousel / slider\",\n description: \"Beeld-/contentcarrousel met dots, pijlen en optioneel autoplay (reduced-motion-veilig).\",\n defaultEnabled: false,\n blocks: [sliderBlock],\n});\n\n/* ── 4.16: nieuwe modules (allemaal opt-in) ──────────────────────────────── */\n\nexport const whatsappModule = defineModule({\n id: \"whatsapp\",\n version: CORE_VERSION,\n label: \"WhatsApp-knop\",\n description: \"Zwevende WhatsApp-/chatknop — laagdrempelig contact (wa.me-link, geen consent nodig).\",\n defaultEnabled: false,\n blocks: [whatsappChatBlock],\n});\n\nexport const beforeAfterModule = defineModule({\n id: \"beforeAfter\",\n version: CORE_VERSION,\n label: \"Voor / na\",\n description: \"Voor/na-vergelijker met sleepbare scheiding — sterk voor hoveniers, schilders, salons.\",\n defaultEnabled: false,\n blocks: [beforeAfterBlock],\n});\n\nexport const portfolioModule = defineModule({\n id: \"portfolio\",\n version: CORE_VERSION,\n label: \"Portfolio / projecten\",\n description: \"Projecten/cases-grid met categorie-filter en lightbox.\",\n defaultEnabled: false,\n blocks: [portfolioBlock],\n});\n\nexport const jobsModule = defineModule({\n id: \"jobs\",\n version: CORE_VERSION,\n label: \"Vacatures\",\n description: \"Vacature-overzicht met JobPosting-JSON-LD (vindbaar via Google Jobs).\",\n defaultEnabled: false,\n blocks: [jobsBlock],\n});\n\nexport const breadcrumbsModule = defineModule({\n id: \"breadcrumbs\",\n version: CORE_VERSION,\n label: \"Kruimelpad\",\n description: \"Kruimelpad afgeleid van de URL, met BreadcrumbList-JSON-LD (SEO).\",\n defaultEnabled: false,\n blocks: [breadcrumbsBlock],\n});\n\nexport const consentModule = defineModule({\n id: \"consent\",\n version: CORE_VERSION,\n label: \"Cookie-consent (AVG)\",\n description: \"Toestemmingsbanner + consent-opslag; stelt niet-essentiële scripts uit.\",\n defaultEnabled: false,\n settingsSchema: z.object({\n message: z\n .string()\n .default(\"We gebruiken cookies om de site te verbeteren. Kies hieronder je voorkeuren.\")\n .describe(\"Bannertekst\"),\n privacyUrl: z.string().optional().describe(\"Link naar privacyverklaring\"),\n version: z.string().optional().describe(\"Beleidsversie (wijzig → banner opnieuw tonen)\"),\n showReopen: z.boolean().default(true).describe(\"Zwevend cookie-knopje om keuze te wijzigen\"),\n categories: z\n .array(\n z.object({\n id: z.string(),\n label: z.string(),\n description: z.string().optional(),\n required: z.boolean().default(false),\n }),\n )\n .default([\n { id: \"necessary\", label: \"Noodzakelijk\", description: \"Nodig om de site te laten werken.\", required: true },\n { id: \"analytics\", label: \"Statistieken\", description: \"Anonieme statistieken om de site te verbeteren.\", required: false },\n { id: \"marketing\", label: \"Marketing\", description: \"Externe embeds zoals video's en kaarten.\", required: false },\n ]),\n }),\n defaultSettings: {},\n});\n\n/** Alle ingebouwde modules (volgorde bepaalt block- en tab-volgorde). */\nexport const builtinModules: ModuleDefinition[] = [\n contentModule,\n pagesModule,\n newsModule,\n mediaModule,\n galleryModule,\n faqModule,\n openingHoursModule,\n pricingModule,\n formsModule,\n statsModule,\n settingsModule,\n testimonialsModule,\n teamModule,\n agendaModule,\n searchModule,\n featureModule,\n countersModule,\n logosModule,\n timelineModule,\n videoModule,\n bannerModule,\n contactModule,\n newsletterModule,\n bookingModule,\n accordionModule,\n embedModule,\n cardsModule,\n tabsModule,\n downloadsModule,\n pdfModule,\n countdownModule,\n sliderModule,\n whatsappModule,\n beforeAfterModule,\n portfolioModule,\n jobsModule,\n breadcrumbsModule,\n consentModule,\n];\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
export interface ConsentCategory {
|
|
2
|
+
id: string;
|
|
3
|
+
label: string;
|
|
4
|
+
/** Korte uitleg wat deze categorie doet (getoond in het voorkeuren-paneel). */
|
|
5
|
+
description?: string;
|
|
6
|
+
required?: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface ConsentSettings {
|
|
9
|
+
title?: string;
|
|
10
|
+
message?: string;
|
|
11
|
+
privacyUrl?: string;
|
|
12
|
+
categories?: ConsentCategory[];
|
|
13
|
+
/** Beleidsversie: verhoog dit als het cookiebeleid wijzigt — bezoekers krijgen de banner dan opnieuw. */
|
|
14
|
+
version?: string;
|
|
15
|
+
/** Zwevend 🍪-knopje tonen om de keuze later te wijzigen (AVG). Standaard aan. */
|
|
16
|
+
showReopen?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* AVG-toestemmingsbanner met twee-staps-UX: compact (accepteren / weigeren / voorkeuren), en een
|
|
20
|
+
* uitklapbaar voorkeuren-paneel met toggle-switches + uitleg per categorie. Strak gestyled op de
|
|
21
|
+
* thema-tokens (`--color-*`), volledig overschrijfbaar via de `xicms-consent*`-classNames. Verschijnt
|
|
22
|
+
* pas als de bezoeker nog niet heeft gekozen; logica/opslag blijven in core.
|
|
23
|
+
*/
|
|
24
|
+
export declare function ConsentBanner({ settings }: {
|
|
25
|
+
settings?: ConsentSettings;
|
|
26
|
+
}): import("react").JSX.Element | null;
|
|
27
|
+
/**
|
|
28
|
+
* Toont children alleen als toestemming voor `category` is gegeven. Gebruik dit om niet-essentiële
|
|
29
|
+
* scripts/embeds (analytics, video, maps) pas na consent te laden.
|
|
30
|
+
*/
|
|
31
|
+
export declare function ConsentGate({ category, children }: {
|
|
32
|
+
category: string;
|
|
33
|
+
children: React.ReactNode;
|
|
34
|
+
}): import("react").JSX.Element | null;
|
|
35
|
+
/**
|
|
36
|
+
* Tekstlink/knop die de cookievoorkeuren heropent — voor in een footer ("Cookie-instellingen").
|
|
37
|
+
* Werkt via het `xicms:consent:open`-event; de ConsentBanner luistert daarnaar.
|
|
38
|
+
*/
|
|
39
|
+
export declare function ConsentReopenLink({ children, className }: {
|
|
40
|
+
children?: React.ReactNode;
|
|
41
|
+
className?: string;
|
|
42
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useRef, useState } from "react";
|
|
4
|
+
import { consentDecided, useConsent } from "./useConsent";
|
|
5
|
+
const DEFAULT_CATEGORIES = [
|
|
6
|
+
{ id: "necessary", label: "Noodzakelijk", required: true, description: "Nodig om de site te laten werken. Altijd actief." },
|
|
7
|
+
{ id: "analytics", label: "Statistieken", description: "Anonieme bezoekersstatistieken om de site te verbeteren." },
|
|
8
|
+
{ id: "marketing", label: "Marketing", description: "Voor gepersonaliseerde content en advertenties." }
|
|
9
|
+
];
|
|
10
|
+
function ConsentBanner({ settings }) {
|
|
11
|
+
const { state, save } = useConsent();
|
|
12
|
+
const categories = settings?.categories?.length ? settings.categories : DEFAULT_CATEGORIES;
|
|
13
|
+
const [choices, setChoices] = useState(
|
|
14
|
+
() => Object.fromEntries(categories.map((c) => [c.id, Boolean(c.required)]))
|
|
15
|
+
);
|
|
16
|
+
const [showPrefs, setShowPrefs] = useState(false);
|
|
17
|
+
const [reopened, setReopened] = useState(false);
|
|
18
|
+
const bannerRef = useRef(null);
|
|
19
|
+
useEffect(() => {
|
|
20
|
+
if (reopened) bannerRef.current?.querySelector(".xicms-consent__btn--primary")?.focus();
|
|
21
|
+
}, [reopened]);
|
|
22
|
+
const decided = consentDecided(state, settings?.version);
|
|
23
|
+
const openBanner = () => {
|
|
24
|
+
setChoices((prev) => ({ ...prev, ...state.categories }));
|
|
25
|
+
setShowPrefs(true);
|
|
26
|
+
setReopened(true);
|
|
27
|
+
};
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
const onOpen = () => openBanner();
|
|
30
|
+
window.addEventListener("xicms:consent:open", onOpen);
|
|
31
|
+
return () => window.removeEventListener("xicms:consent:open", onOpen);
|
|
32
|
+
}, [state.categories]);
|
|
33
|
+
if (decided && !reopened) {
|
|
34
|
+
if (settings?.showReopen === false) return null;
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
"button",
|
|
37
|
+
{
|
|
38
|
+
type: "button",
|
|
39
|
+
className: "xicms-consent__reopen",
|
|
40
|
+
"aria-label": "Cookie-instellingen wijzigen",
|
|
41
|
+
title: "Cookie-instellingen",
|
|
42
|
+
onClick: openBanner,
|
|
43
|
+
children: "\u{1F36A}"
|
|
44
|
+
}
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
const commit = (categories2) => {
|
|
48
|
+
save(categories2, settings?.version);
|
|
49
|
+
setReopened(false);
|
|
50
|
+
};
|
|
51
|
+
const acceptAll = () => commit(Object.fromEntries(categories.map((c) => [c.id, true])));
|
|
52
|
+
const rejectNonEssential = () => commit(Object.fromEntries(categories.map((c) => [c.id, Boolean(c.required)])));
|
|
53
|
+
const saveChoices = () => commit(choices);
|
|
54
|
+
return /* @__PURE__ */ jsx("div", { ref: bannerRef, className: "xicms-consent", role: "dialog", "aria-modal": "false", "aria-label": "Cookievoorkeuren", children: /* @__PURE__ */ jsxs("div", { className: "xicms-consent__inner", "data-prefs": showPrefs ? "1" : "0", children: [
|
|
55
|
+
/* @__PURE__ */ jsxs("div", { className: "xicms-consent__head", children: [
|
|
56
|
+
/* @__PURE__ */ jsx("p", { className: "xicms-consent__title", children: settings?.title ?? "\u{1F36A} Cookievoorkeuren" }),
|
|
57
|
+
/* @__PURE__ */ jsxs("p", { className: "xicms-consent__message", children: [
|
|
58
|
+
settings?.message ?? "We gebruiken cookies om de site te laten werken en te verbeteren. Kies hieronder wat je toestaat.",
|
|
59
|
+
settings?.privacyUrl && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
60
|
+
" ",
|
|
61
|
+
/* @__PURE__ */ jsx("a", { className: "xicms-consent__link", href: settings.privacyUrl, children: "Privacyverklaring" })
|
|
62
|
+
] })
|
|
63
|
+
] })
|
|
64
|
+
] }),
|
|
65
|
+
showPrefs && /* @__PURE__ */ jsxs("fieldset", { className: "xicms-consent__categories", children: [
|
|
66
|
+
/* @__PURE__ */ jsx("legend", { className: "xicms-sr-only", children: "Cookiecategorie\xEBn" }),
|
|
67
|
+
categories.map((c) => {
|
|
68
|
+
const on = choices[c.id] ?? Boolean(c.required);
|
|
69
|
+
return /* @__PURE__ */ jsxs("label", { className: "xicms-consent__category", "data-on": on ? "1" : "0", children: [
|
|
70
|
+
/* @__PURE__ */ jsxs("span", { className: "xicms-consent__cat-text", children: [
|
|
71
|
+
/* @__PURE__ */ jsxs("span", { className: "xicms-consent__cat-label", children: [
|
|
72
|
+
c.label,
|
|
73
|
+
c.required && /* @__PURE__ */ jsx("span", { className: "xicms-consent__required", children: " \xB7 altijd aan" })
|
|
74
|
+
] }),
|
|
75
|
+
c.description && /* @__PURE__ */ jsx("span", { className: "xicms-consent__cat-desc", children: c.description })
|
|
76
|
+
] }),
|
|
77
|
+
/* @__PURE__ */ jsxs("span", { className: "xicms-consent__switch", children: [
|
|
78
|
+
/* @__PURE__ */ jsx(
|
|
79
|
+
"input",
|
|
80
|
+
{
|
|
81
|
+
type: "checkbox",
|
|
82
|
+
checked: on,
|
|
83
|
+
disabled: c.required,
|
|
84
|
+
onChange: (e) => setChoices((prev) => ({ ...prev, [c.id]: e.target.checked }))
|
|
85
|
+
}
|
|
86
|
+
),
|
|
87
|
+
/* @__PURE__ */ jsx("span", { className: "xicms-consent__track", "aria-hidden": "true" })
|
|
88
|
+
] })
|
|
89
|
+
] }, c.id);
|
|
90
|
+
})
|
|
91
|
+
] }),
|
|
92
|
+
/* @__PURE__ */ jsxs("div", { className: "xicms-consent__actions", children: [
|
|
93
|
+
!showPrefs ? /* @__PURE__ */ jsx("button", { type: "button", className: "xicms-consent__btn xicms-consent__btn--ghost", onClick: () => setShowPrefs(true), children: "Voorkeuren" }) : /* @__PURE__ */ jsx("button", { type: "button", className: "xicms-consent__btn xicms-consent__btn--ghost", onClick: saveChoices, children: "Mijn keuze opslaan" }),
|
|
94
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "xicms-consent__btn xicms-consent__btn--ghost", onClick: rejectNonEssential, children: "Alleen noodzakelijk" }),
|
|
95
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "xicms-consent__btn xicms-consent__btn--primary", onClick: acceptAll, children: "Alles accepteren" })
|
|
96
|
+
] })
|
|
97
|
+
] }) });
|
|
98
|
+
}
|
|
99
|
+
function ConsentGate({ category, children }) {
|
|
100
|
+
const { has } = useConsent();
|
|
101
|
+
return has(category) ? /* @__PURE__ */ jsx(Fragment, { children }) : null;
|
|
102
|
+
}
|
|
103
|
+
function ConsentReopenLink({ children, className }) {
|
|
104
|
+
return /* @__PURE__ */ jsx(
|
|
105
|
+
"button",
|
|
106
|
+
{
|
|
107
|
+
type: "button",
|
|
108
|
+
className: className ?? "xicms-consent__reopen-link",
|
|
109
|
+
onClick: () => window.dispatchEvent(new Event("xicms:consent:open")),
|
|
110
|
+
children: children ?? "Cookie-instellingen"
|
|
111
|
+
}
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
export {
|
|
115
|
+
ConsentBanner,
|
|
116
|
+
ConsentGate,
|
|
117
|
+
ConsentReopenLink
|
|
118
|
+
};
|
|
119
|
+
//# sourceMappingURL=ConsentBanner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/consent/ConsentBanner.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport { consentDecided, useConsent } from \"./useConsent\";\n\nexport interface ConsentCategory {\n id: string;\n label: string;\n /** Korte uitleg wat deze categorie doet (getoond in het voorkeuren-paneel). */\n description?: string;\n required?: boolean;\n}\n\nexport interface ConsentSettings {\n title?: string;\n message?: string;\n privacyUrl?: string;\n categories?: ConsentCategory[];\n /** Beleidsversie: verhoog dit als het cookiebeleid wijzigt — bezoekers krijgen de banner dan opnieuw. */\n version?: string;\n /** Zwevend 🍪-knopje tonen om de keuze later te wijzigen (AVG). Standaard aan. */\n showReopen?: boolean;\n}\n\nconst DEFAULT_CATEGORIES: ConsentCategory[] = [\n { id: \"necessary\", label: \"Noodzakelijk\", required: true, description: \"Nodig om de site te laten werken. Altijd actief.\" },\n { id: \"analytics\", label: \"Statistieken\", description: \"Anonieme bezoekersstatistieken om de site te verbeteren.\" },\n { id: \"marketing\", label: \"Marketing\", description: \"Voor gepersonaliseerde content en advertenties.\" },\n];\n\n/**\n * AVG-toestemmingsbanner met twee-staps-UX: compact (accepteren / weigeren / voorkeuren), en een\n * uitklapbaar voorkeuren-paneel met toggle-switches + uitleg per categorie. Strak gestyled op de\n * thema-tokens (`--color-*`), volledig overschrijfbaar via de `xicms-consent*`-classNames. Verschijnt\n * pas als de bezoeker nog niet heeft gekozen; logica/opslag blijven in core.\n */\nexport function ConsentBanner({ settings }: { settings?: ConsentSettings }) {\n const { state, save } = useConsent();\n const categories = settings?.categories?.length ? settings.categories : DEFAULT_CATEGORIES;\n const [choices, setChoices] = useState<Record<string, boolean>>(() =>\n Object.fromEntries(categories.map((c) => [c.id, Boolean(c.required)])),\n );\n const [showPrefs, setShowPrefs] = useState(false);\n // Geforceerd (her)openen: via het 🍪-knopje of het `xicms:consent:open`-event (footerlink).\n const [reopened, setReopened] = useState(false);\n const bannerRef = useRef<HTMLDivElement | null>(null);\n // Bij expliciet heropenen focus de banner in (de bezoeker vroeg erom); bij eerste bezoek\n // stelen we géén focus — de banner is niet-modaal en mag het lezen niet onderbreken.\n useEffect(() => {\n if (reopened) bannerRef.current?.querySelector<HTMLElement>(\".xicms-consent__btn--primary\")?.focus();\n }, [reopened]);\n // Een oude keuze telt niet meer als de beleidsversie is gewijzigd → banner opnieuw tonen.\n const decided = consentDecided(state, settings?.version);\n\n const openBanner = () => {\n // Voorkeuren voor-invullen met de huidige keuze zodat wijzigen intuïtief is.\n setChoices((prev) => ({ ...prev, ...state.categories }));\n setShowPrefs(true);\n setReopened(true);\n };\n\n useEffect(() => {\n const onOpen = () => openBanner();\n window.addEventListener(\"xicms:consent:open\", onOpen);\n return () => window.removeEventListener(\"xicms:consent:open\", onOpen);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [state.categories]);\n\n if (decided && !reopened) {\n // AVG: de bezoeker moet zijn keuze altijd kunnen wijzigen — zwevend knopje (opt-out via settings).\n if (settings?.showReopen === false) return null;\n return (\n <button\n type=\"button\"\n className=\"xicms-consent__reopen\"\n aria-label=\"Cookie-instellingen wijzigen\"\n title=\"Cookie-instellingen\"\n onClick={openBanner}\n >\n 🍪\n </button>\n );\n }\n\n const commit = (categories: Record<string, boolean>) => {\n save(categories, settings?.version);\n setReopened(false);\n };\n const acceptAll = () => commit(Object.fromEntries(categories.map((c) => [c.id, true])));\n const rejectNonEssential = () =>\n commit(Object.fromEntries(categories.map((c) => [c.id, Boolean(c.required)])));\n const saveChoices = () => commit(choices);\n\n return (\n <div ref={bannerRef} className=\"xicms-consent\" role=\"dialog\" aria-modal=\"false\" aria-label=\"Cookievoorkeuren\">\n <div className=\"xicms-consent__inner\" data-prefs={showPrefs ? \"1\" : \"0\"}>\n <div className=\"xicms-consent__head\">\n <p className=\"xicms-consent__title\">{settings?.title ?? \"🍪 Cookievoorkeuren\"}</p>\n <p className=\"xicms-consent__message\">\n {settings?.message ??\n \"We gebruiken cookies om de site te laten werken en te verbeteren. Kies hieronder wat je toestaat.\"}\n {settings?.privacyUrl && (\n <>\n {\" \"}\n <a className=\"xicms-consent__link\" href={settings.privacyUrl}>\n Privacyverklaring\n </a>\n </>\n )}\n </p>\n </div>\n\n {showPrefs && (\n <fieldset className=\"xicms-consent__categories\">\n <legend className=\"xicms-sr-only\">Cookiecategorieën</legend>\n {categories.map((c) => {\n const on = choices[c.id] ?? Boolean(c.required);\n return (\n <label key={c.id} className=\"xicms-consent__category\" data-on={on ? \"1\" : \"0\"}>\n <span className=\"xicms-consent__cat-text\">\n <span className=\"xicms-consent__cat-label\">\n {c.label}\n {c.required && <span className=\"xicms-consent__required\"> · altijd aan</span>}\n </span>\n {c.description && <span className=\"xicms-consent__cat-desc\">{c.description}</span>}\n </span>\n <span className=\"xicms-consent__switch\">\n <input\n type=\"checkbox\"\n checked={on}\n disabled={c.required}\n onChange={(e) => setChoices((prev) => ({ ...prev, [c.id]: e.target.checked }))}\n />\n <span className=\"xicms-consent__track\" aria-hidden=\"true\" />\n </span>\n </label>\n );\n })}\n </fieldset>\n )}\n\n <div className=\"xicms-consent__actions\">\n {!showPrefs ? (\n <button type=\"button\" className=\"xicms-consent__btn xicms-consent__btn--ghost\" onClick={() => setShowPrefs(true)}>\n Voorkeuren\n </button>\n ) : (\n <button type=\"button\" className=\"xicms-consent__btn xicms-consent__btn--ghost\" onClick={saveChoices}>\n Mijn keuze opslaan\n </button>\n )}\n <button type=\"button\" className=\"xicms-consent__btn xicms-consent__btn--ghost\" onClick={rejectNonEssential}>\n Alleen noodzakelijk\n </button>\n <button type=\"button\" className=\"xicms-consent__btn xicms-consent__btn--primary\" onClick={acceptAll}>\n Alles accepteren\n </button>\n </div>\n </div>\n </div>\n );\n}\n\n/**\n * Toont children alleen als toestemming voor `category` is gegeven. Gebruik dit om niet-essentiële\n * scripts/embeds (analytics, video, maps) pas na consent te laden.\n */\nexport function ConsentGate({ category, children }: { category: string; children: React.ReactNode }) {\n const { has } = useConsent();\n return has(category) ? <>{children}</> : null;\n}\n\n/**\n * Tekstlink/knop die de cookievoorkeuren heropent — voor in een footer (\"Cookie-instellingen\").\n * Werkt via het `xicms:consent:open`-event; de ConsentBanner luistert daarnaar.\n */\nexport function ConsentReopenLink({ children, className }: { children?: React.ReactNode; className?: string }) {\n return (\n <button\n type=\"button\"\n className={className ?? \"xicms-consent__reopen-link\"}\n onClick={() => window.dispatchEvent(new Event(\"xicms:consent:open\"))}\n >\n {children ?? \"Cookie-instellingen\"}\n </button>\n );\n}\n"],"mappings":"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","names":["categories"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface ConsentState {
|
|
2
|
+
/** Per categorie-id of de bezoeker toestemming gaf. */
|
|
3
|
+
categories: Record<string, boolean>;
|
|
4
|
+
/** Tijdstip (ms) waarop de keuze is gemaakt; null = nog niet gekozen. */
|
|
5
|
+
decidedAt: number | null;
|
|
6
|
+
/** Versie van het cookiebeleid waarvoor de keuze gold — wijzigt de site zijn beleid
|
|
7
|
+
* (nieuwe `version` in de instellingen), dan telt een oude keuze niet meer. */
|
|
8
|
+
version?: string;
|
|
9
|
+
}
|
|
10
|
+
/** Normaliseer willekeurige opgeslagen JSON naar een geldige ConsentState (defensief tegen
|
|
11
|
+
* corrupte/oude vormen — `has()` mag nooit crashen op een afwijkende localStorage-waarde). */
|
|
12
|
+
export declare function normalizeConsentState(value: unknown): ConsentState;
|
|
13
|
+
/**
|
|
14
|
+
* Geldt de opgeslagen keuze nog? Alleen als er beslist is én de keuze bij de huidige
|
|
15
|
+
* beleidsversie hoort (geen `requiredVersion` = elke keuze telt — het pre-versie-gedrag).
|
|
16
|
+
*/
|
|
17
|
+
export declare function consentDecided(state: ConsentState, requiredVersion?: string): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Leest/zet cookie-consent (client-side, geen backend). Andere code gebruikt `has("analytics")`
|
|
20
|
+
* om niet-essentiële scripts pas te laden na toestemming. De `xicms:consent`-event laat losse
|
|
21
|
+
* luisteraars reageren zonder re-render.
|
|
22
|
+
*/
|
|
23
|
+
export declare function useConsent(): {
|
|
24
|
+
state: ConsentState;
|
|
25
|
+
decided: boolean;
|
|
26
|
+
has: (category: string) => boolean;
|
|
27
|
+
save: (categories: Record<string, boolean>, version?: string) => void;
|
|
28
|
+
};
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useCallback, useEffect, useState } from "react";
|
|
3
|
+
const STORAGE_KEY = "xicms-consent";
|
|
4
|
+
const EMPTY = { categories: {}, decidedAt: null };
|
|
5
|
+
function normalizeConsentState(value) {
|
|
6
|
+
if (!value || typeof value !== "object") return EMPTY;
|
|
7
|
+
const v = value;
|
|
8
|
+
const categories = v.categories && typeof v.categories === "object" ? v.categories : {};
|
|
9
|
+
const decidedAt = typeof v.decidedAt === "number" ? v.decidedAt : null;
|
|
10
|
+
const version = typeof v.version === "string" ? v.version : void 0;
|
|
11
|
+
return version === void 0 ? { categories, decidedAt } : { categories, decidedAt, version };
|
|
12
|
+
}
|
|
13
|
+
function consentDecided(state, requiredVersion) {
|
|
14
|
+
if (state.decidedAt === null) return false;
|
|
15
|
+
if (!requiredVersion) return true;
|
|
16
|
+
return state.version === requiredVersion;
|
|
17
|
+
}
|
|
18
|
+
function read() {
|
|
19
|
+
if (typeof window === "undefined") return EMPTY;
|
|
20
|
+
try {
|
|
21
|
+
const raw = window.localStorage.getItem(STORAGE_KEY);
|
|
22
|
+
if (raw) return normalizeConsentState(JSON.parse(raw));
|
|
23
|
+
} catch {
|
|
24
|
+
}
|
|
25
|
+
return EMPTY;
|
|
26
|
+
}
|
|
27
|
+
function useConsent() {
|
|
28
|
+
const [state, setState] = useState({ categories: {}, decidedAt: null });
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
setState(read());
|
|
31
|
+
const onChange = () => setState(read());
|
|
32
|
+
window.addEventListener("xicms:consent", onChange);
|
|
33
|
+
return () => window.removeEventListener("xicms:consent", onChange);
|
|
34
|
+
}, []);
|
|
35
|
+
const save = useCallback((categories, version) => {
|
|
36
|
+
const next = { categories, decidedAt: Date.now(), ...version ? { version } : {} };
|
|
37
|
+
try {
|
|
38
|
+
window.localStorage.setItem(STORAGE_KEY, JSON.stringify(next));
|
|
39
|
+
} catch {
|
|
40
|
+
}
|
|
41
|
+
setState(next);
|
|
42
|
+
window.dispatchEvent(new Event("xicms:consent"));
|
|
43
|
+
}, []);
|
|
44
|
+
const has = useCallback((category) => state.categories[category] === true, [state]);
|
|
45
|
+
return { state, decided: state.decidedAt !== null, has, save };
|
|
46
|
+
}
|
|
47
|
+
export {
|
|
48
|
+
consentDecided,
|
|
49
|
+
normalizeConsentState,
|
|
50
|
+
useConsent
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=useConsent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/modules/consent/useConsent.ts"],"sourcesContent":["\"use client\";\n\nimport { useCallback, useEffect, useState } from \"react\";\n\nconst STORAGE_KEY = \"xicms-consent\";\n\nexport interface ConsentState {\n /** Per categorie-id of de bezoeker toestemming gaf. */\n categories: Record<string, boolean>;\n /** Tijdstip (ms) waarop de keuze is gemaakt; null = nog niet gekozen. */\n decidedAt: number | null;\n /** Versie van het cookiebeleid waarvoor de keuze gold — wijzigt de site zijn beleid\n * (nieuwe `version` in de instellingen), dan telt een oude keuze niet meer. */\n version?: string;\n}\n\nconst EMPTY: ConsentState = { categories: {}, decidedAt: null };\n\n/** Normaliseer willekeurige opgeslagen JSON naar een geldige ConsentState (defensief tegen\n * corrupte/oude vormen — `has()` mag nooit crashen op een afwijkende localStorage-waarde). */\nexport function normalizeConsentState(value: unknown): ConsentState {\n if (!value || typeof value !== \"object\") return EMPTY;\n const v = value as Record<string, unknown>;\n const categories =\n v.categories && typeof v.categories === \"object\" ? (v.categories as Record<string, boolean>) : {};\n const decidedAt = typeof v.decidedAt === \"number\" ? v.decidedAt : null;\n const version = typeof v.version === \"string\" ? v.version : undefined;\n return version === undefined ? { categories, decidedAt } : { categories, decidedAt, version };\n}\n\n/**\n * Geldt de opgeslagen keuze nog? Alleen als er beslist is én de keuze bij de huidige\n * beleidsversie hoort (geen `requiredVersion` = elke keuze telt — het pre-versie-gedrag).\n */\nexport function consentDecided(state: ConsentState, requiredVersion?: string): boolean {\n if (state.decidedAt === null) return false;\n if (!requiredVersion) return true;\n return state.version === requiredVersion;\n}\n\nfunction read(): ConsentState {\n if (typeof window === \"undefined\") return EMPTY;\n try {\n const raw = window.localStorage.getItem(STORAGE_KEY);\n if (raw) return normalizeConsentState(JSON.parse(raw));\n } catch {\n /* corrupt/onbeschikbaar: behandel als nog-niet-gekozen */\n }\n return EMPTY;\n}\n\n/**\n * Leest/zet cookie-consent (client-side, geen backend). Andere code gebruikt `has(\"analytics\")`\n * om niet-essentiële scripts pas te laden na toestemming. De `xicms:consent`-event laat losse\n * luisteraars reageren zonder re-render.\n */\nexport function useConsent() {\n const [state, setState] = useState<ConsentState>({ categories: {}, decidedAt: null });\n\n useEffect(() => {\n setState(read());\n const onChange = () => setState(read());\n window.addEventListener(\"xicms:consent\", onChange);\n return () => window.removeEventListener(\"xicms:consent\", onChange);\n }, []);\n\n const save = useCallback((categories: Record<string, boolean>, version?: string) => {\n const next: ConsentState = { categories, decidedAt: Date.now(), ...(version ? { version } : {}) };\n try {\n window.localStorage.setItem(STORAGE_KEY, JSON.stringify(next));\n } catch {\n /* opslag geweigerd: keuze geldt dan alleen voor deze sessie */\n }\n setState(next);\n window.dispatchEvent(new Event(\"xicms:consent\"));\n }, []);\n\n const has = useCallback((category: string) => state.categories[category] === true, [state]);\n\n return { state, decided: state.decidedAt !== null, has, save };\n}\n"],"mappings":";AAEA,SAAS,aAAa,WAAW,gBAAgB;AAEjD,MAAM,cAAc;AAYpB,MAAM,QAAsB,EAAE,YAAY,CAAC,GAAG,WAAW,KAAK;AAIvD,SAAS,sBAAsB,OAA8B;AAClE,MAAI,CAAC,SAAS,OAAO,UAAU,SAAU,QAAO;AAChD,QAAM,IAAI;AACV,QAAM,aACJ,EAAE,cAAc,OAAO,EAAE,eAAe,WAAY,EAAE,aAAyC,CAAC;AAClG,QAAM,YAAY,OAAO,EAAE,cAAc,WAAW,EAAE,YAAY;AAClE,QAAM,UAAU,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AAC5D,SAAO,YAAY,SAAY,EAAE,YAAY,UAAU,IAAI,EAAE,YAAY,WAAW,QAAQ;AAC9F;AAMO,SAAS,eAAe,OAAqB,iBAAmC;AACrF,MAAI,MAAM,cAAc,KAAM,QAAO;AACrC,MAAI,CAAC,gBAAiB,QAAO;AAC7B,SAAO,MAAM,YAAY;AAC3B;AAEA,SAAS,OAAqB;AAC5B,MAAI,OAAO,WAAW,YAAa,QAAO;AAC1C,MAAI;AACF,UAAM,MAAM,OAAO,aAAa,QAAQ,WAAW;AACnD,QAAI,IAAK,QAAO,sBAAsB,KAAK,MAAM,GAAG,CAAC;AAAA,EACvD,QAAQ;AAAA,EAER;AACA,SAAO;AACT;AAOO,SAAS,aAAa;AAC3B,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAuB,EAAE,YAAY,CAAC,GAAG,WAAW,KAAK,CAAC;AAEpF,YAAU,MAAM;AACd,aAAS,KAAK,CAAC;AACf,UAAM,WAAW,MAAM,SAAS,KAAK,CAAC;AACtC,WAAO,iBAAiB,iBAAiB,QAAQ;AACjD,WAAO,MAAM,OAAO,oBAAoB,iBAAiB,QAAQ;AAAA,EACnE,GAAG,CAAC,CAAC;AAEL,QAAM,OAAO,YAAY,CAAC,YAAqC,YAAqB;AAClF,UAAM,OAAqB,EAAE,YAAY,WAAW,KAAK,IAAI,GAAG,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC,EAAG;AAChG,QAAI;AACF,aAAO,aAAa,QAAQ,aAAa,KAAK,UAAU,IAAI,CAAC;AAAA,IAC/D,QAAQ;AAAA,IAER;AACA,aAAS,IAAI;AACb,WAAO,cAAc,IAAI,MAAM,eAAe,CAAC;AAAA,EACjD,GAAG,CAAC,CAAC;AAEL,QAAM,MAAM,YAAY,CAAC,aAAqB,MAAM,WAAW,QAAQ,MAAM,MAAM,CAAC,KAAK,CAAC;AAE1F,SAAO,EAAE,OAAO,SAAS,MAAM,cAAc,MAAM,KAAK,KAAK;AAC/D;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Client-context met de actieve modules en hun (per-site) instellingen. Hiermee kan een
|
|
3
|
+
* block-Render in core zijn gedrag parametriseren op basis van wat de site/agent heeft ingesteld
|
|
4
|
+
* — zonder de modulecode te forken.
|
|
5
|
+
*/
|
|
6
|
+
import { type ReactNode } from "react";
|
|
7
|
+
import type { ResolvedModules } from "./registry";
|
|
8
|
+
export declare function ModulesProvider({ value, children, }: {
|
|
9
|
+
value: ResolvedModules;
|
|
10
|
+
children: ReactNode;
|
|
11
|
+
}): import("react").JSX.Element;
|
|
12
|
+
/** Lees alle actieve modules + instellingen. Buiten een provider: lege/inactieve set. */
|
|
13
|
+
export declare function useModules(): ResolvedModules;
|
|
14
|
+
/** Is een module actief? */
|
|
15
|
+
export declare function useModuleActive(id: string): boolean;
|
|
16
|
+
/**
|
|
17
|
+
* Lees de samengestelde instellingen van een module (defaultSettings ⊕ per-site config),
|
|
18
|
+
* generiek getypeerd. Geef je eigen type mee: `useModuleSettings<GallerySettings>("gallery")`.
|
|
19
|
+
*/
|
|
20
|
+
export declare function useModuleSettings<T = Record<string, unknown>>(id: string): T;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { createContext, useContext } from "react";
|
|
4
|
+
const ModulesContext = createContext(null);
|
|
5
|
+
function ModulesProvider({
|
|
6
|
+
value,
|
|
7
|
+
children
|
|
8
|
+
}) {
|
|
9
|
+
return /* @__PURE__ */ jsx(ModulesContext.Provider, { value, children });
|
|
10
|
+
}
|
|
11
|
+
function useModules() {
|
|
12
|
+
return useContext(ModulesContext) ?? {
|
|
13
|
+
activeIds: /* @__PURE__ */ new Set(),
|
|
14
|
+
blocks: [],
|
|
15
|
+
settings: {},
|
|
16
|
+
defs: []
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
function useModuleActive(id) {
|
|
20
|
+
return useModules().activeIds.has(id);
|
|
21
|
+
}
|
|
22
|
+
function useModuleSettings(id) {
|
|
23
|
+
return useModules().settings[id] ?? {};
|
|
24
|
+
}
|
|
25
|
+
export {
|
|
26
|
+
ModulesProvider,
|
|
27
|
+
useModuleActive,
|
|
28
|
+
useModuleSettings,
|
|
29
|
+
useModules
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=context.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/context.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Client-context met de actieve modules en hun (per-site) instellingen. Hiermee kan een\n * block-Render in core zijn gedrag parametriseren op basis van wat de site/agent heeft ingesteld\n * — zonder de modulecode te forken.\n */\nimport { createContext, useContext, type ReactNode } from \"react\";\nimport type { ResolvedModules } from \"./registry\";\n\nconst ModulesContext = createContext<ResolvedModules | null>(null);\n\nexport function ModulesProvider({\n value,\n children,\n}: {\n value: ResolvedModules;\n children: ReactNode;\n}) {\n return <ModulesContext.Provider value={value}>{children}</ModulesContext.Provider>;\n}\n\n/** Lees alle actieve modules + instellingen. Buiten een provider: lege/inactieve set. */\nexport function useModules(): ResolvedModules {\n return (\n useContext(ModulesContext) ?? {\n activeIds: new Set<string>(),\n blocks: [],\n settings: {},\n defs: [],\n }\n );\n}\n\n/** Is een module actief? */\nexport function useModuleActive(id: string): boolean {\n return useModules().activeIds.has(id);\n}\n\n/**\n * Lees de samengestelde instellingen van een module (defaultSettings ⊕ per-site config),\n * generiek getypeerd. Geef je eigen type mee: `useModuleSettings<GallerySettings>(\"gallery\")`.\n */\nexport function useModuleSettings<T = Record<string, unknown>>(id: string): T {\n return (useModules().settings[id] ?? {}) as T;\n}\n"],"mappings":";AAmBS;AAZT,SAAS,eAAe,kBAAkC;AAG1D,MAAM,iBAAiB,cAAsC,IAAI;AAE1D,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AACF,GAGG;AACD,SAAO,oBAAC,eAAe,UAAf,EAAwB,OAAe,UAAS;AAC1D;AAGO,SAAS,aAA8B;AAC5C,SACE,WAAW,cAAc,KAAK;AAAA,IAC5B,WAAW,oBAAI,IAAY;AAAA,IAC3B,QAAQ,CAAC;AAAA,IACT,UAAU,CAAC;AAAA,IACX,MAAM,CAAC;AAAA,EACT;AAEJ;AAGO,SAAS,gBAAgB,IAAqB;AACnD,SAAO,WAAW,EAAE,UAAU,IAAI,EAAE;AACtC;AAMO,SAAS,kBAA+C,IAAe;AAC5E,SAAQ,WAAW,EAAE,SAAS,EAAE,KAAK,CAAC;AACxC;","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Module-contract — controleert dat een set modules consistent is. Bruikbaar in de core-tests én
|
|
3
|
+
* door een klantsite om zijn eigen modules te valideren (`assertModuleContract([mijnModule])`).
|
|
4
|
+
* Geeft een lijst problemen terug (leeg = ok).
|
|
5
|
+
*/
|
|
6
|
+
import type { ModuleDefinition } from "./types";
|
|
7
|
+
export declare function validateModuleContract(defs: ModuleDefinition[]): string[];
|
|
8
|
+
/** Gooit als het contract niet klopt (handig in een test of bij opstart). */
|
|
9
|
+
export declare function assertModuleContract(defs: ModuleDefinition[]): void;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
const SEMVER = /^\d+\.\d+\.\d+(?:[-+].*)?$/;
|
|
2
|
+
const ID = /^[a-z][a-zA-Z0-9-]*$/;
|
|
3
|
+
function validateModuleContract(defs) {
|
|
4
|
+
const problems = [];
|
|
5
|
+
const ids = /* @__PURE__ */ new Set();
|
|
6
|
+
const featureKeys = /* @__PURE__ */ new Set();
|
|
7
|
+
const blockTypes = /* @__PURE__ */ new Set();
|
|
8
|
+
for (const d of defs) {
|
|
9
|
+
if (!ID.test(d.id)) problems.push(`module-id "${d.id}" is geen geldige kebab-id.`);
|
|
10
|
+
if (ids.has(d.id)) problems.push(`dubbele module-id "${d.id}".`);
|
|
11
|
+
ids.add(d.id);
|
|
12
|
+
if (!SEMVER.test(d.version)) problems.push(`module "${d.id}" heeft geen geldige semver (${d.version}).`);
|
|
13
|
+
if (!d.label) problems.push(`module "${d.id}" mist een label.`);
|
|
14
|
+
if (d.featureKey) {
|
|
15
|
+
if (featureKeys.has(d.featureKey)) problems.push(`featureKey "${d.featureKey}" wordt door meerdere modules gebruikt.`);
|
|
16
|
+
featureKeys.add(d.featureKey);
|
|
17
|
+
}
|
|
18
|
+
for (const b of d.blocks ?? []) {
|
|
19
|
+
if (blockTypes.has(b.type)) problems.push(`block-type "${b.type}" wordt door meerdere modules geleverd.`);
|
|
20
|
+
blockTypes.add(b.type);
|
|
21
|
+
if (typeof b.Render !== "function") problems.push(`block "${b.type}" (module "${d.id}") mist een Render-component.`);
|
|
22
|
+
if (!b.schema) problems.push(`block "${b.type}" (module "${d.id}") mist een schema.`);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return problems;
|
|
26
|
+
}
|
|
27
|
+
function assertModuleContract(defs) {
|
|
28
|
+
const problems = validateModuleContract(defs);
|
|
29
|
+
if (problems.length) {
|
|
30
|
+
throw new Error(`Module-contract geschonden:
|
|
31
|
+
- ${problems.join("\n- ")}`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export {
|
|
35
|
+
assertModuleContract,
|
|
36
|
+
validateModuleContract
|
|
37
|
+
};
|
|
38
|
+
//# sourceMappingURL=contract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/contract.ts"],"sourcesContent":["/**\n * Module-contract — controleert dat een set modules consistent is. Bruikbaar in de core-tests én\n * door een klantsite om zijn eigen modules te valideren (`assertModuleContract([mijnModule])`).\n * Geeft een lijst problemen terug (leeg = ok).\n */\nimport type { ModuleDefinition } from \"./types\";\n\nconst SEMVER = /^\\d+\\.\\d+\\.\\d+(?:[-+].*)?$/;\n// kebab- of camelCase, startend met een kleine letter (sluit aan op block-`_type`-conventie).\nconst ID = /^[a-z][a-zA-Z0-9-]*$/;\n\nexport function validateModuleContract(defs: ModuleDefinition[]): string[] {\n const problems: string[] = [];\n const ids = new Set<string>();\n const featureKeys = new Set<string>();\n const blockTypes = new Set<string>();\n\n for (const d of defs) {\n if (!ID.test(d.id)) problems.push(`module-id \"${d.id}\" is geen geldige kebab-id.`);\n if (ids.has(d.id)) problems.push(`dubbele module-id \"${d.id}\".`);\n ids.add(d.id);\n\n if (!SEMVER.test(d.version)) problems.push(`module \"${d.id}\" heeft geen geldige semver (${d.version}).`);\n if (!d.label) problems.push(`module \"${d.id}\" mist een label.`);\n\n if (d.featureKey) {\n if (featureKeys.has(d.featureKey)) problems.push(`featureKey \"${d.featureKey}\" wordt door meerdere modules gebruikt.`);\n featureKeys.add(d.featureKey);\n }\n\n for (const b of d.blocks ?? []) {\n if (blockTypes.has(b.type)) problems.push(`block-type \"${b.type}\" wordt door meerdere modules geleverd.`);\n blockTypes.add(b.type);\n if (typeof b.Render !== \"function\") problems.push(`block \"${b.type}\" (module \"${d.id}\") mist een Render-component.`);\n if (!b.schema) problems.push(`block \"${b.type}\" (module \"${d.id}\") mist een schema.`);\n }\n }\n return problems;\n}\n\n/** Gooit als het contract niet klopt (handig in een test of bij opstart). */\nexport function assertModuleContract(defs: ModuleDefinition[]): void {\n const problems = validateModuleContract(defs);\n if (problems.length) {\n throw new Error(`Module-contract geschonden:\\n- ${problems.join(\"\\n- \")}`);\n }\n}\n"],"mappings":"AAOA,MAAM,SAAS;AAEf,MAAM,KAAK;AAEJ,SAAS,uBAAuB,MAAoC;AACzE,QAAM,WAAqB,CAAC;AAC5B,QAAM,MAAM,oBAAI,IAAY;AAC5B,QAAM,cAAc,oBAAI,IAAY;AACpC,QAAM,aAAa,oBAAI,IAAY;AAEnC,aAAW,KAAK,MAAM;AACpB,QAAI,CAAC,GAAG,KAAK,EAAE,EAAE,EAAG,UAAS,KAAK,cAAc,EAAE,EAAE,6BAA6B;AACjF,QAAI,IAAI,IAAI,EAAE,EAAE,EAAG,UAAS,KAAK,sBAAsB,EAAE,EAAE,IAAI;AAC/D,QAAI,IAAI,EAAE,EAAE;AAEZ,QAAI,CAAC,OAAO,KAAK,EAAE,OAAO,EAAG,UAAS,KAAK,WAAW,EAAE,EAAE,gCAAgC,EAAE,OAAO,IAAI;AACvG,QAAI,CAAC,EAAE,MAAO,UAAS,KAAK,WAAW,EAAE,EAAE,mBAAmB;AAE9D,QAAI,EAAE,YAAY;AAChB,UAAI,YAAY,IAAI,EAAE,UAAU,EAAG,UAAS,KAAK,eAAe,EAAE,UAAU,yCAAyC;AACrH,kBAAY,IAAI,EAAE,UAAU;AAAA,IAC9B;AAEA,eAAW,KAAK,EAAE,UAAU,CAAC,GAAG;AAC9B,UAAI,WAAW,IAAI,EAAE,IAAI,EAAG,UAAS,KAAK,eAAe,EAAE,IAAI,yCAAyC;AACxG,iBAAW,IAAI,EAAE,IAAI;AACrB,UAAI,OAAO,EAAE,WAAW,WAAY,UAAS,KAAK,UAAU,EAAE,IAAI,cAAc,EAAE,EAAE,+BAA+B;AACnH,UAAI,CAAC,EAAE,OAAQ,UAAS,KAAK,UAAU,EAAE,IAAI,cAAc,EAAE,EAAE,qBAAqB;AAAA,IACtF;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,qBAAqB,MAAgC;AACnE,QAAM,WAAW,uBAAuB,IAAI;AAC5C,MAAI,SAAS,QAAQ;AACnB,UAAM,IAAI,MAAM;AAAA,IAAkC,SAAS,KAAK,MAAM,CAAC,EAAE;AAAA,EAC3E;AACF;","names":[]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `defineModule` — identiteits-helper met type-inferentie (zoals `defineBlock`/`defineSiteConfig`).
|
|
3
|
+
* Een module is *data*: hij voegt blocks + instellingen toe aan de engine zonder de `blocks`-prop
|
|
4
|
+
* of de gulden regel te breken.
|
|
5
|
+
*
|
|
6
|
+
* UPDATE-VEILIGHEID: voeg in een nieuwe moduleversie nooit een verplicht block-veld of een verplicht
|
|
7
|
+
* settings-veld toe zonder `.default()`/`.optional()` — anders faalt validatie op bestaande content
|
|
8
|
+
* of instellingen. Zo blijft een core-update non-breaking voor klantsites (semver).
|
|
9
|
+
*/
|
|
10
|
+
import type { ModuleDefinition } from "./types";
|
|
11
|
+
export declare function defineModule(def: ModuleDefinition): ModuleDefinition;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/defineModule.ts"],"sourcesContent":["/**\n * `defineModule` — identiteits-helper met type-inferentie (zoals `defineBlock`/`defineSiteConfig`).\n * Een module is *data*: hij voegt blocks + instellingen toe aan de engine zonder de `blocks`-prop\n * of de gulden regel te breken.\n *\n * UPDATE-VEILIGHEID: voeg in een nieuwe moduleversie nooit een verplicht block-veld of een verplicht\n * settings-veld toe zonder `.default()`/`.optional()` — anders faalt validatie op bestaande content\n * of instellingen. Zo blijft een core-update non-breaking voor klantsites (semver).\n */\nimport type { ModuleDefinition } from \"./types\";\n\nexport function defineModule(def: ModuleDefinition): ModuleDefinition {\n return def;\n}\n"],"mappings":"AAWO,SAAS,aAAa,KAAyC;AACpE,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @xiwebdesign/xicms-core/modules — de module-laag (XiCMS 3.0).
|
|
3
|
+
* Pure data + lichte client-context; admin-panelen zitten in `.../admin`.
|
|
4
|
+
*/
|
|
5
|
+
export { defineModule } from "./defineModule";
|
|
6
|
+
export type { ModuleDefinition, ModuleSiteSetting, ModulesSiteConfig, Capability, } from "./types";
|
|
7
|
+
export { resolveModules, isModuleActive, moduleIdForBlockType, type ResolvedModules, } from "./registry";
|
|
8
|
+
export { ModulesProvider, useModules, useModuleActive, useModuleSettings, } from "./context";
|
|
9
|
+
export { applyBlockOverrides, type BlockOverride, type BlockOverrides, } from "./overrides";
|
|
10
|
+
export { builtinModules } from "./builtins";
|
|
11
|
+
export { validateModuleContract, assertModuleContract } from "./contract";
|
|
12
|
+
export { useConsent, normalizeConsentState, consentDecided, type ConsentState } from "./consent/useConsent";
|
|
13
|
+
export { ConsentBanner, ConsentGate, ConsentReopenLink, type ConsentSettings, type ConsentCategory, } from "./consent/ConsentBanner";
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { defineModule } from "./defineModule";
|
|
2
|
+
import {
|
|
3
|
+
resolveModules,
|
|
4
|
+
isModuleActive,
|
|
5
|
+
moduleIdForBlockType
|
|
6
|
+
} from "./registry";
|
|
7
|
+
import {
|
|
8
|
+
ModulesProvider,
|
|
9
|
+
useModules,
|
|
10
|
+
useModuleActive,
|
|
11
|
+
useModuleSettings
|
|
12
|
+
} from "./context";
|
|
13
|
+
import {
|
|
14
|
+
applyBlockOverrides
|
|
15
|
+
} from "./overrides";
|
|
16
|
+
import { builtinModules } from "./builtins";
|
|
17
|
+
import { validateModuleContract, assertModuleContract } from "./contract";
|
|
18
|
+
import { useConsent, normalizeConsentState, consentDecided } from "./consent/useConsent";
|
|
19
|
+
import {
|
|
20
|
+
ConsentBanner,
|
|
21
|
+
ConsentGate,
|
|
22
|
+
ConsentReopenLink
|
|
23
|
+
} from "./consent/ConsentBanner";
|
|
24
|
+
export {
|
|
25
|
+
ConsentBanner,
|
|
26
|
+
ConsentGate,
|
|
27
|
+
ConsentReopenLink,
|
|
28
|
+
ModulesProvider,
|
|
29
|
+
applyBlockOverrides,
|
|
30
|
+
assertModuleContract,
|
|
31
|
+
builtinModules,
|
|
32
|
+
consentDecided,
|
|
33
|
+
defineModule,
|
|
34
|
+
isModuleActive,
|
|
35
|
+
moduleIdForBlockType,
|
|
36
|
+
normalizeConsentState,
|
|
37
|
+
resolveModules,
|
|
38
|
+
useConsent,
|
|
39
|
+
useModuleActive,
|
|
40
|
+
useModuleSettings,
|
|
41
|
+
useModules,
|
|
42
|
+
validateModuleContract
|
|
43
|
+
};
|
|
44
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/index.ts"],"sourcesContent":["/**\n * @xiwebdesign/xicms-core/modules — de module-laag (XiCMS 3.0).\n * Pure data + lichte client-context; admin-panelen zitten in `.../admin`.\n */\nexport { defineModule } from \"./defineModule\";\nexport type {\n ModuleDefinition,\n ModuleSiteSetting,\n ModulesSiteConfig,\n Capability,\n} from \"./types\";\nexport {\n resolveModules,\n isModuleActive,\n moduleIdForBlockType,\n type ResolvedModules,\n} from \"./registry\";\nexport {\n ModulesProvider,\n useModules,\n useModuleActive,\n useModuleSettings,\n} from \"./context\";\nexport {\n applyBlockOverrides,\n type BlockOverride,\n type BlockOverrides,\n} from \"./overrides\";\nexport { builtinModules } from \"./builtins\";\nexport { validateModuleContract, assertModuleContract } from \"./contract\";\nexport { useConsent, normalizeConsentState, consentDecided, type ConsentState } from \"./consent/useConsent\";\nexport {\n ConsentBanner,\n ConsentGate,\n ConsentReopenLink,\n type ConsentSettings,\n type ConsentCategory,\n} from \"./consent/ConsentBanner\";\n"],"mappings":"AAIA,SAAS,oBAAoB;AAO7B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,OAGK;AACP,SAAS,sBAAsB;AAC/B,SAAS,wBAAwB,4BAA4B;AAC7D,SAAS,YAAY,uBAAuB,sBAAyC;AACrF;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block-overrides — laat een site het *uiterlijk* van een (core-)block volledig vervangen terwijl
|
|
3
|
+
* schema, validatie, admin-editor en datapad in core blijven. Zo kan de agent elk block 100%
|
|
4
|
+
* in de huisstijl van de klant zetten zonder de modulecode te forken.
|
|
5
|
+
*
|
|
6
|
+
* Gebruik (in de klantrepo, client-side):
|
|
7
|
+
* <XiCMSProvider config={...} overrides={{ gallery: { Render: MijnGalerij } }}>
|
|
8
|
+
*
|
|
9
|
+
* Alleen presentatie (`Render`/`Editor`/`label`/`icon`) is te overschrijven; het schema (de
|
|
10
|
+
* structuur/het datacontract) blijft van core. Een override op een onbekend type wordt genegeerd.
|
|
11
|
+
*/
|
|
12
|
+
import type { BlockDefinition, BlockRegistry } from "../blocks/registry";
|
|
13
|
+
export type BlockOverride = Partial<Pick<BlockDefinition, "Render" | "Editor" | "label" | "icon">>;
|
|
14
|
+
/** Map van block-`type` naar de te overschrijven presentatievelden. */
|
|
15
|
+
export type BlockOverrides = Record<string, BlockOverride>;
|
|
16
|
+
/** Past overrides toe en geeft een nieuw registry terug (muteert het origineel niet). */
|
|
17
|
+
export declare function applyBlockOverrides(registry: BlockRegistry, overrides?: BlockOverrides): BlockRegistry;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
function applyBlockOverrides(registry, overrides) {
|
|
2
|
+
if (!overrides) return registry;
|
|
3
|
+
const next = new Map(registry);
|
|
4
|
+
for (const [type, ov] of Object.entries(overrides)) {
|
|
5
|
+
const base = next.get(type);
|
|
6
|
+
if (!base) {
|
|
7
|
+
if (typeof console !== "undefined") {
|
|
8
|
+
console.warn(`[xicms] override voor onbekend block-type "${type}" genegeerd.`);
|
|
9
|
+
}
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
next.set(type, {
|
|
13
|
+
...base,
|
|
14
|
+
...ov.Render ? { Render: ov.Render } : {},
|
|
15
|
+
...ov.Editor ? { Editor: ov.Editor } : {},
|
|
16
|
+
...ov.label ? { label: ov.label } : {},
|
|
17
|
+
...ov.icon ? { icon: ov.icon } : {}
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
return next;
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
applyBlockOverrides
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=overrides.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/modules/overrides.ts"],"sourcesContent":["/**\n * Block-overrides — laat een site het *uiterlijk* van een (core-)block volledig vervangen terwijl\n * schema, validatie, admin-editor en datapad in core blijven. Zo kan de agent elk block 100%\n * in de huisstijl van de klant zetten zonder de modulecode te forken.\n *\n * Gebruik (in de klantrepo, client-side):\n * <XiCMSProvider config={...} overrides={{ gallery: { Render: MijnGalerij } }}>\n *\n * Alleen presentatie (`Render`/`Editor`/`label`/`icon`) is te overschrijven; het schema (de\n * structuur/het datacontract) blijft van core. Een override op een onbekend type wordt genegeerd.\n */\nimport type { BlockDefinition, BlockRegistry } from \"../blocks/registry\";\n\nexport type BlockOverride = Partial<\n Pick<BlockDefinition, \"Render\" | \"Editor\" | \"label\" | \"icon\">\n>;\n\n/** Map van block-`type` naar de te overschrijven presentatievelden. */\nexport type BlockOverrides = Record<string, BlockOverride>;\n\n/** Past overrides toe en geeft een nieuw registry terug (muteert het origineel niet). */\nexport function applyBlockOverrides(\n registry: BlockRegistry,\n overrides?: BlockOverrides,\n): BlockRegistry {\n if (!overrides) return registry;\n const next: BlockRegistry = new Map(registry);\n for (const [type, ov] of Object.entries(overrides)) {\n const base = next.get(type);\n if (!base) {\n if (typeof console !== \"undefined\") {\n console.warn(`[xicms] override voor onbekend block-type \"${type}\" genegeerd.`);\n }\n continue;\n }\n next.set(type, {\n ...base,\n ...(ov.Render ? { Render: ov.Render } : {}),\n ...(ov.Editor ? { Editor: ov.Editor } : {}),\n ...(ov.label ? { label: ov.label } : {}),\n ...(ov.icon ? { icon: ov.icon } : {}),\n });\n }\n return next;\n}\n"],"mappings":"AAqBO,SAAS,oBACd,UACA,WACe;AACf,MAAI,CAAC,UAAW,QAAO;AACvB,QAAM,OAAsB,IAAI,IAAI,QAAQ;AAC5C,aAAW,CAAC,MAAM,EAAE,KAAK,OAAO,QAAQ,SAAS,GAAG;AAClD,UAAM,OAAO,KAAK,IAAI,IAAI;AAC1B,QAAI,CAAC,MAAM;AACT,UAAI,OAAO,YAAY,aAAa;AAClC,gBAAQ,KAAK,8CAA8C,IAAI,cAAc;AAAA,MAC/E;AACA;AAAA,IACF;AACA,SAAK,IAAI,MAAM;AAAA,MACb,GAAG;AAAA,MACH,GAAI,GAAG,SAAS,EAAE,QAAQ,GAAG,OAAO,IAAI,CAAC;AAAA,MACzC,GAAI,GAAG,SAAS,EAAE,QAAQ,GAAG,OAAO,IAAI,CAAC;AAAA,MACzC,GAAI,GAAG,QAAQ,EAAE,OAAO,GAAG,MAAM,IAAI,CAAC;AAAA,MACtC,GAAI,GAAG,OAAO,EAAE,MAAM,GAAG,KAAK,IAAI,CAAC;AAAA,IACrC,CAAC;AAAA,EACH;AACA,SAAO;AACT;","names":[]}
|