@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/blocks/context.tsx"],"sourcesContent":["\"use client\";\n\nimport { createContext, useContext, type ReactNode } from \"react\";\nimport type { BlockRegistry } from \"./registry\";\n\nconst RegistryContext = createContext<BlockRegistry | null>(null);\n\nexport function RegistryProvider({\n registry,\n children,\n}: {\n registry: BlockRegistry;\n children: ReactNode;\n}) {\n return <RegistryContext.Provider value={registry}>{children}</RegistryContext.Provider>;\n}\n\n/** Lees de actieve block-registry (client). Voor server-rendering: geef registry als prop mee. */\nexport function useRegistry(): BlockRegistry {\n const ctx = useContext(RegistryContext);\n if (!ctx) throw new Error(\"useRegistry moet binnen <XiCMSProvider> (met blocks) worden gebruikt.\");\n return ctx;\n}\n"],"mappings":";AAcS;AAZT,SAAS,eAAe,kBAAkC;AAG1D,MAAM,kBAAkB,cAAoC,IAAI;AAEzD,SAAS,iBAAiB;AAAA,EAC/B;AAAA,EACA;AACF,GAGG;AACD,SAAO,oBAAC,gBAAgB,UAAhB,EAAyB,OAAO,UAAW,UAAS;AAC9D;AAGO,SAAS,cAA6B;AAC3C,QAAM,MAAM,WAAW,eAAe;AACtC,MAAI,CAAC,IAAK,OAAM,IAAI,MAAM,uEAAuE;AACjG,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @xiwebdesign/xicms-core/blocks — ingebouwde blokken + de registry-API.
|
|
3
|
+
* Render-componenten zijn server-safe (waar mogelijk); admin-editors zitten in `/admin`.
|
|
4
|
+
*/
|
|
5
|
+
export { defineBlock, createRegistry, mergeRegistry, validateBlocks, type BlockDefinition, type BlockRegistry, type BlockRenderProps, type BlockEditorProps, } from "./registry";
|
|
6
|
+
export { BlockRenderer } from "./BlockRenderer";
|
|
7
|
+
export { RegistryProvider, useRegistry } from "./context";
|
|
8
|
+
export { builtinBlocks } from "./builtins";
|
|
9
|
+
export * from "./builtins";
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import {
|
|
2
|
+
defineBlock,
|
|
3
|
+
createRegistry,
|
|
4
|
+
mergeRegistry,
|
|
5
|
+
validateBlocks
|
|
6
|
+
} from "./registry";
|
|
7
|
+
import { BlockRenderer } from "./BlockRenderer";
|
|
8
|
+
import { RegistryProvider, useRegistry } from "./context";
|
|
9
|
+
import { builtinBlocks } from "./builtins";
|
|
10
|
+
export * from "./builtins";
|
|
11
|
+
export {
|
|
12
|
+
BlockRenderer,
|
|
13
|
+
RegistryProvider,
|
|
14
|
+
builtinBlocks,
|
|
15
|
+
createRegistry,
|
|
16
|
+
defineBlock,
|
|
17
|
+
mergeRegistry,
|
|
18
|
+
useRegistry,
|
|
19
|
+
validateBlocks
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/blocks/index.ts"],"sourcesContent":["/**\n * @xiwebdesign/xicms-core/blocks — ingebouwde blokken + de registry-API.\n * Render-componenten zijn server-safe (waar mogelijk); admin-editors zitten in `/admin`.\n */\nexport {\n defineBlock,\n createRegistry,\n mergeRegistry,\n validateBlocks,\n type BlockDefinition,\n type BlockRegistry,\n type BlockRenderProps,\n type BlockEditorProps,\n} from \"./registry\";\nexport { BlockRenderer } from \"./BlockRenderer\";\nexport { RegistryProvider, useRegistry } from \"./context\";\nexport { builtinBlocks } from \"./builtins\";\nexport * from \"./builtins\";\n"],"mappings":"AAIA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAKK;AACP,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB,mBAAmB;AAC9C,SAAS,qBAAqB;AAC9B,cAAc;","names":[]}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Block-registry: koppelt een `_type` aan zijn Zod-schema, een (server-safe) Render-component
|
|
3
|
+
* en een optionele (client/admin) Editor. Klant-blokken worden hier ingebracht via `defineBlock`
|
|
4
|
+
* — zo blijft de core klant-onafhankelijk: de klant levert de render-component, core de structuur.
|
|
5
|
+
*
|
|
6
|
+
* Pure logica + types (geen "use client"): bruikbaar op server en client.
|
|
7
|
+
*/
|
|
8
|
+
import type { ComponentType } from "react";
|
|
9
|
+
import type { ZodTypeAny, z } from "zod";
|
|
10
|
+
import type { BlockBase } from "../schema/blocks";
|
|
11
|
+
export interface BlockRenderProps<T = unknown> {
|
|
12
|
+
block: T;
|
|
13
|
+
siteId: string;
|
|
14
|
+
/** "view" = publiek; "preview" = draft-weergave in de editor. */
|
|
15
|
+
mode?: "view" | "preview";
|
|
16
|
+
}
|
|
17
|
+
export interface BlockEditorProps<T = unknown> {
|
|
18
|
+
block: T;
|
|
19
|
+
siteId: string;
|
|
20
|
+
onChange: (next: T) => void;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Indeling van een block in het toevoeg-menu:
|
|
24
|
+
* - `content` (default): een gewoon blok dat je op de pagina plaatst.
|
|
25
|
+
* - `widget`: een compacte variant die je naast een blok (in een zijbalk/kolom) zet — haalt z'n
|
|
26
|
+
* gegevens uit dezelfde module als de volwaardige versie (bv. "laatste nieuws", "komende agenda").
|
|
27
|
+
* - `layout`: een indelingsblok dat andere blokken bevat (kolommen, zijbalk, tabs).
|
|
28
|
+
*/
|
|
29
|
+
export type BlockCategory = "content" | "widget" | "layout";
|
|
30
|
+
export interface BlockDefinition<S extends ZodTypeAny = ZodTypeAny> {
|
|
31
|
+
type: string;
|
|
32
|
+
schema: S;
|
|
33
|
+
Render: ComponentType<BlockRenderProps<z.infer<S>>>;
|
|
34
|
+
/**
|
|
35
|
+
* Admin-editor (lazy/client). Optioneel; ontbreekt = automatische schema-editor (GenericEditor):
|
|
36
|
+
* die genereert een formulier uit het Zod-schema, dus een blok zonder eigen editor blijft bewerkbaar.
|
|
37
|
+
*/
|
|
38
|
+
Editor?: ComponentType<BlockEditorProps<z.infer<S>>>;
|
|
39
|
+
label: string;
|
|
40
|
+
icon?: string;
|
|
41
|
+
/** Groep in het toevoeg-menu (content/widget/layout). Standaard "content". */
|
|
42
|
+
category?: BlockCategory;
|
|
43
|
+
/** Defaultwaarden voor een nieuw block (zonder _key/_type). */
|
|
44
|
+
defaults?: () => Record<string, unknown>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Registreert een block-type.
|
|
48
|
+
*
|
|
49
|
+
* UPDATE-VEILIGHEID: voeg in een nieuwe versie nooit een VERPLICHT veld toe aan een bestaand
|
|
50
|
+
* block-schema zonder `.default()` of `.optional()`. Anders faalt validatie op al opgeslagen
|
|
51
|
+
* content en wordt die overgeslagen. Met defaults/optioneel blijft oude content gewoon werken.
|
|
52
|
+
*/
|
|
53
|
+
export declare function defineBlock<S extends ZodTypeAny>(def: BlockDefinition<S>): BlockDefinition;
|
|
54
|
+
export type BlockRegistry = Map<string, BlockDefinition>;
|
|
55
|
+
/**
|
|
56
|
+
* Bouwt de opties voor het "blok toevoegen"-menu, gegroepeerd op categorie: eerst gewone blokken,
|
|
57
|
+
* dan indeling (kolommen/zijbalk/tabs), dan widgets. Widgets/indeling krijgen een suffix zodat de
|
|
58
|
+
* groep duidelijk is in een platte keuzelijst.
|
|
59
|
+
*/
|
|
60
|
+
export declare function buildBlockAddOptions(defs: Iterable<BlockDefinition>): {
|
|
61
|
+
value: string;
|
|
62
|
+
label: string;
|
|
63
|
+
}[];
|
|
64
|
+
export declare function createRegistry(defs: BlockDefinition[]): BlockRegistry;
|
|
65
|
+
export declare function mergeRegistry(base: BlockRegistry, extra: BlockDefinition[]): BlockRegistry;
|
|
66
|
+
/**
|
|
67
|
+
* Strikte per-type validatie van een blocks-array tegen de registry. Onbekende types en
|
|
68
|
+
* blocks die hun schema niet halen worden weggelaten (defensief — nooit half-rendered content).
|
|
69
|
+
* Gebruikt bij publiceren (server) en vóór renderen.
|
|
70
|
+
*
|
|
71
|
+
* Recursief: geneste blokken in de indelingsblokken (kolommen, "Met zijbalk", tabs) worden óók
|
|
72
|
+
* per-type gevalideerd. Hun schema's valideren kinderen bewust alleen als `BlockBaseSchema`
|
|
73
|
+
* (passthrough) zodat klant-blokken erin mogen; de strikte controle gebeurt hier.
|
|
74
|
+
*/
|
|
75
|
+
export declare function validateBlocks(blocks: unknown[] | undefined, registry: BlockRegistry): BlockBase[];
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
function defineBlock(def) {
|
|
2
|
+
return def;
|
|
3
|
+
}
|
|
4
|
+
function buildBlockAddOptions(defs) {
|
|
5
|
+
const order = { content: 0, layout: 1, widget: 2 };
|
|
6
|
+
const suffix = { content: "", layout: " \xB7 indeling", widget: " \xB7 widget" };
|
|
7
|
+
return [...defs].map((d) => ({ def: d, cat: d.category ?? "content" })).sort((a, b) => order[a.cat] - order[b.cat]).map(({ def, cat }) => ({ value: def.type, label: `${def.icon ?? "\u25AB"} ${def.label}${suffix[cat]}` }));
|
|
8
|
+
}
|
|
9
|
+
function createRegistry(defs) {
|
|
10
|
+
const m = /* @__PURE__ */ new Map();
|
|
11
|
+
for (const d of defs) m.set(d.type, d);
|
|
12
|
+
return m;
|
|
13
|
+
}
|
|
14
|
+
function mergeRegistry(base, extra) {
|
|
15
|
+
const m = new Map(base);
|
|
16
|
+
for (const d of extra) m.set(d.type, d);
|
|
17
|
+
return m;
|
|
18
|
+
}
|
|
19
|
+
function validateBlocks(blocks, registry) {
|
|
20
|
+
const out = [];
|
|
21
|
+
for (const raw of blocks ?? []) {
|
|
22
|
+
const type = raw?._type;
|
|
23
|
+
const def = typeof type === "string" ? registry.get(type) : void 0;
|
|
24
|
+
if (!def) {
|
|
25
|
+
warn(`onbekend block-type "${String(type)}" overgeslagen (geen registratie).`);
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
const res = def.schema.safeParse(raw);
|
|
29
|
+
if (res.success) out.push(validateNestedBlocks(res.data, registry));
|
|
30
|
+
else warn(`block "${type}" voldoet niet aan zijn schema en is overgeslagen.`, res.error.issues);
|
|
31
|
+
}
|
|
32
|
+
return out;
|
|
33
|
+
}
|
|
34
|
+
function validateNestedBlocks(block, registry) {
|
|
35
|
+
const b = block;
|
|
36
|
+
if (b._type === "columns" && Array.isArray(b.columns)) {
|
|
37
|
+
return {
|
|
38
|
+
...b,
|
|
39
|
+
columns: b.columns.map(
|
|
40
|
+
(col) => col && typeof col === "object" && Array.isArray(col.blocks) ? { ...col, blocks: validateBlocks(col.blocks, registry) } : col
|
|
41
|
+
)
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (b._type === "withSidebar" && (Array.isArray(b.main) || Array.isArray(b.aside))) {
|
|
45
|
+
return {
|
|
46
|
+
...b,
|
|
47
|
+
main: Array.isArray(b.main) ? validateBlocks(b.main, registry) : b.main,
|
|
48
|
+
aside: Array.isArray(b.aside) ? validateBlocks(b.aside, registry) : b.aside
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
if (b._type === "tabs" && Array.isArray(b.tabs)) {
|
|
52
|
+
return {
|
|
53
|
+
...b,
|
|
54
|
+
tabs: b.tabs.map(
|
|
55
|
+
(tab) => tab && typeof tab === "object" && Array.isArray(tab.blocks) ? { ...tab, blocks: validateBlocks(tab.blocks, registry) } : tab
|
|
56
|
+
)
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
return block;
|
|
60
|
+
}
|
|
61
|
+
function warn(msg, detail) {
|
|
62
|
+
if (typeof console !== "undefined") console.warn(`[xicms] ${msg}`, detail ?? "");
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
buildBlockAddOptions,
|
|
66
|
+
createRegistry,
|
|
67
|
+
defineBlock,
|
|
68
|
+
mergeRegistry,
|
|
69
|
+
validateBlocks
|
|
70
|
+
};
|
|
71
|
+
//# sourceMappingURL=registry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/blocks/registry.ts"],"sourcesContent":["/**\n * Block-registry: koppelt een `_type` aan zijn Zod-schema, een (server-safe) Render-component\n * en een optionele (client/admin) Editor. Klant-blokken worden hier ingebracht via `defineBlock`\n * — zo blijft de core klant-onafhankelijk: de klant levert de render-component, core de structuur.\n *\n * Pure logica + types (geen \"use client\"): bruikbaar op server en client.\n */\nimport type { ComponentType } from \"react\";\nimport type { ZodTypeAny, z } from \"zod\";\nimport type { BlockBase } from \"../schema/blocks\";\n\nexport interface BlockRenderProps<T = unknown> {\n block: T;\n siteId: string;\n /** \"view\" = publiek; \"preview\" = draft-weergave in de editor. */\n mode?: \"view\" | \"preview\";\n}\n\nexport interface BlockEditorProps<T = unknown> {\n block: T;\n siteId: string;\n onChange: (next: T) => void;\n}\n\n/**\n * Indeling van een block in het toevoeg-menu:\n * - `content` (default): een gewoon blok dat je op de pagina plaatst.\n * - `widget`: een compacte variant die je naast een blok (in een zijbalk/kolom) zet — haalt z'n\n * gegevens uit dezelfde module als de volwaardige versie (bv. \"laatste nieuws\", \"komende agenda\").\n * - `layout`: een indelingsblok dat andere blokken bevat (kolommen, zijbalk, tabs).\n */\nexport type BlockCategory = \"content\" | \"widget\" | \"layout\";\n\nexport interface BlockDefinition<S extends ZodTypeAny = ZodTypeAny> {\n type: string;\n schema: S;\n Render: ComponentType<BlockRenderProps<z.infer<S>>>;\n /**\n * Admin-editor (lazy/client). Optioneel; ontbreekt = automatische schema-editor (GenericEditor):\n * die genereert een formulier uit het Zod-schema, dus een blok zonder eigen editor blijft bewerkbaar.\n */\n Editor?: ComponentType<BlockEditorProps<z.infer<S>>>;\n label: string;\n icon?: string;\n /** Groep in het toevoeg-menu (content/widget/layout). Standaard \"content\". */\n category?: BlockCategory;\n /** Defaultwaarden voor een nieuw block (zonder _key/_type). */\n defaults?: () => Record<string, unknown>;\n}\n\n/**\n * Registreert een block-type.\n *\n * UPDATE-VEILIGHEID: voeg in een nieuwe versie nooit een VERPLICHT veld toe aan een bestaand\n * block-schema zonder `.default()` of `.optional()`. Anders faalt validatie op al opgeslagen\n * content en wordt die overgeslagen. Met defaults/optioneel blijft oude content gewoon werken.\n */\nexport function defineBlock<S extends ZodTypeAny>(def: BlockDefinition<S>): BlockDefinition {\n // Type-erased return: het schema-type wordt alleen gebruikt om Render/Editor-props te\n // inferreren bij definitie. Daarna behandelen we blokken generiek in de registry.\n return def as unknown as BlockDefinition;\n}\n\nexport type BlockRegistry = Map<string, BlockDefinition>;\n\n/**\n * Bouwt de opties voor het \"blok toevoegen\"-menu, gegroepeerd op categorie: eerst gewone blokken,\n * dan indeling (kolommen/zijbalk/tabs), dan widgets. Widgets/indeling krijgen een suffix zodat de\n * groep duidelijk is in een platte keuzelijst.\n */\nexport function buildBlockAddOptions(defs: Iterable<BlockDefinition>): { value: string; label: string }[] {\n const order: Record<BlockCategory, number> = { content: 0, layout: 1, widget: 2 };\n const suffix: Record<BlockCategory, string> = { content: \"\", layout: \" · indeling\", widget: \" · widget\" };\n return [...defs]\n .map((d) => ({ def: d, cat: d.category ?? \"content\" }))\n .sort((a, b) => order[a.cat] - order[b.cat])\n .map(({ def, cat }) => ({ value: def.type, label: `${def.icon ?? \"▫\"} ${def.label}${suffix[cat]}` }));\n}\n\nexport function createRegistry(defs: BlockDefinition[]): BlockRegistry {\n const m: BlockRegistry = new Map();\n for (const d of defs) m.set(d.type, d);\n return m;\n}\n\nexport function mergeRegistry(base: BlockRegistry, extra: BlockDefinition[]): BlockRegistry {\n const m: BlockRegistry = new Map(base);\n for (const d of extra) m.set(d.type, d);\n return m;\n}\n\n/**\n * Strikte per-type validatie van een blocks-array tegen de registry. Onbekende types en\n * blocks die hun schema niet halen worden weggelaten (defensief — nooit half-rendered content).\n * Gebruikt bij publiceren (server) en vóór renderen.\n *\n * Recursief: geneste blokken in de indelingsblokken (kolommen, \"Met zijbalk\", tabs) worden óók\n * per-type gevalideerd. Hun schema's valideren kinderen bewust alleen als `BlockBaseSchema`\n * (passthrough) zodat klant-blokken erin mogen; de strikte controle gebeurt hier.\n */\nexport function validateBlocks(blocks: unknown[] | undefined, registry: BlockRegistry): BlockBase[] {\n const out: BlockBase[] = [];\n for (const raw of blocks ?? []) {\n const type = (raw as { _type?: unknown } | null)?._type;\n const def = typeof type === \"string\" ? registry.get(type) : undefined;\n if (!def) {\n warn(`onbekend block-type \"${String(type)}\" overgeslagen (geen registratie).`);\n continue;\n }\n const res = def.schema.safeParse(raw);\n if (res.success) out.push(validateNestedBlocks(res.data as BlockBase, registry));\n else warn(`block \"${type}\" voldoet niet aan zijn schema en is overgeslagen.`, res.error.issues);\n }\n return out;\n}\n\n/** Valideert de geneste blok-lijsten van de bekende indelingsvormen (immutable). */\nfunction validateNestedBlocks(block: BlockBase, registry: BlockRegistry): BlockBase {\n const b = block as BlockBase & Record<string, unknown>;\n if (b._type === \"columns\" && Array.isArray(b.columns)) {\n return {\n ...b,\n columns: b.columns.map((col) =>\n col && typeof col === \"object\" && Array.isArray((col as { blocks?: unknown }).blocks)\n ? { ...col, blocks: validateBlocks((col as { blocks: unknown[] }).blocks, registry) }\n : col,\n ),\n };\n }\n if (b._type === \"withSidebar\" && (Array.isArray(b.main) || Array.isArray(b.aside))) {\n return {\n ...b,\n main: Array.isArray(b.main) ? validateBlocks(b.main, registry) : b.main,\n aside: Array.isArray(b.aside) ? validateBlocks(b.aside, registry) : b.aside,\n };\n }\n if (b._type === \"tabs\" && Array.isArray(b.tabs)) {\n return {\n ...b,\n tabs: b.tabs.map((tab) =>\n tab && typeof tab === \"object\" && Array.isArray((tab as { blocks?: unknown }).blocks)\n ? { ...tab, blocks: validateBlocks((tab as { blocks: unknown[] }).blocks, registry) }\n : tab,\n ),\n };\n }\n return block;\n}\n\nfunction warn(msg: string, detail?: unknown): void {\n // Geen stil verlies: log waarom een block niet rendert (helpt bij schema-wijzigingen).\n if (typeof console !== \"undefined\") console.warn(`[xicms] ${msg}`, detail ?? \"\");\n}\n"],"mappings":"AAyDO,SAAS,YAAkC,KAA0C;AAG1F,SAAO;AACT;AASO,SAAS,qBAAqB,MAAqE;AACxG,QAAM,QAAuC,EAAE,SAAS,GAAG,QAAQ,GAAG,QAAQ,EAAE;AAChF,QAAM,SAAwC,EAAE,SAAS,IAAI,QAAQ,mBAAgB,QAAQ,gBAAa;AAC1G,SAAO,CAAC,GAAG,IAAI,EACZ,IAAI,CAAC,OAAO,EAAE,KAAK,GAAG,KAAK,EAAE,YAAY,UAAU,EAAE,EACrD,KAAK,CAAC,GAAG,MAAM,MAAM,EAAE,GAAG,IAAI,MAAM,EAAE,GAAG,CAAC,EAC1C,IAAI,CAAC,EAAE,KAAK,IAAI,OAAO,EAAE,OAAO,IAAI,MAAM,OAAO,GAAG,IAAI,QAAQ,QAAG,KAAK,IAAI,KAAK,GAAG,OAAO,GAAG,CAAC,GAAG,EAAE;AACzG;AAEO,SAAS,eAAe,MAAwC;AACrE,QAAM,IAAmB,oBAAI,IAAI;AACjC,aAAW,KAAK,KAAM,GAAE,IAAI,EAAE,MAAM,CAAC;AACrC,SAAO;AACT;AAEO,SAAS,cAAc,MAAqB,OAAyC;AAC1F,QAAM,IAAmB,IAAI,IAAI,IAAI;AACrC,aAAW,KAAK,MAAO,GAAE,IAAI,EAAE,MAAM,CAAC;AACtC,SAAO;AACT;AAWO,SAAS,eAAe,QAA+B,UAAsC;AAClG,QAAM,MAAmB,CAAC;AAC1B,aAAW,OAAO,UAAU,CAAC,GAAG;AAC9B,UAAM,OAAQ,KAAoC;AAClD,UAAM,MAAM,OAAO,SAAS,WAAW,SAAS,IAAI,IAAI,IAAI;AAC5D,QAAI,CAAC,KAAK;AACR,WAAK,wBAAwB,OAAO,IAAI,CAAC,oCAAoC;AAC7E;AAAA,IACF;AACA,UAAM,MAAM,IAAI,OAAO,UAAU,GAAG;AACpC,QAAI,IAAI,QAAS,KAAI,KAAK,qBAAqB,IAAI,MAAmB,QAAQ,CAAC;AAAA,QAC1E,MAAK,UAAU,IAAI,sDAAsD,IAAI,MAAM,MAAM;AAAA,EAChG;AACA,SAAO;AACT;AAGA,SAAS,qBAAqB,OAAkB,UAAoC;AAClF,QAAM,IAAI;AACV,MAAI,EAAE,UAAU,aAAa,MAAM,QAAQ,EAAE,OAAO,GAAG;AACrD,WAAO;AAAA,MACL,GAAG;AAAA,MACH,SAAS,EAAE,QAAQ;AAAA,QAAI,CAAC,QACtB,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAS,IAA6B,MAAM,IAChF,EAAE,GAAG,KAAK,QAAQ,eAAgB,IAA8B,QAAQ,QAAQ,EAAE,IAClF;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,MAAI,EAAE,UAAU,kBAAkB,MAAM,QAAQ,EAAE,IAAI,KAAK,MAAM,QAAQ,EAAE,KAAK,IAAI;AAClF,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM,MAAM,QAAQ,EAAE,IAAI,IAAI,eAAe,EAAE,MAAM,QAAQ,IAAI,EAAE;AAAA,MACnE,OAAO,MAAM,QAAQ,EAAE,KAAK,IAAI,eAAe,EAAE,OAAO,QAAQ,IAAI,EAAE;AAAA,IACxE;AAAA,EACF;AACA,MAAI,EAAE,UAAU,UAAU,MAAM,QAAQ,EAAE,IAAI,GAAG;AAC/C,WAAO;AAAA,MACL,GAAG;AAAA,MACH,MAAM,EAAE,KAAK;AAAA,QAAI,CAAC,QAChB,OAAO,OAAO,QAAQ,YAAY,MAAM,QAAS,IAA6B,MAAM,IAChF,EAAE,GAAG,KAAK,QAAQ,eAAgB,IAA8B,QAAQ,QAAQ,EAAE,IAClF;AAAA,MACN;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,KAAK,KAAa,QAAwB;AAEjD,MAAI,OAAO,YAAY,YAAa,SAAQ,KAAK,WAAW,GAAG,IAAI,UAAU,EAAE;AACjF;","names":[]}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Gedeelde presentatie-primitieven voor de runtime-blokken — een dunne laag bovenop het Astryx
|
|
3
|
+
* design system (Meta, StyleX). Blokken bouwen hierop i.p.v. losse `xicms-*`-classNames, zodat het
|
|
4
|
+
* uiterlijk consistent is en we de onderlaag centraal kunnen wijzigen.
|
|
5
|
+
*
|
|
6
|
+
* De merk-look per site komt via de Astryx-token-mapping op `.xicms-root` (zie XiCMSProvider):
|
|
7
|
+
* `--color-accent`, `--font-family-*`, `--radius-*` volgen de XiCMS-thema-tokens.
|
|
8
|
+
*/
|
|
9
|
+
import { type ReactNode } from "react";
|
|
10
|
+
export { VStack } from "@astryxdesign/core/VStack";
|
|
11
|
+
export { HStack } from "@astryxdesign/core/HStack";
|
|
12
|
+
export { Stack } from "@astryxdesign/core/Stack";
|
|
13
|
+
export { Grid } from "@astryxdesign/core/Grid";
|
|
14
|
+
export { Card } from "@astryxdesign/core/Card";
|
|
15
|
+
export { Heading } from "@astryxdesign/core/Heading";
|
|
16
|
+
export { Text } from "@astryxdesign/core/Text";
|
|
17
|
+
export { Divider } from "@astryxdesign/core/Divider";
|
|
18
|
+
export { Badge } from "@astryxdesign/core/Badge";
|
|
19
|
+
export { Avatar } from "@astryxdesign/core/Avatar";
|
|
20
|
+
export interface BtnProps {
|
|
21
|
+
label: string;
|
|
22
|
+
href?: string;
|
|
23
|
+
variant?: string;
|
|
24
|
+
/** Marketing-knoppen zijn standaard wat groter dan de app-default. */
|
|
25
|
+
size?: "sm" | "md" | "lg";
|
|
26
|
+
type?: "button" | "submit" | "reset";
|
|
27
|
+
target?: string;
|
|
28
|
+
onClick?: () => void;
|
|
29
|
+
children?: ReactNode;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Knop/CTA-helper bovenop Astryx `Button`. Rendert als link wanneer `href` gezet is. Houdt de
|
|
33
|
+
* bestaande XiCMS-varianten (primary/secondary/outline) werkend via de mapping hierboven.
|
|
34
|
+
*/
|
|
35
|
+
export declare function Btn({ label, href, variant, size, type, target, onClick }: BtnProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { Button } from "@astryxdesign/core/Button";
|
|
4
|
+
import { VStack } from "@astryxdesign/core/VStack";
|
|
5
|
+
import { HStack } from "@astryxdesign/core/HStack";
|
|
6
|
+
import { Stack } from "@astryxdesign/core/Stack";
|
|
7
|
+
import { Grid } from "@astryxdesign/core/Grid";
|
|
8
|
+
import { Card } from "@astryxdesign/core/Card";
|
|
9
|
+
import { Heading } from "@astryxdesign/core/Heading";
|
|
10
|
+
import { Text } from "@astryxdesign/core/Text";
|
|
11
|
+
import { Divider } from "@astryxdesign/core/Divider";
|
|
12
|
+
import { Badge } from "@astryxdesign/core/Badge";
|
|
13
|
+
import { Avatar } from "@astryxdesign/core/Avatar";
|
|
14
|
+
const VARIANT_MAP = {
|
|
15
|
+
primary: "primary",
|
|
16
|
+
secondary: "secondary",
|
|
17
|
+
outline: "ghost",
|
|
18
|
+
ghost: "ghost"
|
|
19
|
+
};
|
|
20
|
+
function Btn({ label, href, variant = "primary", size = "lg", type, target, onClick }) {
|
|
21
|
+
return /* @__PURE__ */ jsx(
|
|
22
|
+
Button,
|
|
23
|
+
{
|
|
24
|
+
label,
|
|
25
|
+
variant: VARIANT_MAP[variant] ?? "primary",
|
|
26
|
+
size,
|
|
27
|
+
href,
|
|
28
|
+
target: href && target ? target : void 0,
|
|
29
|
+
rel: target === "_blank" ? "noopener noreferrer" : void 0,
|
|
30
|
+
type: href ? void 0 : type ?? "button",
|
|
31
|
+
clickAction: onClick
|
|
32
|
+
}
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
export {
|
|
36
|
+
Avatar,
|
|
37
|
+
Badge,
|
|
38
|
+
Btn,
|
|
39
|
+
Card,
|
|
40
|
+
Divider,
|
|
41
|
+
Grid,
|
|
42
|
+
HStack,
|
|
43
|
+
Heading,
|
|
44
|
+
Stack,
|
|
45
|
+
Text,
|
|
46
|
+
VStack
|
|
47
|
+
};
|
|
48
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/blocks/ui/index.tsx"],"sourcesContent":["\"use client\";\n\n/**\n * Gedeelde presentatie-primitieven voor de runtime-blokken — een dunne laag bovenop het Astryx\n * design system (Meta, StyleX). Blokken bouwen hierop i.p.v. losse `xicms-*`-classNames, zodat het\n * uiterlijk consistent is en we de onderlaag centraal kunnen wijzigen.\n *\n * De merk-look per site komt via de Astryx-token-mapping op `.xicms-root` (zie XiCMSProvider):\n * `--color-accent`, `--font-family-*`, `--radius-*` volgen de XiCMS-thema-tokens.\n */\n\nimport { type ReactNode } from \"react\";\nimport { Button, type ButtonVariant } from \"@astryxdesign/core/Button\";\n\nexport { VStack } from \"@astryxdesign/core/VStack\";\nexport { HStack } from \"@astryxdesign/core/HStack\";\nexport { Stack } from \"@astryxdesign/core/Stack\";\nexport { Grid } from \"@astryxdesign/core/Grid\";\nexport { Card } from \"@astryxdesign/core/Card\";\nexport { Heading } from \"@astryxdesign/core/Heading\";\nexport { Text } from \"@astryxdesign/core/Text\";\nexport { Divider } from \"@astryxdesign/core/Divider\";\nexport { Badge } from \"@astryxdesign/core/Badge\";\nexport { Avatar } from \"@astryxdesign/core/Avatar\";\n\n/** XiCMS-knopvarianten → Astryx-varianten (Astryx kent geen \"outline\" → ghost). */\nconst VARIANT_MAP: Record<string, ButtonVariant> = {\n primary: \"primary\",\n secondary: \"secondary\",\n outline: \"ghost\",\n ghost: \"ghost\",\n};\n\nexport interface BtnProps {\n label: string;\n href?: string;\n variant?: string;\n /** Marketing-knoppen zijn standaard wat groter dan de app-default. */\n size?: \"sm\" | \"md\" | \"lg\";\n type?: \"button\" | \"submit\" | \"reset\";\n target?: string;\n onClick?: () => void;\n children?: ReactNode;\n}\n\n/**\n * Knop/CTA-helper bovenop Astryx `Button`. Rendert als link wanneer `href` gezet is. Houdt de\n * bestaande XiCMS-varianten (primary/secondary/outline) werkend via de mapping hierboven.\n */\nexport function Btn({ label, href, variant = \"primary\", size = \"lg\", type, target, onClick }: BtnProps) {\n return (\n <Button\n label={label}\n variant={VARIANT_MAP[variant] ?? \"primary\"}\n size={size}\n href={href}\n target={href && target ? target : undefined}\n rel={target === \"_blank\" ? \"noopener noreferrer\" : undefined}\n type={href ? undefined : (type ?? \"button\")}\n clickAction={onClick}\n />\n );\n}\n"],"mappings":";AAmDI;AAvCJ,SAAS,cAAkC;AAE3C,SAAS,cAAc;AACvB,SAAS,cAAc;AACvB,SAAS,aAAa;AACtB,SAAS,YAAY;AACrB,SAAS,YAAY;AACrB,SAAS,eAAe;AACxB,SAAS,YAAY;AACrB,SAAS,eAAe;AACxB,SAAS,aAAa;AACtB,SAAS,cAAc;AAGvB,MAAM,cAA6C;AAAA,EACjD,SAAS;AAAA,EACT,WAAW;AAAA,EACX,SAAS;AAAA,EACT,OAAO;AACT;AAkBO,SAAS,IAAI,EAAE,OAAO,MAAM,UAAU,WAAW,OAAO,MAAM,MAAM,QAAQ,QAAQ,GAAa;AACtG,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,SAAS,YAAY,OAAO,KAAK;AAAA,MACjC;AAAA,MACA;AAAA,MACA,QAAQ,QAAQ,SAAS,SAAS;AAAA,MAClC,KAAK,WAAW,WAAW,wBAAwB;AAAA,MACnD,MAAM,OAAO,SAAa,QAAQ;AAAA,MAClC,aAAa;AAAA;AAAA,EACf;AAEJ;","names":[]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useAuth } from "../auth/AuthProvider";
|
|
4
|
+
import { canEdit } from "../auth/roles";
|
|
5
|
+
import { useEditor } from "../editor/EditorProvider";
|
|
6
|
+
function EditBar() {
|
|
7
|
+
const { user, role, signOut, demo } = useAuth();
|
|
8
|
+
const { open, openEditor } = useEditor();
|
|
9
|
+
if (!canEdit(role) || !user || open) return null;
|
|
10
|
+
return /* @__PURE__ */ jsxs("div", { className: "xicms-editbar", children: [
|
|
11
|
+
/* @__PURE__ */ jsx("span", { style: { fontWeight: 600 }, children: demo ? "XiCMS \xB7 demo" : "XiCMS" }),
|
|
12
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "xicms-btn", onClick: openEditor, children: "\u270F\uFE0F Pagina bewerken" }),
|
|
13
|
+
!demo && /* @__PURE__ */ jsx("a", { href: "/beheer", className: "xicms-btn xicms-btn--ghost", children: "Beheer" }),
|
|
14
|
+
/* @__PURE__ */ jsx("button", { type: "button", className: "xicms-btn xicms-btn--ghost", onClick: () => void signOut(), children: "Uitloggen" })
|
|
15
|
+
] });
|
|
16
|
+
}
|
|
17
|
+
export {
|
|
18
|
+
EditBar
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=EditBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/EditBar.tsx"],"sourcesContent":["\"use client\";\n\nimport { useAuth } from \"../auth/AuthProvider\";\nimport { canEdit } from \"../auth/roles\";\nimport { useEditor } from \"../editor/EditorProvider\";\n\n/** Zwevende werkbalk voor ingelogde beheerders/editors. */\nexport function EditBar() {\n // Bewust via useAuth (niet via het deprecated ContentProvider-pad): de EditBar hoort bij het\n // block-model en mag niet aan het legacy inline-systeem hangen.\n const { user, role, signOut, demo } = useAuth();\n const { open, openEditor } = useEditor();\n\n if (!canEdit(role) || !user || open) return null;\n\n return (\n <div className=\"xicms-editbar\">\n <span style={{ fontWeight: 600 }}>{demo ? \"XiCMS · demo\" : \"XiCMS\"}</span>\n {/* Eén heldere bewerk-actie: opent de visuele editor waarin je tekst ter plekke (inline) bewerkt\n én structuur/blokken aanpast. Geen aparte (verwarrende) inline-toggle meer. */}\n <button type=\"button\" className=\"xicms-btn\" onClick={openEditor}>\n ✏️ Pagina bewerken\n </button>\n {/* In de demo bestaat er geen /beheer-route; daar bewerk je alleen op de pagina. */}\n {!demo && <a href=\"/beheer\" className=\"xicms-btn xicms-btn--ghost\">Beheer</a>}\n <button type=\"button\" className=\"xicms-btn xicms-btn--ghost\" onClick={() => void signOut()}>\n Uitloggen\n </button>\n </div>\n );\n}\n"],"mappings":";AAgBI,SACE,KADF;AAdJ,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,iBAAiB;AAGnB,SAAS,UAAU;AAGxB,QAAM,EAAE,MAAM,MAAM,SAAS,KAAK,IAAI,QAAQ;AAC9C,QAAM,EAAE,MAAM,WAAW,IAAI,UAAU;AAEvC,MAAI,CAAC,QAAQ,IAAI,KAAK,CAAC,QAAQ,KAAM,QAAO;AAE5C,SACE,qBAAC,SAAI,WAAU,iBACb;AAAA,wBAAC,UAAK,OAAO,EAAE,YAAY,IAAI,GAAI,iBAAO,oBAAiB,SAAQ;AAAA,IAGnE,oBAAC,YAAO,MAAK,UAAS,WAAU,aAAY,SAAS,YAAY,0CAEjE;AAAA,IAEC,CAAC,QAAQ,oBAAC,OAAE,MAAK,WAAU,WAAU,8BAA6B,oBAAM;AAAA,IACzE,oBAAC,YAAO,MAAK,UAAS,WAAU,8BAA6B,SAAS,MAAM,KAAK,QAAQ,GAAG,uBAE5F;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
interface EditableImageProps {
|
|
3
|
+
/** Stabiel content-id, bv. "home.hero.image". */
|
|
4
|
+
id: string;
|
|
5
|
+
/** Standaard-afbeelding (URL) zolang er geen upload is. */
|
|
6
|
+
src?: string;
|
|
7
|
+
alt?: string;
|
|
8
|
+
className?: string;
|
|
9
|
+
style?: CSSProperties;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Bewerkbare afbeelding. In bewerk-modus kan een nieuwe afbeelding worden geüpload via dezelfde
|
|
13
|
+
* gedeelde pipeline als het beheer (`uploadImage`: automatische webp-compressie + media-registratie),
|
|
14
|
+
* zodat inline bewerken en de block-editor consistent zijn. De URL wordt als content-waarde opgeslagen.
|
|
15
|
+
*/
|
|
16
|
+
/** @deprecated Legacy inline (v1). Gebruik een image-block (inline vervangen via de mediakiezer). */
|
|
17
|
+
export declare function EditableImage({ id, src, alt, className, style }: EditableImageProps): import("react").JSX.Element;
|
|
18
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useRef, useState } from "react";
|
|
4
|
+
import { useContent } from "../content/ContentProvider";
|
|
5
|
+
import { useSiteConfig } from "../config";
|
|
6
|
+
import { uploadImage } from "../admin/lib/upload";
|
|
7
|
+
function EditableImage({ id, src, alt = "", className, style }) {
|
|
8
|
+
const { get, set, editMode, canEdit } = useContent();
|
|
9
|
+
const { siteId } = useSiteConfig();
|
|
10
|
+
const inputRef = useRef(null);
|
|
11
|
+
const [busy, setBusy] = useState(false);
|
|
12
|
+
const url = get(id, src ?? "");
|
|
13
|
+
async function handleFile(file) {
|
|
14
|
+
setBusy(true);
|
|
15
|
+
try {
|
|
16
|
+
const { url: uploaded } = await uploadImage(siteId, file);
|
|
17
|
+
await set(id, uploaded);
|
|
18
|
+
} catch (e) {
|
|
19
|
+
if (typeof window !== "undefined") window.alert(`Upload mislukt: ${e.message}`);
|
|
20
|
+
} finally {
|
|
21
|
+
setBusy(false);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
const img = url ? (
|
|
25
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
26
|
+
/* @__PURE__ */ jsx("img", { src: url, alt, className, style })
|
|
27
|
+
) : /* @__PURE__ */ jsx("div", { className, style: { background: "#e5e7eb", ...style }, "aria-label": alt });
|
|
28
|
+
if (editMode && canEdit) {
|
|
29
|
+
return /* @__PURE__ */ jsxs("div", { style: { position: "relative", display: "inline-block" }, className: "xicms-editable", children: [
|
|
30
|
+
img,
|
|
31
|
+
/* @__PURE__ */ jsx(
|
|
32
|
+
"button",
|
|
33
|
+
{
|
|
34
|
+
type: "button",
|
|
35
|
+
className: "xicms-btn",
|
|
36
|
+
style: { position: "absolute", bottom: 8, left: 8 },
|
|
37
|
+
disabled: busy,
|
|
38
|
+
onClick: () => inputRef.current?.click(),
|
|
39
|
+
children: busy ? "Uploaden\u2026" : "Afbeelding wijzigen"
|
|
40
|
+
}
|
|
41
|
+
),
|
|
42
|
+
/* @__PURE__ */ jsx(
|
|
43
|
+
"input",
|
|
44
|
+
{
|
|
45
|
+
ref: inputRef,
|
|
46
|
+
type: "file",
|
|
47
|
+
accept: "image/*",
|
|
48
|
+
hidden: true,
|
|
49
|
+
onChange: (e) => {
|
|
50
|
+
const f = e.target.files?.[0];
|
|
51
|
+
if (f) void handleFile(f);
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
)
|
|
55
|
+
] });
|
|
56
|
+
}
|
|
57
|
+
return img;
|
|
58
|
+
}
|
|
59
|
+
export {
|
|
60
|
+
EditableImage
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=EditableImage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/EditableImage.tsx"],"sourcesContent":["\"use client\";\n\nimport { useRef, useState, type CSSProperties } from \"react\";\nimport { useContent } from \"../content/ContentProvider\";\nimport { useSiteConfig } from \"../config\";\nimport { uploadImage } from \"../admin/lib/upload\";\n\ninterface EditableImageProps {\n /** Stabiel content-id, bv. \"home.hero.image\". */\n id: string;\n /** Standaard-afbeelding (URL) zolang er geen upload is. */\n src?: string;\n alt?: string;\n className?: string;\n style?: CSSProperties;\n}\n\n/**\n * Bewerkbare afbeelding. In bewerk-modus kan een nieuwe afbeelding worden geüpload via dezelfde\n * gedeelde pipeline als het beheer (`uploadImage`: automatische webp-compressie + media-registratie),\n * zodat inline bewerken en de block-editor consistent zijn. De URL wordt als content-waarde opgeslagen.\n */\n/** @deprecated Legacy inline (v1). Gebruik een image-block (inline vervangen via de mediakiezer). */\nexport function EditableImage({ id, src, alt = \"\", className, style }: EditableImageProps) {\n const { get, set, editMode, canEdit } = useContent();\n const { siteId } = useSiteConfig();\n const inputRef = useRef<HTMLInputElement>(null);\n const [busy, setBusy] = useState(false);\n const url = get(id, src ?? \"\");\n\n async function handleFile(file: File) {\n setBusy(true);\n try {\n const { url: uploaded } = await uploadImage(siteId, file);\n await set(id, uploaded);\n } catch (e) {\n // eslint-disable-next-line no-alert\n if (typeof window !== \"undefined\") window.alert(`Upload mislukt: ${(e as Error).message}`);\n } finally {\n setBusy(false);\n }\n }\n\n const img = url ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img src={url} alt={alt} className={className} style={style} />\n ) : (\n <div className={className} style={{ background: \"#e5e7eb\", ...style }} aria-label={alt} />\n );\n\n if (editMode && canEdit) {\n return (\n <div style={{ position: \"relative\", display: \"inline-block\" }} className=\"xicms-editable\">\n {img}\n <button\n type=\"button\"\n className=\"xicms-btn\"\n style={{ position: \"absolute\", bottom: 8, left: 8 }}\n disabled={busy}\n onClick={() => inputRef.current?.click()}\n >\n {busy ? \"Uploaden…\" : \"Afbeelding wijzigen\"}\n </button>\n <input\n ref={inputRef}\n type=\"file\"\n accept=\"image/*\"\n hidden\n onChange={(e) => {\n const f = e.target.files?.[0];\n if (f) void handleFile(f);\n }}\n />\n </div>\n );\n }\n\n return img;\n}\n"],"mappings":";AA6CI,cAOE,YAPF;AA3CJ,SAAS,QAAQ,gBAAoC;AACrD,SAAS,kBAAkB;AAC3B,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAkBrB,SAAS,cAAc,EAAE,IAAI,KAAK,MAAM,IAAI,WAAW,MAAM,GAAuB;AACzF,QAAM,EAAE,KAAK,KAAK,UAAU,QAAQ,IAAI,WAAW;AACnD,QAAM,EAAE,OAAO,IAAI,cAAc;AACjC,QAAM,WAAW,OAAyB,IAAI;AAC9C,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,MAAM,IAAI,IAAI,OAAO,EAAE;AAE7B,iBAAe,WAAW,MAAY;AACpC,YAAQ,IAAI;AACZ,QAAI;AACF,YAAM,EAAE,KAAK,SAAS,IAAI,MAAM,YAAY,QAAQ,IAAI;AACxD,YAAM,IAAI,IAAI,QAAQ;AAAA,IACxB,SAAS,GAAG;AAEV,UAAI,OAAO,WAAW,YAAa,QAAO,MAAM,mBAAoB,EAAY,OAAO,EAAE;AAAA,IAC3F,UAAE;AACA,cAAQ,KAAK;AAAA,IACf;AAAA,EACF;AAEA,QAAM,MAAM;AAAA;AAAA,IAEV,oBAAC,SAAI,KAAK,KAAK,KAAU,WAAsB,OAAc;AAAA,MAE7D,oBAAC,SAAI,WAAsB,OAAO,EAAE,YAAY,WAAW,GAAG,MAAM,GAAG,cAAY,KAAK;AAG1F,MAAI,YAAY,SAAS;AACvB,WACE,qBAAC,SAAI,OAAO,EAAE,UAAU,YAAY,SAAS,eAAe,GAAG,WAAU,kBACtE;AAAA;AAAA,MACD;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,OAAO,EAAE,UAAU,YAAY,QAAQ,GAAG,MAAM,EAAE;AAAA,UAClD,UAAU;AAAA,UACV,SAAS,MAAM,SAAS,SAAS,MAAM;AAAA,UAEtC,iBAAO,mBAAc;AAAA;AAAA,MACxB;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,KAAK;AAAA,UACL,MAAK;AAAA,UACL,QAAO;AAAA,UACP,QAAM;AAAA,UACN,UAAU,CAAC,MAAM;AACf,kBAAM,IAAI,EAAE,OAAO,QAAQ,CAAC;AAC5B,gBAAI,EAAG,MAAK,WAAW,CAAC;AAAA,UAC1B;AAAA;AAAA,MACF;AAAA,OACF;AAAA,EAEJ;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
interface EditableRichTextProps {
|
|
3
|
+
id: string;
|
|
4
|
+
className?: string;
|
|
5
|
+
style?: CSSProperties;
|
|
6
|
+
children?: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Meerregelig bewerkbaar tekstblok (platte tekst, regelafbrekingen blijven behouden).
|
|
10
|
+
* In bewerk-modus een textarea; daarbuiten paragrafen. Bewust géén HTML, om XSS te vermijden.
|
|
11
|
+
*/
|
|
12
|
+
/** @deprecated Legacy inline (v1). Gebruik een richText-block + de visuele editor. */
|
|
13
|
+
export declare function EditableRichText({ id, className, style, children }: EditableRichTextProps): import("react").JSX.Element;
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { jsx } from "react/jsx-runtime";
|
|
3
|
+
import { useContent } from "../content/ContentProvider";
|
|
4
|
+
function EditableRichText({ id, className, style, children }) {
|
|
5
|
+
const { get, set, editMode, canEdit } = useContent();
|
|
6
|
+
const value = get(id, children ?? "");
|
|
7
|
+
if (editMode && canEdit) {
|
|
8
|
+
return /* @__PURE__ */ jsx(
|
|
9
|
+
"textarea",
|
|
10
|
+
{
|
|
11
|
+
className: `${className ?? ""} xicms-editable`.trim(),
|
|
12
|
+
style: { width: "100%", minHeight: 120, ...style },
|
|
13
|
+
defaultValue: value,
|
|
14
|
+
"data-xicms-id": id,
|
|
15
|
+
onBlur: (e) => {
|
|
16
|
+
if (e.currentTarget.value !== value) void set(id, e.currentTarget.value);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
return /* @__PURE__ */ jsx("div", { className, style, children: value.split(/\n{2,}/).map((para, i) => /* @__PURE__ */ jsx("p", { style: { whiteSpace: "pre-wrap" }, children: para }, i)) });
|
|
22
|
+
}
|
|
23
|
+
export {
|
|
24
|
+
EditableRichText
|
|
25
|
+
};
|
|
26
|
+
//# sourceMappingURL=EditableRichText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/EditableRichText.tsx"],"sourcesContent":["\"use client\";\n\nimport { type CSSProperties } from \"react\";\nimport { useContent } from \"../content/ContentProvider\";\n\ninterface EditableRichTextProps {\n id: string;\n className?: string;\n style?: CSSProperties;\n children?: string;\n}\n\n/**\n * Meerregelig bewerkbaar tekstblok (platte tekst, regelafbrekingen blijven behouden).\n * In bewerk-modus een textarea; daarbuiten paragrafen. Bewust géén HTML, om XSS te vermijden.\n */\n/** @deprecated Legacy inline (v1). Gebruik een richText-block + de visuele editor. */\nexport function EditableRichText({ id, className, style, children }: EditableRichTextProps) {\n const { get, set, editMode, canEdit } = useContent();\n const value = get(id, children ?? \"\");\n\n if (editMode && canEdit) {\n return (\n <textarea\n className={`${className ?? \"\"} xicms-editable`.trim()}\n style={{ width: \"100%\", minHeight: 120, ...style }}\n defaultValue={value}\n data-xicms-id={id}\n onBlur={(e) => {\n if (e.currentTarget.value !== value) void set(id, e.currentTarget.value);\n }}\n />\n );\n }\n\n return (\n <div className={className} style={style}>\n {value.split(/\\n{2,}/).map((para, i) => (\n <p key={i} style={{ whiteSpace: \"pre-wrap\" }}>\n {para}\n </p>\n ))}\n </div>\n );\n}\n"],"mappings":";AAuBM;AApBN,SAAS,kBAAkB;AAcpB,SAAS,iBAAiB,EAAE,IAAI,WAAW,OAAO,SAAS,GAA0B;AAC1F,QAAM,EAAE,KAAK,KAAK,UAAU,QAAQ,IAAI,WAAW;AACnD,QAAM,QAAQ,IAAI,IAAI,YAAY,EAAE;AAEpC,MAAI,YAAY,SAAS;AACvB,WACE;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,GAAG,aAAa,EAAE,kBAAkB,KAAK;AAAA,QACpD,OAAO,EAAE,OAAO,QAAQ,WAAW,KAAK,GAAG,MAAM;AAAA,QACjD,cAAc;AAAA,QACd,iBAAe;AAAA,QACf,QAAQ,CAAC,MAAM;AACb,cAAI,EAAE,cAAc,UAAU,MAAO,MAAK,IAAI,IAAI,EAAE,cAAc,KAAK;AAAA,QACzE;AAAA;AAAA,IACF;AAAA,EAEJ;AAEA,SACE,oBAAC,SAAI,WAAsB,OACxB,gBAAM,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,MAChC,oBAAC,OAAU,OAAO,EAAE,YAAY,WAAW,GACxC,kBADK,CAER,CACD,GACH;AAEJ;","names":[]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { type CSSProperties } from "react";
|
|
2
|
+
interface EditableTextProps {
|
|
3
|
+
/** Stabiel content-id, bv. "home.hero.title". */
|
|
4
|
+
id: string;
|
|
5
|
+
/** HTML-element waarin de tekst wordt gerenderd. */
|
|
6
|
+
as?: keyof React.JSX.IntrinsicElements;
|
|
7
|
+
className?: string;
|
|
8
|
+
style?: CSSProperties;
|
|
9
|
+
/** Standaardtekst als er nog geen waarde is. */
|
|
10
|
+
children?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Inline bewerkbaar tekstblok. In bewerk-modus (voor wie mag bewerken) wordt het element
|
|
14
|
+
* `contentEditable`; bij blur wordt de tekst opgeslagen. Buiten bewerk-modus is het gewone tekst.
|
|
15
|
+
*/
|
|
16
|
+
/** @deprecated Legacy inline (v1). Gebruik een block met `data-xicms-edit` + de visuele editor. */
|
|
17
|
+
export declare function EditableText({ id, as, className, style, children }: EditableTextProps): import("react").ReactElement<{
|
|
18
|
+
className: string | undefined;
|
|
19
|
+
style: CSSProperties | undefined;
|
|
20
|
+
}, string | import("react").JSXElementConstructor<any>>;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { createElement } from "react";
|
|
3
|
+
import { useContent } from "../content/ContentProvider";
|
|
4
|
+
function EditableText({ id, as = "span", className, style, children }) {
|
|
5
|
+
const { get, set, editMode, canEdit } = useContent();
|
|
6
|
+
const value = get(id, children ?? "");
|
|
7
|
+
if (editMode && canEdit) {
|
|
8
|
+
return createElement(as, {
|
|
9
|
+
className: `${className ?? ""} xicms-editable`.trim(),
|
|
10
|
+
style,
|
|
11
|
+
contentEditable: true,
|
|
12
|
+
suppressContentEditableWarning: true,
|
|
13
|
+
"data-xicms-id": id,
|
|
14
|
+
onBlur: (e) => {
|
|
15
|
+
const next = e.currentTarget.textContent ?? "";
|
|
16
|
+
if (next !== value) void set(id, next);
|
|
17
|
+
}
|
|
18
|
+
}, value);
|
|
19
|
+
}
|
|
20
|
+
return createElement(as, { className, style }, value);
|
|
21
|
+
}
|
|
22
|
+
export {
|
|
23
|
+
EditableText
|
|
24
|
+
};
|
|
25
|
+
//# sourceMappingURL=EditableText.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/components/EditableText.tsx"],"sourcesContent":["\"use client\";\n\nimport { createElement, type CSSProperties, type FocusEvent } from \"react\";\nimport { useContent } from \"../content/ContentProvider\";\n\ninterface EditableTextProps {\n /** Stabiel content-id, bv. \"home.hero.title\". */\n id: string;\n /** HTML-element waarin de tekst wordt gerenderd. */\n as?: keyof React.JSX.IntrinsicElements;\n className?: string;\n style?: CSSProperties;\n /** Standaardtekst als er nog geen waarde is. */\n children?: string;\n}\n\n/**\n * Inline bewerkbaar tekstblok. In bewerk-modus (voor wie mag bewerken) wordt het element\n * `contentEditable`; bij blur wordt de tekst opgeslagen. Buiten bewerk-modus is het gewone tekst.\n */\n/** @deprecated Legacy inline (v1). Gebruik een block met `data-xicms-edit` + de visuele editor. */\nexport function EditableText({ id, as = \"span\", className, style, children }: EditableTextProps) {\n const { get, set, editMode, canEdit } = useContent();\n const value = get(id, children ?? \"\");\n\n if (editMode && canEdit) {\n return createElement(as, {\n className: `${className ?? \"\"} xicms-editable`.trim(),\n style,\n contentEditable: true,\n suppressContentEditableWarning: true,\n \"data-xicms-id\": id,\n onBlur: (e: FocusEvent<HTMLElement>) => {\n const next = e.currentTarget.textContent ?? \"\";\n if (next !== value) void set(id, next);\n },\n }, value);\n }\n\n return createElement(as, { className, style }, value);\n}\n"],"mappings":";AAEA,SAAS,qBAA0D;AACnE,SAAS,kBAAkB;AAkBpB,SAAS,aAAa,EAAE,IAAI,KAAK,QAAQ,WAAW,OAAO,SAAS,GAAsB;AAC/F,QAAM,EAAE,KAAK,KAAK,UAAU,QAAQ,IAAI,WAAW;AACnD,QAAM,QAAQ,IAAI,IAAI,YAAY,EAAE;AAEpC,MAAI,YAAY,SAAS;AACvB,WAAO,cAAc,IAAI;AAAA,MACvB,WAAW,GAAG,aAAa,EAAE,kBAAkB,KAAK;AAAA,MACpD;AAAA,MACA,iBAAiB;AAAA,MACjB,gCAAgC;AAAA,MAChC,iBAAiB;AAAA,MACjB,QAAQ,CAAC,MAA+B;AACtC,cAAM,OAAO,EAAE,cAAc,eAAe;AAC5C,YAAI,SAAS,MAAO,MAAK,IAAI,IAAI,IAAI;AAAA,MACvC;AAAA,IACF,GAAG,KAAK;AAAA,EACV;AAEA,SAAO,cAAc,IAAI,EAAE,WAAW,MAAM,GAAG,KAAK;AACtD;","names":[]}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { NewsArticle } from "../content/types";
|
|
2
|
+
/**
|
|
3
|
+
* Lijst van nieuwsartikelen voor de huidige site.
|
|
4
|
+
* - `live: false` (standaard publiek): één keer ophalen met getDocs → geen per-bezoeker listener
|
|
5
|
+
* (scheelt Firestore-kosten op druk bezochte sites).
|
|
6
|
+
* - `live: true` (admin): realtime via onSnapshot, zodat wijzigingen meteen zichtbaar zijn.
|
|
7
|
+
*/
|
|
8
|
+
export declare function useNews(opts?: {
|
|
9
|
+
onlyPublished?: boolean;
|
|
10
|
+
live?: boolean;
|
|
11
|
+
max?: number;
|
|
12
|
+
}): {
|
|
13
|
+
articles: NewsArticle[];
|
|
14
|
+
loading: boolean;
|
|
15
|
+
};
|
|
16
|
+
interface NewsListProps {
|
|
17
|
+
/** Basispad voor links naar een artikel, bv. "/nieuws". */
|
|
18
|
+
basePath?: string;
|
|
19
|
+
className?: string;
|
|
20
|
+
emptyLabel?: string;
|
|
21
|
+
/** Maximaal aantal artikelen om te tonen. */
|
|
22
|
+
limit?: number;
|
|
23
|
+
/** Toon eerst dit aantal en laad de rest met een "Meer laden"-knop (0/leeg = alles ineens). */
|
|
24
|
+
pageSize?: number;
|
|
25
|
+
}
|
|
26
|
+
/** Standaardweergave van nieuwsartikelen als kaartenlijst, optioneel gepagineerd. */
|
|
27
|
+
export declare function NewsList({ basePath, className, emptyLabel, limit, pageSize }: NewsListProps): import("react").JSX.Element;
|
|
28
|
+
/** BlogPosting-JSON-LD voor een artikel — puur, zodat het testbaar is. */
|
|
29
|
+
export declare function articleBlogPostingJsonLd(article: NewsArticle, opts?: {
|
|
30
|
+
siteName?: string;
|
|
31
|
+
url?: string;
|
|
32
|
+
}): Record<string, unknown>;
|
|
33
|
+
/** Detailweergave van één artikel, met BlogPosting-JSON-LD voor zoekmachines. */
|
|
34
|
+
export declare function NewsArticleView({ article, jsonLd }: {
|
|
35
|
+
article: NewsArticle;
|
|
36
|
+
jsonLd?: boolean;
|
|
37
|
+
}): import("react").JSX.Element;
|
|
38
|
+
export {};
|