@xiwebdesign/xicms-core 7.31.0 → 8.16.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 (482) hide show
  1. package/dist/XiCMSProvider.js +23 -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 -60
  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 +248 -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 +159 -0
  133. package/dist/admin/settings/BedrijfInstellingen.js.map +1 -0
  134. package/dist/admin/settings/MailTemplates.js +5 -4
  135. package/dist/admin/settings/MailTemplates.js.map +1 -1
  136. package/dist/admin/settings/SettingsPanel.js +120 -78
  137. package/dist/admin/settings/SettingsPanel.js.map +1 -1
  138. package/dist/admin/settings/SnapshotsCard.js +4 -4
  139. package/dist/admin/settings/SnapshotsCard.js.map +1 -1
  140. package/dist/admin/settings/VorigeTerugzetten.d.ts +15 -0
  141. package/dist/admin/settings/VorigeTerugzetten.js +89 -0
  142. package/dist/admin/settings/VorigeTerugzetten.js.map +1 -0
  143. package/dist/admin/shop/CategoriesTab.js +6 -4
  144. package/dist/admin/shop/CategoriesTab.js.map +1 -1
  145. package/dist/admin/shop/DiscountsTab.js +4 -2
  146. package/dist/admin/shop/DiscountsTab.js.map +1 -1
  147. package/dist/admin/shop/OrdersTab.js +57 -19
  148. package/dist/admin/shop/OrdersTab.js.map +1 -1
  149. package/dist/admin/shop/ProductPaneel.js +2 -1
  150. package/dist/admin/shop/ProductPaneel.js.map +1 -1
  151. package/dist/admin/shop/ProductsTab.js +40 -19
  152. package/dist/admin/shop/ProductsTab.js.map +1 -1
  153. package/dist/admin/shop/ShopPanel.js +13 -1
  154. package/dist/admin/shop/ShopPanel.js.map +1 -1
  155. package/dist/admin/shop/ShopSettingsTab.js +56 -17
  156. package/dist/admin/shop/ShopSettingsTab.js.map +1 -1
  157. package/dist/admin/shop/productClient.js +7 -3
  158. package/dist/admin/shop/productClient.js.map +1 -1
  159. package/dist/admin/stats/NietGevonden.d.ts +10 -0
  160. package/dist/admin/stats/NietGevonden.js +78 -0
  161. package/dist/admin/stats/NietGevonden.js.map +1 -0
  162. package/dist/admin/stats/StatsPanel.js +6 -1
  163. package/dist/admin/stats/StatsPanel.js.map +1 -1
  164. package/dist/admin/stats/lib.d.ts +2 -0
  165. package/dist/admin/stats/lib.js.map +1 -1
  166. package/dist/admin/ui/ConfirmDialog.js +10 -1
  167. package/dist/admin/ui/ConfirmDialog.js.map +1 -1
  168. package/dist/admin/ui/Icon.d.ts +34 -0
  169. package/dist/admin/ui/Icon.js +44 -0
  170. package/dist/admin/ui/Icon.js.map +1 -0
  171. package/dist/admin/ui/ImageField.d.ts +15 -0
  172. package/dist/admin/ui/ImageField.js +67 -0
  173. package/dist/admin/ui/ImageField.js.map +1 -0
  174. package/dist/admin/ui/KleurVeld.d.ts +25 -0
  175. package/dist/admin/ui/KleurVeld.js +76 -0
  176. package/dist/admin/ui/KleurVeld.js.map +1 -0
  177. package/dist/admin/ui/LaadStaat.d.ts +21 -0
  178. package/dist/admin/ui/LaadStaat.js +43 -0
  179. package/dist/admin/ui/LaadStaat.js.map +1 -0
  180. package/dist/admin/ui/LeesbaarheidPaneel.d.ts +10 -0
  181. package/dist/admin/ui/LeesbaarheidPaneel.js +68 -0
  182. package/dist/admin/ui/LeesbaarheidPaneel.js.map +1 -0
  183. package/dist/admin/ui/LinkDialog.d.ts +22 -0
  184. package/dist/admin/ui/LinkDialog.js +131 -0
  185. package/dist/admin/ui/LinkDialog.js.map +1 -0
  186. package/dist/admin/ui/LinkVeld.d.ts +14 -0
  187. package/dist/admin/ui/LinkVeld.js +49 -0
  188. package/dist/admin/ui/LinkVeld.js.map +1 -0
  189. package/dist/admin/ui/PreviewLinkResultaat.d.ts +14 -0
  190. package/dist/admin/ui/PreviewLinkResultaat.js +52 -0
  191. package/dist/admin/ui/PreviewLinkResultaat.js.map +1 -0
  192. package/dist/admin/ui/charts.js +5 -5
  193. package/dist/admin/ui/charts.js.map +1 -1
  194. package/dist/admin/ui/primitives.d.ts +16 -6
  195. package/dist/admin/ui/primitives.js +98 -26
  196. package/dist/admin/ui/primitives.js.map +1 -1
  197. package/dist/admin/ui/select.js +5 -2
  198. package/dist/admin/ui/select.js.map +1 -1
  199. package/dist/admin/ui/switch.d.ts +3 -1
  200. package/dist/admin/ui/switch.js +6 -3
  201. package/dist/admin/ui/switch.js.map +1 -1
  202. package/dist/admin/ui/toast.d.ts +2 -1
  203. package/dist/admin/ui/toast.js +17 -11
  204. package/dist/admin/ui/toast.js.map +1 -1
  205. package/dist/admin/visual/BlokKiezer.d.ts +34 -0
  206. package/dist/admin/visual/BlokKiezer.js +225 -0
  207. package/dist/admin/visual/BlokKiezer.js.map +1 -0
  208. package/dist/admin/visual/InlineGereedschap.d.ts +52 -0
  209. package/dist/admin/visual/InlineGereedschap.js +356 -0
  210. package/dist/admin/visual/InlineGereedschap.js.map +1 -0
  211. package/dist/admin/visual/InlineRijkeTekst.d.ts +23 -0
  212. package/dist/admin/visual/InlineRijkeTekst.js +152 -0
  213. package/dist/admin/visual/InlineRijkeTekst.js.map +1 -0
  214. package/dist/admin/visual/VisualEditor.js +273 -125
  215. package/dist/admin/visual/VisualEditor.js.map +1 -1
  216. package/dist/admin.css +1 -1
  217. package/dist/auth/AuthProvider.js +1 -0
  218. package/dist/auth/AuthProvider.js.map +1 -1
  219. package/dist/bedrijf/bedrijf.d.ts +44 -0
  220. package/dist/bedrijf/bedrijf.js +125 -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 +37 -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 +3 -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/consentEmbed.js +26 -9
  309. package/dist/blocks/builtins/consentEmbed.js.map +1 -1
  310. package/dist/blocks/builtins/index.d.ts +3 -0
  311. package/dist/blocks/builtins/index.js +6 -0
  312. package/dist/blocks/builtins/index.js.map +1 -1
  313. package/dist/blocks/builtins/lib/autoComplete.d.ts +7 -0
  314. package/dist/blocks/builtins/lib/autoComplete.js +20 -0
  315. package/dist/blocks/builtins/lib/autoComplete.js.map +1 -0
  316. package/dist/blocks/builtins/lib/bookingUrl.d.ts +2 -2
  317. package/dist/blocks/builtins/lib/bookingUrl.js +1 -1
  318. package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -1
  319. package/dist/blocks/builtins/lib/ical.d.ts +24 -0
  320. package/dist/blocks/builtins/lib/ical.js +82 -0
  321. package/dist/blocks/builtins/lib/ical.js.map +1 -0
  322. package/dist/blocks/builtins/lib/vandaag.d.ts +8 -0
  323. package/dist/blocks/builtins/lib/vandaag.js +22 -0
  324. package/dist/blocks/builtins/lib/vandaag.js.map +1 -0
  325. package/dist/blocks/registry.d.ts +6 -0
  326. package/dist/blocks/registry.js.map +1 -1
  327. package/dist/blocks/ui/index.js +1 -0
  328. package/dist/blocks/ui/index.js.map +1 -1
  329. package/dist/components/EditBar.js +2 -4
  330. package/dist/components/EditBar.js.map +1 -1
  331. package/dist/components/News.js +26 -18
  332. package/dist/components/News.js.map +1 -1
  333. package/dist/components/PageView.d.ts +7 -1
  334. package/dist/components/PageView.js +17 -0
  335. package/dist/components/PageView.js.map +1 -1
  336. package/dist/components/ResponsiveImage.js +18 -20
  337. package/dist/components/ResponsiveImage.js.map +1 -1
  338. package/dist/components/onderOffset.d.ts +13 -0
  339. package/dist/components/onderOffset.js +74 -0
  340. package/dist/components/onderOffset.js.map +1 -0
  341. package/dist/components/site/Bedrijfsnummers.d.ts +9 -0
  342. package/dist/components/site/Bedrijfsnummers.js +12 -0
  343. package/dist/components/site/Bedrijfsnummers.js.map +1 -0
  344. package/dist/components/site/SiteFooter.d.ts +6 -1
  345. package/dist/components/site/SiteFooter.js +62 -9
  346. package/dist/components/site/SiteFooter.js.map +1 -1
  347. package/dist/components/site/SiteHeader.d.ts +15 -0
  348. package/dist/components/site/SiteHeader.js +70 -0
  349. package/dist/components/site/SiteHeader.js.map +1 -0
  350. package/dist/components/site/SiteNav.d.ts +2 -0
  351. package/dist/components/site/SiteNav.js +29 -5
  352. package/dist/components/site/SiteNav.js.map +1 -1
  353. package/dist/demo/DemoStudio.js +2 -2
  354. package/dist/demo/DemoStudio.js.map +1 -1
  355. package/dist/demo/demoStore.d.ts +13 -0
  356. package/dist/demo/demoStore.js +36 -0
  357. package/dist/demo/demoStore.js.map +1 -1
  358. package/dist/editor/EditorProvider.js +15 -4
  359. package/dist/editor/EditorProvider.js.map +1 -1
  360. package/dist/firebase/functionsClient.js +5 -1
  361. package/dist/firebase/functionsClient.js.map +1 -1
  362. package/dist/index.d.ts +5 -1
  363. package/dist/index.js +20 -1
  364. package/dist/index.js.map +1 -1
  365. package/dist/media/ImageContext.d.ts +17 -0
  366. package/dist/media/ImageContext.js +65 -20
  367. package/dist/media/ImageContext.js.map +1 -1
  368. package/dist/media/altInHtml.d.ts +9 -0
  369. package/dist/media/altInHtml.js +17 -0
  370. package/dist/media/altInHtml.js.map +1 -0
  371. package/dist/media/srcset.d.ts +12 -0
  372. package/dist/media/srcset.js +13 -0
  373. package/dist/media/srcset.js.map +1 -0
  374. package/dist/modules/builtins.d.ts +1 -0
  375. package/dist/modules/builtins.js +22 -9
  376. package/dist/modules/builtins.js.map +1 -1
  377. package/dist/modules/consent/ConsentBanner.d.ts +5 -0
  378. package/dist/modules/consent/ConsentBanner.js +8 -7
  379. package/dist/modules/consent/ConsentBanner.js.map +1 -1
  380. package/dist/modules/consent/standaard.d.ts +12 -0
  381. package/dist/modules/consent/standaard.js +10 -0
  382. package/dist/modules/consent/standaard.js.map +1 -0
  383. package/dist/modules/consent/useConsent.d.ts +4 -0
  384. package/dist/modules/consent/useConsent.js +30 -1
  385. package/dist/modules/consent/useConsent.js.map +1 -1
  386. package/dist/modules/shop/blocks/Cart.js +5 -3
  387. package/dist/modules/shop/blocks/Cart.js.map +1 -1
  388. package/dist/modules/shop/blocks/Checkout.js +56 -35
  389. package/dist/modules/shop/blocks/Checkout.js.map +1 -1
  390. package/dist/modules/shop/blocks/Donation.js +4 -4
  391. package/dist/modules/shop/blocks/Donation.js.map +1 -1
  392. package/dist/modules/shop/blocks/ProductDetail.js +19 -3
  393. package/dist/modules/shop/blocks/ProductDetail.js.map +1 -1
  394. package/dist/modules/shop/blocks/ProductGrid.d.ts +3 -1
  395. package/dist/modules/shop/blocks/ProductGrid.js +8 -4
  396. package/dist/modules/shop/blocks/ProductGrid.js.map +1 -1
  397. package/dist/modules/shop/blocks/ShopCategories.js +4 -3
  398. package/dist/modules/shop/blocks/ShopCategories.js.map +1 -1
  399. package/dist/modules/shop/lib.d.ts +4 -0
  400. package/dist/modules/shop/lib.js +14 -0
  401. package/dist/modules/shop/lib.js.map +1 -1
  402. package/dist/modules/shop/settings.d.ts +3 -0
  403. package/dist/modules/shop/settings.js +14 -0
  404. package/dist/modules/shop/settings.js.map +1 -1
  405. package/dist/modules/shop/strings.d.ts +4 -0
  406. package/dist/modules/shop/strings.js +8 -0
  407. package/dist/modules/shop/strings.js.map +1 -1
  408. package/dist/next/envCheck.d.ts +42 -0
  409. package/dist/next/envCheck.js +106 -0
  410. package/dist/next/envCheck.js.map +1 -0
  411. package/dist/next/index.cjs +185 -2
  412. package/dist/next/index.d.ts +2 -0
  413. package/dist/next/index.js +8 -1
  414. package/dist/next/index.js.map +1 -1
  415. package/dist/next/securityHeaders.d.ts +36 -0
  416. package/dist/next/securityHeaders.js +74 -0
  417. package/dist/next/securityHeaders.js.map +1 -0
  418. package/dist/patterns/builtins.d.ts +7 -0
  419. package/dist/patterns/builtins.js +138 -3
  420. package/dist/patterns/builtins.js.map +1 -1
  421. package/dist/releaseNotes.js +148 -0
  422. package/dist/releaseNotes.js.map +1 -1
  423. package/dist/render/PublishedPage.d.ts +2 -1
  424. package/dist/render/PublishedPage.js +10 -4
  425. package/dist/render/PublishedPage.js.map +1 -1
  426. package/dist/schema/blocks.d.ts +473 -0
  427. package/dist/schema/blocks.js +105 -5
  428. package/dist/schema/blocks.js.map +1 -1
  429. package/dist/schema/business.d.ts +118 -0
  430. package/dist/schema/business.js +75 -0
  431. package/dist/schema/business.js.map +1 -0
  432. package/dist/schema/fields.d.ts +2 -1
  433. package/dist/schema/fields.js.map +1 -1
  434. package/dist/schema/forms.d.ts +18 -0
  435. package/dist/schema/forms.js +18 -3
  436. package/dist/schema/forms.js.map +1 -1
  437. package/dist/schema/mail.d.ts +10 -0
  438. package/dist/schema/mail.js +7 -0
  439. package/dist/schema/mail.js.map +1 -1
  440. package/dist/schema/settings.d.ts +103 -0
  441. package/dist/schema/settings.js +24 -3
  442. package/dist/schema/settings.js.map +1 -1
  443. package/dist/schema/shop.d.ts +2 -0
  444. package/dist/schema/shop.js +4 -0
  445. package/dist/schema/shop.js.map +1 -1
  446. package/dist/schema/shopGeld.d.ts +1 -0
  447. package/dist/schema/shopGeld.js +1 -0
  448. package/dist/schema/shopGeld.js.map +1 -1
  449. package/dist/schema/siteConfig.d.ts +69 -1
  450. package/dist/schema/siteConfig.js +7 -2
  451. package/dist/schema/siteConfig.js.map +1 -1
  452. package/dist/server/blockData.d.ts +1 -1
  453. package/dist/server/blockData.js +74 -18
  454. package/dist/server/blockData.js.map +1 -1
  455. package/dist/server/cspRapport.d.ts +20 -0
  456. package/dist/server/cspRapport.js +56 -0
  457. package/dist/server/cspRapport.js.map +1 -0
  458. package/dist/server/fonts.d.ts +3 -0
  459. package/dist/server/fonts.js +39 -0
  460. package/dist/server/fonts.js.map +1 -0
  461. package/dist/server/index.d.ts +3 -0
  462. package/dist/server/index.js +8 -0
  463. package/dist/server/index.js.map +1 -1
  464. package/dist/server/sanitize.js +2 -0
  465. package/dist/server/sanitize.js.map +1 -1
  466. package/dist/settings/useSiteSettings.js +4 -1
  467. package/dist/settings/useSiteSettings.js.map +1 -1
  468. package/dist/starters/starters.d.ts +69 -0
  469. package/dist/starters/starters.js +171 -0
  470. package/dist/starters/starters.js.map +1 -0
  471. package/dist/styles.css +1181 -212
  472. package/dist/theme/color.d.ts +10 -0
  473. package/dist/theme/color.js +17 -1
  474. package/dist/theme/color.js.map +1 -1
  475. package/dist/theme/fontFallback.d.ts +23 -0
  476. package/dist/theme/fontFallback.js +58 -0
  477. package/dist/theme/fontFallback.js.map +1 -0
  478. package/dist/theme/fonts.d.ts +11 -0
  479. package/dist/theme/fonts.js +16 -0
  480. package/dist/theme/fonts.js.map +1 -0
  481. package/dist/version.js +1 -1
  482. package/package.json +5 -4
