@xiwebdesign/xicms-core 4.17.1

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 (436) hide show
  1. package/dist/XiCMSProvider.d.ts +58 -0
  2. package/dist/XiCMSProvider.js +165 -0
  3. package/dist/XiCMSProvider.js.map +1 -0
  4. package/dist/admin/AdminApp.d.ts +4 -0
  5. package/dist/admin/AdminApp.js +62 -0
  6. package/dist/admin/AdminApp.js.map +1 -0
  7. package/dist/admin/AdminHelp.d.ts +2 -0
  8. package/dist/admin/AdminHelp.js +65 -0
  9. package/dist/admin/AdminHelp.js.map +1 -0
  10. package/dist/admin/NewsEditor.d.ts +2 -0
  11. package/dist/admin/NewsEditor.js +171 -0
  12. package/dist/admin/NewsEditor.js.map +1 -0
  13. package/dist/admin/SuperadminPanel.d.ts +4 -0
  14. package/dist/admin/SuperadminPanel.js +101 -0
  15. package/dist/admin/SuperadminPanel.js.map +1 -0
  16. package/dist/admin/blockEditors/StyleEditor.d.ts +10 -0
  17. package/dist/admin/blockEditors/StyleEditor.js +78 -0
  18. package/dist/admin/blockEditors/StyleEditor.js.map +1 -0
  19. package/dist/admin/blockEditors/index.d.ts +16 -0
  20. package/dist/admin/blockEditors/index.js +1602 -0
  21. package/dist/admin/blockEditors/index.js.map +1 -0
  22. package/dist/admin/editors/RichTextEditor.d.ts +10 -0
  23. package/dist/admin/editors/RichTextEditor.js +86 -0
  24. package/dist/admin/editors/RichTextEditor.js.map +1 -0
  25. package/dist/admin/forms/FormsPanel.d.ts +3 -0
  26. package/dist/admin/forms/FormsPanel.js +203 -0
  27. package/dist/admin/forms/FormsPanel.js.map +1 -0
  28. package/dist/admin/index.d.ts +21 -0
  29. package/dist/admin/index.js +38 -0
  30. package/dist/admin/index.js.map +1 -0
  31. package/dist/admin/lib/compressImage.d.ts +12 -0
  32. package/dist/admin/lib/compressImage.js +53 -0
  33. package/dist/admin/lib/compressImage.js.map +1 -0
  34. package/dist/admin/lib/mediaUsage.d.ts +9 -0
  35. package/dist/admin/lib/mediaUsage.js +25 -0
  36. package/dist/admin/lib/mediaUsage.js.map +1 -0
  37. package/dist/admin/lib/pagesClient.d.ts +38 -0
  38. package/dist/admin/lib/pagesClient.js +143 -0
  39. package/dist/admin/lib/pagesClient.js.map +1 -0
  40. package/dist/admin/lib/slugify.d.ts +2 -0
  41. package/dist/admin/lib/slugify.js +7 -0
  42. package/dist/admin/lib/slugify.js.map +1 -0
  43. package/dist/admin/lib/upload.d.ts +13 -0
  44. package/dist/admin/lib/upload.js +40 -0
  45. package/dist/admin/lib/upload.js.map +1 -0
  46. package/dist/admin/lib/zodFields.d.ts +27 -0
  47. package/dist/admin/lib/zodFields.js +48 -0
  48. package/dist/admin/lib/zodFields.js.map +1 -0
  49. package/dist/admin/media/MediaManager.d.ts +3 -0
  50. package/dist/admin/media/MediaManager.js +132 -0
  51. package/dist/admin/media/MediaManager.js.map +1 -0
  52. package/dist/admin/media/MediaPicker.d.ts +24 -0
  53. package/dist/admin/media/MediaPicker.js +93 -0
  54. package/dist/admin/media/MediaPicker.js.map +1 -0
  55. package/dist/admin/pages/PageEditor.d.ts +5 -0
  56. package/dist/admin/pages/PageEditor.js +239 -0
  57. package/dist/admin/pages/PageEditor.js.map +1 -0
  58. package/dist/admin/pages/PagesPanel.d.ts +3 -0
  59. package/dist/admin/pages/PagesPanel.js +92 -0
  60. package/dist/admin/pages/PagesPanel.js.map +1 -0
  61. package/dist/admin/panelRegistry.d.ts +20 -0
  62. package/dist/admin/panelRegistry.js +23 -0
  63. package/dist/admin/panelRegistry.js.map +1 -0
  64. package/dist/admin/patterns/PatternInserter.d.ts +10 -0
  65. package/dist/admin/patterns/PatternInserter.js +58 -0
  66. package/dist/admin/patterns/PatternInserter.js.map +1 -0
  67. package/dist/admin/settings/SettingsPanel.d.ts +3 -0
  68. package/dist/admin/settings/SettingsPanel.js +304 -0
  69. package/dist/admin/settings/SettingsPanel.js.map +1 -0
  70. package/dist/admin/settings/moduleSettingsForm.d.ts +12 -0
  71. package/dist/admin/settings/moduleSettingsForm.js +45 -0
  72. package/dist/admin/settings/moduleSettingsForm.js.map +1 -0
  73. package/dist/admin/stats/StatsPanel.d.ts +4 -0
  74. package/dist/admin/stats/StatsPanel.js +80 -0
  75. package/dist/admin/stats/StatsPanel.js.map +1 -0
  76. package/dist/admin/ui/ArrayEditor.d.ts +16 -0
  77. package/dist/admin/ui/ArrayEditor.js +38 -0
  78. package/dist/admin/ui/ArrayEditor.js.map +1 -0
  79. package/dist/admin/ui/ConfirmDialog.d.ts +22 -0
  80. package/dist/admin/ui/ConfirmDialog.js +47 -0
  81. package/dist/admin/ui/ConfirmDialog.js.map +1 -0
  82. package/dist/admin/ui/cn.d.ts +3 -0
  83. package/dist/admin/ui/cn.js +9 -0
  84. package/dist/admin/ui/cn.js.map +1 -0
  85. package/dist/admin/ui/dialog.d.ts +9 -0
  86. package/dist/admin/ui/dialog.js +47 -0
  87. package/dist/admin/ui/dialog.js.map +1 -0
  88. package/dist/admin/ui/index.d.ts +7 -0
  89. package/dist/admin/ui/index.js +29 -0
  90. package/dist/admin/ui/index.js.map +1 -0
  91. package/dist/admin/ui/primitives.d.ts +37 -0
  92. package/dist/admin/ui/primitives.js +137 -0
  93. package/dist/admin/ui/primitives.js.map +1 -0
  94. package/dist/admin/ui/select.d.ts +11 -0
  95. package/dist/admin/ui/select.js +27 -0
  96. package/dist/admin/ui/select.js.map +1 -0
  97. package/dist/admin/ui/switch.d.ts +6 -0
  98. package/dist/admin/ui/switch.js +22 -0
  99. package/dist/admin/ui/switch.js.map +1 -0
  100. package/dist/admin/ui/tabs.d.ts +5 -0
  101. package/dist/admin/ui/tabs.js +36 -0
  102. package/dist/admin/ui/tabs.js.map +1 -0
  103. package/dist/admin/ui/toast.d.ts +19 -0
  104. package/dist/admin/ui/toast.js +24 -0
  105. package/dist/admin/ui/toast.js.map +1 -0
  106. package/dist/admin/visual/VisualEditor.d.ts +10 -0
  107. package/dist/admin/visual/VisualEditor.js +597 -0
  108. package/dist/admin/visual/VisualEditor.js.map +1 -0
  109. package/dist/admin/visual/reorder.d.ts +6 -0
  110. package/dist/admin/visual/reorder.js +12 -0
  111. package/dist/admin/visual/reorder.js.map +1 -0
  112. package/dist/admin.css +1 -0
  113. package/dist/auth/AuthProvider.d.ts +30 -0
  114. package/dist/auth/AuthProvider.js +110 -0
  115. package/dist/auth/AuthProvider.js.map +1 -0
  116. package/dist/auth/LoginForm.d.ts +4 -0
  117. package/dist/auth/LoginForm.js +122 -0
  118. package/dist/auth/LoginForm.js.map +1 -0
  119. package/dist/auth/roles.d.ts +15 -0
  120. package/dist/auth/roles.js +21 -0
  121. package/dist/auth/roles.js.map +1 -0
  122. package/dist/blocks/BlockErrorBoundary.d.ts +32 -0
  123. package/dist/blocks/BlockErrorBoundary.js +39 -0
  124. package/dist/blocks/BlockErrorBoundary.js.map +1 -0
  125. package/dist/blocks/BlockRenderer.d.ts +15 -0
  126. package/dist/blocks/BlockRenderer.js +24 -0
  127. package/dist/blocks/BlockRenderer.js.map +1 -0
  128. package/dist/blocks/blockStyle.d.ts +14 -0
  129. package/dist/blocks/blockStyle.js +14 -0
  130. package/dist/blocks/blockStyle.js.map +1 -0
  131. package/dist/blocks/builtins/Accordion.d.ts +2 -0
  132. package/dist/blocks/builtins/Accordion.js +45 -0
  133. package/dist/blocks/builtins/Accordion.js.map +1 -0
  134. package/dist/blocks/builtins/Agenda.d.ts +23 -0
  135. package/dist/blocks/builtins/Agenda.js +102 -0
  136. package/dist/blocks/builtins/Agenda.js.map +1 -0
  137. package/dist/blocks/builtins/Banner.d.ts +2 -0
  138. package/dist/blocks/builtins/Banner.js +45 -0
  139. package/dist/blocks/builtins/Banner.js.map +1 -0
  140. package/dist/blocks/builtins/BeforeAfter.d.ts +2 -0
  141. package/dist/blocks/builtins/BeforeAfter.js +44 -0
  142. package/dist/blocks/builtins/BeforeAfter.js.map +1 -0
  143. package/dist/blocks/builtins/Booking.d.ts +2 -0
  144. package/dist/blocks/builtins/Booking.js +27 -0
  145. package/dist/blocks/builtins/Booking.js.map +1 -0
  146. package/dist/blocks/builtins/Breadcrumbs.d.ts +10 -0
  147. package/dist/blocks/builtins/Breadcrumbs.js +73 -0
  148. package/dist/blocks/builtins/Breadcrumbs.js.map +1 -0
  149. package/dist/blocks/builtins/Cards.d.ts +2 -0
  150. package/dist/blocks/builtins/Cards.js +94 -0
  151. package/dist/blocks/builtins/Cards.js.map +1 -0
  152. package/dist/blocks/builtins/Columns.d.ts +2 -0
  153. package/dist/blocks/builtins/Columns.js +22 -0
  154. package/dist/blocks/builtins/Columns.js.map +1 -0
  155. package/dist/blocks/builtins/Contact.d.ts +7 -0
  156. package/dist/blocks/builtins/Contact.js +121 -0
  157. package/dist/blocks/builtins/Contact.js.map +1 -0
  158. package/dist/blocks/builtins/Countdown.d.ts +18 -0
  159. package/dist/blocks/builtins/Countdown.js +65 -0
  160. package/dist/blocks/builtins/Countdown.js.map +1 -0
  161. package/dist/blocks/builtins/Cta.d.ts +2 -0
  162. package/dist/blocks/builtins/Cta.js +52 -0
  163. package/dist/blocks/builtins/Cta.js.map +1 -0
  164. package/dist/blocks/builtins/Downloads.d.ts +2 -0
  165. package/dist/blocks/builtins/Downloads.js +32 -0
  166. package/dist/blocks/builtins/Downloads.js.map +1 -0
  167. package/dist/blocks/builtins/Elements.d.ts +4 -0
  168. package/dist/blocks/builtins/Elements.js +64 -0
  169. package/dist/blocks/builtins/Elements.js.map +1 -0
  170. package/dist/blocks/builtins/Embed.d.ts +2 -0
  171. package/dist/blocks/builtins/Embed.js +30 -0
  172. package/dist/blocks/builtins/Embed.js.map +1 -0
  173. package/dist/blocks/builtins/Faq.d.ts +6 -0
  174. package/dist/blocks/builtins/Faq.js +110 -0
  175. package/dist/blocks/builtins/Faq.js.map +1 -0
  176. package/dist/blocks/builtins/FormBlock.d.ts +2 -0
  177. package/dist/blocks/builtins/FormBlock.js +221 -0
  178. package/dist/blocks/builtins/FormBlock.js.map +1 -0
  179. package/dist/blocks/builtins/Gallery.d.ts +23 -0
  180. package/dist/blocks/builtins/Gallery.js +177 -0
  181. package/dist/blocks/builtins/Gallery.js.map +1 -0
  182. package/dist/blocks/builtins/Hero.d.ts +2 -0
  183. package/dist/blocks/builtins/Hero.js +47 -0
  184. package/dist/blocks/builtins/Hero.js.map +1 -0
  185. package/dist/blocks/builtins/ImageBlock.d.ts +2 -0
  186. package/dist/blocks/builtins/ImageBlock.js +24 -0
  187. package/dist/blocks/builtins/ImageBlock.js.map +1 -0
  188. package/dist/blocks/builtins/Jobs.d.ts +8 -0
  189. package/dist/blocks/builtins/Jobs.js +65 -0
  190. package/dist/blocks/builtins/Jobs.js.map +1 -0
  191. package/dist/blocks/builtins/Layout.d.ts +3 -0
  192. package/dist/blocks/builtins/Layout.js +67 -0
  193. package/dist/blocks/builtins/Layout.js.map +1 -0
  194. package/dist/blocks/builtins/MapBlock.d.ts +2 -0
  195. package/dist/blocks/builtins/MapBlock.js +31 -0
  196. package/dist/blocks/builtins/MapBlock.js.map +1 -0
  197. package/dist/blocks/builtins/NewsListBlock.d.ts +2 -0
  198. package/dist/blocks/builtins/NewsListBlock.js +24 -0
  199. package/dist/blocks/builtins/NewsListBlock.js.map +1 -0
  200. package/dist/blocks/builtins/Newsletter.d.ts +2 -0
  201. package/dist/blocks/builtins/Newsletter.js +84 -0
  202. package/dist/blocks/builtins/Newsletter.js.map +1 -0
  203. package/dist/blocks/builtins/OpenNowBadge.d.ts +9 -0
  204. package/dist/blocks/builtins/OpenNowBadge.js +20 -0
  205. package/dist/blocks/builtins/OpenNowBadge.js.map +1 -0
  206. package/dist/blocks/builtins/OpeningHours.d.ts +2 -0
  207. package/dist/blocks/builtins/OpeningHours.js +47 -0
  208. package/dist/blocks/builtins/OpeningHours.js.map +1 -0
  209. package/dist/blocks/builtins/PdfBlock.d.ts +2 -0
  210. package/dist/blocks/builtins/PdfBlock.js +97 -0
  211. package/dist/blocks/builtins/PdfBlock.js.map +1 -0
  212. package/dist/blocks/builtins/Portfolio.d.ts +2 -0
  213. package/dist/blocks/builtins/Portfolio.js +94 -0
  214. package/dist/blocks/builtins/Portfolio.js.map +1 -0
  215. package/dist/blocks/builtins/Pricing.d.ts +6 -0
  216. package/dist/blocks/builtins/Pricing.js +77 -0
  217. package/dist/blocks/builtins/Pricing.js.map +1 -0
  218. package/dist/blocks/builtins/RichTextBlock.d.ts +2 -0
  219. package/dist/blocks/builtins/RichTextBlock.js +18 -0
  220. package/dist/blocks/builtins/RichTextBlock.js.map +1 -0
  221. package/dist/blocks/builtins/Search.d.ts +2 -0
  222. package/dist/blocks/builtins/Search.js +99 -0
  223. package/dist/blocks/builtins/Search.js.map +1 -0
  224. package/dist/blocks/builtins/Sections.d.ts +5 -0
  225. package/dist/blocks/builtins/Sections.js +183 -0
  226. package/dist/blocks/builtins/Sections.js.map +1 -0
  227. package/dist/blocks/builtins/Slider.d.ts +2 -0
  228. package/dist/blocks/builtins/Slider.js +131 -0
  229. package/dist/blocks/builtins/Slider.js.map +1 -0
  230. package/dist/blocks/builtins/Spacer.d.ts +2 -0
  231. package/dist/blocks/builtins/Spacer.js +19 -0
  232. package/dist/blocks/builtins/Spacer.js.map +1 -0
  233. package/dist/blocks/builtins/Team.d.ts +2 -0
  234. package/dist/blocks/builtins/Team.js +70 -0
  235. package/dist/blocks/builtins/Team.js.map +1 -0
  236. package/dist/blocks/builtins/Testimonials.d.ts +8 -0
  237. package/dist/blocks/builtins/Testimonials.js +82 -0
  238. package/dist/blocks/builtins/Testimonials.js.map +1 -0
  239. package/dist/blocks/builtins/Video.d.ts +9 -0
  240. package/dist/blocks/builtins/Video.js +77 -0
  241. package/dist/blocks/builtins/Video.js.map +1 -0
  242. package/dist/blocks/builtins/WhatsappChat.d.ts +8 -0
  243. package/dist/blocks/builtins/WhatsappChat.js +51 -0
  244. package/dist/blocks/builtins/WhatsappChat.js.map +1 -0
  245. package/dist/blocks/builtins/Widgets.d.ts +13 -0
  246. package/dist/blocks/builtins/Widgets.js +308 -0
  247. package/dist/blocks/builtins/Widgets.js.map +1 -0
  248. package/dist/blocks/builtins/consentEmbed.d.ts +17 -0
  249. package/dist/blocks/builtins/consentEmbed.js +31 -0
  250. package/dist/blocks/builtins/consentEmbed.js.map +1 -0
  251. package/dist/blocks/builtins/index.d.ts +46 -0
  252. package/dist/blocks/builtins/index.js +121 -0
  253. package/dist/blocks/builtins/index.js.map +1 -0
  254. package/dist/blocks/builtins/lib/bookingUrl.d.ts +8 -0
  255. package/dist/blocks/builtins/lib/bookingUrl.js +50 -0
  256. package/dist/blocks/builtins/lib/bookingUrl.js.map +1 -0
  257. package/dist/blocks/builtins/lib/fileIcon.d.ts +2 -0
  258. package/dist/blocks/builtins/lib/fileIcon.js +45 -0
  259. package/dist/blocks/builtins/lib/fileIcon.js.map +1 -0
  260. package/dist/blocks/builtins/lib/ics.d.ts +17 -0
  261. package/dist/blocks/builtins/lib/ics.js +50 -0
  262. package/dist/blocks/builtins/lib/ics.js.map +1 -0
  263. package/dist/blocks/builtins/lib/openingHours.d.ts +20 -0
  264. package/dist/blocks/builtins/lib/openingHours.js +79 -0
  265. package/dist/blocks/builtins/lib/openingHours.js.map +1 -0
  266. package/dist/blocks/builtins/lib/searchRank.d.ts +22 -0
  267. package/dist/blocks/builtins/lib/searchRank.js +45 -0
  268. package/dist/blocks/builtins/lib/searchRank.js.map +1 -0
  269. package/dist/blocks/builtins/lib/submitForm.d.ts +6 -0
  270. package/dist/blocks/builtins/lib/submitForm.js +14 -0
  271. package/dist/blocks/builtins/lib/submitForm.js.map +1 -0
  272. package/dist/blocks/context.d.ts +8 -0
  273. package/dist/blocks/context.js +20 -0
  274. package/dist/blocks/context.js.map +1 -0
  275. package/dist/blocks/index.d.ts +9 -0
  276. package/dist/blocks/index.js +21 -0
  277. package/dist/blocks/index.js.map +1 -0
  278. package/dist/blocks/registry.d.ts +75 -0
  279. package/dist/blocks/registry.js +71 -0
  280. package/dist/blocks/registry.js.map +1 -0
  281. package/dist/blocks/ui/index.d.ts +35 -0
  282. package/dist/blocks/ui/index.js +48 -0
  283. package/dist/blocks/ui/index.js.map +1 -0
  284. package/dist/components/EditBar.d.ts +2 -0
  285. package/dist/components/EditBar.js +20 -0
  286. package/dist/components/EditBar.js.map +1 -0
  287. package/dist/components/EditableImage.d.ts +18 -0
  288. package/dist/components/EditableImage.js +62 -0
  289. package/dist/components/EditableImage.js.map +1 -0
  290. package/dist/components/EditableRichText.d.ts +14 -0
  291. package/dist/components/EditableRichText.js +26 -0
  292. package/dist/components/EditableRichText.js.map +1 -0
  293. package/dist/components/EditableText.d.ts +21 -0
  294. package/dist/components/EditableText.js +25 -0
  295. package/dist/components/EditableText.js.map +1 -0
  296. package/dist/components/News.d.ts +38 -0
  297. package/dist/components/News.js +128 -0
  298. package/dist/components/News.js.map +1 -0
  299. package/dist/components/PageView.d.ts +8 -0
  300. package/dist/components/PageView.js +28 -0
  301. package/dist/components/PageView.js.map +1 -0
  302. package/dist/components/ResponsiveImage.d.ts +16 -0
  303. package/dist/components/ResponsiveImage.js +39 -0
  304. package/dist/components/ResponsiveImage.js.map +1 -0
  305. package/dist/components/site/SiteFooter.d.ts +12 -0
  306. package/dist/components/site/SiteFooter.js +34 -0
  307. package/dist/components/site/SiteFooter.js.map +1 -0
  308. package/dist/config.d.ts +8 -0
  309. package/dist/config.js +17 -0
  310. package/dist/config.js.map +1 -0
  311. package/dist/content/ContentProvider.d.ts +23 -0
  312. package/dist/content/ContentProvider.js +86 -0
  313. package/dist/content/ContentProvider.js.map +1 -0
  314. package/dist/content/types.d.ts +41 -0
  315. package/dist/content/types.js +1 -0
  316. package/dist/content/types.js.map +1 -0
  317. package/dist/demo/DemoStudio.d.ts +7 -0
  318. package/dist/demo/DemoStudio.js +54 -0
  319. package/dist/demo/DemoStudio.js.map +1 -0
  320. package/dist/demo/demoStore.d.ts +26 -0
  321. package/dist/demo/demoStore.js +115 -0
  322. package/dist/demo/demoStore.js.map +1 -0
  323. package/dist/editor/EditorProvider.d.ts +12 -0
  324. package/dist/editor/EditorProvider.js +22 -0
  325. package/dist/editor/EditorProvider.js.map +1 -0
  326. package/dist/firebase/admin.d.ts +7 -0
  327. package/dist/firebase/admin.js +31 -0
  328. package/dist/firebase/admin.js.map +1 -0
  329. package/dist/firebase/appcheck.d.ts +6 -0
  330. package/dist/firebase/appcheck.js +23 -0
  331. package/dist/firebase/appcheck.js.map +1 -0
  332. package/dist/firebase/client.d.ts +9 -0
  333. package/dist/firebase/client.js +44 -0
  334. package/dist/firebase/client.js.map +1 -0
  335. package/dist/firebase/region.d.ts +5 -0
  336. package/dist/firebase/region.js +7 -0
  337. package/dist/firebase/region.js.map +1 -0
  338. package/dist/index.d.ts +54 -0
  339. package/dist/index.js +172 -0
  340. package/dist/index.js.map +1 -0
  341. package/dist/layers.css +13 -0
  342. package/dist/lock/DemoLock.d.ts +5 -0
  343. package/dist/lock/DemoLock.js +35 -0
  344. package/dist/lock/DemoLock.js.map +1 -0
  345. package/dist/media/ImageContext.d.ts +41 -0
  346. package/dist/media/ImageContext.js +74 -0
  347. package/dist/media/ImageContext.js.map +1 -0
  348. package/dist/modules/builtins.d.ts +46 -0
  349. package/dist/modules/builtins.js +462 -0
  350. package/dist/modules/builtins.js.map +1 -0
  351. package/dist/modules/consent/ConsentBanner.d.ts +42 -0
  352. package/dist/modules/consent/ConsentBanner.js +119 -0
  353. package/dist/modules/consent/ConsentBanner.js.map +1 -0
  354. package/dist/modules/consent/useConsent.d.ts +28 -0
  355. package/dist/modules/consent/useConsent.js +52 -0
  356. package/dist/modules/consent/useConsent.js.map +1 -0
  357. package/dist/modules/context.d.ts +20 -0
  358. package/dist/modules/context.js +31 -0
  359. package/dist/modules/context.js.map +1 -0
  360. package/dist/modules/contract.d.ts +9 -0
  361. package/dist/modules/contract.js +38 -0
  362. package/dist/modules/contract.js.map +1 -0
  363. package/dist/modules/defineModule.d.ts +11 -0
  364. package/dist/modules/defineModule.js +7 -0
  365. package/dist/modules/defineModule.js.map +1 -0
  366. package/dist/modules/index.d.ts +13 -0
  367. package/dist/modules/index.js +44 -0
  368. package/dist/modules/index.js.map +1 -0
  369. package/dist/modules/overrides.d.ts +17 -0
  370. package/dist/modules/overrides.js +25 -0
  371. package/dist/modules/overrides.js.map +1 -0
  372. package/dist/modules/registry.d.ts +40 -0
  373. package/dist/modules/registry.js +79 -0
  374. package/dist/modules/registry.js.map +1 -0
  375. package/dist/modules/types.d.ts +66 -0
  376. package/dist/modules/types.js +1 -0
  377. package/dist/modules/types.js.map +1 -0
  378. package/dist/patterns/builtins.d.ts +31 -0
  379. package/dist/patterns/builtins.js +415 -0
  380. package/dist/patterns/builtins.js.map +1 -0
  381. package/dist/patterns/index.d.ts +6 -0
  382. package/dist/patterns/index.js +9 -0
  383. package/dist/patterns/index.js.map +1 -0
  384. package/dist/patterns/patterns.d.ts +28 -0
  385. package/dist/patterns/patterns.js +53 -0
  386. package/dist/patterns/patterns.js.map +1 -0
  387. package/dist/render/PageRenderer.d.ts +13 -0
  388. package/dist/render/PageRenderer.js +14 -0
  389. package/dist/render/PageRenderer.js.map +1 -0
  390. package/dist/render/PublishedPage.d.ts +13 -0
  391. package/dist/render/PublishedPage.js +16 -0
  392. package/dist/render/PublishedPage.js.map +1 -0
  393. package/dist/schema/blocks.d.ts +15052 -0
  394. package/dist/schema/blocks.js +794 -0
  395. package/dist/schema/blocks.js.map +1 -0
  396. package/dist/schema/forms.d.ts +111 -0
  397. package/dist/schema/forms.js +47 -0
  398. package/dist/schema/forms.js.map +1 -0
  399. package/dist/schema/index.d.ts +11 -0
  400. package/dist/schema/index.js +16 -0
  401. package/dist/schema/index.js.map +1 -0
  402. package/dist/schema/pages.d.ts +674 -0
  403. package/dist/schema/pages.js +37 -0
  404. package/dist/schema/pages.js.map +1 -0
  405. package/dist/schema/seo.d.ts +29 -0
  406. package/dist/schema/seo.js +17 -0
  407. package/dist/schema/seo.js.map +1 -0
  408. package/dist/schema/settings.d.ts +1126 -0
  409. package/dist/schema/settings.js +128 -0
  410. package/dist/schema/settings.js.map +1 -0
  411. package/dist/schema/siteConfig.d.ts +722 -0
  412. package/dist/schema/siteConfig.js +39 -0
  413. package/dist/schema/siteConfig.js.map +1 -0
  414. package/dist/server/env.d.ts +10 -0
  415. package/dist/server/env.js +36 -0
  416. package/dist/server/env.js.map +1 -0
  417. package/dist/server/index.d.ts +10 -0
  418. package/dist/server/index.js +51 -0
  419. package/dist/server/index.js.map +1 -0
  420. package/dist/server/pages.d.ts +15 -0
  421. package/dist/server/pages.js +99 -0
  422. package/dist/server/pages.js.map +1 -0
  423. package/dist/server/sanitize.d.ts +2 -0
  424. package/dist/server/sanitize.js +55 -0
  425. package/dist/server/sanitize.js.map +1 -0
  426. package/dist/server/seo.d.ts +116 -0
  427. package/dist/server/seo.js +179 -0
  428. package/dist/server/seo.js.map +1 -0
  429. package/dist/settings/useSiteSettings.d.ts +25 -0
  430. package/dist/settings/useSiteSettings.js +68 -0
  431. package/dist/settings/useSiteSettings.js.map +1 -0
  432. package/dist/styles.css +2495 -0
  433. package/dist/theme/presets.d.ts +12 -0
  434. package/dist/theme/presets.js +147 -0
  435. package/dist/theme/presets.js.map +1 -0
  436. package/package.json +112 -0
