@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,145 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useState } from "react";
4
+ import { VStack, HStack, Grid, Heading, Text, Btn } from "../ui/index.js";
5
+ import { Img } from "../../media/ImageContext.js";
6
+ function FeatureRender({ block }) {
7
+ const media = block.imageUrl ? /* @__PURE__ */ jsx(
8
+ Img,
9
+ {
10
+ src: block.imageUrl,
11
+ alt: "",
12
+ width: 900,
13
+ height: 700,
14
+ sizes: "(max-width: 720px) 100vw, 50vw",
15
+ editField: "imageUrl",
16
+ style: { width: "100%", height: "100%", maxHeight: 460, objectFit: "cover", borderRadius: "var(--radius-container)" }
17
+ }
18
+ ) : null;
19
+ const body = /* @__PURE__ */ jsxs(VStack, { gap: 3, vAlign: "center", children: [
20
+ block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
21
+ block.html && // eslint-disable-next-line react/no-danger
22
+ /* @__PURE__ */ jsx("div", { className: "xicms-richtext", dangerouslySetInnerHTML: { __html: block.html } }),
23
+ block.buttonLabel && /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(Btn, { label: block.buttonLabel, href: block.buttonHref ?? "#", variant: "primary", editField: "buttonLabel" }) })
24
+ ] });
25
+ return /* @__PURE__ */ jsx(Grid, { columns: { minWidth: 320, max: 2 }, gap: 5, className: "xicms-feature", children: block.imagePosition === "left" ? /* @__PURE__ */ jsxs(Fragment, { children: [
26
+ media,
27
+ body
28
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
29
+ body,
30
+ media
31
+ ] }) });
32
+ }
33
+ function CountUpValue({ value, animate }) {
34
+ const target = Number(value.replace(",", "."));
35
+ const decimals = /[.,](\d+)/.exec(value)?.[1].length ?? 0;
36
+ const [display, setDisplay] = useState(value);
37
+ const ref = useRef(null);
38
+ const started = useRef(false);
39
+ useEffect(() => {
40
+ const canAnimate = animate && Number.isFinite(target) && !window.matchMedia?.("(prefers-reduced-motion: reduce)").matches;
41
+ if (!canAnimate || !ref.current) {
42
+ setDisplay(value);
43
+ return;
44
+ }
45
+ const el = ref.current;
46
+ let raf = 0;
47
+ const obs = new IntersectionObserver((entries) => {
48
+ if (!entries.some((e) => e.isIntersecting) || started.current) return;
49
+ started.current = true;
50
+ obs.disconnect();
51
+ const t0 = performance.now();
52
+ const duration = 1200;
53
+ const tick = (t) => {
54
+ const p = Math.min(1, (t - t0) / duration);
55
+ const eased = 1 - Math.pow(1 - p, 3);
56
+ setDisplay(p < 1 ? (target * eased).toFixed(decimals).replace(".", ",") : value);
57
+ if (p < 1) raf = requestAnimationFrame(tick);
58
+ };
59
+ raf = requestAnimationFrame(tick);
60
+ });
61
+ obs.observe(el);
62
+ return () => {
63
+ obs.disconnect();
64
+ cancelAnimationFrame(raf);
65
+ };
66
+ }, [animate, target, decimals, value]);
67
+ return /* @__PURE__ */ jsx("span", { ref, children: display });
68
+ }
69
+ function CountersRender({ block, mode }) {
70
+ const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((i) => i.value || i.label);
71
+ if (items.length === 0) return null;
72
+ return /* @__PURE__ */ jsxs(VStack, { gap: 4, as: "section", className: "xicms-counters", children: [
73
+ block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, justify: "center", "data-xicms-edit": "heading", style: { textAlign: "center" }, children: block.heading }),
74
+ /* @__PURE__ */ jsx(Grid, { columns: { minWidth: 150 }, gap: 4, children: items.map((it) => /* @__PURE__ */ jsxs(VStack, { gap: 0.5, hAlign: "center", style: { textAlign: "center" }, children: [
75
+ /* @__PURE__ */ jsxs(Heading, { level: 2, className: "xicms-counters__value", children: [
76
+ /* @__PURE__ */ jsx("span", { "data-xicms-edit": `items.${it._i}.prefix`, children: it.prefix }),
77
+ /* @__PURE__ */ jsx(CountUpValue, { value: it.value, animate: block.animate !== false && mode !== "preview" }),
78
+ /* @__PURE__ */ jsx("span", { "data-xicms-edit": `items.${it._i}.suffix`, children: it.suffix })
79
+ ] }),
80
+ /* @__PURE__ */ jsx(Text, { color: "secondary", "data-xicms-edit": `items.${it._i}.label`, children: it.label })
81
+ ] }, it._i)) })
82
+ ] });
83
+ }
84
+ function LogosRender({ block }) {
85
+ const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((i) => i.src);
86
+ if (items.length === 0) return null;
87
+ return /* @__PURE__ */ jsxs(VStack, { gap: 3, as: "section", hAlign: "center", className: "xicms-logos", children: [
88
+ block.heading && /* @__PURE__ */ jsx(Text, { type: "label", color: "secondary", style: { textTransform: "uppercase", letterSpacing: "0.06em" }, children: block.heading }),
89
+ (() => {
90
+ const row = (ariaHidden) => /* @__PURE__ */ jsx(
91
+ HStack,
92
+ {
93
+ gap: 6,
94
+ hAlign: "center",
95
+ vAlign: "center",
96
+ className: block.marquee ? "xicms-logos__row" : void 0,
97
+ style: block.marquee ? void 0 : { flexWrap: "wrap" },
98
+ "aria-hidden": ariaHidden || void 0,
99
+ children: items.map((it) => {
100
+ const i = it._i;
101
+ const img = /* @__PURE__ */ jsx(
102
+ Img,
103
+ {
104
+ src: it.src,
105
+ alt: ariaHidden ? "" : it.alt,
106
+ width: 160,
107
+ height: 48,
108
+ editField: ariaHidden ? void 0 : `items.${i}.src`,
109
+ style: { height: 40, width: "auto", objectFit: "contain", filter: block.grayscale ? "grayscale(1)" : void 0, opacity: block.grayscale ? 0.7 : 1 }
110
+ }
111
+ );
112
+ return it.href && !ariaHidden ? /* @__PURE__ */ jsx("a", { href: it.href, rel: "noopener noreferrer", target: "_blank", children: img }, i) : /* @__PURE__ */ jsx("span", { children: img }, i);
113
+ })
114
+ }
115
+ );
116
+ if (!block.marquee) return row(false);
117
+ return /* @__PURE__ */ jsx("div", { className: "xicms-logos__marquee", children: /* @__PURE__ */ jsxs("div", { className: "xicms-logos__track", children: [
118
+ row(false),
119
+ row(true)
120
+ ] }) });
121
+ })()
122
+ ] });
123
+ }
124
+ function TimelineRender({ block }) {
125
+ const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((i) => i.title);
126
+ if (items.length === 0) return null;
127
+ return /* @__PURE__ */ jsxs(VStack, { gap: 4, as: "section", className: `xicms-timeline${block.alternate ? " xicms-timeline--alternate" : ""}`, children: [
128
+ block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
129
+ /* @__PURE__ */ jsx("ol", { className: "xicms-timeline__list", children: items.map((it, i) => /* @__PURE__ */ jsxs("li", { className: "xicms-timeline__item", children: [
130
+ /* @__PURE__ */ jsx("span", { className: "xicms-timeline__marker", "aria-hidden": true, children: it.icon || "\u25CF" }),
131
+ /* @__PURE__ */ jsxs(VStack, { gap: 0.5, className: "xicms-timeline__body", children: [
132
+ it.date && /* @__PURE__ */ jsx(Text, { type: "label", style: { color: "var(--color-accent)" }, "data-xicms-edit": `items.${it._i}.date`, children: it.date }),
133
+ /* @__PURE__ */ jsx(Heading, { level: 3, "data-xicms-edit": `items.${it._i}.title`, children: it.title }),
134
+ it.text && /* @__PURE__ */ jsx(Text, { color: "secondary", "data-xicms-edit": `items.${it._i}.text`, children: it.text })
135
+ ] })
136
+ ] }, i)) })
137
+ ] });
138
+ }
139
+ export {
140
+ CountersRender,
141
+ FeatureRender,
142
+ LogosRender,
143
+ TimelineRender
144
+ };
145
+ //# sourceMappingURL=SectionsRender.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/SectionsRender.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from \"react\";\nimport type { z } from \"zod\";\nimport type {\n FeatureBlockSchema,\n CountersBlockSchema,\n LogosBlockSchema,\n TimelineBlockSchema,\n} from \"../../schema/blocks\";\nimport type { BlockRenderProps } from \"../registry\";\nimport { VStack, HStack, Grid, Heading, Text, Btn } from \"../ui\";\nimport { Img } from \"../../media/ImageContext\";\n\n/* ── Feature (beeld + tekst) ─────────────────────────────────────────────── */\ntype Feature = z.infer<typeof FeatureBlockSchema>;\nexport function FeatureRender({ block }: BlockRenderProps<Feature>) {\n const media = block.imageUrl ? (\n <Img\n src={block.imageUrl}\n alt=\"\"\n width={900}\n height={700}\n sizes=\"(max-width: 720px) 100vw, 50vw\"\n editField=\"imageUrl\"\n style={{ width: \"100%\", height: \"100%\", maxHeight: 460, objectFit: \"cover\", borderRadius: \"var(--radius-container)\" }}\n />\n ) : null;\n const body = (\n <VStack gap={3} vAlign=\"center\">\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n {block.html && (\n // eslint-disable-next-line react/no-danger\n <div className=\"xicms-richtext\" dangerouslySetInnerHTML={{ __html: block.html }} />\n )}\n {block.buttonLabel && (\n <div><Btn label={block.buttonLabel} href={block.buttonHref ?? \"#\"} variant=\"primary\" editField=\"buttonLabel\" /></div>\n )}\n </VStack>\n );\n return (\n <Grid columns={{ minWidth: 320, max: 2 }} gap={5} className=\"xicms-feature\">\n {block.imagePosition === \"left\" ? (\n <>\n {media}\n {body}\n </>\n ) : (\n <>\n {body}\n {media}\n </>\n )}\n </Grid>\n );\n}\n/* ── Counters (tellers) ──────────────────────────────────────────────────── */\ntype Counters = z.infer<typeof CountersBlockSchema>;\n\n/**\n * Telt van 0 naar `value` (rAF, ease-out) zodra het element in beeld scrolt. Niet-numerieke\n * waarden en reduced-motion tonen direct de eindwaarde; decimalen volgen de invoer (\"4.9\" → 1 dec).\n *\n * HYDRATION-VEILIG: de starttekst is ALTIJD `value` (server en client identiek); pas in het\n * effect (client-only) springt hij naar \"0\" en start de animatie. De vorige opzet initialiseerde\n * client-side op \"0\" → server \"13\" ≠ client \"0\" ≠ hydration-mismatch op elke tellers-pagina.\n */\nfunction CountUpValue({ value, animate }: { value: string; animate: boolean }) {\n const target = Number(value.replace(\",\", \".\"));\n const decimals = /[.,](\\d+)/.exec(value)?.[1].length ?? 0;\n const [display, setDisplay] = useState(value);\n const ref = useRef<HTMLSpanElement>(null);\n const started = useRef(false);\n\n useEffect(() => {\n const canAnimate =\n animate && Number.isFinite(target) && !window.matchMedia?.(\"(prefers-reduced-motion: reduce)\").matches;\n if (!canAnimate || !ref.current) {\n // Volg latere waarde-wijzigingen (bv. bewerken in de editor-preview) ook zonder animatie.\n setDisplay(value);\n return;\n }\n const el = ref.current;\n let raf = 0;\n const obs = new IntersectionObserver((entries) => {\n if (!entries.some((e) => e.isIntersecting) || started.current) return;\n started.current = true;\n obs.disconnect();\n const t0 = performance.now();\n const duration = 1200;\n const tick = (t: number) => {\n const p = Math.min(1, (t - t0) / duration);\n const eased = 1 - Math.pow(1 - p, 3);\n setDisplay(p < 1 ? (target * eased).toFixed(decimals).replace(\".\", \",\") : value);\n if (p < 1) raf = requestAnimationFrame(tick);\n };\n raf = requestAnimationFrame(tick);\n });\n obs.observe(el);\n return () => {\n obs.disconnect();\n cancelAnimationFrame(raf);\n };\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [animate, target, decimals, value]);\n\n return <span ref={ref}>{display}</span>;\n}\n\nexport function CountersRender({ block, mode }: BlockRenderProps<Counters>) {\n // _i = index in de OORSPRONKELIJKE array — de lijst wordt gefilterd op value || label.\n const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((i) => i.value || i.label);\n if (items.length === 0) return null;\n return (\n <VStack gap={4} as=\"section\" className=\"xicms-counters\">\n {block.heading && (\n <Heading level={2} justify=\"center\" data-xicms-edit=\"heading\" style={{ textAlign: \"center\" }}>{block.heading}</Heading>\n )}\n <Grid columns={{ minWidth: 150 }} gap={4}>\n {items.map((it) => (\n <VStack key={it._i} gap={0.5} hAlign=\"center\" style={{ textAlign: \"center\" }}>\n <Heading level={2} className=\"xicms-counters__value\">\n <span data-xicms-edit={`items.${it._i}.prefix`}>{it.prefix}</span>\n {/* In de editor-preview geen animatie (mode-contract: licht en voorspelbaar). */}\n <CountUpValue value={it.value} animate={block.animate !== false && mode !== \"preview\"} />\n <span data-xicms-edit={`items.${it._i}.suffix`}>{it.suffix}</span>\n </Heading>\n <Text color=\"secondary\" data-xicms-edit={`items.${it._i}.label`}>{it.label}</Text>\n </VStack>\n ))}\n </Grid>\n </VStack>\n );\n}\n/* ── Logos (partner-/logostrip) ──────────────────────────────────────────── */\ntype Logos = z.infer<typeof LogosBlockSchema>;\nexport function LogosRender({ block }: BlockRenderProps<Logos>) {\n // _i = index in de OORSPRONKELIJKE array — nodig voor het inline vervang-pad (items.N.src).\n const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((i) => i.src);\n if (items.length === 0) return null;\n return (\n <VStack gap={3} as=\"section\" hAlign=\"center\" className=\"xicms-logos\">\n {block.heading && (\n <Text type=\"label\" color=\"secondary\" style={{ textTransform: \"uppercase\", letterSpacing: \"0.06em\" }}>\n {block.heading}\n </Text>\n )}\n {(() => {\n const row = (ariaHidden: boolean) => (\n <HStack\n gap={6}\n hAlign=\"center\"\n vAlign=\"center\"\n className={block.marquee ? \"xicms-logos__row\" : undefined}\n style={block.marquee ? undefined : { flexWrap: \"wrap\" }}\n aria-hidden={ariaHidden || undefined}\n >\n {items.map((it) => {\n const i = it._i;\n const img = (\n <Img\n src={it.src}\n alt={ariaHidden ? \"\" : it.alt}\n width={160}\n height={48}\n editField={ariaHidden ? undefined : `items.${i}.src`}\n style={{ height: 40, width: \"auto\", objectFit: \"contain\", filter: block.grayscale ? \"grayscale(1)\" : undefined, opacity: block.grayscale ? 0.7 : 1 }}\n />\n );\n return it.href && !ariaHidden ? (\n <a key={i} href={it.href} rel=\"noopener noreferrer\" target=\"_blank\">{img}</a>\n ) : (\n <span key={i}>{img}</span>\n );\n })}\n </HStack>\n );\n if (!block.marquee) return row(false);\n // Doorlopende band: de rij + een aria-hidden kopie schuiven samen 50% op (naadloze loop).\n // CSS pauzeert bij hover en staat stil bij prefers-reduced-motion.\n return (\n <div className=\"xicms-logos__marquee\">\n <div className=\"xicms-logos__track\">\n {row(false)}\n {row(true)}\n </div>\n </div>\n );\n })()}\n </VStack>\n );\n}\n/* ── Timeline (stappen) ──────────────────────────────────────────────────── */\ntype Timeline = z.infer<typeof TimelineBlockSchema>;\nexport function TimelineRender({ block }: BlockRenderProps<Timeline>) {\n // `_i` = ORIGINELE index (items zijn gefilterd op titel): inline edits moeten naar het juiste\n // item in de opgeslagen array schrijven — zelfde patroon als Team/Cards.\n const items = (block.items ?? []).map((it, i) => ({ ...it, _i: i })).filter((i) => i.title);\n if (items.length === 0) return null;\n return (\n <VStack gap={4} as=\"section\" className={`xicms-timeline${block.alternate ? \" xicms-timeline--alternate\" : \"\"}`}>\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n <ol className=\"xicms-timeline__list\">\n {items.map((it, i) => (\n <li key={i} className=\"xicms-timeline__item\">\n <span className=\"xicms-timeline__marker\" aria-hidden>{it.icon || \"●\"}</span>\n <VStack gap={0.5} className=\"xicms-timeline__body\">\n {it.date && (\n <Text type=\"label\" style={{ color: \"var(--color-accent)\" }} data-xicms-edit={`items.${it._i}.date`}>{it.date}</Text>\n )}\n <Heading level={3} data-xicms-edit={`items.${it._i}.title`}>{it.title}</Heading>\n {it.text && <Text color=\"secondary\" data-xicms-edit={`items.${it._i}.text`}>{it.text}</Text>}\n </VStack>\n </li>\n ))}\n </ol>\n </VStack>\n );\n}\n"],"mappings":"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","names":[]}
@@ -1,2 +1 @@
1
- import type { z } from "zod";
2
- export declare const sliderBlock: import("../index.js").BlockDefinition<z.core.$ZodType<unknown, unknown, z.core.$ZodTypeInternals<unknown, unknown>>>;
1
+ export declare const sliderBlock: import("../index.js").BlockDefinition<import("zod/v4/core").$ZodType<unknown, unknown, import("zod/v4/core").$ZodTypeInternals<unknown, unknown>>>;
@@ -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":";AA4CQ,SA6EE,UA7EF,KA4DM,YA5DN;AA1CR,SAAS,WAAW,QAAQ,gBAAgB;AAG5C,SAAS,mBAA0C;AACnD,SAAS,WAAW;AAIpB,SAAS,uBAAgC;AACvC,SAAO,OAAO,WAAW,eAAe,OAAO,aAAa,kCAAkC,EAAE;AAClG;AAGA,SAAS,aAAa,EAAE,OAAO,KAAK,GAA6B;AAE/D,QAAM,UAAU,MAAM,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,OAAO,EAAE,GAAG,GAAG,IAAI,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO;AAC1G,QAAM,CAAC,OAAO,QAAQ,IAAI,SAAS,CAAC;AACpC,QAAM,CAAC,QAAQ,SAAS,IAAI,SAAS,KAAK;AAG1C,QAAM,CAAC,YAAY,aAAa,IAAI,SAAS,KAAK;AAClD,QAAM,aAAa,OAAsB,IAAI;AAC7C,QAAM,QAAQ,OAAO;AAIrB,YAAU,MAAM;AACd,aAAS,CAAC,MAAO,UAAU,IAAI,IAAI,KAAK,IAAI,GAAG,QAAQ,CAAC,CAAE;AAAA,EAC5D,GAAG,CAAC,KAAK,CAAC;AAEV,YAAU,MAAM;AACd,QAAI,CAAC,MAAM,YAAY,UAAU,cAAc,SAAS,KAAK,qBAAqB,EAAG;AACrF,UAAM,KAAK,YAAY,MAAM,SAAS,CAAC,OAAO,IAAI,KAAK,KAAK,GAAG,MAAM,WAAW,GAAI;AACpF,WAAO,MAAM,cAAc,EAAE;AAAA,EAC/B,GAAG,CAAC,MAAM,UAAU,MAAM,UAAU,QAAQ,YAAY,KAAK,CAAC;AAE9D,MAAI,UAAU,GAAG;AAIf,QAAI,SAAS,WAAW;AACtB,aACE,oBAAC,SAAI,WAAU,oCAAmC,sGAElD;AAAA,IAEJ;AACA,WAAO;AAAA,EACT;AACA,QAAM,KAAK,CAAC,MAAc,UAAW,IAAI,QAAS,SAAS,KAAK;AAGhE,QAAM,gBAAgB,CAAC,MAA0B;AAC/C,eAAW,UAAU,EAAE;AAAA,EACzB;AACA,QAAM,cAAc,CAAC,MAA0B;AAC7C,QAAI,WAAW,YAAY,QAAQ,QAAQ,EAAG;AAC9C,UAAM,KAAK,EAAE,UAAU,WAAW;AAClC,eAAW,UAAU;AACrB,QAAI,KAAK,GAAI,IAAG,QAAQ,CAAC;AAAA,aAChB,KAAK,IAAK,IAAG,QAAQ,CAAC;AAAA,EACjC;AACA,QAAM,YAAY,CAAC,MAA2B;AAC5C,QAAI,EAAE,QAAQ,aAAa;AACzB,QAAE,eAAe;AACjB,SAAG,QAAQ,CAAC;AAAA,IACd,WAAW,EAAE,QAAQ,cAAc;AACjC,QAAE,eAAe;AACjB,SAAG,QAAQ,CAAC;AAAA,IACd;AAAA,EACF;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAU;AAAA,MACV,OAAO,EAAE,CAAC,sBAAgC,GAAG,MAAM,YAAY,QAAQ,KAAK,KAAK,EAAE;AAAA,MACnF,cAAc,MAAM,UAAU,IAAI;AAAA,MAClC,cAAc,MAAM,UAAU,KAAK;AAAA,MACnC,SAAS,MAAM,UAAU,IAAI;AAAA,MAC7B,QAAQ,MAAM,UAAU,KAAK;AAAA,MAC7B;AAAA,MACA,UAAU;AAAA,MACV,MAAK;AAAA,MACL,wBAAqB;AAAA,MACrB,cAAW;AAAA,MAEX;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,WAAU;AAAA,YACV;AAAA,YACA;AAAA,YACA,iBAAiB,MAAM;AAAE,yBAAW,UAAU;AAAA,YAAM;AAAA,YACpD,gBAAgB,MAAM;AAAE,yBAAW,UAAU;AAAA,YAAM;AAAA,YACnD,OAAO,EAAE,aAAa,QAAQ;AAAA,YAE9B;AAAA,kCAAC,SAAI,WAAU,uBAAsB,OAAO,EAAE,WAAW,eAAe,QAAQ,GAAG,KAAK,GACrF,iBAAO,IAAI,CAAC,GAAG,MAAM;AACpB,sBAAM,MAAM,EAAE,WACZ,oBAAC,OAAI,WAAU,uBAAsB,KAAK,EAAE,UAAU,KAAK,EAAE,OAAO,IAAI,OAAO,MAAM,QAAQ,KAAK,OAAM,SAAQ,UAAU,MAAM,GAAG,IACjI;AACJ;AAAA;AAAA;AAAA,kBAGE;AAAA,oBAAC;AAAA;AAAA,sBAEC,WAAU;AAAA,sBACV,MAAK;AAAA,sBACL,wBAAqB;AAAA,sBACrB,cAAY,GAAG,IAAI,CAAC,MAAM,KAAK;AAAA,sBAC/B,eAAa,MAAM;AAAA,sBACnB,OAAO,MAAM,SAAS;AAAA,sBAErB;AAAA,0BAAE,OAAO,oBAAC,OAAE,MAAM,EAAE,MAAO,eAAI,IAAO;AAAA,wBACtC,EAAE,WAAW,oBAAC,SAAI,WAAU,yBAAwB,mBAAiB,UAAU,EAAE,EAAE,YAAa,YAAE,SAAQ;AAAA;AAAA;AAAA,oBATtG;AAAA,kBAUP;AAAA;AAAA,cAEJ,CAAC,GACH;AAAA,cAEC,MAAM,cAAc,QAAQ,KAC3B,iCACE;AAAA,oCAAC,YAAO,MAAK,UAAS,WAAU,iDAAgD,cAAW,UAAS,SAAS,MAAM,GAAG,QAAQ,CAAC,GAAG,oBAAC;AAAA,gBACnI,oBAAC,YAAO,MAAK,UAAS,WAAU,iDAAgD,cAAW,YAAW,SAAS,MAAM,GAAG,QAAQ,CAAC,GAAG,oBAAC;AAAA,iBACvI;AAAA,cAGD,MAAM,YAAY,QAAQ,KACzB;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,WAAU;AAAA,kBACV,gBAAc;AAAA,kBACd,cAAY,aAAa,6BAA6B;AAAA,kBACtD,SAAS,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;AAAA,kBAErC,uBAAa,WAAM;AAAA;AAAA,cACtB;AAAA;AAAA;AAAA,QAEJ;AAAA,QAGC,MAAM,YAAY,QAAQ,KACzB,oBAAC,SAAI,WAAU,sBAAqB,MAAK,SAAQ,cAAW,cACzD,iBAAO,IAAI,CAAC,GAAG,MACd;AAAA,UAAC;AAAA;AAAA,YAEC,MAAK;AAAA,YACL,gBAAc,MAAM,SAAS;AAAA,YAC7B,cAAY,cAAc,IAAI,CAAC;AAAA,YAC/B,WAAW,oBAAoB,MAAM,QAAQ,+BAA+B,EAAE;AAAA,YAC9E,SAAS,MAAM,GAAG,CAAC;AAAA;AAAA,UALd;AAAA,QAMP,CACD,GACH;AAAA;AAAA;AAAA,EAEJ;AAEJ;AAEO,MAAM,cAAc,YAAY;AAAA,EACrC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,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":[]}
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>>>;