@@ -43,7 +43,7 @@ const contactWidget = defineBlock({
43
43
  const socialWidget = defineBlock({
44
44
  type: "socialWidget",
45
45
  Render: dynamic(() => import("./WidgetsRender.js").then((m) => m.SocialWidgetRender)),
46
- label: "Social (compact)",
46
+ label: "Sociale media (compact)",
47
47
  icon: "\u{1F517}",
48
48
  category: "widget",
49
49
  defaults: () => ({ heading: "Volg ons", items: [{ platform: "Instagram", href: "" }] })
@@ -59,7 +59,7 @@ const newsletterWidget = defineBlock({
59
59
  const ctaWidget = defineBlock({
60
60
  type: "ctaWidget",
61
61
  Render: dynamic(() => import("./WidgetsRender.js").then((m) => m.CtaWidgetRender)),
62
- label: "Call-to-action (compact)",
62
+ label: "Oproep met knop (compact)",
63
63
  icon: "\u{1F449}",
64
64
  category: "widget",
65
65
  defaults: () => ({ title: "Vragen?", text: "Neem gerust contact op.", buttonLabel: "Contact", buttonHref: "#contact" })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/Widgets.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const newsWidget = defineBlock({\n type: \"newsWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.NewsWidgetRender)),\n label: \"Laatste nieuws\",\n icon: \"🗞️\",\n category: \"widget\",\n defaults: () => ({ heading: \"Laatste nieuws\", limit: 5, basePath: \"/nieuws\", showImages: false }),\n});\n\nexport const agendaWidget = defineBlock({\n type: \"agendaWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.AgendaWidgetRender)),\n label: \"Komende agenda\",\n icon: \"📅\",\n category: \"widget\",\n defaults: () => ({ heading: \"Komende evenementen\", limit: 5, events: [], hidePast: true }),\n});\n\nexport const openingHoursWidget = defineBlock({\n type: \"openingHoursWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.OpeningHoursWidgetRender)),\n label: \"Openingstijden (compact)\",\n icon: \"🕒\",\n category: \"widget\",\n defaults: () => ({\n heading: \"Openingstijden\",\n highlightToday: true,\n rows: [\n { day: \"Maandag t/m vrijdag\", hours: \"09:00 – 17:00\" },\n { day: \"Zaterdag\", hours: \"10:00 – 16:00\" },\n { day: \"Zondag\", hours: \"Gesloten\" },\n ],\n }),\n});\n\nexport const contactWidget = defineBlock({\n type: \"contactWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.ContactWidgetRender)),\n label: \"Contact (compact)\",\n icon: \"📇\",\n category: \"widget\",\n defaults: () => ({ heading: \"Contact\" }),\n});\n\nexport const socialWidget = defineBlock({\n type: \"socialWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.SocialWidgetRender)),\n label: \"Social (compact)\",\n icon: \"🔗\",\n category: \"widget\",\n defaults: () => ({ heading: \"Volg ons\", items: [{ platform: \"Instagram\", href: \"\" }] }),\n});\n\nexport const newsletterWidget = defineBlock({\n type: \"newsletterWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.NewsletterWidgetRender)),\n label: \"Nieuwsbrief (compact)\",\n icon: \"✉️\",\n category: \"widget\",\n defaults: () => ({ heading: \"Blijf op de hoogte\", buttonLabel: \"Aanmelden\" }),\n});\n\nexport const ctaWidget = defineBlock({\n type: \"ctaWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.CtaWidgetRender)),\n label: \"Call-to-action (compact)\",\n icon: \"👉\",\n category: \"widget\",\n defaults: () => ({ title: \"Vragen?\", text: \"Neem gerust contact op.\", buttonLabel: \"Contact\", buttonHref: \"#contact\" }),\n});\n\nexport const galleryWidget = defineBlock({\n type: \"galleryWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.GalleryWidgetRender)),\n label: \"Fotostrip (compact)\",\n icon: \"🖼️\",\n category: \"widget\",\n defaults: () => ({ heading: \"Foto's\", columns: 3, items: [] }),\n});\n\nexport const testimonialsWidget = defineBlock({\n type: \"testimonialsWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.TestimonialsWidgetRender)),\n label: \"Review (compact)\",\n icon: \"⭐\",\n category: \"widget\",\n defaults: () => ({ heading: \"Wat klanten zeggen\", items: [{ quote: \"Echt een aanrader!\", author: \"Tevreden klant\", rating: 5 }] }),\n});\n\nexport const cardsWidget = defineBlock({\n type: \"cardsWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.CardsWidgetRender)),\n label: \"Diensten (compact)\",\n icon: \"🧩\",\n category: \"widget\",\n defaults: () => ({ heading: \"Uitgelicht\", items: [{ icon: \"⭐\", title: \"Dienst\", text: \"Korte omschrijving.\" }] }),\n});\n\nexport const downloadsWidget = defineBlock({\n type: \"downloadsWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.DownloadsWidgetRender)),\n label: \"Downloads (compact)\",\n icon: \"📥\",\n category: \"widget\",\n defaults: () => ({ heading: \"Downloads\", limit: 5, items: [] }),\n});\n\nexport const countdownWidget = defineBlock({\n type: \"countdownWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.CountdownWidgetRender)),\n label: \"Aftelteller (compact)\",\n icon: \"⏳\",\n category: \"widget\",\n defaults: () => ({ heading: \"Aftellen\", target: \"\", expiredText: \"Het is zover!\" }),\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Widgets.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const newsWidget = defineBlock({\n type: \"newsWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.NewsWidgetRender)),\n label: \"Laatste nieuws\",\n icon: \"🗞️\",\n category: \"widget\",\n defaults: () => ({ heading: \"Laatste nieuws\", limit: 5, basePath: \"/nieuws\", showImages: false }),\n});\n\nexport const agendaWidget = defineBlock({\n type: \"agendaWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.AgendaWidgetRender)),\n label: \"Komende agenda\",\n icon: \"📅\",\n category: \"widget\",\n defaults: () => ({ heading: \"Komende evenementen\", limit: 5, events: [], hidePast: true }),\n});\n\nexport const openingHoursWidget = defineBlock({\n type: \"openingHoursWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.OpeningHoursWidgetRender)),\n label: \"Openingstijden (compact)\",\n icon: \"🕒\",\n category: \"widget\",\n defaults: () => ({\n heading: \"Openingstijden\",\n highlightToday: true,\n rows: [\n { day: \"Maandag t/m vrijdag\", hours: \"09:00 – 17:00\" },\n { day: \"Zaterdag\", hours: \"10:00 – 16:00\" },\n { day: \"Zondag\", hours: \"Gesloten\" },\n ],\n }),\n});\n\nexport const contactWidget = defineBlock({\n type: \"contactWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.ContactWidgetRender)),\n label: \"Contact (compact)\",\n icon: \"📇\",\n category: \"widget\",\n defaults: () => ({ heading: \"Contact\" }),\n});\n\nexport const socialWidget = defineBlock({\n type: \"socialWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.SocialWidgetRender)),\n label: \"Sociale media (compact)\",\n icon: \"🔗\",\n category: \"widget\",\n defaults: () => ({ heading: \"Volg ons\", items: [{ platform: \"Instagram\", href: \"\" }] }),\n});\n\nexport const newsletterWidget = defineBlock({\n type: \"newsletterWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.NewsletterWidgetRender)),\n label: \"Nieuwsbrief (compact)\",\n icon: \"✉️\",\n category: \"widget\",\n defaults: () => ({ heading: \"Blijf op de hoogte\", buttonLabel: \"Aanmelden\" }),\n});\n\nexport const ctaWidget = defineBlock({\n type: \"ctaWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.CtaWidgetRender)),\n label: \"Oproep met knop (compact)\",\n icon: \"👉\",\n category: \"widget\",\n defaults: () => ({ title: \"Vragen?\", text: \"Neem gerust contact op.\", buttonLabel: \"Contact\", buttonHref: \"#contact\" }),\n});\n\nexport const galleryWidget = defineBlock({\n type: \"galleryWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.GalleryWidgetRender)),\n label: \"Fotostrip (compact)\",\n icon: \"🖼️\",\n category: \"widget\",\n defaults: () => ({ heading: \"Foto's\", columns: 3, items: [] }),\n});\n\nexport const testimonialsWidget = defineBlock({\n type: \"testimonialsWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.TestimonialsWidgetRender)),\n label: \"Review (compact)\",\n icon: \"⭐\",\n category: \"widget\",\n defaults: () => ({ heading: \"Wat klanten zeggen\", items: [{ quote: \"Echt een aanrader!\", author: \"Tevreden klant\", rating: 5 }] }),\n});\n\nexport const cardsWidget = defineBlock({\n type: \"cardsWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.CardsWidgetRender)),\n label: \"Diensten (compact)\",\n icon: \"🧩\",\n category: \"widget\",\n defaults: () => ({ heading: \"Uitgelicht\", items: [{ icon: \"⭐\", title: \"Dienst\", text: \"Korte omschrijving.\" }] }),\n});\n\nexport const downloadsWidget = defineBlock({\n type: \"downloadsWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.DownloadsWidgetRender)),\n label: \"Downloads (compact)\",\n icon: \"📥\",\n category: \"widget\",\n defaults: () => ({ heading: \"Downloads\", limit: 5, items: [] }),\n});\n\nexport const countdownWidget = defineBlock({\n type: \"countdownWidget\",\n Render: dynamic(() => import(\"./WidgetsRender\").then((m) => m.CountdownWidgetRender)),\n label: \"Aftelteller (compact)\",\n icon: \"⏳\",\n category: \"widget\",\n defaults: () => ({ heading: \"Aftellen\", target: \"\", expiredText: \"Het is zover!\" }),\n});\n"],"mappings":"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","names":[]}
@@ -5,6 +5,7 @@ import { Onvoltooid } from "./lib/Onvoltooid.js";
5
5
  import { Btn } from "../ui/index.js";
6
6
  import { useNews } from "../../components/News.js";
7
7
  import { selectAgendaEvents, formatEventDate } from "./AgendaRender.js";
8
+ import { useVandaag } from "./lib/vandaag.js";
8
9
  import { parseDays } from "./lib/openingHours.js";
9
10
  import { useCountdown, CountdownDigits } from "./CountdownRender.js";
10
11
  import { TextInput } from "@astryxdesign/core/TextInput";
@@ -25,7 +26,8 @@ function NewsWidgetRender({ block }) {
25
26
  ] });
26
27
  }
27
28
  function AgendaWidgetRender({ block }) {
28
- const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast, limit: block.limit });
29
+ const vandaag = useVandaag();
30
+ const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast, limit: block.limit, vandaag });
29
31
  return /* @__PURE__ */ jsxs("div", { className: "xicms-widget xicms-widget--agenda", children: [
30
32
  /* @__PURE__ */ jsx("h3", { className: "xicms-widget__title", "data-xicms-edit": "heading", children: block.heading ?? "Komende evenementen" }),
31
33
  events.length === 0 ? /* @__PURE__ */ jsx("p", { className: "xicms-widget__empty", children: "Geen geplande evenementen." }) : /* @__PURE__ */ jsx("ul", { className: "xicms-widget__list", children: events.map((e) => /* @__PURE__ */ jsxs("li", { className: "xicms-widget__item xicms-widget__item--event", children: [
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/WidgetsRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { z } from \"zod\";\nimport { Onvoltooid } from \"./lib/Onvoltooid\";\nimport type {\n NewsWidgetSchema,\n AgendaWidgetSchema,\n OpeningHoursWidgetSchema,\n ContactWidgetSchema,\n SocialWidgetSchema,\n NewsletterWidgetSchema,\n CtaWidgetSchema,\n GalleryWidgetSchema,\n TestimonialsWidgetSchema,\n CardsWidgetSchema,\n DownloadsWidgetSchema,\n CountdownWidgetSchema,\n} from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { Btn } from \"../ui\";\nimport { useNews } from \"../../components/News\";\nimport { selectAgendaEvents, formatEventDate } from \"./AgendaRender\";\nimport { parseDays } from \"./lib/openingHours\";\nimport { useCountdown, CountdownDigits } from \"./CountdownRender\";\nimport { TextInput } from \"@astryxdesign/core/TextInput\";\nimport { Button } from \"@astryxdesign/core/Button\";\n\n/**\n * Widgets = compacte zijbalk-varianten van de modules. Elke widget hergebruikt de gegevens en\n * logica van de volwaardige versie (zelfde nieuws-collectie, zelfde agenda-selectie, zelfde\n * countdown-hook) en rendert die alleen compacter. Plaats ze in het \"Met zijbalk\"-blok of in een\n * smalle kolom naast je hoofdinhoud.\n */\n\n/* ── Laatste nieuws ────────────────────────────────────────────────────────── */\ntype NewsW = z.infer<typeof NewsWidgetSchema>;\nexport function NewsWidgetRender({ block }: BlockRenderProps<NewsW>) {\n const { articles, loading } = useNews({ max: block.limit });\n const shown = articles.slice(0, block.limit);\n return (\n <div className=\"xicms-widget xicms-widget--news\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Laatste nieuws\"}</h3>\n {loading ? (\n <p className=\"xicms-widget__empty\">Nieuws laden…</p>\n ) : shown.length === 0 ? (\n <p className=\"xicms-widget__empty\">Nog geen nieuws.</p>\n ) : (\n <ul className=\"xicms-widget__list\">\n {shown.map((a) => (\n <li key={a.id} className=\"xicms-widget__item\">\n {block.showImages && a.coverUrl && (\n // eslint-disable-next-line @next/next/no-img-element\n <img className=\"xicms-widget__thumb\" src={a.coverUrl} alt=\"\" loading=\"lazy\" />\n )}\n <div>\n <a className=\"xicms-widget__link\" href={`${block.basePath}/${a.slug}`}>{a.title}</a>\n <span className=\"xicms-widget__meta\">{a.date}</span>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n/* ── Komende agenda ────────────────────────────────────────────────────────── */\ntype AgendaW = z.infer<typeof AgendaWidgetSchema>;\nexport function AgendaWidgetRender({ block }: BlockRenderProps<AgendaW>) {\n const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast, limit: block.limit });\n return (\n <div className=\"xicms-widget xicms-widget--agenda\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Komende evenementen\"}</h3>\n {events.length === 0 ? (\n <p className=\"xicms-widget__empty\">Geen geplande evenementen.</p>\n ) : (\n <ul className=\"xicms-widget__list\">\n {events.map((e) => (\n <li key={e._i} className=\"xicms-widget__item xicms-widget__item--event\">\n <time className=\"xicms-widget__meta\" dateTime={e.start}>{formatEventDate(e.start)}</time>\n <span className=\"xicms-widget__link\">\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 </span>\n {e.location && <span className=\"xicms-widget__sub\" data-xicms-edit={`events.${e._i}.location`}>{e.location}</span>}\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n/* ── Openingstijden (vandaag gemarkeerd) ───────────────────────────────────── */\ntype OpeningW = z.infer<typeof OpeningHoursWidgetSchema>;\nexport function OpeningHoursWidgetRender({ block }: BlockRenderProps<OpeningW>) {\n // \"Vandaag\" client-side bepalen (voorkomt hydration-mismatch t.o.v. de servertijd).\n const [todayIdx, setTodayIdx] = useState<number | null>(null);\n useEffect(() => setTodayIdx(new Date().getDay()), []);\n const rows = block.rows ?? [];\n return (\n <div className=\"xicms-widget xicms-widget--hours\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Openingstijden\"}</h3>\n <table className=\"xicms-widget__hours\">\n <tbody>\n {rows.map((r, i) => {\n // parseDays begrijpt ook bereiken (\"Ma-vr\", \"Maandag t/m vrijdag\") - een woensdag\n // hoort dan net zo goed gemarkeerd als de letterlijk genoemde dagen.\n const isToday =\n block.highlightToday && todayIdx !== null && parseDays(r.day).includes(todayIdx);\n return (\n <tr key={i} className={isToday ? \"xicms-widget__hours-today\" : undefined}>\n <th scope=\"row\" data-xicms-edit={`rows.${i}.day`}>{r.day}</th>\n <td data-xicms-edit={`rows.${i}.hours`}>{r.hours}</td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n/* ── Contact (compact) ─────────────────────────────────────────────────────── */\ntype ContactW = z.infer<typeof ContactWidgetSchema>;\nexport function ContactWidgetRender({ block }: BlockRenderProps<ContactW>) {\n if (!block.address && !block.phone && !block.email) return null;\n return (\n <div className=\"xicms-widget xicms-widget--contact\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Contact\"}</h3>\n <ul className=\"xicms-widget__list\">\n {block.address && <li className=\"xicms-widget__item\" data-xicms-edit=\"address\">{block.address}</li>}\n {block.phone && (\n <li className=\"xicms-widget__item\"><a href={`tel:${block.phone.replace(/\\s+/g, \"\")}`} data-xicms-edit=\"phone\">{block.phone}</a></li>\n )}\n {block.email && (\n <li className=\"xicms-widget__item\"><a href={`mailto:${block.email}`} data-xicms-edit=\"email\">{block.email}</a></li>\n )}\n </ul>\n </div>\n );\n}\n/* ── Social (compact) ──────────────────────────────────────────────────────── */\ntype SocialW = z.infer<typeof SocialWidgetSchema>;\nexport function SocialWidgetRender({ block }: BlockRenderProps<SocialW>) {\n // _i = index in de OORSPRONKELIJKE array — de lijst wordt gefilterd op href && platform.\n const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((i) => i.href && i.platform);\n if (items.length === 0) return null;\n return (\n <div className=\"xicms-widget xicms-widget--social\">\n {block.heading && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading}</h3>}\n <ul className=\"xicms-widget__social\">\n {items.map((it) => (\n <li key={it._i}><a href={it.href} rel=\"noopener noreferrer\" target=\"_blank\" data-xicms-edit={`items.${it._i}.platform`}>{it.platform}</a></li>\n ))}\n </ul>\n </div>\n );\n}\n/* ── Nieuwsbrief (compact) ─────────────────────────────────────────────────── */\ntype NewsletterW = z.infer<typeof NewsletterWidgetSchema>;\nexport function NewsletterWidgetRender({ block }: BlockRenderProps<NewsletterW>) {\n const [email, setEmail] = useState(\"\");\n return (\n <div className=\"xicms-widget xicms-widget--newsletter\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Nieuwsbrief\"}</h3>\n {block.text && <p className=\"xicms-widget__sub\" data-xicms-edit=\"text\">{block.text}</p>}\n {block.actionUrl ? (\n <form className=\"xicms-widget__form\" action={block.actionUrl} method=\"post\" target=\"_blank\" style={{ display: \"grid\", gap: \"0.6rem\" }}>\n <TextInput label=\"E-mailadres\" isLabelHidden type=\"email\" htmlName=\"EMAIL\" isRequired placeholder=\"je@email.nl\" value={email} onChange={setEmail} />\n <Button label={block.buttonLabel} variant=\"primary\" type=\"submit\">\n <span data-xicms-edit=\"buttonLabel\">{block.buttonLabel}</span>\n </Button>\n </form>\n ) : (\n <Onvoltooid>Deze aanmeldwidget mist nog een aanmeld-URL (tandwiel). Bezoekers zien dit blok niet.</Onvoltooid>\n )}\n </div>\n );\n}\n/* ── CTA (compact) ─────────────────────────────────────────────────────────── */\ntype CtaW = z.infer<typeof CtaWidgetSchema>;\nexport function CtaWidgetRender({ block }: BlockRenderProps<CtaW>) {\n if (!block.title && !block.text) return null;\n return (\n <div className=\"xicms-widget xicms-widget--cta\" style={block.backgroundColor ? { background: block.backgroundColor } : undefined}>\n {block.title && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"title\">{block.title}</h3>}\n {block.text && <p className=\"xicms-widget__sub\" data-xicms-edit=\"text\">{block.text}</p>}\n {block.buttonLabel && (\n <Btn label={block.buttonLabel} href={block.buttonHref} variant=\"primary\" size=\"md\" editField=\"buttonLabel\" />\n )}\n </div>\n );\n}\n/* ── Galerij (compacte strip) ──────────────────────────────────────────────── */\ntype GalleryW = z.infer<typeof GalleryWidgetSchema>;\nexport function GalleryWidgetRender({ block }: BlockRenderProps<GalleryW>) {\n const items = (block.items ?? []).filter((i) => i.url);\n if (items.length === 0) return null;\n return (\n <div className=\"xicms-widget xicms-widget--gallery\">\n {block.heading && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading}</h3>}\n <div className=\"xicms-widget__grid\" data-cols={block.columns}>\n {items.map((it, i) => (\n // eslint-disable-next-line @next/next/no-img-element\n <img key={i} className=\"xicms-widget__photo\" src={it.url} alt={it.alt ?? \"\"} loading=\"lazy\" />\n ))}\n </div>\n </div>\n );\n}\n/* ── Review (compact) ──────────────────────────────────────────────────────── */\ntype TestimonialsW = z.infer<typeof TestimonialsWidgetSchema>;\nexport function TestimonialsWidgetRender({ block }: BlockRenderProps<TestimonialsW>) {\n // _i = index in de OORSPRONKELIJKE array — de lijst wordt gefilterd op quote.\n const items = (block.items ?? []).map((t, i) => ({ ...t, _i: i })).filter((t) => t.quote);\n if (items.length === 0) return null;\n return (\n <div className=\"xicms-widget xicms-widget--testimonial\">\n {block.heading && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading}</h3>}\n <ul className=\"xicms-widget__list\">\n {items.map((t) => (\n <li key={t._i} className=\"xicms-widget__quote\">\n {typeof t.rating === \"number\" && (\n <span className=\"xicms-widget__stars\" aria-label={`${t.rating} van 5`}>{\"★\".repeat(t.rating)}{\"☆\".repeat(5 - t.rating)}</span>\n )}\n <p>“<span data-xicms-edit={`items.${t._i}.quote`}>{t.quote}</span>”</p>\n {t.author && <span className=\"xicms-widget__meta\">— <span data-xicms-edit={`items.${t._i}.author`}>{t.author}</span></span>}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n/* ── Diensten (compact) ────────────────────────────────────────────────────── */\ntype CardsW = z.infer<typeof CardsWidgetSchema>;\nexport function CardsWidgetRender({ block }: BlockRenderProps<CardsW>) {\n const items = (block.items ?? []).filter((c) => c.title);\n if (items.length === 0) return null;\n return (\n <div className=\"xicms-widget xicms-widget--cards\">\n {block.heading && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading}</h3>}\n <ul className=\"xicms-widget__list\">\n {items.map((c, i) => {\n const inner = (\n <>\n {c.icon && <span className=\"xicms-widget__cardicon\" aria-hidden=\"true\">{c.icon}</span>}\n <span>\n <span className=\"xicms-widget__link\">{c.title}</span>\n {c.text && <span className=\"xicms-widget__sub\">{c.text}</span>}\n </span>\n </>\n );\n return (\n <li key={i} className=\"xicms-widget__item xicms-widget__item--card\">\n {c.href ? <a href={c.href} className=\"xicms-widget__cardlink\">{inner}</a> : inner}\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n/* ── Downloads (compact) ───────────────────────────────────────────────────── */\ntype DownloadsW = z.infer<typeof DownloadsWidgetSchema>;\nexport function DownloadsWidgetRender({ block }: BlockRenderProps<DownloadsW>) {\n // _i = index in de OORSPRONKELIJKE array — de lijst wordt gefilterd én afgekapt op `limit`.\n const items = (block.items ?? []).map((d, i) => ({ ...d, _i: i })).filter((d) => d.label && d.href).slice(0, block.limit);\n if (items.length === 0) return null;\n return (\n <div className=\"xicms-widget xicms-widget--downloads\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Downloads\"}</h3>\n <ul className=\"xicms-widget__list\">\n {items.map((d) => (\n <li key={d._i} className=\"xicms-widget__item\">\n <a className=\"xicms-widget__link\" href={d.href} download>\n <span aria-hidden=\"true\">📄</span> <span data-xicms-edit={`items.${d._i}.label`}>{d.label}</span>\n </a>\n {d.meta && <span className=\"xicms-widget__meta\" data-xicms-edit={`items.${d._i}.meta`}>{d.meta}</span>}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n/* ── Aftelteller (compact) ─────────────────────────────────────────────────── */\ntype CountdownW = z.infer<typeof CountdownWidgetSchema>;\nexport function CountdownWidgetRender({ block }: BlockRenderProps<CountdownW>) {\n const r = useCountdown(block.target);\n if (!block.target) return null;\n return (\n <div className=\"xicms-widget xicms-widget--countdown\">\n {block.heading && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading}</h3>}\n {r === null ? (\n <p className=\"xicms-widget__empty\" aria-hidden=\"true\">…</p>\n ) : r.done ? (\n <p className=\"xicms-countdown__expired\" data-xicms-edit=\"expiredText\">{block.expiredText}</p>\n ) : (\n <CountdownDigits r={r} showLabels />\n )}\n </div>\n );\n}\n// Let op: exporteer GEEN aggregaat-array vanuit dit \"use client\"-bestand. Een array die hier\n// wordt opgebouwd is niet server-importeerbaar (de individuele block-exports wél). De volledige\n// lijst staat in blocks/builtins/index.ts.\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/WidgetsRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { z } from \"zod\";\nimport { Onvoltooid } from \"./lib/Onvoltooid\";\nimport type {\n NewsWidgetSchema,\n AgendaWidgetSchema,\n OpeningHoursWidgetSchema,\n ContactWidgetSchema,\n SocialWidgetSchema,\n NewsletterWidgetSchema,\n CtaWidgetSchema,\n GalleryWidgetSchema,\n TestimonialsWidgetSchema,\n CardsWidgetSchema,\n DownloadsWidgetSchema,\n CountdownWidgetSchema,\n} from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { Btn } from \"../ui\";\nimport { useNews } from \"../../components/News\";\nimport { selectAgendaEvents, formatEventDate } from \"./AgendaRender\";\nimport { useVandaag } from \"./lib/vandaag\";\nimport { parseDays } from \"./lib/openingHours\";\nimport { useCountdown, CountdownDigits } from \"./CountdownRender\";\nimport { TextInput } from \"@astryxdesign/core/TextInput\";\nimport { Button } from \"@astryxdesign/core/Button\";\n\n/**\n * Widgets = compacte zijbalk-varianten van de modules. Elke widget hergebruikt de gegevens en\n * logica van de volwaardige versie (zelfde nieuws-collectie, zelfde agenda-selectie, zelfde\n * countdown-hook) en rendert die alleen compacter. Plaats ze in het \"Met zijbalk\"-blok of in een\n * smalle kolom naast je hoofdinhoud.\n */\n\n/* ── Laatste nieuws ────────────────────────────────────────────────────────── */\ntype NewsW = z.infer<typeof NewsWidgetSchema>;\nexport function NewsWidgetRender({ block }: BlockRenderProps<NewsW>) {\n const { articles, loading } = useNews({ max: block.limit });\n const shown = articles.slice(0, block.limit);\n return (\n <div className=\"xicms-widget xicms-widget--news\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Laatste nieuws\"}</h3>\n {loading ? (\n <p className=\"xicms-widget__empty\">Nieuws laden…</p>\n ) : shown.length === 0 ? (\n <p className=\"xicms-widget__empty\">Nog geen nieuws.</p>\n ) : (\n <ul className=\"xicms-widget__list\">\n {shown.map((a) => (\n <li key={a.id} className=\"xicms-widget__item\">\n {block.showImages && a.coverUrl && (\n // eslint-disable-next-line @next/next/no-img-element\n <img className=\"xicms-widget__thumb\" src={a.coverUrl} alt=\"\" loading=\"lazy\" />\n )}\n <div>\n <a className=\"xicms-widget__link\" href={`${block.basePath}/${a.slug}`}>{a.title}</a>\n <span className=\"xicms-widget__meta\">{a.date}</span>\n </div>\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n/* ── Komende agenda ────────────────────────────────────────────────────────── */\ntype AgendaW = z.infer<typeof AgendaWidgetSchema>;\nexport function AgendaWidgetRender({ block }: BlockRenderProps<AgendaW>) {\n const vandaag = useVandaag();\n const events = selectAgendaEvents((block.events ?? []).map((e, i) => ({ ...e, _i: i })), { hidePast: block.hidePast, limit: block.limit, vandaag });\n return (\n <div className=\"xicms-widget xicms-widget--agenda\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Komende evenementen\"}</h3>\n {events.length === 0 ? (\n <p className=\"xicms-widget__empty\">Geen geplande evenementen.</p>\n ) : (\n <ul className=\"xicms-widget__list\">\n {events.map((e) => (\n <li key={e._i} className=\"xicms-widget__item xicms-widget__item--event\">\n <time className=\"xicms-widget__meta\" dateTime={e.start}>{formatEventDate(e.start)}</time>\n <span className=\"xicms-widget__link\">\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 </span>\n {e.location && <span className=\"xicms-widget__sub\" data-xicms-edit={`events.${e._i}.location`}>{e.location}</span>}\n </li>\n ))}\n </ul>\n )}\n </div>\n );\n}\n/* ── Openingstijden (vandaag gemarkeerd) ───────────────────────────────────── */\ntype OpeningW = z.infer<typeof OpeningHoursWidgetSchema>;\nexport function OpeningHoursWidgetRender({ block }: BlockRenderProps<OpeningW>) {\n // \"Vandaag\" client-side bepalen (voorkomt hydration-mismatch t.o.v. de servertijd).\n const [todayIdx, setTodayIdx] = useState<number | null>(null);\n useEffect(() => setTodayIdx(new Date().getDay()), []);\n const rows = block.rows ?? [];\n return (\n <div className=\"xicms-widget xicms-widget--hours\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Openingstijden\"}</h3>\n <table className=\"xicms-widget__hours\">\n <tbody>\n {rows.map((r, i) => {\n // parseDays begrijpt ook bereiken (\"Ma-vr\", \"Maandag t/m vrijdag\") - een woensdag\n // hoort dan net zo goed gemarkeerd als de letterlijk genoemde dagen.\n const isToday =\n block.highlightToday && todayIdx !== null && parseDays(r.day).includes(todayIdx);\n return (\n <tr key={i} className={isToday ? \"xicms-widget__hours-today\" : undefined}>\n <th scope=\"row\" data-xicms-edit={`rows.${i}.day`}>{r.day}</th>\n <td data-xicms-edit={`rows.${i}.hours`}>{r.hours}</td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n );\n}\n/* ── Contact (compact) ─────────────────────────────────────────────────────── */\ntype ContactW = z.infer<typeof ContactWidgetSchema>;\nexport function ContactWidgetRender({ block }: BlockRenderProps<ContactW>) {\n if (!block.address && !block.phone && !block.email) return null;\n return (\n <div className=\"xicms-widget xicms-widget--contact\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Contact\"}</h3>\n <ul className=\"xicms-widget__list\">\n {block.address && <li className=\"xicms-widget__item\" data-xicms-edit=\"address\">{block.address}</li>}\n {block.phone && (\n <li className=\"xicms-widget__item\"><a href={`tel:${block.phone.replace(/\\s+/g, \"\")}`} data-xicms-edit=\"phone\">{block.phone}</a></li>\n )}\n {block.email && (\n <li className=\"xicms-widget__item\"><a href={`mailto:${block.email}`} data-xicms-edit=\"email\">{block.email}</a></li>\n )}\n </ul>\n </div>\n );\n}\n/* ── Social (compact) ──────────────────────────────────────────────────────── */\ntype SocialW = z.infer<typeof SocialWidgetSchema>;\nexport function SocialWidgetRender({ block }: BlockRenderProps<SocialW>) {\n // _i = index in de OORSPRONKELIJKE array — de lijst wordt gefilterd op href && platform.\n const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((i) => i.href && i.platform);\n if (items.length === 0) return null;\n return (\n <div className=\"xicms-widget xicms-widget--social\">\n {block.heading && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading}</h3>}\n <ul className=\"xicms-widget__social\">\n {items.map((it) => (\n <li key={it._i}><a href={it.href} rel=\"noopener noreferrer\" target=\"_blank\" data-xicms-edit={`items.${it._i}.platform`}>{it.platform}</a></li>\n ))}\n </ul>\n </div>\n );\n}\n/* ── Nieuwsbrief (compact) ─────────────────────────────────────────────────── */\ntype NewsletterW = z.infer<typeof NewsletterWidgetSchema>;\nexport function NewsletterWidgetRender({ block }: BlockRenderProps<NewsletterW>) {\n const [email, setEmail] = useState(\"\");\n return (\n <div className=\"xicms-widget xicms-widget--newsletter\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Nieuwsbrief\"}</h3>\n {block.text && <p className=\"xicms-widget__sub\" data-xicms-edit=\"text\">{block.text}</p>}\n {block.actionUrl ? (\n <form className=\"xicms-widget__form\" action={block.actionUrl} method=\"post\" target=\"_blank\" style={{ display: \"grid\", gap: \"0.6rem\" }}>\n <TextInput label=\"E-mailadres\" isLabelHidden type=\"email\" htmlName=\"EMAIL\" isRequired placeholder=\"je@email.nl\" value={email} onChange={setEmail} />\n <Button label={block.buttonLabel} variant=\"primary\" type=\"submit\">\n <span data-xicms-edit=\"buttonLabel\">{block.buttonLabel}</span>\n </Button>\n </form>\n ) : (\n <Onvoltooid>Deze aanmeldwidget mist nog een aanmeld-URL (tandwiel). Bezoekers zien dit blok niet.</Onvoltooid>\n )}\n </div>\n );\n}\n/* ── CTA (compact) ─────────────────────────────────────────────────────────── */\ntype CtaW = z.infer<typeof CtaWidgetSchema>;\nexport function CtaWidgetRender({ block }: BlockRenderProps<CtaW>) {\n if (!block.title && !block.text) return null;\n return (\n <div className=\"xicms-widget xicms-widget--cta\" style={block.backgroundColor ? { background: block.backgroundColor } : undefined}>\n {block.title && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"title\">{block.title}</h3>}\n {block.text && <p className=\"xicms-widget__sub\" data-xicms-edit=\"text\">{block.text}</p>}\n {block.buttonLabel && (\n <Btn label={block.buttonLabel} href={block.buttonHref} variant=\"primary\" size=\"md\" editField=\"buttonLabel\" />\n )}\n </div>\n );\n}\n/* ── Galerij (compacte strip) ──────────────────────────────────────────────── */\ntype GalleryW = z.infer<typeof GalleryWidgetSchema>;\nexport function GalleryWidgetRender({ block }: BlockRenderProps<GalleryW>) {\n const items = (block.items ?? []).filter((i) => i.url);\n if (items.length === 0) return null;\n return (\n <div className=\"xicms-widget xicms-widget--gallery\">\n {block.heading && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading}</h3>}\n <div className=\"xicms-widget__grid\" data-cols={block.columns}>\n {items.map((it, i) => (\n // eslint-disable-next-line @next/next/no-img-element\n <img key={i} className=\"xicms-widget__photo\" src={it.url} alt={it.alt ?? \"\"} loading=\"lazy\" />\n ))}\n </div>\n </div>\n );\n}\n/* ── Review (compact) ──────────────────────────────────────────────────────── */\ntype TestimonialsW = z.infer<typeof TestimonialsWidgetSchema>;\nexport function TestimonialsWidgetRender({ block }: BlockRenderProps<TestimonialsW>) {\n // _i = index in de OORSPRONKELIJKE array — de lijst wordt gefilterd op quote.\n const items = (block.items ?? []).map((t, i) => ({ ...t, _i: i })).filter((t) => t.quote);\n if (items.length === 0) return null;\n return (\n <div className=\"xicms-widget xicms-widget--testimonial\">\n {block.heading && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading}</h3>}\n <ul className=\"xicms-widget__list\">\n {items.map((t) => (\n <li key={t._i} className=\"xicms-widget__quote\">\n {typeof t.rating === \"number\" && (\n <span className=\"xicms-widget__stars\" aria-label={`${t.rating} van 5`}>{\"★\".repeat(t.rating)}{\"☆\".repeat(5 - t.rating)}</span>\n )}\n <p>“<span data-xicms-edit={`items.${t._i}.quote`}>{t.quote}</span>”</p>\n {t.author && <span className=\"xicms-widget__meta\">— <span data-xicms-edit={`items.${t._i}.author`}>{t.author}</span></span>}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n/* ── Diensten (compact) ────────────────────────────────────────────────────── */\ntype CardsW = z.infer<typeof CardsWidgetSchema>;\nexport function CardsWidgetRender({ block }: BlockRenderProps<CardsW>) {\n const items = (block.items ?? []).filter((c) => c.title);\n if (items.length === 0) return null;\n return (\n <div className=\"xicms-widget xicms-widget--cards\">\n {block.heading && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading}</h3>}\n <ul className=\"xicms-widget__list\">\n {items.map((c, i) => {\n const inner = (\n <>\n {c.icon && <span className=\"xicms-widget__cardicon\" aria-hidden=\"true\">{c.icon}</span>}\n <span>\n <span className=\"xicms-widget__link\">{c.title}</span>\n {c.text && <span className=\"xicms-widget__sub\">{c.text}</span>}\n </span>\n </>\n );\n return (\n <li key={i} className=\"xicms-widget__item xicms-widget__item--card\">\n {c.href ? <a href={c.href} className=\"xicms-widget__cardlink\">{inner}</a> : inner}\n </li>\n );\n })}\n </ul>\n </div>\n );\n}\n/* ── Downloads (compact) ───────────────────────────────────────────────────── */\ntype DownloadsW = z.infer<typeof DownloadsWidgetSchema>;\nexport function DownloadsWidgetRender({ block }: BlockRenderProps<DownloadsW>) {\n // _i = index in de OORSPRONKELIJKE array — de lijst wordt gefilterd én afgekapt op `limit`.\n const items = (block.items ?? []).map((d, i) => ({ ...d, _i: i })).filter((d) => d.label && d.href).slice(0, block.limit);\n if (items.length === 0) return null;\n return (\n <div className=\"xicms-widget xicms-widget--downloads\">\n <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading ?? \"Downloads\"}</h3>\n <ul className=\"xicms-widget__list\">\n {items.map((d) => (\n <li key={d._i} className=\"xicms-widget__item\">\n <a className=\"xicms-widget__link\" href={d.href} download>\n <span aria-hidden=\"true\">📄</span> <span data-xicms-edit={`items.${d._i}.label`}>{d.label}</span>\n </a>\n {d.meta && <span className=\"xicms-widget__meta\" data-xicms-edit={`items.${d._i}.meta`}>{d.meta}</span>}\n </li>\n ))}\n </ul>\n </div>\n );\n}\n/* ── Aftelteller (compact) ─────────────────────────────────────────────────── */\ntype CountdownW = z.infer<typeof CountdownWidgetSchema>;\nexport function CountdownWidgetRender({ block }: BlockRenderProps<CountdownW>) {\n const r = useCountdown(block.target);\n if (!block.target) return null;\n return (\n <div className=\"xicms-widget xicms-widget--countdown\">\n {block.heading && <h3 className=\"xicms-widget__title\" data-xicms-edit=\"heading\">{block.heading}</h3>}\n {r === null ? (\n <p className=\"xicms-widget__empty\" aria-hidden=\"true\">…</p>\n ) : r.done ? (\n <p className=\"xicms-countdown__expired\" data-xicms-edit=\"expiredText\">{block.expiredText}</p>\n ) : (\n <CountdownDigits r={r} showLabels />\n )}\n </div>\n );\n}\n// Let op: exporteer GEEN aggregaat-array vanuit dit \"use client\"-bestand. Een array die hier\n// wordt opgebouwd is niet server-importeerbaar (de individuele block-exports wél). De volledige\n// lijst staat in blocks/builtins/index.ts.\n"],"mappings":"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","names":[]}
@@ -1,7 +1,7 @@
1
1
  "use client";
2
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useConsent } from "../../modules/consent/useConsent.js";
4
- import { useModuleActive } from "../../modules/context.js";
3
+ import { useConsent, useMeldConsentNodig } from "../../modules/consent/useConsent.js";
4
+ import { useModuleActive, useModuleSettings } from "../../modules/context.js";
5
5
  function ConsentEmbed({
6
6
  gated,
7
7
  category = "marketing",
@@ -9,8 +9,11 @@ function ConsentEmbed({
9
9
  label = "Externe inhoud",
10
10
  children
11
11
  }) {
12
- const { has } = useConsent();
12
+ const { has, state, save } = useConsent();
13
13
  const consentActive = useModuleActive("consent");
14
+ const { version } = useModuleSettings("consent");
15
+ const wacht = !preview && gated && consentActive && !has(category);
16
+ useMeldConsentNodig(category, wacht);
14
17
  if (preview) {
15
18
  return /* @__PURE__ */ jsx("div", { className: "xicms-embed-consent xicms-embed-preview", role: "note", "aria-label": `${label} (voorbeeld)`, children: /* @__PURE__ */ jsxs("p", { children: [
16
19
  "\u{1F50C} ",
@@ -18,12 +21,26 @@ function ConsentEmbed({
18
21
  " \u2014 wordt op de live site geladen (niet in de editor)."
19
22
  ] }) });
20
23
  }
21
- if (!gated || !consentActive || has(category)) return /* @__PURE__ */ jsx(Fragment, { children });
22
- return /* @__PURE__ */ jsx("div", { className: "xicms-embed-consent", role: "note", children: /* @__PURE__ */ jsxs("p", { children: [
23
- "Accepteer cookies (",
24
- category,
25
- ") om deze inhoud te laden."
26
- ] }) });
24
+ if (!wacht) return /* @__PURE__ */ jsx(Fragment, { children });
25
+ const toestaan = () => save({ ...state.categories, necessary: true, [category]: true }, version);
26
+ return /* @__PURE__ */ jsxs("div", { className: "xicms-embed-consent", role: "note", children: [
27
+ /* @__PURE__ */ jsxs("div", { className: "xicms-embed-consent__tekst", children: [
28
+ /* @__PURE__ */ jsx("p", { className: "xicms-embed-consent__titel", children: label }),
29
+ /* @__PURE__ */ jsx("p", { children: "Dit komt van een andere partij en kan cookies plaatsen. Daarom laden we het pas als je dat toestaat." })
30
+ ] }),
31
+ /* @__PURE__ */ jsxs("div", { className: "xicms-embed-consent__knoppen", children: [
32
+ /* @__PURE__ */ jsx("button", { type: "button", className: "xicms-consent__btn xicms-consent__btn--primary", onClick: toestaan, children: "Toestaan en laden" }),
33
+ /* @__PURE__ */ jsx(
34
+ "button",
35
+ {
36
+ type: "button",
37
+ className: "xicms-consent__reopen-link",
38
+ onClick: () => window.dispatchEvent(new Event("xicms:consent:open")),
39
+ children: "Cookie-instellingen"
40
+ }
41
+ )
42
+ ] })
43
+ ] });
27
44
  }
28
45
  export {
29
46
  ConsentEmbed
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/consentEmbed.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { useConsent } from \"../../modules/consent/useConsent\";\nimport { useModuleActive } from \"../../modules/context\";\n\n/**\n * Toont een externe embed (video/kaart/booking) meteen als gating uitstaat óf de consent-module niet\n * actief is; staat consent wél aan, dan pas na toestemming voor de categorie. Anders een nette\n * placeholder i.p.v. de tracker stilletjes te laden (AVG).\n *\n * `preview` (editor): mount NOOIT de echte iframe/het script, maar toon een lichte placeholder. Dit\n * is het `mode === \"preview\"`-contract: in de pagina-editor draaien geen third-party scripts/iframes\n * (geen ResizeObservers, geen externe widgets) — dat houdt de editor licht én voorkomt crashes.\n */\nexport function ConsentEmbed({\n gated,\n category = \"marketing\",\n preview = false,\n label = \"Externe inhoud\",\n children,\n}: {\n gated: boolean;\n category?: string;\n preview?: boolean;\n label?: string;\n children: ReactNode;\n}) {\n const { has } = useConsent();\n const consentActive = useModuleActive(\"consent\");\n if (preview) {\n return (\n <div className=\"xicms-embed-consent xicms-embed-preview\" role=\"note\" aria-label={`${label} (voorbeeld)`}>\n <p>🔌 {label} — wordt op de live site geladen (niet in de editor).</p>\n </div>\n );\n }\n if (!gated || !consentActive || has(category)) return <>{children}</>;\n return (\n <div className=\"xicms-embed-consent\" role=\"note\">\n <p>Accepteer cookies ({category}) om deze inhoud te laden.</p>\n </div>\n );\n}\n"],"mappings":";AAgCM,SAKkD,UALlD,KACE,YADF;AA7BN,SAAS,kBAAkB;AAC3B,SAAS,uBAAuB;AAWzB,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR;AACF,GAMG;AACD,QAAM,EAAE,IAAI,IAAI,WAAW;AAC3B,QAAM,gBAAgB,gBAAgB,SAAS;AAC/C,MAAI,SAAS;AACX,WACE,oBAAC,SAAI,WAAU,2CAA0C,MAAK,QAAO,cAAY,GAAG,KAAK,gBACvF,+BAAC,OAAE;AAAA;AAAA,MAAI;AAAA,MAAM;AAAA,OAAqD,GACpE;AAAA,EAEJ;AACA,MAAI,CAAC,SAAS,CAAC,iBAAiB,IAAI,QAAQ,EAAG,QAAO,gCAAG,UAAS;AAClE,SACE,oBAAC,SAAI,WAAU,uBAAsB,MAAK,QACxC,+BAAC,OAAE;AAAA;AAAA,IAAoB;AAAA,IAAS;AAAA,KAA0B,GAC5D;AAEJ;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/consentEmbed.tsx"],"sourcesContent":["\"use client\";\n\nimport type { ReactNode } from \"react\";\nimport { useConsent, useMeldConsentNodig } from \"../../modules/consent/useConsent\";\nimport { useModuleActive, useModuleSettings } from \"../../modules/context\";\n\n/**\n * Toont een externe embed (video/kaart/booking) meteen als gating uitstaat óf de consent-module niet\n * actief is; staat consent wél aan, dan pas na toestemming voor de categorie. Anders een nette\n * placeholder i.p.v. de tracker stilletjes te laden (AVG).\n *\n * `preview` (editor): mount NOOIT de echte iframe/het script, maar toon een lichte placeholder. Dit\n * is het `mode === \"preview\"`-contract: in de pagina-editor draaien geen third-party scripts/iframes\n * (geen ResizeObservers, geen externe widgets) — dat houdt de editor licht én voorkomt crashes.\n */\nexport function ConsentEmbed({\n gated,\n category = \"marketing\",\n preview = false,\n label = \"Externe inhoud\",\n children,\n}: {\n gated: boolean;\n category?: string;\n preview?: boolean;\n label?: string;\n children: ReactNode;\n}) {\n const { has, state, save } = useConsent();\n const consentActive = useModuleActive(\"consent\");\n const { version } = useModuleSettings<{ version?: string }>(\"consent\");\n const wacht = !preview && gated && consentActive && !has(category);\n // 8.16: zolang dit op toestemming wacht, mag de cookiebanner verschijnen (zie useConsent).\n useMeldConsentNodig(category, wacht);\n if (preview) {\n return (\n <div className=\"xicms-embed-consent xicms-embed-preview\" role=\"note\" aria-label={`${label} (voorbeeld)`}>\n <p>🔌 {label} — wordt op de live site geladen (niet in de editor).</p>\n </div>\n );\n }\n if (!wacht) return <>{children}</>;\n // 8.16: direct hier toestaan, zonder eerst de banner te zoeken. Telt als keuze voor deze\n // categorie; de rest van de eerdere keuze blijft staan.\n const toestaan = () => save({ ...state.categories, necessary: true, [category]: true }, version);\n return (\n <div className=\"xicms-embed-consent\" role=\"note\">\n <div className=\"xicms-embed-consent__tekst\">\n <p className=\"xicms-embed-consent__titel\">{label}</p>\n <p>Dit komt van een andere partij en kan cookies plaatsen. Daarom laden we het pas als je dat toestaat.</p>\n </div>\n <div className=\"xicms-embed-consent__knoppen\">\n <button type=\"button\" className=\"xicms-consent__btn xicms-consent__btn--primary\" onClick={toestaan}>\n Toestaan en laden\n </button>\n <button\n type=\"button\"\n className=\"xicms-consent__reopen-link\"\n onClick={() => window.dispatchEvent(new Event(\"xicms:consent:open\"))}\n >\n Cookie-instellingen\n </button>\n </div>\n </div>\n );\n}\n"],"mappings":";AAoCM,SAKe,UALf,KACE,YADF;AAjCN,SAAS,YAAY,2BAA2B;AAChD,SAAS,iBAAiB,yBAAyB;AAW5C,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA,WAAW;AAAA,EACX,UAAU;AAAA,EACV,QAAQ;AAAA,EACR;AACF,GAMG;AACD,QAAM,EAAE,KAAK,OAAO,KAAK,IAAI,WAAW;AACxC,QAAM,gBAAgB,gBAAgB,SAAS;AAC/C,QAAM,EAAE,QAAQ,IAAI,kBAAwC,SAAS;AACrE,QAAM,QAAQ,CAAC,WAAW,SAAS,iBAAiB,CAAC,IAAI,QAAQ;AAEjE,sBAAoB,UAAU,KAAK;AACnC,MAAI,SAAS;AACX,WACE,oBAAC,SAAI,WAAU,2CAA0C,MAAK,QAAO,cAAY,GAAG,KAAK,gBACvF,+BAAC,OAAE;AAAA;AAAA,MAAI;AAAA,MAAM;AAAA,OAAqD,GACpE;AAAA,EAEJ;AACA,MAAI,CAAC,MAAO,QAAO,gCAAG,UAAS;AAG/B,QAAM,WAAW,MAAM,KAAK,EAAE,GAAG,MAAM,YAAY,WAAW,MAAM,CAAC,QAAQ,GAAG,KAAK,GAAG,OAAO;AAC/F,SACE,qBAAC,SAAI,WAAU,uBAAsB,MAAK,QACxC;AAAA,yBAAC,SAAI,WAAU,8BACb;AAAA,0BAAC,OAAE,WAAU,8BAA8B,iBAAM;AAAA,MACjD,oBAAC,OAAE,kHAAoG;AAAA,OACzG;AAAA,IACA,qBAAC,SAAI,WAAU,gCACb;AAAA,0BAAC,YAAO,MAAK,UAAS,WAAU,kDAAiD,SAAS,UAAU,+BAEpG;AAAA,MACA;AAAA,QAAC;AAAA;AAAA,UACC,MAAK;AAAA,UACL,WAAU;AAAA,UACV,SAAS,MAAM,OAAO,cAAc,IAAI,MAAM,oBAAoB,CAAC;AAAA,UACpE;AAAA;AAAA,MAED;AAAA,OACF;AAAA,KACF;AAEJ;","names":[]}
@@ -13,6 +13,9 @@ export { ctaBlock } from "./Cta.js";
13
13
  export { faqBlock } from "./Faq.js";
14
14
  export { openingHoursBlock } from "./OpeningHours.js";
15
15
  export { pricingBlock } from "./Pricing.js";
16
+ export { priceListBlock } from "./PriceList.js";
17
+ export { sectionHeadingBlock } from "./SectionHeading.js";
18
+ export { availabilityBlock } from "./Availability.js";
16
19
  export { spacerBlock } from "./Spacer.js";
17
20
  export { columnsBlock } from "./Columns.js";
18
21
  export { newsListBlock } from "./NewsListBlock.js";
@@ -14,6 +14,9 @@ import { ctaBlock } from "./Cta.js";
14
14
  import { faqBlock } from "./Faq.js";
15
15
  import { openingHoursBlock } from "./OpeningHours.js";
16
16
  import { pricingBlock } from "./Pricing.js";
17
+ import { priceListBlock } from "./PriceList.js";
18
+ import { sectionHeadingBlock } from "./SectionHeading.js";
19
+ import { availabilityBlock } from "./Availability.js";
17
20
  import { spacerBlock } from "./Spacer.js";
18
21
  import { columnsBlock } from "./Columns.js";
19
22
  import { newsListBlock } from "./NewsListBlock.js";
@@ -63,6 +66,7 @@ export {
63
66
  accordionBlock,
64
67
  agendaBlock,
65
68
  agendaWidget,
69
+ availabilityBlock,
66
70
  bannerBlock,
67
71
  beforeAfterBlock,
68
72
  bookingBlock,
@@ -101,10 +105,12 @@ export {
101
105
  openingHoursWidget,
102
106
  pdfBlock,
103
107
  portfolioBlock,
108
+ priceListBlock,
104
109
  pricingBlock,
105
110
  quoteBlock,
106
111
  richTextBlock,
107
112
  searchBlock,
113
+ sectionHeadingBlock,
108
114
  sliderBlock,
109
115
  socialBlock,
110
116
  socialWidget,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/index.ts"],"sourcesContent":["import type { BlockDefinition } from \"../registry\";\nimport { builtinModules } from \"../../modules/builtins\";\n\n/**\n * Alle ingebouwde blokken. AFGELEID van `builtinModules` (de enige bron van waarheid): een nieuw\n * blok registreer je alleen in zijn module — het verschijnt hier automatisch. Zo kan deze lijst\n * nooit uit de pas lopen met wat de modules leveren. Klant-blokken komen erbij via `mergeRegistry`.\n */\nexport const builtinBlocks: BlockDefinition[] = dedupeByType(\n builtinModules.flatMap((m) => m.blocks ?? []),\n);\n\nfunction dedupeByType(defs: BlockDefinition[]): BlockDefinition[] {\n const seen = new Set<string>();\n return defs.filter((d) => (seen.has(d.type) ? false : (seen.add(d.type), true)));\n}\n\nexport { heroBlock } from \"./Hero\";\nexport { richTextBlock } from \"./RichTextBlock\";\nexport { imageBlock } from \"./ImageBlock\";\nexport { galleryBlock } from \"./Gallery\";\nexport { ctaBlock } from \"./Cta\";\nexport { faqBlock } from \"./Faq\";\nexport { openingHoursBlock } from \"./OpeningHours\";\nexport { pricingBlock } from \"./Pricing\";\nexport { spacerBlock } from \"./Spacer\";\nexport { columnsBlock } from \"./Columns\";\nexport { newsListBlock } from \"./NewsListBlock\";\nexport { formBlock } from \"./FormBlock\";\nexport { testimonialsBlock } from \"./Testimonials\";\nexport { teamBlock } from \"./Team\";\nexport { agendaBlock } from \"./Agenda\";\nexport { searchBlock } from \"./Search\";\nexport { featureBlock, countersBlock, logosBlock, timelineBlock } from \"./Sections\";\nexport { videoBlock } from \"./Video\";\nexport { bannerBlock } from \"./Banner\";\nexport { contactBlock, socialBlock } from \"./Contact\";\nexport { mapBlock } from \"./MapBlock\";\nexport { newsletterBlock } from \"./Newsletter\";\nexport { bookingBlock } from \"./Booking\";\nexport { buttonsBlock, quoteBlock, dividerBlock } from \"./Elements\";\nexport { accordionBlock } from \"./Accordion\";\nexport { embedBlock } from \"./Embed\";\nexport { withSidebarBlock, tabsBlock } from \"./Layout\";\nexport { cardsBlock } from \"./Cards\";\nexport { downloadsBlock } from \"./Downloads\";\nexport { pdfBlock } from \"./PdfBlock\";\nexport { countdownBlock } from \"./Countdown\";\nexport { sliderBlock } from \"./Slider\";\nexport { whatsappChatBlock } from \"./WhatsappChat\";\nexport { beforeAfterBlock } from \"./BeforeAfter\";\nexport { portfolioBlock } from \"./Portfolio\";\nexport { jobsBlock } from \"./Jobs\";\nexport { breadcrumbsBlock } from \"./Breadcrumbs\";\nexport {\n newsWidget,\n agendaWidget,\n openingHoursWidget,\n contactWidget,\n socialWidget,\n newsletterWidget,\n ctaWidget,\n galleryWidget,\n testimonialsWidget,\n cardsWidget,\n downloadsWidget,\n countdownWidget,\n} from \"./Widgets\";\n// Voor eigen consent-gated embeds in klant-blokken (zie AGENTS.md, mode=\"preview\"-contract).\nexport { ConsentEmbed } from \"./consentEmbed\";\n"],"mappings":"AACA,SAAS,sBAAsB;AAOxB,MAAM,gBAAmC;AAAA,EAC9C,eAAe,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC9C;AAEA,SAAS,aAAa,MAA4C;AAChE,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,KAAK,OAAO,CAAC,MAAO,KAAK,IAAI,EAAE,IAAI,IAAI,SAAS,KAAK,IAAI,EAAE,IAAI,GAAG,KAAM;AACjF;AAEA,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAClC,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,cAAc,eAAe,YAAY,qBAAqB;AACvE,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,cAAc,mBAAmB;AAC1C,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,cAAc,YAAY,oBAAoB;AACvD,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB,iBAAiB;AAC5C,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;AACzB,SAAS,sBAAsB;AAC/B,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AACjC,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,oBAAoB;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/index.ts"],"sourcesContent":["import type { BlockDefinition } from \"../registry\";\nimport { builtinModules } from \"../../modules/builtins\";\n\n/**\n * Alle ingebouwde blokken. AFGELEID van `builtinModules` (de enige bron van waarheid): een nieuw\n * blok registreer je alleen in zijn module — het verschijnt hier automatisch. Zo kan deze lijst\n * nooit uit de pas lopen met wat de modules leveren. Klant-blokken komen erbij via `mergeRegistry`.\n */\nexport const builtinBlocks: BlockDefinition[] = dedupeByType(\n builtinModules.flatMap((m) => m.blocks ?? []),\n);\n\nfunction dedupeByType(defs: BlockDefinition[]): BlockDefinition[] {\n const seen = new Set<string>();\n return defs.filter((d) => (seen.has(d.type) ? false : (seen.add(d.type), true)));\n}\n\nexport { heroBlock } from \"./Hero\";\nexport { richTextBlock } from \"./RichTextBlock\";\nexport { imageBlock } from \"./ImageBlock\";\nexport { galleryBlock } from \"./Gallery\";\nexport { ctaBlock } from \"./Cta\";\nexport { faqBlock } from \"./Faq\";\nexport { openingHoursBlock } from \"./OpeningHours\";\nexport { pricingBlock } from \"./Pricing\";\nexport { priceListBlock } from \"./PriceList\";\nexport { sectionHeadingBlock } from \"./SectionHeading\";\nexport { availabilityBlock } from \"./Availability\";\nexport { spacerBlock } from \"./Spacer\";\nexport { columnsBlock } from \"./Columns\";\nexport { newsListBlock } from \"./NewsListBlock\";\nexport { formBlock } from \"./FormBlock\";\nexport { testimonialsBlock } from \"./Testimonials\";\nexport { teamBlock } from \"./Team\";\nexport { agendaBlock } from \"./Agenda\";\nexport { searchBlock } from \"./Search\";\nexport { featureBlock, countersBlock, logosBlock, timelineBlock } from \"./Sections\";\nexport { videoBlock } from \"./Video\";\nexport { bannerBlock } from \"./Banner\";\nexport { contactBlock, socialBlock } from \"./Contact\";\nexport { mapBlock } from \"./MapBlock\";\nexport { newsletterBlock } from \"./Newsletter\";\nexport { bookingBlock } from \"./Booking\";\nexport { buttonsBlock, quoteBlock, dividerBlock } from \"./Elements\";\nexport { accordionBlock } from \"./Accordion\";\nexport { embedBlock } from \"./Embed\";\nexport { withSidebarBlock, tabsBlock } from \"./Layout\";\nexport { cardsBlock } from \"./Cards\";\nexport { downloadsBlock } from \"./Downloads\";\nexport { pdfBlock } from \"./PdfBlock\";\nexport { countdownBlock } from \"./Countdown\";\nexport { sliderBlock } from \"./Slider\";\nexport { whatsappChatBlock } from \"./WhatsappChat\";\nexport { beforeAfterBlock } from \"./BeforeAfter\";\nexport { portfolioBlock } from \"./Portfolio\";\nexport { jobsBlock } from \"./Jobs\";\nexport { breadcrumbsBlock } from \"./Breadcrumbs\";\nexport {\n newsWidget,\n agendaWidget,\n openingHoursWidget,\n contactWidget,\n socialWidget,\n newsletterWidget,\n ctaWidget,\n galleryWidget,\n testimonialsWidget,\n cardsWidget,\n downloadsWidget,\n countdownWidget,\n} from \"./Widgets\";\n// Voor eigen consent-gated embeds in klant-blokken (zie AGENTS.md, mode=\"preview\"-contract).\nexport { ConsentEmbed } from \"./consentEmbed\";\n"],"mappings":"AACA,SAAS,sBAAsB;AAOxB,MAAM,gBAAmC;AAAA,EAC9C,eAAe,QAAQ,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAC9C;AAEA,SAAS,aAAa,MAA4C;AAChE,QAAM,OAAO,oBAAI,IAAY;AAC7B,SAAO,KAAK,OAAO,CAAC,MAAO,KAAK,IAAI,EAAE,IAAI,IAAI,SAAS,KAAK,IAAI,EAAE,IAAI,GAAG,KAAM;AACjF;AAEA,SAAS,iBAAiB;AAC1B,SAAS,qBAAqB;AAC9B,SAAS,kBAAkB;AAC3B,SAAS,oBAAoB;AAC7B,SAAS,gBAAgB;AACzB,SAAS,gBAAgB;AACzB,SAAS,yBAAyB;AAClC,SAAS,oBAAoB;AAC7B,SAAS,sBAAsB;AAC/B,SAAS,2BAA2B;AACpC,SAAS,yBAAyB;AAClC,SAAS,mBAAmB;AAC5B,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAS,iBAAiB;AAC1B,SAAS,yBAAyB;AAClC,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAC5B,SAAS,cAAc,eAAe,YAAY,qBAAqB;AACvE,SAAS,kBAAkB;AAC3B,SAAS,mBAAmB;AAC5B,SAAS,cAAc,mBAAmB;AAC1C,SAAS,gBAAgB;AACzB,SAAS,uBAAuB;AAChC,SAAS,oBAAoB;AAC7B,SAAS,cAAc,YAAY,oBAAoB;AACvD,SAAS,sBAAsB;AAC/B,SAAS,kBAAkB;AAC3B,SAAS,kBAAkB,iBAAiB;AAC5C,SAAS,kBAAkB;AAC3B,SAAS,sBAAsB;AAC/B,SAAS,gBAAgB;AACzB,SAAS,sBAAsB;AAC/B,SAAS,mBAAmB;AAC5B,SAAS,yBAAyB;AAClC,SAAS,wBAAwB;AACjC,SAAS,sBAAsB;AAC/B,SAAS,iBAAiB;AAC1B,SAAS,wBAAwB;AACjC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAEP,SAAS,oBAAoB;","names":[]}
@@ -0,0 +1,7 @@
1
+ import type { FormField } from "../../../schema/forms.js";
2
+ /**
3
+ * Welke browser-autofill past bij een formulierveld (8.0, WCAG 1.3.5). Op type waar dat kan, anders
4
+ * op de naam/het label ("Naam", "Postcode", …). Onbekend = geen hint: de browser raadt dan zelf, wat
5
+ * beter is dan een verkeerde suggestie (een telefoonnummer in een "Opmerking"-veld).
6
+ */
7
+ export declare function autoCompleteVoor(f: Pick<FormField, "type" | "name" | "label">): string | undefined;
@@ -0,0 +1,20 @@
1
+ function autoCompleteVoor(f) {
2
+ if (f.type === "email") return "email";
3
+ if (f.type === "tel") return "tel";
4
+ if (f.type !== "text" && f.type !== "textarea") return void 0;
5
+ const k = `${f.name} ${f.label}`.toLowerCase();
6
+ if (/\b(e-?mail)\b/.test(k)) return "email";
7
+ if (/\b(telefoon|tel|mobiel|phone)\b/.test(k)) return "tel";
8
+ if (/\b(postcode|zip)\b/.test(k)) return "postal-code";
9
+ if (/\b(woonplaats|plaats|stad|city)\b/.test(k)) return "address-level2";
10
+ if (/\b(adres|straat|address)\b/.test(k)) return "street-address";
11
+ if (/\b(bedrijf|organisatie|company)\b/.test(k)) return "organization";
12
+ if (/\b(voornaam)\b/.test(k)) return "given-name";
13
+ if (/\b(achternaam)\b/.test(k)) return "family-name";
14
+ if (/\b(naam|name)\b/.test(k)) return "name";
15
+ return void 0;
16
+ }
17
+ export {
18
+ autoCompleteVoor
19
+ };
20
+ //# sourceMappingURL=autoComplete.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/builtins/lib/autoComplete.ts"],"sourcesContent":["import type { FormField } from \"../../../schema/forms\";\n\n/**\n * Welke browser-autofill past bij een formulierveld (8.0, WCAG 1.3.5). Op type waar dat kan, anders\n * op de naam/het label (\"Naam\", \"Postcode\", …). Onbekend = geen hint: de browser raadt dan zelf, wat\n * beter is dan een verkeerde suggestie (een telefoonnummer in een \"Opmerking\"-veld).\n */\nexport function autoCompleteVoor(f: Pick<FormField, \"type\" | \"name\" | \"label\">): string | undefined {\n if (f.type === \"email\") return \"email\";\n if (f.type === \"tel\") return \"tel\";\n if (f.type !== \"text\" && f.type !== \"textarea\") return undefined;\n const k = `${f.name} ${f.label}`.toLowerCase();\n if (/\\b(e-?mail)\\b/.test(k)) return \"email\";\n if (/\\b(telefoon|tel|mobiel|phone)\\b/.test(k)) return \"tel\";\n if (/\\b(postcode|zip)\\b/.test(k)) return \"postal-code\";\n if (/\\b(woonplaats|plaats|stad|city)\\b/.test(k)) return \"address-level2\";\n if (/\\b(adres|straat|address)\\b/.test(k)) return \"street-address\";\n if (/\\b(bedrijf|organisatie|company)\\b/.test(k)) return \"organization\";\n if (/\\b(voornaam)\\b/.test(k)) return \"given-name\";\n if (/\\b(achternaam)\\b/.test(k)) return \"family-name\";\n if (/\\b(naam|name)\\b/.test(k)) return \"name\";\n return undefined;\n}\n"],"mappings":"AAOO,SAAS,iBAAiB,GAAmE;AAClG,MAAI,EAAE,SAAS,QAAS,QAAO;AAC/B,MAAI,EAAE,SAAS,MAAO,QAAO;AAC7B,MAAI,EAAE,SAAS,UAAU,EAAE,SAAS,WAAY,QAAO;AACvD,QAAM,IAAI,GAAG,EAAE,IAAI,IAAI,EAAE,KAAK,GAAG,YAAY;AAC7C,MAAI,gBAAgB,KAAK,CAAC,EAAG,QAAO;AACpC,MAAI,kCAAkC,KAAK,CAAC,EAAG,QAAO;AACtD,MAAI,qBAAqB,KAAK,CAAC,EAAG,QAAO;AACzC,MAAI,oCAAoC,KAAK,CAAC,EAAG,QAAO;AACxD,MAAI,6BAA6B,KAAK,CAAC,EAAG,QAAO;AACjD,MAAI,oCAAoC,KAAK,CAAC,EAAG,QAAO;AACxD,MAAI,iBAAiB,KAAK,CAAC,EAAG,QAAO;AACrC,MAAI,mBAAmB,KAAK,CAAC,EAAG,QAAO;AACvC,MAAI,kBAAkB,KAAK,CAAC,EAAG,QAAO;AACtC,SAAO;AACT;","names":[]}
@@ -4,5 +4,5 @@
4
4
  * volledige embed-URL. Puur en getest — de provider-keuze in de editor doet hiermee écht iets
5
5
  * (voorheen was hij alleen een hint).
6
6
  */
7
- export type BookingProvider = "custom" | "calendly" | "cal" | "formitable" | "resengo" | "thefork" | "treatwell" | "salonized" | "tablebooker" | "bookingkit";
8
- export declare function buildBookingUrl(provider: BookingProvider, input: string): string;
7
+ export type BookingProvider = "custom" | "calendly" | "cal" | "formitable" | "resengo" | "thefork" | "treatwell" | "salonized" | "tablebooker" | "bookingkit" | "lodgify" | "bookingexperts" | "tommy" | "bookingmotor";
8
+ export declare function buildBookingUrl(provider: BookingProvider, input: string | undefined): string;
@@ -1,5 +1,5 @@
1
1
  function buildBookingUrl(provider, input) {
2
- const raw = input.trim();
2
+ const raw = (input ?? "").trim();
3
3
  if (!raw) return "";
4
4
  const isUrl = /^https?:\/\//i.test(raw);
5
5
  switch (provider) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/blocks/builtins/lib/bookingUrl.ts"],"sourcesContent":["/**\n * Bouwt de embed-URL voor een reserveersysteem uit wat de klant plakt: een volledige URL wordt\n * genormaliseerd naar de embed-variant van de provider; een kale slug/id wordt aangevuld tot de\n * volledige embed-URL. Puur en getest — de provider-keuze in de editor doet hiermee écht iets\n * (voorheen was hij alleen een hint).\n */\nexport type BookingProvider =\n | \"custom\"\n | \"calendly\"\n | \"cal\"\n | \"formitable\"\n | \"resengo\"\n | \"thefork\"\n | \"treatwell\"\n | \"salonized\"\n | \"tablebooker\"\n | \"bookingkit\";\n\nexport function buildBookingUrl(provider: BookingProvider, input: string): string {\n const raw = input.trim();\n if (!raw) return \"\";\n const isUrl = /^https?:\\/\\//i.test(raw);\n\n switch (provider) {\n case \"calendly\": {\n // Volledige link werkt direct als embed; een slug (\"naam/intake\") vullen we aan.\n if (isUrl) return raw;\n return `https://calendly.com/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"cal\": {\n if (isUrl) return raw;\n return `https://cal.com/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"formitable\": {\n // Embed-vorm: https://widget.formitable.com/<restaurant-id>\n if (isUrl) return raw;\n return `https://widget.formitable.com/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"resengo\": {\n if (isUrl) return raw;\n return `https://www.resengo.com/widget/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"thefork\": {\n if (isUrl) return raw;\n return `https://module.lafourchette.com/nl_NL/module/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"treatwell\": {\n if (isUrl) return raw;\n return `https://widget.treatwell.nl/salon/${raw.replace(/^\\/+/, \"\")}/`;\n }\n case \"salonized\": {\n // Salonized-bookingwidget: https://widget.salonized.com/widget_bookings/new?company=<id>\n if (isUrl) return raw;\n return `https://widget.salonized.com/widget_bookings/new?company=${encodeURIComponent(raw)}`;\n }\n case \"tablebooker\": {\n if (isUrl) return raw;\n return `https://book.tablebooker.com/widget/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"bookingkit\": {\n if (isUrl) return raw;\n return `https://widget.bookingkit.net/bkembed/?cw=${encodeURIComponent(raw)}`;\n }\n case \"custom\":\n default:\n return isUrl ? raw : \"\";\n }\n}\n"],"mappings":"AAkBO,SAAS,gBAAgB,UAA2B,OAAuB;AAChF,QAAM,MAAM,MAAM,KAAK;AACvB,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,QAAQ,gBAAgB,KAAK,GAAG;AAEtC,UAAQ,UAAU;AAAA,IAChB,KAAK,YAAY;AAEf,UAAI,MAAO,QAAO;AAClB,aAAO,wBAAwB,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACxD;AAAA,IACA,KAAK,OAAO;AACV,UAAI,MAAO,QAAO;AAClB,aAAO,mBAAmB,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACnD;AAAA,IACA,KAAK,cAAc;AAEjB,UAAI,MAAO,QAAO;AAClB,aAAO,iCAAiC,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACjE;AAAA,IACA,KAAK,WAAW;AACd,UAAI,MAAO,QAAO;AAClB,aAAO,kCAAkC,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IAClE;AAAA,IACA,KAAK,WAAW;AACd,UAAI,MAAO,QAAO;AAClB,aAAO,gDAAgD,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IAChF;AAAA,IACA,KAAK,aAAa;AAChB,UAAI,MAAO,QAAO;AAClB,aAAO,qCAAqC,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACrE;AAAA,IACA,KAAK,aAAa;AAEhB,UAAI,MAAO,QAAO;AAClB,aAAO,4DAA4D,mBAAmB,GAAG,CAAC;AAAA,IAC5F;AAAA,IACA,KAAK,eAAe;AAClB,UAAI,MAAO,QAAO;AAClB,aAAO,uCAAuC,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACvE;AAAA,IACA,KAAK,cAAc;AACjB,UAAI,MAAO,QAAO;AAClB,aAAO,6CAA6C,mBAAmB,GAAG,CAAC;AAAA,IAC7E;AAAA,IACA,KAAK;AAAA,IACL;AACE,aAAO,QAAQ,MAAM;AAAA,EACzB;AACF;","names":[]}
1
+ {"version":3,"sources":["../../../../src/blocks/builtins/lib/bookingUrl.ts"],"sourcesContent":["/**\n * Bouwt de embed-URL voor een reserveersysteem uit wat de klant plakt: een volledige URL wordt\n * genormaliseerd naar de embed-variant van de provider; een kale slug/id wordt aangevuld tot de\n * volledige embed-URL. Puur en getest — de provider-keuze in de editor doet hiermee écht iets\n * (voorheen was hij alleen een hint).\n */\nexport type BookingProvider =\n | \"custom\"\n | \"calendly\"\n | \"cal\"\n | \"formitable\"\n | \"resengo\"\n | \"thefork\"\n | \"treatwell\"\n | \"salonized\"\n | \"tablebooker\"\n | \"bookingkit\"\n | \"lodgify\"\n | \"bookingexperts\"\n | \"tommy\"\n | \"bookingmotor\";\n\nexport function buildBookingUrl(provider: BookingProvider, input: string | undefined): string {\n const raw = (input ?? \"\").trim();\n if (!raw) return \"\";\n const isUrl = /^https?:\\/\\//i.test(raw);\n\n switch (provider) {\n case \"calendly\": {\n // Volledige link werkt direct als embed; een slug (\"naam/intake\") vullen we aan.\n if (isUrl) return raw;\n return `https://calendly.com/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"cal\": {\n if (isUrl) return raw;\n return `https://cal.com/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"formitable\": {\n // Embed-vorm: https://widget.formitable.com/<restaurant-id>\n if (isUrl) return raw;\n return `https://widget.formitable.com/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"resengo\": {\n if (isUrl) return raw;\n return `https://www.resengo.com/widget/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"thefork\": {\n if (isUrl) return raw;\n return `https://module.lafourchette.com/nl_NL/module/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"treatwell\": {\n if (isUrl) return raw;\n return `https://widget.treatwell.nl/salon/${raw.replace(/^\\/+/, \"\")}/`;\n }\n case \"salonized\": {\n // Salonized-bookingwidget: https://widget.salonized.com/widget_bookings/new?company=<id>\n if (isUrl) return raw;\n return `https://widget.salonized.com/widget_bookings/new?company=${encodeURIComponent(raw)}`;\n }\n case \"tablebooker\": {\n if (isUrl) return raw;\n return `https://book.tablebooker.com/widget/${raw.replace(/^\\/+/, \"\")}`;\n }\n case \"bookingkit\": {\n if (isUrl) return raw;\n return `https://widget.bookingkit.net/bkembed/?cw=${encodeURIComponent(raw)}`;\n }\n case \"custom\":\n default:\n return isUrl ? raw : \"\";\n }\n}\n"],"mappings":"AAsBO,SAAS,gBAAgB,UAA2B,OAAmC;AAC5F,QAAM,OAAO,SAAS,IAAI,KAAK;AAC/B,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,QAAQ,gBAAgB,KAAK,GAAG;AAEtC,UAAQ,UAAU;AAAA,IAChB,KAAK,YAAY;AAEf,UAAI,MAAO,QAAO;AAClB,aAAO,wBAAwB,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACxD;AAAA,IACA,KAAK,OAAO;AACV,UAAI,MAAO,QAAO;AAClB,aAAO,mBAAmB,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACnD;AAAA,IACA,KAAK,cAAc;AAEjB,UAAI,MAAO,QAAO;AAClB,aAAO,iCAAiC,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACjE;AAAA,IACA,KAAK,WAAW;AACd,UAAI,MAAO,QAAO;AAClB,aAAO,kCAAkC,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IAClE;AAAA,IACA,KAAK,WAAW;AACd,UAAI,MAAO,QAAO;AAClB,aAAO,gDAAgD,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IAChF;AAAA,IACA,KAAK,aAAa;AAChB,UAAI,MAAO,QAAO;AAClB,aAAO,qCAAqC,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACrE;AAAA,IACA,KAAK,aAAa;AAEhB,UAAI,MAAO,QAAO;AAClB,aAAO,4DAA4D,mBAAmB,GAAG,CAAC;AAAA,IAC5F;AAAA,IACA,KAAK,eAAe;AAClB,UAAI,MAAO,QAAO;AAClB,aAAO,uCAAuC,IAAI,QAAQ,QAAQ,EAAE,CAAC;AAAA,IACvE;AAAA,IACA,KAAK,cAAc;AACjB,UAAI,MAAO,QAAO;AAClB,aAAO,6CAA6C,mBAAmB,GAAG,CAAC;AAAA,IAC7E;AAAA,IACA,KAAK;AAAA,IACL;AACE,aAAO,QAAQ,MAAM;AAAA,EACzB;AACF;","names":[]}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Bezette dagen uit een iCal-agenda (8.15), voor de beschikbaarheidskalender.
3
+ *
4
+ * Airbnb, Booking.com, Vrbo, availcalendar en de meeste verhuursystemen exporteren hun boekingen
5
+ * als iCal-link (`.ics`). Elke VEVENT is een bezette periode: DTSTART tot (exclusief) DTEND —
6
+ * precies zoals een overnachting werkt: aankomst op de 1e, vertrek op de 8e = de nachten 1 t/m 7
7
+ * zijn bezet, en op de 8e kan een nieuwe gast aankomen. Puur en getest; de server haalt de agenda op.
8
+ */
9
+ export interface Bezet {
10
+ /** Eerste bezette dag, "2026-07-01". */
11
+ van: string;
12
+ /** Eerste VRIJE dag erna (vertrekdag), "2026-07-08". */
13
+ tot: string;
14
+ }
15
+ /** Alle bezette periodes uit de tekst van een .ics-bestand, gesorteerd en samengevoegd. */
16
+ export declare function parseIcalBezet(tekst: string): Bezet[];
17
+ /** Is deze nacht (aankomstdag) bezet? */
18
+ export declare function isBezet(dag: string, bezet: Bezet[]): boolean;
19
+ /** Zit er een bezette nacht tussen aankomst (incl.) en vertrek (excl.)? */
20
+ export declare function periodeVrij(van: string, tot: string, bezet: Bezet[]): boolean;
21
+ /** De weken van een maand, maandag eerst; `null` = dag buiten de maand. */
22
+ export declare function maandRaster(jaar: number, maand: number): (string | null)[][];
23
+ /** Mag de server deze link ophalen? Alleen https naar een gewone hostnaam (geen IP, geen intern adres). */
24
+ export declare function veiligeIcalUrl(url: string): boolean;
@@ -0,0 +1,82 @@
1
+ function datumUit(waarde) {
2
+ const m = /^(\d{4})(\d{2})(\d{2})/.exec(waarde.trim());
3
+ return m ? `${m[1]}-${m[2]}-${m[3]}` : null;
4
+ }
5
+ function volgendeDag(iso) {
6
+ const [j, m, d] = iso.split("-").map(Number);
7
+ const dt = new Date(Date.UTC(j, m - 1, d + 1));
8
+ return dt.toISOString().slice(0, 10);
9
+ }
10
+ function parseIcalBezet(tekst) {
11
+ const regels = tekst.replace(/\r?\n[ \t]/g, "").split(/\r?\n/);
12
+ const uit = [];
13
+ let inEvent = false;
14
+ let start = null;
15
+ let eind = null;
16
+ let geannuleerd = false;
17
+ for (const regel of regels) {
18
+ if (regel === "BEGIN:VEVENT") {
19
+ inEvent = true;
20
+ start = eind = null;
21
+ geannuleerd = false;
22
+ } else if (regel === "END:VEVENT") {
23
+ if (start && !geannuleerd) {
24
+ const tot = eind && eind > start ? eind : volgendeDag(start);
25
+ uit.push({ van: start, tot });
26
+ }
27
+ inEvent = false;
28
+ } else if (inEvent) {
29
+ const [sleutel, ...rest] = regel.split(":");
30
+ const waarde = rest.join(":");
31
+ const naam = sleutel.split(";")[0].toUpperCase();
32
+ if (naam === "DTSTART") start = datumUit(waarde);
33
+ else if (naam === "DTEND") eind = datumUit(waarde);
34
+ else if (naam === "STATUS" && /CANCELLED/i.test(waarde)) geannuleerd = true;
35
+ }
36
+ }
37
+ uit.sort((a, b) => a.van.localeCompare(b.van));
38
+ const samen = [];
39
+ for (const b of uit) {
40
+ const laatste = samen[samen.length - 1];
41
+ if (laatste && b.van <= laatste.tot) laatste.tot = b.tot > laatste.tot ? b.tot : laatste.tot;
42
+ else samen.push({ ...b });
43
+ }
44
+ return samen;
45
+ }
46
+ function isBezet(dag, bezet) {
47
+ return bezet.some((b) => b.van <= dag && dag < b.tot);
48
+ }
49
+ function periodeVrij(van, tot, bezet) {
50
+ return tot > van && !bezet.some((b) => b.van < tot && van < b.tot);
51
+ }
52
+ function maandRaster(jaar, maand) {
53
+ const eerste = new Date(Date.UTC(jaar, maand, 1));
54
+ const dagen = new Date(Date.UTC(jaar, maand + 1, 0)).getUTCDate();
55
+ const offset = (eerste.getUTCDay() + 6) % 7;
56
+ const cellen = Array.from({ length: offset }, () => null);
57
+ for (let d = 1; d <= dagen; d++) cellen.push(`${jaar}-${String(maand + 1).padStart(2, "0")}-${String(d).padStart(2, "0")}`);
58
+ while (cellen.length % 7) cellen.push(null);
59
+ const weken = [];
60
+ for (let i = 0; i < cellen.length; i += 7) weken.push(cellen.slice(i, i + 7));
61
+ return weken;
62
+ }
63
+ function veiligeIcalUrl(url) {
64
+ try {
65
+ const u = new URL(url.replace(/^webcal:\/\//i, "https://"));
66
+ if (u.protocol !== "https:") return false;
67
+ const h = u.hostname.toLowerCase();
68
+ if (h === "localhost" || h.endsWith(".local") || h.endsWith(".internal")) return false;
69
+ if (/^\d+\.\d+\.\d+\.\d+$/.test(h) || h.includes(":") || h.startsWith("[")) return false;
70
+ return h.includes(".");
71
+ } catch {
72
+ return false;
73
+ }
74
+ }
75
+ export {
76
+ isBezet,
77
+ maandRaster,
78
+ parseIcalBezet,
79
+ periodeVrij,
80
+ veiligeIcalUrl
81
+ };
82
+ //# sourceMappingURL=ical.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/builtins/lib/ical.ts"],"sourcesContent":["/**\n * Bezette dagen uit een iCal-agenda (8.15), voor de beschikbaarheidskalender.\n *\n * Airbnb, Booking.com, Vrbo, availcalendar en de meeste verhuursystemen exporteren hun boekingen\n * als iCal-link (`.ics`). Elke VEVENT is een bezette periode: DTSTART tot (exclusief) DTEND —\n * precies zoals een overnachting werkt: aankomst op de 1e, vertrek op de 8e = de nachten 1 t/m 7\n * zijn bezet, en op de 8e kan een nieuwe gast aankomen. Puur en getest; de server haalt de agenda op.\n */\nexport interface Bezet {\n /** Eerste bezette dag, \"2026-07-01\". */\n van: string;\n /** Eerste VRIJE dag erna (vertrekdag), \"2026-07-08\". */\n tot: string;\n}\n\nfunction datumUit(waarde: string): string | null {\n // \"20260701\", \"20260701T150000Z\", \"20260701T150000\"\n const m = /^(\\d{4})(\\d{2})(\\d{2})/.exec(waarde.trim());\n return m ? `${m[1]}-${m[2]}-${m[3]}` : null;\n}\n\nfunction volgendeDag(iso: string): string {\n const [j, m, d] = iso.split(\"-\").map(Number);\n const dt = new Date(Date.UTC(j, m - 1, d + 1));\n return dt.toISOString().slice(0, 10);\n}\n\n/** Alle bezette periodes uit de tekst van een .ics-bestand, gesorteerd en samengevoegd. */\nexport function parseIcalBezet(tekst: string): Bezet[] {\n // Regels die met een spatie beginnen zijn een vervolg van de vorige (RFC 5545 \"folding\").\n const regels = tekst.replace(/\\r?\\n[ \\t]/g, \"\").split(/\\r?\\n/);\n const uit: Bezet[] = [];\n let inEvent = false;\n let start: string | null = null;\n let eind: string | null = null;\n let geannuleerd = false;\n for (const regel of regels) {\n if (regel === \"BEGIN:VEVENT\") {\n inEvent = true;\n start = eind = null;\n geannuleerd = false;\n } else if (regel === \"END:VEVENT\") {\n if (start && !geannuleerd) {\n const tot = eind && eind > start ? eind : volgendeDag(start);\n uit.push({ van: start, tot });\n }\n inEvent = false;\n } else if (inEvent) {\n const [sleutel, ...rest] = regel.split(\":\");\n const waarde = rest.join(\":\");\n const naam = sleutel.split(\";\")[0].toUpperCase();\n if (naam === \"DTSTART\") start = datumUit(waarde);\n else if (naam === \"DTEND\") eind = datumUit(waarde);\n else if (naam === \"STATUS\" && /CANCELLED/i.test(waarde)) geannuleerd = true;\n }\n }\n // Samenvoegen van aansluitende of overlappende periodes.\n uit.sort((a, b) => a.van.localeCompare(b.van));\n const samen: Bezet[] = [];\n for (const b of uit) {\n const laatste = samen[samen.length - 1];\n if (laatste && b.van <= laatste.tot) laatste.tot = b.tot > laatste.tot ? b.tot : laatste.tot;\n else samen.push({ ...b });\n }\n return samen;\n}\n\n/** Is deze nacht (aankomstdag) bezet? */\nexport function isBezet(dag: string, bezet: Bezet[]): boolean {\n return bezet.some((b) => b.van <= dag && dag < b.tot);\n}\n\n/** Zit er een bezette nacht tussen aankomst (incl.) en vertrek (excl.)? */\nexport function periodeVrij(van: string, tot: string, bezet: Bezet[]): boolean {\n return tot > van && !bezet.some((b) => b.van < tot && van < b.tot);\n}\n\n/** De weken van een maand, maandag eerst; `null` = dag buiten de maand. */\nexport function maandRaster(jaar: number, maand: number): (string | null)[][] {\n const eerste = new Date(Date.UTC(jaar, maand, 1));\n const dagen = new Date(Date.UTC(jaar, maand + 1, 0)).getUTCDate();\n const offset = (eerste.getUTCDay() + 6) % 7; // maandag = 0\n const cellen: (string | null)[] = Array.from({ length: offset }, () => null);\n for (let d = 1; d <= dagen; d++) cellen.push(`${jaar}-${String(maand + 1).padStart(2, \"0\")}-${String(d).padStart(2, \"0\")}`);\n while (cellen.length % 7) cellen.push(null);\n const weken: (string | null)[][] = [];\n for (let i = 0; i < cellen.length; i += 7) weken.push(cellen.slice(i, i + 7));\n return weken;\n}\n\n/** Mag de server deze link ophalen? Alleen https naar een gewone hostnaam (geen IP, geen intern adres). */\nexport function veiligeIcalUrl(url: string): boolean {\n try {\n const u = new URL(url.replace(/^webcal:\\/\\//i, \"https://\"));\n if (u.protocol !== \"https:\") return false;\n const h = u.hostname.toLowerCase();\n if (h === \"localhost\" || h.endsWith(\".local\") || h.endsWith(\".internal\")) return false;\n if (/^\\d+\\.\\d+\\.\\d+\\.\\d+$/.test(h) || h.includes(\":\") || h.startsWith(\"[\")) return false;\n return h.includes(\".\");\n } catch {\n return false;\n }\n}\n"],"mappings":"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","names":[]}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * "Vandaag" zonder hydratie-mismatch (8.1). Een datumfilter in de render (verlopen agenda-items,
3
+ * ingepland nieuws) gaf op de server een ander resultaat dan in de browser zodra de HTML uit de
4
+ * cache een dag oud was — React gooide dan de hele server-render weg en bouwde alles opnieuw.
5
+ * Tijdens server-render én hydratie is dit `null` (= niet op datum filteren, identiek aan de
6
+ * server); direct daarna de echte datum van de bezoeker.
7
+ */
8
+ export declare function useVandaag(): Date | null;
@@ -0,0 +1,22 @@
1
+ "use client";
2
+ import { useSyncExternalStore } from "react";
3
+ const geenAbonnement = () => () => {
4
+ };
5
+ function useVandaag() {
6
+ return useSyncExternalStore(geenAbonnement, vandaagSnapshot, () => null);
7
+ }
8
+ let cache = null;
9
+ function vandaagSnapshot() {
10
+ const nu = /* @__PURE__ */ new Date();
11
+ const dag = nu.toDateString();
12
+ if (!cache || cache.dag !== dag) {
13
+ const d = new Date(nu);
14
+ d.setHours(0, 0, 0, 0);
15
+ cache = { dag, datum: d };
16
+ }
17
+ return cache.datum;
18
+ }
19
+ export {
20
+ useVandaag
21
+ };
22
+ //# sourceMappingURL=vandaag.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../../src/blocks/builtins/lib/vandaag.ts"],"sourcesContent":["\"use client\";\n\nimport { useSyncExternalStore } from \"react\";\n\nconst geenAbonnement = () => () => {};\n\n/**\n * \"Vandaag\" zonder hydratie-mismatch (8.1). Een datumfilter in de render (verlopen agenda-items,\n * ingepland nieuws) gaf op de server een ander resultaat dan in de browser zodra de HTML uit de\n * cache een dag oud was — React gooide dan de hele server-render weg en bouwde alles opnieuw.\n * Tijdens server-render én hydratie is dit `null` (= niet op datum filteren, identiek aan de\n * server); direct daarna de echte datum van de bezoeker.\n */\nexport function useVandaag(): Date | null {\n return useSyncExternalStore(geenAbonnement, vandaagSnapshot, () => null);\n}\n\nlet cache: { dag: string; datum: Date } | null = null;\nfunction vandaagSnapshot(): Date {\n // Stabiele referentie per dag: useSyncExternalStore eist dat opeenvolgende snapshots gelijk zijn.\n const nu = new Date();\n const dag = nu.toDateString();\n if (!cache || cache.dag !== dag) {\n const d = new Date(nu);\n d.setHours(0, 0, 0, 0);\n cache = { dag, datum: d };\n }\n return cache.datum;\n}\n"],"mappings":";AAEA,SAAS,4BAA4B;AAErC,MAAM,iBAAiB,MAAM,MAAM;AAAC;AAS7B,SAAS,aAA0B;AACxC,SAAO,qBAAqB,gBAAgB,iBAAiB,MAAM,IAAI;AACzE;AAEA,IAAI,QAA6C;AACjD,SAAS,kBAAwB;AAE/B,QAAM,KAAK,oBAAI,KAAK;AACpB,QAAM,MAAM,GAAG,aAAa;AAC5B,MAAI,CAAC,SAAS,MAAM,QAAQ,KAAK;AAC/B,UAAM,IAAI,IAAI,KAAK,EAAE;AACrB,MAAE,SAAS,GAAG,GAAG,GAAG,CAAC;AACrB,YAAQ,EAAE,KAAK,OAAO,EAAE;AAAA,EAC1B;AACA,SAAO,MAAM;AACf;","names":[]}