@xiwebdesign/xicms-core 7.14.0 → 7.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 (263) hide show
  1. package/dist/admin/AdminApp.js +4 -3
  2. package/dist/admin/AdminApp.js.map +1 -1
  3. package/dist/admin/dashboard/DashboardPanel.d.ts +3 -0
  4. package/dist/admin/dashboard/DashboardPanel.js +316 -0
  5. package/dist/admin/dashboard/DashboardPanel.js.map +1 -0
  6. package/dist/admin/navContext.d.ts +14 -0
  7. package/dist/admin/navContext.js +12 -0
  8. package/dist/admin/navContext.js.map +1 -0
  9. package/dist/admin/pages/PagesPanel.js +38 -12
  10. package/dist/admin/pages/PagesPanel.js.map +1 -1
  11. package/dist/admin/panelRegistry.js +4 -0
  12. package/dist/admin/panelRegistry.js.map +1 -1
  13. package/dist/admin/ui/PanelIcon.js +5 -0
  14. package/dist/admin/ui/PanelIcon.js.map +1 -1
  15. package/dist/admin/visual/VisualEditor.js +56 -20
  16. package/dist/admin/visual/VisualEditor.js.map +1 -1
  17. package/dist/admin.css +1 -1
  18. package/dist/auth/AuthProvider.js +8 -1
  19. package/dist/auth/AuthProvider.js.map +1 -1
  20. package/dist/blocks/builtins/Accordion.d.ts +1 -2
  21. package/dist/blocks/builtins/Accordion.js +2 -39
  22. package/dist/blocks/builtins/Accordion.js.map +1 -1
  23. package/dist/blocks/builtins/AccordionRender.d.ts +7 -0
  24. package/dist/blocks/builtins/AccordionRender.js +42 -0
  25. package/dist/blocks/builtins/AccordionRender.js.map +1 -0
  26. package/dist/blocks/builtins/Agenda.d.ts +1 -29
  27. package/dist/blocks/builtins/Agenda.js +3 -94
  28. package/dist/blocks/builtins/Agenda.js.map +1 -1
  29. package/dist/blocks/builtins/AgendaRender.d.ts +34 -0
  30. package/dist/blocks/builtins/AgendaRender.js +96 -0
  31. package/dist/blocks/builtins/AgendaRender.js.map +1 -0
  32. package/dist/blocks/builtins/Banner.d.ts +1 -2
  33. package/dist/blocks/builtins/Banner.js +2 -32
  34. package/dist/blocks/builtins/Banner.js.map +1 -1
  35. package/dist/blocks/builtins/BannerRender.d.ts +11 -0
  36. package/dist/blocks/builtins/BannerRender.js +35 -0
  37. package/dist/blocks/builtins/BannerRender.js.map +1 -0
  38. package/dist/blocks/builtins/BeforeAfter.d.ts +1 -2
  39. package/dist/blocks/builtins/BeforeAfter.js +2 -31
  40. package/dist/blocks/builtins/BeforeAfter.js.map +1 -1
  41. package/dist/blocks/builtins/BeforeAfterRender.d.ts +11 -0
  42. package/dist/blocks/builtins/BeforeAfterRender.js +34 -0
  43. package/dist/blocks/builtins/BeforeAfterRender.js.map +1 -0
  44. package/dist/blocks/builtins/Booking.d.ts +1 -2
  45. package/dist/blocks/builtins/Booking.js +2 -14
  46. package/dist/blocks/builtins/Booking.js.map +1 -1
  47. package/dist/blocks/builtins/BookingRender.d.ts +8 -0
  48. package/dist/blocks/builtins/BookingRender.js +17 -0
  49. package/dist/blocks/builtins/BookingRender.js.map +1 -0
  50. package/dist/blocks/builtins/Breadcrumbs.d.ts +1 -10
  51. package/dist/blocks/builtins/Breadcrumbs.js +3 -69
  52. package/dist/blocks/builtins/Breadcrumbs.js.map +1 -1
  53. package/dist/blocks/builtins/BreadcrumbsRender.d.ts +18 -0
  54. package/dist/blocks/builtins/BreadcrumbsRender.js +71 -0
  55. package/dist/blocks/builtins/BreadcrumbsRender.js.map +1 -0
  56. package/dist/blocks/builtins/Cards.d.ts +1 -2
  57. package/dist/blocks/builtins/Cards.js +2 -74
  58. package/dist/blocks/builtins/Cards.js.map +1 -1
  59. package/dist/blocks/builtins/CardsRender.d.ts +7 -0
  60. package/dist/blocks/builtins/CardsRender.js +77 -0
  61. package/dist/blocks/builtins/CardsRender.js.map +1 -0
  62. package/dist/blocks/builtins/Columns.d.ts +1 -2
  63. package/dist/blocks/builtins/Columns.js +2 -9
  64. package/dist/blocks/builtins/Columns.js.map +1 -1
  65. package/dist/blocks/builtins/ColumnsRender.d.ts +6 -0
  66. package/dist/blocks/builtins/ColumnsRender.js +12 -0
  67. package/dist/blocks/builtins/ColumnsRender.js.map +1 -0
  68. package/dist/blocks/builtins/Contact.d.ts +2 -7
  69. package/dist/blocks/builtins/Contact.js +3 -102
  70. package/dist/blocks/builtins/Contact.js.map +1 -1
  71. package/dist/blocks/builtins/ContactRender.d.ts +9 -0
  72. package/dist/blocks/builtins/ContactRender.js +105 -0
  73. package/dist/blocks/builtins/ContactRender.js.map +1 -0
  74. package/dist/blocks/builtins/Countdown.d.ts +1 -18
  75. package/dist/blocks/builtins/Countdown.js +3 -53
  76. package/dist/blocks/builtins/Countdown.js.map +1 -1
  77. package/dist/blocks/builtins/CountdownRender.d.ts +22 -0
  78. package/dist/blocks/builtins/CountdownRender.js +61 -0
  79. package/dist/blocks/builtins/CountdownRender.js.map +1 -0
  80. package/dist/blocks/builtins/Cta.d.ts +1 -2
  81. package/dist/blocks/builtins/Cta.js +2 -39
  82. package/dist/blocks/builtins/Cta.js.map +1 -1
  83. package/dist/blocks/builtins/CtaRender.d.ts +6 -0
  84. package/dist/blocks/builtins/CtaRender.js +42 -0
  85. package/dist/blocks/builtins/CtaRender.js.map +1 -0
  86. package/dist/blocks/builtins/Downloads.d.ts +1 -2
  87. package/dist/blocks/builtins/Downloads.js +2 -16
  88. package/dist/blocks/builtins/Downloads.js.map +1 -1
  89. package/dist/blocks/builtins/DownloadsRender.d.ts +7 -0
  90. package/dist/blocks/builtins/DownloadsRender.js +19 -0
  91. package/dist/blocks/builtins/DownloadsRender.js.map +1 -0
  92. package/dist/blocks/builtins/Elements.d.ts +3 -4
  93. package/dist/blocks/builtins/Elements.js +4 -38
  94. package/dist/blocks/builtins/Elements.js.map +1 -1
  95. package/dist/blocks/builtins/ElementsRender.d.ts +10 -0
  96. package/dist/blocks/builtins/ElementsRender.js +41 -0
  97. package/dist/blocks/builtins/ElementsRender.js.map +1 -0
  98. package/dist/blocks/builtins/Embed.d.ts +1 -2
  99. package/dist/blocks/builtins/Embed.js +2 -19
  100. package/dist/blocks/builtins/Embed.js.map +1 -1
  101. package/dist/blocks/builtins/EmbedRender.d.ts +7 -0
  102. package/dist/blocks/builtins/EmbedRender.js +22 -0
  103. package/dist/blocks/builtins/EmbedRender.js.map +1 -0
  104. package/dist/blocks/builtins/Faq.d.ts +1 -6
  105. package/dist/blocks/builtins/Faq.js +3 -103
  106. package/dist/blocks/builtins/Faq.js.map +1 -1
  107. package/dist/blocks/builtins/FaqRender.d.ts +10 -0
  108. package/dist/blocks/builtins/FaqRender.js +105 -0
  109. package/dist/blocks/builtins/FaqRender.js.map +1 -0
  110. package/dist/blocks/builtins/FormBlock.d.ts +1 -2
  111. package/dist/blocks/builtins/FormBlock.js +2 -222
  112. package/dist/blocks/builtins/FormBlock.js.map +1 -1
  113. package/dist/blocks/builtins/FormBlockRender.d.ts +6 -0
  114. package/dist/blocks/builtins/FormBlockRender.js +225 -0
  115. package/dist/blocks/builtins/FormBlockRender.js.map +1 -0
  116. package/dist/blocks/builtins/Gallery.d.ts +1 -23
  117. package/dist/blocks/builtins/Gallery.js +2 -164
  118. package/dist/blocks/builtins/Gallery.js.map +1 -1
  119. package/dist/blocks/builtins/GalleryRender.d.ts +25 -0
  120. package/dist/blocks/builtins/GalleryRender.js +167 -0
  121. package/dist/blocks/builtins/GalleryRender.js.map +1 -0
  122. package/dist/blocks/builtins/Hero.d.ts +1 -2
  123. package/dist/blocks/builtins/Hero.js +2 -73
  124. package/dist/blocks/builtins/Hero.js.map +1 -1
  125. package/dist/blocks/builtins/HeroRender.d.ts +6 -0
  126. package/dist/blocks/builtins/HeroRender.js +76 -0
  127. package/dist/blocks/builtins/HeroRender.js.map +1 -0
  128. package/dist/blocks/builtins/ImageBlock.d.ts +1 -2
  129. package/dist/blocks/builtins/ImageBlock.js +2 -22
  130. package/dist/blocks/builtins/ImageBlock.js.map +1 -1
  131. package/dist/blocks/builtins/ImageBlockRender.d.ts +6 -0
  132. package/dist/blocks/builtins/ImageBlockRender.js +25 -0
  133. package/dist/blocks/builtins/ImageBlockRender.js.map +1 -0
  134. package/dist/blocks/builtins/Jobs.d.ts +1 -15
  135. package/dist/blocks/builtins/Jobs.js +3 -69
  136. package/dist/blocks/builtins/Jobs.js.map +1 -1
  137. package/dist/blocks/builtins/JobsRender.d.ts +17 -0
  138. package/dist/blocks/builtins/JobsRender.js +71 -0
  139. package/dist/blocks/builtins/JobsRender.js.map +1 -0
  140. package/dist/blocks/builtins/Layout.d.ts +2 -3
  141. package/dist/blocks/builtins/Layout.js +3 -39
  142. package/dist/blocks/builtins/Layout.js.map +1 -1
  143. package/dist/blocks/builtins/LayoutRender.d.ts +8 -0
  144. package/dist/blocks/builtins/LayoutRender.js +42 -0
  145. package/dist/blocks/builtins/LayoutRender.js.map +1 -0
  146. package/dist/blocks/builtins/MapBlock.d.ts +1 -2
  147. package/dist/blocks/builtins/MapBlock.js +2 -45
  148. package/dist/blocks/builtins/MapBlock.js.map +1 -1
  149. package/dist/blocks/builtins/MapBlockRender.d.ts +6 -0
  150. package/dist/blocks/builtins/MapBlockRender.js +48 -0
  151. package/dist/blocks/builtins/MapBlockRender.js.map +1 -0
  152. package/dist/blocks/builtins/NewsListBlock.d.ts +1 -2
  153. package/dist/blocks/builtins/NewsListBlock.js +2 -11
  154. package/dist/blocks/builtins/NewsListBlock.js.map +1 -1
  155. package/dist/blocks/builtins/NewsListBlockRender.d.ts +6 -0
  156. package/dist/blocks/builtins/NewsListBlockRender.js +14 -0
  157. package/dist/blocks/builtins/NewsListBlockRender.js.map +1 -0
  158. package/dist/blocks/builtins/Newsletter.d.ts +1 -2
  159. package/dist/blocks/builtins/Newsletter.js +2 -89
  160. package/dist/blocks/builtins/Newsletter.js.map +1 -1
  161. package/dist/blocks/builtins/NewsletterRender.d.ts +13 -0
  162. package/dist/blocks/builtins/NewsletterRender.js +92 -0
  163. package/dist/blocks/builtins/NewsletterRender.js.map +1 -0
  164. package/dist/blocks/builtins/OpeningHours.d.ts +1 -2
  165. package/dist/blocks/builtins/OpeningHours.js +2 -28
  166. package/dist/blocks/builtins/OpeningHours.js.map +1 -1
  167. package/dist/blocks/builtins/OpeningHoursRender.d.ts +7 -0
  168. package/dist/blocks/builtins/OpeningHoursRender.js +31 -0
  169. package/dist/blocks/builtins/OpeningHoursRender.js.map +1 -0
  170. package/dist/blocks/builtins/PdfBlock.d.ts +1 -2
  171. package/dist/blocks/builtins/PdfBlock.js +2 -76
  172. package/dist/blocks/builtins/PdfBlock.js.map +1 -1
  173. package/dist/blocks/builtins/PdfBlockRender.d.ts +11 -0
  174. package/dist/blocks/builtins/PdfBlockRender.js +79 -0
  175. package/dist/blocks/builtins/PdfBlockRender.js.map +1 -0
  176. package/dist/blocks/builtins/Portfolio.d.ts +1 -2
  177. package/dist/blocks/builtins/Portfolio.js +2 -75
  178. package/dist/blocks/builtins/Portfolio.js.map +1 -1
  179. package/dist/blocks/builtins/PortfolioRender.d.ts +7 -0
  180. package/dist/blocks/builtins/PortfolioRender.js +78 -0
  181. package/dist/blocks/builtins/PortfolioRender.js.map +1 -0
  182. package/dist/blocks/builtins/Pricing.d.ts +1 -8
  183. package/dist/blocks/builtins/Pricing.js +3 -73
  184. package/dist/blocks/builtins/Pricing.js.map +1 -1
  185. package/dist/blocks/builtins/PricingRender.d.ts +10 -0
  186. package/dist/blocks/builtins/PricingRender.js +75 -0
  187. package/dist/blocks/builtins/PricingRender.js.map +1 -0
  188. package/dist/blocks/builtins/RichTextBlock.d.ts +1 -2
  189. package/dist/blocks/builtins/RichTextBlock.js +2 -5
  190. package/dist/blocks/builtins/RichTextBlock.js.map +1 -1
  191. package/dist/blocks/builtins/RichTextBlockRender.d.ts +6 -0
  192. package/dist/blocks/builtins/RichTextBlockRender.js +8 -0
  193. package/dist/blocks/builtins/RichTextBlockRender.js.map +1 -0
  194. package/dist/blocks/builtins/Search.d.ts +1 -2
  195. package/dist/blocks/builtins/Search.js +2 -80
  196. package/dist/blocks/builtins/Search.js.map +1 -1
  197. package/dist/blocks/builtins/SearchRender.d.ts +7 -0
  198. package/dist/blocks/builtins/SearchRender.js +83 -0
  199. package/dist/blocks/builtins/SearchRender.js.map +1 -0
  200. package/dist/blocks/builtins/Sections.d.ts +4 -5
  201. package/dist/blocks/builtins/Sections.js +5 -142
  202. package/dist/blocks/builtins/Sections.js.map +1 -1
  203. package/dist/blocks/builtins/SectionsRender.d.ts +12 -0
  204. package/dist/blocks/builtins/SectionsRender.js +145 -0
  205. package/dist/blocks/builtins/SectionsRender.js.map +1 -0
  206. package/dist/blocks/builtins/Slider.d.ts +1 -2
  207. package/dist/blocks/builtins/Slider.js +2 -134
  208. package/dist/blocks/builtins/Slider.js.map +1 -1
  209. package/dist/blocks/builtins/SliderRender.d.ts +7 -0
  210. package/dist/blocks/builtins/SliderRender.js +137 -0
  211. package/dist/blocks/builtins/SliderRender.js.map +1 -0
  212. package/dist/blocks/builtins/Spacer.d.ts +1 -2
  213. package/dist/blocks/builtins/Spacer.js +2 -6
  214. package/dist/blocks/builtins/Spacer.js.map +1 -1
  215. package/dist/blocks/builtins/SpacerRender.d.ts +6 -0
  216. package/dist/blocks/builtins/SpacerRender.js +9 -0
  217. package/dist/blocks/builtins/SpacerRender.js.map +1 -0
  218. package/dist/blocks/builtins/SymbolRef.d.ts +1 -2
  219. package/dist/blocks/builtins/SymbolRef.js +2 -76
  220. package/dist/blocks/builtins/SymbolRef.js.map +1 -1
  221. package/dist/blocks/builtins/SymbolRefRender.d.ts +13 -0
  222. package/dist/blocks/builtins/SymbolRefRender.js +79 -0
  223. package/dist/blocks/builtins/SymbolRefRender.js.map +1 -0
  224. package/dist/blocks/builtins/Team.d.ts +1 -2
  225. package/dist/blocks/builtins/Team.js +2 -55
  226. package/dist/blocks/builtins/Team.js.map +1 -1
  227. package/dist/blocks/builtins/TeamRender.d.ts +7 -0
  228. package/dist/blocks/builtins/TeamRender.js +58 -0
  229. package/dist/blocks/builtins/TeamRender.js.map +1 -0
  230. package/dist/blocks/builtins/Testimonials.d.ts +1 -8
  231. package/dist/blocks/builtins/Testimonials.js +2 -69
  232. package/dist/blocks/builtins/Testimonials.js.map +1 -1
  233. package/dist/blocks/builtins/TestimonialsRender.d.ts +10 -0
  234. package/dist/blocks/builtins/TestimonialsRender.js +72 -0
  235. package/dist/blocks/builtins/TestimonialsRender.js.map +1 -0
  236. package/dist/blocks/builtins/Video.d.ts +1 -9
  237. package/dist/blocks/builtins/Video.js +2 -64
  238. package/dist/blocks/builtins/Video.js.map +1 -1
  239. package/dist/blocks/builtins/VideoRender.d.ts +10 -0
  240. package/dist/blocks/builtins/VideoRender.js +67 -0
  241. package/dist/blocks/builtins/VideoRender.js.map +1 -0
  242. package/dist/blocks/builtins/WhatsappChat.d.ts +1 -8
  243. package/dist/blocks/builtins/WhatsappChat.js +2 -37
  244. package/dist/blocks/builtins/WhatsappChat.js.map +1 -1
  245. package/dist/blocks/builtins/WhatsappChatRender.d.ts +17 -0
  246. package/dist/blocks/builtins/WhatsappChatRender.js +40 -0
  247. package/dist/blocks/builtins/WhatsappChatRender.js.map +1 -0
  248. package/dist/blocks/builtins/Widgets.d.ts +12 -13
  249. package/dist/blocks/builtins/Widgets.js +13 -175
  250. package/dist/blocks/builtins/Widgets.js.map +1 -1
  251. package/dist/blocks/builtins/WidgetsRender.d.ts +34 -0
  252. package/dist/blocks/builtins/WidgetsRender.js +178 -0
  253. package/dist/blocks/builtins/WidgetsRender.js.map +1 -0
  254. package/dist/components/barOffset.js +1 -1
  255. package/dist/components/barOffset.js.map +1 -1
  256. package/dist/modules/contract.js +2 -1
  257. package/dist/modules/contract.js.map +1 -1
  258. package/dist/schema/settings.d.ts +4 -0
  259. package/dist/schema/settings.js +10 -1
  260. package/dist/schema/settings.js.map +1 -1
  261. package/dist/styles.css +93 -19
  262. package/dist/version.js +1 -1
  263. package/package.json +1 -1
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/HeroRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState, type CSSProperties } from \"react\";\nimport type { z } from \"zod\";\nimport type { HeroBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { Btn, Heading, Text } from \"../ui\";\nimport { Img } from \"../../media/ImageContext\";\n\ntype Hero = z.infer<typeof HeroBlockSchema>;\n\nexport function HeroRender({ block }: BlockRenderProps<Hero>) {\n // Achtergrondvideo WCAG-proof (2.2.2): geen autoPlay-attribuut (hydration-veilig) — playback\n // start in een effect, en alléén zonder reduced-motion-voorkeur. Altijd een pauzeknop, en\n // imageUrl dient als poster (direct beeld i.p.v. zwart vlak → betere LCP).\n const videoRef = useRef<HTMLVideoElement>(null);\n const [playing, setPlaying] = useState(false);\n useEffect(() => {\n const v = videoRef.current;\n if (!v) return;\n if (window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches) return;\n v.play().then(() => setPlaying(true)).catch(() => undefined);\n }, [block.videoUrl]);\n const toggleVideo = () => {\n const v = videoRef.current;\n if (!v) return;\n if (v.paused) v.play().then(() => setPlaying(true)).catch(() => undefined);\n else {\n v.pause();\n setPlaying(false);\n }\n };\n const overlay =\n block.overlayOpacity > 0\n ? { background: block.overlayColor ?? \"#000000\", opacity: block.overlayOpacity / 100 }\n : null;\n // Beeld/video als dekkende achtergrond (niet bij height \"auto\"): dan moet de tekst licht zijn.\n const coverMedia = Boolean(block.videoUrl || block.imageUrl) && block.minHeight !== \"auto\";\n const light: CSSProperties | undefined = coverMedia\n ? { color: \"#ffffff\", textShadow: \"0 2px 14px rgba(0,0,0,.45)\" }\n : undefined;\n const buttons = block.buttons ?? [];\n\n return (\n <section\n className=\"xicms-hero\"\n data-align={block.align}\n data-valign={block.vAlign}\n data-height={block.minHeight}\n data-media={coverMedia ? \"cover\" : undefined}\n >\n {block.videoUrl ? (\n <video\n ref={videoRef}\n className=\"xicms-hero__media\"\n src={block.videoUrl}\n poster={block.imageUrl || undefined}\n muted\n loop\n playsInline\n preload=\"metadata\"\n aria-hidden=\"true\"\n />\n ) : block.imageUrl ? (\n <Img src={block.imageUrl} alt=\"\" className=\"xicms-hero__media\" width={1600} height={900} sizes=\"100vw\" priority editField=\"imageUrl\" editFill />\n ) : null}\n {overlay && <div className=\"xicms-hero__overlay\" style={overlay} aria-hidden=\"true\" />}\n {/* Gradient (donker onderaan → transparant): leesbare tekst zonder de hele foto te dimmen. */}\n {block.overlayGradient && coverMedia && <div className=\"xicms-hero__gradient\" aria-hidden=\"true\" />}\n <div className=\"xicms-hero__inner\">\n {block.eyebrow && (\n <Text type=\"label\" className=\"xicms-hero__eyebrow\" style={light} data-xicms-edit=\"eyebrow\">\n {block.eyebrow}\n </Text>\n )}\n {block.title && (\n <Heading level={block.headingLevel === \"2\" ? 2 : 1} type=\"display-1\" className=\"xicms-hero__title\" style={light} data-xicms-edit=\"title\">\n {block.title}\n </Heading>\n )}\n {block.subtitle && (\n <Text type=\"large\" className=\"xicms-hero__sub\" style={light} data-xicms-edit=\"subtitle\">\n {block.subtitle}\n </Text>\n )}\n {buttons.length > 0 && (\n <div className=\"xicms-hero__buttons\">\n {/* Via Astryx Btn (zelfde systeem als Cta/Pricing/…): volgt de site-theming en de\n outline→ghost-variantmapping — geen tweede, handmatig te onderhouden knop-CSS. */}\n {buttons.map((b, i) => ({ ...b, _i: i })).filter((b) => b.label).map((b) => (\n <Btn key={b._i} label={b.label} href={b.href} variant={b.variant} size=\"lg\" editField={`buttons.${b._i}.label`} />\n ))}\n </div>\n )}\n </div>\n {block.videoUrl && (\n <button\n type=\"button\"\n className=\"xicms-hero__videotoggle\"\n onClick={toggleVideo}\n aria-label={playing ? \"Achtergrondvideo pauzeren\" : \"Achtergrondvideo afspelen\"}\n >\n {playing ? \"⏸\" : \"▶\"}\n </button>\n )}\n </section>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,2 +1 @@
1
- import type { z } from "zod";
2
- export declare const imageBlock: import("../index.js").BlockDefinition<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
1
+ export declare const imageBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;
@@ -1,28 +1,8 @@
1
- "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import dynamic from "next/dynamic";
3
2
  import { defineBlock } from "../registry.js";
