@morphemecms/cms 0.1.0 → 0.2.0-next-20261104150211

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 (908) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/LICENSE +21 -21
  3. package/README.md +51 -51
  4. package/astro.mjs +162 -162
  5. package/bin/morpheme.mjs +38 -38
  6. package/client.d.ts +10 -10
  7. package/defaults/blockTexts.ts +33 -33
  8. package/defaults/collections.ts +774 -774
  9. package/defaults/colors.ts +125 -125
  10. package/defaults/company.ts +20 -20
  11. package/defaults/editor.ts +178 -178
  12. package/defaults/internalLinks.ts +30 -30
  13. package/defaults/opens.ts +18 -18
  14. package/defaults/popup.tsx +93 -93
  15. package/defaults/privacy.ts +79 -79
  16. package/defaults/rules.ts +450 -450
  17. package/defaults/schema.ts +16 -16
  18. package/defaults/sitedata.ts +129 -129
  19. package/defaults/standard.ts +106 -106
  20. package/defaults/standardPages.ts +87 -87
  21. package/defaults/texts.ts +481 -481
  22. package/demo/README.md +26 -26
  23. package/demo/src/content/blog/build-a-page-from-blocks.md +19 -19
  24. package/demo/src/content/blog/colors-everyone-can-read.md +19 -19
  25. package/demo/src/content/blog/edit-your-website-from-your-phone.md +21 -21
  26. package/demo/src/content/blog/every-save-is-a-version.md +21 -21
  27. package/demo/src/content/blog/schedule-a-post.md +17 -17
  28. package/demo/src/content/blog/secure-from-day-one.md +17 -17
  29. package/demo/src/content/blog/seo-without-the-guesswork.md +23 -23
  30. package/demo/src/content/blog/switch-themes-without-losing-anything.md +23 -23
  31. package/demo/src/content/blog/the-app-store.md +21 -21
  32. package/demo/src/content/pages/about.md +22 -22
  33. package/demo/src/content/pages/app-store.md +30 -30
  34. package/demo/src/content/pages/blocks.md +98 -98
  35. package/demo/src/content/pages/blog-page.md +11 -11
  36. package/demo/src/content/pages/contact.md +16 -16
  37. package/demo/src/content/pages/get-started.md +20 -20
  38. package/demo/src/content/pages/home.md +26 -26
  39. package/demo/src/content/pages/page-not-found.md +11 -11
  40. package/demo/src/content/pages/privacy-policy.md +24 -24
  41. package/demo/src/data/blocks.json +25 -25
  42. package/demo/src/data/booking.json +6 -6
  43. package/demo/src/data/categories/apps.json +6 -6
  44. package/demo/src/data/categories/design.json +6 -6
  45. package/demo/src/data/categories/editing.json +6 -6
  46. package/demo/src/data/categories/security.json +6 -6
  47. package/demo/src/data/categories/seo.json +6 -6
  48. package/demo/src/data/colors.json +75 -75
  49. package/demo/src/data/contact.json +8 -8
  50. package/demo/src/data/cookies.json +21 -21
  51. package/demo/src/data/footer.json +27 -27
  52. package/demo/src/data/menu.json +35 -35
  53. package/demo/src/data/mobile-menu.json +25 -25
  54. package/demo/src/data/popups/booking-bar.json +13 -13
  55. package/demo/src/data/popups/try-the-editor.json +16 -16
  56. package/demo/src/data/standard-pages.json +8 -8
  57. package/demo/src/data/testimonials/sample-bakery.json +10 -10
  58. package/demo/src/data/testimonials/sample-clinic.json +10 -10
  59. package/demo/src/data/testimonials/sample-studio.json +10 -10
  60. package/demo/src/site/colors.ts +11 -11
  61. package/demo/src/site/config.ts +19 -19
  62. package/icons/lucide/LICENSE +43 -43
  63. package/icons/lucide/address-book.svg +1 -1
  64. package/icons/lucide/app-window.svg +1 -1
  65. package/icons/lucide/arrow-counter-clockwise.svg +1 -1
  66. package/icons/lucide/arrow-down.svg +1 -1
  67. package/icons/lucide/arrow-left.svg +1 -1
  68. package/icons/lucide/arrow-right.svg +1 -1
  69. package/icons/lucide/arrow-square-out.svg +1 -1
  70. package/icons/lucide/arrow-u-up-left.svg +1 -1
  71. package/icons/lucide/arrow-u-up-right.svg +1 -1
  72. package/icons/lucide/arrow-up-right.svg +1 -1
  73. package/icons/lucide/arrow-up.svg +1 -1
  74. package/icons/lucide/arrows-down-up.svg +1 -1
  75. package/icons/lucide/arrows-in-line-horizontal.svg +1 -1
  76. package/icons/lucide/arrows-out-line-horizontal.svg +1 -1
  77. package/icons/lucide/article.svg +1 -1
  78. package/icons/lucide/bank.svg +1 -1
  79. package/icons/lucide/bell.svg +1 -1
  80. package/icons/lucide/bicycle.svg +1 -1
  81. package/icons/lucide/binoculars.svg +1 -1
  82. package/icons/lucide/book-open-text.svg +1 -1
  83. package/icons/lucide/book-open.svg +1 -1
  84. package/icons/lucide/browser.svg +1 -1
  85. package/icons/lucide/buildings.svg +1 -1
  86. package/icons/lucide/bus.svg +1 -1
  87. package/icons/lucide/calendar-blank.svg +1 -1
  88. package/icons/lucide/calendar-check.svg +1 -1
  89. package/icons/lucide/car.svg +1 -1
  90. package/icons/lucide/cards.svg +1 -1
  91. package/icons/lucide/caret-down.svg +1 -1
  92. package/icons/lucide/caret-left.svg +1 -1
  93. package/icons/lucide/caret-right.svg +1 -1
  94. package/icons/lucide/caret-up.svg +1 -1
  95. package/icons/lucide/certificate.svg +1 -1
  96. package/icons/lucide/chart-line-up.svg +1 -1
  97. package/icons/lucide/chats.svg +1 -1
  98. package/icons/lucide/check-circle.svg +1 -1
  99. package/icons/lucide/check.svg +1 -1
  100. package/icons/lucide/circle-half.svg +1 -1
  101. package/icons/lucide/circle.svg +1 -1
  102. package/icons/lucide/clock-counter-clockwise.svg +1 -1
  103. package/icons/lucide/clock.svg +1 -1
  104. package/icons/lucide/code.svg +1 -1
  105. package/icons/lucide/coffee.svg +1 -1
  106. package/icons/lucide/columns.svg +1 -1
  107. package/icons/lucide/cookie.svg +1 -1
  108. package/icons/lucide/copy.svg +1 -1
  109. package/icons/lucide/credit-card.svg +1 -1
  110. package/icons/lucide/currency-circle-dollar.svg +1 -1
  111. package/icons/lucide/cursor-click.svg +1 -1
  112. package/icons/lucide/database.svg +1 -1
  113. package/icons/lucide/desktop.svg +1 -1
  114. package/icons/lucide/device-mobile.svg +1 -1
  115. package/icons/lucide/door-open.svg +1 -1
  116. package/icons/lucide/download-simple.svg +1 -1
  117. package/icons/lucide/envelope-simple.svg +1 -1
  118. package/icons/lucide/eye-slash.svg +1 -1
  119. package/icons/lucide/eye.svg +1 -1
  120. package/icons/lucide/file-pdf.svg +1 -1
  121. package/icons/lucide/file-text.svg +1 -1
  122. package/icons/lucide/file-video.svg +1 -1
  123. package/icons/lucide/file-zip.svg +1 -1
  124. package/icons/lucide/flower-lotus.svg +1 -1
  125. package/icons/lucide/folder-simple.svg +1 -1
  126. package/icons/lucide/funnel.svg +1 -1
  127. package/icons/lucide/gauge.svg +1 -1
  128. package/icons/lucide/gear.svg +1 -1
  129. package/icons/lucide/github-logo.svg +1 -1
  130. package/icons/lucide/globe.svg +1 -1
  131. package/icons/lucide/google-logo.svg +1 -1
  132. package/icons/lucide/graduation-cap.svg +1 -1
  133. package/icons/lucide/hammer.svg +1 -1
  134. package/icons/lucide/hand-heart.svg +1 -1
  135. package/icons/lucide/handshake.svg +1 -1
  136. package/icons/lucide/hard-drives.svg +1 -1
  137. package/icons/lucide/heart.svg +1 -1
  138. package/icons/lucide/house.svg +1 -1
  139. package/icons/lucide/image-square.svg +1 -1
  140. package/icons/lucide/image.svg +1 -1
  141. package/icons/lucide/info.svg +1 -1
  142. package/icons/lucide/keyboard.svg +1 -1
  143. package/icons/lucide/leaf.svg +1 -1
  144. package/icons/lucide/lifebuoy.svg +1 -1
  145. package/icons/lucide/lightbulb.svg +1 -1
  146. package/icons/lucide/link-break.svg +1 -1
  147. package/icons/lucide/link-simple.svg +1 -1
  148. package/icons/lucide/list-bullets.svg +1 -1
  149. package/icons/lucide/list-checks.svg +1 -1
  150. package/icons/lucide/list-numbers.svg +1 -1
  151. package/icons/lucide/list.svg +1 -1
  152. package/icons/lucide/lock-simple-open.svg +1 -1
  153. package/icons/lucide/lock-simple.svg +1 -1
  154. package/icons/lucide/magnifying-glass.svg +1 -1
  155. package/icons/lucide/map-pin.svg +1 -1
  156. package/icons/lucide/map-trifold.svg +1 -1
  157. package/icons/lucide/medal.svg +1 -1
  158. package/icons/lucide/megaphone.svg +1 -1
  159. package/icons/lucide/minus.svg +1 -1
  160. package/icons/lucide/moon.svg +1 -1
  161. package/icons/lucide/newspaper.svg +1 -1
  162. package/icons/lucide/pack.json +23 -23
  163. package/icons/lucide/paint-brush-broad.svg +1 -1
  164. package/icons/lucide/palette.svg +1 -1
  165. package/icons/lucide/paper-plane-tilt.svg +1 -1
  166. package/icons/lucide/pencil-simple.svg +1 -1
  167. package/icons/lucide/phone.svg +1 -1
  168. package/icons/lucide/play-fill.svg +1 -1
  169. package/icons/lucide/plus.svg +1 -1
  170. package/icons/lucide/prohibit.svg +1 -1
  171. package/icons/lucide/puzzle-piece.svg +1 -1
  172. package/icons/lucide/question.svg +1 -1
  173. package/icons/lucide/quotes.svg +1 -1
  174. package/icons/lucide/rows.svg +1 -1
  175. package/icons/lucide/ruler.svg +1 -1
  176. package/icons/lucide/scan.svg +1 -1
  177. package/icons/lucide/shapes.svg +1 -1
  178. package/icons/lucide/share-network.svg +1 -1
  179. package/icons/lucide/shield-check.svg +1 -1
  180. package/icons/lucide/sidebar-simple.svg +1 -1
  181. package/icons/lucide/sign-out.svg +1 -1
  182. package/icons/lucide/signpost.svg +1 -1
  183. package/icons/lucide/sliders-horizontal.svg +1 -1
  184. package/icons/lucide/smiley.svg +1 -1
  185. package/icons/lucide/sparkle.svg +1 -1
  186. package/icons/lucide/square-half-bottom.svg +1 -1
  187. package/icons/lucide/square.svg +1 -1
  188. package/icons/lucide/squares-four.svg +1 -1
  189. package/icons/lucide/sticker.svg +1 -1
  190. package/icons/lucide/storefront.svg +1 -1
  191. package/icons/lucide/sun.svg +1 -1
  192. package/icons/lucide/swatches.svg +1 -1
  193. package/icons/lucide/tag.svg +1 -1
  194. package/icons/lucide/text-aa.svg +1 -1
  195. package/icons/lucide/text-align-left.svg +1 -1
  196. package/icons/lucide/text-b.svg +1 -1
  197. package/icons/lucide/text-h-one.svg +1 -1
  198. package/icons/lucide/text-h-three.svg +1 -1
  199. package/icons/lucide/text-h-two.svg +1 -1
  200. package/icons/lucide/text-italic.svg +1 -1
  201. package/icons/lucide/text-t.svg +1 -1
  202. package/icons/lucide/ticket.svg +1 -1
  203. package/icons/lucide/toggle-right.svg +1 -1
  204. package/icons/lucide/train.svg +1 -1
  205. package/icons/lucide/trash.svg +1 -1
  206. package/icons/lucide/upload-simple.svg +1 -1
  207. package/icons/lucide/user-circle.svg +1 -1
  208. package/icons/lucide/user.svg +1 -1
  209. package/icons/lucide/users-three.svg +1 -1
  210. package/icons/lucide/users.svg +1 -1
  211. package/icons/lucide/video-camera.svg +1 -1
  212. package/icons/lucide/warning-circle.svg +1 -1
  213. package/icons/lucide/warning.svg +1 -1
  214. package/icons/lucide/wave-sine.svg +1 -1
  215. package/icons/lucide/wheelchair.svg +1 -1
  216. package/icons/lucide/wrench.svg +1 -1
  217. package/icons/lucide/x.svg +1 -1
  218. package/icons/material-symbols/LICENSE +201 -201
  219. package/icons/material-symbols/address-book.svg +1 -1
  220. package/icons/material-symbols/app-window.svg +1 -1
  221. package/icons/material-symbols/arrow-counter-clockwise.svg +1 -1
  222. package/icons/material-symbols/arrow-down.svg +1 -1
  223. package/icons/material-symbols/arrow-left.svg +1 -1
  224. package/icons/material-symbols/arrow-right.svg +1 -1
  225. package/icons/material-symbols/arrow-square-out.svg +1 -1
  226. package/icons/material-symbols/arrow-u-up-left.svg +1 -1
  227. package/icons/material-symbols/arrow-u-up-right.svg +1 -1
  228. package/icons/material-symbols/arrow-up-right.svg +1 -1
  229. package/icons/material-symbols/arrow-up.svg +1 -1
  230. package/icons/material-symbols/arrows-down-up.svg +1 -1
  231. package/icons/material-symbols/arrows-in-line-horizontal.svg +1 -1
  232. package/icons/material-symbols/arrows-out-line-horizontal.svg +1 -1
  233. package/icons/material-symbols/article.svg +1 -1
  234. package/icons/material-symbols/bank.svg +1 -1
  235. package/icons/material-symbols/bell.svg +1 -1
  236. package/icons/material-symbols/bicycle.svg +1 -1
  237. package/icons/material-symbols/binoculars.svg +1 -1
  238. package/icons/material-symbols/book-open-text.svg +1 -1
  239. package/icons/material-symbols/book-open.svg +1 -1
  240. package/icons/material-symbols/browser.svg +1 -1
  241. package/icons/material-symbols/buildings.svg +1 -1
  242. package/icons/material-symbols/bus.svg +1 -1
  243. package/icons/material-symbols/calendar-blank.svg +1 -1
  244. package/icons/material-symbols/calendar-check.svg +1 -1
  245. package/icons/material-symbols/car.svg +1 -1
  246. package/icons/material-symbols/cards.svg +1 -1
  247. package/icons/material-symbols/caret-down.svg +1 -1
  248. package/icons/material-symbols/caret-left.svg +1 -1
  249. package/icons/material-symbols/caret-right.svg +1 -1
  250. package/icons/material-symbols/caret-up.svg +1 -1
  251. package/icons/material-symbols/certificate.svg +1 -1
  252. package/icons/material-symbols/chart-line-up.svg +1 -1
  253. package/icons/material-symbols/chats.svg +1 -1
  254. package/icons/material-symbols/check-circle.svg +1 -1
  255. package/icons/material-symbols/check.svg +1 -1
  256. package/icons/material-symbols/circle-half.svg +1 -1
  257. package/icons/material-symbols/circle.svg +1 -1
  258. package/icons/material-symbols/clock-counter-clockwise.svg +1 -1
  259. package/icons/material-symbols/clock.svg +1 -1
  260. package/icons/material-symbols/code.svg +1 -1
  261. package/icons/material-symbols/coffee.svg +1 -1
  262. package/icons/material-symbols/columns.svg +1 -1
  263. package/icons/material-symbols/cookie.svg +1 -1
  264. package/icons/material-symbols/copy.svg +1 -1
  265. package/icons/material-symbols/credit-card.svg +1 -1
  266. package/icons/material-symbols/currency-circle-dollar.svg +1 -1
  267. package/icons/material-symbols/cursor-click.svg +1 -1
  268. package/icons/material-symbols/database.svg +1 -1
  269. package/icons/material-symbols/desktop.svg +1 -1
  270. package/icons/material-symbols/device-mobile.svg +1 -1
  271. package/icons/material-symbols/door-open.svg +1 -1
  272. package/icons/material-symbols/download-simple.svg +1 -1
  273. package/icons/material-symbols/envelope-simple.svg +1 -1
  274. package/icons/material-symbols/eye-slash.svg +1 -1
  275. package/icons/material-symbols/eye.svg +1 -1
  276. package/icons/material-symbols/file-pdf.svg +1 -1
  277. package/icons/material-symbols/file-text.svg +1 -1
  278. package/icons/material-symbols/file-video.svg +1 -1
  279. package/icons/material-symbols/file-zip.svg +1 -1
  280. package/icons/material-symbols/flower-lotus.svg +1 -1
  281. package/icons/material-symbols/folder-simple.svg +1 -1
  282. package/icons/material-symbols/funnel.svg +1 -1
  283. package/icons/material-symbols/gauge.svg +1 -1
  284. package/icons/material-symbols/gear.svg +1 -1
  285. package/icons/material-symbols/github-logo.svg +1 -1
  286. package/icons/material-symbols/globe.svg +1 -1
  287. package/icons/material-symbols/google-logo.svg +1 -1
  288. package/icons/material-symbols/graduation-cap.svg +1 -1
  289. package/icons/material-symbols/hammer.svg +1 -1
  290. package/icons/material-symbols/hand-heart.svg +1 -1
  291. package/icons/material-symbols/handshake.svg +1 -1
  292. package/icons/material-symbols/hard-drives.svg +1 -1
  293. package/icons/material-symbols/heart.svg +1 -1
  294. package/icons/material-symbols/house.svg +1 -1
  295. package/icons/material-symbols/image-square.svg +1 -1
  296. package/icons/material-symbols/image.svg +1 -1
  297. package/icons/material-symbols/info.svg +1 -1
  298. package/icons/material-symbols/keyboard.svg +1 -1
  299. package/icons/material-symbols/leaf.svg +1 -1
  300. package/icons/material-symbols/lifebuoy.svg +1 -1
  301. package/icons/material-symbols/lightbulb.svg +1 -1
  302. package/icons/material-symbols/link-break.svg +1 -1
  303. package/icons/material-symbols/link-simple.svg +1 -1
  304. package/icons/material-symbols/list-bullets.svg +1 -1
  305. package/icons/material-symbols/list-checks.svg +1 -1
  306. package/icons/material-symbols/list-numbers.svg +1 -1
  307. package/icons/material-symbols/list.svg +1 -1
  308. package/icons/material-symbols/lock-simple-open.svg +1 -1
  309. package/icons/material-symbols/lock-simple.svg +1 -1
  310. package/icons/material-symbols/magnifying-glass.svg +1 -1
  311. package/icons/material-symbols/map-pin.svg +1 -1
  312. package/icons/material-symbols/map-trifold.svg +1 -1
  313. package/icons/material-symbols/medal.svg +1 -1
  314. package/icons/material-symbols/megaphone.svg +1 -1
  315. package/icons/material-symbols/minus.svg +1 -1
  316. package/icons/material-symbols/moon.svg +1 -1
  317. package/icons/material-symbols/newspaper.svg +1 -1
  318. package/icons/material-symbols/pack.json +29 -29
  319. package/icons/material-symbols/paint-brush-broad.svg +1 -1
  320. package/icons/material-symbols/palette.svg +1 -1
  321. package/icons/material-symbols/paper-plane-tilt.svg +1 -1
  322. package/icons/material-symbols/pencil-simple.svg +1 -1
  323. package/icons/material-symbols/phone.svg +1 -1
  324. package/icons/material-symbols/play-fill.svg +1 -1
  325. package/icons/material-symbols/plus.svg +1 -1
  326. package/icons/material-symbols/prohibit.svg +1 -1
  327. package/icons/material-symbols/puzzle-piece.svg +1 -1
  328. package/icons/material-symbols/question.svg +1 -1
  329. package/icons/material-symbols/quotes.svg +1 -1
  330. package/icons/material-symbols/rows.svg +1 -1
  331. package/icons/material-symbols/ruler.svg +1 -1
  332. package/icons/material-symbols/scan.svg +1 -1
  333. package/icons/material-symbols/shapes.svg +1 -1
  334. package/icons/material-symbols/share-network.svg +1 -1
  335. package/icons/material-symbols/shield-check.svg +1 -1
  336. package/icons/material-symbols/sidebar-simple.svg +1 -1
  337. package/icons/material-symbols/sign-out.svg +1 -1
  338. package/icons/material-symbols/signpost.svg +1 -1
  339. package/icons/material-symbols/sliders-horizontal.svg +1 -1
  340. package/icons/material-symbols/smiley.svg +1 -1
  341. package/icons/material-symbols/sparkle.svg +1 -1
  342. package/icons/material-symbols/square-half-bottom.svg +1 -1
  343. package/icons/material-symbols/square.svg +1 -1
  344. package/icons/material-symbols/squares-four.svg +1 -1
  345. package/icons/material-symbols/sticker.svg +1 -1
  346. package/icons/material-symbols/storefront.svg +1 -1
  347. package/icons/material-symbols/sun.svg +1 -1
  348. package/icons/material-symbols/swatches.svg +1 -1
  349. package/icons/material-symbols/tag.svg +1 -1
  350. package/icons/material-symbols/text-aa.svg +1 -1
  351. package/icons/material-symbols/text-align-left.svg +1 -1
  352. package/icons/material-symbols/text-b.svg +1 -1
  353. package/icons/material-symbols/text-h-one.svg +1 -1
  354. package/icons/material-symbols/text-h-three.svg +1 -1
  355. package/icons/material-symbols/text-h-two.svg +1 -1
  356. package/icons/material-symbols/text-italic.svg +1 -1
  357. package/icons/material-symbols/text-t.svg +1 -1
  358. package/icons/material-symbols/ticket.svg +1 -1
  359. package/icons/material-symbols/toggle-right.svg +1 -1
  360. package/icons/material-symbols/train.svg +1 -1
  361. package/icons/material-symbols/trash.svg +1 -1
  362. package/icons/material-symbols/upload-simple.svg +1 -1
  363. package/icons/material-symbols/user-circle.svg +1 -1
  364. package/icons/material-symbols/user.svg +1 -1
  365. package/icons/material-symbols/users-three.svg +1 -1
  366. package/icons/material-symbols/users.svg +1 -1
  367. package/icons/material-symbols/video-camera.svg +1 -1
  368. package/icons/material-symbols/warning-circle.svg +1 -1
  369. package/icons/material-symbols/warning.svg +1 -1
  370. package/icons/material-symbols/wave-sine.svg +1 -1
  371. package/icons/material-symbols/wheelchair.svg +1 -1
  372. package/icons/material-symbols/wrench.svg +1 -1
  373. package/icons/material-symbols/x.svg +1 -1
  374. package/icons/phosphor/pack.json +8 -8
  375. package/lib/apps.mjs +142 -139
  376. package/lib/apps.test.d.mts +1 -0
  377. package/lib/apps.test.mjs +50 -0
  378. package/lib/blocks.mjs +90 -90
  379. package/lib/caseCollisions.d.mts +4 -0
  380. package/lib/caseCollisions.mjs +62 -0
  381. package/lib/caseCollisions.test.d.mts +1 -0
  382. package/lib/caseCollisions.test.mjs +74 -0
  383. package/lib/colors.ts +86 -86
  384. package/lib/contactBar.ts +18 -18
  385. package/lib/contracts.d.mts +15 -0
  386. package/lib/contracts.mjs +17 -0
  387. package/lib/cookieCategories.mjs +28 -28
  388. package/lib/crop.mjs +83 -83
  389. package/lib/csp.mjs +130 -130
  390. package/lib/cspSources.mjs +60 -60
  391. package/lib/dynamic-colors.ts +426 -426
  392. package/lib/git.mjs +64 -64
  393. package/lib/hooks.ts +51 -51
  394. package/lib/inline.ts +20 -20
  395. package/lib/license-texts/Apache-2.0.txt +190 -190
  396. package/lib/license-texts/BSD-2-Clause.txt +24 -24
  397. package/lib/license-texts/BSD-3-Clause.txt +28 -28
  398. package/lib/license-texts/ISC.txt +15 -15
  399. package/lib/license-texts/MIT.txt +21 -21
  400. package/lib/licenses.d.mts +1 -1
  401. package/lib/licenses.mjs +683 -683
  402. package/lib/markdown.ts +42 -42
  403. package/lib/motion-schemes.mjs +5 -5
  404. package/lib/motion.ts +131 -131
  405. package/lib/notice.mjs +34 -34
  406. package/lib/scheduled.mjs +37 -37
  407. package/lib/snackbar.ts +149 -149
  408. package/lib/status.mjs +18 -18
  409. package/lib/storeEntries.d.mts +18 -0
  410. package/lib/storeEntries.mjs +64 -0
  411. package/lib/storeEntries.test.d.mts +1 -0
  412. package/lib/storeEntries.test.mjs +71 -0
  413. package/lib/svg.mjs +231 -231
  414. package/lib/text-colors.mjs +43 -43
  415. package/lib/video-id.mjs +72 -72
  416. package/lib/video.mjs +91 -91
  417. package/package.json +136 -131
  418. package/pages/404.astro +10 -10
  419. package/pages/[...slug].astro +51 -51
  420. package/pages/_headers.txt +31 -31
  421. package/pages/blog/index.astro +10 -10
  422. package/pages/blog/kategori/[category].astro +18 -18
  423. package/pages/editor/code-images.json.js +25 -25
  424. package/pages/editor/index.astro +75 -75
  425. package/pages/editor/manifest.webmanifest.js +23 -23
  426. package/pages/editor/sw.js +33 -33
  427. package/pages/editor/sw.js.js +4 -4
  428. package/pages/editor/thumbnails.json.js +21 -21
  429. package/pages/editor/version.json.js +22 -22
  430. package/pages/headers.js +4 -4
  431. package/pages/index.astro +10 -10
  432. package/pages/ny.astro +6 -6
  433. package/pages/robots.txt.js +3 -3
  434. package/pages/rss.xml.js +20 -20
  435. package/scripts/app-screenshots.mjs +164 -164
  436. package/scripts/app-workers.mjs +6 -6
  437. package/scripts/bin.mjs +12 -12
  438. package/scripts/built-site.mjs +134 -99
  439. package/scripts/check-consent.mjs +113 -113
  440. package/scripts/check-content.mjs +151 -149
  441. package/scripts/check-demo.mjs +24 -24
  442. package/scripts/check-store.mjs +160 -0
  443. package/scripts/check-themes.mjs +45 -45
  444. package/scripts/check-worker.mjs +569 -569
  445. package/scripts/compare-html.mjs +81 -81
  446. package/scripts/declarations.mjs +10 -0
  447. package/scripts/declarations.test.mjs +32 -0
  448. package/scripts/demo-site.mjs +42 -42
  449. package/scripts/editor-icons.mjs +56 -56
  450. package/scripts/editor-roundtrip.mjs +134 -134
  451. package/scripts/editor-screens.mjs +101 -101
  452. package/scripts/git-env.mjs +9 -9
  453. package/scripts/icon-packs.mjs +151 -151
  454. package/scripts/link-counts.mjs +22 -22
  455. package/scripts/page-colors.mjs +42 -42
  456. package/scripts/releases.mjs +80 -80
  457. package/scripts/responsive-images.mjs +94 -94
  458. package/scripts/scheduled-list.mjs +15 -15
  459. package/scripts/theme-screenshots.mjs +88 -88
  460. package/scripts/types.mjs +17 -21
  461. package/scripts/video-thumbnails.mjs +89 -89
  462. package/scripts/worker-modules.mjs +34 -34
  463. package/site/appCookies.mjs +74 -74
  464. package/site/apps.ts +21 -21
  465. package/site/autolinks.mjs +200 -200
  466. package/site/blockScripts.ts +31 -31
  467. package/site/categories.ts +16 -16
  468. package/site/consent.ts +26 -26
  469. package/site/content.config.ts +84 -84
  470. package/site/content.ts +104 -104
  471. package/site/cookieList.ts +17 -17
  472. package/site/defineSite.d.mts +2 -14
  473. package/site/defineSite.mjs +131 -136
  474. package/site/directives/interact.mjs +31 -31
  475. package/site/editor-version.mjs +26 -26
  476. package/site/fill.ts +13 -13
  477. package/site/format.ts +11 -11
  478. package/site/home.ts +66 -66
  479. package/site/iconPacks.mjs +43 -43
  480. package/site/icons.mjs +605 -605
  481. package/site/images.mjs +157 -157
  482. package/site/motion.ts +13 -13
  483. package/site/noindex.mjs +21 -21
  484. package/site/pageColors.ts +110 -110
  485. package/site/popups.ts +98 -98
  486. package/site/schema.ts +189 -189
  487. package/site/sections.ts +3 -3
  488. package/site/seo.ts +28 -28
  489. package/site/site.ts +76 -76
  490. package/site/siteConfig.mjs +8 -8
  491. package/site/siteCsp.mjs +75 -75
  492. package/site/siteModules.mjs +27 -27
  493. package/site/standardPages.ts +59 -59
  494. package/site/storeTheme.d.mts +6 -0
  495. package/site/storeTheme.mjs +29 -0
  496. package/site/storeTheme.test.d.mts +1 -0
  497. package/site/storeTheme.test.mjs +53 -0
  498. package/site/testimonials.ts +48 -48
  499. package/site/text.ts +43 -43
  500. package/site/theme.mjs +483 -472
  501. package/site/tracking.client.ts +225 -225
  502. package/site/tracking.ts +9 -9
  503. package/src/ActionParts.tsx +205 -205
  504. package/src/Advanced.tsx +152 -152
  505. package/src/App.tsx +901 -904
  506. package/src/AppList.tsx +1362 -1345
  507. package/src/BlockDialog.tsx +360 -360
  508. package/src/BlockParts.tsx +652 -652
  509. package/src/BlockSettings.tsx +533 -533
  510. package/src/BrandForm.tsx +164 -164
  511. package/src/Colors.tsx +476 -476
  512. package/src/CommunicationParts.tsx +199 -199
  513. package/src/CompanyForm.tsx +209 -209
  514. package/src/Consents.tsx +175 -175
  515. package/src/ContainmentParts.tsx +185 -185
  516. package/src/Crop.tsx +152 -152
  517. package/src/DataForm.tsx +434 -434
  518. package/src/Deleted.tsx +177 -177
  519. package/src/EntryForm.tsx +740 -740
  520. package/src/FileView.tsx +30 -30
  521. package/src/FormFrame.tsx +237 -237
  522. package/src/Keywords.tsx +225 -225
  523. package/src/Library.tsx +1563 -1563
  524. package/src/Licenses.tsx +336 -336
  525. package/src/LinkSheet.tsx +138 -138
  526. package/src/MarkdownEditor.tsx +1075 -1075
  527. package/src/Media.tsx +677 -677
  528. package/src/NavigationParts.tsx +350 -350
  529. package/src/NavigationRestParts.tsx +247 -247
  530. package/src/Notifications.tsx +59 -59
  531. package/src/PagePicker.tsx +136 -136
  532. package/src/Parts.tsx +991 -991
  533. package/src/PartsShown.tsx +168 -168
  534. package/src/PickerParts.tsx +183 -183
  535. package/src/Redirects.tsx +450 -450
  536. package/src/Screen.tsx +184 -184
  537. package/src/SectionsField.tsx +65 -65
  538. package/src/SelectionParts.tsx +134 -134
  539. package/src/SeoScores.tsx +184 -184
  540. package/src/Sheet.tsx +35 -35
  541. package/src/ThemeStore.tsx +376 -376
  542. package/src/Tokens.tsx +346 -346
  543. package/src/Versions.tsx +214 -214
  544. package/src/addresses.ts +75 -75
  545. package/src/allIcons.ts +7 -7
  546. package/src/appFiles.ts +29 -29
  547. package/src/apps.ts +281 -281
  548. package/src/ask.tsx +123 -123
  549. package/src/blocks.ts +251 -251
  550. package/src/brand.ts +153 -153
  551. package/src/cache.ts +42 -42
  552. package/src/check.ts +285 -285
  553. package/src/checkSite.ts +256 -256
  554. package/src/{consents.ts → consentData.ts} +26 -26
  555. package/src/cookieList.ts +70 -70
  556. package/src/countries.ts +59 -59
  557. package/src/deploy.ts +155 -155
  558. package/src/editor.css +602 -602
  559. package/src/examples.ts +85 -85
  560. package/src/fields.tsx +942 -942
  561. package/src/frontmatter.mjs +42 -42
  562. package/src/github.ts +376 -376
  563. package/src/i18n/da-DK/advanced.ts +28 -28
  564. package/src/i18n/da-DK/app.ts +71 -71
  565. package/src/i18n/da-DK/apps.ts +90 -90
  566. package/src/i18n/da-DK/blockSettings.ts +38 -38
  567. package/src/i18n/da-DK/blocks.ts +408 -408
  568. package/src/i18n/da-DK/check.ts +25 -25
  569. package/src/i18n/da-DK/colors.ts +64 -64
  570. package/src/i18n/da-DK/common.ts +118 -118
  571. package/src/i18n/da-DK/company.ts +24 -24
  572. package/src/i18n/da-DK/consents.ts +23 -23
  573. package/src/i18n/da-DK/forms.ts +116 -116
  574. package/src/i18n/da-DK/history.ts +35 -35
  575. package/src/i18n/da-DK/index.ts +49 -49
  576. package/src/i18n/da-DK/keywords.ts +19 -19
  577. package/src/i18n/da-DK/library.ts +135 -135
  578. package/src/i18n/da-DK/licenses.ts +25 -25
  579. package/src/i18n/da-DK/media.ts +79 -79
  580. package/src/i18n/da-DK/parts.ts +696 -696
  581. package/src/i18n/da-DK/preview.ts +13 -13
  582. package/src/i18n/da-DK/redirects.ts +51 -51
  583. package/src/i18n/da-DK/seo.ts +20 -20
  584. package/src/i18n/da-DK/text.ts +35 -35
  585. package/src/i18n/da-DK/theme.ts +41 -41
  586. package/src/i18n/en-US/advanced.ts +32 -32
  587. package/src/i18n/en-US/app.ts +84 -84
  588. package/src/i18n/en-US/apps.ts +134 -134
  589. package/src/i18n/en-US/blockSettings.ts +48 -48
  590. package/src/i18n/en-US/blocks.ts +441 -441
  591. package/src/i18n/en-US/check.ts +31 -31
  592. package/src/i18n/en-US/colors.ts +82 -82
  593. package/src/i18n/en-US/common.ts +144 -144
  594. package/src/i18n/en-US/company.ts +25 -25
  595. package/src/i18n/en-US/consents.ts +25 -25
  596. package/src/i18n/en-US/forms.ts +145 -145
  597. package/src/i18n/en-US/history.ts +43 -43
  598. package/src/i18n/en-US/index.ts +51 -51
  599. package/src/i18n/en-US/keywords.ts +24 -24
  600. package/src/i18n/en-US/library.ts +176 -176
  601. package/src/i18n/en-US/licenses.ts +36 -36
  602. package/src/i18n/en-US/media.ts +80 -80
  603. package/src/i18n/en-US/parts.ts +718 -718
  604. package/src/i18n/en-US/preview.ts +15 -15
  605. package/src/i18n/en-US/redirects.ts +66 -66
  606. package/src/i18n/en-US/seo.ts +26 -26
  607. package/src/i18n/en-US/text.ts +41 -41
  608. package/src/i18n/en-US/theme.ts +41 -41
  609. package/src/i18n/index.ts +124 -124
  610. package/src/icon.tsx +160 -160
  611. package/src/iconPacks.ts +89 -89
  612. package/src/images.ts +163 -163
  613. package/src/{licenses.ts → licenseData.ts} +79 -79
  614. package/src/markdown.mjs +204 -204
  615. package/src/nav.ts +68 -68
  616. package/src/notFound.ts +28 -28
  617. package/src/{notifications.ts → notificationData.ts} +223 -223
  618. package/src/pagePreview.tsx +204 -204
  619. package/src/r2Caching.ts +55 -55
  620. package/src/{redirects.ts → redirectData.ts} +149 -149
  621. package/src/registry.tsx +188 -188
  622. package/src/schema.ts +417 -417
  623. package/src/sections.mjs +303 -303
  624. package/src/seo.ts +333 -333
  625. package/src/shared.ts +44 -44
  626. package/src/sidebar.ts +31 -31
  627. package/src/site.ts +317 -317
  628. package/src/standard/Block.astro +19 -19
  629. package/src/standard/BlockSite.astro +18 -18
  630. package/src/standard/accordion/index.tsx +47 -47
  631. package/src/standard/accordion/load.ts +23 -23
  632. package/src/standard/accordion/shared.ts +15 -15
  633. package/src/standard/accordion/view.ts +32 -32
  634. package/src/standard/buttons/fields.ts +98 -98
  635. package/src/standard/buttons/index.tsx +23 -23
  636. package/src/standard/buttons/load.ts +34 -34
  637. package/src/standard/buttons/shared.ts +12 -12
  638. package/src/standard/buttons/view.ts +30 -30
  639. package/src/standard/cards/index.tsx +71 -71
  640. package/src/standard/cards/load.ts +17 -17
  641. package/src/standard/cards/shared.ts +27 -27
  642. package/src/standard/cards/view.ts +29 -29
  643. package/src/standard/checklist/index.tsx +27 -27
  644. package/src/standard/checklist/load.ts +5 -5
  645. package/src/standard/checklist/view.ts +13 -13
  646. package/src/standard/cookies/index.tsx +17 -17
  647. package/src/standard/cookies/list.ts +56 -56
  648. package/src/standard/cookies/load.ts +11 -11
  649. package/src/standard/cookies/shared.ts +20 -20
  650. package/src/standard/cookies/view.ts +28 -28
  651. package/src/standard/faq/index.tsx +29 -29
  652. package/src/standard/faq/load.ts +14 -14
  653. package/src/standard/faq/view.ts +21 -21
  654. package/src/standard/head.ts +23 -23
  655. package/src/standard/hero/fields.ts +48 -48
  656. package/src/standard/hero/index.tsx +57 -57
  657. package/src/standard/hero/load.ts +23 -23
  658. package/src/standard/hero/view.ts +38 -38
  659. package/src/standard/links/index.tsx +41 -41
  660. package/src/standard/links/load.ts +17 -17
  661. package/src/standard/links/view.ts +25 -25
  662. package/src/standard/list/index.tsx +50 -50
  663. package/src/standard/list/load.ts +5 -5
  664. package/src/standard/list/view.ts +18 -18
  665. package/src/standard/load.ts +7 -7
  666. package/src/standard/notice/index.tsx +30 -30
  667. package/src/standard/notice/load.ts +16 -16
  668. package/src/standard/notice/view.ts +10 -10
  669. package/src/standard/points/index.tsx +42 -42
  670. package/src/standard/points/load.ts +5 -5
  671. package/src/standard/points/view.ts +12 -12
  672. package/src/standard/posts/index.tsx +132 -132
  673. package/src/standard/posts/load.ts +36 -36
  674. package/src/standard/posts/shared.ts +21 -21
  675. package/src/standard/posts/view.ts +63 -63
  676. package/src/standard/pricecards/index.tsx +57 -57
  677. package/src/standard/pricecards/load.ts +11 -11
  678. package/src/standard/pricecards/view.ts +50 -50
  679. package/src/standard/sharedTexts.ts +6 -6
  680. package/src/standard/site.ts +124 -124
  681. package/src/standard/siteLooks.ts +19 -19
  682. package/src/standard/sites.ts +13 -13
  683. package/src/standard/steps/index.tsx +28 -28
  684. package/src/standard/steps/load.ts +5 -5
  685. package/src/standard/steps/view.ts +11 -11
  686. package/src/standard/testimonials/index.tsx +87 -87
  687. package/src/standard/testimonials/list.ts +43 -43
  688. package/src/standard/testimonials/load.ts +58 -58
  689. package/src/standard/testimonials/shared.ts +13 -13
  690. package/src/standard/testimonials/view.ts +76 -76
  691. package/src/standard/themeBlocks.ts +13 -13
  692. package/src/standard/video/index.tsx +23 -23
  693. package/src/standard/video/load.ts +10 -10
  694. package/src/standard/video/view.ts +42 -42
  695. package/src/standard/view.tsx +105 -105
  696. package/src/standard/views.ts +37 -37
  697. package/src/store.ts +479 -499
  698. package/src/theme.ts +90 -90
  699. package/src/themeUi.ts +97 -97
  700. package/src/themes.ts +91 -91
  701. package/src/ui.tsx +3402 -3402
  702. package/src/virtual.d.ts +5 -5
  703. package/src/when.ts +22 -22
  704. package/starter/.githooks/pre-push +4 -4
  705. package/starter/.nvmrc +1 -1
  706. package/starter/.prettierignore +11 -11
  707. package/starter/.prettierrc.json +7 -7
  708. package/starter/README.md +27 -26
  709. package/starter/astro.config.mjs +5 -5
  710. package/starter/package.json +67 -67
  711. package/starter/public/_redirects +1 -1
  712. package/starter/public/favicon.svg +1 -1
  713. package/starter/public/logo.svg +1 -1
  714. package/starter/src/content/pages/blog.md +8 -8
  715. package/starter/src/content/pages/forside.md +9 -9
  716. package/starter/src/content/pages/kontakt.md +7 -7
  717. package/starter/src/content/pages/privatlivspolitik.md +9 -9
  718. package/starter/src/content/pages/siden-findes-ikke.md +7 -7
  719. package/starter/src/content.config.ts +2 -2
  720. package/starter/src/data/apps.json +1 -1
  721. package/starter/src/data/block-settings.json +3 -3
  722. package/starter/src/data/blocks.json +1 -1
  723. package/starter/src/data/booking.json +6 -6
  724. package/starter/src/data/colors.json +70 -70
  725. package/starter/src/data/contact.json +8 -8
  726. package/starter/src/data/cookies.json +21 -21
  727. package/starter/src/data/csp.json +1 -1
  728. package/starter/src/data/footer.json +15 -15
  729. package/starter/src/data/internal-links.json +4 -4
  730. package/starter/src/data/menu.json +4 -4
  731. package/starter/src/data/mobile-menu.json +4 -4
  732. package/starter/src/data/old-addresses.json +1 -1
  733. package/starter/src/data/redirects.json +1 -1
  734. package/starter/src/data/standard-pages.json +8 -8
  735. package/starter/src/data/theme.json +1 -1
  736. package/starter/src/env.d.ts +2 -2
  737. package/starter/src/site/config.ts +13 -13
  738. package/starter/src/site/worker.js +14 -14
  739. package/starter/tsconfig.json +17 -17
  740. package/starter/worker/apps.js +6 -6
  741. package/starter/wrangler.jsonc +39 -39
  742. package/theme/LICENSE +21 -21
  743. package/theme/blocks/ArrowLink.tsx +14 -14
  744. package/theme/blocks/BlockHead.tsx +26 -26
  745. package/theme/blocks/Panel.tsx +32 -32
  746. package/theme/blocks/Person.tsx +26 -26
  747. package/theme/blocks/accordion/PageRow.tsx +25 -25
  748. package/theme/blocks/accordion/View.tsx +17 -17
  749. package/theme/blocks/buttons/Buttons.tsx +28 -28
  750. package/theme/blocks/buttons/View.tsx +12 -12
  751. package/theme/blocks/cards/LinkCards.tsx +72 -72
  752. package/theme/blocks/cards/View.tsx +20 -20
  753. package/theme/blocks/checklist/Checks.tsx +15 -15
  754. package/theme/blocks/checklist/View.tsx +14 -14
  755. package/theme/blocks/cookies/View.tsx +36 -36
  756. package/theme/blocks/faq/Accordion.tsx +34 -34
  757. package/theme/blocks/faq/View.tsx +16 -16
  758. package/theme/blocks/faq/script.ts +56 -56
  759. package/theme/blocks/hero/View.tsx +44 -44
  760. package/theme/blocks/links/LinkGroups.tsx +24 -24
  761. package/theme/blocks/links/View.tsx +17 -17
  762. package/theme/blocks/list/Rows.tsx +24 -24
  763. package/theme/blocks/list/View.tsx +14 -14
  764. package/theme/blocks/notice/View.tsx +13 -13
  765. package/theme/blocks/points/PointList.tsx +34 -34
  766. package/theme/blocks/points/View.tsx +14 -14
  767. package/theme/blocks/posts/View.tsx +26 -26
  768. package/theme/blocks/pricecards/View.tsx +40 -40
  769. package/theme/blocks/steps/StepList.tsx +23 -23
  770. package/theme/blocks/steps/View.tsx +14 -14
  771. package/theme/blocks/testimonials/List.tsx +46 -46
  772. package/theme/blocks/testimonials/Slider.tsx +44 -44
  773. package/theme/blocks/testimonials/Testimonial.tsx +124 -124
  774. package/theme/blocks/testimonials/View.tsx +21 -21
  775. package/theme/blocks/testimonials/script.ts +52 -52
  776. package/theme/blocks/video/View.tsx +41 -41
  777. package/theme/components/ActionBar.astro +63 -63
  778. package/theme/components/AppSlot.astro +21 -21
  779. package/theme/components/ArrowLink.tsx +21 -21
  780. package/theme/components/BlogIndex.astro +48 -48
  781. package/theme/components/BlogPosts.astro +18 -18
  782. package/theme/components/BlogPosts.tsx +45 -45
  783. package/theme/components/BookButton.tsx +22 -22
  784. package/theme/components/Container.astro +11 -11
  785. package/theme/components/CookieConsent.astro +121 -121
  786. package/theme/components/EndBlock.astro +21 -21
  787. package/theme/components/FontPreload.astro +6 -6
  788. package/theme/components/Footer.astro +85 -85
  789. package/theme/components/Header.astro +186 -186
  790. package/theme/components/Icon.astro +16 -16
  791. package/theme/components/Img.astro +29 -29
  792. package/theme/components/Img.tsx +33 -33
  793. package/theme/components/Inline.astro +11 -11
  794. package/theme/components/Logo.astro +23 -23
  795. package/theme/components/LogoMark.astro +10 -10
  796. package/theme/components/Markdown.astro +17 -17
  797. package/theme/components/MobileMenu.tsx +224 -224
  798. package/theme/components/MobileNav.astro +33 -33
  799. package/theme/components/PageHeader.astro +22 -22
  800. package/theme/components/PageSection.astro +24 -24
  801. package/theme/components/PhoneButton.tsx +11 -11
  802. package/theme/components/Popup.astro +145 -145
  803. package/theme/components/PopupButton.tsx +24 -24
  804. package/theme/components/PopupView.tsx +48 -48
  805. package/theme/components/PostList.tsx +58 -58
  806. package/theme/components/PostMeta.tsx +17 -17
  807. package/theme/components/RichText.astro +28 -28
  808. package/theme/components/Section.astro +29 -29
  809. package/theme/components/SectionHeading.tsx +8 -8
  810. package/theme/components/TextSection.astro +16 -16
  811. package/theme/components/home/PageBlock.astro +19 -19
  812. package/theme/components/home/Text.astro +13 -13
  813. package/theme/components/loadPopup.ts +22 -22
  814. package/theme/components/loadPosts.ts +16 -16
  815. package/theme/components/posts.ts +15 -15
  816. package/theme/editor/looks.mjs +7 -7
  817. package/theme/editor/previews.tsx +56 -56
  818. package/theme/layouts/Base.astro +273 -273
  819. package/theme/layouts/PageLayout.astro +126 -126
  820. package/theme/layouts/PostLayout.astro +137 -137
  821. package/theme/scripts/motion.ts +29 -29
  822. package/theme/styles/base.css +320 -320
  823. package/theme/styles/blocks.css +1808 -1808
  824. package/theme/styles/components.css +206 -206
  825. package/theme/styles/global.css +1302 -1302
  826. package/theme/styles/ui.css +6544 -6544
  827. package/theme/templates/Blog.astro +38 -38
  828. package/theme/templates/Category.astro +19 -19
  829. package/theme/templates/Home.astro +36 -36
  830. package/theme/templates/New.astro +68 -68
  831. package/theme/templates/NotFound.astro +117 -117
  832. package/theme/theme.json +28 -28
  833. package/theme/ui/Badge.tsx +45 -45
  834. package/theme/ui/BottomSheet.tsx +148 -148
  835. package/theme/ui/Button.tsx +79 -79
  836. package/theme/ui/ButtonGroup.tsx +31 -31
  837. package/theme/ui/Card.tsx +45 -45
  838. package/theme/ui/Carousel.tsx +124 -124
  839. package/theme/ui/Checkbox.tsx +59 -59
  840. package/theme/ui/Chip.tsx +101 -101
  841. package/theme/ui/ChipSet.tsx +27 -27
  842. package/theme/ui/DatePicker.tsx +149 -149
  843. package/theme/ui/DatePickerContainer.tsx +316 -316
  844. package/theme/ui/Dialog.tsx +100 -100
  845. package/theme/ui/Divider.tsx +27 -27
  846. package/theme/ui/ExposedDropdownMenu.tsx +77 -77
  847. package/theme/ui/Fab.tsx +88 -88
  848. package/theme/ui/FabMenu.tsx +67 -67
  849. package/theme/ui/IconButton.tsx +78 -78
  850. package/theme/ui/List.tsx +287 -287
  851. package/theme/ui/LoadingIndicator.tsx +29 -29
  852. package/theme/ui/Menu.tsx +278 -278
  853. package/theme/ui/NavigationBar.tsx +62 -62
  854. package/theme/ui/NavigationDrawer.tsx +80 -80
  855. package/theme/ui/NavigationRail.tsx +154 -154
  856. package/theme/ui/ProgressIndicator.tsx +162 -162
  857. package/theme/ui/RadioButton.tsx +50 -50
  858. package/theme/ui/Search.tsx +129 -129
  859. package/theme/ui/SegmentedButton.tsx +49 -49
  860. package/theme/ui/SideSheet.tsx +54 -54
  861. package/theme/ui/Slider.tsx +155 -155
  862. package/theme/ui/Snackbar.tsx +67 -67
  863. package/theme/ui/SplitButton.tsx +67 -67
  864. package/theme/ui/Switch.tsx +60 -60
  865. package/theme/ui/Tabs.tsx +114 -114
  866. package/theme/ui/TextField.tsx +278 -278
  867. package/theme/ui/TimePicker.tsx +128 -128
  868. package/theme/ui/TimePickerContainer.tsx +234 -234
  869. package/theme/ui/Toolbar.tsx +67 -67
  870. package/theme/ui/Tooltip.tsx +58 -58
  871. package/theme/ui/TopAppBar.tsx +77 -77
  872. package/theme/ui/bottomSheet.script.ts +8 -8
  873. package/theme/ui/{bottomSheet.ts → bottomSheetControl.ts} +211 -211
  874. package/theme/ui/carousel.script.ts +28 -28
  875. package/theme/ui/carouselLayout.ts +229 -229
  876. package/theme/ui/checkbox.script.ts +8 -8
  877. package/theme/ui/datePicker.script.ts +302 -302
  878. package/theme/ui/dates.ts +185 -185
  879. package/theme/ui/{dialog.ts → dialogControl.ts} +48 -48
  880. package/theme/ui/dropdownMenu.script.ts +166 -166
  881. package/theme/ui/fabMenu.script.ts +57 -57
  882. package/theme/ui/navigationRail.script.ts +47 -47
  883. package/theme/ui/ripple.script.ts +159 -159
  884. package/theme/ui/search.script.ts +92 -92
  885. package/theme/ui/{sideSheet.ts → sideSheetControl.ts} +48 -48
  886. package/theme/ui/slider.script.ts +12 -12
  887. package/theme/ui/sliderUpdate.ts +52 -52
  888. package/theme/ui/snackbar.script.ts +16 -16
  889. package/theme/ui/splitButton.script.ts +63 -63
  890. package/theme/ui/tabs.script.ts +48 -48
  891. package/theme/ui/textField.script.ts +17 -17
  892. package/theme/ui/textFieldUpdate.ts +44 -44
  893. package/theme/ui/timePicker.script.ts +248 -248
  894. package/theme/ui/toolbar.script.ts +43 -43
  895. package/theme/ui/tooltip.script.ts +68 -68
  896. package/worker/consent.js +141 -141
  897. package/worker/editor-github.js +167 -167
  898. package/worker/editor-host.js +74 -74
  899. package/worker/files.js +401 -401
  900. package/worker/github.js +36 -36
  901. package/worker/index.js +188 -184
  902. package/worker/not-found.js +97 -97
  903. package/worker/oauth.js +95 -95
  904. package/worker/publish.js +52 -52
  905. package/worker/push.js +270 -270
  906. package/worker/r2-status.js +50 -50
  907. package/worker/session.js +58 -58
  908. package/worker/store.js +46 -0
