@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.
Files changed (463) hide show
  1. package/dist/XiCMSProvider.js +22 -7
  2. package/dist/XiCMSProvider.js.map +1 -1
  3. package/dist/admin/AdminApp.js +175 -93
  4. package/dist/admin/AdminApp.js.map +1 -1
  5. package/dist/admin/AdminHelp.d.ts +1 -1
  6. package/dist/admin/AdminHelp.js +44 -36
  7. package/dist/admin/AdminHelp.js.map +1 -1
  8. package/dist/admin/CoreVersion.d.ts +6 -3
  9. package/dist/admin/CoreVersion.js +60 -24
  10. package/dist/admin/CoreVersion.js.map +1 -1
  11. package/dist/admin/NewsEditor.d.ts +7 -0
  12. package/dist/admin/NewsEditor.js +117 -75
  13. package/dist/admin/NewsEditor.js.map +1 -1
  14. package/dist/admin/SuperadminPanel.js +1 -1
  15. package/dist/admin/SuperadminPanel.js.map +1 -1
  16. package/dist/admin/ZoekPalet.d.ts +15 -0
  17. package/dist/admin/ZoekPalet.js +123 -0
  18. package/dist/admin/ZoekPalet.js.map +1 -0
  19. package/dist/admin/blockEditors/GenericEditor.js +36 -18
  20. package/dist/admin/blockEditors/GenericEditor.js.map +1 -1
  21. package/dist/admin/blockEditors/StyleEditor.js +37 -3
  22. package/dist/admin/blockEditors/StyleEditor.js.map +1 -1
  23. package/dist/admin/blockEditors/SymbolRefEditor.js +44 -2
  24. package/dist/admin/blockEditors/SymbolRefEditor.js.map +1 -1
  25. package/dist/admin/blockEditors/index.js +154 -73
  26. package/dist/admin/blockEditors/index.js.map +1 -1
  27. package/dist/admin/customBlocks/CustomBlocksPanel.js +18 -7
  28. package/dist/admin/customBlocks/CustomBlocksPanel.js.map +1 -1
  29. package/dist/admin/dashboard/DashboardPanel.js +26 -16
  30. package/dist/admin/dashboard/DashboardPanel.js.map +1 -1
  31. package/dist/admin/editors/RichTextEditor.d.ts +4 -3
  32. package/dist/admin/editors/RichTextEditor.js +19 -56
  33. package/dist/admin/editors/RichTextEditor.js.map +1 -1
  34. package/dist/admin/editors/fontSizeExtension.js +7 -1
  35. package/dist/admin/editors/fontSizeExtension.js.map +1 -1
  36. package/dist/admin/editors/slashMenu.d.ts +18 -0
  37. package/dist/admin/editors/slashMenu.js +34 -0
  38. package/dist/admin/editors/slashMenu.js.map +1 -0
  39. package/dist/admin/editors/useRijkeTekst.d.ts +48 -0
  40. package/dist/admin/editors/useRijkeTekst.js +310 -0
  41. package/dist/admin/editors/useRijkeTekst.js.map +1 -0
  42. package/dist/admin/forms/FormsPanel.d.ts +11 -2
  43. package/dist/admin/forms/FormsPanel.js +218 -65
  44. package/dist/admin/forms/FormsPanel.js.map +1 -1
  45. package/dist/admin/lib/blokInfo.d.ts +17 -0
  46. package/dist/admin/lib/blokInfo.js +80 -0
  47. package/dist/admin/lib/blokInfo.js.map +1 -0
  48. package/dist/admin/lib/foutNaarMens.d.ts +1 -0
  49. package/dist/admin/lib/foutNaarMens.js +22 -0
  50. package/dist/admin/lib/foutNaarMens.js.map +1 -0
  51. package/dist/admin/lib/gewisteVelden.d.ts +13 -0
  52. package/dist/admin/lib/gewisteVelden.js +31 -0
  53. package/dist/admin/lib/gewisteVelden.js.map +1 -0
  54. package/dist/admin/lib/heroHulp.d.ts +11 -0
  55. package/dist/admin/lib/heroHulp.js +18 -0
  56. package/dist/admin/lib/heroHulp.js.map +1 -0
  57. package/dist/admin/lib/kleur.js +2 -3
  58. package/dist/admin/lib/kleur.js.map +1 -1
  59. package/dist/admin/lib/leesbaarheid.d.ts +34 -0
  60. package/dist/admin/lib/leesbaarheid.js +82 -0
  61. package/dist/admin/lib/leesbaarheid.js.map +1 -0
  62. package/dist/admin/lib/lengteAdvies.d.ts +1 -0
  63. package/dist/admin/lib/lengteAdvies.js +16 -0
  64. package/dist/admin/lib/lengteAdvies.js.map +1 -0
  65. package/dist/admin/lib/mediaLijst.d.ts +26 -0
  66. package/dist/admin/lib/mediaLijst.js +42 -0
  67. package/dist/admin/lib/mediaLijst.js.map +1 -0
  68. package/dist/admin/lib/mediaUsage.d.ts +12 -1
  69. package/dist/admin/lib/mediaUsage.js +43 -33
  70. package/dist/admin/lib/mediaUsage.js.map +1 -1
  71. package/dist/admin/lib/menuHulp.d.ts +16 -0
  72. package/dist/admin/lib/menuHulp.js +41 -0
  73. package/dist/admin/lib/menuHulp.js.map +1 -0
  74. package/dist/admin/lib/onopgeslagen.d.ts +10 -0
  75. package/dist/admin/lib/onopgeslagen.js +35 -0
  76. package/dist/admin/lib/onopgeslagen.js.map +1 -0
  77. package/dist/admin/lib/pagesClient.d.ts +55 -2
  78. package/dist/admin/lib/pagesClient.js +126 -28
  79. package/dist/admin/lib/pagesClient.js.map +1 -1
  80. package/dist/admin/lib/paginaGebruik.d.ts +56 -0
  81. package/dist/admin/lib/paginaGebruik.js +109 -0
  82. package/dist/admin/lib/paginaGebruik.js.map +1 -0
  83. package/dist/admin/lib/publicatieCheck.d.ts +25 -0
  84. package/dist/admin/lib/publicatieCheck.js +114 -0
  85. package/dist/admin/lib/publicatieCheck.js.map +1 -0
  86. package/dist/admin/lib/scrollNaarDetail.d.ts +6 -0
  87. package/dist/admin/lib/scrollNaarDetail.js +20 -0
  88. package/dist/admin/lib/scrollNaarDetail.js.map +1 -0
  89. package/dist/admin/lib/symbolsClient.d.ts +10 -0
  90. package/dist/admin/lib/symbolsClient.js +14 -1
  91. package/dist/admin/lib/symbolsClient.js.map +1 -1
  92. package/dist/admin/lib/tekstVeld.d.ts +8 -0
  93. package/dist/admin/lib/tekstVeld.js +10 -0
  94. package/dist/admin/lib/tekstVeld.js.map +1 -0
  95. package/dist/admin/lib/useIsSuperadmin.d.ts +2 -0
  96. package/dist/admin/lib/useIsSuperadmin.js +13 -0
  97. package/dist/admin/lib/useIsSuperadmin.js.map +1 -0
  98. package/dist/admin/lib/veldTaal.d.ts +14 -0
  99. package/dist/admin/lib/veldTaal.js +247 -0
  100. package/dist/admin/lib/veldTaal.js.map +1 -0
  101. package/dist/admin/lib/versieVergelijk.d.ts +17 -0
  102. package/dist/admin/lib/versieVergelijk.js +24 -0
  103. package/dist/admin/lib/versieVergelijk.js.map +1 -0
  104. package/dist/admin/lib/zodFields.js +22 -4
  105. package/dist/admin/lib/zodFields.js.map +1 -1
  106. package/dist/admin/lib/zodFout.d.ts +9 -0
  107. package/dist/admin/lib/zodFout.js +63 -0
  108. package/dist/admin/lib/zodFout.js.map +1 -0
  109. package/dist/admin/media/MediaManager.js +162 -32
  110. package/dist/admin/media/MediaManager.js.map +1 -1
  111. package/dist/admin/media/MediaPicker.d.ts +3 -0
  112. package/dist/admin/media/MediaPicker.js +84 -31
  113. package/dist/admin/media/MediaPicker.js.map +1 -1
  114. package/dist/admin/menu/MenuPanel.js +144 -83
  115. package/dist/admin/menu/MenuPanel.js.map +1 -1
  116. package/dist/admin/navContext.d.ts +3 -0
  117. package/dist/admin/navContext.js +13 -1
  118. package/dist/admin/navContext.js.map +1 -1
  119. package/dist/admin/pages/PageEditor.js +146 -30
  120. package/dist/admin/pages/PageEditor.js.map +1 -1
  121. package/dist/admin/pages/PagesPanel.js +215 -61
  122. package/dist/admin/pages/PagesPanel.js.map +1 -1
  123. package/dist/admin/pages/StarterKiezer.d.ts +12 -0
  124. package/dist/admin/pages/StarterKiezer.js +113 -0
  125. package/dist/admin/pages/StarterKiezer.js.map +1 -0
  126. package/dist/admin/panelRegistry.d.ts +1 -1
  127. package/dist/admin/panelRegistry.js +2 -1
  128. package/dist/admin/panelRegistry.js.map +1 -1
  129. package/dist/admin/patterns/PatternInserter.js +1 -1
  130. package/dist/admin/patterns/PatternInserter.js.map +1 -1
  131. package/dist/admin/settings/BedrijfInstellingen.d.ts +20 -0
  132. package/dist/admin/settings/BedrijfInstellingen.js +144 -0
  133. package/dist/admin/settings/BedrijfInstellingen.js.map +1 -0
  134. package/dist/admin/settings/MailSettings.js +2 -2
  135. package/dist/admin/settings/MailSettings.js.map +1 -1
  136. package/dist/admin/settings/MailTemplates.js +5 -4
  137. package/dist/admin/settings/MailTemplates.js.map +1 -1
  138. package/dist/admin/settings/SettingsPanel.js +120 -78
  139. package/dist/admin/settings/SettingsPanel.js.map +1 -1
  140. package/dist/admin/settings/SnapshotsCard.js +4 -4
  141. package/dist/admin/settings/SnapshotsCard.js.map +1 -1
  142. package/dist/admin/settings/VorigeTerugzetten.d.ts +15 -0
  143. package/dist/admin/settings/VorigeTerugzetten.js +89 -0
  144. package/dist/admin/settings/VorigeTerugzetten.js.map +1 -0
  145. package/dist/admin/shop/CategoriesTab.js +6 -4
  146. package/dist/admin/shop/CategoriesTab.js.map +1 -1
  147. package/dist/admin/shop/DiscountsTab.js +4 -2
  148. package/dist/admin/shop/DiscountsTab.js.map +1 -1
  149. package/dist/admin/shop/OrdersTab.js +57 -19
  150. package/dist/admin/shop/OrdersTab.js.map +1 -1
  151. package/dist/admin/shop/ProductPaneel.js +2 -1
  152. package/dist/admin/shop/ProductPaneel.js.map +1 -1
  153. package/dist/admin/shop/ProductsTab.js +40 -19
  154. package/dist/admin/shop/ProductsTab.js.map +1 -1
  155. package/dist/admin/shop/ShopPanel.js +13 -1
  156. package/dist/admin/shop/ShopPanel.js.map +1 -1
  157. package/dist/admin/shop/ShopSettingsTab.js +27 -1
  158. package/dist/admin/shop/ShopSettingsTab.js.map +1 -1
  159. package/dist/admin/shop/productClient.js +7 -3
  160. package/dist/admin/shop/productClient.js.map +1 -1
  161. package/dist/admin/stats/NietGevonden.d.ts +10 -0
  162. package/dist/admin/stats/NietGevonden.js +78 -0
  163. package/dist/admin/stats/NietGevonden.js.map +1 -0
  164. package/dist/admin/stats/StatsPanel.js +6 -1
  165. package/dist/admin/stats/StatsPanel.js.map +1 -1
  166. package/dist/admin/stats/lib.d.ts +2 -0
  167. package/dist/admin/stats/lib.js.map +1 -1
  168. package/dist/admin/ui/ConfirmDialog.js +10 -1
  169. package/dist/admin/ui/ConfirmDialog.js.map +1 -1
  170. package/dist/admin/ui/Icon.d.ts +34 -0
  171. package/dist/admin/ui/Icon.js +44 -0
  172. package/dist/admin/ui/Icon.js.map +1 -0
  173. package/dist/admin/ui/ImageField.d.ts +15 -0
  174. package/dist/admin/ui/ImageField.js +67 -0
  175. package/dist/admin/ui/ImageField.js.map +1 -0
  176. package/dist/admin/ui/KleurVeld.d.ts +25 -0
  177. package/dist/admin/ui/KleurVeld.js +76 -0
  178. package/dist/admin/ui/KleurVeld.js.map +1 -0
  179. package/dist/admin/ui/LaadStaat.d.ts +21 -0
  180. package/dist/admin/ui/LaadStaat.js +43 -0
  181. package/dist/admin/ui/LaadStaat.js.map +1 -0
  182. package/dist/admin/ui/LeesbaarheidPaneel.d.ts +10 -0
  183. package/dist/admin/ui/LeesbaarheidPaneel.js +68 -0
  184. package/dist/admin/ui/LeesbaarheidPaneel.js.map +1 -0
  185. package/dist/admin/ui/LinkDialog.d.ts +22 -0
  186. package/dist/admin/ui/LinkDialog.js +131 -0
  187. package/dist/admin/ui/LinkDialog.js.map +1 -0
  188. package/dist/admin/ui/LinkVeld.d.ts +14 -0
  189. package/dist/admin/ui/LinkVeld.js +49 -0
  190. package/dist/admin/ui/LinkVeld.js.map +1 -0
  191. package/dist/admin/ui/PreviewLinkResultaat.d.ts +14 -0
  192. package/dist/admin/ui/PreviewLinkResultaat.js +52 -0
  193. package/dist/admin/ui/PreviewLinkResultaat.js.map +1 -0
  194. package/dist/admin/ui/charts.js +5 -5
  195. package/dist/admin/ui/charts.js.map +1 -1
  196. package/dist/admin/ui/primitives.d.ts +16 -6
  197. package/dist/admin/ui/primitives.js +98 -26
  198. package/dist/admin/ui/primitives.js.map +1 -1
  199. package/dist/admin/ui/select.js +5 -2
  200. package/dist/admin/ui/select.js.map +1 -1
  201. package/dist/admin/ui/switch.d.ts +3 -1
  202. package/dist/admin/ui/switch.js +6 -3
  203. package/dist/admin/ui/switch.js.map +1 -1
  204. package/dist/admin/ui/toast.d.ts +2 -1
  205. package/dist/admin/ui/toast.js +17 -11
  206. package/dist/admin/ui/toast.js.map +1 -1
  207. package/dist/admin/visual/BlokKiezer.d.ts +34 -0
  208. package/dist/admin/visual/BlokKiezer.js +225 -0
  209. package/dist/admin/visual/BlokKiezer.js.map +1 -0
  210. package/dist/admin/visual/InlineGereedschap.d.ts +52 -0
  211. package/dist/admin/visual/InlineGereedschap.js +356 -0
  212. package/dist/admin/visual/InlineGereedschap.js.map +1 -0
  213. package/dist/admin/visual/InlineRijkeTekst.d.ts +23 -0
  214. package/dist/admin/visual/InlineRijkeTekst.js +152 -0
  215. package/dist/admin/visual/InlineRijkeTekst.js.map +1 -0
  216. package/dist/admin/visual/VisualEditor.js +273 -125
  217. package/dist/admin/visual/VisualEditor.js.map +1 -1
  218. package/dist/admin.css +1 -1
  219. package/dist/bedrijf/bedrijf.d.ts +36 -0
  220. package/dist/bedrijf/bedrijf.js +110 -0
  221. package/dist/bedrijf/bedrijf.js.map +1 -0
  222. package/dist/blocks/BlockRenderer.js +11 -1
  223. package/dist/blocks/BlockRenderer.js.map +1 -1
  224. package/dist/blocks/blockStyle.d.ts +7 -0
  225. package/dist/blocks/blockStyle.js +16 -3
  226. package/dist/blocks/blockStyle.js.map +1 -1
  227. package/dist/blocks/builtinSchemas.js +6 -0
  228. package/dist/blocks/builtinSchemas.js.map +1 -1
  229. package/dist/blocks/builtins/AgendaRender.d.ts +22 -0
  230. package/dist/blocks/builtins/AgendaRender.js +69 -9
  231. package/dist/blocks/builtins/AgendaRender.js.map +1 -1
  232. package/dist/blocks/builtins/Availability.d.ts +1 -0
  233. package/dist/blocks/builtins/Availability.js +23 -0
  234. package/dist/blocks/builtins/Availability.js.map +1 -0
  235. package/dist/blocks/builtins/AvailabilityRender.d.ts +12 -0
  236. package/dist/blocks/builtins/AvailabilityRender.js +105 -0
  237. package/dist/blocks/builtins/AvailabilityRender.js.map +1 -0
  238. package/dist/blocks/builtins/BeforeAfterRender.js +4 -3
  239. package/dist/blocks/builtins/BeforeAfterRender.js.map +1 -1
  240. package/dist/blocks/builtins/Booking.js +1 -1
  241. package/dist/blocks/builtins/Booking.js.map +1 -1
  242. package/dist/blocks/builtins/BreadcrumbsRender.d.ts +4 -3
  243. package/dist/blocks/builtins/BreadcrumbsRender.js +14 -8
  244. package/dist/blocks/builtins/BreadcrumbsRender.js.map +1 -1
  245. package/dist/blocks/builtins/ColumnsRender.d.ts +1 -1
  246. package/dist/blocks/builtins/ColumnsRender.js +3 -1
  247. package/dist/blocks/builtins/ColumnsRender.js.map +1 -1
  248. package/dist/blocks/builtins/Contact.js +1 -1
  249. package/dist/blocks/builtins/Contact.js.map +1 -1
  250. package/dist/blocks/builtins/ContactRender.d.ts +1 -1
  251. package/dist/blocks/builtins/ContactRender.js +29 -8
  252. package/dist/blocks/builtins/ContactRender.js.map +1 -1
  253. package/dist/blocks/builtins/Cta.js +1 -1
  254. package/dist/blocks/builtins/Cta.js.map +1 -1
  255. package/dist/blocks/builtins/CtaRender.d.ts +1 -1
  256. package/dist/blocks/builtins/CtaRender.js +5 -4
  257. package/dist/blocks/builtins/CtaRender.js.map +1 -1
  258. package/dist/blocks/builtins/Embed.js +1 -1
  259. package/dist/blocks/builtins/Embed.js.map +1 -1
  260. package/dist/blocks/builtins/FormBlock.js +1 -0
  261. package/dist/blocks/builtins/FormBlock.js.map +1 -1
  262. package/dist/blocks/builtins/FormBlockRender.d.ts +6 -0
  263. package/dist/blocks/builtins/FormBlockRender.js +88 -16
  264. package/dist/blocks/builtins/FormBlockRender.js.map +1 -1
  265. package/dist/blocks/builtins/GalleryRender.js +3 -2
  266. package/dist/blocks/builtins/GalleryRender.js.map +1 -1
  267. package/dist/blocks/builtins/Hero.js +1 -1
  268. package/dist/blocks/builtins/Hero.js.map +1 -1
  269. package/dist/blocks/builtins/HeroRender.js +7 -3
  270. package/dist/blocks/builtins/HeroRender.js.map +1 -1
  271. package/dist/blocks/builtins/OpenNowBadge.d.ts +4 -2
  272. package/dist/blocks/builtins/OpenNowBadge.js +6 -6
  273. package/dist/blocks/builtins/OpenNowBadge.js.map +1 -1
  274. package/dist/blocks/builtins/OpeningHoursRender.d.ts +8 -2
  275. package/dist/blocks/builtins/OpeningHoursRender.js +27 -6
  276. package/dist/blocks/builtins/OpeningHoursRender.js.map +1 -1
  277. package/dist/blocks/builtins/PriceList.d.ts +1 -0
  278. package/dist/blocks/builtins/PriceList.js +25 -0
  279. package/dist/blocks/builtins/PriceList.js.map +1 -0
  280. package/dist/blocks/builtins/PriceListRender.d.ts +17 -0
  281. package/dist/blocks/builtins/PriceListRender.js +87 -0
  282. package/dist/blocks/builtins/PriceListRender.js.map +1 -0
  283. package/dist/blocks/builtins/RichTextBlockRender.js +6 -1
  284. package/dist/blocks/builtins/RichTextBlockRender.js.map +1 -1
  285. package/dist/blocks/builtins/SectionHeading.d.ts +1 -0
  286. package/dist/blocks/builtins/SectionHeading.js +14 -0
  287. package/dist/blocks/builtins/SectionHeading.js.map +1 -0
  288. package/dist/blocks/builtins/SectionHeadingRender.d.ts +7 -0
  289. package/dist/blocks/builtins/SectionHeadingRender.js +14 -0
  290. package/dist/blocks/builtins/SectionHeadingRender.js.map +1 -0
  291. package/dist/blocks/builtins/SliderRender.js +3 -2
  292. package/dist/blocks/builtins/SliderRender.js.map +1 -1
  293. package/dist/blocks/builtins/SymbolRef.js +1 -1
  294. package/dist/blocks/builtins/SymbolRef.js.map +1 -1
  295. package/dist/blocks/builtins/TeamRender.js +6 -1
  296. package/dist/blocks/builtins/TeamRender.js.map +1 -1
  297. package/dist/blocks/builtins/Testimonials.js +3 -1
  298. package/dist/blocks/builtins/Testimonials.js.map +1 -1
  299. package/dist/blocks/builtins/TestimonialsRender.js +4 -0
  300. package/dist/blocks/builtins/TestimonialsRender.js.map +1 -1
  301. package/dist/blocks/builtins/WhatsappChatRender.d.ts +1 -1
  302. package/dist/blocks/builtins/WhatsappChatRender.js +1 -1
  303. package/dist/blocks/builtins/WhatsappChatRender.js.map +1 -1
  304. package/dist/blocks/builtins/Widgets.js +2 -2
  305. package/dist/blocks/builtins/Widgets.js.map +1 -1
  306. package/dist/blocks/builtins/WidgetsRender.js +3 -1
  307. package/dist/blocks/builtins/WidgetsRender.js.map +1 -1
  308. package/dist/blocks/builtins/index.d.ts +3 -0
  309. package/dist/blocks/builtins/index.js +6 -0
  310. package/dist/blocks/builtins/index.js.map +1 -1
  311. package/dist/blocks/builtins/lib/autoComplete.d.ts +7 -0
  312. package/dist/blocks/builtins/lib/autoComplete.js +20 -0
  313. package/dist/blocks/builtins/lib/autoComplete.js.map +1 -0
  314. package/dist/blocks/builtins/lib/bookingUrl.d.ts +2 -2
  315. package/dist/blocks/builtins/lib/bookingUrl.js +1 -1
  316. package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -1
  317. package/dist/blocks/builtins/lib/ical.d.ts +24 -0
  318. package/dist/blocks/builtins/lib/ical.js +82 -0
  319. package/dist/blocks/builtins/lib/ical.js.map +1 -0
  320. package/dist/blocks/builtins/lib/vandaag.d.ts +8 -0
  321. package/dist/blocks/builtins/lib/vandaag.js +22 -0
  322. package/dist/blocks/builtins/lib/vandaag.js.map +1 -0
  323. package/dist/blocks/registry.d.ts +6 -0
  324. package/dist/blocks/registry.js.map +1 -1
  325. package/dist/blocks/ui/index.js +1 -0
  326. package/dist/blocks/ui/index.js.map +1 -1
  327. package/dist/components/EditBar.js +2 -4
  328. package/dist/components/EditBar.js.map +1 -1
  329. package/dist/components/News.js +26 -18
  330. package/dist/components/News.js.map +1 -1
  331. package/dist/components/PageView.d.ts +7 -1
  332. package/dist/components/PageView.js +17 -0
  333. package/dist/components/PageView.js.map +1 -1
  334. package/dist/components/ResponsiveImage.js +18 -20
  335. package/dist/components/ResponsiveImage.js.map +1 -1
  336. package/dist/components/site/SiteFooter.d.ts +6 -1
  337. package/dist/components/site/SiteFooter.js +61 -9
  338. package/dist/components/site/SiteFooter.js.map +1 -1
  339. package/dist/components/site/SiteHeader.d.ts +15 -0
  340. package/dist/components/site/SiteHeader.js +70 -0
  341. package/dist/components/site/SiteHeader.js.map +1 -0
  342. package/dist/components/site/SiteNav.d.ts +2 -0
  343. package/dist/components/site/SiteNav.js +29 -5
  344. package/dist/components/site/SiteNav.js.map +1 -1
  345. package/dist/demo/DemoStudio.js +2 -2
  346. package/dist/demo/DemoStudio.js.map +1 -1
  347. package/dist/demo/demoStore.d.ts +13 -0
  348. package/dist/demo/demoStore.js +36 -0
  349. package/dist/demo/demoStore.js.map +1 -1
  350. package/dist/editor/EditorProvider.js +15 -4
  351. package/dist/editor/EditorProvider.js.map +1 -1
  352. package/dist/index.d.ts +4 -1
  353. package/dist/index.js +16 -1
  354. package/dist/index.js.map +1 -1
  355. package/dist/media/ImageContext.d.ts +17 -0
  356. package/dist/media/ImageContext.js +65 -20
  357. package/dist/media/ImageContext.js.map +1 -1
  358. package/dist/media/altInHtml.d.ts +9 -0
  359. package/dist/media/altInHtml.js +17 -0
  360. package/dist/media/altInHtml.js.map +1 -0
  361. package/dist/media/srcset.d.ts +12 -0
  362. package/dist/media/srcset.js +13 -0
  363. package/dist/media/srcset.js.map +1 -0
  364. package/dist/modules/builtins.d.ts +1 -0
  365. package/dist/modules/builtins.js +16 -3
  366. package/dist/modules/builtins.js.map +1 -1
  367. package/dist/modules/shop/blocks/Cart.js +5 -3
  368. package/dist/modules/shop/blocks/Cart.js.map +1 -1
  369. package/dist/modules/shop/blocks/Checkout.js +56 -35
  370. package/dist/modules/shop/blocks/Checkout.js.map +1 -1
  371. package/dist/modules/shop/blocks/Donation.js +4 -4
  372. package/dist/modules/shop/blocks/Donation.js.map +1 -1
  373. package/dist/modules/shop/blocks/ProductDetail.js +19 -3
  374. package/dist/modules/shop/blocks/ProductDetail.js.map +1 -1
  375. package/dist/modules/shop/blocks/ProductGrid.d.ts +3 -1
  376. package/dist/modules/shop/blocks/ProductGrid.js +8 -4
  377. package/dist/modules/shop/blocks/ProductGrid.js.map +1 -1
  378. package/dist/modules/shop/blocks/ShopCategories.js +4 -3
  379. package/dist/modules/shop/blocks/ShopCategories.js.map +1 -1
  380. package/dist/modules/shop/lib.d.ts +4 -0
  381. package/dist/modules/shop/lib.js +14 -0
  382. package/dist/modules/shop/lib.js.map +1 -1
  383. package/dist/modules/shop/settings.d.ts +3 -0
  384. package/dist/modules/shop/settings.js +14 -0
  385. package/dist/modules/shop/settings.js.map +1 -1
  386. package/dist/modules/shop/strings.d.ts +4 -0
  387. package/dist/modules/shop/strings.js +8 -0
  388. package/dist/modules/shop/strings.js.map +1 -1
  389. package/dist/next/envCheck.d.ts +42 -0
  390. package/dist/next/envCheck.js +106 -0
  391. package/dist/next/envCheck.js.map +1 -0
  392. package/dist/next/index.cjs +185 -2
  393. package/dist/next/index.d.ts +2 -0
  394. package/dist/next/index.js +8 -1
  395. package/dist/next/index.js.map +1 -1
  396. package/dist/next/securityHeaders.d.ts +36 -0
  397. package/dist/next/securityHeaders.js +74 -0
  398. package/dist/next/securityHeaders.js.map +1 -0
  399. package/dist/patterns/builtins.d.ts +7 -0
  400. package/dist/patterns/builtins.js +138 -3
  401. package/dist/patterns/builtins.js.map +1 -1
  402. package/dist/releaseNotes.js +140 -0
  403. package/dist/releaseNotes.js.map +1 -1
  404. package/dist/render/PublishedPage.d.ts +2 -1
  405. package/dist/render/PublishedPage.js +10 -4
  406. package/dist/render/PublishedPage.js.map +1 -1
  407. package/dist/schema/blocks.d.ts +470 -0
  408. package/dist/schema/blocks.js +102 -4
  409. package/dist/schema/blocks.js.map +1 -1
  410. package/dist/schema/business.d.ts +117 -0
  411. package/dist/schema/business.js +73 -0
  412. package/dist/schema/business.js.map +1 -0
  413. package/dist/schema/fields.d.ts +2 -1
  414. package/dist/schema/fields.js.map +1 -1
  415. package/dist/schema/forms.d.ts +18 -0
  416. package/dist/schema/forms.js +18 -3
  417. package/dist/schema/forms.js.map +1 -1
  418. package/dist/schema/mail.d.ts +10 -0
  419. package/dist/schema/mail.js +7 -0
  420. package/dist/schema/mail.js.map +1 -1
  421. package/dist/schema/settings.d.ts +101 -0
  422. package/dist/schema/settings.js +24 -3
  423. package/dist/schema/settings.js.map +1 -1
  424. package/dist/schema/shop.d.ts +2 -0
  425. package/dist/schema/shop.js +4 -0
  426. package/dist/schema/shop.js.map +1 -1
  427. package/dist/schema/shopGeld.d.ts +1 -0
  428. package/dist/schema/shopGeld.js +1 -0
  429. package/dist/schema/shopGeld.js.map +1 -1
  430. package/dist/schema/siteConfig.d.ts +68 -1
  431. package/dist/schema/siteConfig.js +7 -2
  432. package/dist/schema/siteConfig.js.map +1 -1
  433. package/dist/server/blockData.d.ts +1 -1
  434. package/dist/server/blockData.js +74 -18
  435. package/dist/server/blockData.js.map +1 -1
  436. package/dist/server/cspRapport.d.ts +20 -0
  437. package/dist/server/cspRapport.js +56 -0
  438. package/dist/server/cspRapport.js.map +1 -0
  439. package/dist/server/fonts.d.ts +3 -0
  440. package/dist/server/fonts.js +39 -0
  441. package/dist/server/fonts.js.map +1 -0
  442. package/dist/server/index.d.ts +3 -0
  443. package/dist/server/index.js +8 -0
  444. package/dist/server/index.js.map +1 -1
  445. package/dist/server/sanitize.js +15 -2
  446. package/dist/server/sanitize.js.map +1 -1
  447. package/dist/settings/useSiteSettings.js +4 -1
  448. package/dist/settings/useSiteSettings.js.map +1 -1
  449. package/dist/starters/starters.d.ts +69 -0
  450. package/dist/starters/starters.js +171 -0
  451. package/dist/starters/starters.js.map +1 -0
  452. package/dist/styles.css +1149 -208
  453. package/dist/theme/color.d.ts +10 -0
  454. package/dist/theme/color.js +17 -1
  455. package/dist/theme/color.js.map +1 -1
  456. package/dist/theme/fontFallback.d.ts +23 -0
  457. package/dist/theme/fontFallback.js +58 -0
  458. package/dist/theme/fontFallback.js.map +1 -0
  459. package/dist/theme/fonts.d.ts +11 -0
  460. package/dist/theme/fonts.js +16 -0
  461. package/dist/theme/fonts.js.map +1 -0
  462. package/dist/version.js +1 -1
  463. package/package.json +6 -4