4
- import { Img } from "../../media/ImageContext.js";
5
- function ImageRender({ block }) {
6
- if (!block.url) return null;
7
- const img = /* @__PURE__ */ jsx(
8
- Img,
9
- {
10
- src: block.url,
11
- alt: block.alt ?? "",
12
- width: 1600,
13
- height: 1067,
14
- sizes: "(max-width: 900px) 100vw, 900px",
15
- editField: "url"
16
- }
17
- );
18
- return /* @__PURE__ */ jsxs("figure", { className: "xicms-image", "data-align": block.align, "data-ratio": block.aspectRatio, children: [
19
- block.href ? /* @__PURE__ */ jsx("a", { href: block.href, children: img }) : img,
20
- block.caption && /* @__PURE__ */ jsx("figcaption", { "data-xicms-edit": "caption", children: block.caption })
21
- ] });
22
- }
23
3
  const imageBlock = defineBlock({
24
4
  type: "image",
25
- Render: ImageRender,
5
+ Render: dynamic(() => import("./ImageBlockRender.js").then((m) => m.ImageRender)),
26
6
  label: "Afbeelding",
27
7
  icon: "\u{1F5BC}\uFE0F",
28
8
  defaults: () => ({ alt: "", align: "center", aspectRatio: "auto" })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/ImageBlock.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport type { ImageBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\nimport { Img } from \"../../media/ImageContext\";\n\ntype ImageBlk = z.infer<typeof ImageBlockSchema>;\n\nfunction ImageRender({ block }: BlockRenderProps<ImageBlk>) {\n if (!block.url) return null;\n // Via het geïnjecteerde Img-component (next/image op consumer-sites → optimalisatie/lazy-load)\n // mét editField: klik-om-te-vervangen in de visuele editor. Dit blok — welks hele doel beeld is —\n // was gek genoeg de enige beeld-route zónder beide (rendde om Img heen). De aspect-ratio-CSS\n // (.xicms-image[data-ratio] img) blijft gewoon werken.\n const img = (\n <Img\n src={block.url}\n alt={block.alt ?? \"\"}\n width={1600}\n height={1067}\n sizes=\"(max-width: 900px) 100vw, 900px\"\n editField=\"url\"\n />\n );\n return (\n <figure className=\"xicms-image\" data-align={block.align} data-ratio={block.aspectRatio}>\n {block.href ? <a href={block.href}>{img}</a> : img}\n {block.caption && <figcaption data-xicms-edit=\"caption\">{block.caption}</figcaption>}\n </figure>\n );\n}\n\nexport const imageBlock = defineBlock({\n type: \"image\",\n Render: ImageRender,\n label: \"Afbeelding\",\n icon: \"🖼️\",\n defaults: () => ({ alt: \"\", align: \"center\", aspectRatio: \"auto\" }),\n});\n"],"mappings":";AAgBI,cAUA,YAVA;AAZJ,SAAS,mBAA0C;AACnD,SAAS,WAAW;AAIpB,SAAS,YAAY,EAAE,MAAM,GAA+B;AAC1D,MAAI,CAAC,MAAM,IAAK,QAAO;AAKvB,QAAM,MACJ;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,MAAM;AAAA,MACX,KAAK,MAAM,OAAO;AAAA,MAClB,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAM;AAAA,MACN,WAAU;AAAA;AAAA,EACZ;AAEF,SACE,qBAAC,YAAO,WAAU,eAAc,cAAY,MAAM,OAAO,cAAY,MAAM,aACxE;AAAA,UAAM,OAAO,oBAAC,OAAE,MAAM,MAAM,MAAO,eAAI,IAAO;AAAA,IAC9C,MAAM,WAAW,oBAAC,gBAAW,mBAAgB,WAAW,gBAAM,SAAQ;AAAA,KACzE;AAEJ;AAEO,MAAM,aAAa,YAAY;AAAA,EACpC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,KAAK,IAAI,OAAO,UAAU,aAAa,OAAO;AACnE,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/ImageBlock.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const imageBlock = defineBlock({\n type: \"image\",\n Render: dynamic(() => import(\"./ImageBlockRender\").then((m) => m.ImageRender)),\n label: \"Afbeelding\",\n icon: \"🖼️\",\n defaults: () => ({ alt: \"\", align: \"center\", aspectRatio: \"auto\" }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,aAAa,YAAY;AAAA,EACpC,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,oBAAoB,EAAE,KAAK,CAAC,MAAM,EAAE,WAAW,CAAC;AAAA,EAC7E,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,KAAK,IAAI,OAAO,UAAU,aAAa,OAAO;AACnE,CAAC;","names":[]}
@@ -0,0 +1,6 @@
1
+ import type { z } from "zod";
2
+ import type { ImageBlockSchema } from "../../schema/blocks.js";
3
+ import type { BlockRenderProps } from "../registry.js";
4
+ type ImageBlk = z.infer<typeof ImageBlockSchema>;
5
+ export declare function ImageRender({ block }: BlockRenderProps<ImageBlk>): import("react").JSX.Element | null;
6
+ export {};
@@ -0,0 +1,25 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { Img } from "../../media/ImageContext.js";
4
+ function ImageRender({ block }) {
5
+ if (!block.url) return null;
6
+ const img = /* @__PURE__ */ jsx(
7
+ Img,
8
+ {
9
+ src: block.url,
10
+ alt: block.alt ?? "",
11
+ width: 1600,
12
+ height: 1067,
13
+ sizes: "(max-width: 900px) 100vw, 900px",
14
+ editField: "url"
15
+ }
16
+ );
17
+ return /* @__PURE__ */ jsxs("figure", { className: "xicms-image", "data-align": block.align, "data-ratio": block.aspectRatio, children: [
18
+ block.href ? /* @__PURE__ */ jsx("a", { href: block.href, children: img }) : img,
19
+ block.caption && /* @__PURE__ */ jsx("figcaption", { "data-xicms-edit": "caption", children: block.caption })
20
+ ] });
21
+ }
22
+ export {
23
+ ImageRender
24
+ };
25
+ //# sourceMappingURL=ImageBlockRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/ImageBlockRender.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport type { ImageBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { Img } from \"../../media/ImageContext\";\n\ntype ImageBlk = z.infer<typeof ImageBlockSchema>;\n\nexport function ImageRender({ block }: BlockRenderProps<ImageBlk>) {\n if (!block.url) return null;\n // Via het geïnjecteerde Img-component (next/image op consumer-sites → optimalisatie/lazy-load)\n // mét editField: klik-om-te-vervangen in de visuele editor. Dit blok — welks hele doel beeld is —\n // was gek genoeg de enige beeld-route zónder beide (rendde om Img heen). De aspect-ratio-CSS\n // (.xicms-image[data-ratio] img) blijft gewoon werken.\n const img = (\n <Img\n src={block.url}\n alt={block.alt ?? \"\"}\n width={1600}\n height={1067}\n sizes=\"(max-width: 900px) 100vw, 900px\"\n editField=\"url\"\n />\n );\n return (\n <figure className=\"xicms-image\" data-align={block.align} data-ratio={block.aspectRatio}>\n {block.href ? <a href={block.href}>{img}</a> : img}\n {block.caption && <figcaption data-xicms-edit=\"caption\">{block.caption}</figcaption>}\n </figure>\n );\n}\n"],"mappings":";AAgBI,cAUA,YAVA;AAXJ,SAAS,WAAW;AAIb,SAAS,YAAY,EAAE,MAAM,GAA+B;AACjE,MAAI,CAAC,MAAM,IAAK,QAAO;AAKvB,QAAM,MACJ;AAAA,IAAC;AAAA;AAAA,MACC,KAAK,MAAM;AAAA,MACX,KAAK,MAAM,OAAO;AAAA,MAClB,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,OAAM;AAAA,MACN,WAAU;AAAA;AAAA,EACZ;AAEF,SACE,qBAAC,YAAO,WAAU,eAAc,cAAY,MAAM,OAAO,cAAY,MAAM,aACxE;AAAA,UAAM,OAAO,oBAAC,OAAE,MAAM,MAAM,MAAO,eAAI,IAAO;AAAA,IAC9C,MAAM,WAAW,oBAAC,gBAAW,mBAAgB,WAAW,gBAAM,SAAQ;AAAA,KACzE;AAEJ;","names":[]}
@@ -1,15 +1 @@
1
- import type { z } from "zod";
2
- import type { JobsBlockSchema } from "../../schema/blocks.js";
3
- type Jobs = z.infer<typeof JobsBlockSchema>;
4
- type JobItem = Jobs["items"][number];
5
- /** Vrije-tekst dienstverband → schema.org-enum (Google keurt vrije tekst af). */
6
- export declare function employmentTypeEnum(value?: string): string | null;
7
- /**
8
- * JobPosting-JSON-LD per vacature (Google Jobs). Puur en getest. Alleen vacatures met de door
9
- * Google vereiste kernvelden (titel + plaatsingsdatum + locatie + omschrijving) komen in de JSON-LD
10
- * — incomplete items renderen wél op de pagina maar leveren geen Search-Console-errors op. Salaris
11
- * ("€ 2.800 – € 3.400 p/m") is geen geldige MonetaryAmount en wordt bewust weggelaten.
12
- */
13
- export declare function jobsJsonLd(items: JobItem[], orgName: string): Array<Record<string, unknown>>;
14
- export declare const jobsBlock: import("../index.js").BlockDefinition<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
15
- export {};
1
+ export declare const jobsBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;
@@ -1,73 +1,9 @@
1
- "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
1
+ import dynamic from "next/dynamic";
3
2
  import { defineBlock } from "../registry.js";
4
- import { useSiteConfig } from "../../config.js";
5
- import { VStack, Card, Heading, Text, Btn } from "../ui/index.js";
6
- import { jsonLdHtml } from "./jsonld.js";
7
- function employmentTypeEnum(value) {
8
- const v = (value ?? "").toLowerCase();
9
- if (!v) return null;
10
- if (v.includes("full") || v.includes("voltijd")) return "FULL_TIME";
11
- if (v.includes("part") || v.includes("deeltijd") || /\d+\s*[–-]?\s*\d*\s*uur/.test(v)) return "PART_TIME";
12
- if (v.includes("bbl") || v.includes("leerling") || v.includes("stage") || v.includes("intern")) return "INTERN";
13
- if (v.includes("tijdelijk") || v.includes("temp")) return "TEMPORARY";
14
- if (v.includes("zzp") || v.includes("freelance") || v.includes("contract")) return "CONTRACTOR";
15
- return null;
16
- }
17
- function jobsJsonLd(items, orgName) {
18
- return items.filter((j) => j.title && j.datePosted && j.location && j.description).map((j) => {
19
- const employment = employmentTypeEnum(j.employmentType);
20
- return {
21
- "@context": "https://schema.org",
22
- "@type": "JobPosting",
23
- title: j.title,
24
- hiringOrganization: { "@type": "Organization", name: orgName },
25
- ...j.description ? { description: j.description } : {},
26
- datePosted: j.datePosted,
27
- ...employment ? { employmentType: employment } : {},
28
- jobLocation: { "@type": "Place", address: { "@type": "PostalAddress", addressLocality: j.location } },
29
- ...j.applyUrl ? { url: j.applyUrl } : {}
30
- };
31
- });
32
- }
33
- function JobsRender({ block }) {
34
- const { name } = useSiteConfig();
35
- const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((j) => j.title);
36
- if (items.length === 0 && !block.heading) return null;
37
- return /* @__PURE__ */ jsxs(VStack, { gap: 4, as: "section", className: "xicms-jobs", children: [
38
- (block.heading || block.intro) && /* @__PURE__ */ jsxs(VStack, { gap: 1, children: [
39
- block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
40
- block.intro && /* @__PURE__ */ jsx(Text, { color: "secondary", "data-xicms-edit": "intro", children: block.intro })
41
- ] }),
42
- items.length === 0 && /* @__PURE__ */ jsx(Text, { color: "secondary", children: "Er zijn op dit moment geen openstaande vacatures." }),
43
- /* @__PURE__ */ jsx(VStack, { gap: 3, children: items.map((j) => {
44
- const i = j._i;
45
- return /* @__PURE__ */ jsx(Card, { padding: 4, className: "xicms-jobs__item", children: /* @__PURE__ */ jsxs(VStack, { gap: 1.5, children: [
46
- /* @__PURE__ */ jsxs("div", { className: "xicms-jobs__head", children: [
47
- /* @__PURE__ */ jsx(Heading, { level: 3, "data-xicms-edit": `items.${i}.title`, children: j.title }),
48
- /* @__PURE__ */ jsx("span", { className: "xicms-jobs__meta", children: ["employmentType", "location", "salary"].map((veld) => ({ veld, waarde: j[veld] })).filter((f) => f.waarde).map((f, n) => /* @__PURE__ */ jsxs("span", { children: [
49
- n > 0 && " \xB7 ",
50
- /* @__PURE__ */ jsx("span", { "data-xicms-edit": `items.${i}.${f.veld}`, children: f.waarde })
51
- ] }, f.veld)) })
52
- ] }),
53
- j.description && /* @__PURE__ */ jsx(Text, { color: "secondary", "data-xicms-edit": `items.${i}.description`, children: j.description }),
54
- j.applyUrl && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Btn, { label: "Solliciteer", href: j.applyUrl, variant: "primary" }) })
55
- ] }) }, i);
56
- }) }),
57
- block.jsonLd && jobsJsonLd(items, name).map((ld, i) => /* @__PURE__ */ jsx(
58
- "script",
59
- {
60
- type: "application/ld+json",
61
- dangerouslySetInnerHTML: { __html: jsonLdHtml(ld) }
62
- },
63
- i
64
- ))
65
- ] });
66
- }
67
3
  const jobsBlock = defineBlock({
68
4
  type: "jobs",
69
5
  fields: { "items.datePosted": { type: "date" } },
70
- Render: JobsRender,
6
+ Render: dynamic(() => import("./JobsRender.js").then((m) => m.JobsRender)),
71
7
  label: "Vacatures",
72
8
  icon: "\u{1F9D1}\u200D\u{1F527}",
73
9
  defaults: () => ({
@@ -77,8 +13,6 @@ const jobsBlock = defineBlock({
77
13
  })
78
14
  });
79
15
  export {
80
- employmentTypeEnum,
81
- jobsBlock,
82
- jobsJsonLd
16
+ jobsBlock
83
17
  };
84
18
  //# sourceMappingURL=Jobs.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/Jobs.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport type { JobsBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\nimport { useSiteConfig } from \"../../config\";\nimport { VStack, Card, Heading, Text, Btn } from \"../ui\";\nimport { jsonLdHtml } from \"./jsonld\";\n\ntype Jobs = z.infer<typeof JobsBlockSchema>;\ntype JobItem = Jobs[\"items\"][number];\n\n/** Vrije-tekst dienstverband → schema.org-enum (Google keurt vrije tekst af). */\nexport function employmentTypeEnum(value?: string): string | null {\n const v = (value ?? \"\").toLowerCase();\n if (!v) return null;\n if (v.includes(\"full\") || v.includes(\"voltijd\")) return \"FULL_TIME\";\n if (v.includes(\"part\") || v.includes(\"deeltijd\") || /\\d+\\s*[–-]?\\s*\\d*\\s*uur/.test(v)) return \"PART_TIME\";\n if (v.includes(\"bbl\") || v.includes(\"leerling\") || v.includes(\"stage\") || v.includes(\"intern\")) return \"INTERN\";\n if (v.includes(\"tijdelijk\") || v.includes(\"temp\")) return \"TEMPORARY\";\n if (v.includes(\"zzp\") || v.includes(\"freelance\") || v.includes(\"contract\")) return \"CONTRACTOR\";\n return null;\n}\n\n/**\n * JobPosting-JSON-LD per vacature (Google Jobs). Puur en getest. Alleen vacatures met de door\n * Google vereiste kernvelden (titel + plaatsingsdatum + locatie + omschrijving) komen in de JSON-LD\n * — incomplete items renderen wél op de pagina maar leveren geen Search-Console-errors op. Salaris\n * (\"€ 2.800 – € 3.400 p/m\") is geen geldige MonetaryAmount en wordt bewust weggelaten.\n */\nexport function jobsJsonLd(items: JobItem[], orgName: string): Array<Record<string, unknown>> {\n return items\n .filter((j) => j.title && j.datePosted && j.location && j.description)\n .map((j) => {\n const employment = employmentTypeEnum(j.employmentType);\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"JobPosting\",\n title: j.title,\n hiringOrganization: { \"@type\": \"Organization\", name: orgName },\n ...(j.description ? { description: j.description } : {}),\n datePosted: j.datePosted,\n ...(employment ? { employmentType: employment } : {}),\n jobLocation: { \"@type\": \"Place\", address: { \"@type\": \"PostalAddress\", addressLocality: j.location } },\n ...(j.applyUrl ? { url: j.applyUrl } : {}),\n };\n });\n}\n\n/** Vacature-overzicht met JobPosting-JSON-LD — vindbaar via Google Jobs. */\nfunction JobsRender({ block }: BlockRenderProps<Jobs>) {\n const { name } = useSiteConfig();\n // _i = index in de OORSPRONKELIJKE array — inline-edit-paden (items.N.title) moeten daarheen wijzen.\n const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((j) => j.title);\n if (items.length === 0 && !block.heading) return null;\n return (\n <VStack gap={4} as=\"section\" className=\"xicms-jobs\">\n {(block.heading || block.intro) && (\n <VStack gap={1}>\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n {block.intro && <Text color=\"secondary\" data-xicms-edit=\"intro\">{block.intro}</Text>}\n </VStack>\n )}\n {items.length === 0 && <Text color=\"secondary\">Er zijn op dit moment geen openstaande vacatures.</Text>}\n <VStack gap={3}>\n {items.map((j) => {\n const i = j._i;\n return (\n <Card key={i} padding={4} className=\"xicms-jobs__item\">\n <VStack gap={1.5}>\n <div className=\"xicms-jobs__head\">\n <Heading level={3} data-xicms-edit={`items.${i}.title`}>{j.title}</Heading>\n <span className=\"xicms-jobs__meta\">\n {([\"employmentType\", \"location\", \"salary\"] as const)\n .map((veld) => ({ veld, waarde: j[veld] }))\n .filter((f) => f.waarde)\n .map((f, n) => (\n <span key={f.veld}>\n {n > 0 && \" · \"}\n <span data-xicms-edit={`items.${i}.${f.veld}`}>{f.waarde}</span>\n </span>\n ))}\n </span>\n </div>\n {j.description && <Text color=\"secondary\" data-xicms-edit={`items.${i}.description`}>{j.description}</Text>}\n {j.applyUrl && (\n <div>\n <Btn label=\"Solliciteer\" href={j.applyUrl} variant=\"primary\" />\n </div>\n )}\n </VStack>\n </Card>\n );\n })}\n </VStack>\n {block.jsonLd &&\n jobsJsonLd(items, name).map((ld, i) => (\n <script\n key={i}\n type=\"application/ld+json\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: jsonLdHtml(ld) }}\n />\n ))}\n </VStack>\n );\n}\n\nexport const jobsBlock = defineBlock({\n type: \"jobs\",\n fields: { \"items.datePosted\": { type: \"date\" } },\n Render: JobsRender,\n label: \"Vacatures\",\n icon: \"🧑‍🔧\",\n defaults: () => ({\n heading: \"Vacatures\",\n items: [{ title: \"Vacaturetitel\", employmentType: \"Fulltime\", location: \"\" }],\n jsonLd: true,\n }),\n});\n"],"mappings":";AA0DQ,SACoB,KADpB;AAtDR,SAAS,mBAA0C;AACnD,SAAS,qBAAqB;AAC9B,SAAS,QAAQ,MAAM,SAAS,MAAM,WAAW;AACjD,SAAS,kBAAkB;AAMpB,SAAS,mBAAmB,OAA+B;AAChE,QAAM,KAAK,SAAS,IAAI,YAAY;AACpC,MAAI,CAAC,EAAG,QAAO;AACf,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,SAAS,EAAG,QAAO;AACxD,MAAI,EAAE,SAAS,MAAM,KAAK,EAAE,SAAS,UAAU,KAAK,0BAA0B,KAAK,CAAC,EAAG,QAAO;AAC9F,MAAI,EAAE,SAAS,KAAK,KAAK,EAAE,SAAS,UAAU,KAAK,EAAE,SAAS,OAAO,KAAK,EAAE,SAAS,QAAQ,EAAG,QAAO;AACvG,MAAI,EAAE,SAAS,WAAW,KAAK,EAAE,SAAS,MAAM,EAAG,QAAO;AAC1D,MAAI,EAAE,SAAS,KAAK,KAAK,EAAE,SAAS,WAAW,KAAK,EAAE,SAAS,UAAU,EAAG,QAAO;AACnF,SAAO;AACT;AAQO,SAAS,WAAW,OAAkB,SAAiD;AAC5F,SAAO,MACJ,OAAO,CAAC,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,YAAY,EAAE,WAAW,EACpE,IAAI,CAAC,MAAM;AACV,UAAM,aAAa,mBAAmB,EAAE,cAAc;AACtD,WAAO;AAAA,MACL,YAAY;AAAA,MACZ,SAAS;AAAA,MACT,OAAO,EAAE;AAAA,MACT,oBAAoB,EAAE,SAAS,gBAAgB,MAAM,QAAQ;AAAA,MAC7D,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,MACtD,YAAY,EAAE;AAAA,MACd,GAAI,aAAa,EAAE,gBAAgB,WAAW,IAAI,CAAC;AAAA,MACnD,aAAa,EAAE,SAAS,SAAS,SAAS,EAAE,SAAS,iBAAiB,iBAAiB,EAAE,SAAS,EAAE;AAAA,MACpG,GAAI,EAAE,WAAW,EAAE,KAAK,EAAE,SAAS,IAAI,CAAC;AAAA,IAC1C;AAAA,EACF,CAAC;AACL;AAGA,SAAS,WAAW,EAAE,MAAM,GAA2B;AACrD,QAAM,EAAE,KAAK,IAAI,cAAc;AAE/B,QAAM,SAAS,MAAM,SAAS,CAAC,GAAG,IAAI,CAAC,IAAI,OAAO,EAAE,GAAG,IAAI,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,KAAK;AAC1F,MAAI,MAAM,WAAW,KAAK,CAAC,MAAM,QAAS,QAAO;AACjD,SACE,qBAAC,UAAO,KAAK,GAAG,IAAG,WAAU,WAAU,cACnC;AAAA,WAAM,WAAW,MAAM,UACvB,qBAAC,UAAO,KAAK,GACV;AAAA,YAAM,WAAW,oBAAC,WAAQ,OAAO,GAAG,mBAAgB,WAAW,gBAAM,SAAQ;AAAA,MAC7E,MAAM,SAAS,oBAAC,QAAK,OAAM,aAAY,mBAAgB,SAAS,gBAAM,OAAM;AAAA,OAC/E;AAAA,IAED,MAAM,WAAW,KAAK,oBAAC,QAAK,OAAM,aAAY,+DAAiD;AAAA,IAChG,oBAAC,UAAO,KAAK,GACV,gBAAM,IAAI,CAAC,MAAM;AAChB,YAAM,IAAI,EAAE;AACZ,aACA,oBAAC,QAAa,SAAS,GAAG,WAAU,oBAClC,+BAAC,UAAO,KAAK,KACX;AAAA,6BAAC,SAAI,WAAU,oBACb;AAAA,8BAAC,WAAQ,OAAO,GAAG,mBAAiB,SAAS,CAAC,UAAW,YAAE,OAAM;AAAA,UACjE,oBAAC,UAAK,WAAU,oBACZ,WAAC,kBAAkB,YAAY,QAAQ,EACtC,IAAI,CAAC,UAAU,EAAE,MAAM,QAAQ,EAAE,IAAI,EAAE,EAAE,EACzC,OAAO,CAAC,MAAM,EAAE,MAAM,EACtB,IAAI,CAAC,GAAG,MACP,qBAAC,UACE;AAAA,gBAAI,KAAK;AAAA,YACV,oBAAC,UAAK,mBAAiB,SAAS,CAAC,IAAI,EAAE,IAAI,IAAK,YAAE,QAAO;AAAA,eAFhD,EAAE,IAGb,CACD,GACL;AAAA,WACF;AAAA,QACC,EAAE,eAAe,oBAAC,QAAK,OAAM,aAAY,mBAAiB,SAAS,CAAC,gBAAiB,YAAE,aAAY;AAAA,QACnG,EAAE,YACD,oBAAC,SACC,8BAAC,OAAI,OAAM,eAAc,MAAM,EAAE,UAAU,SAAQ,WAAU,GAC/D;AAAA,SAEJ,KAtBS,CAuBX;AAAA,IAEF,CAAC,GACH;AAAA,IACC,MAAM,UACL,WAAW,OAAO,IAAI,EAAE,IAAI,CAAC,IAAI,MAC/B;AAAA,MAAC;AAAA;AAAA,QAEC,MAAK;AAAA,QAEL,yBAAyB,EAAE,QAAQ,WAAW,EAAE,EAAE;AAAA;AAAA,MAH7C;AAAA,IAIP,CACD;AAAA,KACL;AAEJ;AAEO,MAAM,YAAY,YAAY;AAAA,EACnC,MAAM;AAAA,EACN,QAAQ,EAAE,oBAAoB,EAAE,MAAM,OAAO,EAAE;AAAA,EAC/C,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO;AAAA,IACf,SAAS;AAAA,IACT,OAAO,CAAC,EAAE,OAAO,iBAAiB,gBAAgB,YAAY,UAAU,GAAG,CAAC;AAAA,IAC5E,QAAQ;AAAA,EACV;AACF,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Jobs.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const jobsBlock = defineBlock({\n type: \"jobs\",\n fields: { \"items.datePosted\": { type: \"date\" } },\n Render: dynamic(() => import(\"./JobsRender\").then((m) => m.JobsRender)),\n label: \"Vacatures\",\n icon: \"🧑‍🔧\",\n defaults: () => ({\n heading: \"Vacatures\",\n items: [{ title: \"Vacaturetitel\", employmentType: \"Fulltime\", location: \"\" }],\n jsonLd: true,\n }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,YAAY,YAAY;AAAA,EACnC,MAAM;AAAA,EACN,QAAQ,EAAE,oBAAoB,EAAE,MAAM,OAAO,EAAE;AAAA,EAC/C,QAAQ,QAAQ,MAAM,OAAO,cAAc,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC;AAAA,EACtE,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO;AAAA,IACf,SAAS;AAAA,IACT,OAAO,CAAC,EAAE,OAAO,iBAAiB,gBAAgB,YAAY,UAAU,GAAG,CAAC;AAAA,IAC5E,QAAQ;AAAA,EACV;AACF,CAAC;","names":[]}
@@ -0,0 +1,17 @@
1
+ import type { z } from "zod";
2
+ import type { JobsBlockSchema } from "../../schema/blocks.js";
3
+ import type { BlockRenderProps } from "../registry.js";
4
+ type Jobs = z.infer<typeof JobsBlockSchema>;
5
+ type JobItem = Jobs["items"][number];
6
+ /** Vrije-tekst dienstverband → schema.org-enum (Google keurt vrije tekst af). */
7
+ export declare function employmentTypeEnum(value?: string): string | null;
8
+ /**
9
+ * JobPosting-JSON-LD per vacature (Google Jobs). Puur en getest. Alleen vacatures met de door
10
+ * Google vereiste kernvelden (titel + plaatsingsdatum + locatie + omschrijving) komen in de JSON-LD
11
+ * — incomplete items renderen wél op de pagina maar leveren geen Search-Console-errors op. Salaris
12
+ * ("€ 2.800 – € 3.400 p/m") is geen geldige MonetaryAmount en wordt bewust weggelaten.
13
+ */
14
+ export declare function jobsJsonLd(items: JobItem[], orgName: string): Array<Record<string, unknown>>;
15
+ /** Vacature-overzicht met JobPosting-JSON-LD — vindbaar via Google Jobs. */
16
+ export declare function JobsRender({ block }: BlockRenderProps<Jobs>): import("react").JSX.Element | null;
17
+ export {};
@@ -0,0 +1,71 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useSiteConfig } from "../../config.js";
4
+ import { VStack, Card, Heading, Text, Btn } from "../ui/index.js";
5
+ import { jsonLdHtml } from "./jsonld.js";
6
+ function employmentTypeEnum(value) {
7
+ const v = (value ?? "").toLowerCase();
8
+ if (!v) return null;
9
+ if (v.includes("full") || v.includes("voltijd")) return "FULL_TIME";
10
+ if (v.includes("part") || v.includes("deeltijd") || /\d+\s*[–-]?\s*\d*\s*uur/.test(v)) return "PART_TIME";
11
+ if (v.includes("bbl") || v.includes("leerling") || v.includes("stage") || v.includes("intern")) return "INTERN";
12
+ if (v.includes("tijdelijk") || v.includes("temp")) return "TEMPORARY";
13
+ if (v.includes("zzp") || v.includes("freelance") || v.includes("contract")) return "CONTRACTOR";
14
+ return null;
15
+ }
16
+ function jobsJsonLd(items, orgName) {
17
+ return items.filter((j) => j.title && j.datePosted && j.location && j.description).map((j) => {
18
+ const employment = employmentTypeEnum(j.employmentType);
19
+ return {
20
+ "@context": "https://schema.org",
21
+ "@type": "JobPosting",
22
+ title: j.title,
23
+ hiringOrganization: { "@type": "Organization", name: orgName },
24
+ ...j.description ? { description: j.description } : {},
25
+ datePosted: j.datePosted,
26
+ ...employment ? { employmentType: employment } : {},
27
+ jobLocation: { "@type": "Place", address: { "@type": "PostalAddress", addressLocality: j.location } },
28
+ ...j.applyUrl ? { url: j.applyUrl } : {}
29
+ };
30
+ });
31
+ }
32
+ function JobsRender({ block }) {
33
+ const { name } = useSiteConfig();
34
+ const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((j) => j.title);
35
+ if (items.length === 0 && !block.heading) return null;
36
+ return /* @__PURE__ */ jsxs(VStack, { gap: 4, as: "section", className: "xicms-jobs", children: [
37
+ (block.heading || block.intro) && /* @__PURE__ */ jsxs(VStack, { gap: 1, children: [
38
+ block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
39
+ block.intro && /* @__PURE__ */ jsx(Text, { color: "secondary", "data-xicms-edit": "intro", children: block.intro })
40
+ ] }),
41
+ items.length === 0 && /* @__PURE__ */ jsx(Text, { color: "secondary", children: "Er zijn op dit moment geen openstaande vacatures." }),
42
+ /* @__PURE__ */ jsx(VStack, { gap: 3, children: items.map((j) => {
43
+ const i = j._i;
44
+ return /* @__PURE__ */ jsx(Card, { padding: 4, className: "xicms-jobs__item", children: /* @__PURE__ */ jsxs(VStack, { gap: 1.5, children: [
45
+ /* @__PURE__ */ jsxs("div", { className: "xicms-jobs__head", children: [
46
+ /* @__PURE__ */ jsx(Heading, { level: 3, "data-xicms-edit": `items.${i}.title`, children: j.title }),
47
+ /* @__PURE__ */ jsx("span", { className: "xicms-jobs__meta", children: ["employmentType", "location", "salary"].map((veld) => ({ veld, waarde: j[veld] })).filter((f) => f.waarde).map((f, n) => /* @__PURE__ */ jsxs("span", { children: [
48
+ n > 0 && " \xB7 ",
49
+ /* @__PURE__ */ jsx("span", { "data-xicms-edit": `items.${i}.${f.veld}`, children: f.waarde })
50
+ ] }, f.veld)) })
51
+ ] }),
52
+ j.description && /* @__PURE__ */ jsx(Text, { color: "secondary", "data-xicms-edit": `items.${i}.description`, children: j.description }),
53
+ j.applyUrl && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Btn, { label: "Solliciteer", href: j.applyUrl, variant: "primary" }) })
54
+ ] }) }, i);
55
+ }) }),
56
+ block.jsonLd && jobsJsonLd(items, name).map((ld, i) => /* @__PURE__ */ jsx(
57
+ "script",
58
+ {
59
+ type: "application/ld+json",
60
+ dangerouslySetInnerHTML: { __html: jsonLdHtml(ld) }
61
+ },
62
+ i
63
+ ))
64
+ ] });
65
+ }
66
+ export {
67
+ JobsRender,
68
+ employmentTypeEnum,
69
+ jobsJsonLd
70
+ };
71
+ //# sourceMappingURL=JobsRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/JobsRender.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport type { JobsBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { useSiteConfig } from \"../../config\";\nimport { VStack, Card, Heading, Text, Btn } from \"../ui\";\nimport { jsonLdHtml } from \"./jsonld\";\n\ntype Jobs = z.infer<typeof JobsBlockSchema>;\ntype JobItem = Jobs[\"items\"][number];\n\n/** Vrije-tekst dienstverband → schema.org-enum (Google keurt vrije tekst af). */\nexport function employmentTypeEnum(value?: string): string | null {\n const v = (value ?? \"\").toLowerCase();\n if (!v) return null;\n if (v.includes(\"full\") || v.includes(\"voltijd\")) return \"FULL_TIME\";\n if (v.includes(\"part\") || v.includes(\"deeltijd\") || /\\d+\\s*[–-]?\\s*\\d*\\s*uur/.test(v)) return \"PART_TIME\";\n if (v.includes(\"bbl\") || v.includes(\"leerling\") || v.includes(\"stage\") || v.includes(\"intern\")) return \"INTERN\";\n if (v.includes(\"tijdelijk\") || v.includes(\"temp\")) return \"TEMPORARY\";\n if (v.includes(\"zzp\") || v.includes(\"freelance\") || v.includes(\"contract\")) return \"CONTRACTOR\";\n return null;\n}\n\n/**\n * JobPosting-JSON-LD per vacature (Google Jobs). Puur en getest. Alleen vacatures met de door\n * Google vereiste kernvelden (titel + plaatsingsdatum + locatie + omschrijving) komen in de JSON-LD\n * — incomplete items renderen wél op de pagina maar leveren geen Search-Console-errors op. Salaris\n * (\"€ 2.800 – € 3.400 p/m\") is geen geldige MonetaryAmount en wordt bewust weggelaten.\n */\nexport function jobsJsonLd(items: JobItem[], orgName: string): Array<Record<string, unknown>> {\n return items\n .filter((j) => j.title && j.datePosted && j.location && j.description)\n .map((j) => {\n const employment = employmentTypeEnum(j.employmentType);\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"JobPosting\",\n title: j.title,\n hiringOrganization: { \"@type\": \"Organization\", name: orgName },\n ...(j.description ? { description: j.description } : {}),\n datePosted: j.datePosted,\n ...(employment ? { employmentType: employment } : {}),\n jobLocation: { \"@type\": \"Place\", address: { \"@type\": \"PostalAddress\", addressLocality: j.location } },\n ...(j.applyUrl ? { url: j.applyUrl } : {}),\n };\n });\n}\n\n/** Vacature-overzicht met JobPosting-JSON-LD — vindbaar via Google Jobs. */\nexport function JobsRender({ block }: BlockRenderProps<Jobs>) {\n const { name } = useSiteConfig();\n // _i = index in de OORSPRONKELIJKE array — inline-edit-paden (items.N.title) moeten daarheen wijzen.\n const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((j) => j.title);\n if (items.length === 0 && !block.heading) return null;\n return (\n <VStack gap={4} as=\"section\" className=\"xicms-jobs\">\n {(block.heading || block.intro) && (\n <VStack gap={1}>\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n {block.intro && <Text color=\"secondary\" data-xicms-edit=\"intro\">{block.intro}</Text>}\n </VStack>\n )}\n {items.length === 0 && <Text color=\"secondary\">Er zijn op dit moment geen openstaande vacatures.</Text>}\n <VStack gap={3}>\n {items.map((j) => {\n const i = j._i;\n return (\n <Card key={i} padding={4} className=\"xicms-jobs__item\">\n <VStack gap={1.5}>\n <div className=\"xicms-jobs__head\">\n <Heading level={3} data-xicms-edit={`items.${i}.title`}>{j.title}</Heading>\n <span className=\"xicms-jobs__meta\">\n {([\"employmentType\", \"location\", \"salary\"] as const)\n .map((veld) => ({ veld, waarde: j[veld] }))\n .filter((f) => f.waarde)\n .map((f, n) => (\n <span key={f.veld}>\n {n > 0 && \" · \"}\n <span data-xicms-edit={`items.${i}.${f.veld}`}>{f.waarde}</span>\n </span>\n ))}\n </span>\n </div>\n {j.description && <Text color=\"secondary\" data-xicms-edit={`items.${i}.description`}>{j.description}</Text>}\n {j.applyUrl && (\n <div>\n <Btn label=\"Solliciteer\" href={j.applyUrl} variant=\"primary\" />\n </div>\n )}\n </VStack>\n </Card>\n );\n })}\n </VStack>\n {block.jsonLd &&\n jobsJsonLd(items, name).map((ld, i) => (\n <script\n key={i}\n type=\"application/ld+json\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: jsonLdHtml(ld) }}\n />\n ))}\n </VStack>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,3 +1,2 @@
1
- import type { z } from "zod";
2
- export declare const withSidebarBlock: import("../index.js").BlockDefinition<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
3
- export declare const tabsBlock: import("../index.js").BlockDefinition<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
1
+ export declare const withSidebarBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;
2
+ export declare const tabsBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;
@@ -1,52 +1,16 @@
1
- "use client";
2
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useState } from "react";
1
+ import dynamic from "next/dynamic";
4
2
  import { defineBlock } from "../registry.js";