@@ -1,16 +1,16 @@
1
- // What the structured data (schema.org JSON-LD, packages/editor/site/schema.ts) says of a site beyond its contact
2
- // details, when the site's src/site/schema.ts does not say more: a local business in the country of the site's
3
- // language, without terms, an area, offers or a person behind it. Only facts that are on the site; no ratings or reviews.
4
- import { config } from '@site/config';
5
- import type { SiteSchema } from '../site/schema';
6
-
7
- export const schema: SiteSchema = {
8
- ids: { business: 'virksomhed', person: 'person' },
9
- businessType: 'LocalBusiness',
10
- country: config.locale.split('-')[1] ?? 'DK',
11
- terms: {},
12
- areaServed: [],
13
- offers: null,
14
- person: null,
15
- aboutPath: config.aboutPath ?? null,
16
- };
1
+ // What the structured data (schema.org JSON-LD, packages/editor/site/schema.ts) says of a site beyond its contact
2
+ // details, when the site's src/site/schema.ts does not say more: a local business in the country of the site's
3
+ // language, without terms, an area, offers or a person behind it. Only facts that are on the site; no ratings or reviews.
4
+ import { config } from '@site/config';
5
+ import type { SiteSchema } from '../site/schema';
6
+
7
+ export const schema: SiteSchema = {
8
+ ids: { business: 'virksomhed', person: 'person' },
9
+ businessType: 'LocalBusiness',
10
+ country: config.locale.split('-')[1] ?? 'DK',
11
+ terms: {},
12
+ areaServed: [],
13
+ offers: null,
14
+ person: null,
15
+ aboutPath: config.aboutPath ?? null,
16
+ };
@@ -1,129 +1,129 @@
1
- // What the previews of the blocks (src/apps/<app>/blocks/, previews.tsx) show from elsewhere on the site, from the files
2
- // as the editor has them now: the pages (their titles and texts, for the topics and the services),
3
- // the blog posts, the phone, e-mail and address (contact.json), the payment details (payment.json) and
4
- // the texts of the "Book en tid" box (booking.json), the settings of the apps (src/apps/) and the cookie list.
5
- import type { RepoFile } from '../src/github';
6
- import type { StandardSiteData } from '../src/standard/site';
7
- import { categoryOf } from '../lib/cookieCategories.mjs';
8
- import { readFields, splitFrontmatter } from '../src/frontmatter.mjs';
9
- import { readingMinutes } from '../site/format';
10
- import { stateOf } from '../lib/status.mjs';
11
- import { blockTexts } from '../site/site';
12
- import { config } from '@site/config';
13
-
14
- export type SitePage = { path: string; title: string; body: string };
15
- export type SitePost = {
16
- slug: string;
17
- title: string;
18
- date: Date;
19
- image?: string;
20
- imageAlt?: string;
21
- description?: string;
22
- categories: string[];
23
- minutes: number;
24
- };
25
- export type SiteData = {
26
- pages: SitePage[];
27
- /** The posts on the blog (only published ones, packages/editor/lib/status.mjs), newest first. */
28
- posts: SitePost[];
29
- contact: { name: string; role: string; phone: string; email: string; street: string; city: string };
30
- /** The bank details, and what else the site keeps in payment.json (a site's other ways to pay). */
31
- payment: { bank: string; reg: string; account: string } & Record<string, string>;
32
- booking: { heading: string; text: string };
33
- /** The labels of the buttons "Book en tid" and "Ring …" (booking.json). */
34
- labels: { book: string; call: string };
35
- /** The texts every copy of a block has (its shared.ts, saved in blocks.json). */
36
- blocks: BlockTexts;
37
- /** The texts of the buttons of "Knapper" that go elsewhere than a page (config.buttonTargets). */
38
- buttons: StandardSiteData['buttons'];
39
- /** The tags not shown on the blog ("Blogkategori" off, packages/editor/site/categories.ts). */
40
- tagsOffBlog: string[];
41
- /** The settings of the apps as saved (config.apps.settings), by the app's id; an app's blocks put
42
- * them over those in its settings.ts. */
43
- apps: Record<string, Record<string, unknown>>;
44
- /** The ids of the apps installed (config.apps.installed). */
45
- installed: string[];
46
- /** The cookie list ("Cookies", config.cookieList). */
47
- cookies: StandardSiteData['cookies'];
48
- };
49
-
50
- export type BlockTexts = typeof blockTexts;
51
-
52
- const text = (v: unknown) => (v == null ? '' : String(v));
53
-
54
- export function siteOf(files: RepoFile[]): SiteData {
55
- const md = (folder: string) =>
56
- files
57
- .filter((f) => f.path.startsWith(`${folder}/`) && f.path.endsWith('.md'))
58
- .map((f) => {
59
- const { yaml, body } = splitFrontmatter(f.text);
60
- return { file: f.path.slice(folder.length + 1, -3), data: readFields(yaml) as Record<string, unknown>, body };
61
- });
62
- const json = (path: string) => {
63
- const file = files.find((f) => f.path === path);
64
- return (file ? JSON.parse(file.text) : {}) as Record<string, any>;
65
- };
66
- const contact = json('src/data/contact.json');
67
- const payment: Record<string, unknown> = json('src/data/payment.json') ?? {};
68
- const booking = json('src/data/booking.json');
69
- return {
70
- pages: md('src/content/pages').map(({ file, data, body }) => ({
71
- path: text(data.path) || `/${file.replace(/\/index$/, '')}/`,
72
- title: text(data.title),
73
- body,
74
- })),
75
- posts: md('src/content/blog')
76
- .filter(({ data }) => stateOf(data) === 'published')
77
- .map(({ file, data, body }) => ({
78
- slug: file,
79
- title: text(data.title),
80
- date: new Date(text(data.date)),
81
- image: text(data.image) || undefined,
82
- imageAlt: (data.imageDecorative !== true && text(data.imageAlt)) || undefined,
83
- description: text(data.description) || undefined,
84
- categories: Array.isArray(data.categories) ? data.categories.map(String) : [],
85
- minutes: readingMinutes(body),
86
- }))
87
- .sort((a, b) => b.date.valueOf() - a.date.valueOf()),
88
- contact: {
89
- name: text(contact.name),
90
- role: text(contact.role),
91
- phone: text(contact.phone),
92
- email: text(contact.email),
93
- street: text(contact.street),
94
- city: text(contact.city),
95
- },
96
- payment: {
97
- ...Object.fromEntries(Object.entries(payment).map(([k, v]) => [k, text(v)])),
98
- bank: text(payment.bank),
99
- reg: text(payment.reg),
100
- account: text(payment.account),
101
- },
102
- booking: { heading: text(booking.heading), text: text(booking.text) },
103
- labels: { book: text(booking.book), call: text(booking.call) },
104
- tagsOffBlog: files
105
- .filter((f) => f.path.startsWith('src/data/categories/') && f.path.endsWith('.json') && JSON.parse(f.text).blogCategory === false)
106
- .map((f) => f.path.slice('src/data/categories/'.length, -'.json'.length)),
107
- apps: Object.fromEntries(
108
- files
109
- .filter((f) => f.path.startsWith(`${config.apps.settings}/`) && f.path.endsWith('.json'))
110
- .map((f) => [f.path.slice(config.apps.settings.length + 1, -'.json'.length), json(f.path)]),
111
- ),
112
- installed: ((json(config.apps.installed).installed ?? []) as unknown[]).map(String),
113
- cookies: files
114
- .filter((f) => f.path.startsWith(`${config.cookieList}/`) && f.path.endsWith('.json'))
115
- .map((f) => json(f.path))
116
- .map((c) => ({
117
- name: text(c.name),
118
- provider: text(c.provider),
119
- purpose: text(c.purpose) || undefined,
120
- lasts: text(c.lasts) || undefined,
121
- category: categoryOf(c),
122
- })),
123
- buttons: { booking: { text: text(booking.book) }, phone: { text: text(booking.call), after: text(contact.phone) } },
124
- // As the file has them now, each text falling back on the site's (a text not in the file yet).
125
- blocks: Object.fromEntries(
126
- Object.entries(blockTexts).map(([block, texts]) => [block, { ...texts, ...(json(config.blockTexts)[block] ?? {}) }]),
127
- ) as BlockTexts,
128
- };
129
- }
1
+ // What the previews of the blocks (src/apps/<app>/blocks/, previews.tsx) show from elsewhere on the site, from the files
2
+ // as the editor has them now: the pages (their titles and texts, for the topics and the services),
3
+ // the blog posts, the phone, e-mail and address (contact.json), the payment details (payment.json) and
4
+ // the texts of the "Book en tid" box (booking.json), the settings of the apps (src/apps/) and the cookie list.
5
+ import type { RepoFile } from '../src/github';
6
+ import type { StandardSiteData } from '../src/standard/site';
7
+ import { categoryOf } from '../lib/cookieCategories.mjs';
8
+ import { readFields, splitFrontmatter } from '../src/frontmatter.mjs';
9
+ import { readingMinutes } from '../site/format';
10
+ import { stateOf } from '../lib/status.mjs';
11
+ import { blockTexts } from '../site/site';
12
+ import { config } from '@site/config';
13
+
14
+ export type SitePage = { path: string; title: string; body: string };
15
+ export type SitePost = {
16
+ slug: string;
17
+ title: string;
18
+ date: Date;
19
+ image?: string;
20
+ imageAlt?: string;
21
+ description?: string;
22
+ categories: string[];
23
+ minutes: number;
24
+ };
25
+ export type SiteData = {
26
+ pages: SitePage[];
27
+ /** The posts on the blog (only published ones, packages/editor/lib/status.mjs), newest first. */
28
+ posts: SitePost[];
29
+ contact: { name: string; role: string; phone: string; email: string; street: string; city: string };
30
+ /** The bank details, and what else the site keeps in payment.json (a site's other ways to pay). */
31
+ payment: { bank: string; reg: string; account: string } & Record<string, string>;
32
+ booking: { heading: string; text: string };
33
+ /** The labels of the buttons "Book en tid" and "Ring …" (booking.json). */
34
+ labels: { book: string; call: string };
35
+ /** The texts every copy of a block has (its shared.ts, saved in blocks.json). */
36
+ blocks: BlockTexts;
37
+ /** The texts of the buttons of "Knapper" that go elsewhere than a page (config.buttonTargets). */
38
+ buttons: StandardSiteData['buttons'];
39
+ /** The tags not shown on the blog ("Blogkategori" off, packages/editor/site/categories.ts). */
40
+ tagsOffBlog: string[];
41
+ /** The settings of the apps as saved (config.apps.settings), by the app's id; an app's blocks put
42
+ * them over those in its settings.ts. */
43
+ apps: Record<string, Record<string, unknown>>;
44
+ /** The ids of the apps installed (config.apps.installed). */
45
+ installed: string[];
46
+ /** The cookie list ("Cookies", config.cookieList). */
47
+ cookies: StandardSiteData['cookies'];
48
+ };
49
+
50
+ export type BlockTexts = typeof blockTexts;
51
+
52
+ const text = (v: unknown) => (v == null ? '' : String(v));
53
+
54
+ export function siteOf(files: RepoFile[]): SiteData {
55
+ const md = (folder: string) =>
56
+ files
57
+ .filter((f) => f.path.startsWith(`${folder}/`) && f.path.endsWith('.md'))
58
+ .map((f) => {
59
+ const { yaml, body } = splitFrontmatter(f.text);
60
+ return { file: f.path.slice(folder.length + 1, -3), data: readFields(yaml) as Record<string, unknown>, body };
61
+ });
62
+ const json = (path: string) => {
63
+ const file = files.find((f) => f.path === path);
64
+ return (file ? JSON.parse(file.text) : {}) as Record<string, any>;
65
+ };
66
+ const contact = json('src/data/contact.json');
67
+ const payment: Record<string, unknown> = json('src/data/payment.json') ?? {};
68
+ const booking = json('src/data/booking.json');
69
+ return {
70
+ pages: md('src/content/pages').map(({ file, data, body }) => ({
71
+ path: text(data.path) || `/${file.replace(/\/index$/, '')}/`,
72
+ title: text(data.title),
73
+ body,
74
+ })),
75
+ posts: md('src/content/blog')
76
+ .filter(({ data }) => stateOf(data) === 'published')
77
+ .map(({ file, data, body }) => ({
78
+ slug: file,
79
+ title: text(data.title),
80
+ date: new Date(text(data.date)),
81
+ image: text(data.image) || undefined,
82
+ imageAlt: (data.imageDecorative !== true && text(data.imageAlt)) || undefined,
83
+ description: text(data.description) || undefined,
84
+ categories: Array.isArray(data.categories) ? data.categories.map(String) : [],
85
+ minutes: readingMinutes(body),
86
+ }))
87
+ .sort((a, b) => b.date.valueOf() - a.date.valueOf()),
88
+ contact: {
89
+ name: text(contact.name),
90
+ role: text(contact.role),
91
+ phone: text(contact.phone),
92
+ email: text(contact.email),
93
+ street: text(contact.street),
94
+ city: text(contact.city),
95
+ },
96
+ payment: {
97
+ ...Object.fromEntries(Object.entries(payment).map(([k, v]) => [k, text(v)])),
98
+ bank: text(payment.bank),
99
+ reg: text(payment.reg),
100
+ account: text(payment.account),
101
+ },
102
+ booking: { heading: text(booking.heading), text: text(booking.text) },
103
+ labels: { book: text(booking.book), call: text(booking.call) },
104
+ tagsOffBlog: files
105
+ .filter((f) => f.path.startsWith('src/data/categories/') && f.path.endsWith('.json') && JSON.parse(f.text).blogCategory === false)
106
+ .map((f) => f.path.slice('src/data/categories/'.length, -'.json'.length)),
107
+ apps: Object.fromEntries(
108
+ files
109
+ .filter((f) => f.path.startsWith(`${config.apps.settings}/`) && f.path.endsWith('.json'))
110
+ .map((f) => [f.path.slice(config.apps.settings.length + 1, -'.json'.length), json(f.path)]),
111
+ ),
112
+ installed: ((json(config.apps.installed).installed ?? []) as unknown[]).map(String),
113
+ cookies: files
114
+ .filter((f) => f.path.startsWith(`${config.cookieList}/`) && f.path.endsWith('.json'))
115
+ .map((f) => json(f.path))
116
+ .map((c) => ({
117
+ name: text(c.name),
118
+ provider: text(c.provider),
119
+ purpose: text(c.purpose) || undefined,
120
+ lasts: text(c.lasts) || undefined,
121
+ category: categoryOf(c),
122
+ })),
123
+ buttons: { booking: { text: text(booking.book) }, phone: { text: text(booking.call), after: text(contact.phone) } },
124
+ // As the file has them now, each text falling back on the site's (a text not in the file yet).
125
+ blocks: Object.fromEntries(
126
+ Object.entries(blockTexts).map(([block, texts]) => [block, { ...texts, ...(json(config.blockTexts)[block] ?? {}) }]),
127
+ ) as BlockTexts,
128
+ };
129
+ }
@@ -1,106 +1,106 @@
1
- // What the editor's standard blocks (packages/editor/src/standard/) take from the site on the site, as
2
- // `@site/standard` (StandardSite in packages/editor/src/standard/site.ts): only their load.ts and the
3
- // site's own pages that draw the same parts import it, never the editor, so it reads the content
4
- // (astro:content) and uses the site's components.
5
- import type { ListedPost, StandardSite } from '../src/standard/site';
6
- import {
7
- categoryName,
8
- displayTitle,
9
- getCategories,
10
- getPages,
11
- getPosts,
12
- openingText,
13
- pageHeading,
14
- postPath,
15
- postsFor,
16
- testimonialId,
17
- type Page,
18
- type Post,
19
- } from '../site/content';
20
- import { allPostsCategory, allPostsLink } from '../site/home';
21
- import { responsive } from '../site/images.mjs';
22
- import { readingMinutes } from '../site/format';
23
- import { testimonials, testimonialsPath } from '../site/testimonials';
24
- import { cookieList } from '../site/cookieList';
25
- import { PREVIEW } from '../site/noindex.mjs';
26
- import { blockTexts, nav, site } from '../site/site';
27
- import { popups } from '../site/popups';
28
- import { opensOf } from '@site/opens';
29
-
30
- // A post as "Blogindlæg" shows it.
31
- const listedPost = (p: Post): ListedPost => ({
32
- href: postPath(p),
33
- title: p.data.title,
34
- description: p.data.description,
35
- image: p.data.image,
36
- imageAlt: p.data.imageDecorative ? undefined : p.data.imageAlt,
37
- date: p.data.date.toISOString(),
38
- minutes: readingMinutes(p.body),
39
- });
40
-
41
- let pages: Promise<Map<string, Page>> | undefined;
42
- let tagPages: Promise<Set<string>> | undefined;
43
- const byPath = () => (pages ??= getPages().then((all) => new Map(all.map((p) => [p.data.path, p]))));
44
-
45
- export const standard: StandardSite = {
46
- texts: blockTexts,
47
- // A new version of a page (/ny/…) shows the openings of the new versions of the pages it links to.
48
- async pageOpening(href, preview) {
49
- const all = await byPath();
50
- const page = all.get(href);
51
- if (!page) return undefined;
52
- return openingText(((preview && all.get(PREVIEW + href.slice(1))) || page).body);
53
- },
54
- // Its heading; a page built in code (such as /kontakt/) by its name in the menu.
55
- async pageName(href) {
56
- const page = (await byPath()).get(href);
57
- return page ? pageHeading(page) : (nav.flatMap((n) => [n, ...(n.children ?? [])]).find((n) => n.href === href)?.label ?? href);
58
- },
59
- // Its title, as in the menu and the lists of pages; a page built in code by its name in the menu.
60
- async pageTitle(href) {
61
- const page = (await byPath()).get(href);
62
- return page ? displayTitle(page.data.title) : nav.flatMap((n) => [n, ...(n.children ?? [])]).find((n) => n.href === href)?.label;
63
- },
64
- // "Book en tid" opens the booking sheet on the page (`data-open="booking"`, the app Calendly's), and
65
- // goes to the booking page without one there; "Ring" has the number after its text.
66
- buttons: {
67
- booking: { href: site.bookingPath, text: site.labels.book, open: 'booking' },
68
- phone: { href: site.phoneHref, text: site.labels.call, after: site.phone },
69
- },
70
- // "Åbn promovering": a promotion turned on that a button can open (opens.ts). One that stands for a target does
71
- // what it does (the booking sheet: "Book en tid"); a pop-up opens itself (`data-open="promotion:<file name>"`,
72
- // Popup.astro), with its heading as the text.
73
- picked(target, value) {
74
- const promotion = target === 'promotion' ? popups.find((p) => p.slug === value) : undefined;
75
- const opens = promotion && opensOf(promotion.type);
76
- if (!opens) return undefined;
77
- if (opens.as) return this.buttons[opens.as];
78
- return { href: `#${value}`, text: promotion.heading, open: `promotion:${value}` };
79
- },
80
- cookies: cookieList,
81
- testimonials: {
82
- list: testimonials,
83
- page: testimonialsPath,
84
- anchor: testimonialId,
85
- // Only a tag with posts has a page (/blog/kategori/<slug>/).
86
- async tag(slug) {
87
- tagPages ??= getCategories().then((all) => new Set(all.map((c) => c.slug)));
88
- return { name: categoryName(slug), href: (await tagPages).has(slug) ? `/blog/kategori/${slug}/` : undefined };
89
- },
90
- },
91
- posts: {
92
- async choose(choice, count) {
93
- const { posts, random } = await postsFor(choice as Parameters<typeof postsFor>[0], count);
94
- return { posts: posts.map(listedPost), random };
95
- },
96
- async list(categories) {
97
- return (await getPosts()).filter((p) => !categories.length || p.data.categories.some((c) => categories.includes(c))).map(listedPost);
98
- },
99
- // A tag's page when the posts are from one blog tag (or one is picked for the link), else the blog.
100
- all(choice) {
101
- const tag = allPostsCategory(choice);
102
- return { href: allPostsLink(choice), tag: tag ? categoryName(tag) : undefined };
103
- },
104
- image: responsive,
105
- },
106
- };
1
+ // What the editor's standard blocks (packages/editor/src/standard/) take from the site on the site, as
2
+ // `@site/standard` (StandardSite in packages/editor/src/standard/site.ts): only their load.ts and the
3
+ // site's own pages that draw the same parts import it, never the editor, so it reads the content
4
+ // (astro:content) and uses the site's components.
5
+ import type { ListedPost, StandardSite } from '../src/standard/site';
6
+ import {
7
+ categoryName,
8
+ displayTitle,
9
+ getCategories,
10
+ getPages,
11
+ getPosts,
12
+ openingText,
13
+ pageHeading,
14
+ postPath,
15
+ postsFor,
16
+ testimonialId,
17
+ type Page,
18
+ type Post,
19
+ } from '../site/content';
20
+ import { allPostsCategory, allPostsLink } from '../site/home';
21
+ import { responsive } from '../site/images.mjs';
22
+ import { readingMinutes } from '../site/format';
23
+ import { testimonials, testimonialsPath } from '../site/testimonials';
24
+ import { cookieList } from '../site/cookieList';
25
+ import { PREVIEW } from '../site/noindex.mjs';
26
+ import { blockTexts, nav, site } from '../site/site';
27
+ import { popups } from '../site/popups';
28
+ import { opensOf } from '@site/opens';
29
+
30
+ // A post as "Blogindlæg" shows it.
31
+ const listedPost = (p: Post): ListedPost => ({
32
+ href: postPath(p),
33
+ title: p.data.title,
34
+ description: p.data.description,
35
+ image: p.data.image,
36
+ imageAlt: p.data.imageDecorative ? undefined : p.data.imageAlt,
37
+ date: p.data.date.toISOString(),
38
+ minutes: readingMinutes(p.body),
39
+ });
40
+
41
+ let pages: Promise<Map<string, Page>> | undefined;
42
+ let tagPages: Promise<Set<string>> | undefined;
43
+ const byPath = () => (pages ??= getPages().then((all) => new Map(all.map((p) => [p.data.path, p]))));
44
+
45
+ export const standard: StandardSite = {
46
+ texts: blockTexts,
47
+ // A new version of a page (/ny/…) shows the openings of the new versions of the pages it links to.
48
+ async pageOpening(href, preview) {
49
+ const all = await byPath();
50
+ const page = all.get(href);
51
+ if (!page) return undefined;
52
+ return openingText(((preview && all.get(PREVIEW + href.slice(1))) || page).body);
53
+ },
54
+ // Its heading; a page built in code (such as /kontakt/) by its name in the menu.
55
+ async pageName(href) {
56
+ const page = (await byPath()).get(href);
57
+ return page ? pageHeading(page) : (nav.flatMap((n) => [n, ...(n.children ?? [])]).find((n) => n.href === href)?.label ?? href);
58
+ },
59
+ // Its title, as in the menu and the lists of pages; a page built in code by its name in the menu.
60
+ async pageTitle(href) {
61
+ const page = (await byPath()).get(href);
62
+ return page ? displayTitle(page.data.title) : nav.flatMap((n) => [n, ...(n.children ?? [])]).find((n) => n.href === href)?.label;
63
+ },
64
+ // "Book en tid" opens the booking sheet on the page (`data-open="booking"`, the app Calendly's), and
65
+ // goes to the booking page without one there; "Ring" has the number after its text.
66
+ buttons: {
67
+ booking: { href: site.bookingPath, text: site.labels.book, open: 'booking' },
68
+ phone: { href: site.phoneHref, text: site.labels.call, after: site.phone },
69
+ },
70
+ // "Åbn promovering": a promotion turned on that a button can open (opens.ts). One that stands for a target does
71
+ // what it does (the booking sheet: "Book en tid"); a pop-up opens itself (`data-open="promotion:<file name>"`,
72
+ // Popup.astro), with its heading as the text.
73
+ picked(target, value) {
74
+ const promotion = target === 'promotion' ? popups.find((p) => p.slug === value) : undefined;
75
+ const opens = promotion && opensOf(promotion.type);
76
+ if (!opens) return undefined;
77
+ if (opens.as) return this.buttons[opens.as];
78
+ return { href: `#${value}`, text: promotion.heading, open: `promotion:${value}` };
79
+ },
80
+ cookies: cookieList,
81
+ testimonials: {
82
+ list: testimonials,
83
+ page: testimonialsPath,
84
+ anchor: testimonialId,
85
+ // Only a tag with posts has a page (/blog/kategori/<slug>/).
86
+ async tag(slug) {
87
+ tagPages ??= getCategories().then((all) => new Set(all.map((c) => c.slug)));
88
+ return { name: categoryName(slug), href: (await tagPages).has(slug) ? `/blog/kategori/${slug}/` : undefined };
89
+ },
90
+ },
91
+ posts: {
92
+ async choose(choice, count) {
93
+ const { posts, random } = await postsFor(choice as Parameters<typeof postsFor>[0], count);
94
+ return { posts: posts.map(listedPost), random };
95
+ },
96
+ async list(categories) {
97
+ return (await getPosts()).filter((p) => !categories.length || p.data.categories.some((c) => categories.includes(c))).map(listedPost);
98
+ },
99
+ // A tag's page when the posts are from one blog tag (or one is picked for the link), else the blog.
100
+ all(choice) {
101
+ const tag = allPostsCategory(choice);
102
+ return { href: allPostsLink(choice), tag: tag ? categoryName(tag) : undefined };
103
+ },
104
+ image: responsive,
105
+ },
106
+ };