@morphemecms/cms 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1106) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -3
  3. package/astro.d.mts +2 -0
  4. package/astro.mjs +162 -0
  5. package/bin/morpheme.mjs +38 -0
  6. package/client.d.ts +10 -0
  7. package/defaults/blockTexts.ts +33 -0
  8. package/defaults/collections.ts +774 -0
  9. package/defaults/colors.ts +125 -0
  10. package/defaults/company.ts +20 -0
  11. package/defaults/editor.ts +178 -0
  12. package/defaults/internalLinks.ts +30 -0
  13. package/defaults/opens.ts +18 -0
  14. package/defaults/popup.tsx +93 -0
  15. package/defaults/privacy.ts +79 -0
  16. package/defaults/rules.ts +450 -0
  17. package/defaults/schema.ts +16 -0
  18. package/defaults/sitedata.ts +129 -0
  19. package/defaults/standard.ts +106 -0
  20. package/defaults/standardPages.ts +87 -0
  21. package/defaults/texts.ts +481 -0
  22. package/demo/README.md +26 -0
  23. package/demo/public/apple-touch-icon.png +0 -0
  24. package/demo/public/editor/apple-touch-icon.png +0 -0
  25. package/demo/public/editor/icon-192.png +0 -0
  26. package/demo/public/editor/icon-512.png +0 -0
  27. package/demo/public/editor/icon-maskable-512.png +0 -0
  28. package/demo/public/favicon.ico +0 -0
  29. package/demo/public/favicon.svg +1 -0
  30. package/demo/public/images/uploads/2026/10/andromeda.webp +0 -0
  31. package/demo/public/images/uploads/2026/10/earth-from-space.webp +0 -0
  32. package/demo/public/images/uploads/2026/10/editor-blog.webp +0 -0
  33. package/demo/public/images/uploads/2026/10/editor-colors.webp +0 -0
  34. package/demo/public/images/uploads/2026/10/editor-home.webp +0 -0
  35. package/demo/public/images/uploads/2026/10/editor-page.webp +0 -0
  36. package/demo/public/images/uploads/2026/10/editor-pages.webp +0 -0
  37. package/demo/public/images/uploads/2026/10/editor-seo.webp +0 -0
  38. package/demo/public/images/uploads/2026/10/editor-start.webp +0 -0
  39. package/demo/public/images/uploads/2026/10/editor-themes.webp +0 -0
  40. package/demo/public/images/uploads/2026/10/moon.webp +0 -0
  41. package/demo/public/images/uploads/2026/10/saturn.webp +0 -0
  42. package/demo/public/logo.svg +1 -0
  43. package/demo/src/content/blog/build-a-page-from-blocks.md +19 -0
  44. package/demo/src/content/blog/colors-everyone-can-read.md +19 -0
  45. package/demo/src/content/blog/edit-your-website-from-your-phone.md +21 -0
  46. package/demo/src/content/blog/every-save-is-a-version.md +21 -0
  47. package/demo/src/content/blog/schedule-a-post.md +17 -0
  48. package/demo/src/content/blog/secure-from-day-one.md +17 -0
  49. package/demo/src/content/blog/seo-without-the-guesswork.md +23 -0
  50. package/demo/src/content/blog/switch-themes-without-losing-anything.md +23 -0
  51. package/demo/src/content/blog/the-app-store.md +21 -0
  52. package/demo/src/content/pages/about.md +22 -0
  53. package/demo/src/content/pages/app-store.md +30 -0
  54. package/demo/src/content/pages/blocks.md +98 -0
  55. package/demo/src/content/pages/blog-page.md +11 -0
  56. package/demo/src/content/pages/contact.md +16 -0
  57. package/demo/src/content/pages/get-started.md +20 -0
  58. package/demo/src/content/pages/home.md +26 -0
  59. package/demo/src/content/pages/page-not-found.md +11 -0
  60. package/demo/src/content/pages/privacy-policy.md +24 -0
  61. package/demo/src/data/blocks.json +25 -0
  62. package/demo/src/data/booking.json +6 -0
  63. package/demo/src/data/categories/apps.json +6 -0
  64. package/demo/src/data/categories/design.json +6 -0
  65. package/demo/src/data/categories/editing.json +6 -0
  66. package/demo/src/data/categories/security.json +6 -0
  67. package/demo/src/data/categories/seo.json +6 -0
  68. package/demo/src/data/colors.json +75 -0
  69. package/demo/src/data/contact.json +8 -0
  70. package/demo/src/data/cookies.json +21 -0
  71. package/demo/src/data/footer.json +27 -0
  72. package/demo/src/data/menu.json +35 -0
  73. package/demo/src/data/mobile-menu.json +25 -0
  74. package/demo/src/data/popups/booking-bar.json +13 -0
  75. package/demo/src/data/popups/try-the-editor.json +16 -0
  76. package/demo/src/data/standard-pages.json +8 -0
  77. package/demo/src/data/testimonials/sample-bakery.json +10 -0
  78. package/demo/src/data/testimonials/sample-clinic.json +10 -0
  79. package/demo/src/data/testimonials/sample-studio.json +10 -0
  80. package/demo/src/site/colors.ts +11 -0
  81. package/demo/src/site/config.ts +19 -0
  82. package/icons/lucide/LICENSE +43 -0
  83. package/icons/lucide/LICENSE-material-design-icons +20 -0
  84. package/icons/lucide/address-book.svg +1 -0
  85. package/icons/lucide/app-window.svg +1 -0
  86. package/icons/lucide/arrow-counter-clockwise.svg +1 -0
  87. package/icons/lucide/arrow-down.svg +1 -0
  88. package/icons/lucide/arrow-left.svg +1 -0
  89. package/icons/lucide/arrow-right.svg +1 -0
  90. package/icons/lucide/arrow-square-out.svg +1 -0
  91. package/icons/lucide/arrow-u-up-left.svg +1 -0
  92. package/icons/lucide/arrow-u-up-right.svg +1 -0
  93. package/icons/lucide/arrow-up-right.svg +1 -0
  94. package/icons/lucide/arrow-up.svg +1 -0
  95. package/icons/lucide/arrows-down-up.svg +1 -0
  96. package/icons/lucide/arrows-in-line-horizontal.svg +1 -0
  97. package/icons/lucide/arrows-out-line-horizontal.svg +1 -0
  98. package/icons/lucide/article.svg +1 -0
  99. package/icons/lucide/bank.svg +1 -0
  100. package/icons/lucide/bell.svg +1 -0
  101. package/icons/lucide/bicycle.svg +1 -0
  102. package/icons/lucide/binoculars.svg +1 -0
  103. package/icons/lucide/book-open-text.svg +1 -0
  104. package/icons/lucide/book-open.svg +1 -0
  105. package/icons/lucide/browser.svg +1 -0
  106. package/icons/lucide/buildings.svg +1 -0
  107. package/icons/lucide/bus.svg +1 -0
  108. package/icons/lucide/calendar-blank.svg +1 -0
  109. package/icons/lucide/calendar-check.svg +1 -0
  110. package/icons/lucide/car.svg +1 -0
  111. package/icons/lucide/cards.svg +1 -0
  112. package/icons/lucide/caret-down.svg +1 -0
  113. package/icons/lucide/caret-left.svg +1 -0
  114. package/icons/lucide/caret-right.svg +1 -0
  115. package/icons/lucide/caret-up.svg +1 -0
  116. package/icons/lucide/certificate.svg +1 -0
  117. package/icons/lucide/chart-line-up.svg +1 -0
  118. package/icons/lucide/chats.svg +1 -0
  119. package/icons/lucide/check-circle.svg +1 -0
  120. package/icons/lucide/check.svg +1 -0
  121. package/icons/lucide/circle-half.svg +1 -0
  122. package/icons/lucide/circle.svg +1 -0
  123. package/icons/lucide/clock-counter-clockwise.svg +1 -0
  124. package/icons/lucide/clock.svg +1 -0
  125. package/icons/lucide/code.svg +1 -0
  126. package/icons/lucide/coffee.svg +1 -0
  127. package/icons/lucide/columns.svg +1 -0
  128. package/icons/lucide/cookie.svg +1 -0
  129. package/icons/lucide/copy.svg +1 -0
  130. package/icons/lucide/credit-card.svg +1 -0
  131. package/icons/lucide/currency-circle-dollar.svg +1 -0
  132. package/icons/lucide/cursor-click.svg +1 -0
  133. package/icons/lucide/database.svg +1 -0
  134. package/icons/lucide/desktop.svg +1 -0
  135. package/icons/lucide/device-mobile.svg +1 -0
  136. package/icons/lucide/door-open.svg +1 -0
  137. package/icons/lucide/download-simple.svg +1 -0
  138. package/icons/lucide/envelope-simple.svg +1 -0
  139. package/icons/lucide/eye-slash.svg +1 -0
  140. package/icons/lucide/eye.svg +1 -0
  141. package/icons/lucide/file-pdf.svg +1 -0
  142. package/icons/lucide/file-text.svg +1 -0
  143. package/icons/lucide/file-video.svg +1 -0
  144. package/icons/lucide/file-zip.svg +1 -0
  145. package/icons/lucide/flower-lotus.svg +1 -0
  146. package/icons/lucide/folder-simple.svg +1 -0
  147. package/icons/lucide/funnel.svg +1 -0
  148. package/icons/lucide/gauge.svg +1 -0
  149. package/icons/lucide/gear.svg +1 -0
  150. package/icons/lucide/github-logo.svg +1 -0
  151. package/icons/lucide/globe.svg +1 -0
  152. package/icons/lucide/google-logo.svg +1 -0
  153. package/icons/lucide/graduation-cap.svg +1 -0
  154. package/icons/lucide/hammer.svg +1 -0
  155. package/icons/lucide/hand-heart.svg +1 -0
  156. package/icons/lucide/handshake.svg +1 -0
  157. package/icons/lucide/hard-drives.svg +1 -0
  158. package/icons/lucide/heart.svg +1 -0
  159. package/icons/lucide/house.svg +1 -0
  160. package/icons/lucide/image-square.svg +1 -0
  161. package/icons/lucide/image.svg +1 -0
  162. package/icons/lucide/info.svg +1 -0
  163. package/icons/lucide/keyboard.svg +1 -0
  164. package/icons/lucide/leaf.svg +1 -0
  165. package/icons/lucide/lifebuoy.svg +1 -0
  166. package/icons/lucide/lightbulb.svg +1 -0
  167. package/icons/lucide/link-break.svg +1 -0
  168. package/icons/lucide/link-simple.svg +1 -0
  169. package/icons/lucide/list-bullets.svg +1 -0
  170. package/icons/lucide/list-checks.svg +1 -0
  171. package/icons/lucide/list-numbers.svg +1 -0
  172. package/icons/lucide/list.svg +1 -0
  173. package/icons/lucide/lock-simple-open.svg +1 -0
  174. package/icons/lucide/lock-simple.svg +1 -0
  175. package/icons/lucide/magnifying-glass.svg +1 -0
  176. package/icons/lucide/map-pin.svg +1 -0
  177. package/icons/lucide/map-trifold.svg +1 -0
  178. package/icons/lucide/medal.svg +1 -0
  179. package/icons/lucide/megaphone.svg +1 -0
  180. package/icons/lucide/minus.svg +1 -0
  181. package/icons/lucide/moon.svg +1 -0
  182. package/icons/lucide/newspaper.svg +1 -0
  183. package/icons/lucide/pack.json +23 -0
  184. package/icons/lucide/paint-brush-broad.svg +1 -0
  185. package/icons/lucide/palette.svg +1 -0
  186. package/icons/lucide/paper-plane-tilt.svg +1 -0
  187. package/icons/lucide/pencil-simple.svg +1 -0
  188. package/icons/lucide/phone.svg +1 -0
  189. package/icons/lucide/play-fill.svg +1 -0
  190. package/icons/lucide/plus.svg +1 -0
  191. package/icons/lucide/prohibit.svg +1 -0
  192. package/icons/lucide/puzzle-piece.svg +1 -0
  193. package/icons/lucide/question.svg +1 -0
  194. package/icons/lucide/quotes.svg +1 -0
  195. package/icons/lucide/rows.svg +1 -0
  196. package/icons/lucide/ruler.svg +1 -0
  197. package/icons/lucide/scan.svg +1 -0
  198. package/icons/lucide/shapes.svg +1 -0
  199. package/icons/lucide/share-network.svg +1 -0
  200. package/icons/lucide/shield-check.svg +1 -0
  201. package/icons/lucide/sidebar-simple.svg +1 -0
  202. package/icons/lucide/sign-out.svg +1 -0
  203. package/icons/lucide/signpost.svg +1 -0
  204. package/icons/lucide/sliders-horizontal.svg +1 -0
  205. package/icons/lucide/smiley.svg +1 -0
  206. package/icons/lucide/sparkle.svg +1 -0
  207. package/icons/lucide/square-half-bottom.svg +1 -0
  208. package/icons/lucide/square.svg +1 -0
  209. package/icons/lucide/squares-four.svg +1 -0
  210. package/icons/lucide/sticker.svg +1 -0
  211. package/icons/lucide/storefront.svg +1 -0
  212. package/icons/lucide/sun.svg +1 -0
  213. package/icons/lucide/swatches.svg +1 -0
  214. package/icons/lucide/tag.svg +1 -0
  215. package/icons/lucide/text-aa.svg +1 -0
  216. package/icons/lucide/text-align-left.svg +1 -0
  217. package/icons/lucide/text-b.svg +1 -0
  218. package/icons/lucide/text-h-one.svg +1 -0
  219. package/icons/lucide/text-h-three.svg +1 -0
  220. package/icons/lucide/text-h-two.svg +1 -0
  221. package/icons/lucide/text-italic.svg +1 -0
  222. package/icons/lucide/text-t.svg +1 -0
  223. package/icons/lucide/ticket.svg +1 -0
  224. package/icons/lucide/toggle-right.svg +1 -0
  225. package/icons/lucide/train.svg +1 -0
  226. package/icons/lucide/trash.svg +1 -0
  227. package/icons/lucide/upload-simple.svg +1 -0
  228. package/icons/lucide/user-circle.svg +1 -0
  229. package/icons/lucide/user.svg +1 -0
  230. package/icons/lucide/users-three.svg +1 -0
  231. package/icons/lucide/users.svg +1 -0
  232. package/icons/lucide/video-camera.svg +1 -0
  233. package/icons/lucide/warning-circle.svg +1 -0
  234. package/icons/lucide/warning.svg +1 -0
  235. package/icons/lucide/wave-sine.svg +1 -0
  236. package/icons/lucide/wheelchair.svg +1 -0
  237. package/icons/lucide/wrench.svg +1 -0
  238. package/icons/lucide/x.svg +1 -0
  239. package/icons/material-symbols/LICENSE +201 -0
  240. package/icons/material-symbols/LICENSE-material-design-icons +20 -0
  241. package/icons/material-symbols/address-book.svg +1 -0
  242. package/icons/material-symbols/app-window.svg +1 -0
  243. package/icons/material-symbols/arrow-counter-clockwise.svg +1 -0
  244. package/icons/material-symbols/arrow-down.svg +1 -0
  245. package/icons/material-symbols/arrow-left.svg +1 -0
  246. package/icons/material-symbols/arrow-right.svg +1 -0
  247. package/icons/material-symbols/arrow-square-out.svg +1 -0
  248. package/icons/material-symbols/arrow-u-up-left.svg +1 -0
  249. package/icons/material-symbols/arrow-u-up-right.svg +1 -0
  250. package/icons/material-symbols/arrow-up-right.svg +1 -0
  251. package/icons/material-symbols/arrow-up.svg +1 -0
  252. package/icons/material-symbols/arrows-down-up.svg +1 -0
  253. package/icons/material-symbols/arrows-in-line-horizontal.svg +1 -0
  254. package/icons/material-symbols/arrows-out-line-horizontal.svg +1 -0
  255. package/icons/material-symbols/article.svg +1 -0
  256. package/icons/material-symbols/bank.svg +1 -0
  257. package/icons/material-symbols/bell.svg +1 -0
  258. package/icons/material-symbols/bicycle.svg +1 -0
  259. package/icons/material-symbols/binoculars.svg +1 -0
  260. package/icons/material-symbols/book-open-text.svg +1 -0
  261. package/icons/material-symbols/book-open.svg +1 -0
  262. package/icons/material-symbols/browser.svg +1 -0
  263. package/icons/material-symbols/buildings.svg +1 -0
  264. package/icons/material-symbols/bus.svg +1 -0
  265. package/icons/material-symbols/calendar-blank.svg +1 -0
  266. package/icons/material-symbols/calendar-check.svg +1 -0
  267. package/icons/material-symbols/car.svg +1 -0
  268. package/icons/material-symbols/cards.svg +1 -0
  269. package/icons/material-symbols/caret-down.svg +1 -0
  270. package/icons/material-symbols/caret-left.svg +1 -0
  271. package/icons/material-symbols/caret-right.svg +1 -0
  272. package/icons/material-symbols/caret-up.svg +1 -0
  273. package/icons/material-symbols/certificate.svg +1 -0
  274. package/icons/material-symbols/chart-line-up.svg +1 -0
  275. package/icons/material-symbols/chats.svg +1 -0
  276. package/icons/material-symbols/check-circle.svg +1 -0
  277. package/icons/material-symbols/check.svg +1 -0
  278. package/icons/material-symbols/circle-half.svg +1 -0
  279. package/icons/material-symbols/circle.svg +1 -0
  280. package/icons/material-symbols/clock-counter-clockwise.svg +1 -0
  281. package/icons/material-symbols/clock.svg +1 -0
  282. package/icons/material-symbols/code.svg +1 -0
  283. package/icons/material-symbols/coffee.svg +1 -0
  284. package/icons/material-symbols/columns.svg +1 -0
  285. package/icons/material-symbols/cookie.svg +1 -0
  286. package/icons/material-symbols/copy.svg +1 -0
  287. package/icons/material-symbols/credit-card.svg +1 -0
  288. package/icons/material-symbols/currency-circle-dollar.svg +1 -0
  289. package/icons/material-symbols/cursor-click.svg +1 -0
  290. package/icons/material-symbols/database.svg +1 -0
  291. package/icons/material-symbols/desktop.svg +1 -0
  292. package/icons/material-symbols/device-mobile.svg +1 -0
  293. package/icons/material-symbols/door-open.svg +1 -0
  294. package/icons/material-symbols/download-simple.svg +1 -0
  295. package/icons/material-symbols/envelope-simple.svg +1 -0
  296. package/icons/material-symbols/eye-slash.svg +1 -0
  297. package/icons/material-symbols/eye.svg +1 -0
  298. package/icons/material-symbols/file-pdf.svg +1 -0
  299. package/icons/material-symbols/file-text.svg +1 -0
  300. package/icons/material-symbols/file-video.svg +1 -0
  301. package/icons/material-symbols/file-zip.svg +1 -0
  302. package/icons/material-symbols/flower-lotus.svg +1 -0
  303. package/icons/material-symbols/folder-simple.svg +1 -0
  304. package/icons/material-symbols/funnel.svg +1 -0
  305. package/icons/material-symbols/gauge.svg +1 -0
  306. package/icons/material-symbols/gear.svg +1 -0
  307. package/icons/material-symbols/github-logo.svg +1 -0
  308. package/icons/material-symbols/globe.svg +1 -0
  309. package/icons/material-symbols/google-logo.svg +1 -0
  310. package/icons/material-symbols/graduation-cap.svg +1 -0
  311. package/icons/material-symbols/hammer.svg +1 -0
  312. package/icons/material-symbols/hand-heart.svg +1 -0
  313. package/icons/material-symbols/handshake.svg +1 -0
  314. package/icons/material-symbols/hard-drives.svg +1 -0
  315. package/icons/material-symbols/heart.svg +1 -0
  316. package/icons/material-symbols/house.svg +1 -0
  317. package/icons/material-symbols/image-square.svg +1 -0
  318. package/icons/material-symbols/image.svg +1 -0
  319. package/icons/material-symbols/info.svg +1 -0
  320. package/icons/material-symbols/keyboard.svg +1 -0
  321. package/icons/material-symbols/leaf.svg +1 -0
  322. package/icons/material-symbols/lifebuoy.svg +1 -0
  323. package/icons/material-symbols/lightbulb.svg +1 -0
  324. package/icons/material-symbols/link-break.svg +1 -0
  325. package/icons/material-symbols/link-simple.svg +1 -0
  326. package/icons/material-symbols/list-bullets.svg +1 -0
  327. package/icons/material-symbols/list-checks.svg +1 -0
  328. package/icons/material-symbols/list-numbers.svg +1 -0
  329. package/icons/material-symbols/list.svg +1 -0
  330. package/icons/material-symbols/lock-simple-open.svg +1 -0
  331. package/icons/material-symbols/lock-simple.svg +1 -0
  332. package/icons/material-symbols/magnifying-glass.svg +1 -0
  333. package/icons/material-symbols/map-pin.svg +1 -0
  334. package/icons/material-symbols/map-trifold.svg +1 -0
  335. package/icons/material-symbols/medal.svg +1 -0
  336. package/icons/material-symbols/megaphone.svg +1 -0
  337. package/icons/material-symbols/minus.svg +1 -0
  338. package/icons/material-symbols/moon.svg +1 -0
  339. package/icons/material-symbols/newspaper.svg +1 -0
  340. package/icons/material-symbols/pack.json +29 -0
  341. package/icons/material-symbols/paint-brush-broad.svg +1 -0
  342. package/icons/material-symbols/palette.svg +1 -0
  343. package/icons/material-symbols/paper-plane-tilt.svg +1 -0
  344. package/icons/material-symbols/pencil-simple.svg +1 -0
  345. package/icons/material-symbols/phone.svg +1 -0
  346. package/icons/material-symbols/play-fill.svg +1 -0
  347. package/icons/material-symbols/plus.svg +1 -0
  348. package/icons/material-symbols/prohibit.svg +1 -0
  349. package/icons/material-symbols/puzzle-piece.svg +1 -0
  350. package/icons/material-symbols/question.svg +1 -0
  351. package/icons/material-symbols/quotes.svg +1 -0
  352. package/icons/material-symbols/rows.svg +1 -0
  353. package/icons/material-symbols/ruler.svg +1 -0
  354. package/icons/material-symbols/scan.svg +1 -0
  355. package/icons/material-symbols/shapes.svg +1 -0
  356. package/icons/material-symbols/share-network.svg +1 -0
  357. package/icons/material-symbols/shield-check.svg +1 -0
  358. package/icons/material-symbols/sidebar-simple.svg +1 -0
  359. package/icons/material-symbols/sign-out.svg +1 -0
  360. package/icons/material-symbols/signpost.svg +1 -0
  361. package/icons/material-symbols/sliders-horizontal.svg +1 -0
  362. package/icons/material-symbols/smiley.svg +1 -0
  363. package/icons/material-symbols/sparkle.svg +1 -0
  364. package/icons/material-symbols/square-half-bottom.svg +1 -0
  365. package/icons/material-symbols/square.svg +1 -0
  366. package/icons/material-symbols/squares-four.svg +1 -0
  367. package/icons/material-symbols/sticker.svg +1 -0
  368. package/icons/material-symbols/storefront.svg +1 -0
  369. package/icons/material-symbols/sun.svg +1 -0
  370. package/icons/material-symbols/swatches.svg +1 -0
  371. package/icons/material-symbols/tag.svg +1 -0
  372. package/icons/material-symbols/text-aa.svg +1 -0
  373. package/icons/material-symbols/text-align-left.svg +1 -0
  374. package/icons/material-symbols/text-b.svg +1 -0
  375. package/icons/material-symbols/text-h-one.svg +1 -0
  376. package/icons/material-symbols/text-h-three.svg +1 -0
  377. package/icons/material-symbols/text-h-two.svg +1 -0
  378. package/icons/material-symbols/text-italic.svg +1 -0
  379. package/icons/material-symbols/text-t.svg +1 -0
  380. package/icons/material-symbols/ticket.svg +1 -0
  381. package/icons/material-symbols/toggle-right.svg +1 -0
  382. package/icons/material-symbols/train.svg +1 -0
  383. package/icons/material-symbols/trash.svg +1 -0
  384. package/icons/material-symbols/upload-simple.svg +1 -0
  385. package/icons/material-symbols/user-circle.svg +1 -0
  386. package/icons/material-symbols/user.svg +1 -0
  387. package/icons/material-symbols/users-three.svg +1 -0
  388. package/icons/material-symbols/users.svg +1 -0
  389. package/icons/material-symbols/video-camera.svg +1 -0
  390. package/icons/material-symbols/warning-circle.svg +1 -0
  391. package/icons/material-symbols/warning.svg +1 -0
  392. package/icons/material-symbols/wave-sine.svg +1 -0
  393. package/icons/material-symbols/wheelchair.svg +1 -0
  394. package/icons/material-symbols/wrench.svg +1 -0
  395. package/icons/material-symbols/x.svg +1 -0
  396. package/icons/phosphor/LICENSE +21 -0
  397. package/icons/phosphor/address-book.svg +1 -0
  398. package/icons/phosphor/app-window.svg +1 -0
  399. package/icons/phosphor/arrow-counter-clockwise.svg +1 -0
  400. package/icons/phosphor/arrow-down.svg +1 -0
  401. package/icons/phosphor/arrow-left.svg +1 -0
  402. package/icons/phosphor/arrow-right.svg +1 -0
  403. package/icons/phosphor/arrow-square-out.svg +1 -0
  404. package/icons/phosphor/arrow-u-up-left.svg +1 -0
  405. package/icons/phosphor/arrow-u-up-right.svg +1 -0
  406. package/icons/phosphor/arrow-up-right.svg +1 -0
  407. package/icons/phosphor/arrow-up.svg +1 -0
  408. package/icons/phosphor/arrows-down-up.svg +1 -0
  409. package/icons/phosphor/arrows-in-line-horizontal.svg +1 -0
  410. package/icons/phosphor/arrows-out-line-horizontal.svg +1 -0
  411. package/icons/phosphor/article.svg +1 -0
  412. package/icons/phosphor/bank.svg +1 -0
  413. package/icons/phosphor/bell.svg +1 -0
  414. package/icons/phosphor/bicycle.svg +1 -0
  415. package/icons/phosphor/binoculars.svg +1 -0
  416. package/icons/phosphor/book-open-text.svg +1 -0
  417. package/icons/phosphor/book-open.svg +1 -0
  418. package/icons/phosphor/browser.svg +1 -0
  419. package/icons/phosphor/buildings.svg +1 -0
  420. package/icons/phosphor/bus.svg +1 -0
  421. package/icons/phosphor/calendar-blank.svg +1 -0
  422. package/icons/phosphor/calendar-check.svg +1 -0
  423. package/icons/phosphor/car.svg +1 -0
  424. package/icons/phosphor/cards.svg +1 -0
  425. package/icons/phosphor/caret-down.svg +1 -0
  426. package/icons/phosphor/caret-left.svg +1 -0
  427. package/icons/phosphor/caret-right.svg +1 -0
  428. package/icons/phosphor/caret-up.svg +1 -0
  429. package/icons/phosphor/certificate.svg +1 -0
  430. package/icons/phosphor/chart-line-up.svg +1 -0
  431. package/icons/phosphor/chats.svg +1 -0
  432. package/icons/phosphor/check-circle.svg +1 -0
  433. package/icons/phosphor/check.svg +1 -0
  434. package/icons/phosphor/circle-half.svg +1 -0
  435. package/icons/phosphor/circle.svg +1 -0
  436. package/icons/phosphor/clock-counter-clockwise.svg +1 -0
  437. package/icons/phosphor/clock.svg +1 -0
  438. package/icons/phosphor/code.svg +1 -0
  439. package/icons/phosphor/coffee.svg +1 -0
  440. package/icons/phosphor/columns.svg +1 -0
  441. package/icons/phosphor/cookie.svg +1 -0
  442. package/icons/phosphor/copy.svg +1 -0
  443. package/icons/phosphor/credit-card.svg +1 -0
  444. package/icons/phosphor/currency-circle-dollar.svg +1 -0
  445. package/icons/phosphor/cursor-click.svg +1 -0
  446. package/icons/phosphor/database.svg +1 -0
  447. package/icons/phosphor/desktop.svg +1 -0
  448. package/icons/phosphor/device-mobile.svg +1 -0
  449. package/icons/phosphor/door-open.svg +1 -0
  450. package/icons/phosphor/download-simple.svg +1 -0
  451. package/icons/phosphor/envelope-simple.svg +1 -0
  452. package/icons/phosphor/eye-slash.svg +1 -0
  453. package/icons/phosphor/eye.svg +1 -0
  454. package/icons/phosphor/file-pdf.svg +1 -0
  455. package/icons/phosphor/file-text.svg +1 -0
  456. package/icons/phosphor/file-video.svg +1 -0
  457. package/icons/phosphor/file-zip.svg +1 -0
  458. package/icons/phosphor/flower-lotus.svg +1 -0
  459. package/icons/phosphor/folder-simple.svg +1 -0
  460. package/icons/phosphor/funnel.svg +1 -0
  461. package/icons/phosphor/gauge.svg +1 -0
  462. package/icons/phosphor/gear.svg +1 -0
  463. package/icons/phosphor/github-logo.svg +1 -0
  464. package/icons/phosphor/globe.svg +1 -0
  465. package/icons/phosphor/google-logo.svg +1 -0
  466. package/icons/phosphor/graduation-cap.svg +1 -0
  467. package/icons/phosphor/hammer.svg +1 -0
  468. package/icons/phosphor/hand-heart.svg +1 -0
  469. package/icons/phosphor/handshake.svg +1 -0
  470. package/icons/phosphor/hard-drives.svg +1 -0
  471. package/icons/phosphor/heart.svg +1 -0
  472. package/icons/phosphor/house.svg +1 -0
  473. package/icons/phosphor/image-square.svg +1 -0
  474. package/icons/phosphor/image.svg +1 -0
  475. package/icons/phosphor/info.svg +1 -0
  476. package/icons/phosphor/keyboard.svg +1 -0
  477. package/icons/phosphor/leaf.svg +1 -0
  478. package/icons/phosphor/lifebuoy.svg +1 -0
  479. package/icons/phosphor/lightbulb.svg +1 -0
  480. package/icons/phosphor/link-break.svg +1 -0
  481. package/icons/phosphor/link-simple.svg +1 -0
  482. package/icons/phosphor/list-bullets.svg +1 -0
  483. package/icons/phosphor/list-checks.svg +1 -0
  484. package/icons/phosphor/list-numbers.svg +1 -0
  485. package/icons/phosphor/list.svg +1 -0
  486. package/icons/phosphor/lock-simple-open.svg +1 -0
  487. package/icons/phosphor/lock-simple.svg +1 -0
  488. package/icons/phosphor/magnifying-glass.svg +1 -0
  489. package/icons/phosphor/map-pin.svg +1 -0
  490. package/icons/phosphor/map-trifold.svg +1 -0
  491. package/icons/phosphor/medal.svg +1 -0
  492. package/icons/phosphor/megaphone.svg +1 -0
  493. package/icons/phosphor/minus.svg +1 -0
  494. package/icons/phosphor/moon.svg +1 -0
  495. package/icons/phosphor/newspaper.svg +1 -0
  496. package/icons/phosphor/pack.json +8 -0
  497. package/icons/phosphor/paint-brush-broad.svg +1 -0
  498. package/icons/phosphor/palette.svg +1 -0
  499. package/icons/phosphor/paper-plane-tilt.svg +1 -0
  500. package/icons/phosphor/pencil-simple.svg +1 -0
  501. package/icons/phosphor/phone.svg +1 -0
  502. package/icons/phosphor/play-fill.svg +1 -0
  503. package/icons/phosphor/plus.svg +1 -0
  504. package/icons/phosphor/prohibit.svg +1 -0
  505. package/icons/phosphor/puzzle-piece.svg +1 -0
  506. package/icons/phosphor/question.svg +1 -0
  507. package/icons/phosphor/quotes.svg +1 -0
  508. package/icons/phosphor/rows.svg +1 -0
  509. package/icons/phosphor/ruler.svg +1 -0
  510. package/icons/phosphor/scan.svg +1 -0
  511. package/icons/phosphor/shapes.svg +1 -0
  512. package/icons/phosphor/share-network.svg +1 -0
  513. package/icons/phosphor/shield-check.svg +1 -0
  514. package/icons/phosphor/sidebar-simple.svg +1 -0
  515. package/icons/phosphor/sign-out.svg +1 -0
  516. package/icons/phosphor/signpost.svg +1 -0
  517. package/icons/phosphor/sliders-horizontal.svg +1 -0
  518. package/icons/phosphor/smiley.svg +1 -0
  519. package/icons/phosphor/sparkle.svg +1 -0
  520. package/icons/phosphor/square-half-bottom.svg +1 -0
  521. package/icons/phosphor/square.svg +1 -0
  522. package/icons/phosphor/squares-four.svg +1 -0
  523. package/icons/phosphor/sticker.svg +1 -0
  524. package/icons/phosphor/storefront.svg +1 -0
  525. package/icons/phosphor/sun.svg +1 -0
  526. package/icons/phosphor/swatches.svg +1 -0
  527. package/icons/phosphor/tag.svg +1 -0
  528. package/icons/phosphor/text-aa.svg +1 -0
  529. package/icons/phosphor/text-align-left.svg +1 -0
  530. package/icons/phosphor/text-b.svg +1 -0
  531. package/icons/phosphor/text-h-one.svg +1 -0
  532. package/icons/phosphor/text-h-three.svg +1 -0
  533. package/icons/phosphor/text-h-two.svg +1 -0
  534. package/icons/phosphor/text-italic.svg +1 -0
  535. package/icons/phosphor/text-t.svg +1 -0
  536. package/icons/phosphor/ticket.svg +1 -0
  537. package/icons/phosphor/toggle-right.svg +1 -0
  538. package/icons/phosphor/train.svg +1 -0
  539. package/icons/phosphor/trash.svg +1 -0
  540. package/icons/phosphor/upload-simple.svg +1 -0
  541. package/icons/phosphor/user-circle.svg +1 -0
  542. package/icons/phosphor/user.svg +1 -0
  543. package/icons/phosphor/users-three.svg +1 -0
  544. package/icons/phosphor/users.svg +1 -0
  545. package/icons/phosphor/video-camera.svg +1 -0
  546. package/icons/phosphor/warning-circle.svg +1 -0
  547. package/icons/phosphor/warning.svg +1 -0
  548. package/icons/phosphor/wave-sine.svg +1 -0
  549. package/icons/phosphor/wheelchair.svg +1 -0
  550. package/icons/phosphor/wrench.svg +1 -0
  551. package/icons/phosphor/x.svg +1 -0
  552. package/lib/apps.d.mts +28 -0
  553. package/lib/apps.mjs +139 -0
  554. package/lib/blocks.d.mts +23 -0
  555. package/lib/blocks.mjs +90 -0
  556. package/lib/colors.ts +86 -0
  557. package/lib/contactBar.ts +18 -0
  558. package/lib/cookieCategories.d.mts +17 -0
  559. package/lib/cookieCategories.mjs +28 -0
  560. package/lib/crop.d.mts +34 -0
  561. package/lib/crop.mjs +83 -0
  562. package/lib/csp.d.mts +22 -0
  563. package/lib/csp.mjs +130 -0
  564. package/lib/cspSources.d.mts +24 -0
  565. package/lib/cspSources.mjs +60 -0
  566. package/lib/dynamic-colors.ts +426 -0
  567. package/lib/git.d.mts +24 -0
  568. package/lib/git.mjs +64 -0
  569. package/lib/hooks.ts +51 -0
  570. package/lib/inline.ts +20 -0
  571. package/lib/license-texts/Apache-2.0.txt +191 -0
  572. package/lib/license-texts/BSD-2-Clause.txt +24 -0
  573. package/lib/license-texts/BSD-3-Clause.txt +28 -0
  574. package/lib/license-texts/ISC.txt +15 -0
  575. package/lib/license-texts/MIT.txt +21 -0
  576. package/lib/licenses.d.mts +190 -0
  577. package/lib/licenses.mjs +683 -0
  578. package/lib/markdown.ts +42 -0
  579. package/lib/motion-schemes.d.mts +2 -0
  580. package/lib/motion-schemes.mjs +5 -0
  581. package/lib/motion.ts +131 -0
  582. package/lib/notice.d.mts +3 -0
  583. package/lib/notice.mjs +34 -0
  584. package/lib/scheduled.d.mts +15 -0
  585. package/lib/scheduled.mjs +37 -0
  586. package/lib/snackbar.ts +149 -0
  587. package/lib/status.d.mts +7 -0
  588. package/lib/status.mjs +18 -0
  589. package/lib/svg.d.mts +22 -0
  590. package/lib/svg.mjs +231 -0
  591. package/lib/text-colors.d.mts +11 -0
  592. package/lib/text-colors.mjs +43 -0
  593. package/lib/video-id.d.mts +14 -0
  594. package/lib/video-id.mjs +72 -0
  595. package/lib/video.d.mts +20 -0
  596. package/lib/video.mjs +91 -0
  597. package/package.json +131 -6
  598. package/pages/404.astro +10 -0
  599. package/pages/[...slug].astro +51 -0
  600. package/pages/_headers.txt +31 -0
  601. package/pages/blog/index.astro +10 -0
  602. package/pages/blog/kategori/[category].astro +18 -0
  603. package/pages/editor/code-images.json.js +25 -0
  604. package/pages/editor/index.astro +75 -0
  605. package/pages/editor/manifest.webmanifest.js +23 -0
  606. package/pages/editor/sw.js +33 -0
  607. package/pages/editor/sw.js.js +4 -0
  608. package/pages/editor/thumbnails.json.js +21 -0
  609. package/pages/editor/version.json.js +22 -0
  610. package/pages/headers.js +4 -0
  611. package/pages/index.astro +10 -0
  612. package/pages/ny.astro +6 -0
  613. package/pages/robots.txt.js +3 -0
  614. package/pages/rss.xml.js +20 -0
  615. package/scripts/app-screenshots.mjs +164 -0
  616. package/scripts/app-workers.mjs +6 -0
  617. package/scripts/bin.mjs +12 -0
  618. package/scripts/built-site.mjs +99 -0
  619. package/scripts/check-consent.mjs +113 -0
  620. package/scripts/check-content.mjs +149 -0
  621. package/scripts/check-demo.mjs +24 -0
  622. package/scripts/check-themes.mjs +45 -0
  623. package/scripts/check-worker.mjs +569 -0
  624. package/scripts/compare-html.mjs +81 -0
  625. package/scripts/demo-site.mjs +42 -0
  626. package/scripts/editor-icons.mjs +56 -0
  627. package/scripts/editor-roundtrip.mjs +134 -0
  628. package/scripts/editor-screens.mjs +101 -0
  629. package/scripts/git-env.mjs +9 -0
  630. package/scripts/icon-packs.mjs +151 -0
  631. package/scripts/link-counts.mjs +22 -0
  632. package/scripts/page-colors.mjs +42 -0
  633. package/scripts/releases.d.mts +10 -0
  634. package/scripts/releases.mjs +80 -0
  635. package/scripts/responsive-images.mjs +94 -0
  636. package/scripts/scheduled-list.mjs +15 -0
  637. package/scripts/theme-screenshots.mjs +88 -0
  638. package/scripts/types.mjs +21 -0
  639. package/scripts/video-thumbnails.mjs +89 -0
  640. package/scripts/worker-modules.mjs +34 -0
  641. package/site/appCookies.d.mts +9 -0
  642. package/site/appCookies.mjs +74 -0
  643. package/site/apps.ts +21 -0
  644. package/site/autolinks.d.mts +11 -0
  645. package/site/autolinks.mjs +200 -0
  646. package/site/blockScripts.ts +31 -0
  647. package/site/categories.ts +16 -0
  648. package/site/consent.ts +26 -0
  649. package/site/content.config.ts +84 -0
  650. package/site/content.ts +104 -0
  651. package/site/cookieList.ts +17 -0
  652. package/site/defineSite.d.mts +142 -0
  653. package/site/defineSite.mjs +136 -0
  654. package/site/directives/interact.d.mts +2 -0
  655. package/site/directives/interact.mjs +31 -0
  656. package/site/editor-version.d.mts +1 -0
  657. package/site/editor-version.mjs +26 -0
  658. package/site/fill.ts +13 -0
  659. package/site/format.ts +11 -0
  660. package/site/home.ts +66 -0
  661. package/site/iconPacks.d.mts +20 -0
  662. package/site/iconPacks.mjs +43 -0
  663. package/site/icons.d.mts +693 -0
  664. package/site/icons.mjs +605 -0
  665. package/site/images.d.mts +43 -0
  666. package/site/images.mjs +157 -0
  667. package/site/motion.ts +13 -0
  668. package/site/noindex.d.mts +6 -0
  669. package/site/noindex.mjs +21 -0
  670. package/site/pageColors.ts +110 -0
  671. package/site/popups.ts +98 -0
  672. package/site/schema.ts +189 -0
  673. package/site/sections.ts +3 -0
  674. package/site/seo.ts +28 -0
  675. package/site/site.ts +76 -0
  676. package/site/siteConfig.d.mts +1 -0
  677. package/site/siteConfig.mjs +8 -0
  678. package/site/siteCsp.d.mts +10 -0
  679. package/site/siteCsp.mjs +75 -0
  680. package/site/siteModules.d.mts +7 -0
  681. package/site/siteModules.mjs +27 -0
  682. package/site/standardPages.ts +59 -0
  683. package/site/testimonials.ts +48 -0
  684. package/site/text.ts +43 -0
  685. package/site/theme.d.mts +83 -0
  686. package/site/theme.mjs +472 -0
  687. package/site/tracking.client.ts +225 -0
  688. package/site/tracking.ts +9 -0
  689. package/src/ActionParts.tsx +205 -0
  690. package/src/Advanced.tsx +152 -0
  691. package/src/App.tsx +904 -0
  692. package/src/AppList.tsx +1345 -0
  693. package/src/BlockDialog.tsx +360 -0
  694. package/src/BlockParts.tsx +652 -0
  695. package/src/BlockSettings.tsx +533 -0
  696. package/src/BrandForm.tsx +164 -0
  697. package/src/Colors.tsx +476 -0
  698. package/src/CommunicationParts.tsx +199 -0
  699. package/src/CompanyForm.tsx +209 -0
  700. package/src/Consents.tsx +175 -0
  701. package/src/ContainmentParts.tsx +185 -0
  702. package/src/Crop.tsx +152 -0
  703. package/src/DataForm.tsx +434 -0
  704. package/src/Deleted.tsx +177 -0
  705. package/src/EntryForm.tsx +740 -0
  706. package/src/FileView.tsx +30 -0
  707. package/src/FormFrame.tsx +237 -0
  708. package/src/Keywords.tsx +225 -0
  709. package/src/Library.tsx +1563 -0
  710. package/src/Licenses.tsx +336 -0
  711. package/src/LinkSheet.tsx +138 -0
  712. package/src/MarkdownEditor.tsx +1075 -0
  713. package/src/Media.tsx +677 -0
  714. package/src/NavigationParts.tsx +350 -0
  715. package/src/NavigationRestParts.tsx +247 -0
  716. package/src/Notifications.tsx +59 -0
  717. package/src/PagePicker.tsx +136 -0
  718. package/src/Parts.tsx +991 -0
  719. package/src/PartsShown.tsx +168 -0
  720. package/src/PickerParts.tsx +183 -0
  721. package/src/Redirects.tsx +450 -0
  722. package/src/Screen.tsx +184 -0
  723. package/src/SectionsField.tsx +65 -0
  724. package/src/SelectionParts.tsx +134 -0
  725. package/src/SeoScores.tsx +184 -0
  726. package/src/Sheet.tsx +35 -0
  727. package/src/ThemeStore.tsx +376 -0
  728. package/src/Tokens.tsx +346 -0
  729. package/src/Versions.tsx +214 -0
  730. package/src/addresses.ts +75 -0
  731. package/src/allIcons.ts +7 -0
  732. package/src/appFiles.ts +29 -0
  733. package/src/apps.ts +281 -0
  734. package/src/ask.tsx +123 -0
  735. package/src/blocks.ts +251 -0
  736. package/src/brand.ts +153 -0
  737. package/src/cache.ts +42 -0
  738. package/src/check.ts +285 -0
  739. package/src/checkSite.ts +256 -0
  740. package/src/consents.ts +26 -0
  741. package/src/cookieList.ts +70 -0
  742. package/src/countries.ts +59 -0
  743. package/src/deploy.ts +155 -0
  744. package/src/editor.css +602 -0
  745. package/src/examples.ts +85 -0
  746. package/src/fields.tsx +942 -0
  747. package/src/frontmatter.d.mts +6 -0
  748. package/src/frontmatter.mjs +42 -0
  749. package/src/github.ts +376 -0
  750. package/src/i18n/da-DK/advanced.ts +28 -0
  751. package/src/i18n/da-DK/app.ts +71 -0
  752. package/src/i18n/da-DK/apps.ts +90 -0
  753. package/src/i18n/da-DK/blockSettings.ts +38 -0
  754. package/src/i18n/da-DK/blocks.ts +408 -0
  755. package/src/i18n/da-DK/check.ts +25 -0
  756. package/src/i18n/da-DK/colors.ts +64 -0
  757. package/src/i18n/da-DK/common.ts +118 -0
  758. package/src/i18n/da-DK/company.ts +24 -0
  759. package/src/i18n/da-DK/consents.ts +23 -0
  760. package/src/i18n/da-DK/forms.ts +116 -0
  761. package/src/i18n/da-DK/history.ts +35 -0
  762. package/src/i18n/da-DK/index.ts +49 -0
  763. package/src/i18n/da-DK/keywords.ts +19 -0
  764. package/src/i18n/da-DK/library.ts +135 -0
  765. package/src/i18n/da-DK/licenses.ts +25 -0
  766. package/src/i18n/da-DK/media.ts +79 -0
  767. package/src/i18n/da-DK/parts.ts +696 -0
  768. package/src/i18n/da-DK/preview.ts +13 -0
  769. package/src/i18n/da-DK/redirects.ts +51 -0
  770. package/src/i18n/da-DK/seo.ts +20 -0
  771. package/src/i18n/da-DK/text.ts +35 -0
  772. package/src/i18n/da-DK/theme.ts +41 -0
  773. package/src/i18n/en-US/advanced.ts +32 -0
  774. package/src/i18n/en-US/app.ts +84 -0
  775. package/src/i18n/en-US/apps.ts +134 -0
  776. package/src/i18n/en-US/blockSettings.ts +48 -0
  777. package/src/i18n/en-US/blocks.ts +441 -0
  778. package/src/i18n/en-US/check.ts +31 -0
  779. package/src/i18n/en-US/colors.ts +82 -0
  780. package/src/i18n/en-US/common.ts +144 -0
  781. package/src/i18n/en-US/company.ts +25 -0
  782. package/src/i18n/en-US/consents.ts +25 -0
  783. package/src/i18n/en-US/forms.ts +145 -0
  784. package/src/i18n/en-US/history.ts +43 -0
  785. package/src/i18n/en-US/index.ts +51 -0
  786. package/src/i18n/en-US/keywords.ts +24 -0
  787. package/src/i18n/en-US/library.ts +176 -0
  788. package/src/i18n/en-US/licenses.ts +36 -0
  789. package/src/i18n/en-US/media.ts +80 -0
  790. package/src/i18n/en-US/parts.ts +718 -0
  791. package/src/i18n/en-US/preview.ts +15 -0
  792. package/src/i18n/en-US/redirects.ts +66 -0
  793. package/src/i18n/en-US/seo.ts +26 -0
  794. package/src/i18n/en-US/text.ts +41 -0
  795. package/src/i18n/en-US/theme.ts +41 -0
  796. package/src/i18n/index.ts +124 -0
  797. package/src/icon.tsx +160 -0
  798. package/src/iconPacks.ts +89 -0
  799. package/src/images.ts +163 -0
  800. package/src/licenses.ts +79 -0
  801. package/src/markdown.d.mts +12 -0
  802. package/src/markdown.mjs +204 -0
  803. package/src/nav.ts +68 -0
  804. package/src/notFound.ts +28 -0
  805. package/src/notifications.ts +223 -0
  806. package/src/pagePreview.tsx +204 -0
  807. package/src/r2Caching.ts +55 -0
  808. package/src/redirects.ts +149 -0
  809. package/src/registry.tsx +188 -0
  810. package/src/schema.ts +417 -0
  811. package/src/sections.d.mts +45 -0
  812. package/src/sections.mjs +303 -0
  813. package/src/seo.ts +333 -0
  814. package/src/shared.ts +44 -0
  815. package/src/sidebar.ts +31 -0
  816. package/src/site.ts +317 -0
  817. package/src/standard/Block.astro +19 -0
  818. package/src/standard/BlockSite.astro +18 -0
  819. package/src/standard/accordion/index.tsx +47 -0
  820. package/src/standard/accordion/load.ts +23 -0
  821. package/src/standard/accordion/shared.ts +15 -0
  822. package/src/standard/accordion/view.ts +32 -0
  823. package/src/standard/buttons/fields.ts +98 -0
  824. package/src/standard/buttons/index.tsx +23 -0
  825. package/src/standard/buttons/load.ts +34 -0
  826. package/src/standard/buttons/shared.ts +12 -0
  827. package/src/standard/buttons/view.ts +30 -0
  828. package/src/standard/cards/index.tsx +71 -0
  829. package/src/standard/cards/load.ts +17 -0
  830. package/src/standard/cards/shared.ts +27 -0
  831. package/src/standard/cards/view.ts +29 -0
  832. package/src/standard/checklist/index.tsx +27 -0
  833. package/src/standard/checklist/load.ts +5 -0
  834. package/src/standard/checklist/view.ts +13 -0
  835. package/src/standard/cookies/index.tsx +17 -0
  836. package/src/standard/cookies/list.ts +56 -0
  837. package/src/standard/cookies/load.ts +11 -0
  838. package/src/standard/cookies/shared.ts +20 -0
  839. package/src/standard/cookies/view.ts +28 -0
  840. package/src/standard/faq/index.tsx +29 -0
  841. package/src/standard/faq/load.ts +14 -0
  842. package/src/standard/faq/view.ts +21 -0
  843. package/src/standard/head.ts +23 -0
  844. package/src/standard/hero/fields.ts +48 -0
  845. package/src/standard/hero/index.tsx +57 -0
  846. package/src/standard/hero/load.ts +23 -0
  847. package/src/standard/hero/view.ts +38 -0
  848. package/src/standard/links/index.tsx +41 -0
  849. package/src/standard/links/load.ts +17 -0
  850. package/src/standard/links/view.ts +25 -0
  851. package/src/standard/list/index.tsx +50 -0
  852. package/src/standard/list/load.ts +5 -0
  853. package/src/standard/list/view.ts +18 -0
  854. package/src/standard/load.ts +7 -0
  855. package/src/standard/notice/index.tsx +30 -0
  856. package/src/standard/notice/load.ts +16 -0
  857. package/src/standard/notice/view.ts +10 -0
  858. package/src/standard/points/index.tsx +42 -0
  859. package/src/standard/points/load.ts +5 -0
  860. package/src/standard/points/view.ts +12 -0
  861. package/src/standard/posts/index.tsx +132 -0
  862. package/src/standard/posts/load.ts +36 -0
  863. package/src/standard/posts/shared.ts +21 -0
  864. package/src/standard/posts/view.ts +63 -0
  865. package/src/standard/pricecards/index.tsx +57 -0
  866. package/src/standard/pricecards/load.ts +11 -0
  867. package/src/standard/pricecards/view.ts +50 -0
  868. package/src/standard/sharedTexts.ts +6 -0
  869. package/src/standard/site.ts +124 -0
  870. package/src/standard/siteLooks.ts +19 -0
  871. package/src/standard/sites.ts +13 -0
  872. package/src/standard/steps/index.tsx +28 -0
  873. package/src/standard/steps/load.ts +5 -0
  874. package/src/standard/steps/view.ts +11 -0
  875. package/src/standard/testimonials/index.tsx +87 -0
  876. package/src/standard/testimonials/list.ts +43 -0
  877. package/src/standard/testimonials/load.ts +58 -0
  878. package/src/standard/testimonials/shared.ts +13 -0
  879. package/src/standard/testimonials/view.ts +76 -0
  880. package/src/standard/themeBlocks.ts +13 -0
  881. package/src/standard/video/index.tsx +23 -0
  882. package/src/standard/video/load.ts +10 -0
  883. package/src/standard/video/view.ts +42 -0
  884. package/src/standard/view.tsx +105 -0
  885. package/src/standard/views.ts +37 -0
  886. package/src/store.ts +499 -0
  887. package/src/theme.ts +90 -0
  888. package/src/themeUi.ts +97 -0
  889. package/src/themes.ts +91 -0
  890. package/src/ui.tsx +3402 -0
  891. package/src/virtual.d.ts +5 -0
  892. package/src/when.ts +22 -0
  893. package/starter/.githooks/pre-push +4 -0
  894. package/starter/.nvmrc +1 -0
  895. package/starter/.prettierignore +11 -0
  896. package/starter/.prettierrc.json +7 -0
  897. package/starter/README.md +26 -0
  898. package/starter/astro.config.mjs +5 -0
  899. package/starter/package.json +67 -0
  900. package/starter/public/_redirects +1 -0
  901. package/starter/public/apple-touch-icon.png +0 -0
  902. package/starter/public/editor/apple-touch-icon.png +0 -0
  903. package/starter/public/editor/icon-192.png +0 -0
  904. package/starter/public/editor/icon-512.png +0 -0
  905. package/starter/public/editor/icon-maskable-512.png +0 -0
  906. package/starter/public/favicon.ico +0 -0
  907. package/starter/public/favicon.svg +1 -0
  908. package/starter/public/logo.svg +1 -0
  909. package/starter/src/content/pages/blog.md +8 -0
  910. package/starter/src/content/pages/forside.md +9 -0
  911. package/starter/src/content/pages/kontakt.md +7 -0
  912. package/starter/src/content/pages/privatlivspolitik.md +9 -0
  913. package/starter/src/content/pages/siden-findes-ikke.md +7 -0
  914. package/starter/src/content.config.ts +2 -0
  915. package/starter/src/data/apps.json +1 -0
  916. package/starter/src/data/block-settings.json +3 -0
  917. package/starter/src/data/blocks.json +1 -0
  918. package/starter/src/data/booking.json +6 -0
  919. package/starter/src/data/colors.json +70 -0
  920. package/starter/src/data/contact.json +8 -0
  921. package/starter/src/data/cookies.json +21 -0
  922. package/starter/src/data/csp.json +1 -0
  923. package/starter/src/data/footer.json +15 -0
  924. package/starter/src/data/internal-links.json +4 -0
  925. package/starter/src/data/menu.json +4 -0
  926. package/starter/src/data/mobile-menu.json +4 -0
  927. package/starter/src/data/old-addresses.json +1 -0
  928. package/starter/src/data/redirects.json +1 -0
  929. package/starter/src/data/standard-pages.json +8 -0
  930. package/starter/src/data/theme.json +1 -0
  931. package/starter/src/env.d.ts +2 -0
  932. package/starter/src/site/config.ts +13 -0
  933. package/starter/src/site/worker.js +14 -0
  934. package/starter/tsconfig.json +17 -0
  935. package/starter/worker/apps.js +6 -0
  936. package/starter/wrangler.jsonc +39 -0
  937. package/theme/LICENSE +21 -0
  938. package/theme/blocks/ArrowLink.tsx +14 -0
  939. package/theme/blocks/BlockHead.tsx +26 -0
  940. package/theme/blocks/Panel.tsx +32 -0
  941. package/theme/blocks/Person.tsx +26 -0
  942. package/theme/blocks/accordion/PageRow.tsx +25 -0
  943. package/theme/blocks/accordion/View.tsx +17 -0
  944. package/theme/blocks/buttons/Buttons.tsx +28 -0
  945. package/theme/blocks/buttons/View.tsx +12 -0
  946. package/theme/blocks/cards/LinkCards.tsx +72 -0
  947. package/theme/blocks/cards/View.tsx +20 -0
  948. package/theme/blocks/checklist/Checks.tsx +15 -0
  949. package/theme/blocks/checklist/View.tsx +14 -0
  950. package/theme/blocks/cookies/View.tsx +36 -0
  951. package/theme/blocks/faq/Accordion.tsx +34 -0
  952. package/theme/blocks/faq/View.tsx +16 -0
  953. package/theme/blocks/faq/script.ts +56 -0
  954. package/theme/blocks/hero/View.tsx +44 -0
  955. package/theme/blocks/links/LinkGroups.tsx +24 -0
  956. package/theme/blocks/links/View.tsx +17 -0
  957. package/theme/blocks/list/Rows.tsx +24 -0
  958. package/theme/blocks/list/View.tsx +14 -0
  959. package/theme/blocks/notice/View.tsx +13 -0
  960. package/theme/blocks/points/PointList.tsx +34 -0
  961. package/theme/blocks/points/View.tsx +14 -0
  962. package/theme/blocks/posts/View.tsx +26 -0
  963. package/theme/blocks/pricecards/View.tsx +40 -0
  964. package/theme/blocks/steps/StepList.tsx +23 -0
  965. package/theme/blocks/steps/View.tsx +14 -0
  966. package/theme/blocks/testimonials/List.tsx +46 -0
  967. package/theme/blocks/testimonials/Slider.tsx +44 -0
  968. package/theme/blocks/testimonials/Testimonial.tsx +124 -0
  969. package/theme/blocks/testimonials/View.tsx +21 -0
  970. package/theme/blocks/testimonials/script.ts +52 -0
  971. package/theme/blocks/video/View.tsx +41 -0
  972. package/theme/components/ActionBar.astro +63 -0
  973. package/theme/components/AppSlot.astro +21 -0
  974. package/theme/components/ArrowLink.tsx +21 -0
  975. package/theme/components/BlogIndex.astro +48 -0
  976. package/theme/components/BlogPosts.astro +18 -0
  977. package/theme/components/BlogPosts.tsx +45 -0
  978. package/theme/components/BookButton.tsx +22 -0
  979. package/theme/components/Container.astro +11 -0
  980. package/theme/components/CookieConsent.astro +121 -0
  981. package/theme/components/EndBlock.astro +21 -0
  982. package/theme/components/FontPreload.astro +6 -0
  983. package/theme/components/Footer.astro +85 -0
  984. package/theme/components/Header.astro +186 -0
  985. package/theme/components/Icon.astro +16 -0
  986. package/theme/components/Img.astro +29 -0
  987. package/theme/components/Img.tsx +33 -0
  988. package/theme/components/Inline.astro +11 -0
  989. package/theme/components/Logo.astro +23 -0
  990. package/theme/components/LogoMark.astro +10 -0
  991. package/theme/components/Markdown.astro +17 -0
  992. package/theme/components/MobileMenu.tsx +224 -0
  993. package/theme/components/MobileNav.astro +33 -0
  994. package/theme/components/PageHeader.astro +22 -0
  995. package/theme/components/PageSection.astro +24 -0
  996. package/theme/components/PhoneButton.tsx +11 -0
  997. package/theme/components/Popup.astro +145 -0
  998. package/theme/components/PopupButton.tsx +24 -0
  999. package/theme/components/PopupView.tsx +48 -0
  1000. package/theme/components/PostList.tsx +58 -0
  1001. package/theme/components/PostMeta.tsx +17 -0
  1002. package/theme/components/RichText.astro +28 -0
  1003. package/theme/components/Section.astro +29 -0
  1004. package/theme/components/SectionHeading.tsx +8 -0
  1005. package/theme/components/TextSection.astro +16 -0
  1006. package/theme/components/home/PageBlock.astro +19 -0
  1007. package/theme/components/home/Text.astro +13 -0
  1008. package/theme/components/loadPopup.ts +22 -0
  1009. package/theme/components/loadPosts.ts +16 -0
  1010. package/theme/components/posts.ts +15 -0
  1011. package/theme/editor/looks.mjs +7 -0
  1012. package/theme/editor/previews.tsx +56 -0
  1013. package/theme/layouts/Base.astro +273 -0
  1014. package/theme/layouts/PageLayout.astro +126 -0
  1015. package/theme/layouts/PostLayout.astro +137 -0
  1016. package/theme/screenshots/1-front.jpg +0 -0
  1017. package/theme/screenshots/2-front-dark.jpg +0 -0
  1018. package/theme/screenshots/3-blog.jpg +0 -0
  1019. package/theme/screenshots/4-contact.jpg +0 -0
  1020. package/theme/scripts/motion.ts +29 -0
  1021. package/theme/styles/base.css +320 -0
  1022. package/theme/styles/blocks.css +1808 -0
  1023. package/theme/styles/components.css +206 -0
  1024. package/theme/styles/global.css +1302 -0
  1025. package/theme/styles/ui.css +6544 -0
  1026. package/theme/templates/Blog.astro +38 -0
  1027. package/theme/templates/Category.astro +19 -0
  1028. package/theme/templates/Home.astro +36 -0
  1029. package/theme/templates/New.astro +68 -0
  1030. package/theme/templates/NotFound.astro +117 -0
  1031. package/theme/theme.json +28 -0
  1032. package/theme/ui/Badge.tsx +45 -0
  1033. package/theme/ui/BottomSheet.tsx +148 -0
  1034. package/theme/ui/Button.tsx +79 -0
  1035. package/theme/ui/ButtonGroup.tsx +31 -0
  1036. package/theme/ui/Card.tsx +45 -0
  1037. package/theme/ui/Carousel.tsx +124 -0
  1038. package/theme/ui/Checkbox.tsx +59 -0
  1039. package/theme/ui/Chip.tsx +101 -0
  1040. package/theme/ui/ChipSet.tsx +27 -0
  1041. package/theme/ui/DatePicker.tsx +149 -0
  1042. package/theme/ui/DatePickerContainer.tsx +316 -0
  1043. package/theme/ui/Dialog.tsx +100 -0
  1044. package/theme/ui/Divider.tsx +27 -0
  1045. package/theme/ui/ExposedDropdownMenu.tsx +77 -0
  1046. package/theme/ui/Fab.tsx +88 -0
  1047. package/theme/ui/FabMenu.tsx +67 -0
  1048. package/theme/ui/IconButton.tsx +78 -0
  1049. package/theme/ui/List.tsx +287 -0
  1050. package/theme/ui/LoadingIndicator.tsx +29 -0
  1051. package/theme/ui/Menu.tsx +278 -0
  1052. package/theme/ui/NavigationBar.tsx +62 -0
  1053. package/theme/ui/NavigationDrawer.tsx +80 -0
  1054. package/theme/ui/NavigationRail.tsx +154 -0
  1055. package/theme/ui/ProgressIndicator.tsx +162 -0
  1056. package/theme/ui/RadioButton.tsx +50 -0
  1057. package/theme/ui/Search.tsx +129 -0
  1058. package/theme/ui/SegmentedButton.tsx +49 -0
  1059. package/theme/ui/SideSheet.tsx +54 -0
  1060. package/theme/ui/Slider.tsx +155 -0
  1061. package/theme/ui/Snackbar.tsx +67 -0
  1062. package/theme/ui/SplitButton.tsx +67 -0
  1063. package/theme/ui/Switch.tsx +60 -0
  1064. package/theme/ui/Tabs.tsx +114 -0
  1065. package/theme/ui/TextField.tsx +278 -0
  1066. package/theme/ui/TimePicker.tsx +128 -0
  1067. package/theme/ui/TimePickerContainer.tsx +234 -0
  1068. package/theme/ui/Toolbar.tsx +67 -0
  1069. package/theme/ui/Tooltip.tsx +58 -0
  1070. package/theme/ui/TopAppBar.tsx +77 -0
  1071. package/theme/ui/bottomSheet.script.ts +8 -0
  1072. package/theme/ui/bottomSheet.ts +211 -0
  1073. package/theme/ui/carousel.script.ts +28 -0
  1074. package/theme/ui/carouselLayout.ts +229 -0
  1075. package/theme/ui/checkbox.script.ts +8 -0
  1076. package/theme/ui/datePicker.script.ts +302 -0
  1077. package/theme/ui/dates.ts +185 -0
  1078. package/theme/ui/dialog.ts +48 -0
  1079. package/theme/ui/dropdownMenu.script.ts +166 -0
  1080. package/theme/ui/fabMenu.script.ts +57 -0
  1081. package/theme/ui/navigationRail.script.ts +47 -0
  1082. package/theme/ui/ripple.script.ts +159 -0
  1083. package/theme/ui/search.script.ts +92 -0
  1084. package/theme/ui/sideSheet.ts +48 -0
  1085. package/theme/ui/slider.script.ts +12 -0
  1086. package/theme/ui/sliderUpdate.ts +52 -0
  1087. package/theme/ui/snackbar.script.ts +16 -0
  1088. package/theme/ui/splitButton.script.ts +63 -0
  1089. package/theme/ui/tabs.script.ts +48 -0
  1090. package/theme/ui/textField.script.ts +17 -0
  1091. package/theme/ui/textFieldUpdate.ts +44 -0
  1092. package/theme/ui/timePicker.script.ts +248 -0
  1093. package/theme/ui/toolbar.script.ts +43 -0
  1094. package/theme/ui/tooltip.script.ts +68 -0
  1095. package/worker/consent.js +141 -0
  1096. package/worker/editor-github.js +167 -0
  1097. package/worker/editor-host.js +74 -0
  1098. package/worker/files.js +401 -0
  1099. package/worker/github.js +36 -0
  1100. package/worker/index.js +184 -0
  1101. package/worker/not-found.js +97 -0
  1102. package/worker/oauth.js +95 -0
  1103. package/worker/publish.js +52 -0
  1104. package/worker/push.js +270 -0
  1105. package/worker/r2-status.js +50 -0
  1106. package/worker/session.js +58 -0