5
- import { BlockRenderer } from "../BlockRenderer.js";
6
- import { useRegistry } from "../context.js";
7
- import { TabList, Tab } from "@astryxdesign/core/TabList";
8
- function WithSidebarRender({ block, siteId, mode }) {
9
- const registry = useRegistry();
10
- const main = /* @__PURE__ */ jsx("div", { className: "xicms-sidebar__main", children: /* @__PURE__ */ jsx(BlockRenderer, { blocks: block.main, registry, siteId, mode }) });
11
- const aside = /* @__PURE__ */ jsx("aside", { "aria-label": "Zijbalk", className: `xicms-sidebar__aside${block.sticky ? " xicms-sidebar__aside--sticky" : ""}`, children: /* @__PURE__ */ jsx(BlockRenderer, { blocks: block.aside, registry, siteId, mode }) });
12
- return /* @__PURE__ */ jsx(
13
- "div",
14
- {
15
- className: "xicms-sidebar",
16
- "data-side": block.side,
17
- "data-width": block.sidebarWidth,
18
- children: block.side === "left" ? /* @__PURE__ */ jsxs(Fragment, { children: [
19
- aside,
20
- main
21
- ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
22
- main,
23
- aside
24
- ] })
25
- }
26
- );
27
- }
28
3
  const withSidebarBlock = defineBlock({
29
4
  type: "withSidebar",
30
- Render: WithSidebarRender,
5
+ Render: dynamic(() => import("./LayoutRender.js").then((m) => m.WithSidebarRender)),
31
6
  label: "Met zijbalk",
32
7
  icon: "\u25A4",
33
8
  category: "layout",
34
9
  defaults: () => ({ main: [], aside: [], side: "right", sidebarWidth: "md", sticky: true })
35
10
  });
