@xiwebdesign/xicms-core 7.14.0 → 7.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (238) hide show
  1. package/dist/blocks/builtins/Accordion.d.ts +1 -2
  2. package/dist/blocks/builtins/Accordion.js +2 -39
  3. package/dist/blocks/builtins/Accordion.js.map +1 -1
  4. package/dist/blocks/builtins/AccordionRender.d.ts +7 -0
  5. package/dist/blocks/builtins/AccordionRender.js +42 -0
  6. package/dist/blocks/builtins/AccordionRender.js.map +1 -0
  7. package/dist/blocks/builtins/Agenda.d.ts +1 -29
  8. package/dist/blocks/builtins/Agenda.js +3 -94
  9. package/dist/blocks/builtins/Agenda.js.map +1 -1
  10. package/dist/blocks/builtins/AgendaRender.d.ts +34 -0
  11. package/dist/blocks/builtins/AgendaRender.js +96 -0
  12. package/dist/blocks/builtins/AgendaRender.js.map +1 -0
  13. package/dist/blocks/builtins/Banner.d.ts +1 -2
  14. package/dist/blocks/builtins/Banner.js +2 -32
  15. package/dist/blocks/builtins/Banner.js.map +1 -1
  16. package/dist/blocks/builtins/BannerRender.d.ts +11 -0
  17. package/dist/blocks/builtins/BannerRender.js +35 -0
  18. package/dist/blocks/builtins/BannerRender.js.map +1 -0
  19. package/dist/blocks/builtins/BeforeAfter.d.ts +1 -2
  20. package/dist/blocks/builtins/BeforeAfter.js +2 -31
  21. package/dist/blocks/builtins/BeforeAfter.js.map +1 -1
  22. package/dist/blocks/builtins/BeforeAfterRender.d.ts +11 -0
  23. package/dist/blocks/builtins/BeforeAfterRender.js +34 -0
  24. package/dist/blocks/builtins/BeforeAfterRender.js.map +1 -0
  25. package/dist/blocks/builtins/Booking.d.ts +1 -2
  26. package/dist/blocks/builtins/Booking.js +2 -14
  27. package/dist/blocks/builtins/Booking.js.map +1 -1
  28. package/dist/blocks/builtins/BookingRender.d.ts +8 -0
  29. package/dist/blocks/builtins/BookingRender.js +17 -0
  30. package/dist/blocks/builtins/BookingRender.js.map +1 -0
  31. package/dist/blocks/builtins/Breadcrumbs.d.ts +1 -10
  32. package/dist/blocks/builtins/Breadcrumbs.js +3 -69
  33. package/dist/blocks/builtins/Breadcrumbs.js.map +1 -1
  34. package/dist/blocks/builtins/BreadcrumbsRender.d.ts +18 -0
  35. package/dist/blocks/builtins/BreadcrumbsRender.js +71 -0
  36. package/dist/blocks/builtins/BreadcrumbsRender.js.map +1 -0
  37. package/dist/blocks/builtins/Cards.d.ts +1 -2
  38. package/dist/blocks/builtins/Cards.js +2 -74
  39. package/dist/blocks/builtins/Cards.js.map +1 -1
  40. package/dist/blocks/builtins/CardsRender.d.ts +7 -0
  41. package/dist/blocks/builtins/CardsRender.js +77 -0
  42. package/dist/blocks/builtins/CardsRender.js.map +1 -0
  43. package/dist/blocks/builtins/Columns.d.ts +1 -2
  44. package/dist/blocks/builtins/Columns.js +2 -9
  45. package/dist/blocks/builtins/Columns.js.map +1 -1
  46. package/dist/blocks/builtins/ColumnsRender.d.ts +6 -0
  47. package/dist/blocks/builtins/ColumnsRender.js +12 -0
  48. package/dist/blocks/builtins/ColumnsRender.js.map +1 -0
  49. package/dist/blocks/builtins/Contact.d.ts +2 -7
  50. package/dist/blocks/builtins/Contact.js +3 -102
  51. package/dist/blocks/builtins/Contact.js.map +1 -1
  52. package/dist/blocks/builtins/ContactRender.d.ts +9 -0
  53. package/dist/blocks/builtins/ContactRender.js +105 -0
  54. package/dist/blocks/builtins/ContactRender.js.map +1 -0
  55. package/dist/blocks/builtins/Countdown.d.ts +1 -18
  56. package/dist/blocks/builtins/Countdown.js +3 -53
  57. package/dist/blocks/builtins/Countdown.js.map +1 -1
  58. package/dist/blocks/builtins/CountdownRender.d.ts +22 -0
  59. package/dist/blocks/builtins/CountdownRender.js +55 -0
  60. package/dist/blocks/builtins/CountdownRender.js.map +1 -0
  61. package/dist/blocks/builtins/Cta.d.ts +1 -2
  62. package/dist/blocks/builtins/Cta.js +2 -39
  63. package/dist/blocks/builtins/Cta.js.map +1 -1
  64. package/dist/blocks/builtins/CtaRender.d.ts +6 -0
  65. package/dist/blocks/builtins/CtaRender.js +42 -0
  66. package/dist/blocks/builtins/CtaRender.js.map +1 -0
  67. package/dist/blocks/builtins/Downloads.d.ts +1 -2
  68. package/dist/blocks/builtins/Downloads.js +2 -16
  69. package/dist/blocks/builtins/Downloads.js.map +1 -1
  70. package/dist/blocks/builtins/DownloadsRender.d.ts +7 -0
  71. package/dist/blocks/builtins/DownloadsRender.js +19 -0
  72. package/dist/blocks/builtins/DownloadsRender.js.map +1 -0
  73. package/dist/blocks/builtins/Elements.d.ts +3 -4
  74. package/dist/blocks/builtins/Elements.js +4 -38
  75. package/dist/blocks/builtins/Elements.js.map +1 -1
  76. package/dist/blocks/builtins/ElementsRender.d.ts +10 -0
  77. package/dist/blocks/builtins/ElementsRender.js +41 -0
  78. package/dist/blocks/builtins/ElementsRender.js.map +1 -0
  79. package/dist/blocks/builtins/Embed.d.ts +1 -2
  80. package/dist/blocks/builtins/Embed.js +2 -19
  81. package/dist/blocks/builtins/Embed.js.map +1 -1
  82. package/dist/blocks/builtins/EmbedRender.d.ts +7 -0
  83. package/dist/blocks/builtins/EmbedRender.js +22 -0
  84. package/dist/blocks/builtins/EmbedRender.js.map +1 -0
  85. package/dist/blocks/builtins/Faq.d.ts +1 -6
  86. package/dist/blocks/builtins/Faq.js +3 -103
  87. package/dist/blocks/builtins/Faq.js.map +1 -1
  88. package/dist/blocks/builtins/FaqRender.d.ts +10 -0
  89. package/dist/blocks/builtins/FaqRender.js +105 -0
  90. package/dist/blocks/builtins/FaqRender.js.map +1 -0
  91. package/dist/blocks/builtins/FormBlock.d.ts +1 -2
  92. package/dist/blocks/builtins/FormBlock.js +2 -222
  93. package/dist/blocks/builtins/FormBlock.js.map +1 -1
  94. package/dist/blocks/builtins/FormBlockRender.d.ts +6 -0
  95. package/dist/blocks/builtins/FormBlockRender.js +225 -0
  96. package/dist/blocks/builtins/FormBlockRender.js.map +1 -0
  97. package/dist/blocks/builtins/Gallery.d.ts +1 -23
  98. package/dist/blocks/builtins/Gallery.js +2 -164
  99. package/dist/blocks/builtins/Gallery.js.map +1 -1
  100. package/dist/blocks/builtins/GalleryRender.d.ts +25 -0
  101. package/dist/blocks/builtins/GalleryRender.js +167 -0
  102. package/dist/blocks/builtins/GalleryRender.js.map +1 -0
  103. package/dist/blocks/builtins/Hero.d.ts +1 -2
  104. package/dist/blocks/builtins/Hero.js +2 -73
  105. package/dist/blocks/builtins/Hero.js.map +1 -1
  106. package/dist/blocks/builtins/HeroRender.d.ts +6 -0
  107. package/dist/blocks/builtins/HeroRender.js +76 -0
  108. package/dist/blocks/builtins/HeroRender.js.map +1 -0
  109. package/dist/blocks/builtins/ImageBlock.d.ts +1 -2
  110. package/dist/blocks/builtins/ImageBlock.js +2 -22
  111. package/dist/blocks/builtins/ImageBlock.js.map +1 -1
  112. package/dist/blocks/builtins/ImageBlockRender.d.ts +6 -0
  113. package/dist/blocks/builtins/ImageBlockRender.js +25 -0
  114. package/dist/blocks/builtins/ImageBlockRender.js.map +1 -0
  115. package/dist/blocks/builtins/Jobs.d.ts +1 -15
  116. package/dist/blocks/builtins/Jobs.js +3 -69
  117. package/dist/blocks/builtins/Jobs.js.map +1 -1
  118. package/dist/blocks/builtins/JobsRender.d.ts +17 -0
  119. package/dist/blocks/builtins/JobsRender.js +71 -0
  120. package/dist/blocks/builtins/JobsRender.js.map +1 -0
  121. package/dist/blocks/builtins/Layout.d.ts +2 -3
  122. package/dist/blocks/builtins/Layout.js +3 -39
  123. package/dist/blocks/builtins/Layout.js.map +1 -1
  124. package/dist/blocks/builtins/LayoutRender.d.ts +8 -0
  125. package/dist/blocks/builtins/LayoutRender.js +42 -0
  126. package/dist/blocks/builtins/LayoutRender.js.map +1 -0
  127. package/dist/blocks/builtins/MapBlock.d.ts +1 -2
  128. package/dist/blocks/builtins/MapBlock.js +2 -45
  129. package/dist/blocks/builtins/MapBlock.js.map +1 -1
  130. package/dist/blocks/builtins/MapBlockRender.d.ts +6 -0
  131. package/dist/blocks/builtins/MapBlockRender.js +48 -0
  132. package/dist/blocks/builtins/MapBlockRender.js.map +1 -0
  133. package/dist/blocks/builtins/NewsListBlock.d.ts +1 -2
  134. package/dist/blocks/builtins/NewsListBlock.js +2 -11
  135. package/dist/blocks/builtins/NewsListBlock.js.map +1 -1
  136. package/dist/blocks/builtins/NewsListBlockRender.d.ts +6 -0
  137. package/dist/blocks/builtins/NewsListBlockRender.js +14 -0
  138. package/dist/blocks/builtins/NewsListBlockRender.js.map +1 -0
  139. package/dist/blocks/builtins/Newsletter.d.ts +1 -2
  140. package/dist/blocks/builtins/Newsletter.js +2 -89
  141. package/dist/blocks/builtins/Newsletter.js.map +1 -1
  142. package/dist/blocks/builtins/NewsletterRender.d.ts +13 -0
  143. package/dist/blocks/builtins/NewsletterRender.js +92 -0
  144. package/dist/blocks/builtins/NewsletterRender.js.map +1 -0
  145. package/dist/blocks/builtins/OpeningHours.d.ts +1 -2
  146. package/dist/blocks/builtins/OpeningHours.js +2 -28
  147. package/dist/blocks/builtins/OpeningHours.js.map +1 -1
  148. package/dist/blocks/builtins/OpeningHoursRender.d.ts +7 -0
  149. package/dist/blocks/builtins/OpeningHoursRender.js +31 -0
  150. package/dist/blocks/builtins/OpeningHoursRender.js.map +1 -0
  151. package/dist/blocks/builtins/PdfBlock.d.ts +1 -2
  152. package/dist/blocks/builtins/PdfBlock.js +2 -76
  153. package/dist/blocks/builtins/PdfBlock.js.map +1 -1
  154. package/dist/blocks/builtins/PdfBlockRender.d.ts +11 -0
  155. package/dist/blocks/builtins/PdfBlockRender.js +79 -0
  156. package/dist/blocks/builtins/PdfBlockRender.js.map +1 -0
  157. package/dist/blocks/builtins/Portfolio.d.ts +1 -2
  158. package/dist/blocks/builtins/Portfolio.js +2 -75
  159. package/dist/blocks/builtins/Portfolio.js.map +1 -1
  160. package/dist/blocks/builtins/PortfolioRender.d.ts +7 -0
  161. package/dist/blocks/builtins/PortfolioRender.js +78 -0
  162. package/dist/blocks/builtins/PortfolioRender.js.map +1 -0
  163. package/dist/blocks/builtins/Pricing.d.ts +1 -8
  164. package/dist/blocks/builtins/Pricing.js +3 -73
  165. package/dist/blocks/builtins/Pricing.js.map +1 -1
  166. package/dist/blocks/builtins/PricingRender.d.ts +10 -0
  167. package/dist/blocks/builtins/PricingRender.js +75 -0
  168. package/dist/blocks/builtins/PricingRender.js.map +1 -0
  169. package/dist/blocks/builtins/RichTextBlock.d.ts +1 -2
  170. package/dist/blocks/builtins/RichTextBlock.js +2 -5
  171. package/dist/blocks/builtins/RichTextBlock.js.map +1 -1
  172. package/dist/blocks/builtins/RichTextBlockRender.d.ts +6 -0
  173. package/dist/blocks/builtins/RichTextBlockRender.js +8 -0
  174. package/dist/blocks/builtins/RichTextBlockRender.js.map +1 -0
  175. package/dist/blocks/builtins/Search.d.ts +1 -2
  176. package/dist/blocks/builtins/Search.js +2 -80
  177. package/dist/blocks/builtins/Search.js.map +1 -1
  178. package/dist/blocks/builtins/SearchRender.d.ts +7 -0
  179. package/dist/blocks/builtins/SearchRender.js +83 -0
  180. package/dist/blocks/builtins/SearchRender.js.map +1 -0
  181. package/dist/blocks/builtins/Sections.d.ts +4 -5
  182. package/dist/blocks/builtins/Sections.js +5 -142
  183. package/dist/blocks/builtins/Sections.js.map +1 -1
  184. package/dist/blocks/builtins/SectionsRender.d.ts +12 -0
  185. package/dist/blocks/builtins/SectionsRender.js +145 -0
  186. package/dist/blocks/builtins/SectionsRender.js.map +1 -0
  187. package/dist/blocks/builtins/Slider.d.ts +1 -2
  188. package/dist/blocks/builtins/Slider.js +2 -134
  189. package/dist/blocks/builtins/Slider.js.map +1 -1
  190. package/dist/blocks/builtins/SliderRender.d.ts +7 -0
  191. package/dist/blocks/builtins/SliderRender.js +137 -0
  192. package/dist/blocks/builtins/SliderRender.js.map +1 -0
  193. package/dist/blocks/builtins/Spacer.d.ts +1 -2
  194. package/dist/blocks/builtins/Spacer.js +2 -6
  195. package/dist/blocks/builtins/Spacer.js.map +1 -1
  196. package/dist/blocks/builtins/SpacerRender.d.ts +6 -0
  197. package/dist/blocks/builtins/SpacerRender.js +9 -0
  198. package/dist/blocks/builtins/SpacerRender.js.map +1 -0
  199. package/dist/blocks/builtins/SymbolRef.d.ts +1 -2
  200. package/dist/blocks/builtins/SymbolRef.js +2 -76
  201. package/dist/blocks/builtins/SymbolRef.js.map +1 -1
  202. package/dist/blocks/builtins/SymbolRefRender.d.ts +13 -0
  203. package/dist/blocks/builtins/SymbolRefRender.js +79 -0
  204. package/dist/blocks/builtins/SymbolRefRender.js.map +1 -0
  205. package/dist/blocks/builtins/Team.d.ts +1 -2
  206. package/dist/blocks/builtins/Team.js +2 -55
  207. package/dist/blocks/builtins/Team.js.map +1 -1
  208. package/dist/blocks/builtins/TeamRender.d.ts +7 -0
  209. package/dist/blocks/builtins/TeamRender.js +58 -0
  210. package/dist/blocks/builtins/TeamRender.js.map +1 -0
  211. package/dist/blocks/builtins/Testimonials.d.ts +1 -8
  212. package/dist/blocks/builtins/Testimonials.js +2 -69
  213. package/dist/blocks/builtins/Testimonials.js.map +1 -1
  214. package/dist/blocks/builtins/TestimonialsRender.d.ts +10 -0
  215. package/dist/blocks/builtins/TestimonialsRender.js +72 -0
  216. package/dist/blocks/builtins/TestimonialsRender.js.map +1 -0
  217. package/dist/blocks/builtins/Video.d.ts +1 -9
  218. package/dist/blocks/builtins/Video.js +2 -64
  219. package/dist/blocks/builtins/Video.js.map +1 -1
  220. package/dist/blocks/builtins/VideoRender.d.ts +10 -0
  221. package/dist/blocks/builtins/VideoRender.js +67 -0
  222. package/dist/blocks/builtins/VideoRender.js.map +1 -0
  223. package/dist/blocks/builtins/WhatsappChat.d.ts +1 -8
  224. package/dist/blocks/builtins/WhatsappChat.js +2 -37
  225. package/dist/blocks/builtins/WhatsappChat.js.map +1 -1
  226. package/dist/blocks/builtins/WhatsappChatRender.d.ts +17 -0
  227. package/dist/blocks/builtins/WhatsappChatRender.js +40 -0
  228. package/dist/blocks/builtins/WhatsappChatRender.js.map +1 -0
  229. package/dist/blocks/builtins/Widgets.d.ts +12 -13
  230. package/dist/blocks/builtins/Widgets.js +13 -175
  231. package/dist/blocks/builtins/Widgets.js.map +1 -1
  232. package/dist/blocks/builtins/WidgetsRender.d.ts +34 -0
  233. package/dist/blocks/builtins/WidgetsRender.js +178 -0
  234. package/dist/blocks/builtins/WidgetsRender.js.map +1 -0
  235. package/dist/modules/contract.js +2 -1
  236. package/dist/modules/contract.js.map +1 -1
  237. package/dist/version.js +1 -1
  238. package/package.json +1 -1