@@ -0,0 +1,97 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useState } from "react";
4
+ import { PdfBlockSchema } from "../../schema/blocks";
5
+ import { defineBlock } from "../registry";
6
+ import { VStack, HStack, Heading, Text } from "../ui";
7
+ function PdfRender({ block, mode }) {
8
+ const docs = (block.documents ?? []).filter((d) => d.url);
9
+ const [active, setActive] = useState(0);
10
+ if (docs.length === 0 && !block.heading) return null;
11
+ const current = docs[Math.min(active, docs.length - 1)];
12
+ return /* @__PURE__ */ jsxs(VStack, { gap: 3, as: "section", children: [
13
+ block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
14
+ docs.length > 1 && /* @__PURE__ */ jsx(HStack, { gap: 1, style: { flexWrap: "wrap" }, role: "tablist", children: docs.map((d, i) => /* @__PURE__ */ jsx(
15
+ "button",
16
+ {
17
+ type: "button",
18
+ role: "tab",
19
+ "aria-selected": i === active,
20
+ onClick: () => setActive(i),
21
+ style: {
22
+ padding: "0.4rem 0.9rem",
23
+ borderRadius: "var(--radius-full, 999px)",
24
+ border: "1px solid var(--color-border)",
25
+ cursor: "pointer",
26
+ fontWeight: 600,
27
+ fontSize: "0.9rem",
28
+ background: i === active ? "var(--color-accent)" : "transparent",
29
+ color: i === active ? "var(--color-on-accent)" : "var(--color-text-primary)"
30
+ },
31
+ children: d.label || `Document ${i + 1}`
32
+ },
33
+ i
34
+ )) }),
35
+ current ? /* @__PURE__ */ jsx(
36
+ "div",
37
+ {
38
+ style: {
39
+ borderRadius: "var(--radius-container)",
40
+ overflow: "hidden",
41
+ border: "1px solid var(--color-border)",
42
+ background: "var(--color-background-muted, rgba(0,0,0,0.03))"
43
+ },
44
+ children: mode === "preview" ? /* @__PURE__ */ jsx("div", { className: "xicms-embed-consent xicms-embed-preview", role: "note", style: { height: Math.min(block.height, 360) }, children: /* @__PURE__ */ jsxs("p", { children: [
45
+ "\u{1F4C4} PDF \u201C",
46
+ current.label || "document",
47
+ "\u201D \u2014 wordt op de live site geladen (niet in de editor)."
48
+ ] }) }) : (
49
+ // <object> i.p.v. <iframe>: browsers zonder inline PDF-viewer (veel mobiel) tonen
50
+ // dan de fallback-inhoud met een open/download-knop i.p.v. een leeg vlak.
51
+ /* @__PURE__ */ jsx(
52
+ "object",
53
+ {
54
+ data: `${current.url}#view=FitH`,
55
+ type: "application/pdf",
56
+ "aria-label": current.label || block.heading || "PDF",
57
+ style: { border: 0, width: "100%", height: block.height, display: "block" },
58
+ children: /* @__PURE__ */ jsxs("div", { style: { display: "grid", placeItems: "center", gap: "0.6rem", padding: "2.5rem 1rem", textAlign: "center" }, children: [
59
+ /* @__PURE__ */ jsx(Text, { color: "secondary", children: "Je browser kan deze PDF niet inline tonen." }),
60
+ /* @__PURE__ */ jsxs("a", { className: "xicms-btn", href: current.url, target: "_blank", rel: "noopener noreferrer", children: [
61
+ "\u{1F4C4} Open \u201C",
62
+ current.label || "PDF",
63
+ "\u201D"
64
+ ] })
65
+ ] })
66
+ }
67
+ )
68
+ )
69
+ }
70
+ ) : /* @__PURE__ */ jsx(Text, { color: "secondary", children: "Voeg een PDF toe in de editor." }),
71
+ block.showDownload && current && /* @__PURE__ */ jsx("a", { href: current.url, target: "_blank", rel: "noopener noreferrer", style: { color: "var(--color-accent)" }, children: /* @__PURE__ */ jsxs(Text, { type: "label", children: [
72
+ "\u2197 Open \u201C",
73
+ current.label || "PDF",
74
+ "\u201D in een nieuw tabblad"
75
+ ] }) })
76
+ ] });
77
+ }
78
+ const pdfBlock = defineBlock({
79
+ type: "pdf",
80
+ schema: PdfBlockSchema,
81
+ Render: PdfRender,
82
+ label: "PDF-lezer (menu/document)",
83
+ icon: "\u{1F4C4}",
84
+ defaults: () => ({
85
+ heading: "Onze kaart",
86
+ documents: [
87
+ { label: "Lunchkaart", url: "" },
88
+ { label: "Dinerkaart", url: "" }
89
+ ],
90
+ height: 820,
91
+ showDownload: true
92
+ })
93
+ });
94
+ export {
95
+ pdfBlock
96
+ };
97
+ //# sourceMappingURL=PdfBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/PdfBlock.tsx"],"sourcesContent":["\"use client\";\n\nimport { useState } from \"react\";\nimport type { z } from \"zod\";\nimport { PdfBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\nimport { VStack, HStack, Heading, Text } from \"../ui\";\n\ntype Pdf = z.infer<typeof PdfBlockSchema>;\n\n/**\n * Inline PDF-lezer voor bv. menukaarten. Eén of meer PDF's; bij meerdere verschijnen tabs\n * (lunchkaart/dinerkaart/wijnkaart…). De klant vervangt de PDF's zelf in de editor (URL of\n * media-upload). In de editor (mode=\"preview\") tonen we een lichte placeholder i.p.v. de iframe.\n */\nfunction PdfRender({ block, mode }: BlockRenderProps<Pdf>) {\n const docs = (block.documents ?? []).filter((d) => d.url);\n const [active, setActive] = useState(0);\n if (docs.length === 0 && !block.heading) return null;\n const current = docs[Math.min(active, docs.length - 1)];\n\n return (\n <VStack gap={3} as=\"section\">\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n\n {docs.length > 1 && (\n <HStack gap={1} style={{ flexWrap: \"wrap\" }} role=\"tablist\">\n {docs.map((d, i) => (\n <button\n key={i}\n type=\"button\"\n role=\"tab\"\n aria-selected={i === active}\n onClick={() => setActive(i)}\n style={{\n padding: \"0.4rem 0.9rem\",\n borderRadius: \"var(--radius-full, 999px)\",\n border: \"1px solid var(--color-border)\",\n cursor: \"pointer\",\n fontWeight: 600,\n fontSize: \"0.9rem\",\n background: i === active ? \"var(--color-accent)\" : \"transparent\",\n color: i === active ? \"var(--color-on-accent)\" : \"var(--color-text-primary)\",\n }}\n >\n {d.label || `Document ${i + 1}`}\n </button>\n ))}\n </HStack>\n )}\n\n {current ? (\n <div\n style={{\n borderRadius: \"var(--radius-container)\",\n overflow: \"hidden\",\n border: \"1px solid var(--color-border)\",\n background: \"var(--color-background-muted, rgba(0,0,0,0.03))\",\n }}\n >\n {mode === \"preview\" ? (\n <div className=\"xicms-embed-consent xicms-embed-preview\" role=\"note\" style={{ height: Math.min(block.height, 360) }}>\n <p>📄 PDF “{current.label || \"document\"}” — wordt op de live site geladen (niet in de editor).</p>\n </div>\n ) : (\n // <object> i.p.v. <iframe>: browsers zonder inline PDF-viewer (veel mobiel) tonen\n // dan de fallback-inhoud met een open/download-knop i.p.v. een leeg vlak.\n <object\n data={`${current.url}#view=FitH`}\n type=\"application/pdf\"\n aria-label={current.label || block.heading || \"PDF\"}\n style={{ border: 0, width: \"100%\", height: block.height, display: \"block\" }}\n >\n <div style={{ display: \"grid\", placeItems: \"center\", gap: \"0.6rem\", padding: \"2.5rem 1rem\", textAlign: \"center\" }}>\n <Text color=\"secondary\">Je browser kan deze PDF niet inline tonen.</Text>\n <a className=\"xicms-btn\" href={current.url} target=\"_blank\" rel=\"noopener noreferrer\">\n 📄 Open “{current.label || \"PDF\"}”\n </a>\n </div>\n </object>\n )}\n </div>\n ) : (\n <Text color=\"secondary\">Voeg een PDF toe in de editor.</Text>\n )}\n\n {block.showDownload && current && (\n <a href={current.url} target=\"_blank\" rel=\"noopener noreferrer\" style={{ color: \"var(--color-accent)\" }}>\n <Text type=\"label\">↗ Open “{current.label || \"PDF\"}” in een nieuw tabblad</Text>\n </a>\n )}\n </VStack>\n );\n}\n\nexport const pdfBlock = defineBlock({\n type: \"pdf\",\n schema: PdfBlockSchema,\n Render: PdfRender,\n label: \"PDF-lezer (menu/document)\",\n icon: \"📄\",\n defaults: () => ({\n heading: \"Onze kaart\",\n documents: [\n { label: \"Lunchkaart\", url: \"\" },\n { label: \"Dinerkaart\", url: \"\" },\n ],\n height: 820,\n showDownload: true,\n }),\n});\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+ import type { z } from "zod";
2
+ export declare const portfolioBlock: import("..").BlockDefinition<z.ZodTypeAny>;
@@ -0,0 +1,94 @@
1
+ "use client";
2
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
3
+ import { useRef, useState } from "react";
4
+ import { PortfolioBlockSchema } from "../../schema/blocks";
5
+ import { defineBlock } from "../registry";
6
+ import { VStack, Grid, Heading, Text } from "../ui";
7
+ import { Img } from "../../media/ImageContext";
8
+ import { LightboxOverlay } from "./Gallery";
9
+ function PortfolioRender({ block }) {
10
+ const allItems = (block.items ?? []).filter((i) => i.imageUrl);
11
+ const [activeCat, setActiveCat] = useState(null);
12
+ const [open, setOpen] = useState(false);
13
+ const [index, setIndex] = useState(0);
14
+ const triggerRef = useRef(null);
15
+ const cats = block.showFilter ? [...new Set(allItems.map((i) => i.category).filter((c) => Boolean(c)))] : [];
16
+ const items = activeCat ? allItems.filter((i) => i.category === activeCat) : allItems;
17
+ if (allItems.length === 0) return null;
18
+ const lightboxItems = items.map((i) => ({ url: i.imageUrl, alt: i.title, caption: i.description ? `${i.title} \u2014 ${i.description}` : i.title }));
19
+ const close = () => {
20
+ setOpen(false);
21
+ triggerRef.current?.focus({ preventScroll: true });
22
+ };
23
+ return /* @__PURE__ */ jsxs(VStack, { gap: 4, as: "section", className: "xicms-portfolio", children: [
24
+ (block.heading || block.intro) && /* @__PURE__ */ jsxs(VStack, { gap: 1, hAlign: "center", style: { textAlign: "center" }, children: [
25
+ block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, "data-xicms-edit": "heading", children: block.heading }),
26
+ block.intro && /* @__PURE__ */ jsx(Text, { type: "large", color: "secondary", "data-xicms-edit": "intro", children: block.intro })
27
+ ] }),
28
+ cats.length > 0 && /* @__PURE__ */ jsxs("div", { className: "xicms-gallery__filter", role: "group", "aria-label": "Filter op categorie", style: { justifyContent: "center", marginBottom: 0 }, children: [
29
+ /* @__PURE__ */ jsx("button", { type: "button", className: "xicms-gallery__filterbtn", "data-active": activeCat === null ? "1" : "0", onClick: () => setActiveCat(null), children: "Alles" }),
30
+ cats.map((c) => /* @__PURE__ */ jsx("button", { type: "button", className: "xicms-gallery__filterbtn", "data-active": activeCat === c ? "1" : "0", onClick: () => setActiveCat(c), children: c }, c))
31
+ ] }),
32
+ /* @__PURE__ */ jsx(Grid, { columns: { minWidth: 240, max: block.columns }, gap: 3, children: items.map((it, idx) => {
33
+ const media = /* @__PURE__ */ jsx(
34
+ Img,
35
+ {
36
+ src: it.imageUrl,
37
+ alt: it.title,
38
+ width: 720,
39
+ height: 540,
40
+ sizes: "(max-width: 720px) 100vw, 33vw",
41
+ style: { width: "100%", aspectRatio: "4 / 3", objectFit: "cover", display: "block" }
42
+ }
43
+ );
44
+ const body = /* @__PURE__ */ jsxs(Fragment, { children: [
45
+ media,
46
+ /* @__PURE__ */ jsxs("div", { className: "xicms-portfolio__body", children: [
47
+ it.category && /* @__PURE__ */ jsx("span", { className: "xicms-portfolio__cat", children: it.category }),
48
+ /* @__PURE__ */ jsx("strong", { className: "xicms-portfolio__title", children: it.title }),
49
+ it.description && /* @__PURE__ */ jsx("span", { className: "xicms-portfolio__desc", children: it.description })
50
+ ] })
51
+ ] });
52
+ if (it.href) {
53
+ return /* @__PURE__ */ jsx("a", { className: "xicms-portfolio__item", href: it.href, children: body }, idx);
54
+ }
55
+ if (block.lightbox) {
56
+ return /* @__PURE__ */ jsx(
57
+ "button",
58
+ {
59
+ type: "button",
60
+ className: "xicms-portfolio__item",
61
+ onClick: (e) => {
62
+ triggerRef.current = e.currentTarget;
63
+ setIndex(idx);
64
+ setOpen(true);
65
+ },
66
+ "aria-label": `${it.title} vergroten`,
67
+ children: body
68
+ },
69
+ idx
70
+ );
71
+ }
72
+ return /* @__PURE__ */ jsx("div", { className: "xicms-portfolio__item", children: body }, idx);
73
+ }) }),
74
+ block.lightbox && open && /* @__PURE__ */ jsx(LightboxOverlay, { items: lightboxItems, index, onIndex: setIndex, onClose: close })
75
+ ] });
76
+ }
77
+ const portfolioBlock = defineBlock({
78
+ type: "portfolio",
79
+ schema: PortfolioBlockSchema,
80
+ Render: PortfolioRender,
81
+ label: "Portfolio / projecten",
82
+ icon: "\u{1F5C2}\uFE0F",
83
+ defaults: () => ({
84
+ heading: "Ons werk",
85
+ columns: 3,
86
+ items: [{ imageUrl: "", title: "Project", category: "" }],
87
+ showFilter: true,
88
+ lightbox: true
89
+ })
90
+ });
91
+ export {
92
+ portfolioBlock
93
+ };
94
+ //# sourceMappingURL=Portfolio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Portfolio.tsx"],"sourcesContent":["\"use client\";\n\nimport { useRef, useState } from \"react\";\nimport type { z } from \"zod\";\nimport { PortfolioBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\nimport { VStack, Grid, Heading, Text } from \"../ui\";\nimport { Img } from \"../../media/ImageContext\";\nimport { LightboxOverlay } from \"./Gallery\";\n\ntype Portfolio = z.infer<typeof PortfolioBlockSchema>;\n\n/** Projecten/cases-grid met categorie-filter en lightbox (hergebruikt de galerij-lightbox). */\nfunction PortfolioRender({ block }: BlockRenderProps<Portfolio>) {\n const allItems = (block.items ?? []).filter((i) => i.imageUrl);\n const [activeCat, setActiveCat] = useState<string | null>(null);\n const [open, setOpen] = useState(false);\n const [index, setIndex] = useState(0);\n const triggerRef = useRef<HTMLButtonElement | null>(null);\n\n const cats = block.showFilter ? [...new Set(allItems.map((i) => i.category).filter((c): c is string => Boolean(c)))] : [];\n const items = activeCat ? allItems.filter((i) => i.category === activeCat) : allItems;\n if (allItems.length === 0) return null;\n\n const lightboxItems = items.map((i) => ({ url: i.imageUrl, alt: i.title, caption: i.description ? `${i.title} — ${i.description}` : i.title }));\n const close = () => {\n setOpen(false);\n triggerRef.current?.focus({ preventScroll: true });\n };\n\n return (\n <VStack gap={4} as=\"section\" className=\"xicms-portfolio\">\n {(block.heading || block.intro) && (\n <VStack gap={1} hAlign=\"center\" style={{ textAlign: \"center\" }}>\n {block.heading && <Heading level={2} data-xicms-edit=\"heading\">{block.heading}</Heading>}\n {block.intro && <Text type=\"large\" color=\"secondary\" data-xicms-edit=\"intro\">{block.intro}</Text>}\n </VStack>\n )}\n {cats.length > 0 && (\n <div className=\"xicms-gallery__filter\" role=\"group\" aria-label=\"Filter op categorie\" style={{ justifyContent: \"center\", marginBottom: 0 }}>\n <button type=\"button\" className=\"xicms-gallery__filterbtn\" data-active={activeCat === null ? \"1\" : \"0\"} onClick={() => setActiveCat(null)}>\n Alles\n </button>\n {cats.map((c) => (\n <button key={c} type=\"button\" className=\"xicms-gallery__filterbtn\" data-active={activeCat === c ? \"1\" : \"0\"} onClick={() => setActiveCat(c)}>\n {c}\n </button>\n ))}\n </div>\n )}\n <Grid columns={{ minWidth: 240, max: block.columns }} gap={3}>\n {items.map((it, idx) => {\n const media = (\n <Img\n src={it.imageUrl}\n alt={it.title}\n width={720}\n height={540}\n sizes=\"(max-width: 720px) 100vw, 33vw\"\n style={{ width: \"100%\", aspectRatio: \"4 / 3\", objectFit: \"cover\", display: \"block\" }}\n />\n );\n const body = (\n <>\n {media}\n <div className=\"xicms-portfolio__body\">\n {it.category && <span className=\"xicms-portfolio__cat\">{it.category}</span>}\n <strong className=\"xicms-portfolio__title\">{it.title}</strong>\n {it.description && <span className=\"xicms-portfolio__desc\">{it.description}</span>}\n </div>\n </>\n );\n if (it.href) {\n return (\n <a key={idx} className=\"xicms-portfolio__item\" href={it.href}>\n {body}\n </a>\n );\n }\n if (block.lightbox) {\n return (\n <button\n key={idx}\n type=\"button\"\n className=\"xicms-portfolio__item\"\n onClick={(e) => { triggerRef.current = e.currentTarget; setIndex(idx); setOpen(true); }}\n aria-label={`${it.title} vergroten`}\n >\n {body}\n </button>\n );\n }\n return (\n <div key={idx} className=\"xicms-portfolio__item\">\n {body}\n </div>\n );\n })}\n </Grid>\n {block.lightbox && open && (\n <LightboxOverlay items={lightboxItems} index={index} onIndex={setIndex} onClose={close} />\n )}\n </VStack>\n );\n}\n\nexport const portfolioBlock = defineBlock({\n type: \"portfolio\",\n schema: PortfolioBlockSchema,\n Render: PortfolioRender,\n label: \"Portfolio / projecten\",\n icon: \"🗂️\",\n defaults: () => ({\n heading: \"Ons werk\",\n columns: 3,\n items: [{ imageUrl: \"\", title: \"Project\", category: \"\" }],\n showFilter: true,\n lightbox: true,\n }),\n});\n"],"mappings":"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","names":[]}
@@ -0,0 +1,6 @@
1
+ import type { z } from "zod";
2
+ import { PricingBlockSchema } from "../../schema/blocks";
3
+ type Pricing = z.infer<typeof PricingBlockSchema>;
4
+ export declare function pricingJsonLd(items: Pricing["items"], currency?: string): Record<string, unknown>;
5
+ export declare const pricingBlock: import("..").BlockDefinition<z.ZodTypeAny>;
6
+ export {};
@@ -0,0 +1,77 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { PricingBlockSchema } from "../../schema/blocks";
4
+ import { defineBlock } from "../registry";
5
+ import { VStack, Grid, Card, Heading, Text, Btn } from "../ui";
6
+ function pricingJsonLd(items, currency = "EUR") {
7
+ return {
8
+ "@context": "https://schema.org",
9
+ "@type": "ItemList",
10
+ itemListElement: items.filter((it) => it.label).map((it, i) => ({
11
+ "@type": "ListItem",
12
+ position: i + 1,
13
+ item: {
14
+ "@type": "Product",
15
+ name: it.label,
16
+ ...it.detail ? { description: it.detail } : {},
17
+ offers: { "@type": "Offer", price: it.price, priceCurrency: currency }
18
+ }
19
+ }))
20
+ };
21
+ }
22
+ function PricingRender({ block }) {
23
+ const items = block.items ?? [];
24
+ return /* @__PURE__ */ jsxs(VStack, { gap: 4, as: "section", className: "xicms-pricing", children: [
25
+ block.heading && /* @__PURE__ */ jsx(Heading, { level: 2, justify: "center", "data-xicms-edit": "heading", style: { textAlign: "center" }, children: block.heading }),
26
+ /* @__PURE__ */ jsx(Grid, { columns: { minWidth: 240, max: 4 }, gap: 4, children: items.map((it, i) => /* @__PURE__ */ jsx(
27
+ Card,
28
+ {
29
+ padding: 5,
30
+ height: "100%",
31
+ className: `xicms-pricing__card${it.highlighted ? " xicms-pricing__card--highlighted" : ""}`,
32
+ style: it.highlighted ? { outline: "2px solid var(--color-accent)", outlineOffset: -2 } : void 0,
33
+ children: /* @__PURE__ */ jsxs(VStack, { gap: 2, style: { height: "100%" }, children: [
34
+ /* @__PURE__ */ jsx(Text, { type: "label", color: "secondary", className: "xicms-pricing__label", "data-xicms-edit": `items.${i}.label`, style: { textTransform: "uppercase", letterSpacing: "0.05em" }, children: it.label }),
35
+ /* @__PURE__ */ jsxs(VStack, { gap: 0, children: [
36
+ /* @__PURE__ */ jsx(Heading, { level: 3, className: "xicms-pricing__price", "data-xicms-edit": `items.${i}.price`, style: { fontSize: "clamp(1.75rem, 4vw, 2.25rem)", lineHeight: 1.1, fontWeight: 700 }, children: it.price }),
37
+ it.billingPeriod && /* @__PURE__ */ jsx(Text, { type: "supporting", color: "secondary", children: it.billingPeriod })
38
+ ] }),
39
+ it.detail && /* @__PURE__ */ jsx(Text, { color: "secondary", children: it.detail }),
40
+ it.features && it.features.length > 0 && /* @__PURE__ */ jsx(VStack, { gap: 1, as: "ul", style: { listStyle: "none", margin: 0, padding: 0, flex: 1 }, children: it.features.map((f, j) => (
41
+ // Echte <li> binnen de <ul> (geldige HTML; screenreaders kondigen de lijst aan).
42
+ /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs(Text, { display: "block", children: [
43
+ "\u2713 ",
44
+ f
45
+ ] }) }, j)
46
+ )) }),
47
+ it.ctaLabel && /* @__PURE__ */ jsx(Btn, { label: it.ctaLabel, href: it.ctaHref ?? "#", variant: it.highlighted ? "primary" : "outline" })
48
+ ] })
49
+ },
50
+ i
51
+ )) }),
52
+ block.note && /* @__PURE__ */ jsx(Text, { color: "secondary", justify: "center", style: { textAlign: "center" }, children: block.note }),
53
+ block.jsonLd && /* @__PURE__ */ jsx(
54
+ "script",
55
+ {
56
+ type: "application/ld+json",
57
+ dangerouslySetInnerHTML: { __html: JSON.stringify(pricingJsonLd(items, block.currency)) }
58
+ }
59
+ )
60
+ ] });
61
+ }
62
+ const pricingBlock = defineBlock({
63
+ type: "pricing",
64
+ schema: PricingBlockSchema,
65
+ Render: PricingRender,
66
+ label: "Prijzen",
67
+ icon: "\u{1F4B6}",
68
+ defaults: () => ({
69
+ heading: "Prijzen",
70
+ items: [{ label: "Pakket", price: "\u20AC 00", billingPeriod: "/maand", features: [], highlighted: false }]
71
+ })
72
+ });
73
+ export {
74
+ pricingBlock,
75
+ pricingJsonLd
76
+ };
77
+ //# sourceMappingURL=Pricing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Pricing.tsx"],"sourcesContent":["\"use client\";\n\nimport type { z } from \"zod\";\nimport { PricingBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\nimport { VStack, Grid, Card, Heading, Text, Btn } from \"../ui\";\n\ntype Pricing = z.infer<typeof PricingBlockSchema>;\n\nexport function pricingJsonLd(items: Pricing[\"items\"], currency = \"EUR\"): Record<string, unknown> {\n return {\n \"@context\": \"https://schema.org\",\n \"@type\": \"ItemList\",\n itemListElement: items\n .filter((it) => it.label)\n .map((it, i) => ({\n \"@type\": \"ListItem\",\n position: i + 1,\n item: {\n \"@type\": \"Product\",\n name: it.label,\n ...(it.detail ? { description: it.detail } : {}),\n offers: { \"@type\": \"Offer\", price: it.price, priceCurrency: currency },\n },\n })),\n };\n}\n\n/** Prijzen als kaarten met optionele features, uitgelichte tier en per-tier knop (Astryx). */\nfunction PricingRender({ block }: BlockRenderProps<Pricing>) {\n const items = block.items ?? [];\n return (\n <VStack gap={4} as=\"section\" className=\"xicms-pricing\">\n {block.heading && (\n <Heading level={2} justify=\"center\" data-xicms-edit=\"heading\" style={{ textAlign: \"center\" }}>{block.heading}</Heading>\n )}\n <Grid columns={{ minWidth: 240, max: 4 }} gap={4}>\n {items.map((it, i) => (\n <Card\n key={i}\n padding={5}\n height=\"100%\"\n className={`xicms-pricing__card${it.highlighted ? \" xicms-pricing__card--highlighted\" : \"\"}`}\n style={it.highlighted ? { outline: \"2px solid var(--color-accent)\", outlineOffset: -2 } : undefined}\n >\n <VStack gap={2} style={{ height: \"100%\" }}>\n <Text type=\"label\" color=\"secondary\" className=\"xicms-pricing__label\" data-xicms-edit={`items.${i}.label`} style={{ textTransform: \"uppercase\", letterSpacing: \"0.05em\" }}>\n {it.label}\n </Text>\n <VStack gap={0}>\n <Heading level={3} className=\"xicms-pricing__price\" data-xicms-edit={`items.${i}.price`} style={{ fontSize: \"clamp(1.75rem, 4vw, 2.25rem)\", lineHeight: 1.1, fontWeight: 700 }}>\n {it.price}\n </Heading>\n {it.billingPeriod && <Text type=\"supporting\" color=\"secondary\">{it.billingPeriod}</Text>}\n </VStack>\n {it.detail && <Text color=\"secondary\">{it.detail}</Text>}\n {it.features && it.features.length > 0 && (\n <VStack gap={1} as=\"ul\" style={{ listStyle: \"none\", margin: 0, padding: 0, flex: 1 }}>\n {it.features.map((f, j) => (\n // Echte <li> binnen de <ul> (geldige HTML; screenreaders kondigen de lijst aan).\n <li key={j}>\n <Text display=\"block\">✓ {f}</Text>\n </li>\n ))}\n </VStack>\n )}\n {it.ctaLabel && (\n <Btn label={it.ctaLabel} href={it.ctaHref ?? \"#\"} variant={it.highlighted ? \"primary\" : \"outline\"} />\n )}\n </VStack>\n </Card>\n ))}\n </Grid>\n {block.note && <Text color=\"secondary\" justify=\"center\" style={{ textAlign: \"center\" }}>{block.note}</Text>}\n {block.jsonLd && (\n <script\n type=\"application/ld+json\"\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{ __html: JSON.stringify(pricingJsonLd(items, block.currency)) }}\n />\n )}\n </VStack>\n );\n}\n\nexport const pricingBlock = defineBlock({\n type: \"pricing\",\n schema: PricingBlockSchema,\n Render: PricingRender,\n label: \"Prijzen\",\n icon: \"💶\",\n defaults: () => ({\n heading: \"Prijzen\",\n items: [{ label: \"Pakket\", price: \"€ 00\", billingPeriod: \"/maand\", features: [], highlighted: false }],\n }),\n});\n"],"mappings":"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","names":[]}
@@ -0,0 +1,2 @@
1
+ import type { z } from "zod";
2
+ export declare const richTextBlock: import("..").BlockDefinition<z.ZodTypeAny>;
@@ -0,0 +1,18 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { RichTextBlockSchema } from "../../schema/blocks";
3
+ import { defineBlock } from "../registry";
4
+ function RichTextRender({ block }) {
5
+ return /* @__PURE__ */ jsx("div", { className: "xicms-richtext", dangerouslySetInnerHTML: { __html: block.html } });
6
+ }
7
+ const richTextBlock = defineBlock({
8
+ type: "richText",
9
+ schema: RichTextBlockSchema,
10
+ Render: RichTextRender,
11
+ label: "Tekst",
12
+ icon: "\xB6",
13
+ defaults: () => ({ html: "<p></p>" })
14
+ });
15
+ export {
16
+ richTextBlock
17
+ };
18
+ //# sourceMappingURL=RichTextBlock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/RichTextBlock.tsx"],"sourcesContent":["import type { z } from \"zod\";\nimport { RichTextBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\n\ntype RichText = z.infer<typeof RichTextBlockSchema>;\n\nfunction RichTextRender({ block }: BlockRenderProps<RichText>) {\n // `html` is bij opslaan server-side gesanitized (server/sanitize.ts), dus veilig te renderen.\n return <div className=\"xicms-richtext\" dangerouslySetInnerHTML={{ __html: block.html }} />;\n}\n\nexport const richTextBlock = defineBlock({\n type: \"richText\",\n schema: RichTextBlockSchema,\n Render: RichTextRender,\n label: \"Tekst\",\n icon: \"¶\",\n defaults: () => ({ html: \"<p></p>\" }),\n});\n"],"mappings":"AAQS;AAPT,SAAS,2BAA2B;AACpC,SAAS,mBAA0C;AAInD,SAAS,eAAe,EAAE,MAAM,GAA+B;AAE7D,SAAO,oBAAC,SAAI,WAAU,kBAAiB,yBAAyB,EAAE,QAAQ,MAAM,KAAK,GAAG;AAC1F;AAEO,MAAM,gBAAgB,YAAY;AAAA,EACvC,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,MAAM;AAAA,EACN,UAAU,OAAO,EAAE,MAAM,UAAU;AACrC,CAAC;","names":[]}
@@ -0,0 +1,2 @@
1
+ import type { z } from "zod";
2
+ export declare const searchBlock: import("..").BlockDefinition<z.ZodTypeAny>;
@@ -0,0 +1,99 @@
1
+ "use client";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useMemo, useState } from "react";
4
+ import { collection, getDocs, query, where } from "firebase/firestore";
5
+ import { SearchBlockSchema } from "../../schema/blocks";
6
+ import { defineBlock } from "../registry";
7
+ import { getDb } from "../../firebase/client";
8
+ import { TextInput } from "@astryxdesign/core/TextInput";
9
+ import { rankResults, highlightParts } from "./lib/searchRank";
10
+ function blocksToText(blocks) {
11
+ if (!Array.isArray(blocks)) return "";
12
+ const parts = [];
13
+ for (const b of blocks) {
14
+ if (b && typeof b === "object") {
15
+ for (const v of Object.values(b)) {
16
+ if (typeof v === "string") parts.push(v);
17
+ }
18
+ }
19
+ }
20
+ return parts.join(" ").replace(/<[^>]*>/g, " ");
21
+ }
22
+ function SearchRender({ block, siteId }) {
23
+ const [entries, setEntries] = useState([]);
24
+ const [q, setQ] = useState("");
25
+ useEffect(() => {
26
+ const db = getDb();
27
+ if (!db) return;
28
+ let cancelled = false;
29
+ (async () => {
30
+ const out = [];
31
+ try {
32
+ const pagesSnap = await getDocs(
33
+ query(collection(db, `sites/${siteId}/pages`), where("status", "==", "published"))
34
+ );
35
+ pagesSnap.forEach((d) => {
36
+ const data = d.data();
37
+ out.push({
38
+ title: String(data.title ?? ""),
39
+ path: String(data.path ?? "/"),
40
+ text: blocksToText(data.blocks)
41
+ });
42
+ });
43
+ if (block.includeNews) {
44
+ const newsSnap = await getDocs(
45
+ query(collection(db, `sites/${siteId}/news`), where("published", "==", true))
46
+ );
47
+ newsSnap.forEach((d) => {
48
+ const data = d.data();
49
+ out.push({
50
+ title: String(data.title ?? ""),
51
+ path: `/nieuws/${String(data.slug ?? d.id)}`,
52
+ text: String(data.excerpt ?? "") + " " + String(data.body ?? "").replace(/<[^>]*>/g, " ")
53
+ });
54
+ });
55
+ }
56
+ } catch {
57
+ }
58
+ if (!cancelled) setEntries(out);
59
+ })();
60
+ return () => {
61
+ cancelled = true;
62
+ };
63
+ }, [siteId, block.includeNews]);
64
+ const [debouncedQ, setDebouncedQ] = useState("");
65
+ useEffect(() => {
66
+ const t = setTimeout(() => setDebouncedQ(q), 250);
67
+ return () => clearTimeout(t);
68
+ }, [q]);
69
+ const results = useMemo(() => rankResults(debouncedQ, entries), [entries, debouncedQ]);
70
+ const mark = (text) => highlightParts(text, debouncedQ).map((p, i) => p.hit ? /* @__PURE__ */ jsx("mark", { children: p.text }, i) : /* @__PURE__ */ jsx("span", { children: p.text }, i));
71
+ return /* @__PURE__ */ jsxs("div", { className: "xicms-search", children: [
72
+ /* @__PURE__ */ jsx(
73
+ TextInput,
74
+ {
75
+ label: block.placeholder,
76
+ isLabelHidden: true,
77
+ placeholder: block.placeholder,
78
+ value: q,
79
+ onChange: setQ
80
+ }
81
+ ),
82
+ debouncedQ.trim() && /* @__PURE__ */ jsx("ul", { className: "xicms-search__results", children: results.length === 0 ? /* @__PURE__ */ jsx("li", { className: "xicms-search__empty", children: "Niets gevonden." }) : results.map((r, i) => /* @__PURE__ */ jsxs("li", { className: "xicms-search__result", children: [
83
+ /* @__PURE__ */ jsx("a", { href: r.path, children: mark(r.title || r.path) }),
84
+ r.snippet && /* @__PURE__ */ jsx("p", { className: "xicms-search__snippet", children: mark(r.snippet) })
85
+ ] }, i)) })
86
+ ] });
87
+ }
88
+ const searchBlock = defineBlock({
89
+ type: "search",
90
+ schema: SearchBlockSchema,
91
+ Render: SearchRender,
92
+ label: "Zoeken",
93
+ icon: "\u{1F50D}",
94
+ defaults: () => ({ placeholder: "Zoeken\u2026", includeNews: true })
95
+ });
96
+ export {
97
+ searchBlock
98
+ };
99
+ //# sourceMappingURL=Search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../../../src/blocks/builtins/Search.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useMemo, useState } from \"react\";\nimport { collection, getDocs, query, where } from \"firebase/firestore\";\nimport type { z } from \"zod\";\nimport { SearchBlockSchema } from \"../../schema/blocks\";\nimport { defineBlock, type BlockRenderProps } from \"../registry\";\nimport { getDb } from \"../../firebase/client\";\nimport { TextInput } from \"@astryxdesign/core/TextInput\";\nimport { rankResults, highlightParts } from \"./lib/searchRank\";\n\ntype SearchBlock = z.infer<typeof SearchBlockSchema>;\n\ninterface Entry {\n title: string;\n path: string;\n text: string;\n}\n\n/** Vlakt block-content uit tot doorzoekbare tekst (titels, rich text, faq-vragen, …). */\nfunction blocksToText(blocks: unknown): string {\n if (!Array.isArray(blocks)) return \"\";\n const parts: string[] = [];\n for (const b of blocks) {\n if (b && typeof b === \"object\") {\n for (const v of Object.values(b as Record<string, unknown>)) {\n if (typeof v === \"string\") parts.push(v);\n }\n }\n }\n return parts.join(\" \").replace(/<[^>]*>/g, \" \");\n}\n\n/** Site-zoek — leest gepubliceerde pagina's (en optioneel nieuws) en filtert client-side. */\nfunction SearchRender({ block, siteId }: BlockRenderProps<SearchBlock>) {\n const [entries, setEntries] = useState<Entry[]>([]);\n const [q, setQ] = useState(\"\");\n\n useEffect(() => {\n const db = getDb();\n if (!db) return;\n let cancelled = false;\n (async () => {\n const out: Entry[] = [];\n try {\n const pagesSnap = await getDocs(\n query(collection(db, `sites/${siteId}/pages`), where(\"status\", \"==\", \"published\")),\n );\n pagesSnap.forEach((d) => {\n const data = d.data() as Record<string, unknown>;\n out.push({\n title: String(data.title ?? \"\"),\n path: String(data.path ?? \"/\"),\n text: blocksToText(data.blocks),\n });\n });\n if (block.includeNews) {\n const newsSnap = await getDocs(\n query(collection(db, `sites/${siteId}/news`), where(\"published\", \"==\", true)),\n );\n newsSnap.forEach((d) => {\n const data = d.data() as Record<string, unknown>;\n out.push({\n title: String(data.title ?? \"\"),\n path: `/nieuws/${String(data.slug ?? d.id)}`,\n text: String(data.excerpt ?? \"\") + \" \" + String(data.body ?? \"\").replace(/<[^>]*>/g, \" \"),\n });\n });\n }\n } catch {\n /* stil: zonder leesrechten/Firebase blijft het zoekveld leeg */\n }\n if (!cancelled) setEntries(out);\n })();\n return () => {\n cancelled = true;\n };\n }, [siteId, block.includeNews]);\n\n // Debounce (250ms): niet bij elke toetsaanslag opnieuw ranken/renderen.\n const [debouncedQ, setDebouncedQ] = useState(\"\");\n useEffect(() => {\n const t = setTimeout(() => setDebouncedQ(q), 250);\n return () => clearTimeout(t);\n }, [q]);\n\n const results = useMemo(() => rankResults(debouncedQ, entries), [entries, debouncedQ]);\n\n const mark = (text: string) =>\n highlightParts(text, debouncedQ).map((p, i) => (p.hit ? <mark key={i}>{p.text}</mark> : <span key={i}>{p.text}</span>));\n\n return (\n <div className=\"xicms-search\">\n <TextInput\n label={block.placeholder}\n isLabelHidden\n placeholder={block.placeholder}\n value={q}\n onChange={setQ}\n />\n {debouncedQ.trim() && (\n <ul className=\"xicms-search__results\">\n {results.length === 0 ? (\n <li className=\"xicms-search__empty\">Niets gevonden.</li>\n ) : (\n results.map((r, i) => (\n <li key={i} className=\"xicms-search__result\">\n <a href={r.path}>{mark(r.title || r.path)}</a>\n {r.snippet && <p className=\"xicms-search__snippet\">{mark(r.snippet)}</p>}\n </li>\n ))\n )}\n </ul>\n )}\n </div>\n );\n}\n\nexport const searchBlock = defineBlock({\n type: \"search\",\n schema: SearchBlockSchema,\n Render: SearchRender,\n label: \"Zoeken\",\n icon: \"🔍\",\n defaults: () => ({ placeholder: \"Zoeken…\", includeNews: true }),\n});\n"],"mappings":"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","names":[]}
@@ -0,0 +1,5 @@
1
+ import type { z } from "zod";
2
+ export declare const featureBlock: import("..").BlockDefinition<z.ZodTypeAny>;
3
+ export declare const countersBlock: import("..").BlockDefinition<z.ZodTypeAny>;
4
+ export declare const logosBlock: import("..").BlockDefinition<z.ZodTypeAny>;
5
+ export declare const timelineBlock: import("..").BlockDefinition<z.ZodTypeAny>;