@@ -0,0 +1,188 @@
1
+ // The blocks in the editor: the editor's standard blocks (packages/editor/src/standard/), which every site has,
2
+ // and the apps' (src/apps/<app>/blocks/), with their texts in the editor's language (site.ts). Each block is
3
+ // a folder named by its type (the `data-block` of its line in the text, packages/editor/lib/blocks.mjs).
4
+ // A standard block's folder has
5
+ // index.tsx what the editor knows about it (defineBlock in blocks.ts): its name, icon, fields and
6
+ // what its card says;
7
+ // view.ts what it shows (its view), made from its fields and the site's data (viewOf);
8
+ // load.ts the same view on the site, when it is built (BlockSite.astro);
9
+ // and its look is the theme's (packages/editor/theme/blocks/<type>/, or the theme in use's): View.tsx, which draws its
10
+ // view in the editor (blockViews, from standard/themeBlocks.ts) and on the site. A new folder is a new block, in the editor and on
11
+ // the site; nothing else lists them. The apps (src/apps/<app>/, apps.ts) add blocks the same way, in their folder's
12
+ // blocks/, each with its own View.tsx; they are offered once the app is installed. A theme has no blocks of its own,
13
+ // only the look of the standard ones.
14
+ import type { ReactNode } from 'react';
15
+ import { appIdOf, installedApps } from './apps';
16
+ import { htmlBlock, type BlockData, type BlockDefinition, type BlockProps, type DrawBlock, type SiteBlock } from './blocks';
17
+ import { check, templateProblems } from './check';
18
+ import { slugOf, type Field, type Lead, type Template } from './schema';
19
+ import { config, everyFixedPage, fixedPages, standardPages, standardPaths, Texts, type Props, type StandardPage } from '@site/editor';
20
+ import { readFields, splitFrontmatter } from './frontmatter.mjs';
21
+ import { partsOfMarkdown, sectionsFromParts } from './sections.mjs';
22
+ import { blockViews } from './standard/themeBlocks';
23
+ import { InEditor, type View, type ViewOf } from './standard/view';
24
+ import { appBlocks, appViewOfs, appViews } from './appFiles';
25
+ import { blocksIn, splitBlocks } from '../lib/blocks.mjs';
26
+ import { t } from './i18n';
27
+ import { localSiteBlock } from './site';
28
+
29
+ export { apps } from './site';
30
+
31
+ const standard = import.meta.glob<{ default: BlockDefinition }>('./standard/*/index.tsx', { eager: true });
32
+ const views = import.meta.glob<{ viewOf: ViewOf<unknown> }>('./standard/*/view.ts', { eager: true });
33
+ const fromApps = appBlocks;
34
+ const typeOf = (path: string) => path.split('/').at(-2)!;
35
+
36
+ // A block in the editor: its drawing (View.tsx) of the view its contract makes (view.ts).
37
+ function drawn(View: View<unknown> | undefined, viewOf: ViewOf<unknown> | undefined): SiteBlock['draw'] {
38
+ if (!View || !viewOf) return undefined;
39
+ return (props, data) => {
40
+ const view = viewOf(props, data);
41
+ return view === null ? null : <View view={view} />;
42
+ };
43
+ }
44
+
45
+ // A folder's file, by the path of its index.tsx.
46
+ const beside = (path: string, file: string) => `${path.slice(0, path.lastIndexOf('/'))}/${file}`;
47
+
48
+ /** The types of the standard blocks: every theme has them. */
49
+ export const standardTypes = new Set(Object.keys(standard).map(typeOf));
50
+
51
+ /** The blocks that can be put in the text of a page: the standard ones (and HTML on a line of its own)
52
+ * and the apps'. */
53
+ export const siteBlocks: SiteBlock[] = [
54
+ ...Object.entries(standard).map(([path, m]) => ({
55
+ ...m.default,
56
+ draw: drawn(blockViews[typeOf(path)], views[beside(path, 'view.ts')]?.viewOf),
57
+ type: typeOf(path),
58
+ standard: true,
59
+ })),
60
+ ...Object.entries(fromApps).map(([path, m]) =>
61
+ localSiteBlock({
62
+ ...m.default,
63
+ draw: drawn(appViews[beside(path, 'View.tsx')]?.default, appViewOfs[beside(path, 'view.ts')]?.viewOf),
64
+ type: typeOf(path),
65
+ app: appIdOf(path),
66
+ }),
67
+ ),
68
+ htmlBlock,
69
+ ];
70
+
71
+ /** The blocks turned off under "Blokindstillinger" (BlockSettings.tsx), and the apps' kinds of the site's lists
72
+ * (kindKey, "popups/mailchimp"), from the site's file of block settings (config.blockSettings). */
73
+ export function offBlocks(files: { path: string; text: string }[]): string[] {
74
+ try {
75
+ const off = JSON.parse(files.find((f) => f.path === config.blockSettings)?.text ?? '{}').off;
76
+ return Array.isArray(off) ? off.map(String) : [];
77
+ } catch {
78
+ return [];
79
+ }
80
+ }
81
+
82
+ /** The blocks not offered to put in, and that a new page does not start with: those turned off, and
83
+ * those of the apps not installed (AppList.tsx). */
84
+ export function notOffered(files: { path: string; text: string }[]): string[] {
85
+ const installed = installedApps(files);
86
+ return [...offBlocks(files), ...siteBlocks.filter((b) => b.app && !installed.includes(b.app)).map((b) => b.type)];
87
+ }
88
+
89
+ /** The fields with a fixed page's sections (`pageBlocks`) given every block a page can have after their own (not HTML):
90
+ * the editor draws them and checks them by their own fields, as the site's build does (checkSite.ts), also one turned
91
+ * off or of an app not installed, as on a page; those are only not offered under "Indsæt" (SectionsField's `off`). */
92
+ export const withPageBlocks = (fields: Field[]): Field[] =>
93
+ fields.map((f) =>
94
+ f.type === 'blocks' && f.pageBlocks
95
+ ? {
96
+ ...f,
97
+ blocks: [
98
+ ...(f.blocks ?? []),
99
+ ...siteBlocks.filter((b) => b.type !== htmlBlock.type && !f.blocks?.some((own) => own.type === b.type)),
100
+ ],
101
+ }
102
+ : f,
103
+ );
104
+
105
+ /** What is wrong with the blocks in a text, a message for each, by their own fields (check.ts) and
106
+ * the page's template: the editor says the first before it saves a page (EntryForm.tsx), and the
107
+ * site's build says them all (checkSite.ts). A hidden block is not on the site, so it may be
108
+ * unfinished. */
109
+ /** The standard page a page is ("Indstillinger" › "Udseende" › "Standardsider", config.standardPages: the front page,
110
+ * the blog page …), by the address there, or undefined. */
111
+ export function standardPageOf(file: { path: string; text: string }, files: { path: string; text: string }[]): StandardPage | undefined {
112
+ if (!config.standardPages || !file.path.startsWith(`${config.folders.pages}/`)) return undefined;
113
+ const own = String(readFields(splitFrontmatter(file.text).yaml).path ?? `/${slugOf(file.path, config.folders.pages)}/`);
114
+ const paths = standardPaths(files.find((f) => f.path === config.standardPages)?.text);
115
+ return standardPages.find((p) => paths[p.key] === own);
116
+ }
117
+
118
+ /** A page's template as a standard page's: its own rules and the standard page's (its `template`, packages/editor/defaults/standardPages.ts). */
119
+ export const asStandardTemplate = (template: Template | undefined, standard: StandardPage | undefined): Template | undefined => {
120
+ const own = standard?.template;
121
+ if (!own) return template;
122
+ return {
123
+ ...template,
124
+ ...own,
125
+ max: { ...template?.max, ...own.max },
126
+ required: [...(template?.required ?? []), ...(own.required ?? [])],
127
+ locked: [...(template?.locked ?? []), ...(own.locked ?? [])],
128
+ };
129
+ };
130
+
131
+ /** What is wrong with the blocks in a text (with or without its front matter) by their fields and the template. With
132
+ * `leads` (the front page), a block's heading, text and picture may be the text above its card, as the site reads it. */
133
+ export function blockProblems(text: string, template?: Template, leads?: Record<string, Lead>): string[] {
134
+ const name = (type: string) => siteBlocks.find((b) => b.type === type)?.label ?? type;
135
+ const rules = template
136
+ ? templateProblems(
137
+ template,
138
+ blocksIn(text).map((b) => ({ type: b.type, hidden: b.props.hidden })),
139
+ name,
140
+ )
141
+ : [];
142
+ const parts = leads
143
+ ? (sectionsFromParts(partsOfMarkdown(splitFrontmatter(text).body), leads) as { type: string; hidden?: boolean }[])
144
+ .filter((s) => s.type !== 'text' && !s.hidden)
145
+ .map(({ type, ...props }) => ({ type, props }))
146
+ : splitBlocks(text, null);
147
+ const own = parts.flatMap((part) => {
148
+ if (!('type' in part)) return [];
149
+ const block = siteBlocks.find((b) => b.type === part.type);
150
+ if (!block) return [t.blocks.gone(part.type)];
151
+ const problem = check(block.fields, part.props, block.label);
152
+ return problem ? [problem] : [];
153
+ });
154
+ return [...own, ...rules];
155
+ }
156
+
157
+ /** The block as it looks on the site, or null when there is no picture of it. On a fixed page its
158
+ * sections (the theme's previews.tsx), or the block of the section's type (Book en tid); a section can
159
+ * draw a block by its type too (`block`, the prices on the prices page), so the theme never imports one. */
160
+ export function preview(type: string, props: BlockProps, data: BlockData) {
161
+ const file = data.page?.file;
162
+ const drawOf = (t: string) => siteBlocks.find((b) => b.type === t)?.draw;
163
+ const block: DrawBlock = (t, p) => drawOf(t)?.(p, data) ?? null;
164
+ const draw = file ? (fixedPages[file]?.[type] ?? everyFixedPage[type] ?? drawOf(type)) : drawOf(type);
165
+ return draw ? (
166
+ <InEditor>
167
+ <Texts.Provider value={data.site}>
168
+ <Drawn draw={draw} props={props as Props} data={data} block={block} />
169
+ </Texts.Provider>
170
+ </InEditor>
171
+ ) : null;
172
+ }
173
+
174
+ // A block drawn as a component, inside Texts: a section that reads the texts (useTexts in the theme's
175
+ // previews.tsx) uses a hook, which is only allowed while React draws a component.
176
+ function Drawn({
177
+ draw,
178
+ props,
179
+ data,
180
+ block,
181
+ }: {
182
+ draw: (props: Props, data: BlockData, block: DrawBlock) => ReactNode;
183
+ props: Props;
184
+ data: BlockData;
185
+ block: DrawBlock;
186
+ }) {
187
+ return draw(props, data, block);
188
+ }
package/src/schema.ts ADDED
@@ -0,0 +1,417 @@
1
+ // The kinds of things the editor edits, which a site describes its content with (packages/editor/defaults/collections.ts):
2
+ // collections of files and their fields, the blocks of a fixed page and the rules of a text (Template),
3
+ // and the small helpers for them that do not depend on a site.
4
+ // markdown: a folder of .md files (front matter + text): blog posts and pages.
5
+ // folder: a folder of .json files, one entry per file: categories, prices, testimonials.
6
+ // files: single .json files: the pages built in code (fixed pages) and the menu.
7
+ import type { Icon } from '@phosphor-icons/react';
8
+ import type { ComponentType, ReactNode } from 'react';
9
+ import type { BlockData } from './blocks';
10
+ import type { AppCategory } from './store';
11
+ import type { SiteData } from '@site/editor';
12
+ import { locale } from './i18n';
13
+
14
+ /** What a relation field picks from: one of the lists the site makes of its files (relationsOf in
15
+ * packages/editor/defaults/editor.ts), e.g. 'pages', 'blog', 'categories', 'files' (the PDFs). 'fixed': the fixed pages, only offered
16
+ * together with the pages (a field with `fixed`). */
17
+ export type Relation = string;
18
+
19
+ export type Field = {
20
+ name: string;
21
+ label: string;
22
+ type:
23
+ | 'string'
24
+ | 'text'
25
+ | 'number'
26
+ | 'date'
27
+ | 'datetime'
28
+ | 'boolean'
29
+ | 'image'
30
+ | 'readonly'
31
+ | 'select'
32
+ | 'relation'
33
+ | 'object'
34
+ | 'list'
35
+ | 'blocks'
36
+ | 'markdown';
37
+ hint?: string;
38
+ /** An address on the site (string), written as one when it is typed (addressOf in addresses.ts):
39
+ * a page's may have more parts, a post's only one. */
40
+ address?: 'page' | 'post';
41
+ /** What is used when it is empty, shown greyed in it (string, text). */
42
+ placeholder?: (site: SiteData) => string;
43
+ /** Edited elsewhere: a link there under the label. */
44
+ edit?: Edit;
45
+ required?: boolean;
46
+ /** Most characters (string, text). */
47
+ max?: number;
48
+ /** A regular expression the text must match, and the message when it does not. */
49
+ pattern?: [string, string];
50
+ /** A number written with its digits in pairs, as "30 64 16 12": typed any way, it is written so
51
+ * (inPairs in check.ts); a number of digits: it must have that many. */
52
+ digitsInPairs?: number | true;
53
+ /** A phone number, with its country code picked before it in a sheet (PhoneField): the site's own
54
+ * country code ("+45"). A number with it is saved without it ("30 64 16 12"), one with another with
55
+ * that before it ("+46 70 123 45 67"); only the site's own is written in pairs and has its digits
56
+ * counted (digitsInPairs). */
57
+ phone?: string;
58
+ /** string: words typed as chips (ChipField), saved separated by commas: 'one', one word, the field gone while it has
59
+ * it (a primary keyword); 'many', any number of them. */
60
+ chips?: 'one' | 'many';
61
+ /** select */
62
+ /** `icon`: shown before its name (only with `segments`). `hint`: shown under the label while it is
63
+ * chosen, in place of the field's own (the status of a page: what each one means). `onPage`: offered only while
64
+ * that relation has a choice on the page being edited (a button that opens a promotion); chosen, it is still shown. */
65
+ options?: { label: string; value: string; icon?: Icon; hint?: string; onPage?: Relation }[];
66
+ /** select: the options are icons (their names, `icons`), shown as the icons to tap (fields.tsx). */
67
+ icons?: boolean;
68
+ /** select: the options side by side in a bar, the chosen one raised (SegmentedButton in ui.tsx), for two or
69
+ * three short ones. */
70
+ segments?: boolean;
71
+ /** select: shown as what is chosen, with its hint, and not changed here (the kind of an entry,
72
+ * picked when it is made). */
73
+ locked?: boolean;
74
+ /** select: the choices on a page of their own under the form, at its address with the field's name after it
75
+ * (#apps/content-colors/indstillinger/variant), in place of the sheet, drawn by this with what each gives (a picture of
76
+ * it); the field links there. Only a field of a part's own form (CompanyForm.tsx: an app's settings), not one in a
77
+ * group or a list; elsewhere the choices are in the sheet. */
78
+ page?: ComponentType<FieldPageProps>;
79
+ /** relation: what is picked. Pages are stored by their path, the others by their file name. */
80
+ to?: Relation;
81
+ multiple?: boolean;
82
+ /** relation, multiple: the text of the pill that opens the sheet to pick one ("Tilføj tag"). */
83
+ add?: string;
84
+ /** relation to pages: the fixed pages can be picked too (the menu). */
85
+ fixed?: boolean;
86
+ /** relation: only the choices shown on the page being edited (Option.on, FieldContext.page); where no page is
87
+ * edited (the shared buttons), only those shown on every page. */
88
+ onPage?: boolean;
89
+ /** relation with `multiple`, and list: at most this many. */
90
+ maxItems?: number;
91
+ /** object, and list of objects */
92
+ fields?: Field[];
93
+ /** list of single values */
94
+ field?: Field;
95
+ /** list: the field shown as the title of each item; of several, the first filled in (a button's text or a text). */
96
+ summary?: string | string[];
97
+ singular?: string;
98
+ /** The value in a new entry. */
99
+ default?: unknown;
100
+ /** The value of a saved entry that has none (saved before the field was there, or with its empty choice, which is
101
+ * not written), when it is not `default`: a banner from before it could go across the whole width is as wide as
102
+ * the text. */
103
+ missing?: unknown;
104
+ /** Shown, checked and saved only while another field next to it (a select) has one of these values,
105
+ * and that field is itself in use. */
106
+ only?: { field: string; is: string[] };
107
+ /** boolean: shown as a switch, with what it says when on and when off. */
108
+ toggle?: [string, string];
109
+ /** Its value changes how the page is laid out (a page across the whole width): "Forhåndsvis" shows a page whose value
110
+ * is changed in another page saved with the same value (EntryForm.tsx). */
111
+ layout?: boolean;
112
+ /** blocks: a list where each item has a `type`, one of these, which gives its fields. */
113
+ blocks?: Block[];
114
+ /** blocks: also every block a page can have (the standard ones and the apps', not HTML), after its own; one of
115
+ * its own by the same type wins (withPageBlocks in registry.tsx). */
116
+ pageBlocks?: boolean;
117
+ /** blocks: the page's field (its introduction) written as the text at the top, above the sections. */
118
+ intro?: string;
119
+ /** blocks: the lead of a block a page can have, by its type, on this page (a fixed page's sections: the front page's
120
+ * headings and texts, written in the text above their cards, sections.mjs); its own blocks have theirs (Block.lead). */
121
+ leads?: Record<string, Lead>;
122
+ /** blocks: what the page may have of them (Template). markdown: the blocks that can be put in its text with "+", and
123
+ * how many (Template `blocks` and `max`; 'image' a picture); without it, none. */
124
+ template?: Template;
125
+ };
126
+
127
+ /** What a field's page of its own (Field.page) is given: the field, what is chosen, the form's other values as they are
128
+ * now (not saved yet) and the choice, which goes back to the form with it. */
129
+ export type FieldPageProps = {
130
+ field: Field;
131
+ value: string;
132
+ values: Record<string, unknown>;
133
+ onChange: (value: string) => void;
134
+ };
135
+
136
+ /** What a text may have of blocks: the developer's rules for a page's blocks (MarkdownCollection) or a
137
+ * fixed page's sections (a `blocks` field), by type. The editor keeps to them (what can be put in,
138
+ * hidden, moved and removed), checks them before it saves, and so does the site before it is built
139
+ * (templateProblems in check.ts). */
140
+ export type Template = {
141
+ /** The blocks that can be put in; all of them when left out. */
142
+ blocks?: string[];
143
+ /** At most this many of a type, hidden ones too. */
144
+ max?: Record<string, number>;
145
+ /** On the page, shown: the last one cannot be hidden or removed. */
146
+ required?: string[];
147
+ /** Stays where it is, shown: it can be edited, but not moved, hidden or removed, and nothing moves
148
+ * past it (the front page's top). */
149
+ locked?: string[];
150
+ /** The blocks a new page starts with, in order, with no fields filled in (a page collection). */
151
+ start?: string[];
152
+ };
153
+
154
+ /** What a button can open of an entry of a list shown on the pages (a promotion), offered by its kind: `label`, what
155
+ * opens, in the site's language ("Pop op-vindue", "Bookingarket"), the choice named after it with the entry's name in
156
+ * parentheses; `as`, a target of the buttons (`buttonTargets`) it stands for, which the button then does (the booking
157
+ * bar opens the booking sheet, as "Book en tid" does), else the entry itself opens. */
158
+ export type Opens = { label: string; as?: string };
159
+
160
+ /** A place in the editor (a route, e.g. 'virksomheden/kontakt') and the text of the link to it. */
161
+ export type Edit = { to: string; text: string };
162
+
163
+ // A kind of item in a list of blocks (a fixed page's sections; in the editor cards in its text, SectionsField.tsx).
164
+ export type Block = {
165
+ type: string;
166
+ label: string;
167
+ /** What the block is, where one is picked. */
168
+ hint?: string;
169
+ /** Edited elsewhere: "Ret" goes there (without fields), or a link there over its fields. */
170
+ edit?: Edit;
171
+ fields: Field[];
172
+ /** Its own text and picture are written in the page's text, above its card (sections.mjs): */
173
+ lead?: Lead;
174
+ };
175
+
176
+ /** heading: the field of the heading (an "Overskrift", H2); body: the field of the text under it, one
177
+ * text (paragraphs) or, with `list`, one item per paragraph; image: a picture (`image`, `imageAlt`, `imageDecorative`)
178
+ * above the heading, in place of the design's own; upTo: only the body's text before its first block of this type is
179
+ * written above the card (the front page's "Banner": its "Knapper" block), the block and the text after it stay in the
180
+ * field, which the card has too. */
181
+ export type Lead = { heading?: string; body?: string; list?: boolean; image?: boolean; upTo?: string };
182
+
183
+ type Base = {
184
+ id: string;
185
+ label: string;
186
+ singular: string;
187
+ /** The button for a new entry ("Nyt blogindlæg"); without it, no new entries are made here. */
188
+ create?: string;
189
+ };
190
+
191
+ export type MarkdownCollection = Base & {
192
+ kind: 'markdown';
193
+ folder: string;
194
+ fields: Field[];
195
+ deletable?: boolean;
196
+ /** The site's blocks can be put in the text (src/apps/<app>/blocks/). */
197
+ blocks?: boolean;
198
+ /** What a text may have of them. */
199
+ template?: Template;
200
+ };
201
+
202
+ export type FolderCollection = Base & {
203
+ kind: 'folder';
204
+ folder: string;
205
+ fields: Field[];
206
+ deletable?: boolean;
207
+ /** Entries have an `order` (first in the file), changed with the arrows in the list. */
208
+ orderable?: boolean;
209
+ /** The field the file name is made from when the entry is created; of several, the first filled in
210
+ * (a pop-up's heading, or the name of a kind without one). */
211
+ slugFrom: string | string[];
212
+ /** The entries are of kinds: the name of the select field that says which (`locked`), which the apps
213
+ * add kinds to (apps.ts withKinds). With more than one, "+" opens a sheet to pick the kind. */
214
+ kinds?: string;
215
+ /** What the list shows for an entry. */
216
+ summary: (data: Record<string, unknown>) => string;
217
+ /** What the list shows under it, smaller (a cookie's name under who sets it), and is searched with it. */
218
+ detail?: (data: Record<string, unknown>) => string;
219
+ /** The fields the list can be filtered by (the funnel, Library.tsx List), each among the values its entries have:
220
+ * a select by its options' names, another by the value itself (a cookie's provider); `all`: the choice that shows
221
+ * them all ("Alle udbydere"). */
222
+ filters?: { field: string; all: string }[];
223
+ /** The entries are shown on pages of the site: the field with their addresses, the field with the tags
224
+ * whose posts they are on, and the field and value that say an entry is on every page. The list can
225
+ * then be filtered by a page or a tag (Library.tsx List). */
226
+ shownOn?: { pages: string; tags?: string; everywhere?: { field: string; is: string } };
227
+ /** What a button can open of an entry of one of the list's own kinds, by the kind, as AppKind.opens for an app's
228
+ * kinds: a pop-up opens itself; a kind left out offers nothing (the action bar). */
229
+ opens?: Record<string, Opens>;
230
+ /** The boolean field that turns an entry on and off (a promotion's "Slået til"/"Slået fra"): the list
231
+ * can then be filtered by it, the choices its `toggle` (Library.tsx List). */
232
+ onOff?: string;
233
+ /** The list's own fields one of its own kinds does not have, by the kind (a bar has no picture or
234
+ * heading), as AppKind.omit for an app's kinds (apps.ts withKinds). */
235
+ omit?: Record<string, string[]>;
236
+ /** How an entry of one of the list's own kinds looks on the site, by the kind, drawn beside its form
237
+ * with the fields as they are now (a pop-up); an app's kinds have their own (AppKind.draw). */
238
+ draws?: Record<string, (values: Record<string, any>, data: BlockData) => ReactNode>;
239
+ /** How an entry of an app's kind with a part (AppKind.part) looks on the site: the list's own drawing (a pop-up's box)
240
+ * with the app's part in it, the same as on the site (kindDraw in apps.ts). */
241
+ drawPart?: (values: Record<string, any>, data: BlockData, part: KindPart) => ReactNode;
242
+ /** Entries something else added (the app "Cookiescanner" a cookie it found), not yet looked through: the field in the
243
+ * file that says so (`true`, not one of `fields`), the heading they are under at the top of the list (Library.tsx
244
+ * List), what each says in the accent colour in it and at the top of its form (`label`, by its data: "Ny", "Mangler
245
+ * formål"), what the form says of it (`notice`) and its button that takes the field away (`approve`). Saving the entry
246
+ * takes it away too (DataForm.tsx). */
247
+ fresh?: { field: string; heading: string; label: (data: Record<string, unknown>) => string; notice: string; approve: string };
248
+ /** An entry as saved before the list changed (of a kind that is gone: a contact bar, now an action bar), as the list
249
+ * has it now, from its data and the site's files: read so in the list, the form (and saved so) and the check of the
250
+ * site (entryData: Library.tsx, DataForm.tsx, checkSite.ts). */
251
+ upgrade?: (data: Record<string, unknown>, files: { path: string; text: string }[]) => Record<string, unknown>;
252
+ };
253
+
254
+ /** An entry's data from its file's text, as the list has it now (FolderCollection.upgrade). */
255
+ export const entryData = (collection: FolderCollection, text: string, files: { path: string; text: string }[]) => {
256
+ const data = JSON.parse(text) as Record<string, unknown>;
257
+ return collection.upgrade ? collection.upgrade(data, files) : data;
258
+ };
259
+
260
+ /** An entry's name on its own screen and among those deleted: what its list shows, with the line under it after it
261
+ * ("Google Analytics · _ga"). */
262
+ export const entryName = (collection: FolderCollection, data: Record<string, unknown>) =>
263
+ [collection.summary(data), collection.detail?.(data)].filter(Boolean).join(' · ');
264
+
265
+ /** An app's part of an entry of its kind, drawn in the list's own drawing (a Mailchimp signup in a pop-up's box), on the
266
+ * site and in the editor alike: its drawing (`View`, given its view and the entry's own button to show where it wants)
267
+ * and what makes its view in the editor (`viewOf`, as a block's view.ts). */
268
+ export type KindPart = {
269
+ View: ComponentType<{ view: any; button: ReactNode }>;
270
+ viewOf: (values: Record<string, any>, data: BlockData) => unknown;
271
+ };
272
+
273
+ /** A list a standard block or an app brings ("Udtalelser", "Priser"), as the site's own, with its icon under "Lister". */
274
+ export type OwnedList = FolderCollection & {
275
+ icon: Icon;
276
+ /** Made-up rows, as the files have them, for the parts under "Dele" and an app's pictures for the store (examples.ts). */
277
+ examples?: Record<string, unknown>[];
278
+ };
279
+
280
+ export type DataFile = {
281
+ file: string;
282
+ label: string;
283
+ /** Where it is seen on the site. */
284
+ view: string;
285
+ fields: Field[];
286
+ /** The file is a list (the menus): this field holds it in the form. With `fields` ("Aktiveret"), the file holds
287
+ * them and the list under this field's name, and the form shows them above the list. */
288
+ root?: Field;
289
+ /** A fixed page called by its label, not its H1 (the front page). */
290
+ byLabel?: boolean;
291
+ };
292
+
293
+ /** A fixed page's name in the editor: its H1 (`heading`), as the page has it now; the front page
294
+ * (byLabel) and the about page, whose file has none, by their label. `data`: the file's content, or its text. */
295
+ export function fixedName(file: DataFile, data?: string | Record<string, unknown>): string {
296
+ if (file.byLabel) return file.label;
297
+ try {
298
+ const heading = (typeof data === 'string' ? JSON.parse(data) : data)?.heading;
299
+ return typeof heading === 'string' && heading.trim() ? heading.trim() : file.label;
300
+ } catch {
301
+ return file.label;
302
+ }
303
+ }
304
+
305
+ export type FilesCollection = Base & {
306
+ kind: 'files';
307
+ files: DataFile[];
308
+ /** Its files are pages of the site (the fixed pages): each form says when it was last saved, as a page's. */
309
+ pages?: boolean;
310
+ };
311
+
312
+ export type Collection = MarkdownCollection | FolderCollection | FilesCollection;
313
+
314
+ // The collection a file belongs to, and for single files its entry.
315
+ export function collectionOf(collections: Collection[], path: string): { collection: Collection; dataFile?: DataFile } | null {
316
+ for (const collection of collections) {
317
+ if (collection.kind === 'files') {
318
+ const dataFile = collection.files.find((f) => f.file === path);
319
+ if (dataFile) return { collection, dataFile };
320
+ } else if (path.startsWith(`${collection.folder}/`)) {
321
+ return { collection };
322
+ }
323
+ }
324
+ return null;
325
+ }
326
+
327
+ // A file's name in its folder, without .md or .json (and /index): a post's address, an entry's slug.
328
+ export const slugOf = (path: string, folder: string) => path.slice(folder.length + 1).replace(/(\/index)?\.(md|json)$/, '');
329
+
330
+ // Titles in alphabetical order, in the editor's language (Danish: æ, ø, å last), without the quotation marks and other signs
331
+ // some begin with: “Livet med og efter bipolar lidelse” under L.
332
+ const sortable = (title: string) => title.replace(/^[^\p{L}\p{N}]+/u, '');
333
+ export const byText = (a: string, b: string) => sortable(a).localeCompare(sortable(b), locale);
334
+
335
+ // Addresses and file names from a title, spelled like the existing ones: æ -> ae, ø -> oe, å -> aa.
336
+ export const slugify = (title: string) =>
337
+ title
338
+ .toLowerCase()
339
+ .replace(/æ/g, 'ae')
340
+ .replace(/ø/g, 'oe')
341
+ .replace(/å/g, 'aa')
342
+ .normalize('NFKD')
343
+ .replace(/[̀-ͯ]/g, '')
344
+ .replace(/[^a-z0-9]+/g, '-')
345
+ .replace(/^-|-$/g, '');
346
+
347
+ /** A screen of the site's own with parts (PartScreen), "Virksomheden" or "Blokke" (CompanyForm.tsx): a
348
+ * part of one data file. */
349
+ export type Part = {
350
+ id: string;
351
+ label: string;
352
+ icon: Icon;
353
+ /** The fields and the file they are in, at the top level or under `at`; without them, a part is only a
354
+ * row that opens its own screen (the ones under "Udseende", Library.tsx). */
355
+ file?: string;
356
+ at?: string;
357
+ fields?: Field[];
358
+ /** The values before any are saved (a block's shared.ts). */
359
+ defaults?: Record<string, unknown>;
360
+ /** A block drawn under the fields with them as they are now (its draw, src/apps/<app>/blocks/): its type, and props
361
+ * for when no page has the block (the first one on a page is drawn). shared: always with `props`,
362
+ * as a copy that has nothing of its own (the shared buttons). variants: drawn once for each, under its
363
+ * name, always with `props` and the variant's over them (the designs of "Kort"). */
364
+ preview?: {
365
+ type: string;
366
+ props?: Record<string, unknown>;
367
+ shared?: boolean;
368
+ variants?: PreviewVariant[];
369
+ };
370
+ /** Where its row opens, when not its own screen under the one it is on (the front page under "Udseende"). */
371
+ href?: string;
372
+ /** At the end of its row, before the arrow: the theme in use, by "Temaer" under "Udseende". */
373
+ detail?: string;
374
+ /** At the end of its row, after `detail` and before the arrow: the site's primary, secondary and tertiary colours by
375
+ * "Farver" under "Udseende" (ColorSwatches). */
376
+ trailing?: ReactNode;
377
+ /** Where its screen goes back to: "Virksomheden", or "Blokke" (blockTexts.ts, site.ts). */
378
+ back?: { href: string; label: string };
379
+ /** What the commit says was edited, in the site's language, when not its name in lower case (an
380
+ * app's settings, AppList.tsx: "indstillinger for Mailchimp"). */
381
+ commit?: string;
382
+ /** Parts of its own, instead of fields: a row that opens a screen with them, each at
383
+ * #<screen>/<id>/<part> and going back to it ("Virksomheden" › "Betaling" with "Bank"). */
384
+ parts?: Part[];
385
+ /** With `parts`: the settings of the apps installed of these kinds (AppDefinition.category) come after them, each at
386
+ * #<screen>/<id>/<app> ("Betaling" with MobilePay; AppList.tsx appPartsIn). */
387
+ apps?: AppCategory[];
388
+ /** One of the editor's own lists, drawn under its fields: "keywords", every keyword of the pages, posts and fixed
389
+ * pages ("Interne links", Keywords.tsx). */
390
+ below?: 'keywords';
391
+ /** One of the editor's own screens, instead of a form: "consents", the visitors' answers in the cookie banner
392
+ * ("Samtykker" under "Privatliv", Consents.tsx). */
393
+ opens?: 'consents';
394
+ /** Its fields, which pick a page (`relation`), as the rows of a list, each opening the sheet with the pages (FieldRows):
395
+ * "Standardsider" and "Privatlivssider". */
396
+ rows?: boolean;
397
+ };
398
+
399
+ /** A part of the start screen that is a screen with parts, each a screen of its own at #<id>/<part>
400
+ * (Library.tsx PartsScreen, CompanyForm.tsx): "Privatliv" with the cookie banner and the privacy pages. With `apps`, the
401
+ * settings of the apps installed of those kinds (AppDefinition.category) come after its own parts, each at
402
+ * #<id>/<app> ("Analytics" with Google Analytics; AppList.tsx appPartsIn). */
403
+ export type PartScreen = { id: string; label: string; parts: Part[]; apps?: AppCategory[] };
404
+
405
+ /** One way a block's screen under "Blokke" draws it (Part.preview): its name and its own props. */
406
+ export type PreviewVariant = { label: string; props: Record<string, unknown> };
407
+
408
+ /** What a block on the site is given by RichText.astro (BlockSite.astro gives it to its load.ts): its props (as written in its line in the
409
+ * text), its place among the parts of the text, the page's address, whether the page is a new
410
+ * version of a page (/ny/), and its shared texts (shared.ts, with those saved over them). */
411
+ export type SiteProps<P = Record<string, any>> = {
412
+ props: P;
413
+ index: number;
414
+ path?: string;
415
+ preview?: boolean;
416
+ texts?: Record<string, any>;
417
+ };
@@ -0,0 +1,45 @@
1
+ /** The text of the editor for a list of sections; leads: the lead of each type of section; intro: the
2
+ * page's introduction, above the sections. */
3
+ export function sectionsToMarkdown(sections: any, leads: {} | undefined, intro: any): string;
4
+ /** The page's introduction (the text before the first heading or card) and the parts after it. */
5
+ export function introOf(parts: any): any[];
6
+ /** The sections for the parts of the text (partsOf in markdown.mjs); leads as for sectionsToMarkdown. */
7
+ export function sectionsFromParts(parts: any, leads?: {}): any;
8
+ /** The look of each part of the text (null: as text), from its parts in order: { kind: 'block', type }
9
+ * for a card, 'heading' (H2), 'p' (with image: a picture), 'gap' (a free line) or 'other'. The text a
10
+ * section takes as its own is found as in sectionsFromParts. A text after the first is marked "rest". */
11
+ export function looksOf(items: any, { file, leads, intro, sectionLooks, headingLooks }: {
12
+ file: any;
13
+ leads?: {} | undefined;
14
+ intro?: boolean | undefined;
15
+ sectionLooks?: {} | undefined;
16
+ headingLooks?: {} | undefined;
17
+ }): any;
18
+ /** A page's H1: the heading "# …" on the first line of its text that is not empty (the page's own heading, written
19
+ * at the top of its text), as text, and the text without it. Without one: no heading, and the text as it is. With a
20
+ * word or more in colour, `html` is the heading as HTML with its colours (coloredHtml), for the layout to draw. */
21
+ export function pageH1(markdown: any): {
22
+ heading: undefined;
23
+ rest: string;
24
+ html?: undefined;
25
+ } | {
26
+ heading: any;
27
+ html: any;
28
+ rest: string;
29
+ };
30
+ /** The parts of a page's Markdown as the editor reads them (partsOf in markdown.mjs), without the editor: each block,
31
+ * each heading at the top level (H2), and the Markdown between them; for the site, which reads the front page into
32
+ * sections (packages/editor/site/home.ts). The page's H1 ("# …") is no section's and is left out. `npm run check:editor` checks
33
+ * that it gives the editor's sections for every page. */
34
+ export function partsOfMarkdown(markdown: any): ({
35
+ block: any;
36
+ heading?: undefined;
37
+ } | {
38
+ heading: any;
39
+ block?: undefined;
40
+ })[];
41
+ export function leadsOf(blocks: any): {
42
+ [k: string]: any;
43
+ };
44
+ export function leadsOfField(field: any): any;
45
+ export function plainHeading(s: any): any;