36
- function TabsRender({ block, siteId, mode }) {
37
- const registry = useRegistry();
38
- const tabs = block.tabs ?? [];
39
- const [active, setActive] = useState("0");
40
- if (tabs.length === 0) return null;
41
- const current = Math.min(Math.max(Number(active) || 0, 0), tabs.length - 1);
42
- return /* @__PURE__ */ jsxs("section", { className: "xicms-tabs", children: [
43
- /* @__PURE__ */ jsx(TabList, { value: String(current), onChange: setActive, hasDivider: true, children: tabs.map((t, i) => /* @__PURE__ */ jsx(Tab, { value: String(i), label: t.label || `Tab ${i + 1}` }, i)) }),
44
- /* @__PURE__ */ jsx("div", { role: "tabpanel", "aria-label": tabs[current].label || `Tab ${current + 1}`, style: { marginTop: "1.25rem" }, children: /* @__PURE__ */ jsx(BlockRenderer, { blocks: tabs[current].blocks, registry, siteId, mode }) })
45
- ] });
46
- }
47
11
  const tabsBlock = defineBlock({
48
12
  type: "tabs",
49
- Render: TabsRender,
13
+ Render: dynamic(() => import("./LayoutRender.js").then((m) => m.TabsRender)),
50
14
  label: "Tabbladen",
51
15
  icon: "\u{1F5C2}\uFE0F",
52
16
  category: "layout",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/Layout.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { WithSidebarBlockSchema, TabsBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\nimport { BlockRenderer } from \"../BlockRenderer\";\nimport { useRegistry } from \"../context\";\nimport { TabList, Tab } from \"@astryxdesign/core/TabList\";\n\n/* ── Met zijbalk ───────────────────────────────────────────────────────────\n * Brede hoofdkolom + smalle (sticky) zijbalk. De zijbalk is dé plek voor de compacte\n * widget-varianten (\"laatste nieuws\", \"komende agenda\", contact, …). Beide kanten zijn\n * gewone block-arrays, dus alles wat op een pagina kan, kan ook hier. */\ntype WithSidebar = z.infer<typeof WithSidebarBlockSchema>;\n\nfunction WithSidebarRender({ block, siteId, mode }: BlockRenderProps<WithSidebar>) {\n const registry = useRegistry();\n const main = (\n <div className=\"xicms-sidebar__main\">\n <BlockRenderer blocks={block.main} registry={registry} siteId={siteId} mode={mode} />\n </div>\n );\n const aside = (\n <aside aria-label=\"Zijbalk\" className={`xicms-sidebar__aside${block.sticky ? \" xicms-sidebar__aside--sticky\" : \"\"}`}>\n <BlockRenderer blocks={block.aside} registry={registry} siteId={siteId} mode={mode} />\n </aside>\n );\n return (\n <div\n className=\"xicms-sidebar\"\n data-side={block.side}\n data-width={block.sidebarWidth}\n >\n {block.side === \"left\" ? (\n <>\n {aside}\n {main}\n </>\n ) : (\n <>\n {main}\n {aside}\n </>\n )}\n </div>\n );\n}\n\nexport const withSidebarBlock = defineBlock({\n type: \"withSidebar\",\n Render: WithSidebarRender,\n label: \"Met zijbalk\",\n icon: \"▤\",\n category: \"layout\",\n defaults: () => ({ main: [], aside: [], side: \"right\", sidebarWidth: \"md\", sticky: true }),\n});\n\n/* ── Tabbladen ─────────────────────────────────────────────────────────────\n * Per tab een eigen set blokken. Toegankelijk (role=tab/tabpanel, pijltjes-navigatie via\n * de browser-default focus). */\ntype Tabs = z.infer<typeof TabsBlockSchema>;\n\nfunction TabsRender({ block, siteId, mode }: BlockRenderProps<Tabs>) {\n const registry = useRegistry();\n const tabs = block.tabs ?? [];\n const [active, setActive] = useState(\"0\");\n if (tabs.length === 0) return null;\n const current = Math.min(Math.max(Number(active) || 0, 0), tabs.length - 1);\n return (\n <section className=\"xicms-tabs\">\n <TabList value={String(current)} onChange={setActive} hasDivider>\n {tabs.map((t, i) => (\n <Tab key={i} value={String(i)} label={t.label || `Tab ${i + 1}`} />\n ))}\n </TabList>\n <div role=\"tabpanel\" aria-label={tabs[current].label || `Tab ${current + 1}`} style={{ marginTop: \"1.25rem\" }}>\n <BlockRenderer blocks={tabs[current].blocks} registry={registry} siteId={siteId} mode={mode} />\n </div>\n </section>\n );\n}\n\nexport const tabsBlock = defineBlock({\n type: \"tabs\",\n Render: TabsRender,\n label: \"Tabbladen\",\n icon: \"🗂️\",\n category: \"layout\",\n defaults: () => ({\n tabs: [\n { label: \"Tab 1\", blocks: [] },\n { label: \"Tab 2\", blocks: [] },\n ],\n }),\n});\n"],"mappings":";AAoBM,SAeE,UAfF,KAeE,YAfF;AAlBN,SAAS,gBAAgB;AAGzB,SAAS,mBAA0C;AACnD,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,SAAS,WAAW;AAQ7B,SAAS,kBAAkB,EAAE,OAAO,QAAQ,KAAK,GAAkC;AACjF,QAAM,WAAW,YAAY;AAC7B,QAAM,OACJ,oBAAC,SAAI,WAAU,uBACb,8BAAC,iBAAc,QAAQ,MAAM,MAAM,UAAoB,QAAgB,MAAY,GACrF;AAEF,QAAM,QACJ,oBAAC,WAAM,cAAW,WAAU,WAAW,uBAAuB,MAAM,SAAS,kCAAkC,EAAE,IAC/G,8BAAC,iBAAc,QAAQ,MAAM,OAAO,UAAoB,QAAgB,MAAY,GACtF;AAEF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,aAAW,MAAM;AAAA,MACjB,cAAY,MAAM;AAAA,MAEjB,gBAAM,SAAS,SACd,iCACG;AAAA;AAAA,QACA;AAAA,SACH,IAEA,iCACG;AAAA;AAAA,QACA;AAAA,SACH;AAAA;AAAA,EAEJ;AAEJ;AAEO,MAAM,mBAAmB,YAAY;AAAA,EAC1C,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU,OAAO,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,MAAM,SAAS,cAAc,MAAM,QAAQ,KAAK;AAC1F,CAAC;AAOD,SAAS,WAAW,EAAE,OAAO,QAAQ,KAAK,GAA2B;AACnE,QAAM,WAAW,YAAY;AAC7B,QAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,GAAG;AACxC,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAM,UAAU,KAAK,IAAI,KAAK,IAAI,OAAO,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC;AAC1E,SACE,qBAAC,aAAQ,WAAU,cACjB;AAAA,wBAAC,WAAQ,OAAO,OAAO,OAAO,GAAG,UAAU,WAAW,YAAU,MAC7D,eAAK,IAAI,CAAC,GAAG,MACZ,oBAAC,OAAY,OAAO,OAAO,CAAC,GAAG,OAAO,EAAE,SAAS,OAAO,IAAI,CAAC,MAAnD,CAAuD,CAClE,GACH;AAAA,IACA,oBAAC,SAAI,MAAK,YAAW,cAAY,KAAK,OAAO,EAAE,SAAS,OAAO,UAAU,CAAC,IAAI,OAAO,EAAE,WAAW,UAAU,GAC1G,8BAAC,iBAAc,QAAQ,KAAK,OAAO,EAAE,QAAQ,UAAoB,QAAgB,MAAY,GAC/F;AAAA,KACF;AAEJ;AAEO,MAAM,YAAY,YAAY;AAAA,EACnC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU,OAAO;AAAA,IACf,MAAM;AAAA,MACJ,EAAE,OAAO,SAAS,QAAQ,CAAC,EAAE;AAAA,MAC7B,EAAE,OAAO,SAAS,QAAQ,CAAC,EAAE;AAAA,IAC/B;AAAA,EACF;AACF,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Layout.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const withSidebarBlock = defineBlock({\n type: \"withSidebar\",\n Render: dynamic(() => import(\"./LayoutRender\").then((m) => m.WithSidebarRender)),\n label: \"Met zijbalk\",\n icon: \"▤\",\n category: \"layout\",\n defaults: () => ({ main: [], aside: [], side: \"right\", sidebarWidth: \"md\", sticky: true }),\n});\n\nexport const tabsBlock = defineBlock({\n type: \"tabs\",\n Render: dynamic(() => import(\"./LayoutRender\").then((m) => m.TabsRender)),\n label: \"Tabbladen\",\n icon: \"🗂️\",\n category: \"layout\",\n defaults: () => ({\n tabs: [\n { label: \"Tab 1\", blocks: [] },\n { label: \"Tab 2\", blocks: [] },\n ],\n }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,mBAAmB,YAAY;AAAA,EAC1C,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,gBAAgB,EAAE,KAAK,CAAC,MAAM,EAAE,iBAAiB,CAAC;AAAA,EAC/E,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU,OAAO,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,GAAG,MAAM,SAAS,cAAc,MAAM,QAAQ,KAAK;AAC1F,CAAC;AAEM,MAAM,YAAY,YAAY;AAAA,EACnC,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,gBAAgB,EAAE,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC;AAAA,EACxE,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU;AAAA,EACV,UAAU,OAAO;AAAA,IACf,MAAM;AAAA,MACJ,EAAE,OAAO,SAAS,QAAQ,CAAC,EAAE;AAAA,MAC7B,EAAE,OAAO,SAAS,QAAQ,CAAC,EAAE;AAAA,IAC/B;AAAA,EACF;AACF,CAAC;","names":[]}
@@ -0,0 +1,8 @@
1
+ import type { z } from "zod";
2
+ import type { WithSidebarBlockSchema, TabsBlockSchema } from "../../schema/blocks.js";
3
+ import type { BlockRenderProps } from "../registry.js";
4
+ type WithSidebar = z.infer<typeof WithSidebarBlockSchema>;
5
+ export declare function WithSidebarRender({ block, siteId, mode }: BlockRenderProps<WithSidebar>): import("react").JSX.Element;
6
+ type Tabs = z.infer<typeof TabsBlockSchema>;
7
+ export declare function TabsRender({ block, siteId, mode }: BlockRenderProps<Tabs>): import("react").JSX.Element | null;
8
+ export {};
@@ -0,0 +1,42 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { BlockRenderer } from "../BlockRenderer.js";
5
+ import { useRegistry } from "../context.js";
6
+ import { TabList, Tab } from "@astryxdesign/core/TabList";
7
+ function WithSidebarRender({ block, siteId, mode }) {
8
+ const registry = useRegistry();
9
+ const main = /* @__PURE__ */ jsx("div", { className: "xicms-sidebar__main", children: /* @__PURE__ */ jsx(BlockRenderer, { blocks: block.main, registry, siteId, mode }) });
10
+ const aside = /* @__PURE__ */ jsx("aside", { "aria-label": "Zijbalk", className: `xicms-sidebar__aside${block.sticky ? " xicms-sidebar__aside--sticky" : ""}`, children: /* @__PURE__ */ jsx(BlockRenderer, { blocks: block.aside, registry, siteId, mode }) });
11
+ return /* @__PURE__ */ jsx(
12
+ "div",
13
+ {
14
+ className: "xicms-sidebar",
15
+ "data-side": block.side,
16
+ "data-width": block.sidebarWidth,
17
+ children: block.side === "left" ? /* @__PURE__ */ jsxs(Fragment, { children: [
18
+ aside,
19
+ main
20
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
21
+ main,
22
+ aside
23
+ ] })
24
+ }
25
+ );
26
+ }
27
+ function TabsRender({ block, siteId, mode }) {
28
+ const registry = useRegistry();
29
+ const tabs = block.tabs ?? [];
30
+ const [active, setActive] = useState("0");
31
+ if (tabs.length === 0) return null;
32
+ const current = Math.min(Math.max(Number(active) || 0, 0), tabs.length - 1);
33
+ return /* @__PURE__ */ jsxs("section", { className: "xicms-tabs", children: [
34
+ /* @__PURE__ */ jsx(TabList, { value: String(current), onChange: setActive, hasDivider: true, children: tabs.map((t, i) => /* @__PURE__ */ jsx(Tab, { value: String(i), label: t.label || `Tab ${i + 1}` }, i)) }),
35
+ /* @__PURE__ */ jsx("div", { role: "tabpanel", "aria-label": tabs[current].label || `Tab ${current + 1}`, style: { marginTop: "1.25rem" }, children: /* @__PURE__ */ jsx(BlockRenderer, { blocks: tabs[current].blocks, registry, siteId, mode }) })
36
+ ] });
37
+ }
38
+ export {
39
+ TabsRender,
40
+ WithSidebarRender
41
+ };
42
+ //# sourceMappingURL=LayoutRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/LayoutRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { WithSidebarBlockSchema, TabsBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { BlockRenderer } from \"../BlockRenderer\";\nimport { useRegistry } from \"../context\";\nimport { TabList, Tab } from \"@astryxdesign/core/TabList\";\n\n/* ── Met zijbalk ───────────────────────────────────────────────────────────\n * Brede hoofdkolom + smalle (sticky) zijbalk. De zijbalk is dé plek voor de compacte\n * widget-varianten (\"laatste nieuws\", \"komende agenda\", contact, …). Beide kanten zijn\n * gewone block-arrays, dus alles wat op een pagina kan, kan ook hier. */\ntype WithSidebar = z.infer<typeof WithSidebarBlockSchema>;\n\nexport function WithSidebarRender({ block, siteId, mode }: BlockRenderProps<WithSidebar>) {\n const registry = useRegistry();\n const main = (\n <div className=\"xicms-sidebar__main\">\n <BlockRenderer blocks={block.main} registry={registry} siteId={siteId} mode={mode} />\n </div>\n );\n const aside = (\n <aside aria-label=\"Zijbalk\" className={`xicms-sidebar__aside${block.sticky ? \" xicms-sidebar__aside--sticky\" : \"\"}`}>\n <BlockRenderer blocks={block.aside} registry={registry} siteId={siteId} mode={mode} />\n </aside>\n );\n return (\n <div\n className=\"xicms-sidebar\"\n data-side={block.side}\n data-width={block.sidebarWidth}\n >\n {block.side === \"left\" ? (\n <>\n {aside}\n {main}\n </>\n ) : (\n <>\n {main}\n {aside}\n </>\n )}\n </div>\n );\n}\n\n/* ── Tabbladen ─────────────────────────────────────────────────────────────\n * Per tab een eigen set blokken. Toegankelijk (role=tab/tabpanel, pijltjes-navigatie via\n * de browser-default focus). */\ntype Tabs = z.infer<typeof TabsBlockSchema>;\n\nexport function TabsRender({ block, siteId, mode }: BlockRenderProps<Tabs>) {\n const registry = useRegistry();\n const tabs = block.tabs ?? [];\n const [active, setActive] = useState(\"0\");\n if (tabs.length === 0) return null;\n const current = Math.min(Math.max(Number(active) || 0, 0), tabs.length - 1);\n return (\n <section className=\"xicms-tabs\">\n <TabList value={String(current)} onChange={setActive} hasDivider>\n {tabs.map((t, i) => (\n <Tab key={i} value={String(i)} label={t.label || `Tab ${i + 1}`} />\n ))}\n </TabList>\n <div role=\"tabpanel\" aria-label={tabs[current].label || `Tab ${current + 1}`} style={{ marginTop: \"1.25rem\" }}>\n <BlockRenderer blocks={tabs[current].blocks} registry={registry} siteId={siteId} mode={mode} />\n </div>\n </section>\n );\n}\n"],"mappings":";AAoBM,SAeE,UAfF,KAeE,YAfF;AAlBN,SAAS,gBAAgB;AAIzB,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,SAAS,WAAW;AAQtB,SAAS,kBAAkB,EAAE,OAAO,QAAQ,KAAK,GAAkC;AACxF,QAAM,WAAW,YAAY;AAC7B,QAAM,OACJ,oBAAC,SAAI,WAAU,uBACb,8BAAC,iBAAc,QAAQ,MAAM,MAAM,UAAoB,QAAgB,MAAY,GACrF;AAEF,QAAM,QACJ,oBAAC,WAAM,cAAW,WAAU,WAAW,uBAAuB,MAAM,SAAS,kCAAkC,EAAE,IAC/G,8BAAC,iBAAc,QAAQ,MAAM,OAAO,UAAoB,QAAgB,MAAY,GACtF;AAEF,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,aAAW,MAAM;AAAA,MACjB,cAAY,MAAM;AAAA,MAEjB,gBAAM,SAAS,SACd,iCACG;AAAA;AAAA,QACA;AAAA,SACH,IAEA,iCACG;AAAA;AAAA,QACA;AAAA,SACH;AAAA;AAAA,EAEJ;AAEJ;AAOO,SAAS,WAAW,EAAE,OAAO,QAAQ,KAAK,GAA2B;AAC1E,QAAM,WAAW,YAAY;AAC7B,QAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,GAAG;AACxC,MAAI,KAAK,WAAW,EAAG,QAAO;AAC9B,QAAM,UAAU,KAAK,IAAI,KAAK,IAAI,OAAO,MAAM,KAAK,GAAG,CAAC,GAAG,KAAK,SAAS,CAAC;AAC1E,SACE,qBAAC,aAAQ,WAAU,cACjB;AAAA,wBAAC,WAAQ,OAAO,OAAO,OAAO,GAAG,UAAU,WAAW,YAAU,MAC7D,eAAK,IAAI,CAAC,GAAG,MACZ,oBAAC,OAAY,OAAO,OAAO,CAAC,GAAG,OAAO,EAAE,SAAS,OAAO,IAAI,CAAC,MAAnD,CAAuD,CAClE,GACH;AAAA,IACA,oBAAC,SAAI,MAAK,YAAW,cAAY,KAAK,OAAO,EAAE,SAAS,OAAO,UAAU,CAAC,IAAI,OAAO,EAAE,WAAW,UAAU,GAC1G,8BAAC,iBAAc,QAAQ,KAAK,OAAO,EAAE,QAAQ,UAAoB,QAAgB,MAAY,GAC/F;AAAA,KACF;AAEJ;","names":[]}
@@ -1,2 +1 @@
1
- import type { z } from "zod";
2
- export declare const mapBlock: import("../index.js").BlockDefinition<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
1
+ export declare const mapBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;
@@ -1,51 +1,8 @@
1
- "use client";
2
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
1
+ import dynamic from "next/dynamic";
3
2
  import { defineBlock } from "../registry.js";
4
- import { ConsentEmbed } from "./consentEmbed.js";
5
- function osmSrc(block) {
6
- if (block.lat != null && block.lng != null) {
7
- const degPerTile = 360 / Math.pow(2, block.zoom);
8
- const lngHalf = degPerTile * 1.25;
9
- const latHalf = lngHalf * Math.cos(block.lat * Math.PI / 180) * 0.6;
10
- const bbox = [block.lng - lngHalf, block.lat - latHalf, block.lng + lngHalf, block.lat + latHalf].join(",");
11
- const marker = `${block.lat},${block.lng}`;
12
- return `https://www.openstreetmap.org/export/embed.html?bbox=${encodeURIComponent(bbox)}&layer=mapnik&marker=${encodeURIComponent(marker)}`;
13
- }
14
- return null;
15
- }
16
- function MapRender({ block, mode }) {
17
- const src = block.provider === "google" ? block.query || null : osmSrc(block);
18
- if (!src) {
19
- if (block.provider === "osm" && block.query) {
20
- return /* @__PURE__ */ jsxs(Fragment, { children: [
21
- mode === "preview" && /* @__PURE__ */ jsx("p", { className: "xicms-ve__hint", children: "\u{1F5FA}\uFE0F Kaart: vul co\xF6rdinaten (lat/lng) in om de kaart te tonen \u2014 nu staat er een kaartlink." }),
22
- /* @__PURE__ */ jsxs("p", { className: "xicms-map__fallback", children: [
23
- "\u{1F4CD}",
24
- " ",
25
- /* @__PURE__ */ jsxs("a", { href: `https://www.openstreetmap.org/search?query=${encodeURIComponent(block.query)}`, target: "_blank", rel: "noopener noreferrer", children: [
26
- "Bekijk ",
27
- /* @__PURE__ */ jsx("span", { "data-xicms-edit": "query", children: block.query }),
28
- " op de kaart"
29
- ] })
30
- ] })
31
- ] });
32
- }
33
- return null;
34
- }
35
- return /* @__PURE__ */ jsx("div", { className: "xicms-map", style: { height: `${block.height}px` }, children: /* @__PURE__ */ jsx(ConsentEmbed, { gated: block.consentGated, preview: mode === "preview", label: "Kaart", children: /* @__PURE__ */ jsx(
36
- "iframe",
37
- {
38
- src,
39
- title: block.query ? `Kaart: ${block.query}` : "Kaart",
40
- loading: "lazy",
41
- style: { border: 0, width: "100%", height: "100%" },
42
- referrerPolicy: "no-referrer-when-downgrade"
43
- }
44
- ) }) });
45
- }
46
3
  const mapBlock = defineBlock({
47
4
  type: "map",
48
- Render: MapRender,
5
+ Render: dynamic(() => import("./MapBlockRender.js").then((m) => m.MapRender)),
49
6
  label: "Kaart",
50
7
  icon: "\u{1F5FA}\uFE0F",
51
8
  defaults: () => ({ provider: "osm", query: "", zoom: 14, height: 360, consentGated: true })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/MapBlock.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport type { MapBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\nimport { ConsentEmbed } from \"./consentEmbed\";\n\ntype MapBlk = z.infer<typeof MapBlockSchema>;\n\n/**\n * Bouwt de OSM-embed-URL. OSM's `export/embed.html` negeert een tekst-`q` en centreert puur op\n * `bbox`; zonder bbox toont het de HELE WERELD. Daarom: als er `lat`/`lng` zijn, berekenen we\n * deterministisch een echte bbox rond het punt (zoom → graden-span, cos(lat)-correctie zodat de\n * kaart niet vervormt) + een marker. Zonder coördinaten is er geen zinvolle embed — de render\n * toont dan een kaartlink op basis van `query` (beter dan de wereldkaart die het q=-pad gaf).\n */\nfunction osmSrc(block: MapBlk): string | null {\n if (block.lat != null && block.lng != null) {\n const degPerTile = 360 / Math.pow(2, block.zoom);\n const lngHalf = degPerTile * 1.25;\n const latHalf = lngHalf * Math.cos((block.lat * Math.PI) / 180) * 0.6;\n const bbox = [block.lng - lngHalf, block.lat - latHalf, block.lng + lngHalf, block.lat + latHalf].join(\",\");\n const marker = `${block.lat},${block.lng}`;\n return `https://www.openstreetmap.org/export/embed.html?bbox=${encodeURIComponent(bbox)}&layer=mapnik&marker=${encodeURIComponent(marker)}`;\n }\n return null;\n}\n\nfunction MapRender({ block, mode }: BlockRenderProps<MapBlk>) {\n const src = block.provider === \"google\" ? block.query || null : osmSrc(block);\n if (!src) {\n // OSM zonder coördinaten kán niet zinvol embedden (het legacy q=-pad toonde de wereldkaart).\n // Toon een duidelijke kaartlink i.p.v. een nutteloze kaart, en leg het in de editor uit.\n if (block.provider === \"osm\" && block.query) {\n // In de editor stond hier alleen de uitleg. Daardoor was de zoekterm — het enige wat de\n // bezoeker straks ziet — nergens aanklikbaar en dus niet inline te bewerken. Nu tonen we\n // de uitleg én de kaartlink zoals hij live wordt.\n return (\n <>\n {mode === \"preview\" && (\n <p className=\"xicms-ve__hint\">🗺️ Kaart: vul coördinaten (lat/lng) in om de kaart te tonen — nu staat er een kaartlink.</p>\n )}\n <p className=\"xicms-map__fallback\">\n 📍{\" \"}\n <a href={`https://www.openstreetmap.org/search?query=${encodeURIComponent(block.query)}`} target=\"_blank\" rel=\"noopener noreferrer\">\n Bekijk <span data-xicms-edit=\"query\">{block.query}</span> op de kaart\n </a>\n </p>\n </>\n );\n }\n return null;\n }\n return (\n <div className=\"xicms-map\" style={{ height: `${block.height}px` }}>\n <ConsentEmbed gated={block.consentGated} preview={mode === \"preview\"} label=\"Kaart\">\n <iframe\n src={src}\n title={block.query ? `Kaart: ${block.query}` : \"Kaart\"}\n loading=\"lazy\"\n style={{ border: 0, width: \"100%\", height: \"100%\" }}\n referrerPolicy=\"no-referrer-when-downgrade\"\n />\n </ConsentEmbed>\n </div>\n );\n}\n\nexport const mapBlock = defineBlock({\n type: \"map\",\n Render: MapRender,\n label: \"Kaart\",\n icon: \"🗺️\",\n defaults: () => ({ provider: \"osm\", query: \"\", zoom: 14, height: 360, consentGated: true }),\n});\n"],"mappings":";AAsCQ,mBAEI,KAIA,YANJ;AAlCR,SAAS,mBAA0C;AACnD,SAAS,oBAAoB;AAW7B,SAAS,OAAO,OAA8B;AAC5C,MAAI,MAAM,OAAO,QAAQ,MAAM,OAAO,MAAM;AAC1C,UAAM,aAAa,MAAM,KAAK,IAAI,GAAG,MAAM,IAAI;AAC/C,UAAM,UAAU,aAAa;AAC7B,UAAM,UAAU,UAAU,KAAK,IAAK,MAAM,MAAM,KAAK,KAAM,GAAG,IAAI;AAClE,UAAM,OAAO,CAAC,MAAM,MAAM,SAAS,MAAM,MAAM,SAAS,MAAM,MAAM,SAAS,MAAM,MAAM,OAAO,EAAE,KAAK,GAAG;AAC1G,UAAM,SAAS,GAAG,MAAM,GAAG,IAAI,MAAM,GAAG;AACxC,WAAO,wDAAwD,mBAAmB,IAAI,CAAC,wBAAwB,mBAAmB,MAAM,CAAC;AAAA,EAC3I;AACA,SAAO;AACT;AAEA,SAAS,UAAU,EAAE,OAAO,KAAK,GAA6B;AAC5D,QAAM,MAAM,MAAM,aAAa,WAAW,MAAM,SAAS,OAAO,OAAO,KAAK;AAC5E,MAAI,CAAC,KAAK;AAGR,QAAI,MAAM,aAAa,SAAS,MAAM,OAAO;AAI3C,aACE,iCACG;AAAA,iBAAS,aACR,oBAAC,OAAE,WAAU,kBAAiB,2HAAyF;AAAA,QAEzH,qBAAC,OAAE,WAAU,uBAAsB;AAAA;AAAA,UAC9B;AAAA,UACH,qBAAC,OAAE,MAAM,8CAA8C,mBAAmB,MAAM,KAAK,CAAC,IAAI,QAAO,UAAS,KAAI,uBAAsB;AAAA;AAAA,YAC3H,oBAAC,UAAK,mBAAgB,SAAS,gBAAM,OAAM;AAAA,YAAO;AAAA,aAC3D;AAAA,WACF;AAAA,SACF;AAAA,IAEJ;AACA,WAAO;AAAA,EACT;AACA,SACE,oBAAC,SAAI,WAAU,aAAY,OAAO,EAAE,QAAQ,GAAG,MAAM,MAAM,KAAK,GAC9D,8BAAC,gBAAa,OAAO,MAAM,cAAc,SAAS,SAAS,WAAW,OAAM,SAC1E;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA,OAAO,MAAM,QAAQ,UAAU,MAAM,KAAK,KAAK;AAAA,MAC/C,SAAQ;AAAA,MACR,OAAO,EAAE,QAAQ,GAAG,OAAO,QAAQ,QAAQ,OAAO;AAAA,MAClD,gBAAe;AAAA;AAAA,EACjB,GACF,GACF;AAEJ;AAEO,MAAM,WAAW,YAAY;AAAA,EAClC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,UAAU,OAAO,OAAO,IAAI,MAAM,IAAI,QAAQ,KAAK,cAAc,KAAK;AAC3F,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/MapBlock.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const mapBlock = defineBlock({\n type: \"map\",\n Render: dynamic(() => import(\"./MapBlockRender\").then((m) => m.MapRender)),\n label: \"Kaart\",\n icon: \"🗺️\",\n defaults: () => ({ provider: \"osm\", query: \"\", zoom: 14, height: 360, consentGated: true }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,WAAW,YAAY;AAAA,EAClC,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,kBAAkB,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC;AAAA,EACzE,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,UAAU,OAAO,OAAO,IAAI,MAAM,IAAI,QAAQ,KAAK,cAAc,KAAK;AAC3F,CAAC;","names":[]}
@@ -0,0 +1,6 @@
1
+ import type { z } from "zod";
2
+ import type { MapBlockSchema } from "../../schema/blocks.js";
3
+ import type { BlockRenderProps } from "../registry.js";
4
+ type MapBlk = z.infer<typeof MapBlockSchema>;
5
+ export declare function MapRender({ block, mode }: BlockRenderProps<MapBlk>): import("react").JSX.Element | null;
6
+ export {};