@@ -1,140 +1,8 @@
1
- "use client";
2
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
- import { useEffect, useRef, useState } from "react";
1
+ import dynamic from "next/dynamic";
4
2
  import { defineBlock } from "../registry.js";
5
- import { Img } from "../../media/ImageContext.js";
6
- function prefersReducedMotion() {
7
- return typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
8
- }
9
- function SliderRender({ block, mode }) {
10
- const slides = (block.slides ?? []).map((s, i) => ({ ...s, _i: i })).filter((s) => s.imageUrl || s.caption);
11
- const [index, setIndex] = useState(0);
12
- const [paused, setPaused] = useState(false);
13
- const [userPaused, setUserPaused] = useState(false);
14
- const swipeStart = useRef(null);
15
- const count = slides.length;
16
- useEffect(() => {
17
- setIndex((i) => count === 0 ? 0 : Math.min(i, count - 1));
18
- }, [count]);
19
- useEffect(() => {
20
- if (!block.autoplay || paused || userPaused || count <= 1 || prefersReducedMotion()) return;
21
- const id = setInterval(() => setIndex((i) => (i + 1) % count), block.interval * 1e3);
22
- return () => clearInterval(id);
23
- }, [block.autoplay, block.interval, paused, userPaused, count]);
24
- if (count === 0) {
25
- if (mode === "preview") {
26
- return /* @__PURE__ */ jsx("div", { className: "xicms-slider xicms-slider--empty", children: "\u{1F3A0} Carrousel \u2014 voeg in het zijpaneel slides met een afbeelding of tekst toe." });
27
- }
28
- return null;
29
- }
30
- const go = (i) => setIndex((i % count + count) % count);
31
- const onPointerDown = (e) => {
32
- swipeStart.current = e.clientX;
33
- };
34
- const onPointerUp = (e) => {
35
- if (swipeStart.current === null || count < 2) return;
36
- const dx = e.clientX - swipeStart.current;
37
- swipeStart.current = null;
38
- if (dx > 40) go(index - 1);
39
- else if (dx < -40) go(index + 1);
40
- };
41
- const onKeyDown = (e) => {
42
- if (e.key === "ArrowLeft") {
43
- e.preventDefault();
44
- go(index - 1);
45
- } else if (e.key === "ArrowRight") {
46
- e.preventDefault();
47
- go(index + 1);
48
- }
49
- };
50
- return /* @__PURE__ */ jsxs(
51
- "section",
52
- {
53
- className: "xicms-slider",
54
- style: { ["--xicms-slider-ratio"]: block.aspectRatio.replace("/", " / ") },
55
- onMouseEnter: () => setPaused(true),
56
- onMouseLeave: () => setPaused(false),
57
- onFocus: () => setPaused(true),
58
- onBlur: () => setPaused(false),
59
- onKeyDown,
60
- tabIndex: 0,
61
- role: "region",
62
- "aria-roledescription": "carousel",
63
- "aria-label": "Carrousel",
64
- children: [
65
- /* @__PURE__ */ jsxs(
66
- "div",
67
- {
68
- className: "xicms-slider__viewport",
69
- onPointerDown,
70
- onPointerUp,
71
- onPointerCancel: () => {
72
- swipeStart.current = null;
73
- },
74
- onPointerLeave: () => {
75
- swipeStart.current = null;
76
- },
77
- style: { touchAction: "pan-y" },
78
- children: [
79
- /* @__PURE__ */ jsx("div", { className: "xicms-slider__track", style: { transform: `translateX(-${index * 100}%)` }, children: slides.map((s, i) => {
80
- const img = s.imageUrl ? /* @__PURE__ */ jsx(Img, { className: "xicms-slider__image", src: s.imageUrl, alt: s.alt ?? "", width: 1800, height: 800, sizes: "100vw", priority: i === 0 }) : null;
81
- return (
82
- /* inert haalt links in verborgen slides ook uit de tabvolgorde — aria-hidden
83
- mét bereikbare focusables is een WCAG-schending (4.1.2). */
84
- /* @__PURE__ */ jsxs(
85
- "div",
86
- {
87
- className: "xicms-slider__slide",
88
- role: "group",
89
- "aria-roledescription": "slide",
90
- "aria-label": `${i + 1} / ${count}`,
91
- "aria-hidden": i !== index,
92
- inert: i !== index || void 0,
93
- children: [
94
- s.href ? /* @__PURE__ */ jsx("a", { href: s.href, children: img }) : img,
95
- s.caption && /* @__PURE__ */ jsx("div", { className: "xicms-slider__caption", "data-xicms-edit": `slides.${s._i}.caption`, children: s.caption })
96
- ]
97
- },
98
- i
99
- )
100
- );
101
- }) }),
102
- block.showArrows && count > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
103
- /* @__PURE__ */ jsx("button", { type: "button", className: "xicms-slider__arrow xicms-slider__arrow--prev", "aria-label": "Vorige", onClick: () => go(index - 1), children: "\u2039" }),
104
- /* @__PURE__ */ jsx("button", { type: "button", className: "xicms-slider__arrow xicms-slider__arrow--next", "aria-label": "Volgende", onClick: () => go(index + 1), children: "\u203A" })
105
- ] }),
106
- block.autoplay && count > 1 && /* @__PURE__ */ jsx(
107
- "button",
108
- {
109
- type: "button",
110
- className: "xicms-slider__pause",
111
- "aria-pressed": userPaused,
112
- "aria-label": userPaused ? "Diavoorstelling afspelen" : "Diavoorstelling pauzeren",
113
- onClick: () => setUserPaused((v) => !v),
114
- children: userPaused ? "\u25B6" : "\u23F8"
115
- }
116
- )
117
- ]
118
- }
119
- ),
120
- block.showDots && count > 1 && /* @__PURE__ */ jsx("div", { className: "xicms-slider__dots", role: "group", "aria-label": "Kies slide", children: slides.map((_, i) => /* @__PURE__ */ jsx(
121
- "button",
122
- {
123
- type: "button",
124
- "aria-current": i === index || void 0,
125
- "aria-label": `Naar slide ${i + 1}`,
126
- className: `xicms-slider__dot${i === index ? " xicms-slider__dot--active" : ""}`,
127
- onClick: () => go(i)
128
- },
129
- i
130
- )) })
131
- ]
132
- }
133
- );
134
- }
135
3
  const sliderBlock = defineBlock({
136
4
  type: "slider",
137
- Render: SliderRender,
5
+ Render: dynamic(() => import("./SliderRender.js").then((m) => m.SliderRender)),
138
6
  label: "Carrousel / slider",
139
7
  icon: "\u{1F3A0}",
140
8
  defaults: () => ({
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/Slider.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { SliderBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\nimport { Img } from \"../../media/ImageContext\";\n\ntype Slider = z.infer<typeof SliderBlockSchema>;\n\nfunction prefersReducedMotion(): boolean {\n return typeof window !== \"undefined\" && window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n/** Beeld-/contentcarrousel. Client-side; autoplay respecteert reduced-motion en pauzeert bij hover. */\nfunction SliderRender({ block, mode }: BlockRenderProps<Slider>) {\n // `_i` = ORIGINELE index (slides gefilterd): inline caption-edits schrijven naar het juiste item.\n const slides = (block.slides ?? []).map((s, i) => ({ ...s, _i: i })).filter((s) => s.imageUrl || s.caption);\n const [index, setIndex] = useState(0);\n const [paused, setPaused] = useState(false);\n // Expliciete stopknop voor autoplay: hover-/focus-pauze helpt touch- en screenreadergebruikers\n // niet, dus WCAG (2.2.2, bewegende content) vraagt een echte pauzeknop.\n const [userPaused, setUserPaused] = useState(false);\n const swipeStart = useRef<number | null>(null);\n const count = slides.length;\n\n // Clamp de index als het aantal slides krimpt (bv. tijdens bewerken in preview), anders blijft\n // de carrousel op een lege positie hangen tot de bezoeker interacteert.\n useEffect(() => {\n setIndex((i) => (count === 0 ? 0 : Math.min(i, count - 1)));\n }, [count]);\n\n useEffect(() => {\n if (!block.autoplay || paused || userPaused || count <= 1 || prefersReducedMotion()) return;\n const id = setInterval(() => setIndex((i) => (i + 1) % count), block.interval * 1000);\n return () => clearInterval(id);\n }, [block.autoplay, block.interval, paused, userPaused, count]);\n\n if (count === 0) {\n // In de editor was een verse slider ONZICHTBAAR (default-slide is leeg → weggefilterd → null):\n // de klant zag \"er gebeurt niets\" na toevoegen. Toon in preview een duidelijke lege staat;\n // publiek blijft het blok gewoon verborgen.\n if (mode === \"preview\") {\n return (\n <div className=\"xicms-slider xicms-slider--empty\">\n 🎠 Carrousel — voeg in het zijpaneel slides met een afbeelding of tekst toe.\n </div>\n );\n }\n return null;\n }\n const go = (i: number) => setIndex(((i % count) + count) % count);\n\n // Swipe (pointer events: touch én muis-sleep) + pijltjestoetsen wanneer de carrousel focus heeft.\n const onPointerDown = (e: React.PointerEvent) => {\n swipeStart.current = e.clientX;\n };\n const onPointerUp = (e: React.PointerEvent) => {\n if (swipeStart.current === null || count < 2) return;\n const dx = e.clientX - swipeStart.current;\n swipeStart.current = null;\n if (dx > 40) go(index - 1);\n else if (dx < -40) go(index + 1);\n };\n const onKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n go(index - 1);\n } else if (e.key === \"ArrowRight\") {\n e.preventDefault();\n go(index + 1);\n }\n };\n\n return (\n <section\n className=\"xicms-slider\"\n style={{ [\"--xicms-slider-ratio\" as string]: block.aspectRatio.replace(\"/\", \" / \") }}\n onMouseEnter={() => setPaused(true)}\n onMouseLeave={() => setPaused(false)}\n onFocus={() => setPaused(true)}\n onBlur={() => setPaused(false)}\n onKeyDown={onKeyDown}\n tabIndex={0}\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label=\"Carrousel\"\n >\n <div\n className=\"xicms-slider__viewport\"\n onPointerDown={onPointerDown}\n onPointerUp={onPointerUp}\n onPointerCancel={() => { swipeStart.current = null; }}\n onPointerLeave={() => { swipeStart.current = null; }}\n style={{ touchAction: \"pan-y\" }}\n >\n <div className=\"xicms-slider__track\" style={{ transform: `translateX(-${index * 100}%)` }}>\n {slides.map((s, i) => {\n const img = s.imageUrl ? (\n <Img className=\"xicms-slider__image\" src={s.imageUrl} alt={s.alt ?? \"\"} width={1800} height={800} sizes=\"100vw\" priority={i === 0} />\n ) : null;\n return (\n /* inert haalt links in verborgen slides ook uit de tabvolgorde — aria-hidden\n mét bereikbare focusables is een WCAG-schending (4.1.2). */\n <div\n key={i}\n className=\"xicms-slider__slide\"\n role=\"group\"\n aria-roledescription=\"slide\"\n aria-label={`${i + 1} / ${count}`}\n aria-hidden={i !== index}\n inert={i !== index || undefined}\n >\n {s.href ? <a href={s.href}>{img}</a> : img}\n {s.caption && <div className=\"xicms-slider__caption\" data-xicms-edit={`slides.${s._i}.caption`}>{s.caption}</div>}\n </div>\n );\n })}\n </div>\n\n {block.showArrows && count > 1 && (\n <>\n <button type=\"button\" className=\"xicms-slider__arrow xicms-slider__arrow--prev\" aria-label=\"Vorige\" onClick={() => go(index - 1)}>‹</button>\n <button type=\"button\" className=\"xicms-slider__arrow xicms-slider__arrow--next\" aria-label=\"Volgende\" onClick={() => go(index + 1)}>›</button>\n </>\n )}\n {/* Geen reduced-motion-check hier: die zou server en client verschillend laten renderen. */}\n {block.autoplay && count > 1 && (\n <button\n type=\"button\"\n className=\"xicms-slider__pause\"\n aria-pressed={userPaused}\n aria-label={userPaused ? \"Diavoorstelling afspelen\" : \"Diavoorstelling pauzeren\"}\n onClick={() => setUserPaused((v) => !v)}\n >\n {userPaused ? \"▶\" : \"⏸\"}\n </button>\n )}\n </div>\n\n {/* Dots als gewone knoppen (geen tablist: er zijn geen tabpanels om aan te koppelen). */}\n {block.showDots && count > 1 && (\n <div className=\"xicms-slider__dots\" role=\"group\" aria-label=\"Kies slide\">\n {slides.map((_, i) => (\n <button\n key={i}\n type=\"button\"\n aria-current={i === index || undefined}\n aria-label={`Naar slide ${i + 1}`}\n className={`xicms-slider__dot${i === index ? \" xicms-slider__dot--active\" : \"\"}`}\n onClick={() => go(i)}\n />\n ))}\n </div>\n )}\n </section>\n );\n}\n\nexport const sliderBlock = defineBlock({\n type: \"slider\",\n Render: SliderRender,\n label: \"Carrousel / slider\",\n icon: \"🎠\",\n defaults: () => ({\n slides: [{ imageUrl: \"\", alt: \"\", caption: \"\" }],\n autoplay: false,\n interval: 5,\n showDots: true,\n showArrows: true,\n aspectRatio: \"16/9\",\n }),\n});\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Slider.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const sliderBlock = defineBlock({\n type: \"slider\",\n Render: dynamic(() => import(\"./SliderRender\").then((m) => m.SliderRender)),\n label: \"Carrousel / slider\",\n icon: \"🎠\",\n defaults: () => ({\n slides: [{ imageUrl: \"\", alt: \"\", caption: \"\" }],\n autoplay: false,\n interval: 5,\n showDots: true,\n showArrows: true,\n aspectRatio: \"16/9\",\n }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,cAAc,YAAY;AAAA,EACrC,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,gBAAgB,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,EAC1E,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO;AAAA,IACf,QAAQ,CAAC,EAAE,UAAU,IAAI,KAAK,IAAI,SAAS,GAAG,CAAC;AAAA,IAC/C,UAAU;AAAA,IACV,UAAU;AAAA,IACV,UAAU;AAAA,IACV,YAAY;AAAA,IACZ,aAAa;AAAA,EACf;AACF,CAAC;","names":[]}
@@ -0,0 +1,7 @@
1
+ import type { z } from "zod";
2
+ import type { SliderBlockSchema } from "../../schema/blocks.js";
3
+ import type { BlockRenderProps } from "../registry.js";
4
+ type Slider = z.infer<typeof SliderBlockSchema>;
5
+ /** Beeld-/contentcarrousel. Client-side; autoplay respecteert reduced-motion en pauzeert bij hover. */
6
+ export declare function SliderRender({ block, mode }: BlockRenderProps<Slider>): import("react").JSX.Element | null;
7
+ export {};
@@ -0,0 +1,137 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { Img } from "../../media/ImageContext.js";
5
+ function prefersReducedMotion() {
6
+ return typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
7
+ }
8
+ function SliderRender({ block, mode }) {
9
+ const slides = (block.slides ?? []).map((s, i) => ({ ...s, _i: i })).filter((s) => s.imageUrl || s.caption);
10
+ const [index, setIndex] = useState(0);
11
+ const [paused, setPaused] = useState(false);
12
+ const [userPaused, setUserPaused] = useState(false);
13
+ const swipeStart = useRef(null);
14
+ const count = slides.length;
15
+ useEffect(() => {
16
+ setIndex((i) => count === 0 ? 0 : Math.min(i, count - 1));
17
+ }, [count]);
18
+ useEffect(() => {
19
+ if (!block.autoplay || paused || userPaused || count <= 1 || prefersReducedMotion()) return;
20
+ const id = setInterval(() => setIndex((i) => (i + 1) % count), block.interval * 1e3);
21
+ return () => clearInterval(id);
22
+ }, [block.autoplay, block.interval, paused, userPaused, count]);
23
+ if (count === 0) {
24
+ if (mode === "preview") {
25
+ return /* @__PURE__ */ jsx("div", { className: "xicms-slider xicms-slider--empty", children: "\u{1F3A0} Carrousel \u2014 voeg in het zijpaneel slides met een afbeelding of tekst toe." });
26
+ }
27
+ return null;
28
+ }
29
+ const go = (i) => setIndex((i % count + count) % count);
30
+ const onPointerDown = (e) => {
31
+ swipeStart.current = e.clientX;
32
+ };
33
+ const onPointerUp = (e) => {
34
+ if (swipeStart.current === null || count < 2) return;
35
+ const dx = e.clientX - swipeStart.current;
36
+ swipeStart.current = null;
37
+ if (dx > 40) go(index - 1);
38
+ else if (dx < -40) go(index + 1);
39
+ };
40
+ const onKeyDown = (e) => {
41
+ if (e.key === "ArrowLeft") {
42
+ e.preventDefault();
43
+ go(index - 1);
44
+ } else if (e.key === "ArrowRight") {
45
+ e.preventDefault();
46
+ go(index + 1);
47
+ }
48
+ };
49
+ return /* @__PURE__ */ jsxs(
50
+ "section",
51
+ {
52
+ className: "xicms-slider",
53
+ style: { ["--xicms-slider-ratio"]: block.aspectRatio.replace("/", " / ") },
54
+ onMouseEnter: () => setPaused(true),
55
+ onMouseLeave: () => setPaused(false),
56
+ onFocus: () => setPaused(true),
57
+ onBlur: () => setPaused(false),
58
+ onKeyDown,
59
+ tabIndex: 0,
60
+ role: "region",
61
+ "aria-roledescription": "carousel",
62
+ "aria-label": "Carrousel",
63
+ children: [
64
+ /* @__PURE__ */ jsxs(
65
+ "div",
66
+ {
67
+ className: "xicms-slider__viewport",
68
+ onPointerDown,
69
+ onPointerUp,
70
+ onPointerCancel: () => {
71
+ swipeStart.current = null;
72
+ },
73
+ onPointerLeave: () => {
74
+ swipeStart.current = null;
75
+ },
76
+ style: { touchAction: "pan-y" },
77
+ children: [
78
+ /* @__PURE__ */ jsx("div", { className: "xicms-slider__track", style: { transform: `translateX(-${index * 100}%)` }, children: slides.map((s, i) => {
79
+ const img = s.imageUrl ? /* @__PURE__ */ jsx(Img, { className: "xicms-slider__image", src: s.imageUrl, alt: s.alt ?? "", width: 1800, height: 800, sizes: "100vw", priority: i === 0 }) : null;
80
+ return (
81
+ /* inert haalt links in verborgen slides ook uit de tabvolgorde — aria-hidden
82
+ mét bereikbare focusables is een WCAG-schending (4.1.2). */
83
+ /* @__PURE__ */ jsxs(
84
+ "div",
85
+ {
86
+ className: "xicms-slider__slide",
87
+ role: "group",
88
+ "aria-roledescription": "slide",
89
+ "aria-label": `${i + 1} / ${count}`,
90
+ "aria-hidden": i !== index,
91
+ inert: i !== index || void 0,
92
+ children: [
93
+ s.href ? /* @__PURE__ */ jsx("a", { href: s.href, children: img }) : img,
94
+ s.caption && /* @__PURE__ */ jsx("div", { className: "xicms-slider__caption", "data-xicms-edit": `slides.${s._i}.caption`, children: s.caption })
95
+ ]
96
+ },
97
+ i
98
+ )
99
+ );
100
+ }) }),
101
+ block.showArrows && count > 1 && /* @__PURE__ */ jsxs(Fragment, { children: [
102
+ /* @__PURE__ */ jsx("button", { type: "button", className: "xicms-slider__arrow xicms-slider__arrow--prev", "aria-label": "Vorige", onClick: () => go(index - 1), children: "\u2039" }),
103
+ /* @__PURE__ */ jsx("button", { type: "button", className: "xicms-slider__arrow xicms-slider__arrow--next", "aria-label": "Volgende", onClick: () => go(index + 1), children: "\u203A" })
104
+ ] }),
105
+ block.autoplay && count > 1 && /* @__PURE__ */ jsx(
106
+ "button",
107
+ {
108
+ type: "button",
109
+ className: "xicms-slider__pause",
110
+ "aria-pressed": userPaused,
111
+ "aria-label": userPaused ? "Diavoorstelling afspelen" : "Diavoorstelling pauzeren",
112
+ onClick: () => setUserPaused((v) => !v),
113
+ children: userPaused ? "\u25B6" : "\u23F8"
114
+ }
115
+ )
116
+ ]
117
+ }
118
+ ),
119
+ block.showDots && count > 1 && /* @__PURE__ */ jsx("div", { className: "xicms-slider__dots", role: "group", "aria-label": "Kies slide", children: slides.map((_, i) => /* @__PURE__ */ jsx(
120
+ "button",
121
+ {
122
+ type: "button",
123
+ "aria-current": i === index || void 0,
124
+ "aria-label": `Naar slide ${i + 1}`,
125
+ className: `xicms-slider__dot${i === index ? " xicms-slider__dot--active" : ""}`,
126
+ onClick: () => go(i)
127
+ },
128
+ i
129
+ )) })
130
+ ]
131
+ }
132
+ );
133
+ }
134
+ export {
135
+ SliderRender
136
+ };
137
+ //# sourceMappingURL=SliderRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/SliderRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { SliderBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { Img } from \"../../media/ImageContext\";\n\ntype Slider = z.infer<typeof SliderBlockSchema>;\n\nfunction prefersReducedMotion(): boolean {\n return typeof window !== \"undefined\" && window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches;\n}\n\n/** Beeld-/contentcarrousel. Client-side; autoplay respecteert reduced-motion en pauzeert bij hover. */\nexport function SliderRender({ block, mode }: BlockRenderProps<Slider>) {\n // `_i` = ORIGINELE index (slides gefilterd): inline caption-edits schrijven naar het juiste item.\n const slides = (block.slides ?? []).map((s, i) => ({ ...s, _i: i })).filter((s) => s.imageUrl || s.caption);\n const [index, setIndex] = useState(0);\n const [paused, setPaused] = useState(false);\n // Expliciete stopknop voor autoplay: hover-/focus-pauze helpt touch- en screenreadergebruikers\n // niet, dus WCAG (2.2.2, bewegende content) vraagt een echte pauzeknop.\n const [userPaused, setUserPaused] = useState(false);\n const swipeStart = useRef<number | null>(null);\n const count = slides.length;\n\n // Clamp de index als het aantal slides krimpt (bv. tijdens bewerken in preview), anders blijft\n // de carrousel op een lege positie hangen tot de bezoeker interacteert.\n useEffect(() => {\n setIndex((i) => (count === 0 ? 0 : Math.min(i, count - 1)));\n }, [count]);\n\n useEffect(() => {\n if (!block.autoplay || paused || userPaused || count <= 1 || prefersReducedMotion()) return;\n const id = setInterval(() => setIndex((i) => (i + 1) % count), block.interval * 1000);\n return () => clearInterval(id);\n }, [block.autoplay, block.interval, paused, userPaused, count]);\n\n if (count === 0) {\n // In de editor was een verse slider ONZICHTBAAR (default-slide is leeg → weggefilterd → null):\n // de klant zag \"er gebeurt niets\" na toevoegen. Toon in preview een duidelijke lege staat;\n // publiek blijft het blok gewoon verborgen.\n if (mode === \"preview\") {\n return (\n <div className=\"xicms-slider xicms-slider--empty\">\n 🎠 Carrousel — voeg in het zijpaneel slides met een afbeelding of tekst toe.\n </div>\n );\n }\n return null;\n }\n const go = (i: number) => setIndex(((i % count) + count) % count);\n\n // Swipe (pointer events: touch én muis-sleep) + pijltjestoetsen wanneer de carrousel focus heeft.\n const onPointerDown = (e: React.PointerEvent) => {\n swipeStart.current = e.clientX;\n };\n const onPointerUp = (e: React.PointerEvent) => {\n if (swipeStart.current === null || count < 2) return;\n const dx = e.clientX - swipeStart.current;\n swipeStart.current = null;\n if (dx > 40) go(index - 1);\n else if (dx < -40) go(index + 1);\n };\n const onKeyDown = (e: React.KeyboardEvent) => {\n if (e.key === \"ArrowLeft\") {\n e.preventDefault();\n go(index - 1);\n } else if (e.key === \"ArrowRight\") {\n e.preventDefault();\n go(index + 1);\n }\n };\n\n return (\n <section\n className=\"xicms-slider\"\n style={{ [\"--xicms-slider-ratio\" as string]: block.aspectRatio.replace(\"/\", \" / \") }}\n onMouseEnter={() => setPaused(true)}\n onMouseLeave={() => setPaused(false)}\n onFocus={() => setPaused(true)}\n onBlur={() => setPaused(false)}\n onKeyDown={onKeyDown}\n tabIndex={0}\n role=\"region\"\n aria-roledescription=\"carousel\"\n aria-label=\"Carrousel\"\n >\n <div\n className=\"xicms-slider__viewport\"\n onPointerDown={onPointerDown}\n onPointerUp={onPointerUp}\n onPointerCancel={() => { swipeStart.current = null; }}\n onPointerLeave={() => { swipeStart.current = null; }}\n style={{ touchAction: \"pan-y\" }}\n >\n <div className=\"xicms-slider__track\" style={{ transform: `translateX(-${index * 100}%)` }}>\n {slides.map((s, i) => {\n const img = s.imageUrl ? (\n <Img className=\"xicms-slider__image\" src={s.imageUrl} alt={s.alt ?? \"\"} width={1800} height={800} sizes=\"100vw\" priority={i === 0} />\n ) : null;\n return (\n /* inert haalt links in verborgen slides ook uit de tabvolgorde — aria-hidden\n mét bereikbare focusables is een WCAG-schending (4.1.2). */\n <div\n key={i}\n className=\"xicms-slider__slide\"\n role=\"group\"\n aria-roledescription=\"slide\"\n aria-label={`${i + 1} / ${count}`}\n aria-hidden={i !== index}\n inert={i !== index || undefined}\n >\n {s.href ? <a href={s.href}>{img}</a> : img}\n {s.caption && <div className=\"xicms-slider__caption\" data-xicms-edit={`slides.${s._i}.caption`}>{s.caption}</div>}\n </div>\n );\n })}\n </div>\n\n {block.showArrows && count > 1 && (\n <>\n <button type=\"button\" className=\"xicms-slider__arrow xicms-slider__arrow--prev\" aria-label=\"Vorige\" onClick={() => go(index - 1)}>‹</button>\n <button type=\"button\" className=\"xicms-slider__arrow xicms-slider__arrow--next\" aria-label=\"Volgende\" onClick={() => go(index + 1)}>›</button>\n </>\n )}\n {/* Geen reduced-motion-check hier: die zou server en client verschillend laten renderen. */}\n {block.autoplay && count > 1 && (\n <button\n type=\"button\"\n className=\"xicms-slider__pause\"\n aria-pressed={userPaused}\n aria-label={userPaused ? \"Diavoorstelling afspelen\" : \"Diavoorstelling pauzeren\"}\n onClick={() => setUserPaused((v) => !v)}\n >\n {userPaused ? \"▶\" : \"⏸\"}\n </button>\n )}\n </div>\n\n {/* Dots als gewone knoppen (geen tablist: er zijn geen tabpanels om aan te koppelen). */}\n {block.showDots && count > 1 && (\n <div className=\"xicms-slider__dots\" role=\"group\" aria-label=\"Kies slide\">\n {slides.map((_, i) => (\n <button\n key={i}\n type=\"button\"\n aria-current={i === index || undefined}\n aria-label={`Naar slide ${i + 1}`}\n className={`xicms-slider__dot${i === index ? \" xicms-slider__dot--active\" : \"\"}`}\n onClick={() => go(i)}\n />\n ))}\n </div>\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 spacerBlock: import("../index.js").BlockDefinition<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
1
+ export declare const spacerBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;
@@ -1,12 +1,8 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ import dynamic from "next/dynamic";
2
2
  import { defineBlock } from "../registry.js";
3
- const HEIGHTS = { sm: 16, md: 32, lg: 64, xl: 120 };
4
- function SpacerRender({ block }) {
5
- return /* @__PURE__ */ jsx("div", { "aria-hidden": true, style: { height: HEIGHTS[block.size] } });
6
- }
7
3
  const spacerBlock = defineBlock({
8
4
  type: "spacer",
9
- Render: SpacerRender,
5
+ Render: dynamic(() => import("./SpacerRender.js").then((m) => m.SpacerRender)),
10
6
  label: "Witruimte",
11
7
  icon: "\u2195",
12
8
  defaults: () => ({ size: "md" })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/Spacer.tsx"],"sourcesContent":["import type { z } from \"zod\";\nimport type { SpacerBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\n\ntype Spacer = z.infer<typeof SpacerBlockSchema>;\n\nconst HEIGHTS: Record<Spacer[\"size\"], number> = { sm: 16, md: 32, lg: 64, xl: 120 };\n\nfunction SpacerRender({ block }: BlockRenderProps<Spacer>) {\n return <div aria-hidden style={{ height: HEIGHTS[block.size] }} />;\n}\n\nexport const spacerBlock = defineBlock({\n type: \"spacer\",\n Render: SpacerRender,\n label: \"Witruimte\",\n icon: \"↕\",\n defaults: () => ({ size: \"md\" }),\n});\n"],"mappings":"AASS;AAPT,SAAS,mBAA0C;AAInD,MAAM,UAA0C,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAElF,SAAS,aAAa,EAAE,MAAM,GAA6B;AACzD,SAAO,oBAAC,SAAI,eAAW,MAAC,OAAO,EAAE,QAAQ,QAAQ,MAAM,IAAI,EAAE,GAAG;AAClE;AAEO,MAAM,cAAc,YAAY;AAAA,EACrC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,MAAM,KAAK;AAChC,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Spacer.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const spacerBlock = defineBlock({\n type: \"spacer\",\n Render: dynamic(() => import(\"./SpacerRender\").then((m) => m.SpacerRender)),\n label: \"Witruimte\",\n icon: \"↕\",\n defaults: () => ({ size: \"md\" }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,cAAc,YAAY;AAAA,EACrC,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,gBAAgB,EAAE,KAAK,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,EAC1E,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,MAAM,KAAK;AAChC,CAAC;","names":[]}
@@ -0,0 +1,6 @@
1
+ import type { z } from "zod";
2
+ import type { SpacerBlockSchema } from "../../schema/blocks.js";
3
+ import type { BlockRenderProps } from "../registry.js";
4
+ type Spacer = z.infer<typeof SpacerBlockSchema>;
5
+ export declare function SpacerRender({ block }: BlockRenderProps<Spacer>): import("react").JSX.Element;
6
+ export {};
@@ -0,0 +1,9 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ const HEIGHTS = { sm: 16, md: 32, lg: 64, xl: 120 };
3
+ function SpacerRender({ block }) {
4
+ return /* @__PURE__ */ jsx("div", { "aria-hidden": true, style: { height: HEIGHTS[block.size] } });
5
+ }
6
+ export {
7
+ SpacerRender
8
+ };
9
+ //# sourceMappingURL=SpacerRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/SpacerRender.tsx"],"sourcesContent":["import type { z } from \"zod\";\nimport type { SpacerBlockSchema } from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\n\ntype Spacer = z.infer<typeof SpacerBlockSchema>;\n\nconst HEIGHTS: Record<Spacer[\"size\"], number> = { sm: 16, md: 32, lg: 64, xl: 120 };\n\nexport function SpacerRender({ block }: BlockRenderProps<Spacer>) {\n return <div aria-hidden style={{ height: HEIGHTS[block.size] }} />;\n}\n"],"mappings":"AASS;AAHT,MAAM,UAA0C,EAAE,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI,IAAI;AAE3E,SAAS,aAAa,EAAE,MAAM,GAA6B;AAChE,SAAO,oBAAC,SAAI,eAAW,MAAC,OAAO,EAAE,QAAQ,QAAQ,MAAM,IAAI,EAAE,GAAG;AAClE;","names":[]}
@@ -1,2 +1 @@
1
- import type { z } from "zod";
2
- export declare const symbolRefBlock: import("../index.js").BlockDefinition<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
1
+ export declare const symbolRefBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;
@@ -1,82 +1,8 @@
1
- "use client";
2
- import { jsx, jsxs } from "react/jsx-runtime";
3
- import { useEffect, 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 { useEditor } from "../../editor/EditorProvider.js";
8
- function SymbolRefRender({ block, siteId, mode }) {
9
- const registry = useRegistry();
10
- const bewerken = useEditor().open || mode === "preview";
11
- const [symbol, setSymbol] = useState(void 0);
12
- useEffect(() => {
13
- if (!block.symbolId) {
14
- setSymbol(null);
15
- return;
16
- }
17
- let unsub;
18
- let afgebroken = false;
19
- void (async () => {
20
- const [{ getDb }, { doc, onSnapshot }] = await Promise.all([
21
- import("../../firebase/client.js"),
22
- import("firebase/firestore")
23
- ]);
24
- const db = getDb();
25
- if (!db || afgebroken) {
26
- setSymbol(null);
27
- return;
28
- }
29
- const ref = doc(db, "sites", siteId, "symbols", block.symbolId);
30
- const zet = (data, bestaat) => {
31
- const d = bestaat && data && typeof data === "object" ? data : null;
32
- const geldig = d && typeof d.name === "string" && Array.isArray(d.blocks);
33
- setSymbol(geldig ? d : null);
34
- };
35
- if (bewerken) {
36
- unsub = onSnapshot(
37
- ref,
38
- (snap) => zet(snap.data(), snap.exists()),
39
- () => setSymbol(null)
40
- );
41
- } else {
42
- const { getDoc } = await import("firebase/firestore");
43
- try {
44
- const snap = await getDoc(ref);
45
- if (!afgebroken) zet(snap.data(), snap.exists());
46
- } catch {
47
- if (!afgebroken) setSymbol(null);
48
- }
49
- }
50
- })();
51
- return () => {
52
- afgebroken = true;
53
- unsub?.();
54
- };
55
- }, [siteId, block.symbolId, bewerken]);
56
- if (symbol === void 0) return null;
57
- if (symbol === null) {
58
- return mode === "preview" ? /* @__PURE__ */ jsxs("p", { className: "xicms-ve__hint", children: [
59
- "\u{1F9E9} Symbool niet gevonden (",
60
- block.symbolId,
61
- ") \u2014 kies een ander symbool of verwijder dit blok."
62
- ] }) : null;
63
- }
64
- const inner = /* @__PURE__ */ jsx(BlockRenderer, { blocks: symbol.blocks, registry, siteId, mode });
65
- if (mode === "preview") {
66
- return /* @__PURE__ */ jsxs("div", { className: "xicms-symbol", "data-symbol": block.symbolId, children: [
67
- /* @__PURE__ */ jsxs("div", { className: "xicms-symbol__badge", children: [
68
- "\u{1F9E9} ",
69
- symbol.name,
70
- " \u2014 gedeeld symbool (wijzigingen gelden op \xE9lke pagina)"
71
- ] }),
72
- inner
73
- ] });
74
- }
75
- return inner;
76
- }
77
3
  const symbolRefBlock = defineBlock({
78
4
  type: "symbolRef",
79
- Render: SymbolRefRender,
5
+ Render: dynamic(() => import("./SymbolRefRender.js").then((m) => m.SymbolRefRender)),
80
6
  label: "Symbool (gedeelde sectie)",
81
7
  icon: "\u{1F9E9}",
82
8
  defaults: () => ({ symbolId: "" })
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/blocks/builtins/SymbolRef.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { SymbolRefBlockSchema } from \"../../schema/blocks\";\nimport type { SymbolDefinition } from \"../../schema/symbols\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\nimport { BlockRenderer } from \"../BlockRenderer\";\nimport { useRegistry } from \"../context\";\nimport { useEditor } from \"../../editor/EditorProvider\";\n\ntype SymbolRef = z.infer<typeof SymbolRefBlockSchema>;\n\n/**\n * Verwijzing naar een gedeeld symbool. Op de LIVE site wordt een symbolRef normaliter al\n * server-side vervangen door de symbool-blokken (server/pages.ts `expandSymbols`) — dan komt\n * deze Render niet eens aan bod. In de editor/preview (en als client-fallback) rendert hij het\n * symbool live vanuit Firestore, met een subtiel kader zodat de editor ziet dat dit gedeelde\n * inhoud is die op meerdere pagina's meebeweegt.\n */\nfunction SymbolRefRender({ block, siteId, mode }: BlockRenderProps<SymbolRef>) {\n const registry = useRegistry();\n // Live meebewegen is alleen nuttig terwijl er BEWERKT wordt. Voor een gewone bezoeker was de\n // onSnapshot hieronder het duurste patroon van het systeem: een read plus een blijvend open\n // verbinding, per bezoeker — voor content die toch pas verandert als iemand publiceert.\n const bewerken = useEditor().open || mode === \"preview\";\n const [symbol, setSymbol] = useState<SymbolDefinition | null | undefined>(undefined);\n useEffect(() => {\n if (!block.symbolId) {\n setSymbol(null);\n return;\n }\n // Firestore dynamisch laden: een pagina zonder symbolen haalt de SDK zo nooit binnen, en een\n // pagina mét symbolen pas op het moment dat er echt iets op te halen valt.\n let unsub: (() => void) | undefined;\n let afgebroken = false;\n void (async () => {\n const [{ getDb }, { doc, onSnapshot }] = await Promise.all([\n import(\"../../firebase/client\"),\n import(\"firebase/firestore\"),\n ]);\n const db = getDb();\n if (!db || afgebroken) {\n setSymbol(null);\n return;\n }\n const ref = doc(db, \"sites\", siteId, \"symbols\", block.symbolId!);\n const zet = (data: unknown, bestaat: boolean) => {\n // Lichte vormcheck i.p.v. zod (7.13): dit is een publiek renderpad en de enige plek die\n // anders het hele symbols-schema (en daarmee de zod-runtime) in de bezoekersbundel trok.\n // De BlockRenderer eronder valideert de blokken zelf al per type.\n const d = bestaat && data && typeof data === \"object\" ? (data as { name?: unknown; blocks?: unknown }) : null;\n const geldig = d && typeof d.name === \"string\" && Array.isArray(d.blocks);\n setSymbol(geldig ? (d as unknown as SymbolDefinition) : null);\n };\n if (bewerken) {\n unsub = onSnapshot(\n ref,\n (snap) => zet(snap.data(), snap.exists()),\n () => setSymbol(null),\n );\n } else {\n // Publieke fallback (zeldzaam: normaal is de ref al server-side geëxpandeerd): één read,\n // geen listener.\n const { getDoc } = await import(\"firebase/firestore\");\n try {\n const snap = await getDoc(ref);\n if (!afgebroken) zet(snap.data(), snap.exists());\n } catch {\n if (!afgebroken) setSymbol(null);\n }\n }\n })();\n return () => {\n afgebroken = true;\n unsub?.();\n };\n }, [siteId, block.symbolId, bewerken]);\n\n if (symbol === undefined) return null; // laden — geen flits\n if (symbol === null) {\n // Verweesde referentie: nooit de pagina breken; in preview uitleggen, live niets tonen.\n return mode === \"preview\" ? (\n <p className=\"xicms-ve__hint\">🧩 Symbool niet gevonden ({block.symbolId}) — kies een ander symbool of verwijder dit blok.</p>\n ) : null;\n }\n const inner = <BlockRenderer blocks={symbol.blocks} registry={registry} siteId={siteId} mode={mode} />;\n if (mode === \"preview\") {\n return (\n <div className=\"xicms-symbol\" data-symbol={block.symbolId}>\n <div className=\"xicms-symbol__badge\">🧩 {symbol.name} — gedeeld symbool (wijzigingen gelden op élke pagina)</div>\n {inner}\n </div>\n );\n }\n return inner;\n}\n\nexport const symbolRefBlock = defineBlock({\n type: \"symbolRef\",\n Render: SymbolRefRender,\n label: \"Symbool (gedeelde sectie)\",\n icon: \"🧩\",\n defaults: () => ({ symbolId: \"\" }),\n});\n"],"mappings":";AAmFM,SAGU,KAHV;AAjFN,SAAS,WAAW,gBAAgB;AAIpC,SAAS,mBAA0C;AACnD,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAW1B,SAAS,gBAAgB,EAAE,OAAO,QAAQ,KAAK,GAAgC;AAC7E,QAAM,WAAW,YAAY;AAI7B,QAAM,WAAW,UAAU,EAAE,QAAQ,SAAS;AAC9C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA8C,MAAS;AACnF,YAAU,MAAM;AACd,QAAI,CAAC,MAAM,UAAU;AACnB,gBAAU,IAAI;AACd;AAAA,IACF;AAGA,QAAI;AACJ,QAAI,aAAa;AACjB,UAAM,YAAY;AAChB,YAAM,CAAC,EAAE,MAAM,GAAG,EAAE,KAAK,WAAW,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,QACzD,OAAO,uBAAuB;AAAA,QAC9B,OAAO,oBAAoB;AAAA,MAC7B,CAAC;AACD,YAAM,KAAK,MAAM;AACjB,UAAI,CAAC,MAAM,YAAY;AACrB,kBAAU,IAAI;AACd;AAAA,MACF;AACA,YAAM,MAAM,IAAI,IAAI,SAAS,QAAQ,WAAW,MAAM,QAAS;AAC/D,YAAM,MAAM,CAAC,MAAe,YAAqB;AAI/C,cAAM,IAAI,WAAW,QAAQ,OAAO,SAAS,WAAY,OAAgD;AACzG,cAAM,SAAS,KAAK,OAAO,EAAE,SAAS,YAAY,MAAM,QAAQ,EAAE,MAAM;AACxE,kBAAU,SAAU,IAAoC,IAAI;AAAA,MAC9D;AACA,UAAI,UAAU;AACZ,gBAAQ;AAAA,UACN;AAAA,UACA,CAAC,SAAS,IAAI,KAAK,KAAK,GAAG,KAAK,OAAO,CAAC;AAAA,UACxC,MAAM,UAAU,IAAI;AAAA,QACtB;AAAA,MACF,OAAO;AAGL,cAAM,EAAE,OAAO,IAAI,MAAM,OAAO,oBAAoB;AACpD,YAAI;AACF,gBAAM,OAAO,MAAM,OAAO,GAAG;AAC7B,cAAI,CAAC,WAAY,KAAI,KAAK,KAAK,GAAG,KAAK,OAAO,CAAC;AAAA,QACjD,QAAQ;AACN,cAAI,CAAC,WAAY,WAAU,IAAI;AAAA,QACjC;AAAA,MACF;AAAA,IACF,GAAG;AACH,WAAO,MAAM;AACX,mBAAa;AACb,cAAQ;AAAA,IACV;AAAA,EACF,GAAG,CAAC,QAAQ,MAAM,UAAU,QAAQ,CAAC;AAErC,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,WAAW,MAAM;AAEnB,WAAO,SAAS,YACd,qBAAC,OAAE,WAAU,kBAAiB;AAAA;AAAA,MAA2B,MAAM;AAAA,MAAS;AAAA,OAAiD,IACvH;AAAA,EACN;AACA,QAAM,QAAQ,oBAAC,iBAAc,QAAQ,OAAO,QAAQ,UAAoB,QAAgB,MAAY;AACpG,MAAI,SAAS,WAAW;AACtB,WACE,qBAAC,SAAI,WAAU,gBAAe,eAAa,MAAM,UAC/C;AAAA,2BAAC,SAAI,WAAU,uBAAsB;AAAA;AAAA,QAAI,OAAO;AAAA,QAAK;AAAA,SAAsD;AAAA,MAC1G;AAAA,OACH;AAAA,EAEJ;AACA,SAAO;AACT;AAEO,MAAM,iBAAiB,YAAY;AAAA,EACxC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,UAAU,GAAG;AAClC,CAAC;","names":[]}
1
+ {"version":3,"sources":["../../../src/blocks/builtins/SymbolRef.tsx"],"sourcesContent":["import dynamic from \"next/dynamic\";\nimport { defineBlock } from \"../registry\";\n\nexport const symbolRefBlock = defineBlock({\n type: \"symbolRef\",\n Render: dynamic(() => import(\"./SymbolRefRender\").then((m) => m.SymbolRefRender)),\n label: \"Symbool (gedeelde sectie)\",\n icon: \"🧩\",\n defaults: () => ({ symbolId: \"\" }),\n});\n"],"mappings":"AAAA,OAAO,aAAa;AACpB,SAAS,mBAAmB;AAErB,MAAM,iBAAiB,YAAY;AAAA,EACxC,MAAM;AAAA,EACN,QAAQ,QAAQ,MAAM,OAAO,mBAAmB,EAAE,KAAK,CAAC,MAAM,EAAE,eAAe,CAAC;AAAA,EAChF,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,UAAU,GAAG;AAClC,CAAC;","names":[]}
@@ -0,0 +1,13 @@
1
+ import type { z } from "zod";
2
+ import type { SymbolRefBlockSchema } from "../../schema/blocks.js";
3
+ import type { BlockRenderProps } from "../registry.js";
4
+ type SymbolRef = z.infer<typeof SymbolRefBlockSchema>;
5
+ /**
6
+ * Verwijzing naar een gedeeld symbool. Op de LIVE site wordt een symbolRef normaliter al
7
+ * server-side vervangen door de symbool-blokken (server/pages.ts `expandSymbols`) — dan komt
8
+ * deze Render niet eens aan bod. In de editor/preview (en als client-fallback) rendert hij het
9
+ * symbool live vanuit Firestore, met een subtiel kader zodat de editor ziet dat dit gedeelde
10
+ * inhoud is die op meerdere pagina's meebeweegt.
11
+ */
12
+ export declare function SymbolRefRender({ block, siteId, mode }: BlockRenderProps<SymbolRef>): import("react").JSX.Element | null;
13
+ export {};
@@ -0,0 +1,79 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useState } from "react";
4
+ import { BlockRenderer } from "../BlockRenderer.js";
5
+ import { useRegistry } from "../context.js";
6
+ import { useEditor } from "../../editor/EditorProvider.js";
7
+ function SymbolRefRender({ block, siteId, mode }) {
8
+ const registry = useRegistry();
9
+ const bewerken = useEditor().open || mode === "preview";
10
+ const [symbol, setSymbol] = useState(void 0);
11
+ useEffect(() => {
12
+ if (!block.symbolId) {
13
+ setSymbol(null);
14
+ return;
15
+ }
16
+ let unsub;
17
+ let afgebroken = false;
18
+ void (async () => {
19
+ const [{ getDb }, { doc, onSnapshot }] = await Promise.all([
20
+ import("../../firebase/client.js"),
21
+ import("firebase/firestore")
22
+ ]);
23
+ const db = getDb();
24
+ if (!db || afgebroken) {
25
+ setSymbol(null);
26
+ return;
27
+ }
28
+ const ref = doc(db, "sites", siteId, "symbols", block.symbolId);
29
+ const zet = (data, bestaat) => {
30
+ const d = bestaat && data && typeof data === "object" ? data : null;
31
+ const geldig = d && typeof d.name === "string" && Array.isArray(d.blocks);
32
+ setSymbol(geldig ? d : null);
33
+ };
34
+ if (bewerken) {
35
+ unsub = onSnapshot(
36
+ ref,
37
+ (snap) => zet(snap.data(), snap.exists()),
38
+ () => setSymbol(null)
39
+ );
40
+ } else {
41
+ const { getDoc } = await import("firebase/firestore");
42
+ try {
43
+ const snap = await getDoc(ref);
44
+ if (!afgebroken) zet(snap.data(), snap.exists());
45
+ } catch {
46
+ if (!afgebroken) setSymbol(null);
47
+ }
48
+ }
49
+ })();
50
+ return () => {
51
+ afgebroken = true;
52
+ unsub?.();
53
+ };
54
+ }, [siteId, block.symbolId, bewerken]);
55
+ if (symbol === void 0) return null;
56
+ if (symbol === null) {
57
+ return mode === "preview" ? /* @__PURE__ */ jsxs("p", { className: "xicms-ve__hint", children: [
58
+ "\u{1F9E9} Symbool niet gevonden (",
59
+ block.symbolId,
60
+ ") \u2014 kies een ander symbool of verwijder dit blok."
61
+ ] }) : null;
62
+ }
63
+ const inner = /* @__PURE__ */ jsx(BlockRenderer, { blocks: symbol.blocks, registry, siteId, mode });
64
+ if (mode === "preview") {
65
+ return /* @__PURE__ */ jsxs("div", { className: "xicms-symbol", "data-symbol": block.symbolId, children: [
66
+ /* @__PURE__ */ jsxs("div", { className: "xicms-symbol__badge", children: [
67
+ "\u{1F9E9} ",
68
+ symbol.name,
69
+ " \u2014 gedeeld symbool (wijzigingen gelden op \xE9lke pagina)"
70
+ ] }),
71
+ inner
72
+ ] });
73
+ }
74
+ return inner;
75
+ }
76
+ export {
77
+ SymbolRefRender
78
+ };
79
+ //# sourceMappingURL=SymbolRefRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/SymbolRefRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useState } from \"react\";\nimport type { z } from \"zod\";\nimport type { SymbolRefBlockSchema } from \"../../schema/blocks\";\nimport type { SymbolDefinition } from \"../../schema/symbols\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { BlockRenderer } from \"../BlockRenderer\";\nimport { useRegistry } from \"../context\";\nimport { useEditor } from \"../../editor/EditorProvider\";\n\ntype SymbolRef = z.infer<typeof SymbolRefBlockSchema>;\n\n/**\n * Verwijzing naar een gedeeld symbool. Op de LIVE site wordt een symbolRef normaliter al\n * server-side vervangen door de symbool-blokken (server/pages.ts `expandSymbols`) — dan komt\n * deze Render niet eens aan bod. In de editor/preview (en als client-fallback) rendert hij het\n * symbool live vanuit Firestore, met een subtiel kader zodat de editor ziet dat dit gedeelde\n * inhoud is die op meerdere pagina's meebeweegt.\n */\nexport function SymbolRefRender({ block, siteId, mode }: BlockRenderProps<SymbolRef>) {\n const registry = useRegistry();\n // Live meebewegen is alleen nuttig terwijl er BEWERKT wordt. Voor een gewone bezoeker was de\n // onSnapshot hieronder het duurste patroon van het systeem: een read plus een blijvend open\n // verbinding, per bezoeker — voor content die toch pas verandert als iemand publiceert.\n const bewerken = useEditor().open || mode === \"preview\";\n const [symbol, setSymbol] = useState<SymbolDefinition | null | undefined>(undefined);\n useEffect(() => {\n if (!block.symbolId) {\n setSymbol(null);\n return;\n }\n // Firestore dynamisch laden: een pagina zonder symbolen haalt de SDK zo nooit binnen, en een\n // pagina mét symbolen pas op het moment dat er echt iets op te halen valt.\n let unsub: (() => void) | undefined;\n let afgebroken = false;\n void (async () => {\n const [{ getDb }, { doc, onSnapshot }] = await Promise.all([\n import(\"../../firebase/client\"),\n import(\"firebase/firestore\"),\n ]);\n const db = getDb();\n if (!db || afgebroken) {\n setSymbol(null);\n return;\n }\n const ref = doc(db, \"sites\", siteId, \"symbols\", block.symbolId!);\n const zet = (data: unknown, bestaat: boolean) => {\n // Lichte vormcheck i.p.v. zod (7.13): dit is een publiek renderpad en de enige plek die\n // anders het hele symbols-schema (en daarmee de zod-runtime) in de bezoekersbundel trok.\n // De BlockRenderer eronder valideert de blokken zelf al per type.\n const d = bestaat && data && typeof data === \"object\" ? (data as { name?: unknown; blocks?: unknown }) : null;\n const geldig = d && typeof d.name === \"string\" && Array.isArray(d.blocks);\n setSymbol(geldig ? (d as unknown as SymbolDefinition) : null);\n };\n if (bewerken) {\n unsub = onSnapshot(\n ref,\n (snap) => zet(snap.data(), snap.exists()),\n () => setSymbol(null),\n );\n } else {\n // Publieke fallback (zeldzaam: normaal is de ref al server-side geëxpandeerd): één read,\n // geen listener.\n const { getDoc } = await import(\"firebase/firestore\");\n try {\n const snap = await getDoc(ref);\n if (!afgebroken) zet(snap.data(), snap.exists());\n } catch {\n if (!afgebroken) setSymbol(null);\n }\n }\n })();\n return () => {\n afgebroken = true;\n unsub?.();\n };\n }, [siteId, block.symbolId, bewerken]);\n\n if (symbol === undefined) return null; // laden — geen flits\n if (symbol === null) {\n // Verweesde referentie: nooit de pagina breken; in preview uitleggen, live niets tonen.\n return mode === \"preview\" ? (\n <p className=\"xicms-ve__hint\">🧩 Symbool niet gevonden ({block.symbolId}) — kies een ander symbool of verwijder dit blok.</p>\n ) : null;\n }\n const inner = <BlockRenderer blocks={symbol.blocks} registry={registry} siteId={siteId} mode={mode} />;\n if (mode === \"preview\") {\n return (\n <div className=\"xicms-symbol\" data-symbol={block.symbolId}>\n <div className=\"xicms-symbol__badge\">🧩 {symbol.name} — gedeeld symbool (wijzigingen gelden op élke pagina)</div>\n {inner}\n </div>\n );\n }\n return inner;\n}\n"],"mappings":";AAmFM,SAGU,KAHV;AAjFN,SAAS,WAAW,gBAAgB;AAKpC,SAAS,qBAAqB;AAC9B,SAAS,mBAAmB;AAC5B,SAAS,iBAAiB;AAWnB,SAAS,gBAAgB,EAAE,OAAO,QAAQ,KAAK,GAAgC;AACpF,QAAM,WAAW,YAAY;AAI7B,QAAM,WAAW,UAAU,EAAE,QAAQ,SAAS;AAC9C,QAAM,CAAC,QAAQ,SAAS,IAAI,SAA8C,MAAS;AACnF,YAAU,MAAM;AACd,QAAI,CAAC,MAAM,UAAU;AACnB,gBAAU,IAAI;AACd;AAAA,IACF;AAGA,QAAI;AACJ,QAAI,aAAa;AACjB,UAAM,YAAY;AAChB,YAAM,CAAC,EAAE,MAAM,GAAG,EAAE,KAAK,WAAW,CAAC,IAAI,MAAM,QAAQ,IAAI;AAAA,QACzD,OAAO,uBAAuB;AAAA,QAC9B,OAAO,oBAAoB;AAAA,MAC7B,CAAC;AACD,YAAM,KAAK,MAAM;AACjB,UAAI,CAAC,MAAM,YAAY;AACrB,kBAAU,IAAI;AACd;AAAA,MACF;AACA,YAAM,MAAM,IAAI,IAAI,SAAS,QAAQ,WAAW,MAAM,QAAS;AAC/D,YAAM,MAAM,CAAC,MAAe,YAAqB;AAI/C,cAAM,IAAI,WAAW,QAAQ,OAAO,SAAS,WAAY,OAAgD;AACzG,cAAM,SAAS,KAAK,OAAO,EAAE,SAAS,YAAY,MAAM,QAAQ,EAAE,MAAM;AACxE,kBAAU,SAAU,IAAoC,IAAI;AAAA,MAC9D;AACA,UAAI,UAAU;AACZ,gBAAQ;AAAA,UACN;AAAA,UACA,CAAC,SAAS,IAAI,KAAK,KAAK,GAAG,KAAK,OAAO,CAAC;AAAA,UACxC,MAAM,UAAU,IAAI;AAAA,QACtB;AAAA,MACF,OAAO;AAGL,cAAM,EAAE,OAAO,IAAI,MAAM,OAAO,oBAAoB;AACpD,YAAI;AACF,gBAAM,OAAO,MAAM,OAAO,GAAG;AAC7B,cAAI,CAAC,WAAY,KAAI,KAAK,KAAK,GAAG,KAAK,OAAO,CAAC;AAAA,QACjD,QAAQ;AACN,cAAI,CAAC,WAAY,WAAU,IAAI;AAAA,QACjC;AAAA,MACF;AAAA,IACF,GAAG;AACH,WAAO,MAAM;AACX,mBAAa;AACb,cAAQ;AAAA,IACV;AAAA,EACF,GAAG,CAAC,QAAQ,MAAM,UAAU,QAAQ,CAAC;AAErC,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,WAAW,MAAM;AAEnB,WAAO,SAAS,YACd,qBAAC,OAAE,WAAU,kBAAiB;AAAA;AAAA,MAA2B,MAAM;AAAA,MAAS;AAAA,OAAiD,IACvH;AAAA,EACN;AACA,QAAM,QAAQ,oBAAC,iBAAc,QAAQ,OAAO,QAAQ,UAAoB,QAAgB,MAAY;AACpG,MAAI,SAAS,WAAW;AACtB,WACE,qBAAC,SAAI,WAAU,gBAAe,eAAa,MAAM,UAC/C;AAAA,2BAAC,SAAI,WAAU,uBAAsB;AAAA;AAAA,QAAI,OAAO;AAAA,QAAK;AAAA,SAAsD;AAAA,MAC1G;AAAA,OACH;AAAA,EAEJ;AACA,SAAO;AACT;","names":[]}
@@ -1,2 +1 @@
1
- import type { z } from "zod";
2
- export declare const teamBlock: import("../index.js").BlockDefinition<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
1
+ export declare const teamBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;