@@ -1,7 +1,40 @@
1
+ "use client";
1
2
  import { jsx, jsxs } from "react/jsx-runtime";
2
3
  import { jsonLdHtml } from "./jsonld.js";
4
+ import { useVandaag } from "./lib/vandaag.js";
3
5
  import { Heading } from "../ui/index.js";
4
6
  import { icsDataUrl } from "./lib/ics.js";
7
+ import { useMergedSiteConfig } from "../../settings/useSiteSettings.js";
8
+ import { adresRegels } from "../../bedrijf/bedrijf.js";
9
+ function verschuif(waarde, dagen, maanden) {
10
+ const metTijd = waarde.includes("T");
11
+ const d = parseEventDate(waarde);
12
+ if (Number.isNaN(d.getTime())) return waarde;
13
+ d.setMonth(d.getMonth() + maanden);
14
+ d.setDate(d.getDate() + dagen);
15
+ const p = (n) => String(n).padStart(2, "0");
16
+ const datum = `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;
17
+ return metTijd ? `${datum}T${p(d.getHours())}:${p(d.getMinutes())}` : datum;
18
+ }
19
+ function vouwHerhalingenUit(events, vanaf = /* @__PURE__ */ new Date()) {
20
+ const uit = [];
21
+ for (const e of events) {
22
+ uit.push(e);
23
+ if (!e.herhaal || !e.start) continue;
24
+ const start = parseEventDate(e.start);
25
+ if (Number.isNaN(start.getTime())) continue;
26
+ const grens = e.herhaalTot ? parseEventDate(e.herhaalTot) : new Date(vanaf.getFullYear() + 1, vanaf.getMonth(), vanaf.getDate());
27
+ grens.setHours(23, 59, 59, 999);
28
+ for (let n = 1; n <= 60; n++) {
29
+ const dagen = e.herhaal === "wekelijks" ? 7 * n : e.herhaal === "tweewekelijks" ? 14 * n : 0;
30
+ const maanden = e.herhaal === "maandelijks" ? n : 0;
31
+ const volgendeStart = verschuif(e.start, dagen, maanden);
32
+ if (parseEventDate(volgendeStart) > grens) break;
33
+ uit.push({ ...e, start: volgendeStart, ...e.end ? { end: verschuif(e.end, dagen, maanden) } : {} });
34
+ }
35
+ }
36
+ return uit;
37
+ }
5
38
  function parseEventDate(value) {
6
39
  const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
7
40
  if (m) return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
@@ -21,9 +54,9 @@ function formatEventDate(value) {
21
54
  });
22
55
  }
23
56
  function selectAgendaEvents(events, opts = {}) {
24
- let list = (events ?? []).filter((e) => e.title);
25
- if (opts.hidePast) {
26
- const today = /* @__PURE__ */ new Date();
57
+ let list = vouwHerhalingenUit((events ?? []).filter((e) => e.title), opts.vandaag ?? void 0);
58
+ if (opts.hidePast && opts.vandaag !== null) {
59
+ const today = opts.vandaag ? new Date(opts.vandaag) : /* @__PURE__ */ new Date();
27
60
  today.setHours(0, 0, 0, 0);
28
61
  list = list.filter((e) => {
29
62
  const d = parseEventDate(e.end || e.start);
@@ -40,7 +73,17 @@ function selectAgendaEvents(events, opts = {}) {
40
73
  });
41
74
  return typeof opts.limit === "number" ? list.slice(0, opts.limit) : list;
42
75
  }
43
- function eventJsonLd(events) {
76
+ function eventJsonLd(events, bedrijf) {
77
+ const prijsGetal = (p) => {
78
+ if (!p) return void 0;
79
+ if (/gratis|vrij/i.test(p)) return 0;
80
+ const m = /(\d+(?:[.,]\d{1,2})?)/.exec(p.replace(/\s/g, ""));
81
+ return m ? Number(m[1].replace(",", ".")) : void 0;
82
+ };
83
+ const statusUrl = {
84
+ afgelast: "https://schema.org/EventCancelled",
85
+ verplaatst: "https://schema.org/EventRescheduled"
86
+ };
44
87
  return {
45
88
  "@context": "https://schema.org",
46
89
  "@type": "ItemList",
@@ -54,15 +97,27 @@ function eventJsonLd(events) {
54
97
  name: e.title,
55
98
  startDate: e.start,
56
99
  ...e.end ? { endDate: e.end } : {},
57
- location: { "@type": "Place", name: e.location },
100
+ eventStatus: statusUrl[e.status ?? ""] ?? "https://schema.org/EventScheduled",
101
+ eventAttendanceMode: e.status === "online" ? "https://schema.org/OnlineEventAttendanceMode" : "https://schema.org/OfflineEventAttendanceMode",
102
+ location: e.status === "online" ? { "@type": "VirtualLocation", url: e.url || bedrijf?.url || "" } : { "@type": "Place", name: e.location, ...e.address || bedrijf?.address ? { address: e.address || bedrijf?.address } : {} },
103
+ ...e.imageUrl ? { image: [e.imageUrl] } : {},
58
104
  ...e.description ? { description: e.description } : {},
59
- ...e.url ? { url: e.url } : {}
105
+ ...e.url ? { url: e.url } : {},
106
+ ...prijsGetal(e.price) !== void 0 ? { offers: { "@type": "Offer", price: prijsGetal(e.price).toFixed(2), priceCurrency: "EUR", availability: "https://schema.org/InStock", ...e.url ? { url: e.url } : {} } } : {},
107
+ ...bedrijf?.name ? { organizer: { "@type": "Organization", name: bedrijf.name, ...bedrijf.url ? { url: bedrijf.url } : {} } } : {}
60
108
  }
61
109
  }))
62
110
  };
63
111
  }
64
112
  function AgendaRender({ block }) {
65
- const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast });
113
+ const vandaag = useVandaag();
114
+ const cfg = useMergedSiteConfig();
115
+ const organisator = {
116
+ name: cfg.business?.name || cfg.name,
117
+ url: cfg.domain ? `https://${cfg.domain}` : void 0,
118
+ address: adresRegels(cfg.business).join(", ") || void 0
119
+ };
120
+ const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast, vandaag });
66
121
  if (events.length === 0) return null;
