@xiwebdesign/xicms-core 7.30.0 → 8.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/XiCMSProvider.js +22 -7
- package/dist/XiCMSProvider.js.map +1 -1
- package/dist/admin/AdminApp.js +175 -93
- package/dist/admin/AdminApp.js.map +1 -1
- package/dist/admin/AdminHelp.d.ts +1 -1
- package/dist/admin/AdminHelp.js +44 -36
- package/dist/admin/AdminHelp.js.map +1 -1
- package/dist/admin/CoreVersion.d.ts +6 -3
- package/dist/admin/CoreVersion.js +60 -24
- package/dist/admin/CoreVersion.js.map +1 -1
- package/dist/admin/NewsEditor.d.ts +7 -0
- package/dist/admin/NewsEditor.js +117 -75
- package/dist/admin/NewsEditor.js.map +1 -1
- package/dist/admin/SuperadminPanel.js +1 -1
- package/dist/admin/SuperadminPanel.js.map +1 -1
- package/dist/admin/ZoekPalet.d.ts +15 -0
- package/dist/admin/ZoekPalet.js +123 -0
- package/dist/admin/ZoekPalet.js.map +1 -0
- package/dist/admin/blockEditors/GenericEditor.js +36 -18
- package/dist/admin/blockEditors/GenericEditor.js.map +1 -1
- package/dist/admin/blockEditors/StyleEditor.js +37 -3
- package/dist/admin/blockEditors/StyleEditor.js.map +1 -1
- package/dist/admin/blockEditors/SymbolRefEditor.js +44 -2
- package/dist/admin/blockEditors/SymbolRefEditor.js.map +1 -1
- package/dist/admin/blockEditors/index.js +154 -73
- package/dist/admin/blockEditors/index.js.map +1 -1
- package/dist/admin/customBlocks/CustomBlocksPanel.js +18 -7
- package/dist/admin/customBlocks/CustomBlocksPanel.js.map +1 -1
- package/dist/admin/dashboard/DashboardPanel.js +26 -16
- package/dist/admin/dashboard/DashboardPanel.js.map +1 -1
- package/dist/admin/editors/RichTextEditor.d.ts +4 -3
- package/dist/admin/editors/RichTextEditor.js +19 -56
- package/dist/admin/editors/RichTextEditor.js.map +1 -1
- package/dist/admin/editors/fontSizeExtension.js +7 -1
- package/dist/admin/editors/fontSizeExtension.js.map +1 -1
- package/dist/admin/editors/slashMenu.d.ts +18 -0
- package/dist/admin/editors/slashMenu.js +34 -0
- package/dist/admin/editors/slashMenu.js.map +1 -0
- package/dist/admin/editors/useRijkeTekst.d.ts +48 -0
- package/dist/admin/editors/useRijkeTekst.js +310 -0
- package/dist/admin/editors/useRijkeTekst.js.map +1 -0
- package/dist/admin/forms/FormsPanel.d.ts +11 -2
- package/dist/admin/forms/FormsPanel.js +218 -65
- package/dist/admin/forms/FormsPanel.js.map +1 -1
- package/dist/admin/lib/blokInfo.d.ts +17 -0
- package/dist/admin/lib/blokInfo.js +80 -0
- package/dist/admin/lib/blokInfo.js.map +1 -0
- package/dist/admin/lib/foutNaarMens.d.ts +1 -0
- package/dist/admin/lib/foutNaarMens.js +22 -0
- package/dist/admin/lib/foutNaarMens.js.map +1 -0
- package/dist/admin/lib/gewisteVelden.d.ts +13 -0
- package/dist/admin/lib/gewisteVelden.js +31 -0
- package/dist/admin/lib/gewisteVelden.js.map +1 -0
- package/dist/admin/lib/heroHulp.d.ts +11 -0
- package/dist/admin/lib/heroHulp.js +18 -0
- package/dist/admin/lib/heroHulp.js.map +1 -0
- package/dist/admin/lib/kleur.js +2 -3
- package/dist/admin/lib/kleur.js.map +1 -1
- package/dist/admin/lib/leesbaarheid.d.ts +34 -0
- package/dist/admin/lib/leesbaarheid.js +82 -0
- package/dist/admin/lib/leesbaarheid.js.map +1 -0
- package/dist/admin/lib/lengteAdvies.d.ts +1 -0
- package/dist/admin/lib/lengteAdvies.js +16 -0
- package/dist/admin/lib/lengteAdvies.js.map +1 -0
- package/dist/admin/lib/mediaLijst.d.ts +26 -0
- package/dist/admin/lib/mediaLijst.js +42 -0
- package/dist/admin/lib/mediaLijst.js.map +1 -0
- package/dist/admin/lib/mediaUsage.d.ts +12 -1
- package/dist/admin/lib/mediaUsage.js +43 -33
- package/dist/admin/lib/mediaUsage.js.map +1 -1
- package/dist/admin/lib/menuHulp.d.ts +16 -0
- package/dist/admin/lib/menuHulp.js +41 -0
- package/dist/admin/lib/menuHulp.js.map +1 -0
- package/dist/admin/lib/onopgeslagen.d.ts +10 -0
- package/dist/admin/lib/onopgeslagen.js +35 -0
- package/dist/admin/lib/onopgeslagen.js.map +1 -0
- package/dist/admin/lib/pagesClient.d.ts +55 -2
- package/dist/admin/lib/pagesClient.js +126 -28
- package/dist/admin/lib/pagesClient.js.map +1 -1
- package/dist/admin/lib/paginaGebruik.d.ts +56 -0
- package/dist/admin/lib/paginaGebruik.js +109 -0
- package/dist/admin/lib/paginaGebruik.js.map +1 -0
- package/dist/admin/lib/publicatieCheck.d.ts +25 -0
- package/dist/admin/lib/publicatieCheck.js +114 -0
- package/dist/admin/lib/publicatieCheck.js.map +1 -0
- package/dist/admin/lib/scrollNaarDetail.d.ts +6 -0
- package/dist/admin/lib/scrollNaarDetail.js +20 -0
- package/dist/admin/lib/scrollNaarDetail.js.map +1 -0
- package/dist/admin/lib/symbolsClient.d.ts +10 -0
- package/dist/admin/lib/symbolsClient.js +14 -1
- package/dist/admin/lib/symbolsClient.js.map +1 -1
- package/dist/admin/lib/tekstVeld.d.ts +8 -0
- package/dist/admin/lib/tekstVeld.js +10 -0
- package/dist/admin/lib/tekstVeld.js.map +1 -0
- package/dist/admin/lib/useIsSuperadmin.d.ts +2 -0
- package/dist/admin/lib/useIsSuperadmin.js +13 -0
- package/dist/admin/lib/useIsSuperadmin.js.map +1 -0
- package/dist/admin/lib/veldTaal.d.ts +14 -0
- package/dist/admin/lib/veldTaal.js +247 -0
- package/dist/admin/lib/veldTaal.js.map +1 -0
- package/dist/admin/lib/versieVergelijk.d.ts +17 -0
- package/dist/admin/lib/versieVergelijk.js +24 -0
- package/dist/admin/lib/versieVergelijk.js.map +1 -0
- package/dist/admin/lib/zodFields.js +22 -4
- package/dist/admin/lib/zodFields.js.map +1 -1
- package/dist/admin/lib/zodFout.d.ts +9 -0
- package/dist/admin/lib/zodFout.js +63 -0
- package/dist/admin/lib/zodFout.js.map +1 -0
- package/dist/admin/media/MediaManager.js +162 -32
- package/dist/admin/media/MediaManager.js.map +1 -1
- package/dist/admin/media/MediaPicker.d.ts +3 -0
- package/dist/admin/media/MediaPicker.js +84 -31
- package/dist/admin/media/MediaPicker.js.map +1 -1
- package/dist/admin/menu/MenuPanel.js +144 -83
- package/dist/admin/menu/MenuPanel.js.map +1 -1
- package/dist/admin/navContext.d.ts +3 -0
- package/dist/admin/navContext.js +13 -1
- package/dist/admin/navContext.js.map +1 -1
- package/dist/admin/pages/PageEditor.js +146 -30
- package/dist/admin/pages/PageEditor.js.map +1 -1
- package/dist/admin/pages/PagesPanel.js +215 -61
- package/dist/admin/pages/PagesPanel.js.map +1 -1
- package/dist/admin/pages/StarterKiezer.d.ts +12 -0
- package/dist/admin/pages/StarterKiezer.js +113 -0
- package/dist/admin/pages/StarterKiezer.js.map +1 -0
- package/dist/admin/panelRegistry.d.ts +1 -1
- package/dist/admin/panelRegistry.js +2 -1
- package/dist/admin/panelRegistry.js.map +1 -1
- package/dist/admin/patterns/PatternInserter.js +1 -1
- package/dist/admin/patterns/PatternInserter.js.map +1 -1
- package/dist/admin/settings/BedrijfInstellingen.d.ts +20 -0
- package/dist/admin/settings/BedrijfInstellingen.js +144 -0
- package/dist/admin/settings/BedrijfInstellingen.js.map +1 -0
- package/dist/admin/settings/MailSettings.js +2 -2
- package/dist/admin/settings/MailSettings.js.map +1 -1
- package/dist/admin/settings/MailTemplates.js +5 -4
- package/dist/admin/settings/MailTemplates.js.map +1 -1
- package/dist/admin/settings/SettingsPanel.js +120 -78
- package/dist/admin/settings/SettingsPanel.js.map +1 -1
- package/dist/admin/settings/SnapshotsCard.js +4 -4
- package/dist/admin/settings/SnapshotsCard.js.map +1 -1
- package/dist/admin/settings/VorigeTerugzetten.d.ts +15 -0
- package/dist/admin/settings/VorigeTerugzetten.js +89 -0
- package/dist/admin/settings/VorigeTerugzetten.js.map +1 -0
- package/dist/admin/shop/CategoriesTab.js +6 -4
- package/dist/admin/shop/CategoriesTab.js.map +1 -1
- package/dist/admin/shop/DiscountsTab.js +4 -2
- package/dist/admin/shop/DiscountsTab.js.map +1 -1
- package/dist/admin/shop/OrdersTab.js +57 -19
- package/dist/admin/shop/OrdersTab.js.map +1 -1
- package/dist/admin/shop/ProductPaneel.js +2 -1
- package/dist/admin/shop/ProductPaneel.js.map +1 -1
- package/dist/admin/shop/ProductsTab.js +40 -19
- package/dist/admin/shop/ProductsTab.js.map +1 -1
- package/dist/admin/shop/ShopPanel.js +13 -1
- package/dist/admin/shop/ShopPanel.js.map +1 -1
- package/dist/admin/shop/ShopSettingsTab.js +27 -1
- package/dist/admin/shop/ShopSettingsTab.js.map +1 -1
- package/dist/admin/shop/productClient.js +7 -3
- package/dist/admin/shop/productClient.js.map +1 -1
- package/dist/admin/stats/NietGevonden.d.ts +10 -0
- package/dist/admin/stats/NietGevonden.js +78 -0
- package/dist/admin/stats/NietGevonden.js.map +1 -0
- package/dist/admin/stats/StatsPanel.js +6 -1
- package/dist/admin/stats/StatsPanel.js.map +1 -1
- package/dist/admin/stats/lib.d.ts +2 -0
- package/dist/admin/stats/lib.js.map +1 -1
- package/dist/admin/ui/ConfirmDialog.js +10 -1
- package/dist/admin/ui/ConfirmDialog.js.map +1 -1
- package/dist/admin/ui/Icon.d.ts +34 -0
- package/dist/admin/ui/Icon.js +44 -0
- package/dist/admin/ui/Icon.js.map +1 -0
- package/dist/admin/ui/ImageField.d.ts +15 -0
- package/dist/admin/ui/ImageField.js +67 -0
- package/dist/admin/ui/ImageField.js.map +1 -0
- package/dist/admin/ui/KleurVeld.d.ts +25 -0
- package/dist/admin/ui/KleurVeld.js +76 -0
- package/dist/admin/ui/KleurVeld.js.map +1 -0
- package/dist/admin/ui/LaadStaat.d.ts +21 -0
- package/dist/admin/ui/LaadStaat.js +43 -0
- package/dist/admin/ui/LaadStaat.js.map +1 -0
- package/dist/admin/ui/LeesbaarheidPaneel.d.ts +10 -0
- package/dist/admin/ui/LeesbaarheidPaneel.js +68 -0
- package/dist/admin/ui/LeesbaarheidPaneel.js.map +1 -0
- package/dist/admin/ui/LinkDialog.d.ts +22 -0
- package/dist/admin/ui/LinkDialog.js +131 -0
- package/dist/admin/ui/LinkDialog.js.map +1 -0
- package/dist/admin/ui/LinkVeld.d.ts +14 -0
- package/dist/admin/ui/LinkVeld.js +49 -0
- package/dist/admin/ui/LinkVeld.js.map +1 -0
- package/dist/admin/ui/PreviewLinkResultaat.d.ts +14 -0
- package/dist/admin/ui/PreviewLinkResultaat.js +52 -0
- package/dist/admin/ui/PreviewLinkResultaat.js.map +1 -0
- package/dist/admin/ui/charts.js +5 -5
- package/dist/admin/ui/charts.js.map +1 -1
- package/dist/admin/ui/primitives.d.ts +16 -6
- package/dist/admin/ui/primitives.js +98 -26
- package/dist/admin/ui/primitives.js.map +1 -1
- package/dist/admin/ui/select.js +5 -2
- package/dist/admin/ui/select.js.map +1 -1
- package/dist/admin/ui/switch.d.ts +3 -1
- package/dist/admin/ui/switch.js +6 -3
- package/dist/admin/ui/switch.js.map +1 -1
- package/dist/admin/ui/toast.d.ts +2 -1
- package/dist/admin/ui/toast.js +17 -11
- package/dist/admin/ui/toast.js.map +1 -1
- package/dist/admin/visual/BlokKiezer.d.ts +34 -0
- package/dist/admin/visual/BlokKiezer.js +225 -0
- package/dist/admin/visual/BlokKiezer.js.map +1 -0
- package/dist/admin/visual/InlineGereedschap.d.ts +52 -0
- package/dist/admin/visual/InlineGereedschap.js +356 -0
- package/dist/admin/visual/InlineGereedschap.js.map +1 -0
- package/dist/admin/visual/InlineRijkeTekst.d.ts +23 -0
- package/dist/admin/visual/InlineRijkeTekst.js +152 -0
- package/dist/admin/visual/InlineRijkeTekst.js.map +1 -0
- package/dist/admin/visual/VisualEditor.js +273 -125
- package/dist/admin/visual/VisualEditor.js.map +1 -1
- package/dist/admin.css +1 -1
- package/dist/bedrijf/bedrijf.d.ts +36 -0
- package/dist/bedrijf/bedrijf.js +110 -0
- package/dist/bedrijf/bedrijf.js.map +1 -0
- package/dist/blocks/BlockRenderer.js +11 -1
- package/dist/blocks/BlockRenderer.js.map +1 -1
- package/dist/blocks/blockStyle.d.ts +7 -0
- package/dist/blocks/blockStyle.js +16 -3
- package/dist/blocks/blockStyle.js.map +1 -1
- package/dist/blocks/builtinSchemas.js +6 -0
- package/dist/blocks/builtinSchemas.js.map +1 -1
- package/dist/blocks/builtins/AgendaRender.d.ts +22 -0
- package/dist/blocks/builtins/AgendaRender.js +69 -9
- package/dist/blocks/builtins/AgendaRender.js.map +1 -1
- package/dist/blocks/builtins/Availability.d.ts +1 -0
- package/dist/blocks/builtins/Availability.js +23 -0
- package/dist/blocks/builtins/Availability.js.map +1 -0
- package/dist/blocks/builtins/AvailabilityRender.d.ts +12 -0
- package/dist/blocks/builtins/AvailabilityRender.js +105 -0
- package/dist/blocks/builtins/AvailabilityRender.js.map +1 -0
- package/dist/blocks/builtins/BeforeAfterRender.js +4 -3
- package/dist/blocks/builtins/BeforeAfterRender.js.map +1 -1
- package/dist/blocks/builtins/Booking.js +1 -1
- package/dist/blocks/builtins/Booking.js.map +1 -1
- package/dist/blocks/builtins/BreadcrumbsRender.d.ts +4 -3
- package/dist/blocks/builtins/BreadcrumbsRender.js +14 -8
- package/dist/blocks/builtins/BreadcrumbsRender.js.map +1 -1
- package/dist/blocks/builtins/ColumnsRender.d.ts +1 -1
- package/dist/blocks/builtins/ColumnsRender.js +3 -1
- package/dist/blocks/builtins/ColumnsRender.js.map +1 -1
- package/dist/blocks/builtins/Contact.js +1 -1
- package/dist/blocks/builtins/Contact.js.map +1 -1
- package/dist/blocks/builtins/ContactRender.d.ts +1 -1
- package/dist/blocks/builtins/ContactRender.js +29 -8
- package/dist/blocks/builtins/ContactRender.js.map +1 -1
- package/dist/blocks/builtins/Cta.js +1 -1
- package/dist/blocks/builtins/Cta.js.map +1 -1
- package/dist/blocks/builtins/CtaRender.d.ts +1 -1
- package/dist/blocks/builtins/CtaRender.js +5 -4
- package/dist/blocks/builtins/CtaRender.js.map +1 -1
- package/dist/blocks/builtins/Embed.js +1 -1
- package/dist/blocks/builtins/Embed.js.map +1 -1
- package/dist/blocks/builtins/FormBlock.js +1 -0
- package/dist/blocks/builtins/FormBlock.js.map +1 -1
- package/dist/blocks/builtins/FormBlockRender.d.ts +6 -0
- package/dist/blocks/builtins/FormBlockRender.js +88 -16
- package/dist/blocks/builtins/FormBlockRender.js.map +1 -1
- package/dist/blocks/builtins/GalleryRender.js +3 -2
- package/dist/blocks/builtins/GalleryRender.js.map +1 -1
- package/dist/blocks/builtins/Hero.js +1 -1
- package/dist/blocks/builtins/Hero.js.map +1 -1
- package/dist/blocks/builtins/HeroRender.js +7 -3
- package/dist/blocks/builtins/HeroRender.js.map +1 -1
- package/dist/blocks/builtins/OpenNowBadge.d.ts +4 -2
- package/dist/blocks/builtins/OpenNowBadge.js +6 -6
- package/dist/blocks/builtins/OpenNowBadge.js.map +1 -1
- package/dist/blocks/builtins/OpeningHoursRender.d.ts +8 -2
- package/dist/blocks/builtins/OpeningHoursRender.js +27 -6
- package/dist/blocks/builtins/OpeningHoursRender.js.map +1 -1
- package/dist/blocks/builtins/PriceList.d.ts +1 -0
- package/dist/blocks/builtins/PriceList.js +25 -0
- package/dist/blocks/builtins/PriceList.js.map +1 -0
- package/dist/blocks/builtins/PriceListRender.d.ts +17 -0
- package/dist/blocks/builtins/PriceListRender.js +87 -0
- package/dist/blocks/builtins/PriceListRender.js.map +1 -0
- package/dist/blocks/builtins/RichTextBlockRender.js +6 -1
- package/dist/blocks/builtins/RichTextBlockRender.js.map +1 -1
- package/dist/blocks/builtins/SectionHeading.d.ts +1 -0
- package/dist/blocks/builtins/SectionHeading.js +14 -0
- package/dist/blocks/builtins/SectionHeading.js.map +1 -0
- package/dist/blocks/builtins/SectionHeadingRender.d.ts +7 -0
- package/dist/blocks/builtins/SectionHeadingRender.js +14 -0
- package/dist/blocks/builtins/SectionHeadingRender.js.map +1 -0
- package/dist/blocks/builtins/SliderRender.js +3 -2
- package/dist/blocks/builtins/SliderRender.js.map +1 -1
- package/dist/blocks/builtins/SymbolRef.js +1 -1
- package/dist/blocks/builtins/SymbolRef.js.map +1 -1
- package/dist/blocks/builtins/TeamRender.js +6 -1
- package/dist/blocks/builtins/TeamRender.js.map +1 -1
- package/dist/blocks/builtins/Testimonials.js +3 -1
- package/dist/blocks/builtins/Testimonials.js.map +1 -1
- package/dist/blocks/builtins/TestimonialsRender.js +4 -0
- package/dist/blocks/builtins/TestimonialsRender.js.map +1 -1
- package/dist/blocks/builtins/WhatsappChatRender.d.ts +1 -1
- package/dist/blocks/builtins/WhatsappChatRender.js +1 -1
- package/dist/blocks/builtins/WhatsappChatRender.js.map +1 -1
- package/dist/blocks/builtins/Widgets.js +2 -2
- package/dist/blocks/builtins/Widgets.js.map +1 -1
- package/dist/blocks/builtins/WidgetsRender.js +3 -1
- package/dist/blocks/builtins/WidgetsRender.js.map +1 -1
- package/dist/blocks/builtins/index.d.ts +3 -0
- package/dist/blocks/builtins/index.js +6 -0
- package/dist/blocks/builtins/index.js.map +1 -1
- package/dist/blocks/builtins/lib/autoComplete.d.ts +7 -0
- package/dist/blocks/builtins/lib/autoComplete.js +20 -0
- package/dist/blocks/builtins/lib/autoComplete.js.map +1 -0
- package/dist/blocks/builtins/lib/bookingUrl.d.ts +2 -2
- package/dist/blocks/builtins/lib/bookingUrl.js +1 -1
- package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -1
- package/dist/blocks/builtins/lib/ical.d.ts +24 -0
- package/dist/blocks/builtins/lib/ical.js +82 -0
- package/dist/blocks/builtins/lib/ical.js.map +1 -0
- package/dist/blocks/builtins/lib/vandaag.d.ts +8 -0
- package/dist/blocks/builtins/lib/vandaag.js +22 -0
- package/dist/blocks/builtins/lib/vandaag.js.map +1 -0
- package/dist/blocks/registry.d.ts +6 -0
- package/dist/blocks/registry.js.map +1 -1
- package/dist/blocks/ui/index.js +1 -0
- package/dist/blocks/ui/index.js.map +1 -1
- package/dist/components/EditBar.js +2 -4
- package/dist/components/EditBar.js.map +1 -1
- package/dist/components/News.js +26 -18
- package/dist/components/News.js.map +1 -1
- package/dist/components/PageView.d.ts +7 -1
- package/dist/components/PageView.js +17 -0
- package/dist/components/PageView.js.map +1 -1
- package/dist/components/ResponsiveImage.js +18 -20
- package/dist/components/ResponsiveImage.js.map +1 -1
- package/dist/components/site/SiteFooter.d.ts +6 -1
- package/dist/components/site/SiteFooter.js +61 -9
- package/dist/components/site/SiteFooter.js.map +1 -1
- package/dist/components/site/SiteHeader.d.ts +15 -0
- package/dist/components/site/SiteHeader.js +70 -0
- package/dist/components/site/SiteHeader.js.map +1 -0
- package/dist/components/site/SiteNav.d.ts +2 -0
- package/dist/components/site/SiteNav.js +29 -5
- package/dist/components/site/SiteNav.js.map +1 -1
- package/dist/demo/DemoStudio.js +2 -2
- package/dist/demo/DemoStudio.js.map +1 -1
- package/dist/demo/demoStore.d.ts +13 -0
- package/dist/demo/demoStore.js +36 -0
- package/dist/demo/demoStore.js.map +1 -1
- package/dist/editor/EditorProvider.js +15 -4
- package/dist/editor/EditorProvider.js.map +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +16 -1
- package/dist/index.js.map +1 -1
- package/dist/media/ImageContext.d.ts +17 -0
- package/dist/media/ImageContext.js +65 -20
- package/dist/media/ImageContext.js.map +1 -1
- package/dist/media/altInHtml.d.ts +9 -0
- package/dist/media/altInHtml.js +17 -0
- package/dist/media/altInHtml.js.map +1 -0
- package/dist/media/srcset.d.ts +12 -0
- package/dist/media/srcset.js +13 -0
- package/dist/media/srcset.js.map +1 -0
- package/dist/modules/builtins.d.ts +1 -0
- package/dist/modules/builtins.js +16 -3
- package/dist/modules/builtins.js.map +1 -1
- package/dist/modules/shop/blocks/Cart.js +5 -3
- package/dist/modules/shop/blocks/Cart.js.map +1 -1
- package/dist/modules/shop/blocks/Checkout.js +56 -35
- package/dist/modules/shop/blocks/Checkout.js.map +1 -1
- package/dist/modules/shop/blocks/Donation.js +4 -4
- package/dist/modules/shop/blocks/Donation.js.map +1 -1
- package/dist/modules/shop/blocks/ProductDetail.js +19 -3
- package/dist/modules/shop/blocks/ProductDetail.js.map +1 -1
- package/dist/modules/shop/blocks/ProductGrid.d.ts +3 -1
- package/dist/modules/shop/blocks/ProductGrid.js +8 -4
- package/dist/modules/shop/blocks/ProductGrid.js.map +1 -1
- package/dist/modules/shop/blocks/ShopCategories.js +4 -3
- package/dist/modules/shop/blocks/ShopCategories.js.map +1 -1
- package/dist/modules/shop/lib.d.ts +4 -0
- package/dist/modules/shop/lib.js +14 -0
- package/dist/modules/shop/lib.js.map +1 -1
- package/dist/modules/shop/settings.d.ts +3 -0
- package/dist/modules/shop/settings.js +14 -0
- package/dist/modules/shop/settings.js.map +1 -1
- package/dist/modules/shop/strings.d.ts +4 -0
- package/dist/modules/shop/strings.js +8 -0
- package/dist/modules/shop/strings.js.map +1 -1
- package/dist/next/envCheck.d.ts +42 -0
- package/dist/next/envCheck.js +106 -0
- package/dist/next/envCheck.js.map +1 -0
- package/dist/next/index.cjs +185 -2
- package/dist/next/index.d.ts +2 -0
- package/dist/next/index.js +8 -1
- package/dist/next/index.js.map +1 -1
- package/dist/next/securityHeaders.d.ts +36 -0
- package/dist/next/securityHeaders.js +74 -0
- package/dist/next/securityHeaders.js.map +1 -0
- package/dist/patterns/builtins.d.ts +7 -0
- package/dist/patterns/builtins.js +138 -3
- package/dist/patterns/builtins.js.map +1 -1
- package/dist/releaseNotes.js +140 -0
- package/dist/releaseNotes.js.map +1 -1
- package/dist/render/PublishedPage.d.ts +2 -1
- package/dist/render/PublishedPage.js +10 -4
- package/dist/render/PublishedPage.js.map +1 -1
- package/dist/schema/blocks.d.ts +470 -0
- package/dist/schema/blocks.js +102 -4
- package/dist/schema/blocks.js.map +1 -1
- package/dist/schema/business.d.ts +117 -0
- package/dist/schema/business.js +73 -0
- package/dist/schema/business.js.map +1 -0
- package/dist/schema/fields.d.ts +2 -1
- package/dist/schema/fields.js.map +1 -1
- package/dist/schema/forms.d.ts +18 -0
- package/dist/schema/forms.js +18 -3
- package/dist/schema/forms.js.map +1 -1
- package/dist/schema/mail.d.ts +10 -0
- package/dist/schema/mail.js +7 -0
- package/dist/schema/mail.js.map +1 -1
- package/dist/schema/settings.d.ts +101 -0
- package/dist/schema/settings.js +24 -3
- package/dist/schema/settings.js.map +1 -1
- package/dist/schema/shop.d.ts +2 -0
- package/dist/schema/shop.js +4 -0
- package/dist/schema/shop.js.map +1 -1
- package/dist/schema/shopGeld.d.ts +1 -0
- package/dist/schema/shopGeld.js +1 -0
- package/dist/schema/shopGeld.js.map +1 -1
- package/dist/schema/siteConfig.d.ts +68 -1
- package/dist/schema/siteConfig.js +7 -2
- package/dist/schema/siteConfig.js.map +1 -1
- package/dist/server/blockData.d.ts +1 -1
- package/dist/server/blockData.js +74 -18
- package/dist/server/blockData.js.map +1 -1
- package/dist/server/cspRapport.d.ts +20 -0
- package/dist/server/cspRapport.js +56 -0
- package/dist/server/cspRapport.js.map +1 -0
- package/dist/server/fonts.d.ts +3 -0
- package/dist/server/fonts.js +39 -0
- package/dist/server/fonts.js.map +1 -0
- package/dist/server/index.d.ts +3 -0
- package/dist/server/index.js +8 -0
- package/dist/server/index.js.map +1 -1
- package/dist/server/sanitize.js +15 -2
- package/dist/server/sanitize.js.map +1 -1
- package/dist/settings/useSiteSettings.js +4 -1
- package/dist/settings/useSiteSettings.js.map +1 -1
- package/dist/starters/starters.d.ts +69 -0
- package/dist/starters/starters.js +171 -0
- package/dist/starters/starters.js.map +1 -0
- package/dist/styles.css +1149 -208
- package/dist/theme/color.d.ts +10 -0
- package/dist/theme/color.js +17 -1
- package/dist/theme/color.js.map +1 -1
- package/dist/theme/fontFallback.d.ts +23 -0
- package/dist/theme/fontFallback.js +58 -0
- package/dist/theme/fontFallback.js.map +1 -0
- package/dist/theme/fonts.d.ts +11 -0
- package/dist/theme/fonts.js +16 -0
- package/dist/theme/fonts.js.map +1 -0
- package/dist/version.js +1 -1
- package/package.json +6 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/PageView.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useSiteConfig } from \"../config\";\n\n/**\n * Registreert één pageview voor de huidige site/pad — max. één keer per browsersessie per pad\n * (sessionStorage). Privacy-vriendelijk en goedkoop. No-op zonder Firebase. Plaats dit in de\n * publieke layout van een klantsite (binnen <XiCMSProvider>).\n */\nexport function PageView({ path }: { path: string }) {\n const { siteId } = useSiteConfig();\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n const key = `xicms_view:${siteId}:${path}`;\n try {\n if (sessionStorage.getItem(key)) return;\n sessionStorage.setItem(key, \"1\");\n } catch {\n /* private mode e.d. — ga gewoon door */\n }\n // Firebase pas laden wanneer er écht getracked wordt: statisch importeren zette de hele SDK\n // in de bundel van elke publieke pagina, voor één fire-and-forget-call.\n void (async () => {\n const [{ getFirebaseApp }, { callable }] = await Promise.all([\n import(\"../firebase/client\"),\n import(\"../firebase/functionsClient\"),\n ]);\n const app = getFirebaseApp();\n if (!app) return;\n // 7.24: alleen de HOST van de verwijzer (nooit pad/query — daar kan een zoekterm of\n // sessie-id in staan) en een grove apparaatklasse. Beide zonder cookies of fingerprint.\n let ref: string | undefined;\n try {\n ref = document.referrer ? new URL(document.referrer).hostname : undefined;\n } catch {\n ref = undefined;\n }\n const w = window.innerWidth;\n const device = w < 720 ? \"mobiel\" : w < 1100 ? \"tablet\" : \"desktop\";\n await callable(app, \"trackView\")({ siteId, path, ...(ref ? { ref } : {}), device });\n })().catch(() => {\n /* stats mogen nooit de site breken */\n });\n }, [siteId, path]);\n\n return null;\n}\n\n/**\n * Telt een gebeurtenis (7.24): \"formulier\" verstuurd, \"uitgaand\" geklikt, enz. Zelfde teller,\n * zelfde privacy-regels; fire-and-forget en nooit een fout naar de bezoeker.\n */\nexport function trackEvent(siteId: string, event: \"formulier\" | \"bestelling\" | \"uitgaand\" | \"telefoon\" | \"mail\" | \"whatsapp\", path?: string): void {\n if (typeof window === \"undefined\") return;\n void (async () => {\n const [{ getFirebaseApp }, { callable }] = await Promise.all([\n import(\"../firebase/client\"),\n import(\"../firebase/functionsClient\"),\n ]);\n const app = getFirebaseApp();\n if (!app) return;\n await callable(app, \"trackView\")({ siteId, path: path ?? window.location.pathname ?? \"/\", event });\n })().catch(() => {\n /* stats mogen nooit de site breken */\n });\n}\n"],"mappings":";AAEA,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB;AAOvB,SAAS,SAAS,EAAE,KAAK,GAAqB;AACnD,QAAM,EAAE,OAAO,IAAI,cAAc;AAEjC,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;
|
|
1
|
+
{"version":3,"sources":["../../src/components/PageView.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect } from \"react\";\nimport { useSiteConfig } from \"../config\";\n\n/**\n * Registreert één pageview voor de huidige site/pad — max. één keer per browsersessie per pad\n * (sessionStorage). Privacy-vriendelijk en goedkoop. No-op zonder Firebase. Plaats dit in de\n * publieke layout van een klantsite (binnen <XiCMSProvider>).\n */\nexport function PageView({ path }: { path: string }) {\n const { siteId } = useSiteConfig();\n\n useEffect(() => {\n if (typeof window === \"undefined\") return;\n // 8.3: geautomatiseerde browsers (Lighthouse, testtools) tellen niet als bezoek; de server\n // filtert daarnaast op user-agent.\n if (navigator.webdriver) return;\n const key = `xicms_view:${siteId}:${path}`;\n try {\n if (sessionStorage.getItem(key)) return;\n sessionStorage.setItem(key, \"1\");\n } catch {\n /* private mode e.d. — ga gewoon door */\n }\n // Firebase pas laden wanneer er écht getracked wordt: statisch importeren zette de hele SDK\n // in de bundel van elke publieke pagina, voor één fire-and-forget-call.\n void (async () => {\n const [{ getFirebaseApp }, { callable }] = await Promise.all([\n import(\"../firebase/client\"),\n import(\"../firebase/functionsClient\"),\n ]);\n const app = getFirebaseApp();\n if (!app) return;\n // 7.24: alleen de HOST van de verwijzer (nooit pad/query — daar kan een zoekterm of\n // sessie-id in staan) en een grove apparaatklasse. Beide zonder cookies of fingerprint.\n let ref: string | undefined;\n try {\n ref = document.referrer ? new URL(document.referrer).hostname : undefined;\n } catch {\n ref = undefined;\n }\n const w = window.innerWidth;\n const device = w < 720 ? \"mobiel\" : w < 1100 ? \"tablet\" : \"desktop\";\n await callable(app, \"trackView\")({ siteId, path, ...(ref ? { ref } : {}), device });\n })().catch(() => {\n /* stats mogen nooit de site breken */\n });\n }, [siteId, path]);\n\n return null;\n}\n\n/**\n * Telt een gebeurtenis (7.24): \"formulier\" verstuurd, \"uitgaand\" geklikt, enz. Zelfde teller,\n * zelfde privacy-regels; fire-and-forget en nooit een fout naar de bezoeker.\n */\nexport function trackEvent(siteId: string, event: \"formulier\" | \"bestelling\" | \"uitgaand\" | \"telefoon\" | \"mail\" | \"whatsapp\" | \"niet-gevonden\", path?: string): void {\n if (typeof window === \"undefined\") return;\n void (async () => {\n const [{ getFirebaseApp }, { callable }] = await Promise.all([\n import(\"../firebase/client\"),\n import(\"../firebase/functionsClient\"),\n ]);\n const app = getFirebaseApp();\n if (!app) return;\n await callable(app, \"trackView\")({ siteId, path: path ?? window.location.pathname ?? \"/\", event });\n })().catch(() => {\n /* stats mogen nooit de site breken */\n });\n}\n\n/**\n * 404-monitor (8.4): zet dit op de niet-gevonden-pagina van de site. Meldt het pad één keer per\n * sessie; in /beheer → Statistieken verschijnen de vaakst gemiste adressen met een knop om er een\n * doorverwijzing van te maken. Geen cookies, alleen het pad.\n */\nexport function NietGevondenMelder() {\n const { siteId } = useSiteConfig();\n useEffect(() => {\n if (typeof window === \"undefined\" || navigator.webdriver) return;\n const pad = window.location.pathname;\n const key = `xicms_404:${siteId}:${pad}`;\n try {\n if (sessionStorage.getItem(key)) return;\n sessionStorage.setItem(key, \"1\");\n } catch {\n /* private mode — gewoon melden */\n }\n trackEvent(siteId, \"niet-gevonden\", pad);\n }, [siteId]);\n return null;\n}\n"],"mappings":";AAEA,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB;AAOvB,SAAS,SAAS,EAAE,KAAK,GAAqB;AACnD,QAAM,EAAE,OAAO,IAAI,cAAc;AAEjC,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,YAAa;AAGnC,QAAI,UAAU,UAAW;AACzB,UAAM,MAAM,cAAc,MAAM,IAAI,IAAI;AACxC,QAAI;AACF,UAAI,eAAe,QAAQ,GAAG,EAAG;AACjC,qBAAe,QAAQ,KAAK,GAAG;AAAA,IACjC,QAAQ;AAAA,IAER;AAGA,UAAM,YAAY;AAChB,YAAM,CAAC,EAAE,eAAe,GAAG,EAAE,SAAS,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,QAC3D,OAAO,oBAAoB;AAAA,QAC3B,OAAO,6BAA6B;AAAA,MACtC,CAAC;AACD,YAAM,MAAM,eAAe;AAC3B,UAAI,CAAC,IAAK;AAGV,UAAI;AACJ,UAAI;AACF,cAAM,SAAS,WAAW,IAAI,IAAI,SAAS,QAAQ,EAAE,WAAW;AAAA,MAClE,QAAQ;AACN,cAAM;AAAA,MACR;AACA,YAAM,IAAI,OAAO;AACjB,YAAM,SAAS,IAAI,MAAM,WAAW,IAAI,OAAO,WAAW;AAC1D,YAAM,SAAS,KAAK,WAAW,EAAE,EAAE,QAAQ,MAAM,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC,GAAI,OAAO,CAAC;AAAA,IACpF,GAAG,EAAE,MAAM,MAAM;AAAA,IAEjB,CAAC;AAAA,EACH,GAAG,CAAC,QAAQ,IAAI,CAAC;AAEjB,SAAO;AACT;AAMO,SAAS,WAAW,QAAgB,OAAqG,MAAqB;AACnK,MAAI,OAAO,WAAW,YAAa;AACnC,QAAM,YAAY;AAChB,UAAM,CAAC,EAAE,eAAe,GAAG,EAAE,SAAS,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,MAC3D,OAAO,oBAAoB;AAAA,MAC3B,OAAO,6BAA6B;AAAA,IACtC,CAAC;AACD,UAAM,MAAM,eAAe;AAC3B,QAAI,CAAC,IAAK;AACV,UAAM,SAAS,KAAK,WAAW,EAAE,EAAE,QAAQ,MAAM,QAAQ,OAAO,SAAS,YAAY,KAAK,MAAM,CAAC;AAAA,EACnG,GAAG,EAAE,MAAM,MAAM;AAAA,EAEjB,CAAC;AACH;AAOO,SAAS,qBAAqB;AACnC,QAAM,EAAE,OAAO,IAAI,cAAc;AACjC,YAAU,MAAM;AACd,QAAI,OAAO,WAAW,eAAe,UAAU,UAAW;AAC1D,UAAM,MAAM,OAAO,SAAS;AAC5B,UAAM,MAAM,aAAa,MAAM,IAAI,GAAG;AACtC,QAAI;AACF,UAAI,eAAe,QAAQ,GAAG,EAAG;AACjC,qBAAe,QAAQ,KAAK,GAAG;AAAA,IACjC,QAAQ;AAAA,IAER;AACA,eAAW,QAAQ,iBAAiB,GAAG;AAAA,EACzC,GAAG,CAAC,MAAM,CAAC;AACX,SAAO;AACT;","names":[]}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { jsx
|
|
1
|
+
import { jsx } from "react/jsx-runtime";
|
|
2
|
+
import { bronSet } from "../media/srcset.js";
|
|
2
3
|
function ResponsiveImage({
|
|
3
4
|
media,
|
|
4
5
|
url,
|
|
@@ -15,25 +16,22 @@ function ResponsiveImage({
|
|
|
15
16
|
const webp = media?.variants?.webp;
|
|
16
17
|
const focal = media?.focal;
|
|
17
18
|
const stijl = focal && !(style && style.objectPosition) ? { ...style, objectPosition: `${Math.round(focal.x * 100)}% ${Math.round(focal.y * 100)}%` } : style;
|
|
18
|
-
const srcSet = ladder.length ? ladder
|
|
19
|
-
return /* @__PURE__ */
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
)
|
|
36
|
-
] });
|
|
19
|
+
const srcSet = ladder.length ? bronSet(ladder, webp) : void 0;
|
|
20
|
+
return /* @__PURE__ */ jsx("picture", { children: /* @__PURE__ */ jsx(
|
|
21
|
+
"img",
|
|
22
|
+
{
|
|
23
|
+
src,
|
|
24
|
+
srcSet,
|
|
25
|
+
sizes: srcSet ? sizes : void 0,
|
|
26
|
+
alt: altText,
|
|
27
|
+
width: media?.width,
|
|
28
|
+
height: media?.height,
|
|
29
|
+
loading: priority ? "eager" : "lazy",
|
|
30
|
+
fetchPriority: priority ? "high" : void 0,
|
|
31
|
+
className,
|
|
32
|
+
style: stijl
|
|
33
|
+
}
|
|
34
|
+
) });
|
|
37
35
|
}
|
|
38
36
|
export {
|
|
39
37
|
ResponsiveImage
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/ResponsiveImage.tsx"],"sourcesContent":["import type { CSSProperties } from \"react\";\nimport type { MediaItem } from \"../content/types\";\n\n/**\n * Rendert een afbeelding met srcset/webp uit de door de pipeline gegenereerde varianten.\n * Server-safe. Valt terug op de originele `url` als er nog geen varianten zijn.\n */\nexport function ResponsiveImage({\n media,\n url,\n alt,\n className,\n style,\n sizes = \"100vw\",\n priority = false,\n}: {\n media?: Pick<MediaItem, \"url\" | \"alt\" | \"width\" | \"height\" | \"variants\" | \"focal\">;\n url?: string;\n alt?: string;\n className?: string;\n style?: CSSProperties;\n sizes?: string;\n /** Zet dit op een above-the-fold beeld (bv. hero): eager laden + hoge fetch-prioriteit voor LCP. */\n priority?: boolean;\n}) {\n const src = media?.url ?? url;\n if (!src) return null;\n const altText = alt ?? media?.alt ?? \"\";\n const ladder = media?.variants?.sizes ?? [];\n const webp = media?.variants?.webp;\n // Focuspunt (7.24): bijsnijden rond het gekozen punt i.p.v. het midden (zie MediaItem.focal).\n const focal = media?.focal;\n const stijl = focal && !(style && style.objectPosition)\n ? { ...style, objectPosition: `${Math.round(focal.x * 100)}% ${Math.round(focal.y * 100)}%` }\n : style;\n\n
|
|
1
|
+
{"version":3,"sources":["../../src/components/ResponsiveImage.tsx"],"sourcesContent":["import { bronSet } from \"../media/srcset\";\nimport type { CSSProperties } from \"react\";\nimport type { MediaItem } from \"../content/types\";\n\n/**\n * Rendert een afbeelding met srcset/webp uit de door de pipeline gegenereerde varianten.\n * Server-safe. Valt terug op de originele `url` als er nog geen varianten zijn.\n */\nexport function ResponsiveImage({\n media,\n url,\n alt,\n className,\n style,\n sizes = \"100vw\",\n priority = false,\n}: {\n media?: Pick<MediaItem, \"url\" | \"alt\" | \"width\" | \"height\" | \"variants\" | \"focal\">;\n url?: string;\n alt?: string;\n className?: string;\n style?: CSSProperties;\n sizes?: string;\n /** Zet dit op een above-the-fold beeld (bv. hero): eager laden + hoge fetch-prioriteit voor LCP. */\n priority?: boolean;\n}) {\n const src = media?.url ?? url;\n if (!src) return null;\n const altText = alt ?? media?.alt ?? \"\";\n const ladder = media?.variants?.sizes ?? [];\n const webp = media?.variants?.webp;\n // Focuspunt (7.24): bijsnijden rond het gekozen punt i.p.v. het midden (zie MediaItem.focal).\n const focal = media?.focal;\n const stijl = focal && !(style && style.objectPosition)\n ? { ...style, objectPosition: `${Math.round(focal.x * 100)}% ${Math.round(focal.y * 100)}%` }\n : style;\n\n // Eén srcset met ladder + volle WebP (8.3; de losse <source> overstemde de ladder altijd).\n const srcSet = ladder.length ? bronSet(ladder, webp) : undefined;\n\n return (\n <picture>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img\n src={src}\n srcSet={srcSet}\n sizes={srcSet ? sizes : undefined}\n alt={altText}\n width={media?.width}\n height={media?.height}\n loading={priority ? \"eager\" : \"lazy\"}\n fetchPriority={priority ? \"high\" : undefined}\n className={className}\n style={stijl}\n />\n </picture>\n );\n}\n"],"mappings":"AA2CM;AA3CN,SAAS,eAAe;AAQjB,SAAS,gBAAgB;AAAA,EAC9B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ;AAAA,EACR,WAAW;AACb,GASG;AACD,QAAM,MAAM,OAAO,OAAO;AAC1B,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,UAAU,OAAO,OAAO,OAAO;AACrC,QAAM,SAAS,OAAO,UAAU,SAAS,CAAC;AAC1C,QAAM,OAAO,OAAO,UAAU;AAE9B,QAAM,QAAQ,OAAO;AACrB,QAAM,QAAQ,SAAS,EAAE,SAAS,MAAM,kBACpC,EAAE,GAAG,OAAO,gBAAgB,GAAG,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,KAAK,KAAK,MAAM,MAAM,IAAI,GAAG,CAAC,IAAI,IAC1F;AAGJ,QAAM,SAAS,OAAO,SAAS,QAAQ,QAAQ,IAAI,IAAI;AAEvD,SACE,oBAAC,aAEC;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA,OAAO,SAAS,QAAQ;AAAA,MACxB,KAAK;AAAA,MACL,OAAO,OAAO;AAAA,MACd,QAAQ,OAAO;AAAA,MACf,SAAS,WAAW,UAAU;AAAA,MAC9B,eAAe,WAAW,SAAS;AAAA,MACnC;AAAA,MACA,OAAO;AAAA;AAAA,EACT,GACF;AAEJ;","names":[]}
|
|
@@ -5,8 +5,13 @@ import type { FooterSettings } from "../../schema/settings.js";
|
|
|
5
5
|
* `xicms-footer*`-classNames + thema-CSS-variabelen, zodat een site hem volledig kan herstijlen
|
|
6
6
|
* (of vervangen door een eigen footer). De inhoud komt live uit `settings/public.footer`.
|
|
7
7
|
*/
|
|
8
|
-
export declare function SiteFooter({ className, renderColumn, }: {
|
|
8
|
+
export declare function SiteFooter({ className, renderColumn, bedrijf, }: {
|
|
9
9
|
className?: string;
|
|
10
|
+
/**
|
|
11
|
+
* 8.13: een eerste kolom met adres, telefoon, e-mail en openingstijden uit het bedrijfsprofiel
|
|
12
|
+
* (Instellingen → Bedrijf). Uit voor bestaande sites; de template zet hem aan.
|
|
13
|
+
*/
|
|
14
|
+
bedrijf?: boolean;
|
|
10
15
|
/** Override de opmaak van één kolom zonder de logica te forken. */
|
|
11
16
|
renderColumn?: (column: NonNullable<FooterSettings["columns"]>[number], index: number) => ReactNode;
|
|
12
17
|
}): import("react").JSX.Element;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useSiteSettings } from "../../settings/useSiteSettings.js";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useMergedSiteConfig, useSiteSettings } from "../../settings/useSiteSettings.js";
|
|
4
|
+
import { adresRegels, heeftProfiel, telLink } from "../../bedrijf/bedrijf.js";
|
|
4
5
|
import { useSiteConfig } from "../../config.js";
|
|
5
6
|
function SiteFooter({
|
|
6
7
|
className,
|
|
7
|
-
renderColumn
|
|
8
|
+
renderColumn,
|
|
9
|
+
bedrijf = false
|
|
8
10
|
}) {
|
|
9
11
|
const { settings } = useSiteSettings();
|
|
10
12
|
const config = useSiteConfig();
|
|
@@ -14,17 +16,67 @@ function SiteFooter({
|
|
|
14
16
|
const social = footer.social ?? [];
|
|
15
17
|
const showAdminLink = footer.showAdminLink !== false;
|
|
16
18
|
const year = (/* @__PURE__ */ new Date()).getFullYear();
|
|
19
|
+
const profiel = useMergedSiteConfig().business;
|
|
20
|
+
const toonProfiel = bedrijf && heeftProfiel(profiel);
|
|
17
21
|
return /* @__PURE__ */ jsxs("footer", { className: className ?? "xicms-footer", children: [
|
|
18
|
-
columns.length > 0 && /* @__PURE__ */
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
/* @__PURE__ */
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
(columns.length > 0 || toonProfiel) && /* @__PURE__ */ jsxs("div", { className: "xicms-footer__columns", children: [
|
|
23
|
+
toonProfiel && profiel && /* @__PURE__ */ jsxs("div", { className: "xicms-footer__column xicms-footer__column--bedrijf", children: [
|
|
24
|
+
/* @__PURE__ */ jsx("h3", { className: "xicms-footer__heading", children: "Contact" }),
|
|
25
|
+
/* @__PURE__ */ jsxs("ul", { className: "xicms-footer__links", children: [
|
|
26
|
+
adresRegels(profiel).map((r) => /* @__PURE__ */ jsx("li", { children: r }, r)),
|
|
27
|
+
profiel.phone && /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: telLink(profiel.phone), children: profiel.phone }) }),
|
|
28
|
+
profiel.email && /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: `mailto:${profiel.email}`, children: profiel.email }) })
|
|
29
|
+
] }),
|
|
30
|
+
(profiel.hours?.length ?? 0) > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
31
|
+
/* @__PURE__ */ jsx("h3", { className: "xicms-footer__heading", children: "Openingstijden" }),
|
|
32
|
+
/* @__PURE__ */ jsx("ul", { className: "xicms-footer__links", children: profiel.hours.map((r, i) => /* @__PURE__ */ jsxs("li", { children: [
|
|
33
|
+
r.day,
|
|
34
|
+
" \u2014 ",
|
|
35
|
+
r.hours
|
|
36
|
+
] }, i)) })
|
|
37
|
+
] })
|
|
38
|
+
] }),
|
|
39
|
+
columns.map(
|
|
40
|
+
(col, i) => renderColumn ? /* @__PURE__ */ jsx("div", { children: renderColumn(col, i) }, i) : /* @__PURE__ */ jsxs("div", { className: "xicms-footer__column", children: [
|
|
41
|
+
col.heading && /* @__PURE__ */ jsx("h3", { className: "xicms-footer__heading", children: col.heading }),
|
|
42
|
+
/* @__PURE__ */ jsx("ul", { className: "xicms-footer__links", children: (col.links ?? []).map((l, j) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: l.href, children: l.label }) }, j)) })
|
|
43
|
+
] }, i)
|
|
44
|
+
)
|
|
45
|
+
] }),
|
|
24
46
|
social.length > 0 && /* @__PURE__ */ jsx("ul", { className: "xicms-footer__social", children: social.map((s, i) => /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsx("a", { href: s.href, "aria-label": s.platform, rel: "noopener noreferrer", target: "_blank", children: s.platform }) }, i)) }),
|
|
25
47
|
/* @__PURE__ */ jsxs("div", { className: "xicms-footer__bottom", children: [
|
|
26
48
|
/* @__PURE__ */ jsx("span", { children: footer.copyright ?? `\xA9 ${year} ${name}` }),
|
|
27
49
|
showAdminLink && /* @__PURE__ */ jsx("a", { href: "/beheer", children: "Beheer" })
|
|
50
|
+
] }),
|
|
51
|
+
/* @__PURE__ */ jsxs("div", { className: "xicms-footer__credit", children: [
|
|
52
|
+
/* @__PURE__ */ jsxs(
|
|
53
|
+
"a",
|
|
54
|
+
{
|
|
55
|
+
className: "xicms-footer__credit-merk",
|
|
56
|
+
href: "https://www.xiwebdesign.nl",
|
|
57
|
+
rel: "noopener noreferrer",
|
|
58
|
+
target: "_blank",
|
|
59
|
+
children: [
|
|
60
|
+
/* @__PURE__ */ jsxs("svg", { viewBox: "0 0 64 64", "aria-hidden": "true", fill: "currentColor", children: [
|
|
61
|
+
/* @__PURE__ */ jsx("rect", { x: "6", y: "10", width: "52", height: "11", rx: "3" }),
|
|
62
|
+
/* @__PURE__ */ jsx("rect", { x: "16", y: "27", width: "32", height: "11", rx: "3", opacity: "0.7" }),
|
|
63
|
+
/* @__PURE__ */ jsx("rect", { x: "6", y: "44", width: "52", height: "11", rx: "3" })
|
|
64
|
+
] }),
|
|
65
|
+
"Website gemaakt door Xi Webdesign"
|
|
66
|
+
]
|
|
67
|
+
}
|
|
68
|
+
),
|
|
69
|
+
/* @__PURE__ */ jsx("span", { "aria-hidden": true, children: "\xB7" }),
|
|
70
|
+
/* @__PURE__ */ jsx(
|
|
71
|
+
"a",
|
|
72
|
+
{
|
|
73
|
+
className: "xicms-footer__credit-cta",
|
|
74
|
+
href: "https://www.xiwebdesign.nl/#contact",
|
|
75
|
+
rel: "noopener noreferrer",
|
|
76
|
+
target: "_blank",
|
|
77
|
+
children: "Ook zo'n mooie website? Neem contact op \u2192"
|
|
78
|
+
}
|
|
79
|
+
)
|
|
28
80
|
] })
|
|
29
81
|
] });
|
|
30
82
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/site/SiteFooter.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { useSiteSettings } from \"../../settings/useSiteSettings\";\nimport { useSiteConfig } from \"../../config\";\nimport type { FooterSettings } from \"../../schema/settings\";\n\n/**\n * Door de klant in /beheer bewerkbare footer. Unstyled-by-default: alle opmaak hangt aan\n * `xicms-footer*`-classNames + thema-CSS-variabelen, zodat een site hem volledig kan herstijlen\n * (of vervangen door een eigen footer). De inhoud komt live uit `settings/public.footer`.\n */\nexport function SiteFooter({\n className,\n renderColumn,\n}: {\n className?: string;\n /** Override de opmaak van één kolom zonder de logica te forken. */\n renderColumn?: (column: NonNullable<FooterSettings[\"columns\"]>[number], index: number) => ReactNode;\n}) {\n const { settings } = useSiteSettings();\n const config = useSiteConfig();\n const footer = settings.footer ?? {};\n const name = settings.name ?? config.name;\n const columns = footer.columns ?? [];\n const social = footer.social ?? [];\n const showAdminLink = footer.showAdminLink !== false;\n const year = new Date().getFullYear();\n\n return (\n <footer className={className ?? \"xicms-footer\"}>\n {columns.length > 0 && (\n <div className=\"xicms-footer__columns\">\n {columns.map((col, i) =>\n renderColumn ? (\n <div key={i}>{renderColumn(col, i)}</div>\n ) : (\n <div key={i} className=\"xicms-footer__column\">\n {col.heading && <h3 className=\"xicms-footer__heading\">{col.heading}</h3>}\n <ul className=\"xicms-footer__links\">\n {(col.links ?? []).map((l, j) => (\n <li key={j}>\n <a href={l.href}>{l.label}</a>\n </li>\n ))}\n </ul>\n </div>\n ),\n )}\n </div>\n )}\n\n {social.length > 0 && (\n <ul className=\"xicms-footer__social\">\n {social.map((s, i) => (\n <li key={i}>\n <a href={s.href} aria-label={s.platform} rel=\"noopener noreferrer\" target=\"_blank\">\n {s.platform}\n </a>\n </li>\n ))}\n </ul>\n )}\n\n <div className=\"xicms-footer__bottom\">\n <span>{footer.copyright ?? `© ${year} ${name}`}</span>\n {showAdminLink && <a href=\"/beheer\">Beheer</a>}\n </div>\n </footer>\n );\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../../src/components/site/SiteFooter.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { useMergedSiteConfig, useSiteSettings } from \"../../settings/useSiteSettings\";\nimport { adresRegels, heeftProfiel, telLink } from \"../../bedrijf/bedrijf\";\nimport { useSiteConfig } from \"../../config\";\nimport type { FooterSettings } from \"../../schema/settings\";\n\n/**\n * Door de klant in /beheer bewerkbare footer. Unstyled-by-default: alle opmaak hangt aan\n * `xicms-footer*`-classNames + thema-CSS-variabelen, zodat een site hem volledig kan herstijlen\n * (of vervangen door een eigen footer). De inhoud komt live uit `settings/public.footer`.\n */\nexport function SiteFooter({\n className,\n renderColumn,\n bedrijf = false,\n}: {\n className?: string;\n /**\n * 8.13: een eerste kolom met adres, telefoon, e-mail en openingstijden uit het bedrijfsprofiel\n * (Instellingen → Bedrijf). Uit voor bestaande sites; de template zet hem aan.\n */\n bedrijf?: boolean;\n /** Override de opmaak van één kolom zonder de logica te forken. */\n renderColumn?: (column: NonNullable<FooterSettings[\"columns\"]>[number], index: number) => ReactNode;\n}) {\n const { settings } = useSiteSettings();\n const config = useSiteConfig();\n const footer = settings.footer ?? {};\n const name = settings.name ?? config.name;\n const columns = footer.columns ?? [];\n const social = footer.social ?? [];\n const showAdminLink = footer.showAdminLink !== false;\n const year = new Date().getFullYear();\n const profiel = useMergedSiteConfig().business;\n const toonProfiel = bedrijf && heeftProfiel(profiel);\n\n return (\n <footer className={className ?? \"xicms-footer\"}>\n {(columns.length > 0 || toonProfiel) && (\n <div className=\"xicms-footer__columns\">\n {toonProfiel && profiel && (\n <div className=\"xicms-footer__column xicms-footer__column--bedrijf\">\n <h3 className=\"xicms-footer__heading\">Contact</h3>\n <ul className=\"xicms-footer__links\">\n {adresRegels(profiel).map((r) => <li key={r}>{r}</li>)}\n {profiel.phone && <li><a href={telLink(profiel.phone)}>{profiel.phone}</a></li>}\n {profiel.email && <li><a href={`mailto:${profiel.email}`}>{profiel.email}</a></li>}\n </ul>\n {(profiel.hours?.length ?? 0) > 0 && (\n <>\n <h3 className=\"xicms-footer__heading\">Openingstijden</h3>\n <ul className=\"xicms-footer__links\">\n {profiel.hours!.map((r, i) => <li key={i}>{r.day} — {r.hours}</li>)}\n </ul>\n </>\n )}\n </div>\n )}\n {columns.map((col, i) =>\n renderColumn ? (\n <div key={i}>{renderColumn(col, i)}</div>\n ) : (\n <div key={i} className=\"xicms-footer__column\">\n {col.heading && <h3 className=\"xicms-footer__heading\">{col.heading}</h3>}\n <ul className=\"xicms-footer__links\">\n {(col.links ?? []).map((l, j) => (\n <li key={j}>\n <a href={l.href}>{l.label}</a>\n </li>\n ))}\n </ul>\n </div>\n ),\n )}\n </div>\n )}\n\n {social.length > 0 && (\n <ul className=\"xicms-footer__social\">\n {social.map((s, i) => (\n <li key={i}>\n <a href={s.href} aria-label={s.platform} rel=\"noopener noreferrer\" target=\"_blank\">\n {s.platform}\n </a>\n </li>\n ))}\n </ul>\n )}\n\n <div className=\"xicms-footer__bottom\">\n <span>{footer.copyright ?? `© ${year} ${name}`}</span>\n {showAdminLink && <a href=\"/beheer\">Beheer</a>}\n </div>\n\n <div className=\"xicms-footer__credit\">\n <a\n className=\"xicms-footer__credit-merk\"\n href=\"https://www.xiwebdesign.nl\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n <svg viewBox=\"0 0 64 64\" aria-hidden=\"true\" fill=\"currentColor\">\n <rect x=\"6\" y=\"10\" width=\"52\" height=\"11\" rx=\"3\" />\n <rect x=\"16\" y=\"27\" width=\"32\" height=\"11\" rx=\"3\" opacity=\"0.7\" />\n <rect x=\"6\" y=\"44\" width=\"52\" height=\"11\" rx=\"3\" />\n </svg>\n Website gemaakt door Xi Webdesign\n </a>\n <span aria-hidden>·</span>\n <a\n className=\"xicms-footer__credit-cta\"\n href=\"https://www.xiwebdesign.nl/#contact\"\n rel=\"noopener noreferrer\"\n target=\"_blank\"\n >\n Ook zo'n mooie website? Neem contact op →\n </a>\n </div>\n </footer>\n );\n}\n"],"mappings":"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","names":[]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* De kop van de site (8.13): logo, het beheerde menu, één actieknop — en op een telefoon een
|
|
3
|
+
* hamburgermenu en (optioneel) een vaste balk onderaan met "Bel" en de actieknop.
|
|
4
|
+
*
|
|
5
|
+
* Alle drie de klantsites bouwden dit zelf (Header.tsx van 100+ regels, StickyCta.tsx), en de
|
|
6
|
+
* template had alleen `<strong>naam</strong>` plus het menu, zonder mobiel menu. Nu kan een
|
|
7
|
+
* nieuwe site starten met een kop die op elk scherm werkt, en past de klant logo en knop zelf aan
|
|
8
|
+
* in /beheer → Instellingen → Kop. Sites met een eigen header gebruiken dit gewoon niet.
|
|
9
|
+
*
|
|
10
|
+
* Unstyled-by-default zoals SiteNav en SiteFooter: alle opmaak hangt aan `.xicms-header*` en de
|
|
11
|
+
* thema-variabelen (styles.css), te overschrijven per site.
|
|
12
|
+
*/
|
|
13
|
+
export declare function SiteHeader({ className }: {
|
|
14
|
+
className?: string;
|
|
15
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { useEffect, useId, useState } from "react";
|
|
4
|
+
import { useLinkComponent } from "@astryxdesign/core/Link";
|
|
5
|
+
import { useMergedSiteConfig } from "../../settings/useSiteSettings.js";
|
|
6
|
+
import { telLink } from "../../bedrijf/bedrijf.js";
|
|
7
|
+
import { SiteNav } from "./SiteNav.js";
|
|
8
|
+
function SiteHeader({ className }) {
|
|
9
|
+
const cfg = useMergedSiteConfig();
|
|
10
|
+
const Link = useLinkComponent();
|
|
11
|
+
const header = cfg.header ?? {};
|
|
12
|
+
const [open, setOpen] = useState(false);
|
|
13
|
+
const menuId = useId();
|
|
14
|
+
useEffect(() => {
|
|
15
|
+
if (!open) return;
|
|
16
|
+
const sluit = () => setOpen(false);
|
|
17
|
+
const opToets = (e) => e.key === "Escape" && sluit();
|
|
18
|
+
window.addEventListener("popstate", sluit);
|
|
19
|
+
window.addEventListener("keydown", opToets);
|
|
20
|
+
const vorige = document.documentElement.style.overflow;
|
|
21
|
+
document.documentElement.style.overflow = "hidden";
|
|
22
|
+
return () => {
|
|
23
|
+
window.removeEventListener("popstate", sluit);
|
|
24
|
+
window.removeEventListener("keydown", opToets);
|
|
25
|
+
document.documentElement.style.overflow = vorige;
|
|
26
|
+
};
|
|
27
|
+
}, [open]);
|
|
28
|
+
const cta = header.cta?.label?.trim() && header.cta.href ? header.cta : null;
|
|
29
|
+
const bel = telLink(cfg.business?.phone);
|
|
30
|
+
const LinkEl = Link;
|
|
31
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
32
|
+
/* @__PURE__ */ jsx(
|
|
33
|
+
"header",
|
|
34
|
+
{
|
|
35
|
+
className: ["xicms-header", header.sticky === false ? "" : "is-sticky", open ? "is-open" : "", className].filter(Boolean).join(" "),
|
|
36
|
+
children: /* @__PURE__ */ jsxs("div", { className: "xicms-header__binnen", children: [
|
|
37
|
+
/* @__PURE__ */ jsx(LinkEl, { href: "/", className: "xicms-header__merk", children: header.logo ? (
|
|
38
|
+
// eslint-disable-next-line @next/next/no-img-element
|
|
39
|
+
/* @__PURE__ */ jsx("img", { src: header.logo, alt: cfg.name, style: { height: header.logoHoogte ?? 40 } })
|
|
40
|
+
) : /* @__PURE__ */ jsx("span", { children: cfg.name }) }),
|
|
41
|
+
/* @__PURE__ */ jsxs("div", { className: "xicms-header__nav", id: menuId, children: [
|
|
42
|
+
/* @__PURE__ */ jsx("div", { onClick: (e) => e.target.closest("a") && setOpen(false), children: /* @__PURE__ */ jsx(SiteNav, { className: "xicms-nav xicms-header__menu" }) }),
|
|
43
|
+
cta && /* @__PURE__ */ jsx(LinkEl, { href: cta.href, className: "xicms-header__cta xicms-header__cta--in-menu", onClick: () => setOpen(false), children: cta.label })
|
|
44
|
+
] }),
|
|
45
|
+
cta && /* @__PURE__ */ jsx(LinkEl, { href: cta.href, className: "xicms-header__cta", children: cta.label }),
|
|
46
|
+
/* @__PURE__ */ jsx(
|
|
47
|
+
"button",
|
|
48
|
+
{
|
|
49
|
+
type: "button",
|
|
50
|
+
className: "xicms-header__knop",
|
|
51
|
+
"aria-expanded": open,
|
|
52
|
+
"aria-controls": menuId,
|
|
53
|
+
"aria-label": open ? "Menu sluiten" : "Menu openen",
|
|
54
|
+
onClick: () => setOpen((v) => !v),
|
|
55
|
+
children: /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "xicms-header__streepjes" })
|
|
56
|
+
}
|
|
57
|
+
)
|
|
58
|
+
] })
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
header.mobielBalk && (bel || cta) && /* @__PURE__ */ jsxs("div", { className: "xicms-mobielbalk", role: "region", "aria-label": "Snel contact", children: [
|
|
62
|
+
bel && /* @__PURE__ */ jsx("a", { href: bel, className: "xicms-mobielbalk__bel", children: "Bel ons" }),
|
|
63
|
+
cta && /* @__PURE__ */ jsx(LinkEl, { href: cta.href, className: "xicms-mobielbalk__cta", children: cta.label })
|
|
64
|
+
] })
|
|
65
|
+
] });
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
SiteHeader
|
|
69
|
+
};
|
|
70
|
+
//# sourceMappingURL=SiteHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/site/SiteHeader.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useId, useState } from \"react\";\nimport { useLinkComponent } from \"@astryxdesign/core/Link\";\nimport { useMergedSiteConfig } from \"../../settings/useSiteSettings\";\nimport { telLink } from \"../../bedrijf/bedrijf\";\nimport { SiteNav } from \"./SiteNav\";\n\n/**\n * De kop van de site (8.13): logo, het beheerde menu, één actieknop — en op een telefoon een\n * hamburgermenu en (optioneel) een vaste balk onderaan met \"Bel\" en de actieknop.\n *\n * Alle drie de klantsites bouwden dit zelf (Header.tsx van 100+ regels, StickyCta.tsx), en de\n * template had alleen `<strong>naam</strong>` plus het menu, zonder mobiel menu. Nu kan een\n * nieuwe site starten met een kop die op elk scherm werkt, en past de klant logo en knop zelf aan\n * in /beheer → Instellingen → Kop. Sites met een eigen header gebruiken dit gewoon niet.\n *\n * Unstyled-by-default zoals SiteNav en SiteFooter: alle opmaak hangt aan `.xicms-header*` en de\n * thema-variabelen (styles.css), te overschrijven per site.\n */\nexport function SiteHeader({ className }: { className?: string }) {\n const cfg = useMergedSiteConfig();\n const Link = useLinkComponent();\n const header = cfg.header ?? {};\n const [open, setOpen] = useState(false);\n const menuId = useId();\n\n // Menu dicht bij navigeren (Terug/Vooruit) en met Escape; scrollen blokkeren terwijl het open is.\n useEffect(() => {\n if (!open) return;\n const sluit = () => setOpen(false);\n const opToets = (e: KeyboardEvent) => e.key === \"Escape\" && sluit();\n window.addEventListener(\"popstate\", sluit);\n window.addEventListener(\"keydown\", opToets);\n const vorige = document.documentElement.style.overflow;\n document.documentElement.style.overflow = \"hidden\";\n return () => {\n window.removeEventListener(\"popstate\", sluit);\n window.removeEventListener(\"keydown\", opToets);\n document.documentElement.style.overflow = vorige;\n };\n }, [open]);\n\n const cta = header.cta?.label?.trim() && header.cta.href ? header.cta : null;\n const bel = telLink(cfg.business?.phone);\n const LinkEl = Link as unknown as React.ComponentType<{ href: string; className?: string; children: React.ReactNode; onClick?: () => void }>;\n\n return (\n <>\n <header\n className={[\"xicms-header\", header.sticky === false ? \"\" : \"is-sticky\", open ? \"is-open\" : \"\", className].filter(Boolean).join(\" \")}\n >\n <div className=\"xicms-header__binnen\">\n <LinkEl href=\"/\" className=\"xicms-header__merk\">\n {header.logo ? (\n // eslint-disable-next-line @next/next/no-img-element\n <img src={header.logo} alt={cfg.name} style={{ height: header.logoHoogte ?? 40 }} />\n ) : (\n <span>{cfg.name}</span>\n )}\n </LinkEl>\n <div className=\"xicms-header__nav\" id={menuId}>\n {/* Een klik op een link in het (mobiele) menu sluit het; de nav zelf is SiteNav. */}\n <div onClick={(e) => (e.target as HTMLElement).closest(\"a\") && setOpen(false)}>\n <SiteNav className=\"xicms-nav xicms-header__menu\" />\n </div>\n {cta && (\n <LinkEl href={cta.href} className=\"xicms-header__cta xicms-header__cta--in-menu\" onClick={() => setOpen(false)}>\n {cta.label}\n </LinkEl>\n )}\n </div>\n {cta && (\n <LinkEl href={cta.href} className=\"xicms-header__cta\">\n {cta.label}\n </LinkEl>\n )}\n <button\n type=\"button\"\n className=\"xicms-header__knop\"\n aria-expanded={open}\n aria-controls={menuId}\n aria-label={open ? \"Menu sluiten\" : \"Menu openen\"}\n onClick={() => setOpen((v) => !v)}\n >\n <span aria-hidden className=\"xicms-header__streepjes\" />\n </button>\n </div>\n </header>\n {header.mobielBalk && (bel || cta) && (\n <div className=\"xicms-mobielbalk\" role=\"region\" aria-label=\"Snel contact\">\n {bel && (\n <a href={bel} className=\"xicms-mobielbalk__bel\">\n Bel ons\n </a>\n )}\n {cta && (\n <LinkEl href={cta.href} className=\"xicms-mobielbalk__cta\">\n {cta.label}\n </LinkEl>\n )}\n </div>\n )}\n </>\n );\n}\n"],"mappings":";AAgDI,mBAQU,KAKJ,YAbN;AA9CJ,SAAS,WAAW,OAAO,gBAAgB;AAC3C,SAAS,wBAAwB;AACjC,SAAS,2BAA2B;AACpC,SAAS,eAAe;AACxB,SAAS,eAAe;AAcjB,SAAS,WAAW,EAAE,UAAU,GAA2B;AAChE,QAAM,MAAM,oBAAoB;AAChC,QAAM,OAAO,iBAAiB;AAC9B,QAAM,SAAS,IAAI,UAAU,CAAC;AAC9B,QAAM,CAAC,MAAM,OAAO,IAAI,SAAS,KAAK;AACtC,QAAM,SAAS,MAAM;AAGrB,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,UAAM,QAAQ,MAAM,QAAQ,KAAK;AACjC,UAAM,UAAU,CAAC,MAAqB,EAAE,QAAQ,YAAY,MAAM;AAClE,WAAO,iBAAiB,YAAY,KAAK;AACzC,WAAO,iBAAiB,WAAW,OAAO;AAC1C,UAAM,SAAS,SAAS,gBAAgB,MAAM;AAC9C,aAAS,gBAAgB,MAAM,WAAW;AAC1C,WAAO,MAAM;AACX,aAAO,oBAAoB,YAAY,KAAK;AAC5C,aAAO,oBAAoB,WAAW,OAAO;AAC7C,eAAS,gBAAgB,MAAM,WAAW;AAAA,IAC5C;AAAA,EACF,GAAG,CAAC,IAAI,CAAC;AAET,QAAM,MAAM,OAAO,KAAK,OAAO,KAAK,KAAK,OAAO,IAAI,OAAO,OAAO,MAAM;AACxE,QAAM,MAAM,QAAQ,IAAI,UAAU,KAAK;AACvC,QAAM,SAAS;AAEf,SACE,iCACE;AAAA;AAAA,MAAC;AAAA;AAAA,QACC,WAAW,CAAC,gBAAgB,OAAO,WAAW,QAAQ,KAAK,aAAa,OAAO,YAAY,IAAI,SAAS,EAAE,OAAO,OAAO,EAAE,KAAK,GAAG;AAAA,QAElI,+BAAC,SAAI,WAAU,wBACb;AAAA,8BAAC,UAAO,MAAK,KAAI,WAAU,sBACxB,iBAAO;AAAA;AAAA,YAEN,oBAAC,SAAI,KAAK,OAAO,MAAM,KAAK,IAAI,MAAM,OAAO,EAAE,QAAQ,OAAO,cAAc,GAAG,GAAG;AAAA,cAElF,oBAAC,UAAM,cAAI,MAAK,GAEpB;AAAA,UACA,qBAAC,SAAI,WAAU,qBAAoB,IAAI,QAErC;AAAA,gCAAC,SAAI,SAAS,CAAC,MAAO,EAAE,OAAuB,QAAQ,GAAG,KAAK,QAAQ,KAAK,GAC1E,8BAAC,WAAQ,WAAU,gCAA+B,GACpD;AAAA,YACC,OACC,oBAAC,UAAO,MAAM,IAAI,MAAM,WAAU,gDAA+C,SAAS,MAAM,QAAQ,KAAK,GAC1G,cAAI,OACP;AAAA,aAEJ;AAAA,UACC,OACC,oBAAC,UAAO,MAAM,IAAI,MAAM,WAAU,qBAC/B,cAAI,OACP;AAAA,UAEF;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,WAAU;AAAA,cACV,iBAAe;AAAA,cACf,iBAAe;AAAA,cACf,cAAY,OAAO,iBAAiB;AAAA,cACpC,SAAS,MAAM,QAAQ,CAAC,MAAM,CAAC,CAAC;AAAA,cAEhC,8BAAC,UAAK,eAAW,MAAC,WAAU,2BAA0B;AAAA;AAAA,UACxD;AAAA,WACF;AAAA;AAAA,IACF;AAAA,IACC,OAAO,eAAe,OAAO,QAC5B,qBAAC,SAAI,WAAU,oBAAmB,MAAK,UAAS,cAAW,gBACxD;AAAA,aACC,oBAAC,OAAE,MAAM,KAAK,WAAU,yBAAwB,qBAEhD;AAAA,MAED,OACC,oBAAC,UAAO,MAAM,IAAI,MAAM,WAAU,yBAC/B,cAAI,OACP;AAAA,OAEJ;AAAA,KAEJ;AAEJ;","names":[]}
|
|
@@ -27,3 +27,5 @@ export declare function SiteNav({ className, ariaLabel, items, }: {
|
|
|
27
27
|
/** Overschrijft de items (bv. voor een footer-menu); standaard de beheerde hoofdnavigatie. */
|
|
28
28
|
items?: NavItem[];
|
|
29
29
|
}): import("react").JSX.Element | null;
|
|
30
|
+
/** Is dit menu-item de huidige pagina (of, voor een item met submenu, een van zijn kinderen)? */
|
|
31
|
+
export declare function isHuidig(href: string, pad: string | null): boolean;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useEffect, useId, useRef, useState } from "react";
|
|
3
|
+
import { useEffect, useId, useRef, useState, useSyncExternalStore } from "react";
|
|
4
4
|
import { useLinkComponent } from "@astryxdesign/core/Link";
|
|
5
5
|
import { useMergedSiteConfig } from "../../settings/useSiteSettings.js";
|
|
6
6
|
import { isExterneLink, navHref } from "../../schema/settings.js";
|
|
@@ -14,7 +14,26 @@ function SiteNav({
|
|
|
14
14
|
if (lijst.length === 0) return null;
|
|
15
15
|
return /* @__PURE__ */ jsx("nav", { className: className ?? "xicms-nav", "aria-label": ariaLabel, children: /* @__PURE__ */ jsx("ul", { className: "xicms-nav__list", children: lijst.map((item, i) => /* @__PURE__ */ jsx(NavEntry, { item }, `${item.href}-${i}`)) }) });
|
|
16
16
|
}
|
|
17
|
+
function abonneerOpPad(cb) {
|
|
18
|
+
window.addEventListener("popstate", cb);
|
|
19
|
+
const nav = window.navigation;
|
|
20
|
+
nav?.addEventListener("navigatesuccess", cb);
|
|
21
|
+
return () => {
|
|
22
|
+
window.removeEventListener("popstate", cb);
|
|
23
|
+
nav?.removeEventListener("navigatesuccess", cb);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
function useHuidigPad() {
|
|
27
|
+
return useSyncExternalStore(abonneerOpPad, () => window.location.pathname, () => null);
|
|
28
|
+
}
|
|
29
|
+
function isHuidig(href, pad) {
|
|
30
|
+
if (!pad || isExterneLink(href)) return false;
|
|
31
|
+
const schoon = (p) => p.length > 1 ? p.replace(/\/+$/, "") : p;
|
|
32
|
+
return schoon(href.split(/[?#]/)[0]) === schoon(pad);
|
|
33
|
+
}
|
|
17
34
|
function NavEntry({ item }) {
|
|
35
|
+
const pad = useHuidigPad();
|
|
36
|
+
const toggleRef = useRef(null);
|
|
18
37
|
const LinkC = useLinkComponent();
|
|
19
38
|
const kinderen = item.children ?? [];
|
|
20
39
|
const [open, setOpen] = useState(false);
|
|
@@ -26,7 +45,9 @@ function NavEntry({ item }) {
|
|
|
26
45
|
if (!ref.current?.contains(e.target)) setOpen(false);
|
|
27
46
|
};
|
|
28
47
|
const onKey = (e) => {
|
|
29
|
-
if (e.key
|
|
48
|
+
if (e.key !== "Escape") return;
|
|
49
|
+
setOpen(false);
|
|
50
|
+
if (ref.current?.contains(document.activeElement)) toggleRef.current?.focus();
|
|
30
51
|
};
|
|
31
52
|
document.addEventListener("pointerdown", onDown);
|
|
32
53
|
document.addEventListener("keydown", onKey);
|
|
@@ -42,14 +63,15 @@ function NavEntry({ item }) {
|
|
|
42
63
|
rel: extern && item.target === "_blank" ? "noopener noreferrer" : void 0
|
|
43
64
|
};
|
|
44
65
|
if (kinderen.length === 0) {
|
|
45
|
-
return /* @__PURE__ */ jsx("li", { className: "xicms-nav__item", children: /* @__PURE__ */ jsx(LinkC, { className: "xicms-nav__link", ...linkProps, children: item.label }) });
|
|
66
|
+
return /* @__PURE__ */ jsx("li", { className: "xicms-nav__item", children: /* @__PURE__ */ jsx(LinkC, { className: "xicms-nav__link", ...linkProps, "aria-current": isHuidig(item.href, pad) ? "page" : void 0, children: item.label }) });
|
|
46
67
|
}
|
|
47
68
|
return /* @__PURE__ */ jsxs("li", { ref, className: `xicms-nav__item xicms-nav__item--sub${open ? " is-open" : ""}`, children: [
|
|
48
69
|
/* @__PURE__ */ jsxs("span", { className: "xicms-nav__pair", children: [
|
|
49
|
-
/* @__PURE__ */ jsx(LinkC, { className: "xicms-nav__link", ...linkProps, children: item.label }),
|
|
70
|
+
/* @__PURE__ */ jsx(LinkC, { className: "xicms-nav__link", ...linkProps, "aria-current": isHuidig(item.href, pad) ? "page" : void 0, children: item.label }),
|
|
50
71
|
/* @__PURE__ */ jsx(
|
|
51
72
|
"button",
|
|
52
73
|
{
|
|
74
|
+
ref: toggleRef,
|
|
53
75
|
type: "button",
|
|
54
76
|
className: "xicms-nav__toggle",
|
|
55
77
|
"aria-expanded": open,
|
|
@@ -70,6 +92,7 @@ function NavEntry({ item }) {
|
|
|
70
92
|
target: kind.target === "_blank" ? "_blank" : void 0,
|
|
71
93
|
rel: kExtern && kind.target === "_blank" ? "noopener noreferrer" : void 0,
|
|
72
94
|
onClick: () => setOpen(false),
|
|
95
|
+
"aria-current": isHuidig(kind.href, pad) ? "page" : void 0,
|
|
73
96
|
children: kind.label
|
|
74
97
|
}
|
|
75
98
|
) }, `${kind.href}-${j}`);
|
|
@@ -77,6 +100,7 @@ function NavEntry({ item }) {
|
|
|
77
100
|
] });
|
|
78
101
|
}
|
|
79
102
|
export {
|
|
80
|
-
SiteNav
|
|
103
|
+
SiteNav,
|
|
104
|
+
isHuidig
|
|
81
105
|
};
|
|
82
106
|
//# sourceMappingURL=SiteNav.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/site/SiteNav.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useId, useRef, useState } from \"react\";\nimport { useLinkComponent } from \"@astryxdesign/core/Link\";\nimport { useMergedSiteConfig } from \"../../settings/useSiteSettings\";\nimport { isExterneLink, navHref, type NavItem } from \"../../schema/settings\";\n\n/**\n * De hoofdnavigatie zoals de klant hem in /beheer → Menu beheert (7.24).\n *\n * Tot 7.24 schreef het Menu-paneel netjes naar `settings.nav`, meldde \"De navigatie is\n * bijgewerkt\" — en las geen enkele header dat veld. De template en de klantsites renderden\n * `siteConfig.nav` rechtstreeks uit Git, dus wat de klant in het beheer deed kwam nooit op de\n * site. Deze component is de ontbrekende consument: hij leest de samengevoegde config\n * (Firestore wint, Git is de terugval) en is daarmee de énige plek die een menu hoort te tekenen.\n *\n * SSR-veilig: de settings zitten in de server-seed (`settingsData` op XiCMSProvider), dus het menu\n * staat al in de HTML en er is geen flits van het oude menu.\n *\n * Unstyled-by-default, net als `SiteFooter`: alle opmaak hangt aan `xicms-nav*`-klassen en de\n * thema-variabelen, zodat elke site hem kan herstijlen zonder de logica te forken. De klassen die\n * de template gebruikte (`.site-header nav a`) blijven werken doordat dit een gewone `<nav>` met\n * `<a>`'s blijft.\n *\n * Submenu's (één niveau): een item mét kinderen is zélf een link naar zijn overzichtspagina, met\n * ernaast een knop die het submenu openklapt (`aria-expanded`). Zo werkt het menu zonder\n * JavaScript (alle links staan in de HTML), met het toetsenbord (knop = Enter/Spatie, Escape\n * sluit) en op touch (geen hover nodig).\n */\nexport function SiteNav({\n className,\n ariaLabel = \"Hoofdnavigatie\",\n items,\n}: {\n className?: string;\n ariaLabel?: string;\n /** Overschrijft de items (bv. voor een footer-menu); standaard de beheerde hoofdnavigatie. */\n items?: NavItem[];\n}) {\n const cfg = useMergedSiteConfig();\n const lijst = items ?? cfg.nav ?? [];\n if (lijst.length === 0) return null;\n return (\n <nav className={className ?? \"xicms-nav\"} aria-label={ariaLabel}>\n <ul className=\"xicms-nav__list\">\n {lijst.map((item, i) => (\n <NavEntry key={`${item.href}-${i}`} item={item} />\n ))}\n </ul>\n </nav>\n );\n}\n\nfunction NavEntry({ item }: { item: NavItem }) {\n const LinkC = useLinkComponent();\n const kinderen = item.children ?? [];\n const [open, setOpen] = useState(false);\n const id = useId();\n const ref = useRef<HTMLLIElement>(null);\n\n // Buiten klikken of Escape sluit het submenu — anders blijft het hangen tot je een ander opent.\n useEffect(() => {\n if (!open) return;\n const onDown = (e: PointerEvent) => {\n if (!ref.current?.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key
|
|
1
|
+
{"version":3,"sources":["../../../src/components/site/SiteNav.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useId, useRef, useState, useSyncExternalStore } from \"react\";\nimport { useLinkComponent } from \"@astryxdesign/core/Link\";\nimport { useMergedSiteConfig } from \"../../settings/useSiteSettings\";\nimport { isExterneLink, navHref, type NavItem } from \"../../schema/settings\";\n\n/**\n * De hoofdnavigatie zoals de klant hem in /beheer → Menu beheert (7.24).\n *\n * Tot 7.24 schreef het Menu-paneel netjes naar `settings.nav`, meldde \"De navigatie is\n * bijgewerkt\" — en las geen enkele header dat veld. De template en de klantsites renderden\n * `siteConfig.nav` rechtstreeks uit Git, dus wat de klant in het beheer deed kwam nooit op de\n * site. Deze component is de ontbrekende consument: hij leest de samengevoegde config\n * (Firestore wint, Git is de terugval) en is daarmee de énige plek die een menu hoort te tekenen.\n *\n * SSR-veilig: de settings zitten in de server-seed (`settingsData` op XiCMSProvider), dus het menu\n * staat al in de HTML en er is geen flits van het oude menu.\n *\n * Unstyled-by-default, net als `SiteFooter`: alle opmaak hangt aan `xicms-nav*`-klassen en de\n * thema-variabelen, zodat elke site hem kan herstijlen zonder de logica te forken. De klassen die\n * de template gebruikte (`.site-header nav a`) blijven werken doordat dit een gewone `<nav>` met\n * `<a>`'s blijft.\n *\n * Submenu's (één niveau): een item mét kinderen is zélf een link naar zijn overzichtspagina, met\n * ernaast een knop die het submenu openklapt (`aria-expanded`). Zo werkt het menu zonder\n * JavaScript (alle links staan in de HTML), met het toetsenbord (knop = Enter/Spatie, Escape\n * sluit) en op touch (geen hover nodig).\n */\nexport function SiteNav({\n className,\n ariaLabel = \"Hoofdnavigatie\",\n items,\n}: {\n className?: string;\n ariaLabel?: string;\n /** Overschrijft de items (bv. voor een footer-menu); standaard de beheerde hoofdnavigatie. */\n items?: NavItem[];\n}) {\n const cfg = useMergedSiteConfig();\n const lijst = items ?? cfg.nav ?? [];\n if (lijst.length === 0) return null;\n return (\n <nav className={className ?? \"xicms-nav\"} aria-label={ariaLabel}>\n <ul className=\"xicms-nav__list\">\n {lijst.map((item, i) => (\n <NavEntry key={`${item.href}-${i}`} item={item} />\n ))}\n </ul>\n </nav>\n );\n}\n\n/**\n * Het huidige pad, hydratie-veilig (8.3): op de server en tijdens de hydratie `null`, daarna het\n * echte pad. Luistert naar Terug/Vooruit en — waar de browser hem heeft — de Navigation API, zodat\n * ook een client-side navigatie de markering verplaatst.\n */\nfunction abonneerOpPad(cb: () => void): () => void {\n window.addEventListener(\"popstate\", cb);\n const nav = (window as unknown as { navigation?: EventTarget }).navigation;\n nav?.addEventListener(\"navigatesuccess\", cb);\n return () => {\n window.removeEventListener(\"popstate\", cb);\n nav?.removeEventListener(\"navigatesuccess\", cb);\n };\n}\nfunction useHuidigPad(): string | null {\n return useSyncExternalStore(abonneerOpPad, () => window.location.pathname, () => null);\n}\n\n/** Is dit menu-item de huidige pagina (of, voor een item met submenu, een van zijn kinderen)? */\nexport function isHuidig(href: string, pad: string | null): boolean {\n if (!pad || isExterneLink(href)) return false;\n const schoon = (p: string) => (p.length > 1 ? p.replace(/\\/+$/, \"\") : p);\n return schoon(href.split(/[?#]/)[0]) === schoon(pad);\n}\n\nfunction NavEntry({ item }: { item: NavItem }) {\n const pad = useHuidigPad();\n const toggleRef = useRef<HTMLButtonElement>(null);\n const LinkC = useLinkComponent();\n const kinderen = item.children ?? [];\n const [open, setOpen] = useState(false);\n const id = useId();\n const ref = useRef<HTMLLIElement>(null);\n\n // Buiten klikken of Escape sluit het submenu — anders blijft het hangen tot je een ander opent.\n useEffect(() => {\n if (!open) return;\n const onDown = (e: PointerEvent) => {\n if (!ref.current?.contains(e.target as Node)) setOpen(false);\n };\n const onKey = (e: KeyboardEvent) => {\n if (e.key !== \"Escape\") return;\n setOpen(false);\n // 8.3: focus terug naar de knop — anders stond de toetsenbordgebruiker nergens meer.\n if (ref.current?.contains(document.activeElement)) toggleRef.current?.focus();\n };\n document.addEventListener(\"pointerdown\", onDown);\n document.addEventListener(\"keydown\", onKey);\n return () => {\n document.removeEventListener(\"pointerdown\", onDown);\n document.removeEventListener(\"keydown\", onKey);\n };\n }, [open]);\n\n const extern = isExterneLink(item.href);\n const linkProps = {\n href: navHref(item),\n target: item.target === \"_blank\" ? \"_blank\" : undefined,\n rel: extern && item.target === \"_blank\" ? \"noopener noreferrer\" : undefined,\n };\n\n if (kinderen.length === 0) {\n return (\n <li className=\"xicms-nav__item\">\n <LinkC className=\"xicms-nav__link\" {...linkProps} aria-current={isHuidig(item.href, pad) ? \"page\" : undefined}>{item.label}</LinkC>\n </li>\n );\n }\n\n return (\n <li ref={ref} className={`xicms-nav__item xicms-nav__item--sub${open ? \" is-open\" : \"\"}`}>\n <span className=\"xicms-nav__pair\">\n <LinkC className=\"xicms-nav__link\" {...linkProps} aria-current={isHuidig(item.href, pad) ? \"page\" : undefined}>{item.label}</LinkC>\n <button\n ref={toggleRef}\n type=\"button\"\n className=\"xicms-nav__toggle\"\n aria-expanded={open}\n aria-controls={id}\n aria-label={`Submenu van ${item.label} ${open ? \"sluiten\" : \"openen\"}`}\n onClick={() => setOpen((v) => !v)}\n >\n <svg viewBox=\"0 0 24 24\" width=\"14\" height=\"14\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" strokeLinecap=\"round\" strokeLinejoin=\"round\" aria-hidden=\"true\">\n <path d=\"M6 9l6 6 6-6\" />\n </svg>\n </button>\n </span>\n <ul id={id} className=\"xicms-nav__sub\" hidden={!open}>\n {kinderen.map((kind, j) => {\n const kExtern = isExterneLink(kind.href);\n return (\n <li key={`${kind.href}-${j}`} className=\"xicms-nav__subitem\">\n <LinkC\n className=\"xicms-nav__sublink\"\n href={navHref(kind)}\n target={kind.target === \"_blank\" ? \"_blank\" : undefined}\n rel={kExtern && kind.target === \"_blank\" ? \"noopener noreferrer\" : undefined}\n onClick={() => setOpen(false)}\n aria-current={isHuidig(kind.href, pad) ? \"page\" : undefined}\n >\n {kind.label}\n </LinkC>\n </li>\n );\n })}\n </ul>\n </li>\n );\n}\n"],"mappings":"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","names":[]}
|
package/dist/demo/DemoStudio.js
CHANGED
|
@@ -28,8 +28,8 @@ function DemoStudio() {
|
|
|
28
28
|
/* @__PURE__ */ jsxs("span", { className: "xicms-demostudio__msg", children: [
|
|
29
29
|
"\u270F\uFE0F ",
|
|
30
30
|
/* @__PURE__ */ jsx("strong", { children: "Demo-bewerkmodus." }),
|
|
31
|
-
"
|
|
32
|
-
/* @__PURE__ */ jsx("strong", { children: "\
|
|
31
|
+
" Kies onderaan ",
|
|
32
|
+
/* @__PURE__ */ jsx("strong", { children: "\u201CBewerken\u201D" }),
|
|
33
33
|
" om blokken aan te passen. Let op: ",
|
|
34
34
|
/* @__PURE__ */ jsx("strong", { children: "wijzigingen worden niet opgeslagen" }),
|
|
35
35
|
" \u2014 ze staan alleen lokaal in jouw browser."
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/demo/DemoStudio.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { useAuth } from \"../auth/AuthProvider\";\nimport { useSiteConfig } from \"../config\";\nimport { DEMO_EVENT, isDemoLoggedIn, resetDemo } from \"./demoStore\";\n\n/**\n * Bovenbalk voor de DEMO-bewerkmodus (`config.demoEditing`). Biedt een pseudo-login waarmee\n * bezoekers het beheer (teksten + blokken) kunnen uitproberen, en maakt heel duidelijk dat\n * wijzigingen NIET worden opgeslagen — ze blijven alleen lokaal in de browser en zijn met één\n * klik te resetten. De echte bewerkacties (\"Pagina bewerken\", \"Uitloggen\") staan in de EditBar.\n */\nexport function DemoStudio() {\n const { demo, demoSignIn } = useAuth();\n const { siteId } = useSiteConfig();\n const [loggedIn, setLoggedIn] = useState(false);\n\n useEffect(() => {\n if (!demo) return;\n const sync = () => setLoggedIn(isDemoLoggedIn());\n sync();\n window.addEventListener(DEMO_EVENT, sync);\n return () => window.removeEventListener(DEMO_EVENT, sync);\n }, [demo]);\n\n if (!demo) return null;\n\n return (\n <div className=\"xicms-demostudio\" role=\"region\" aria-label=\"Demo-bewerkmodus\">\n {!loggedIn ? (\n <>\n <span className=\"xicms-demostudio__msg\">\n <strong>Probeer het zelf:</strong> log in als demo-beheerder en bewerk teksten, foto's en\n blokken — <strong>niets wordt opgeslagen</strong>, je wijzigingen blijven alleen in jouw browser.\n </span>\n <button type=\"button\" className=\"xicms-btn\" onClick={demoSignIn}>\n Probeer het beheer (demo-login)\n </button>\n </>\n ) : (\n <>\n <span className=\"xicms-demostudio__msg\">\n ✏️ <strong>Demo-bewerkmodus.</strong>
|
|
1
|
+
{"version":3,"sources":["../../src/demo/DemoStudio.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport { useAuth } from \"../auth/AuthProvider\";\nimport { useSiteConfig } from \"../config\";\nimport { DEMO_EVENT, isDemoLoggedIn, resetDemo } from \"./demoStore\";\n\n/**\n * Bovenbalk voor de DEMO-bewerkmodus (`config.demoEditing`). Biedt een pseudo-login waarmee\n * bezoekers het beheer (teksten + blokken) kunnen uitproberen, en maakt heel duidelijk dat\n * wijzigingen NIET worden opgeslagen — ze blijven alleen lokaal in de browser en zijn met één\n * klik te resetten. De echte bewerkacties (\"Pagina bewerken\", \"Uitloggen\") staan in de EditBar.\n */\nexport function DemoStudio() {\n const { demo, demoSignIn } = useAuth();\n const { siteId } = useSiteConfig();\n const [loggedIn, setLoggedIn] = useState(false);\n\n useEffect(() => {\n if (!demo) return;\n const sync = () => setLoggedIn(isDemoLoggedIn());\n sync();\n window.addEventListener(DEMO_EVENT, sync);\n return () => window.removeEventListener(DEMO_EVENT, sync);\n }, [demo]);\n\n if (!demo) return null;\n\n return (\n <div className=\"xicms-demostudio\" role=\"region\" aria-label=\"Demo-bewerkmodus\">\n {!loggedIn ? (\n <>\n <span className=\"xicms-demostudio__msg\">\n <strong>Probeer het zelf:</strong> log in als demo-beheerder en bewerk teksten, foto's en\n blokken — <strong>niets wordt opgeslagen</strong>, je wijzigingen blijven alleen in jouw browser.\n </span>\n <button type=\"button\" className=\"xicms-btn\" onClick={demoSignIn}>\n Probeer het beheer (demo-login)\n </button>\n </>\n ) : (\n <>\n <span className=\"xicms-demostudio__msg\">\n ✏️ <strong>Demo-bewerkmodus.</strong> Kies onderaan <strong>“Bewerken”</strong> om\n blokken aan te passen. Let op: <strong>wijzigingen worden niet opgeslagen</strong> — ze staan\n alleen lokaal in jouw browser.\n </span>\n <button\n type=\"button\"\n className=\"xicms-btn xicms-btn--ghost\"\n onClick={() => {\n resetDemo(siteId);\n // Herlaad zodat de pagina terugvalt op de oorspronkelijke (seed-)inhoud.\n if (typeof window !== \"undefined\") window.location.reload();\n }}\n >\n Reset demo\n </button>\n </>\n )}\n </div>\n );\n}\n"],"mappings":";AA+BQ,mBAEI,KADF,YADF;AA7BR,SAAS,WAAW,gBAAgB;AACpC,SAAS,eAAe;AACxB,SAAS,qBAAqB;AAC9B,SAAS,YAAY,gBAAgB,iBAAiB;AAQ/C,SAAS,aAAa;AAC3B,QAAM,EAAE,MAAM,WAAW,IAAI,QAAQ;AACrC,QAAM,EAAE,OAAO,IAAI,cAAc;AACjC,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAE9C,YAAU,MAAM;AACd,QAAI,CAAC,KAAM;AACX,UAAM,OAAO,MAAM,YAAY,eAAe,CAAC;AAC/C,SAAK;AACL,WAAO,iBAAiB,YAAY,IAAI;AACxC,WAAO,MAAM,OAAO,oBAAoB,YAAY,IAAI;AAAA,EAC1D,GAAG,CAAC,IAAI,CAAC;AAET,MAAI,CAAC,KAAM,QAAO;AAElB,SACE,oBAAC,SAAI,WAAU,oBAAmB,MAAK,UAAS,cAAW,oBACxD,WAAC,WACA,iCACE;AAAA,yBAAC,UAAK,WAAU,yBACd;AAAA,0BAAC,YAAO,+BAAiB;AAAA,MAAS;AAAA,MACxB,oBAAC,YAAO,oCAAsB;AAAA,MAAS;AAAA,OACnD;AAAA,IACA,oBAAC,YAAO,MAAK,UAAS,WAAU,aAAY,SAAS,YAAY,6CAEjE;AAAA,KACF,IAEA,iCACE;AAAA,yBAAC,UAAK,WAAU,yBAAwB;AAAA;AAAA,MACnC,oBAAC,YAAO,+BAAiB;AAAA,MAAS;AAAA,MAAe,oBAAC,YAAO,kCAAU;AAAA,MAAS;AAAA,MAChD,oBAAC,YAAO,gDAAkC;AAAA,MAAS;AAAA,OAEpF;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,WAAU;AAAA,QACV,SAAS,MAAM;AACb,oBAAU,MAAM;AAEhB,cAAI,OAAO,WAAW,YAAa,QAAO,SAAS,OAAO;AAAA,QAC5D;AAAA,QACD;AAAA;AAAA,IAED;AAAA,KACF,GAEJ;AAEJ;","names":[]}
|
package/dist/demo/demoStore.d.ts
CHANGED
|
@@ -33,10 +33,23 @@ export declare function addDemoMedia(siteId: string, item: {
|
|
|
33
33
|
url: string;
|
|
34
34
|
name: string;
|
|
35
35
|
}): MediaItem;
|
|
36
|
+
/**
|
|
37
|
+
* Verwijderen in demo-modus (8.5): lokale uploads echt weg; een geseed item wordt alleen voor
|
|
38
|
+
* deze sessie verborgen (de seed komt bij herladen terug, zoals de rest van de demo).
|
|
39
|
+
*/
|
|
40
|
+
export declare function removeDemoMedia(siteId: string, id: string): void;
|
|
36
41
|
/** Inclusief geheugen-only items (opslag-vol-vangnet) — gebruikt door de kiezer. */
|
|
37
42
|
export declare function listDemoMediaAll(siteId: string): MediaItem[];
|
|
38
43
|
export declare function loadDemoDraft(siteId: string, id: string): Partial<Page> | null;
|
|
39
44
|
export declare function saveDemoDraft(siteId: string, id: string, patch: Partial<Page>): void;
|
|
45
|
+
/**
|
|
46
|
+
* Alle pagina's die de demo kent (8.6): geseede pagina's plus lokaal aangemaakte/bewerkte, met de
|
|
47
|
+
* lokale bewerking eroverheen. Voor het paginaoverzicht in het beheer — dat wachtte eerst op een
|
|
48
|
+
* rechtenfout van de echte database en toonde dan niets.
|
|
49
|
+
*/
|
|
50
|
+
export declare function listDemoPages(siteId: string): Array<Page & {
|
|
51
|
+
id: string;
|
|
52
|
+
}>;
|
|
40
53
|
/** Verwijdert alle lokale demo-bewerkingen + login voor deze site (de "Reset"-knop). */
|
|
41
54
|
export declare function resetDemo(siteId: string): void;
|
|
42
55
|
/**
|
package/dist/demo/demoStore.js
CHANGED
|
@@ -98,6 +98,18 @@ function addDemoMedia(siteId, item) {
|
|
|
98
98
|
emit();
|
|
99
99
|
return media;
|
|
100
100
|
}
|
|
101
|
+
function removeDemoMedia(siteId, id) {
|
|
102
|
+
const lokaal = loadLocalDemoMedia(siteId);
|
|
103
|
+
if (lokaal.some((m) => m.id === id)) {
|
|
104
|
+
try {
|
|
105
|
+
window.localStorage.setItem(mediaKey(siteId), JSON.stringify(lokaal.filter((m) => m.id !== id)));
|
|
106
|
+
} catch {
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
memoryOnlyMedia.set(siteId, (memoryOnlyMedia.get(siteId) ?? []).filter((m) => m.id !== id));
|
|
110
|
+
mediaSeeds.set(siteId, (mediaSeeds.get(siteId) ?? []).filter((m) => m.id !== id));
|
|
111
|
+
emit();
|
|
112
|
+
}
|
|
101
113
|
function listDemoMediaAll(siteId) {
|
|
102
114
|
return [...memoryOnlyMedia.get(siteId) ?? [], ...listDemoMedia(siteId)];
|
|
103
115
|
}
|
|
@@ -122,6 +134,28 @@ function saveDemoDraft(siteId, id, patch) {
|
|
|
122
134
|
}
|
|
123
135
|
emit();
|
|
124
136
|
}
|
|
137
|
+
function listDemoPages(siteId) {
|
|
138
|
+
const paden = /* @__PURE__ */ new Set();
|
|
139
|
+
for (const k of seeds.keys()) if (k.startsWith(`${siteId}::`)) paden.add(k.slice(siteId.length + 2));
|
|
140
|
+
if (typeof window !== "undefined") {
|
|
141
|
+
try {
|
|
142
|
+
const prefix = `${DRAFT_PREFIX}:${siteId}:`;
|
|
143
|
+
for (let i = 0; i < window.localStorage.length; i++) {
|
|
144
|
+
const k = window.localStorage.key(i);
|
|
145
|
+
const pad = k?.startsWith(prefix) ? demoPathForId(k.slice(prefix.length)) : null;
|
|
146
|
+
if (pad) paden.add(pad);
|
|
147
|
+
}
|
|
148
|
+
} catch {
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
const lijst = [];
|
|
152
|
+
for (const pad of paden) {
|
|
153
|
+
const id = demoIdForPath(pad);
|
|
154
|
+
const page = resolveDemoPage(siteId, pad) ?? loadDemoDraft(siteId, id);
|
|
155
|
+
if (page) lijst.push({ ...page, path: page.path ?? pad, id });
|
|
156
|
+
}
|
|
157
|
+
return lijst.sort((a, b) => a.path === "/" ? -1 : b.path === "/" ? 1 : (a.order ?? 0) - (b.order ?? 0));
|
|
158
|
+
}
|
|
125
159
|
function resetDemo(siteId) {
|
|
126
160
|
if (typeof window === "undefined") return;
|
|
127
161
|
try {
|
|
@@ -156,11 +190,13 @@ export {
|
|
|
156
190
|
isDemoLoggedIn,
|
|
157
191
|
listDemoMedia,
|
|
158
192
|
listDemoMediaAll,
|
|
193
|
+
listDemoPages,
|
|
159
194
|
loadDemoDraft,
|
|
160
195
|
registerDemoForm,
|
|
161
196
|
registerDemoMedia,
|
|
162
197
|
registerDemoNews,
|
|
163
198
|
registerSeed,
|
|
199
|
+
removeDemoMedia,
|
|
164
200
|
resetDemo,
|
|
165
201
|
resolveDemoPage,
|
|
166
202
|
saveDemoDraft,
|