67
122
  return /* @__PURE__ */ jsxs("section", { className: "xicms-agenda", children: [
68
123
  block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
@@ -70,7 +125,10 @@ function AgendaRender({ block }) {
70
125
  /* @__PURE__ */ jsx("time", { className: "xicms-agenda__date", dateTime: e.start, children: formatEventDate(e.start) }),
71
126
  /* @__PURE__ */ jsxs("div", { className: "xicms-agenda__body", children: [
72
127
  /* @__PURE__ */ jsx("strong", { className: "xicms-agenda__title", children: e.url ? /* @__PURE__ */ jsx("a", { href: e.url, "data-xicms-edit": `events.${e._i}.title`, children: e.title }) : /* @__PURE__ */ jsx("span", { "data-xicms-edit": `events.${e._i}.title`, children: e.title }) }),
128
+ e.status === "afgelast" && /* @__PURE__ */ jsx("span", { className: "xicms-agenda__status", "data-status": "afgelast", children: "Afgelast" }),
129
+ e.status === "verplaatst" && /* @__PURE__ */ jsx("span", { className: "xicms-agenda__status", "data-status": "verplaatst", children: "Verplaatst" }),
73
130
  e.location && /* @__PURE__ */ jsx("span", { className: "xicms-agenda__location", "data-xicms-edit": `events.${e._i}.location`, children: e.location }),
131
+ e.price && /* @__PURE__ */ jsx("span", { className: "xicms-agenda__prijs", "data-xicms-edit": `events.${e._i}.price`, children: e.price }),
74
132
  e.description && /* @__PURE__ */ jsx("p", { className: "xicms-agenda__desc", "data-xicms-edit": `events.${e._i}.description`, children: e.description }),
75
133
  (() => {
76
134
  const ics = icsDataUrl(e);
@@ -82,15 +140,17 @@ function AgendaRender({ block }) {
82
140
  "script",
83
141
  {
84
142
  type: "application/ld+json",
85
- dangerouslySetInnerHTML: { __html: jsonLdHtml(eventJsonLd(events)) }
143
+ dangerouslySetInnerHTML: { __html: jsonLdHtml(eventJsonLd(events, organisator)) }
86
144
  }
87
145
  )
88
146
  ] });
89
147
  }
90
148
  export {
91
149
  AgendaRender,
150
+ eventJsonLd,
92
151
  formatEventDate,
93
152
  parseEventDate,
94
- selectAgendaEvents
153
+ selectAgendaEvents,
154
+ vouwHerhalingenUit
95
155
  };
96
156
  //# sourceMappingURL=AgendaRender.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/AgendaRender.tsx"],"sourcesContent":["import type { z } from \"zod\";\nimport { jsonLdHtml } from \"./jsonld\";\nimport type { AgendaBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { Heading } from \"../ui\";\nimport { icsDataUrl } from \"./lib/ics\";\n\ntype Agenda = z.infer<typeof AgendaBlockSchema>;\n\n/** Eén event zoals zowel het Agenda-blok als de Agenda-widget het kennen. */\nexport interface AgendaEvent {\n title: string;\n start: string;\n end?: string;\n location?: string;\n description?: string;\n url?: string;\n}\n\n/**\n * Parseert een event-datum als LOKALE tijd. Cruciaal voor datum-zonder-tijd: `new Date(\"2026-08-01\")`\n * is per spec UTC-middernacht, waardoor west-van-UTC-bezoekers \"31 juli\" te zien kregen (en de\n * server/client bij hydration konden verschillen). \"2026-08-01\" is hier gewoon 1 augustus, overal.\n */\nexport function parseEventDate(value: string): Date {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value.trim());\n if (m) return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));\n return new Date(value);\n}\n\n/** Toont een datum leesbaar (nl-NL). Valt terug op de ruwe string bij ongeldige invoer. */\nexport function formatEventDate(value: string): string {\n if (!value) return \"\";\n const d = parseEventDate(value);\n if (Number.isNaN(d.getTime())) return value;\n const hasTime = value.includes(\"T\");\n return d.toLocaleDateString(\"nl-NL\", {\n weekday: \"short\",\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n ...(hasTime ? { hour: \"2-digit\", minute: \"2-digit\" } : {}),\n });\n}\n\n/**\n * Selecteert de te tonen events: filtert lege titels, optioneel verlopen events, sorteert\n * chronologisch (events zonder geldige datum achteraan, in invoervolgorde) en limiteert. Gedeeld\n * door het volwaardige Agenda-blok en de compacte Agenda-widget — zo \"haalt\" de widget alles\n * uit dezelfde logica als de volledige versie.\n */\nexport function selectAgendaEvents<T extends AgendaEvent>(\n events: T[] | undefined,\n opts: { hidePast?: boolean; limit?: number } = {},\n): T[] {\n let list = (events ?? []).filter((e) => e.title);\n if (opts.hidePast) {\n const today = new Date();\n today.setHours(0, 0, 0, 0);\n list = list.filter((e) => {\n const d = parseEventDate(e.end || e.start);\n return Number.isNaN(d.getTime()) || d >= today;\n });\n }\n list = [...list].sort((a, b) => {\n const ta = parseEventDate(a.start).getTime();\n const tb = parseEventDate(b.start).getTime();\n if (Number.isNaN(ta) && Number.isNaN(tb)) return 0;\n if (Number.isNaN(ta)) return 1;\n if (Number.isNaN(tb)) return -1;\n return ta - tb;\n });\n return typeof opts.limit === \"number\" ? list.slice(0, opts.limit) : list;\n}\n\nfunction eventJsonLd(events: Agenda[\"events\"]): Record<string, unknown> {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"ItemList\",\n // Google vereist `location` voor Event-rich-results: events zonder locatie renderen wel op\n // de pagina, maar blijven uit de JSON-LD (voorkomt gegarandeerde Search-Console-errors).\n itemListElement: events\n .filter((e) => e.title && e.start && e.location)\n .map((e, i) => ({\n \"@type\": \"ListItem\",\n position: i + 1,\n item: {\n \"@type\": \"Event\",\n name: e.title,\n startDate: e.start,\n ...(e.end ? { endDate: e.end } : {}),\n location: { \"@type\": \"Place\", name: e.location },\n ...(e.description ? { description: e.description } : {}),\n ...(e.url ? { url: e.url } : {}),\n },\n })),\n };\n}\n\n/** Agenda/evenementen. Server-safe (geen client-state); `hidePast` filtert verlopen events. */\nexport function AgendaRender({ block }: BlockRenderProps<Agenda>) {\n const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast });\n if (events.length === 0) return null;\n\n return (\n <section className=\"xicms-agenda\">\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n <ul className=\"xicms-agenda__list\">\n {events.map((e) => (\n <li key={e._i} className=\"xicms-agenda__item\">\n <time className=\"xicms-agenda__date\" dateTime={e.start}>\n {formatEventDate(e.start)}\n </time>\n <div className=\"xicms-agenda__body\">\n <strong className=\"xicms-agenda__title\">\n {e.url\n ? <a href={e.url} data-xicms-edit={`events.${e._i}.title`}>{e.title}</a>\n : <span data-xicms-edit={`events.${e._i}.title`}>{e.title}</span>}\n </strong>\n {e.location && <span className=\"xicms-agenda__location\" data-xicms-edit={`events.${e._i}.location`}>{e.location}</span>}\n {e.description && <p className=\"xicms-agenda__desc\" data-xicms-edit={`events.${e._i}.description`}>{e.description}</p>}\n {(() => {\n const ics = icsDataUrl(e);\n return ics ? (\n <a className=\"xicms-agenda__ics\" href={ics} download={`${(e.title || \"evenement\").toLowerCase().replace(/\\s+/g, \"-\").slice(0, 40)}.ics`}>\n 📅 Zet in agenda\n </a>\n ) : null;\n })()}\n </div>\n </li>\n ))}\n </ul>\n {block.jsonLd && (\n <script\n type=\"application/ld+json\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: jsonLdHtml(eventJsonLd(events)) }}\n />\n )}\n </section>\n );\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/AgendaRender.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport { jsonLdHtml } from \"./jsonld\";\nimport { useVandaag } from \"./lib/vandaag\";\nimport type { AgendaBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { Heading } from \"../ui\";\nimport { icsDataUrl } from \"./lib/ics\";\nimport { useMergedSiteConfig } from \"../../settings/useSiteSettings\";\nimport { adresRegels } from \"../../bedrijf/bedrijf\";\n\ntype Agenda = z.infer<typeof AgendaBlockSchema>;\n\n/** Eén event zoals zowel het Agenda-blok als de Agenda-widget het kennen. */\nexport interface AgendaEvent {\n title: string;\n start: string;\n end?: string;\n location?: string;\n description?: string;\n url?: string;\n /** 8.15: terugkerend. */\n herhaal?: \"wekelijks\" | \"tweewekelijks\" | \"maandelijks\";\n /** Laatste datum van de herhaling (\"2027-06-30\"); leeg = een jaar vooruit. */\n herhaalTot?: string;\n}\n\n/** ISO-string met dezelfde vorm als het origineel (alleen datum, of datum + tijd), verschoven. */\nfunction verschuif(waarde: string, dagen: number, maanden: number): string {\n const metTijd = waarde.includes(\"T\");\n const d = parseEventDate(waarde);\n if (Number.isNaN(d.getTime())) return waarde;\n d.setMonth(d.getMonth() + maanden);\n d.setDate(d.getDate() + dagen);\n const p = (n: number) => String(n).padStart(2, \"0\");\n const datum = `${d.getFullYear()}-${p(d.getMonth() + 1)}-${p(d.getDate())}`;\n return metTijd ? `${datum}T${p(d.getHours())}:${p(d.getMinutes())}` : datum;\n}\n\n/**\n * Terugkerende activiteiten uitvouwen (8.15): \"elke dinsdag koor\" staat één keer in het beheer en\n * verschijnt op de site als losse data — tot de einddatum, anders een jaar vooruit, en nooit meer\n * dan 60 keer. Elke herhaling houdt de index van het origineel (`_i`), dus bewerken op de pagina\n * past de reeks aan.\n */\nexport function vouwHerhalingenUit<T extends AgendaEvent>(events: T[], vanaf: Date = new Date()): T[] {\n const uit: T[] = [];\n for (const e of events) {\n uit.push(e);\n if (!e.herhaal || !e.start) continue;\n const start = parseEventDate(e.start);\n if (Number.isNaN(start.getTime())) continue;\n const grens = e.herhaalTot ? parseEventDate(e.herhaalTot) : new Date(vanaf.getFullYear() + 1, vanaf.getMonth(), vanaf.getDate());\n grens.setHours(23, 59, 59, 999);\n for (let n = 1; n <= 60; n++) {\n const dagen = e.herhaal === \"wekelijks\" ? 7 * n : e.herhaal === \"tweewekelijks\" ? 14 * n : 0;\n const maanden = e.herhaal === \"maandelijks\" ? n : 0;\n const volgendeStart = verschuif(e.start, dagen, maanden);\n if (parseEventDate(volgendeStart) > grens) break;\n uit.push({ ...e, start: volgendeStart, ...(e.end ? { end: verschuif(e.end, dagen, maanden) } : {}) });\n }\n }\n return uit;\n}\n\n/**\n * Parseert een event-datum als LOKALE tijd. Cruciaal voor datum-zonder-tijd: `new Date(\"2026-08-01\")`\n * is per spec UTC-middernacht, waardoor west-van-UTC-bezoekers \"31 juli\" te zien kregen (en de\n * server/client bij hydration konden verschillen). \"2026-08-01\" is hier gewoon 1 augustus, overal.\n */\nexport function parseEventDate(value: string): Date {\n const m = /^(\\d{4})-(\\d{2})-(\\d{2})$/.exec(value.trim());\n if (m) return new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));\n return new Date(value);\n}\n\n/** Toont een datum leesbaar (nl-NL). Valt terug op de ruwe string bij ongeldige invoer. */\nexport function formatEventDate(value: string): string {\n if (!value) return \"\";\n const d = parseEventDate(value);\n if (Number.isNaN(d.getTime())) return value;\n const hasTime = value.includes(\"T\");\n return d.toLocaleDateString(\"nl-NL\", {\n weekday: \"short\",\n day: \"numeric\",\n month: \"long\",\n year: \"numeric\",\n ...(hasTime ? { hour: \"2-digit\", minute: \"2-digit\" } : {}),\n });\n}\n\n/**\n * Selecteert de te tonen events: filtert lege titels, optioneel verlopen events, sorteert\n * chronologisch (events zonder geldige datum achteraan, in invoervolgorde) en limiteert. Gedeeld\n * door het volwaardige Agenda-blok en de compacte Agenda-widget — zo \"haalt\" de widget alles\n * uit dezelfde logica als de volledige versie.\n */\nexport function selectAgendaEvents<T extends AgendaEvent>(\n events: T[] | undefined,\n opts: { hidePast?: boolean; limit?: number; vandaag?: Date | null } = {},\n): T[] {\n let list = vouwHerhalingenUit((events ?? []).filter((e) => e.title), opts.vandaag ?? undefined);\n // `vandaag: null` = server-render/hydratie (zie useVandaag): dan nog niet op datum filteren.\n if (opts.hidePast && opts.vandaag !== null) {\n const today = opts.vandaag ? new Date(opts.vandaag) : new Date();\n today.setHours(0, 0, 0, 0);\n list = list.filter((e) => {\n const d = parseEventDate(e.end || e.start);\n return Number.isNaN(d.getTime()) || d >= today;\n });\n }\n list = [...list].sort((a, b) => {\n const ta = parseEventDate(a.start).getTime();\n const tb = parseEventDate(b.start).getTime();\n if (Number.isNaN(ta) && Number.isNaN(tb)) return 0;\n if (Number.isNaN(ta)) return 1;\n if (Number.isNaN(tb)) return -1;\n return ta - tb;\n });\n return typeof opts.limit === \"number\" ? list.slice(0, opts.limit) : list;\n}\n\n/**\n * Event-JSON-LD (8.14 vollediger): adres (eigen adres of dat uit het bedrijfsprofiel), afbeelding,\n * prijs, status (afgelast/verplaatst/online) en de organisator. Google vroeg in Search Console bij\n * de oude versie om \"ontbrekend veld: address / image / offers / organizer\".\n */\nexport function eventJsonLd(\n events: Agenda[\"events\"],\n bedrijf?: { name?: string; url?: string; address?: string },\n): Record<string, unknown> {\n const prijsGetal = (p?: string) => {\n if (!p) return undefined;\n if (/gratis|vrij/i.test(p)) return 0;\n const m = /(\\d+(?:[.,]\\d{1,2})?)/.exec(p.replace(/\\s/g, \"\"));\n return m ? Number(m[1].replace(\",\", \".\")) : undefined;\n };\n const statusUrl: Record<string, string> = {\n afgelast: \"https://schema.org/EventCancelled\",\n verplaatst: \"https://schema.org/EventRescheduled\",\n };\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"ItemList\",\n // Google vereist `location` voor Event-rich-results: events zonder locatie renderen wel op\n // de pagina, maar blijven uit de JSON-LD (voorkomt gegarandeerde Search-Console-errors).\n itemListElement: events\n .filter((e) => e.title && e.start && e.location)\n .map((e, i) => ({\n \"@type\": \"ListItem\",\n position: i + 1,\n item: {\n \"@type\": \"Event\",\n name: e.title,\n startDate: e.start,\n ...(e.end ? { endDate: e.end } : {}),\n eventStatus: statusUrl[e.status ?? \"\"] ?? \"https://schema.org/EventScheduled\",\n eventAttendanceMode: e.status === \"online\" ? \"https://schema.org/OnlineEventAttendanceMode\" : \"https://schema.org/OfflineEventAttendanceMode\",\n location:\n e.status === \"online\"\n ? { \"@type\": \"VirtualLocation\", url: e.url || bedrijf?.url || \"\" }\n : { \"@type\": \"Place\", name: e.location, ...((e.address || bedrijf?.address) ? { address: e.address || bedrijf?.address } : {}) },\n ...(e.imageUrl ? { image: [e.imageUrl] } : {}),\n ...(e.description ? { description: e.description } : {}),\n ...(e.url ? { url: e.url } : {}),\n ...(prijsGetal(e.price) !== undefined\n ? { offers: { \"@type\": \"Offer\", price: prijsGetal(e.price)!.toFixed(2), priceCurrency: \"EUR\", availability: \"https://schema.org/InStock\", ...(e.url ? { url: e.url } : {}) } }\n : {}),\n ...(bedrijf?.name ? { organizer: { \"@type\": \"Organization\", name: bedrijf.name, ...(bedrijf.url ? { url: bedrijf.url } : {}) } } : {}),\n },\n })),\n };\n}\n\n/** Agenda/evenementen. Server-safe (geen client-state); `hidePast` filtert verlopen events. */\nexport function AgendaRender({ block }: BlockRenderProps<Agenda>) {\n // Client-component (8.1): \"verlopen verbergen\" filtert op de datum van de bezoeker, en dat moet\n // hydratie-veilig (zie useVandaag) — de server-HTML kan een dag oud zijn.\n const vandaag = useVandaag();\n const cfg = useMergedSiteConfig();\n const organisator = {\n name: cfg.business?.name || cfg.name,\n url: cfg.domain ? `https://${cfg.domain}` : undefined,\n address: adresRegels(cfg.business).join(\", \") || undefined,\n };\n const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast, vandaag });\n if (events.length === 0) return null;\n\n return (\n <section className=\"xicms-agenda\">\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n <ul className=\"xicms-agenda__list\">\n {events.map((e) => (\n <li key={e._i} className=\"xicms-agenda__item\">\n <time className=\"xicms-agenda__date\" dateTime={e.start}>\n {formatEventDate(e.start)}\n </time>\n <div className=\"xicms-agenda__body\">\n <strong className=\"xicms-agenda__title\">\n {e.url\n ? <a href={e.url} data-xicms-edit={`events.${e._i}.title`}>{e.title}</a>\n : <span data-xicms-edit={`events.${e._i}.title`}>{e.title}</span>}\n </strong>\n {e.status === \"afgelast\" && <span className=\"xicms-agenda__status\" data-status=\"afgelast\">Afgelast</span>}\n {e.status === \"verplaatst\" && <span className=\"xicms-agenda__status\" data-status=\"verplaatst\">Verplaatst</span>}\n {e.location && <span className=\"xicms-agenda__location\" data-xicms-edit={`events.${e._i}.location`}>{e.location}</span>}\n {e.price && <span className=\"xicms-agenda__prijs\" data-xicms-edit={`events.${e._i}.price`}>{e.price}</span>}\n {e.description && <p className=\"xicms-agenda__desc\" data-xicms-edit={`events.${e._i}.description`}>{e.description}</p>}\n {(() => {\n const ics = icsDataUrl(e);\n return ics ? (\n <a className=\"xicms-agenda__ics\" href={ics} download={`${(e.title || \"evenement\").toLowerCase().replace(/\\s+/g, \"-\").slice(0, 40)}.ics`}>\n 📅 Zet in agenda\n </a>\n ) : null;\n })()}\n </div>\n </li>\n ))}\n </ul>\n {block.jsonLd && (\n <script\n type=\"application/ld+json\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: jsonLdHtml(eventJsonLd(events, organisator)) }}\n />\n )}\n </section>\n );\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1 @@
1
+ export declare const availabilityBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;
@@ -0,0 +1,23 @@
1
+ import dynamic from "next/dynamic";
2
+ import { defineBlock } from "../registry.js";
3
+ const availabilityBlock = defineBlock({
4
+ type: "availability",
5
+ Render: dynamic(() => import("./AvailabilityRender.js").then((m) => m.AvailabilityRender)),
6
+ label: "Beschikbaarheid",
7
+ icon: "\u{1F4C5}",
8
+ fields: { "units.icalUrl": { type: "url", hint: "De iCal-export van je boekingssysteem (Airbnb, Booking.com, availcalendar \u2026): begint met https:// of webcal://." } },
9
+ defaults: () => ({
10
+ heading: "Beschikbaarheid",
11
+ units: [{ label: "Ons verblijf", icalUrl: "" }],
12
+ months: 4,
13
+ minNights: 2,
14
+ requestPath: "/contact",
15
+ requestLabel: "Aanvragen",
16
+ periodField: "verblijf",
17
+ unitField: "accommodatie"
18
+ })
19
+ });
20
+ export {
21
+ availabilityBlock
22
+ };
23
+ //# sourceMappingURL=Availability.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Availability.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const availabilityBlock = defineBlock({\n type: \"availability\",\n Render: dynamic(() => import(\"./AvailabilityRender\").then((m) => m.AvailabilityRender)),\n label: \"Beschikbaarheid\",\n icon: \"📅\",\n fields: { \"units.icalUrl\": { type: \"url\", hint: \"De iCal-export van je boekingssysteem (Airbnb, Booking.com, availcalendar …): begint met https:// of webcal://.\" } },\n defaults: () => ({\n heading: \"Beschikbaarheid\",\n units: [{ label: \"Ons verblijf\", icalUrl: \"\" }],\n months: 4,\n minNights: 2,\n requestPath: \"/contact\",\n requestLabel: \"Aanvragen\",\n periodField: \"verblijf\",\n unitField: \"accommodatie\",\n }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,oBAAoB,YAAY;AAAA,EAC3C,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,sBAAsB,EAAE,KAAK,CAAC,MAAM,EAAE,kBAAkB,CAAC;AAAA,EACtF,OAAO;AAAA,EACP,MAAM;AAAA,EACN,QAAQ,EAAE,iBAAiB,EAAE,MAAM,OAAO,MAAM,uHAAkH,EAAE;AAAA,EACpK,UAAU,OAAO;AAAA,IACf,SAAS;AAAA,IACT,OAAO,CAAC,EAAE,OAAO,gBAAgB,SAAS,GAAG,CAAC;AAAA,IAC9C,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,aAAa;AAAA,IACb,cAAc;AAAA,IACd,aAAa;AAAA,IACb,WAAW;AAAA,EACb;AACF,CAAC;","names":[]}
@@ -0,0 +1,12 @@
1
+ import type { z } from "zod";
2
+ import type { AvailabilityBlockSchema } from "../../schema/blocks.js";
3
+ import type { BlockRenderProps } from "../registry.js";
4
+ type Beschikbaarheid = z.infer<typeof AvailabilityBlockSchema>;
5
+ /**
6
+ * Beschikbaarheidskalender (8.15). De bezette nachten komen van de server (seed "beschikbaarheid",
7
+ * per iCal-link, een uur gecachet); zonder seed toont de kalender alles als vrij met een eerlijke
8
+ * melding. Klik een aankomstdag en een vertrekdag; "Aanvragen" opent het formulier met
9
+ * `?verblijf=van/tot&accommodatie=…`, dat de velden "Periode" en "Verborgen" (8.14) invullen.
10
+ */
11
+ export declare function AvailabilityRender({ block, mode }: BlockRenderProps<Beschikbaarheid>): import("react").JSX.Element | null;
12
+ export {};
@@ -0,0 +1,105 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useMemo, useState } from "react";
4
+ import { useBlockData } from "../context.js";
5
+ import { Btn, Heading } from "../ui/index.js";
6
+ import { isBezet, maandRaster, periodeVrij } from "./lib/ical.js";
7
+ import { useVandaag } from "./lib/vandaag.js";
8
+ import { isoDatum } from "../../bedrijf/bedrijf.js";
9
+ const DAGEN = ["ma", "di", "wo", "do", "vr", "za", "zo"];
10
+ function nachten(van, tot) {
11
+ return Math.round((Date.parse(tot) - Date.parse(van)) / 864e5);
12
+ }
13
+ function mooi(iso) {
14
+ const [j, m, d] = iso.split("-").map(Number);
15
+ return new Date(j, m - 1, d).toLocaleDateString("nl-NL", { weekday: "short", day: "numeric", month: "short" });
16
+ }
17
+ function AvailabilityRender({ block, mode }) {
18
+ const seed = useBlockData("beschikbaarheid");
19
+ const units = (block.units ?? []).filter((u) => u.label || u.icalUrl);
20
+ const [actief, setActief] = useState(0);
21
+ const [van, setVan] = useState(null);
22
+ const [tot, setTot] = useState(null);
23
+ const vandaagDatum = useVandaag();
24
+ const vandaagIso = vandaagDatum ? isoDatum(vandaagDatum) : null;
25
+ const unit = units[Math.min(actief, Math.max(units.length - 1, 0))];
26
+ const bezet = unit?.icalUrl ? seed?.[unit.icalUrl] : void 0;
27
+ const onbekend = Boolean(unit?.icalUrl) && !Array.isArray(bezet);
28
+ const maanden = useMemo(() => {
29
+ const basis = vandaagDatum ?? /* @__PURE__ */ new Date();
30
+ return Array.from({ length: block.months ?? 4 }, (_, i) => {
31
+ const d = new Date(basis.getFullYear(), basis.getMonth() + i, 1);
32
+ return { jaar: d.getFullYear(), maand: d.getMonth(), naam: d.toLocaleDateString("nl-NL", { month: "long", year: "numeric" }) };
33
+ });
34
+ }, [vandaagDatum, block.months]);
35
+ if (units.length === 0) {
36
+ return mode === "preview" ? /* @__PURE__ */ jsx("p", { className: "xicms-ve__hint", children: "Beschikbaarheid: voeg een accommodatie toe met de iCal-link uit je boekingssysteem." }) : null;
37
+ }
38
+ const lijst = Array.isArray(bezet) ? bezet : [];
39
+ const vandaag = vandaagIso ?? "0000-00-00";
40
+ const kies = (dag) => {
41
+ if (!van || tot || dag <= van) {
42
+ setVan(isBezet(dag, lijst) ? null : dag);
43
+ setTot(null);
44
+ return;
45
+ }
46
+ setTot(dag);
47
+ };
48
+ const geldig = van && tot && periodeVrij(van, tot, lijst) && nachten(van, tot) >= (block.minNights ?? 1);
49
+ const link = van && tot ? `${block.requestPath || "/contact"}?${encodeURIComponent(block.periodField || "verblijf")}=${van}/${tot}&${encodeURIComponent(block.unitField || "accommodatie")}=${encodeURIComponent(unit?.label ?? "")}` : void 0;
50
+ return /* @__PURE__ */ jsxs("section", { className: "xicms-beschikbaar", children: [
51
+ block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
52
+ block.intro && /* @__PURE__ */ jsx("p", { className: "xicms-beschikbaar__intro", "data-xicms-edit": "intro", children: block.intro }),
53
+ units.length > 1 && /* @__PURE__ */ jsx("div", { className: "xicms-beschikbaar__tabs", role: "tablist", "aria-label": "Accommodatie", children: units.map((u, i) => /* @__PURE__ */ jsx("button", { type: "button", role: "tab", "aria-selected": i === actief, onClick: () => {
54
+ setActief(i);
55
+ setVan(null);
56
+ setTot(null);
57
+ }, children: u.label || `Accommodatie ${i + 1}` }, i)) }),
58
+ unit?.note && /* @__PURE__ */ jsx("p", { className: "xicms-beschikbaar__noot", children: unit.note }),
59
+ onbekend && /* @__PURE__ */ jsx("p", { className: "xicms-beschikbaar__melding", role: "status", children: "De actuele bezetting kon niet worden geladen. Vraag gerust aan \u2014 we laten snel weten of het past." }),
60
+ /* @__PURE__ */ jsx("div", { className: "xicms-beschikbaar__maanden", children: maanden.map((m) => /* @__PURE__ */ jsxs("div", { className: "xicms-beschikbaar__maand", children: [
61
+ /* @__PURE__ */ jsx("p", { className: "xicms-beschikbaar__maandnaam", children: m.naam }),
62
+ /* @__PURE__ */ jsxs("table", { children: [
63
+ /* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { children: DAGEN.map((d) => /* @__PURE__ */ jsx("th", { scope: "col", children: d }, d)) }) }),
64
+ /* @__PURE__ */ jsx("tbody", { children: maandRaster(m.jaar, m.maand).map((week, wi) => /* @__PURE__ */ jsx("tr", { children: week.map((dag, di) => {
65
+ if (!dag) return /* @__PURE__ */ jsx("td", {}, di);
66
+ const verleden = dag < vandaag;
67
+ const vol = isBezet(dag, lijst);
68
+ const gekozen = van && (dag === van || tot && dag >= van && dag < tot || dag === tot);
69
+ return /* @__PURE__ */ jsx("td", { children: /* @__PURE__ */ jsx(
70
+ "button",
71
+ {
72
+ type: "button",
73
+ disabled: verleden || vol && !(van && !tot && dag > van),
74
+ "data-status": verleden ? "voorbij" : vol ? "bezet" : "vrij",
75
+ "data-gekozen": gekozen ? "1" : void 0,
76
+ "aria-label": `${mooi(dag)}${vol ? ", bezet" : ", vrij"}`,
77
+ "aria-pressed": Boolean(gekozen),
78
+ onClick: () => kies(dag),
79
+ children: Number(dag.slice(8))
80
+ }
81
+ ) }, di);
82
+ }) }, wi)) })
83
+ ] })
84
+ ] }, `${m.jaar}-${m.maand}`)) }),
85
+ /* @__PURE__ */ jsxs("div", { className: "xicms-beschikbaar__voet", children: [
86
+ /* @__PURE__ */ jsxs("span", { className: "xicms-beschikbaar__legenda", children: [
87
+ /* @__PURE__ */ jsx("i", { "data-status": "vrij" }),
88
+ " vrij ",
89
+ /* @__PURE__ */ jsx("i", { "data-status": "bezet" }),
90
+ " bezet"
91
+ ] }),
92
+ /* @__PURE__ */ jsxs("span", { className: "xicms-beschikbaar__keuze", "aria-live": "polite", children: [
93
+ !van && "Kies je aankomstdag.",
94
+ van && !tot && `Aankomst ${mooi(van)} \u2014 kies je vertrekdag.`,
95
+ van && tot && !geldig && (periodeVrij(van, tot, lijst) ? `Minimaal ${block.minNights} ${block.minNights === 1 ? "nacht" : "nachten"}.` : "In deze periode is het al bezet. Kies andere data."),
96
+ van && tot && geldig && `${mooi(van)} \u2013 ${mooi(tot)} \xB7 ${nachten(van, tot)} ${nachten(van, tot) === 1 ? "nacht" : "nachten"}`
97
+ ] }),
98
+ geldig && link && /* @__PURE__ */ jsx(Btn, { label: block.requestLabel || "Aanvragen", href: link, size: "md" })
99
+ ] })
100
+ ] });
101
+ }
102
+ export {
103
+ AvailabilityRender
104
+ };
105
+ //# sourceMappingURL=AvailabilityRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/AvailabilityRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useMemo, useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { AvailabilityBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { useBlockData } from \"../context\";\nimport { Btn, Heading } from \"../ui\";\nimport { isBezet, maandRaster, periodeVrij, type Bezet } from \"./lib/ical\";\nimport { useVandaag } from \"./lib/vandaag\";\nimport { isoDatum } from \"../../bedrijf/bedrijf\";\n\ntype Beschikbaarheid = z.infer<typeof AvailabilityBlockSchema>;\n\nconst DAGEN = [\"ma\", \"di\", \"wo\", \"do\", \"vr\", \"za\", \"zo\"];\n\nfunction nachten(van: string, tot: string): number {\n return Math.round((Date.parse(tot) - Date.parse(van)) / 86_400_000);\n}\n\nfunction mooi(iso: string): string {\n const [j, m, d] = iso.split(\"-\").map(Number);\n return new Date(j, m - 1, d).toLocaleDateString(\"nl-NL\", { weekday: \"short\", day: \"numeric\", month: \"short\" });\n}\n\n/**\n * Beschikbaarheidskalender (8.15). De bezette nachten komen van de server (seed \"beschikbaarheid\",\n * per iCal-link, een uur gecachet); zonder seed toont de kalender alles als vrij met een eerlijke\n * melding. Klik een aankomstdag en een vertrekdag; \"Aanvragen\" opent het formulier met\n * `?verblijf=van/tot&accommodatie=…`, dat de velden \"Periode\" en \"Verborgen\" (8.14) invullen.\n */\nexport function AvailabilityRender({ block, mode }: BlockRenderProps<Beschikbaarheid>) {\n const seed = useBlockData<Record<string, Bezet[] | null>>(\"beschikbaarheid\");\n const units = (block.units ?? []).filter((u) => u.label || u.icalUrl);\n const [actief, setActief] = useState(0);\n const [van, setVan] = useState<string | null>(null);\n const [tot, setTot] = useState<string | null>(null);\n // Null tijdens server-render en hydratie (zie useVandaag): dan nog geen dagen als \"voorbij\".\n const vandaagDatum = useVandaag();\n const vandaagIso = vandaagDatum ? isoDatum(vandaagDatum) : null;\n const unit = units[Math.min(actief, Math.max(units.length - 1, 0))];\n const bezet = unit?.icalUrl ? seed?.[unit.icalUrl] : undefined;\n const onbekend = Boolean(unit?.icalUrl) && !Array.isArray(bezet);\n\n const maanden = useMemo(() => {\n const basis = vandaagDatum ?? new Date();\n return Array.from({ length: block.months ?? 4 }, (_, i) => {\n const d = new Date(basis.getFullYear(), basis.getMonth() + i, 1);\n return { jaar: d.getFullYear(), maand: d.getMonth(), naam: d.toLocaleDateString(\"nl-NL\", { month: \"long\", year: \"numeric\" }) };\n });\n }, [vandaagDatum, block.months]);\n\n if (units.length === 0) {\n return mode === \"preview\" ? <p className=\"xicms-ve__hint\">Beschikbaarheid: voeg een accommodatie toe met de iCal-link uit je boekingssysteem.</p> : null;\n }\n\n const lijst = Array.isArray(bezet) ? bezet : [];\n const vandaag = vandaagIso ?? \"0000-00-00\";\n const kies = (dag: string) => {\n if (!van || tot || dag <= van) {\n setVan(isBezet(dag, lijst) ? null : dag);\n setTot(null);\n return;\n }\n setTot(dag);\n };\n const geldig = van && tot && periodeVrij(van, tot, lijst) && nachten(van, tot) >= (block.minNights ?? 1);\n const link = van && tot\n ? `${block.requestPath || \"/contact\"}?${encodeURIComponent(block.periodField || \"verblijf\")}=${van}/${tot}&${encodeURIComponent(block.unitField || \"accommodatie\")}=${encodeURIComponent(unit?.label ?? \"\")}`\n : undefined;\n\n return (\n <section className=\"xicms-beschikbaar\">\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n {block.intro && <p className=\"xicms-beschikbaar__intro\" data-xicms-edit=\"intro\">{block.intro}</p>}\n {units.length > 1 && (\n <div className=\"xicms-beschikbaar__tabs\" role=\"tablist\" aria-label=\"Accommodatie\">\n {units.map((u, i) => (\n <button key={i} type=\"button\" role=\"tab\" aria-selected={i === actief} onClick={() => { setActief(i); setVan(null); setTot(null); }}>\n {u.label || `Accommodatie ${i + 1}`}\n </button>\n ))}\n </div>\n )}\n {unit?.note && <p className=\"xicms-beschikbaar__noot\">{unit.note}</p>}\n {onbekend && (\n <p className=\"xicms-beschikbaar__melding\" role=\"status\">\n De actuele bezetting kon niet worden geladen. Vraag gerust aan — we laten snel weten of het past.\n </p>\n )}\n <div className=\"xicms-beschikbaar__maanden\">\n {maanden.map((m) => (\n <div key={`${m.jaar}-${m.maand}`} className=\"xicms-beschikbaar__maand\">\n <p className=\"xicms-beschikbaar__maandnaam\">{m.naam}</p>\n <table>\n <thead>\n <tr>{DAGEN.map((d) => <th key={d} scope=\"col\">{d}</th>)}</tr>\n </thead>\n <tbody>\n {maandRaster(m.jaar, m.maand).map((week, wi) => (\n <tr key={wi}>\n {week.map((dag, di) => {\n if (!dag) return <td key={di} />;\n const verleden = dag < vandaag;\n const vol = isBezet(dag, lijst);\n const gekozen = van && (dag === van || (tot && dag >= van && dag < tot) || dag === tot);\n return (\n <td key={di}>\n <button\n type=\"button\"\n disabled={verleden || (vol && !(van && !tot && dag > van))}\n data-status={verleden ? \"voorbij\" : vol ? \"bezet\" : \"vrij\"}\n data-gekozen={gekozen ? \"1\" : undefined}\n aria-label={`${mooi(dag)}${vol ? \", bezet\" : \", vrij\"}`}\n aria-pressed={Boolean(gekozen)}\n onClick={() => kies(dag)}\n >\n {Number(dag.slice(8))}\n </button>\n </td>\n );\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n ))}\n </div>\n <div className=\"xicms-beschikbaar__voet\">\n <span className=\"xicms-beschikbaar__legenda\"><i data-status=\"vrij\" /> vrij <i data-status=\"bezet\" /> bezet</span>\n <span className=\"xicms-beschikbaar__keuze\" aria-live=\"polite\">\n {!van && \"Kies je aankomstdag.\"}\n {van && !tot && `Aankomst ${mooi(van)} — kies je vertrekdag.`}\n {van && tot && !geldig && (periodeVrij(van, tot, lijst)\n ? `Minimaal ${block.minNights} ${block.minNights === 1 ? \"nacht\" : \"nachten\"}.`\n : \"In deze periode is het al bezet. Kies andere data.\")}\n {van && tot && geldig && `${mooi(van)} – ${mooi(tot)} · ${nachten(van, tot)} ${nachten(van, tot) === 1 ? \"nacht\" : \"nachten\"}`}\n </span>\n {geldig && link && <Btn label={block.requestLabel || \"Aanvragen\"} href={link} size=\"md\" />}\n </div>\n </section>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,14 +1,15 @@
1
1
  "use client";
2
2
  import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useState } from "react";
4
+ import { SeedImg } from "../../media/ImageContext.js";
4
5
  function BeforeAfterRender({ block }) {
5
6
  const [pos, setPos] = useState(50);
6
7
  if (!block.beforeUrl || !block.afterUrl) return null;
7
- return /* @__PURE__ */ jsxs("figure", { className: "xicms-beforeafter", style: { aspectRatio: block.aspectRatio.replace("/", " / ") }, children: [
8
+ return /* @__PURE__ */ jsxs("figure", { className: "xicms-beforeafter", style: { aspectRatio: (block.aspectRatio ?? "4/3").replace("/", " / ") }, children: [
8
9
  block.heading && /* @__PURE__ */ jsx("figcaption", { className: "xicms-beforeafter__heading", "data-xicms-edit": "heading", children: block.heading }),
9
10
  /* @__PURE__ */ jsxs("div", { className: "xicms-beforeafter__stage", children: [
10
- /* @__PURE__ */ jsx("img", { className: "xicms-beforeafter__img", src: block.beforeUrl, alt: block.alt || block.beforeLabel, loading: "lazy" }),
11
- /* @__PURE__ */ jsx("div", { className: "xicms-beforeafter__clip", style: { clipPath: `inset(0 0 0 ${pos}%)` }, "aria-hidden": true, children: /* @__PURE__ */ jsx("img", { className: "xicms-beforeafter__img", src: block.afterUrl, alt: "", loading: "lazy" }) }),
11
+ /* @__PURE__ */ jsx(SeedImg, { className: "xicms-beforeafter__img", src: block.beforeUrl, alt: block.alt || block.beforeLabel, sizes: "(max-width: 900px) 100vw, 900px" }),
12
+ /* @__PURE__ */ jsx("div", { className: "xicms-beforeafter__clip", style: { clipPath: `inset(0 0 0 ${pos}%)` }, "aria-hidden": true, children: /* @__PURE__ */ jsx(SeedImg, { className: "xicms-beforeafter__img", src: block.afterUrl, alt: "", sizes: "(max-width: 900px) 100vw, 900px" }) }),
12
13
  /* @__PURE__ */ jsx("div", { className: "xicms-beforeafter__divider", style: { left: `${pos}%` }, "aria-hidden": true, children: /* @__PURE__ */ jsx("span", { className: "xicms-beforeafter__handle", children: "\u27E8\u27E9" }) }),
13
14
  /* @__PURE__ */ jsx("span", { className: "xicms-beforeafter__badge xicms-beforeafter__badge--before", "data-xicms-edit": "beforeLabel", children: block.beforeLabel }),
14
15
  /* @__PURE__ */ jsx("span", { className: "xicms-beforeafter__badge xicms-beforeafter__badge--after", "data-xicms-edit": "afterLabel", children: block.afterLabel }),
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/BeforeAfterRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { BeforeAfterBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\n\ntype BeforeAfter = z.infer<typeof BeforeAfterBlockSchema>;\n\n/**\n * Voor/na-vergelijker: het \"na\"-beeld wordt geclipt op de sleppositie. De greep is een échte\n * range-input (over de hele breedte, transparant) — slepen, klikken én pijltjestoetsen werken\n * daarmee gratis en toegankelijk (aria-label + waarde in %).\n */\nexport function BeforeAfterRender({ block }: BlockRenderProps<BeforeAfter>) {\n const [pos, setPos] = useState(50);\n if (!block.beforeUrl || !block.afterUrl) return null;\n return (\n <figure className=\"xicms-beforeafter\" style={{ aspectRatio: block.aspectRatio.replace(\"/\", \" / \") }}>\n {block.heading && <figcaption className=\"xicms-beforeafter__heading\" data-xicms-edit=\"heading\">{block.heading}</figcaption>}\n <div className=\"xicms-beforeafter__stage\">\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img className=\"xicms-beforeafter__img\" src={block.beforeUrl} alt={block.alt || block.beforeLabel} loading=\"lazy\" />\n <div className=\"xicms-beforeafter__clip\" style={{ clipPath: `inset(0 0 0 ${pos}%)` }} aria-hidden>\n {/* eslint-disable-next-line @next/next/no-img-element */}\n <img className=\"xicms-beforeafter__img\" src={block.afterUrl} alt=\"\" loading=\"lazy\" />\n </div>\n <div className=\"xicms-beforeafter__divider\" style={{ left: `${pos}%` }} aria-hidden>\n <span className=\"xicms-beforeafter__handle\">⟨⟩</span>\n </div>\n <span className=\"xicms-beforeafter__badge xicms-beforeafter__badge--before\" data-xicms-edit=\"beforeLabel\">{block.beforeLabel}</span>\n <span className=\"xicms-beforeafter__badge xicms-beforeafter__badge--after\" data-xicms-edit=\"afterLabel\">{block.afterLabel}</span>\n <input\n className=\"xicms-beforeafter__range\"\n type=\"range\"\n min={0}\n max={100}\n value={pos}\n onChange={(e) => setPos(Number(e.target.value))}\n aria-label={`Vergelijk ${block.beforeLabel} en ${block.afterLabel}`}\n aria-valuetext={`${pos}% ${block.afterLabel}`}\n />\n </div>\n </figure>\n );\n}\n"],"mappings":";AAmBwB,cAClB,YADkB;AAjBxB,SAAS,gBAAgB;AAYlB,SAAS,kBAAkB,EAAE,MAAM,GAAkC;AAC1E,QAAM,CAAC,KAAK,MAAM,IAAI,SAAS,EAAE;AACjC,MAAI,CAAC,MAAM,aAAa,CAAC,MAAM,SAAU,QAAO;AAChD,SACE,qBAAC,YAAO,WAAU,qBAAoB,OAAO,EAAE,aAAa,MAAM,YAAY,QAAQ,KAAK,KAAK,EAAE,GAC/F;AAAA,UAAM,WAAW,oBAAC,gBAAW,WAAU,8BAA6B,mBAAgB,WAAW,gBAAM,SAAQ;AAAA,IAC9G,qBAAC,SAAI,WAAU,4BAEb;AAAA,0BAAC,SAAI,WAAU,0BAAyB,KAAK,MAAM,WAAW,KAAK,MAAM,OAAO,MAAM,aAAa,SAAQ,QAAO;AAAA,MAClH,oBAAC,SAAI,WAAU,2BAA0B,OAAO,EAAE,UAAU,eAAe,GAAG,KAAK,GAAG,eAAW,MAE/F,8BAAC,SAAI,WAAU,0BAAyB,KAAK,MAAM,UAAU,KAAI,IAAG,SAAQ,QAAO,GACrF;AAAA,MACA,oBAAC,SAAI,WAAU,8BAA6B,OAAO,EAAE,MAAM,GAAG,GAAG,IAAI,GAAG,eAAW,MACjF,8BAAC,UAAK,WAAU,6BAA4B,0BAAE,GAChD;AAAA,MACA,oBAAC,UAAK,WAAU,6DAA4D,mBAAgB,eAAe,gBAAM,aAAY;AAAA,MAC7H,oBAAC,UAAK,WAAU,4DAA2D,mBAAgB,cAAc,gBAAM,YAAW;AAAA,MAC1H;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,OAAO,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,UAC9C,cAAY,aAAa,MAAM,WAAW,OAAO,MAAM,UAAU;AAAA,UACjE,kBAAgB,GAAG,GAAG,KAAK,MAAM,UAAU;AAAA;AAAA,MAC7C;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/BeforeAfterRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { BeforeAfterBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { SeedImg } from \"../../media/ImageContext\";\n\ntype BeforeAfter = z.infer<typeof BeforeAfterBlockSchema>;\n\n/**\n * Voor/na-vergelijker: het \"na\"-beeld wordt geclipt op de sleppositie. De greep is een échte\n * range-input (over de hele breedte, transparant) — slepen, klikken én pijltjestoetsen werken\n * daarmee gratis en toegankelijk (aria-label + waarde in %).\n */\nexport function BeforeAfterRender({ block }: BlockRenderProps<BeforeAfter>) {\n const [pos, setPos] = useState(50);\n if (!block.beforeUrl || !block.afterUrl) return null;\n return (\n <figure className=\"xicms-beforeafter\" style={{ aspectRatio: (block.aspectRatio ?? \"4/3\").replace(\"/\", \" / \") }}>\n {block.heading && <figcaption className=\"xicms-beforeafter__heading\" data-xicms-edit=\"heading\">{block.heading}</figcaption>}\n <div className=\"xicms-beforeafter__stage\">\n <SeedImg className=\"xicms-beforeafter__img\" src={block.beforeUrl} alt={block.alt || block.beforeLabel} sizes=\"(max-width: 900px) 100vw, 900px\" />\n <div className=\"xicms-beforeafter__clip\" style={{ clipPath: `inset(0 0 0 ${pos}%)` }} aria-hidden>\n <SeedImg className=\"xicms-beforeafter__img\" src={block.afterUrl} alt=\"\" sizes=\"(max-width: 900px) 100vw, 900px\" />\n </div>\n <div className=\"xicms-beforeafter__divider\" style={{ left: `${pos}%` }} aria-hidden>\n <span className=\"xicms-beforeafter__handle\">⟨⟩</span>\n </div>\n <span className=\"xicms-beforeafter__badge xicms-beforeafter__badge--before\" data-xicms-edit=\"beforeLabel\">{block.beforeLabel}</span>\n <span className=\"xicms-beforeafter__badge xicms-beforeafter__badge--after\" data-xicms-edit=\"afterLabel\">{block.afterLabel}</span>\n <input\n className=\"xicms-beforeafter__range\"\n type=\"range\"\n min={0}\n max={100}\n value={pos}\n onChange={(e) => setPos(Number(e.target.value))}\n aria-label={`Vergelijk ${block.beforeLabel} en ${block.afterLabel}`}\n aria-valuetext={`${pos}% ${block.afterLabel}`}\n />\n </div>\n </figure>\n );\n}\n"],"mappings":";AAoBwB,cAClB,YADkB;AAlBxB,SAAS,gBAAgB;AAIzB,SAAS,eAAe;AASjB,SAAS,kBAAkB,EAAE,MAAM,GAAkC;AAC1E,QAAM,CAAC,KAAK,MAAM,IAAI,SAAS,EAAE;AACjC,MAAI,CAAC,MAAM,aAAa,CAAC,MAAM,SAAU,QAAO;AAChD,SACE,qBAAC,YAAO,WAAU,qBAAoB,OAAO,EAAE,cAAc,MAAM,eAAe,OAAO,QAAQ,KAAK,KAAK,EAAE,GAC1G;AAAA,UAAM,WAAW,oBAAC,gBAAW,WAAU,8BAA6B,mBAAgB,WAAW,gBAAM,SAAQ;AAAA,IAC9G,qBAAC,SAAI,WAAU,4BACb;AAAA,0BAAC,WAAQ,WAAU,0BAAyB,KAAK,MAAM,WAAW,KAAK,MAAM,OAAO,MAAM,aAAa,OAAM,mCAAkC;AAAA,MAC/I,oBAAC,SAAI,WAAU,2BAA0B,OAAO,EAAE,UAAU,eAAe,GAAG,KAAK,GAAG,eAAW,MAC/F,8BAAC,WAAQ,WAAU,0BAAyB,KAAK,MAAM,UAAU,KAAI,IAAG,OAAM,mCAAkC,GAClH;AAAA,MACA,oBAAC,SAAI,WAAU,8BAA6B,OAAO,EAAE,MAAM,GAAG,GAAG,IAAI,GAAG,eAAW,MACjF,8BAAC,UAAK,WAAU,6BAA4B,0BAAE,GAChD;AAAA,MACA,oBAAC,UAAK,WAAU,6DAA4D,mBAAgB,eAAe,gBAAM,aAAY;AAAA,MAC7H,oBAAC,UAAK,WAAU,4DAA2D,mBAAgB,cAAc,gBAAM,YAAW;AAAA,MAC1H;AAAA,QAAC;AAAA;AAAA,UACC,WAAU;AAAA,UACV,MAAK;AAAA,UACL,KAAK;AAAA,UACL,KAAK;AAAA,UACL,OAAO;AAAA,UACP,UAAU,CAAC,MAAM,OAAO,OAAO,EAAE,OAAO,KAAK,CAAC;AAAA,UAC9C,cAAY,aAAa,MAAM,WAAW,OAAO,MAAM,UAAU;AAAA,UACjE,kBAAgB,GAAG,GAAG,KAAK,MAAM,UAAU;AAAA;AAAA,MAC7C;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
@@ -3,7 +3,7 @@ import { defineBlock } from "../registry.js";
3
3
  const bookingBlock = defineBlock({
4
4
  type: "booking",
5
5
  Render: dynamic(() => import("./BookingRender.js").then((m) => m.BookingRender)),
6
- label: "Afspraak/booking",
6
+ label: "Afspraak maken",
7
7
  icon: "\u{1F4C6}",
8
8
  defaults: () => ({ embedUrl: "", height: 630, consentGated: true })
9
9
  });
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/Booking.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const bookingBlock = defineBlock({\n type: \"booking\",\n Render: dynamic(() => import(\"./BookingRender\").then((m) => m.BookingRender)),\n label: \"Afspraak/booking\",\n icon: \"📆\",\n defaults: () => ({ embedUrl: \"\", height: 630, consentGated: true }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,eAAe,YAAY;AAAA,EACtC,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,iBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC;AAAA,EAC5E,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,UAAU,IAAI,QAAQ,KAAK,cAAc,KAAK;AACnE,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Booking.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const bookingBlock = defineBlock({\n type: \"booking\",\n Render: dynamic(() => import(\"./BookingRender\").then((m) => m.BookingRender)),\n label: \"Afspraak maken\",\n icon: \"📆\",\n defaults: () => ({ embedUrl: \"\", height: 630, consentGated: true }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,eAAe,YAAY;AAAA,EACtC,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,iBAAiB,EAAE,KAAK,CAAC,MAAM,EAAE,aAAa,CAAC;AAAA,EAC5E,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,UAAU,IAAI,QAAQ,KAAK,cAAc,KAAK;AACnE,CAAC;","names":[]}
@@ -7,12 +7,13 @@ export interface Crumb {
7
7
  href: string;
8
8
  }
9
9
  /** Kruimels uit een pad: "/diensten/tuinaanleg" → Home / Diensten / Tuinaanleg. Puur en getest. */
10
- export declare function crumbsFromPath(path: string, homeLabel?: string): Crumb[];
10
+ export declare function crumbsFromPath(path: string, homeLabel?: string, titels?: Record<string, string>): Crumb[];
11
11
  /** BreadcrumbList-JSON-LD. Puur en getest. */
12
12
  export declare function breadcrumbsJsonLd(crumbs: Crumb[]): Record<string, unknown>;
13
13
  /**
14
- * Kruimelpad, afgeleid van de URL (client, ná mount — hydration-veilig). Op de homepage
15
- * (alleen "Home") wordt niets getoond.
14
+ * Kruimelpad. Sinds 8.3 server-side uit de seed (pad + paginatitels, zie server/blockData.ts);
15
+ * zonder seed (editor, oudere site) zoals vroeger: uit de URL, ná mount — hydratie-veilig.
16
+ * Op de homepage (alleen "Home") wordt niets getoond.
16
17
  */
17
18
  export declare function BreadcrumbsRender({ block, mode }: BlockRenderProps<Breadcrumbs>): import("react").JSX.Element | null;
18
19
  export {};
@@ -3,7 +3,9 @@ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  import { useEffect, useState } from "react";
4
4
  import { useLinkComponent } from "@astryxdesign/core/Link";
5
5
  import { jsonLdHtml } from "./jsonld.js";
6
- function crumbsFromPath(path, homeLabel = "Home") {
6
+ import { useBlockData } from "../context.js";
7
+ import { useSiteConfig } from "../../config.js";
8
+ function crumbsFromPath(path, homeLabel = "Home", titels = {}) {
7
9
  const segments = path.split("/").filter(Boolean);
8
10
  const crumbs = [{ label: homeLabel, href: "/" }];
9
11
  let href = "";
@@ -14,7 +16,7 @@ function crumbsFromPath(path, homeLabel = "Home") {
14
16
  decoded = decodeURIComponent(seg);
15
17
  } catch {
16
18
  }
17
- const label = decoded.replace(/[-_]+/g, " ").replace(/^./, (c) => c.toUpperCase());
19
+ const label = titels[href] ?? decoded.replace(/[-_]+/g, " ").replace(/^./, (c) => c.toUpperCase());
18
20
  crumbs.push({ label, href });
19
21
  }
20
22
  return crumbs;
@@ -33,10 +35,14 @@ function breadcrumbsJsonLd(crumbs) {
33
35
  }
34
36
  function BreadcrumbsRender({ block, mode }) {
35
37
  const LinkC = useLinkComponent();
36
- const [path, setPath] = useState(null);
38
+ const seed = useBlockData("breadcrumbs");
39
+ const { domain } = useSiteConfig();
40
+ const [clientPath, setPath] = useState(null);
37
41
  useEffect(() => {
38
- setPath(window.location.pathname);
39
- }, []);
42
+ if (!seed?.path) setPath(window.location.pathname);
43
+ }, [seed?.path]);
44
+ const path = seed?.path ?? clientPath;
45
+ const origin = domain ? `https://${domain}` : clientPath !== null && typeof window !== "undefined" ? window.location.origin : null;
40
46
  if (mode === "preview" && (path === null || path === "/")) {
41
47
  return /* @__PURE__ */ jsxs("nav", { className: "xicms-breadcrumbs", "aria-label": "Kruimelpad", children: [
42
48
  /* @__PURE__ */ jsx("span", { "data-xicms-edit": "homeLabel", children: block.homeLabel }),
@@ -44,19 +50,19 @@ function BreadcrumbsRender({ block, mode }) {
44
50
  ] });
45
51
  }
46
52
  if (path === null || path === "/") return null;
47
- const crumbs = crumbsFromPath(path, block.homeLabel);
53
+ const crumbs = crumbsFromPath(path, block.homeLabel, seed?.titels);
48
54
  return /* @__PURE__ */ jsxs("nav", { className: "xicms-breadcrumbs", "aria-label": "Kruimelpad", children: [
49
55
  /* @__PURE__ */ jsx("ol", { className: "xicms-breadcrumbs__list", children: crumbs.map((c, i) => /* @__PURE__ */ jsx("li", { className: "xicms-breadcrumbs__item", children: i < crumbs.length - 1 ? (
50
56
  // De eerste kruimel ís `homeLabel`; de rest komt uit het pad en is dus geen blokveld.
51
57
  /* @__PURE__ */ jsx(LinkC, { href: c.href, children: i === 0 ? /* @__PURE__ */ jsx("span", { "data-xicms-edit": "homeLabel", children: c.label }) : c.label })
52
58
  ) : /* @__PURE__ */ jsx("span", { "aria-current": "page", children: c.label }) }, c.href)) }),
53
- block.jsonLd && /* @__PURE__ */ jsx(
59
+ block.jsonLd && origin && /* @__PURE__ */ jsx(
54
60
  "script",
55
61
  {
56
62
  type: "application/ld+json",
57
63
  dangerouslySetInnerHTML: {
58
64
  __html: jsonLdHtml(
59
- breadcrumbsJsonLd(crumbs.map((c) => ({ ...c, href: `${window.location.origin}${c.href}` })))
65
+ breadcrumbsJsonLd(crumbs.map((c) => ({ ...c, href: `${origin}${c.href}` })))
60
66
  )
61
67
  }
62
68
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/BreadcrumbsRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { BreadcrumbsBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { useLinkComponent } from \"@astryxdesign/core/Link\";\nimport { jsonLdHtml } from \"./jsonld\";\n\ntype Breadcrumbs = z.infer<typeof BreadcrumbsBlockSchema>;\n\nexport interface Crumb {\n label: string;\n href: string;\n}\n\n/** Kruimels uit een pad: \"/diensten/tuinaanleg\" → Home / Diensten / Tuinaanleg. Puur en getest. */\nexport function crumbsFromPath(path: string, homeLabel = \"Home\"): Crumb[] {\n const segments = path.split(\"/\").filter(Boolean);\n const crumbs: Crumb[] = [{ label: homeLabel, href: \"/\" }];\n let href = \"\";\n for (const seg of segments) {\n href += `/${seg}`;\n // decodeURIComponent gooit op misvormde percent-encoding (\"%E0%A4%A\") — dan het rauwe segment.\n let decoded = seg;\n try {\n decoded = decodeURIComponent(seg);\n } catch {\n /* rauw segment als label */\n }\n const label = decoded.replace(/[-_]+/g, \" \").replace(/^./, (c) => c.toUpperCase());\n crumbs.push({ label, href });\n }\n return crumbs;\n}\n\n/** BreadcrumbList-JSON-LD. Puur en getest. */\nexport function breadcrumbsJsonLd(crumbs: Crumb[]): Record<string, unknown> {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: crumbs.map((c, i) => ({\n \"@type\": \"ListItem\",\n position: i + 1,\n name: c.label,\n item: c.href,\n })),\n };\n}\n\n/**\n * Kruimelpad, afgeleid van de URL (client, ná mount — hydration-veilig). Op de homepage\n * (alleen \"Home\") wordt niets getoond.\n */\nexport function BreadcrumbsRender({ block, mode }: BlockRenderProps<Breadcrumbs>) {\n const LinkC = useLinkComponent();\n const [path, setPath] = useState<string | null>(null);\n useEffect(() => {\n setPath(window.location.pathname);\n }, []);\n\n if (mode === \"preview\" && (path === null || path === \"/\")) {\n return <nav className=\"xicms-breadcrumbs\" aria-label=\"Kruimelpad\"><span data-xicms-edit=\"homeLabel\">{block.homeLabel}</span> / Voorbeeldpagina</nav>;\n }\n if (path === null || path === \"/\") return null;\n const crumbs = crumbsFromPath(path, block.homeLabel);\n\n return (\n <nav className=\"xicms-breadcrumbs\" aria-label=\"Kruimelpad\">\n <ol className=\"xicms-breadcrumbs__list\">\n {crumbs.map((c, i) => (\n <li key={c.href} className=\"xicms-breadcrumbs__item\">\n {i < crumbs.length - 1 ? (\n // De eerste kruimel ís `homeLabel`; de rest komt uit het pad en is dus geen blokveld.\n <LinkC href={c.href}>{i === 0 ? <span data-xicms-edit=\"homeLabel\">{c.label}</span> : c.label}</LinkC>\n ) : (\n <span aria-current=\"page\">{c.label}</span>\n )}\n </li>\n ))}\n </ol>\n {block.jsonLd && (\n <script\n type=\"application/ld+json\"\n // eslint-disable-next-line react/no-danger\n // Absolute URL's: Google wil volledige item-URL's in BreadcrumbList (dit rendert\n // client-side ná mount, dus window.location.origin is beschikbaar).\n dangerouslySetInnerHTML={{\n __html: jsonLdHtml(\n breadcrumbsJsonLd(crumbs.map((c) => ({ ...c, href: `${window.location.origin}${c.href}` }))),\n ),\n }}\n />\n )}\n </nav>\n );\n}\n"],"mappings":";AA8DW,SAA2D,KAA3D;AA5DX,SAAS,WAAW,gBAAgB;AAIpC,SAAS,wBAAwB;AACjC,SAAS,kBAAkB;AAUpB,SAAS,eAAe,MAAc,YAAY,QAAiB;AACxE,QAAM,WAAW,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAC/C,QAAM,SAAkB,CAAC,EAAE,OAAO,WAAW,MAAM,IAAI,CAAC;AACxD,MAAI,OAAO;AACX,aAAW,OAAO,UAAU;AAC1B,YAAQ,IAAI,GAAG;AAEf,QAAI,UAAU;AACd,QAAI;AACF,gBAAU,mBAAmB,GAAG;AAAA,IAClC,QAAQ;AAAA,IAER;AACA,UAAM,QAAQ,QAAQ,QAAQ,UAAU,GAAG,EAAE,QAAQ,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC;AACjF,WAAO,KAAK,EAAE,OAAO,KAAK,CAAC;AAAA,EAC7B;AACA,SAAO;AACT;AAGO,SAAS,kBAAkB,QAA0C;AAC1E,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,iBAAiB,OAAO,IAAI,CAAC,GAAG,OAAO;AAAA,MACrC,SAAS;AAAA,MACT,UAAU,IAAI;AAAA,MACd,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,EACJ;AACF;AAMO,SAAS,kBAAkB,EAAE,OAAO,KAAK,GAAkC;AAChF,QAAM,QAAQ,iBAAiB;AAC/B,QAAM,CAAC,MAAM,OAAO,IAAI,SAAwB,IAAI;AACpD,YAAU,MAAM;AACd,YAAQ,OAAO,SAAS,QAAQ;AAAA,EAClC,GAAG,CAAC,CAAC;AAEL,MAAI,SAAS,cAAc,SAAS,QAAQ,SAAS,MAAM;AACzD,WAAO,qBAAC,SAAI,WAAU,qBAAoB,cAAW,cAAa;AAAA,0BAAC,UAAK,mBAAgB,aAAa,gBAAM,WAAU;AAAA,MAAO;AAAA,OAAkB;AAAA,EAChJ;AACA,MAAI,SAAS,QAAQ,SAAS,IAAK,QAAO;AAC1C,QAAM,SAAS,eAAe,MAAM,MAAM,SAAS;AAEnD,SACE,qBAAC,SAAI,WAAU,qBAAoB,cAAW,cAC5C;AAAA,wBAAC,QAAG,WAAU,2BACX,iBAAO,IAAI,CAAC,GAAG,MACd,oBAAC,QAAgB,WAAU,2BACxB,cAAI,OAAO,SAAS;AAAA;AAAA,MAEnB,oBAAC,SAAM,MAAM,EAAE,MAAO,gBAAM,IAAI,oBAAC,UAAK,mBAAgB,aAAa,YAAE,OAAM,IAAU,EAAE,OAAM;AAAA,QAE7F,oBAAC,UAAK,gBAAa,QAAQ,YAAE,OAAM,KAL9B,EAAE,IAOX,CACD,GACH;AAAA,IACC,MAAM,UACL;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QAIL,yBAAyB;AAAA,UACvB,QAAQ;AAAA,YACN,kBAAkB,OAAO,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,GAAG,OAAO,SAAS,MAAM,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC;AAAA,UAC7F;AAAA,QACF;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/BreadcrumbsRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { BreadcrumbsBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { useLinkComponent } from \"@astryxdesign/core/Link\";\nimport { jsonLdHtml } from \"./jsonld\";\nimport { useBlockData } from \"../context\";\nimport { useSiteConfig } from \"../../config\";\n\ntype Breadcrumbs = z.infer<typeof BreadcrumbsBlockSchema>;\n\nexport interface Crumb {\n label: string;\n href: string;\n}\n\n/** Kruimels uit een pad: \"/diensten/tuinaanleg\" → Home / Diensten / Tuinaanleg. Puur en getest. */\nexport function crumbsFromPath(path: string, homeLabel = \"Home\", titels: Record<string, string> = {}): Crumb[] {\n const segments = path.split(\"/\").filter(Boolean);\n const crumbs: Crumb[] = [{ label: homeLabel, href: \"/\" }];\n let href = \"\";\n for (const seg of segments) {\n href += `/${seg}`;\n // decodeURIComponent gooit op misvormde percent-encoding (\"%E0%A4%A\") — dan het rauwe segment.\n let decoded = seg;\n try {\n decoded = decodeURIComponent(seg);\n } catch {\n /* rauw segment als label */\n }\n // 8.3: de echte paginatitel als die bekend is (\"Over ons\" i.p.v. \"Over ons\" uit \"over-ons\" — en\n // \"Tuinaanleg & beplanting\" i.p.v. \"Tuinaanleg beplanting\").\n const label = titels[href] ?? decoded.replace(/[-_]+/g, \" \").replace(/^./, (c) => c.toUpperCase());\n crumbs.push({ label, href });\n }\n return crumbs;\n}\n\n/** BreadcrumbList-JSON-LD. Puur en getest. */\nexport function breadcrumbsJsonLd(crumbs: Crumb[]): Record<string, unknown> {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"BreadcrumbList\",\n itemListElement: crumbs.map((c, i) => ({\n \"@type\": \"ListItem\",\n position: i + 1,\n name: c.label,\n item: c.href,\n })),\n };\n}\n\n/**\n * Kruimelpad. Sinds 8.3 server-side uit de seed (pad + paginatitels, zie server/blockData.ts);\n * zonder seed (editor, oudere site) zoals vroeger: uit de URL, ná mount — hydratie-veilig.\n * Op de homepage (alleen \"Home\") wordt niets getoond.\n */\nexport function BreadcrumbsRender({ block, mode }: BlockRenderProps<Breadcrumbs>) {\n const LinkC = useLinkComponent();\n const seed = useBlockData<{ path?: string; titels?: Record<string, string> }>(\"breadcrumbs\");\n const { domain } = useSiteConfig();\n const [clientPath, setPath] = useState<string | null>(null);\n useEffect(() => {\n if (!seed?.path) setPath(window.location.pathname);\n }, [seed?.path]);\n const path = seed?.path ?? clientPath;\n // Absolute URL's voor Google: uit het domein van de site (werkt server-side), anders pas in de browser.\n const origin = domain ? `https://${domain}` : clientPath !== null && typeof window !== \"undefined\" ? window.location.origin : null;\n\n if (mode === \"preview\" && (path === null || path === \"/\")) {\n return <nav className=\"xicms-breadcrumbs\" aria-label=\"Kruimelpad\"><span data-xicms-edit=\"homeLabel\">{block.homeLabel}</span> / Voorbeeldpagina</nav>;\n }\n if (path === null || path === \"/\") return null;\n const crumbs = crumbsFromPath(path, block.homeLabel, seed?.titels);\n\n return (\n <nav className=\"xicms-breadcrumbs\" aria-label=\"Kruimelpad\">\n <ol className=\"xicms-breadcrumbs__list\">\n {crumbs.map((c, i) => (\n <li key={c.href} className=\"xicms-breadcrumbs__item\">\n {i < crumbs.length - 1 ? (\n // De eerste kruimel ís `homeLabel`; de rest komt uit het pad en is dus geen blokveld.\n <LinkC href={c.href}>{i === 0 ? <span data-xicms-edit=\"homeLabel\">{c.label}</span> : c.label}</LinkC>\n ) : (\n <span aria-current=\"page\">{c.label}</span>\n )}\n </li>\n ))}\n </ol>\n {block.jsonLd && origin && (\n <script\n type=\"application/ld+json\"\n // eslint-disable-next-line react/no-danger\n // Absolute URL's: Google wil volledige item-URL's in BreadcrumbList.\n dangerouslySetInnerHTML={{\n __html: jsonLdHtml(\n breadcrumbsJsonLd(crumbs.map((c) => ({ ...c, href: `${origin}${c.href}` }))),\n ),\n }}\n />\n )}\n </nav>\n );\n}\n"],"mappings":";AAwEW,SAA2D,KAA3D;AAtEX,SAAS,WAAW,gBAAgB;AAIpC,SAAS,wBAAwB;AACjC,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAUvB,SAAS,eAAe,MAAc,YAAY,QAAQ,SAAiC,CAAC,GAAY;AAC7G,QAAM,WAAW,KAAK,MAAM,GAAG,EAAE,OAAO,OAAO;AAC/C,QAAM,SAAkB,CAAC,EAAE,OAAO,WAAW,MAAM,IAAI,CAAC;AACxD,MAAI,OAAO;AACX,aAAW,OAAO,UAAU;AAC1B,YAAQ,IAAI,GAAG;AAEf,QAAI,UAAU;AACd,QAAI;AACF,gBAAU,mBAAmB,GAAG;AAAA,IAClC,QAAQ;AAAA,IAER;AAGA,UAAM,QAAQ,OAAO,IAAI,KAAK,QAAQ,QAAQ,UAAU,GAAG,EAAE,QAAQ,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC;AACjG,WAAO,KAAK,EAAE,OAAO,KAAK,CAAC;AAAA,EAC7B;AACA,SAAO;AACT;AAGO,SAAS,kBAAkB,QAA0C;AAC1E,SAAO;AAAA,IACL,YAAY;AAAA,IACZ,SAAS;AAAA,IACT,iBAAiB,OAAO,IAAI,CAAC,GAAG,OAAO;AAAA,MACrC,SAAS;AAAA,MACT,UAAU,IAAI;AAAA,MACd,MAAM,EAAE;AAAA,MACR,MAAM,EAAE;AAAA,IACV,EAAE;AAAA,EACJ;AACF;AAOO,SAAS,kBAAkB,EAAE,OAAO,KAAK,GAAkC;AAChF,QAAM,QAAQ,iBAAiB;AAC/B,QAAM,OAAO,aAAiE,aAAa;AAC3F,QAAM,EAAE,OAAO,IAAI,cAAc;AACjC,QAAM,CAAC,YAAY,OAAO,IAAI,SAAwB,IAAI;AAC1D,YAAU,MAAM;AACd,QAAI,CAAC,MAAM,KAAM,SAAQ,OAAO,SAAS,QAAQ;AAAA,EACnD,GAAG,CAAC,MAAM,IAAI,CAAC;AACf,QAAM,OAAO,MAAM,QAAQ;AAE3B,QAAM,SAAS,SAAS,WAAW,MAAM,KAAK,eAAe,QAAQ,OAAO,WAAW,cAAc,OAAO,SAAS,SAAS;AAE9H,MAAI,SAAS,cAAc,SAAS,QAAQ,SAAS,MAAM;AACzD,WAAO,qBAAC,SAAI,WAAU,qBAAoB,cAAW,cAAa;AAAA,0BAAC,UAAK,mBAAgB,aAAa,gBAAM,WAAU;AAAA,MAAO;AAAA,OAAkB;AAAA,EAChJ;AACA,MAAI,SAAS,QAAQ,SAAS,IAAK,QAAO;AAC1C,QAAM,SAAS,eAAe,MAAM,MAAM,WAAW,MAAM,MAAM;AAEjE,SACE,qBAAC,SAAI,WAAU,qBAAoB,cAAW,cAC5C;AAAA,wBAAC,QAAG,WAAU,2BACX,iBAAO,IAAI,CAAC,GAAG,MACd,oBAAC,QAAgB,WAAU,2BACxB,cAAI,OAAO,SAAS;AAAA;AAAA,MAEnB,oBAAC,SAAM,MAAM,EAAE,MAAO,gBAAM,IAAI,oBAAC,UAAK,mBAAgB,aAAa,YAAE,OAAM,IAAU,EAAE,OAAM;AAAA,QAE7F,oBAAC,UAAK,gBAAa,QAAQ,YAAE,OAAM,KAL9B,EAAE,IAOX,CACD,GACH;AAAA,IACC,MAAM,UAAU,UACf;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QAGL,yBAAyB;AAAA,UACvB,QAAQ;AAAA,YACN,kBAAkB,OAAO,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,GAAG,MAAM,GAAG,EAAE,IAAI,GAAG,EAAE,CAAC;AAAA,UAC7E;AAAA,QACF;AAAA;AAAA,IACF;AAAA,KAEJ;AAEJ;","names":[]}
@@ -2,5 +2,5 @@ import type { z } from "zod";
2
2
  import type { ColumnsBlockSchema } from "../../schema/blocks.js";
3
3
  import type { BlockRenderProps } from "../registry.js";
4
4
  type Columns = z.infer<typeof ColumnsBlockSchema>;
5
- export declare function ColumnsRender({ block, siteId, mode }: BlockRenderProps<Columns>): import("react").JSX.Element;
5
+ export declare function ColumnsRender({ block, siteId, mode }: BlockRenderProps<Columns>): import("react").JSX.Element | null;
6
6
  export {};
@@ -4,7 +4,9 @@ import { BlockRenderer } from "../BlockRenderer.js";
4
4
  import { useRegistry } from "../context.js";
5
5
  function ColumnsRender({ block, siteId, mode }) {
6
6
  const registry = useRegistry();
7
- return /* @__PURE__ */ jsx("div", { className: "xicms-columns", "data-cols": block.columns.length, style: { gridTemplateColumns: `repeat(${block.columns.length}, 1fr)` }, children: block.columns.map((col, idx) => /* @__PURE__ */ jsx("div", { className: "xicms-column", children: /* @__PURE__ */ jsx(BlockRenderer, { blocks: col.blocks, registry, siteId, mode }) }, idx)) });
7
+ const columns = block.columns ?? [];
8
+ if (columns.length === 0) return null;
9
+ return /* @__PURE__ */ jsx("div", { className: "xicms-columns", "data-cols": columns.length, style: { gridTemplateColumns: `repeat(${columns.length}, 1fr)` }, children: columns.map((col, idx) => /* @__PURE__ */ jsx("div", { className: "xicms-column", children: /* @__PURE__ */ jsx(BlockRenderer, { blocks: col.blocks, registry, siteId, mode }) }, idx)) });
8
10
  }
9
11
  export {
10
12
  ColumnsRender
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/ColumnsRender.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport type { ColumnsBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { BlockRenderer } from \"../BlockRenderer\";\nimport { useRegistry } from \"../context\";\n\ntype Columns = z.infer<typeof ColumnsBlockSchema>;\n\nexport function ColumnsRender({ block, siteId, mode }: BlockRenderProps<Columns>) {\n const registry = useRegistry();\n return (\n <div className=\"xicms-columns\" data-cols={block.columns.length} style={{ gridTemplateColumns: `repeat(${block.columns.length}, 1fr)` }}>\n {block.columns.map((col, idx) => (\n <div key={idx} className=\"xicms-column\">\n <BlockRenderer blocks={col.blocks} registry={registry} siteId={siteId} mode={mode} />\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":";AAgBU;AAXV,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAIrB,SAAS,cAAc,EAAE,OAAO,QAAQ,KAAK,GAA8B;AAChF,QAAM,WAAW,YAAY;AAC7B,SACE,oBAAC,SAAI,WAAU,iBAAgB,aAAW,MAAM,QAAQ,QAAQ,OAAO,EAAE,qBAAqB,UAAU,MAAM,QAAQ,MAAM,SAAS,GAClI,gBAAM,QAAQ,IAAI,CAAC,KAAK,QACvB,oBAAC,SAAc,WAAU,gBACvB,8BAAC,iBAAc,QAAQ,IAAI,QAAQ,UAAoB,QAAgB,MAAY,KAD3E,GAEV,CACD,GACH;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/ColumnsRender.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport type { ColumnsBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { BlockRenderer } from \"../BlockRenderer\";\nimport { useRegistry } from \"../context\";\n\ntype Columns = z.infer<typeof ColumnsBlockSchema>;\n\nexport function ColumnsRender({ block, siteId, mode }: BlockRenderProps<Columns>) {\n const registry = useRegistry();\n // Oude/half ingevulde data heeft soms geen `columns` (8.1): dan niets i.p.v. een server-crash.\n const columns = block.columns ?? [];\n if (columns.length === 0) return null;\n return (\n <div className=\"xicms-columns\" data-cols={columns.length} style={{ gridTemplateColumns: `repeat(${columns.length}, 1fr)` }}>\n {columns.map((col, idx) => (\n <div key={idx} className=\"xicms-column\">\n <BlockRenderer blocks={col.blocks} registry={registry} siteId={siteId} mode={mode} />\n </div>\n ))}\n </div>\n );\n}\n"],"mappings":";AAmBU;AAdV,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAIrB,SAAS,cAAc,EAAE,OAAO,QAAQ,KAAK,GAA8B;AAChF,QAAM,WAAW,YAAY;AAE7B,QAAM,UAAU,MAAM,WAAW,CAAC;AAClC,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SACE,oBAAC,SAAI,WAAU,iBAAgB,aAAW,QAAQ,QAAQ,OAAO,EAAE,qBAAqB,UAAU,QAAQ,MAAM,SAAS,GACtH,kBAAQ,IAAI,CAAC,KAAK,QACjB,oBAAC,SAAc,WAAU,gBACvB,8BAAC,iBAAc,QAAQ,IAAI,QAAQ,UAAoB,QAAgB,MAAY,KAD3E,GAEV,CACD,GACH;AAEJ;","names":[]}
@@ -10,7 +10,7 @@ const contactBlock = defineBlock({
10
10
  const socialBlock = defineBlock({
11
11
  type: "social",
12
12
  Render: dynamic(() => import("./ContactRender.js").then((m) => m.SocialRender)),
13
- label: "Social-links",
13
+ label: "Sociale media",
14
14
  icon: "\u{1F517}",
15
15
  defaults: () => ({ items: [{ platform: "Instagram", href: "" }] })
16
16
  });