@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,78 @@
1
+ // An icon button (m3.material.io/components/icon-buttons, .icon-button in ../styles/ui.css): only an icon (`icon`, its
2
+ // name in the theme's icons, or in the editor an icon already made), its name (`label`) read by screen readers. Its kind (`kind`: standard, the default, filled,
3
+ // tonal or outlined), its size (`size`: xsmall, small, the default, medium, large or xlarge), its width (`width`:
4
+ // narrow, default or wide) and its shape (`shape`: round, the default, or square) are Material's names; how each looks
5
+ // is the theme's. With `selected` (true or false) it is a toggle icon button, aria-pressed: the theme gives each kind its
6
+ // look off and on, and its corners turn square when it is on (round when it is square); what turns it on and off is the
7
+ // script of the block that shows it (or the editor), and its icon is drawn filled while it is on, where the site draws
8
+ // it filled. `badge`: the theme's Badge at its icon's corner, a number or a dot (true), which `label` should say too. With
9
+ // `href` it is a link (Link: on the site; in the editor only drawn; never a toggle), else a <button type="button">.
10
+ // Other attributes (data-…, disabled) go on it, and `className` after its own classes (its place). An Astro component
11
+ // without React gives an element the same classes with iconButtonClass, and a toggle aria-pressed itself.
12
+ import { Glyph, type IconRef } from '@morphemecms/cms/src/icon';
13
+ import Badge from '@theme/ui/Badge';
14
+ import { Link, type IconButtonKind } from '@morphemecms/cms/src/standard/view';
15
+ import { ToggleIcon, type ButtonShape, type ButtonSize } from '@theme/ui/Button';
16
+
17
+ export const iconButtonWidths = ['narrow', 'default', 'wide'] as const;
18
+ export type IconButtonWidth = (typeof iconButtonWidths)[number];
19
+
20
+ /** An icon button's classes: its kind's and, unless it is small, its size's, unless it is the default width, its
21
+ * width's and, unless it is round, its shape's. */
22
+ export const iconButtonClass = (
23
+ kind: IconButtonKind = 'standard',
24
+ size: ButtonSize = 'small',
25
+ width: IconButtonWidth = 'default',
26
+ shape: ButtonShape = 'round',
27
+ ) =>
28
+ [
29
+ 'icon-button',
30
+ `icon-button-${kind}`,
31
+ size !== 'small' && `icon-button-${size}`,
32
+ width !== 'default' && `icon-button-${width}`,
33
+ shape !== 'round' && `icon-button-${shape}`,
34
+ ]
35
+ .filter(Boolean)
36
+ .join(' ');
37
+
38
+ export default function IconButton({
39
+ icon,
40
+ label,
41
+ kind,
42
+ size,
43
+ width,
44
+ shape,
45
+ selected,
46
+ badge,
47
+ href,
48
+ className,
49
+ ...rest
50
+ }: {
51
+ icon: IconRef;
52
+ label: string;
53
+ kind?: IconButtonKind;
54
+ size?: ButtonSize;
55
+ width?: IconButtonWidth;
56
+ shape?: ButtonShape;
57
+ selected?: boolean;
58
+ badge?: number | boolean;
59
+ href?: string;
60
+ className?: string;
61
+ } & Record<string, unknown>) {
62
+ const classes = [iconButtonClass(kind, size, width, shape), className].filter(Boolean).join(' ');
63
+ const toggle = selected !== undefined && href === undefined;
64
+ const glyph =
65
+ toggle && typeof icon === 'string' ? <ToggleIcon part="icon-button" name={icon} size={22} /> : <Glyph icon={icon} size={22} />;
66
+ const button =
67
+ href === undefined ? (
68
+ <button type="button" aria-label={label} className={classes} aria-pressed={toggle ? selected : undefined} {...rest}>
69
+ {glyph}
70
+ </button>
71
+ ) : (
72
+ <Link href={href} aria-label={label} className={classes} {...rest}>
73
+ {glyph}
74
+ </Link>
75
+ );
76
+ if (!badge) return button;
77
+ return <Badge count={badge === true ? undefined : badge}>{button}</Badge>;
78
+ }
@@ -0,0 +1,287 @@
1
+ // A list (m3.material.io/components/lists, .list in ../styles/ui.css): items under each other (List, a <ul>), each
2
+ // (ListItem, an <li>) with what leads it, its headline, evt. an overline over it (`overline`) and a supporting text
3
+ // under it (`supporting`), and what trails it. Its kind (`kind`: standard, the default, the items on what the list
4
+ // stands on, or segmented, M3 Expressive's, each item on its own surface with a small gap between them) and its dividers
5
+ // (`dividers`: full-width, the default for a standard list, inset, from where the items' text starts, middle-inset or
6
+ // none) are Material's. An item has one, two or three lines (`lines`): with a supporting text two (also when the text
7
+ // is empty, so the items of a list are alike), with an overline too three; a supporting text of two lines needs
8
+ // `lines={3}`. What leads it: `leading` (anything: an icon, a picture, a block's own), or Material's leading
9
+ // kinds, an icon (`leadingIcon`), an avatar (`leadingAvatar`: a letter or a picture), an image (`leadingImage`) or a
10
+ // video's thumbnail (`leadingVideo`). What trails it: a trailing supporting text (`trailingSupporting`: a number, a
11
+ // date), anything (`trailing`: swatches, what is chosen) and an icon (`trailingIcon`: an arrow). With `control` the item is a choice, the theme's
12
+ // Checkbox, RadioButton or Switch before or after its text (`at`; a switch after it, the others before it by default),
13
+ // and a tap anywhere on the item changes it; its name is the headline. `selected`: the chosen one; `disabled`: it
14
+ // cannot be followed or changed. With `href` the item is a link (Link: on the site; in the editor only drawn), with
15
+ // `onClick` a button (what a tap does: the editor's rows), else a <div>; the rest (data-…, aria-…) on it, and
16
+ // `presentation` takes the <li>'s own role away (an item that is an option of a listbox: Search.tsx). `leadingIconSelected`:
17
+ // its icon in the selected colour (the open one, where the item itself is not drawn selected). `truncate`: its texts each
18
+ // on one line, cut off (a name, an address); else they wrap. `columns`: on a wide screen its headline and supporting text
19
+ // side by side, as columns of the list (an address and where it sends to), under each other on a phone. `actions`: secondary actions beside it (icon buttons, a
20
+ // switch), a multi-action item (Material's) with the item its primary action; `children`: what is in its <li> after it
21
+ // (a sheet it opens, a text it folds out). How it looks is the theme's. `className` after the list's own classes (its
22
+ // place in a block), and after an item's own on the item (its place on a screen). An Astro component without React gives its elements the same classes with listClasses and listItemClass.
23
+ // What leads an item, its leading icon, trailing supporting text and trailing icon are parts of their own (ListItemLeading,
24
+ // ListItemLeadingIcon, ListItemTrailingSupporting, ListItemTrailingIcon), so the editor's rows have the same; an icon is its name, as the site
25
+ // gives it, or an icon made, as the editor gives it (IconRef).
26
+ import { useId, type HTMLAttributes, type ReactNode } from 'react';
27
+ import { Glyph, type IconRef } from '@morphemecms/cms/src/icon';
28
+ import { Link } from '@morphemecms/cms/src/standard/view';
29
+ import Checkbox from '@theme/ui/Checkbox';
30
+ import RadioButton from '@theme/ui/RadioButton';
31
+ import Switch, { type SwitchIcons } from '@theme/ui/Switch';
32
+
33
+ /** A list's kinds and dividers, and its items' lines, as Material 3 names them. */
34
+ export type ListKind = 'standard' | 'segmented';
35
+ export type ListDividers = 'full-width' | 'inset' | 'middle-inset' | 'none';
36
+ export type ListItemLines = 1 | 2 | 3;
37
+
38
+ /** A list's class. */
39
+ export const listClass = 'list';
40
+
41
+ /** A list's classes: its kind's (none for standard) and its dividers' (none for full-width; a segmented list has none). */
42
+ export const listClasses = (kind: ListKind = 'standard', dividers: ListDividers = kind === 'segmented' ? 'none' : 'full-width') =>
43
+ [listClass, kind === 'segmented' && 'list-segmented', dividers !== 'full-width' && `list-dividers-${dividers}`].filter(Boolean).join(' ');
44
+
45
+ /** A multi-action item's class (Material's): on what holds an item's container, its primary action (a link or a button
46
+ * with listItemClass), and its secondary actions (icon buttons, a switch) beside it, on one row, which has the primary
47
+ * action's state (pointed at, pressed). Never an <li> of its own: the <li> holds it. */
48
+ export const listItemMultiActionClass = 'list-item-multi-action';
49
+
50
+ /** A list item's classes: its lines' (true is two lines), and selected or disabled. */
51
+ export const listItemClass = (lines: boolean | ListItemLines = 1, state: { selected?: boolean; disabled?: boolean } = {}) => {
52
+ const n = lines === true ? 2 : lines === false ? 1 : lines;
53
+ return [
54
+ 'list-item-container',
55
+ n === 2 && 'list-item-two-line',
56
+ n === 3 && 'list-item-three-line',
57
+ state.selected && 'list-item-selected',
58
+ state.disabled && 'list-item-disabled',
59
+ ]
60
+ .filter(Boolean)
61
+ .join(' ');
62
+ };
63
+
64
+ export default function List({
65
+ kind,
66
+ dividers,
67
+ className,
68
+ children,
69
+ ...rest
70
+ }: { kind?: ListKind; dividers?: ListDividers } & HTMLAttributes<HTMLUListElement>) {
71
+ return (
72
+ <ul className={[listClasses(kind, dividers), className].filter(Boolean).join(' ')} {...rest}>
73
+ {children}
74
+ </ul>
75
+ );
76
+ }
77
+
78
+ /** A picture before an item: its address and what it shows (empty: the headline says it). */
79
+ export type ListItemPicture = { src: string; alt?: string };
80
+
81
+ /** A choice in an item: the theme's checkbox, radio button or switch, before or after the text (`at`). */
82
+ export type ListItemControl = {
83
+ type: 'checkbox' | 'radio-button' | 'switch';
84
+ at?: 'leading' | 'trailing';
85
+ checked?: boolean;
86
+ name?: string;
87
+ value?: string;
88
+ icons?: SwitchIcons;
89
+ };
90
+
91
+ /** What leads an item: anything (a picture, a block's own). */
92
+ export function ListItemLeading({ children }: { children: ReactNode }) {
93
+ return <span className="list-item-leading">{children}</span>;
94
+ }
95
+
96
+ /** What leads an item, an icon (`icon`, or something drawn as one: `children`), in the muted colour; in the selected
97
+ * colour in a selected item, or with `selected` (the open one, where the item itself is not drawn selected). */
98
+ export function ListItemLeadingIcon({ icon, selected, children }: { icon?: IconRef; selected?: boolean; children?: ReactNode }) {
99
+ return (
100
+ <span className={['list-item-leading list-item-leading-icon', selected && 'list-item-leading-icon-selected'].filter(Boolean).join(' ')}>
101
+ {icon ? <Glyph icon={icon} size={24} /> : children}
102
+ </span>
103
+ );
104
+ }
105
+
106
+ /** What trails an item as text: a number, a date. */
107
+ export function ListItemTrailingSupporting({ children }: { children: ReactNode }) {
108
+ return <span className="list-item-trailing-supporting">{children}</span>;
109
+ }
110
+
111
+ /** What trails an item as an icon (an arrow), or anything (`children`). */
112
+ export function ListItemTrailingIcon({ icon, children }: { icon?: IconRef; children?: ReactNode }) {
113
+ return <span className="list-item-trailing">{icon ? <Glyph icon={icon} size={24} /> : children}</span>;
114
+ }
115
+
116
+ export function ListItem({
117
+ href,
118
+ onClick,
119
+ leading,
120
+ leadingIcon,
121
+ leadingIconSelected,
122
+ leadingAvatar,
123
+ leadingImage,
124
+ leadingVideo,
125
+ overline,
126
+ headline,
127
+ supporting,
128
+ trailingSupporting,
129
+ trailingIcon,
130
+ trailing,
131
+ control,
132
+ lines,
133
+ selected,
134
+ disabled,
135
+ presentation,
136
+ truncate,
137
+ columns,
138
+ actions,
139
+ className,
140
+ children,
141
+ ...rest
142
+ }: {
143
+ href?: string;
144
+ onClick?: () => void;
145
+ leading?: ReactNode;
146
+ leadingIcon?: IconRef;
147
+ leadingIconSelected?: boolean;
148
+ leadingAvatar?: string | ListItemPicture;
149
+ leadingImage?: ListItemPicture;
150
+ leadingVideo?: ListItemPicture;
151
+ overline?: ReactNode;
152
+ headline: ReactNode;
153
+ supporting?: ReactNode;
154
+ trailingSupporting?: ReactNode;
155
+ trailingIcon?: IconRef;
156
+ trailing?: ReactNode;
157
+ control?: ListItemControl;
158
+ lines?: ListItemLines;
159
+ selected?: boolean;
160
+ disabled?: boolean;
161
+ presentation?: boolean;
162
+ truncate?: boolean;
163
+ columns?: boolean;
164
+ actions?: ReactNode;
165
+ className?: string;
166
+ children?: ReactNode;
167
+ } & Record<string, unknown>) {
168
+ const id = useId();
169
+ const shown = (v: ReactNode) => v != null && v !== '';
170
+ const n: ListItemLines =
171
+ lines ?? (overline != null && supporting !== undefined ? 3 : supporting !== undefined || overline != null ? 2 : 1);
172
+ const at = control?.at ?? (control?.type === 'switch' ? 'trailing' : 'leading');
173
+
174
+ // The choice: the theme's part, named by the headline and described by the supporting text, without a name of its own.
175
+ const choice = control && (
176
+ <span className="list-item-control">
177
+ {(() => {
178
+ const { type, at: _, icons, ...input } = control;
179
+ const own = {
180
+ ...input,
181
+ label: '',
182
+ id: `${id}-control`,
183
+ disabled,
184
+ 'aria-labelledby': `${id}-headline`,
185
+ 'aria-describedby': shown(supporting) ? `${id}-supporting` : undefined,
186
+ };
187
+ return type === 'checkbox' ? (
188
+ <Checkbox {...own} />
189
+ ) : type === 'radio-button' ? (
190
+ <RadioButton {...own} />
191
+ ) : (
192
+ <Switch icons={icons} {...own} />
193
+ );
194
+ })()}
195
+ </span>
196
+ );
197
+
198
+ const picture = (p: ListItemPicture, kind: string) => (
199
+ <img src={p.src} alt={p.alt ?? ''} className={`list-item-${kind}`} loading="lazy" />
200
+ );
201
+ const lead =
202
+ control && at === 'leading' ? (
203
+ choice
204
+ ) : leading != null ? (
205
+ <ListItemLeading>{leading}</ListItemLeading>
206
+ ) : leadingIcon ? (
207
+ <ListItemLeadingIcon icon={leadingIcon} selected={leadingIconSelected} />
208
+ ) : typeof leadingAvatar === 'string' ? (
209
+ <span className="list-item-leading list-item-leading-avatar" aria-hidden="true">
210
+ <span className="list-item-avatar">{leadingAvatar}</span>
211
+ </span>
212
+ ) : leadingAvatar ? (
213
+ <span className="list-item-leading list-item-leading-avatar">{picture(leadingAvatar, 'avatar')}</span>
214
+ ) : leadingImage ? (
215
+ <span className="list-item-leading list-item-leading-image">{picture(leadingImage, 'image')}</span>
216
+ ) : leadingVideo ? (
217
+ <span className="list-item-leading list-item-leading-video">{picture(leadingVideo, 'video')}</span>
218
+ ) : null;
219
+
220
+ const cut = truncate ? ' truncate' : '';
221
+ const text = (
222
+ <>
223
+ {shown(overline) && <span className="list-item-overline">{overline}</span>}
224
+ {/* Ids only for a choice, which they name and describe. */}
225
+ <span id={control && `${id}-headline`} className={`list-item-headline${cut}`}>
226
+ {headline}
227
+ </span>
228
+ {shown(supporting) && (
229
+ <span id={control && `${id}-supporting`} className={`list-item-supporting${cut}`}>
230
+ {supporting}
231
+ </span>
232
+ )}
233
+ </>
234
+ );
235
+ const tail = (shown(trailingSupporting) || trailingIcon || trailing != null || (control && at === 'trailing')) && (
236
+ <>
237
+ {shown(trailingSupporting) && <ListItemTrailingSupporting>{trailingSupporting}</ListItemTrailingSupporting>}
238
+ {trailing != null && <ListItemTrailingIcon>{trailing}</ListItemTrailingIcon>}
239
+ {trailingIcon && <ListItemTrailingIcon icon={trailingIcon} />}
240
+ {control && at === 'trailing' && choice}
241
+ </>
242
+ );
243
+ const content = (
244
+ <>
245
+ {lead}
246
+ {control ? (
247
+ // A second name for the choice's <input>, so a tap on the text (and, stretched, on the whole item) changes it.
248
+ <label htmlFor={`${id}-control`} className="list-item-content">
249
+ {text}
250
+ </label>
251
+ ) : (
252
+ <span className="list-item-content">{text}</span>
253
+ )}
254
+ {tail}
255
+ </>
256
+ );
257
+ const classes = [listItemClass(n, { selected, disabled }), control && 'list-item-with-control', columns && 'list-item-columns', className]
258
+ .filter(Boolean)
259
+ .join(' ');
260
+ const item =
261
+ href !== undefined && !control && !disabled ? (
262
+ <Link href={href} className={classes} aria-current={selected ? 'true' : undefined} {...rest}>
263
+ {content}
264
+ </Link>
265
+ ) : onClick && !control ? (
266
+ <button type="button" className={classes} disabled={disabled} onClick={onClick} {...rest}>
267
+ {content}
268
+ </button>
269
+ ) : (
270
+ <div className={classes} aria-disabled={disabled && href !== undefined ? true : undefined} {...rest}>
271
+ {content}
272
+ </div>
273
+ );
274
+ return (
275
+ <li role={presentation ? 'presentation' : undefined}>
276
+ {actions != null && actions !== false ? (
277
+ <div className={listItemMultiActionClass}>
278
+ {item}
279
+ {actions}
280
+ </div>
281
+ ) : (
282
+ item
283
+ )}
284
+ {children}
285
+ </li>
286
+ );
287
+ }
@@ -0,0 +1,29 @@
1
+ // A loading indicator (M3 Expressive, m3.material.io/components/loading-indicator, .loading-indicator in
2
+ // ../styles/ui.css): a shape that turns and changes from one of Material's shapes into the next, while something that
3
+ // takes only a moment is on its way (where how far it has come is known, a progress indicator says it instead). By
4
+ // itself, or in its round container (`contained`, where it stands on something else). Screen readers read it as a
5
+ // progress bar without a value, named by `label` (e.g. "Henter …"). With reduced motion it only turns, slowly. How it
6
+ // looks is the theme's (--loading-indicator-*). An Astro component gives an element the same classes with
7
+ // loadingIndicatorClass, with a .loading-indicator-shape in it.
8
+
9
+ /** A loading indicator's classes, with its container or without. */
10
+ export const loadingIndicatorClass = (contained?: boolean) =>
11
+ ['loading-indicator', contained && 'loading-indicator-contained'].filter(Boolean).join(' ');
12
+
13
+ export default function LoadingIndicator({
14
+ label,
15
+ contained,
16
+ className,
17
+ ...rest
18
+ }: { label: string; contained?: boolean; className?: string } & Record<string, unknown>) {
19
+ return (
20
+ <span
21
+ role="progressbar"
22
+ aria-label={label}
23
+ className={[loadingIndicatorClass(contained), className].filter(Boolean).join(' ')}
24
+ {...rest}
25
+ >
26
+ <span className="loading-indicator-shape"></span>
27
+ </span>
28
+ );
29
+ }
@@ -0,0 +1,278 @@
1
+ // A menu (m3.material.io/components/menus, .menu in ../styles/ui.css): choices on a surface (Menu, a <ul>), each a menu
2
+ // item (MenuItem, .menu-item). The header's pages under an item (components/Header.astro, and a theme's own header)
3
+ // and a split button's other ways (SplitButton.tsx) are menus of links; an Astro header gives its elements the classes
4
+ // with menuClass and menuItemClass. A menu's colour (`color`: standard, the default, on the surface; vibrant, in the
5
+ // accent) and its groups (MenuGroup, evt. with a name over them; `groups`: each group on its own surface with a gap
6
+ // between them, the default, or one surface with a divider between them) are Material's (M3 Expressive); a divider
7
+ // between items is MenuDivider (the theme's Divider). An item is a link (`href`; Link: on the site, in the editor only
8
+ // drawn) or an action (a <button>; the rest, data-… and `onClick`, on it), with its icon (`icon`), a line under its
9
+ // label (`supporting`), a shortcut or a value at its end (`trailingSupporting`) and an icon there (`trailingIcon`); an
10
+ // icon is its name, or an icon made (IconRef: the editor's).
11
+ // `selected`: the open page (a link) or the chosen one of a few (an action); `checked`: an action that is on or off,
12
+ // with the theme's tick (`check`) before it when it is on; `disabled`: it cannot be chosen. With `submenu` (its items)
13
+ // the item opens another menu beside it, with an arrow (`open`: drawn open, the editor).
14
+ //
15
+ // A dropdown menu (DropdownMenu) is a menu a button opens on the site: the theme's Button (`label`, `icon`, `kind`,
16
+ // `size`, with an arrow) or IconButton (`iconButton`: only the icon, `label` its name), and the menu, a WAI-ARIA
17
+ // menu (role="menu", its items menuitem, menuitemcheckbox or menuitemradio). It opens as a popover (popovertarget), so
18
+ // it opens, closes with Escape and a tap outside, and stands over everything also without JavaScript; it is placed at
19
+ // the button with CSS anchor positioning. On the site ui/dropdownMenu.script.ts gives it the keyboard of WAI-ARIA's
20
+ // menu button (the arrow keys, Home, End, a letter, Escape, Tab, and the arrow keys into and out of a submenu), places
21
+ // it where anchor positioning is missing, opens a submenu when the mouse rests on its item, and ticks and chooses
22
+ // items. `open` draws it open (the editor). How all of it looks is the theme's.
23
+ import { createContext, useContext, useId, type CSSProperties, type ReactNode } from 'react';
24
+ import { Glyph, Svg, type IconRef } from '@morphemecms/cms/src/icon';
25
+ import { Link, type ButtonKind } from '@morphemecms/cms/src/standard/view';
26
+ import Button, { type ButtonSize } from '@theme/ui/Button';
27
+ import IconButton from '@theme/ui/IconButton';
28
+ import Divider from '@theme/ui/Divider';
29
+
30
+ /** A menu's colours, and how its groups stand apart, as Material 3 names them. */
31
+ export type MenuColor = 'standard' | 'vibrant';
32
+ export type MenuGroups = 'gap' | 'divider';
33
+
34
+ /** A menu's class, and its items'. */
35
+ export const menuClass = 'menu';
36
+ export const menuItemClass = 'menu-item';
37
+
38
+ /** A menu's classes: its colour's (none for standard) and, with groups divided by a line, `menu-groups-divider`. */
39
+ export const menuClasses = (color: MenuColor = 'standard', groups: MenuGroups = 'gap') =>
40
+ [menuClass, color === 'vibrant' && 'menu-vibrant', groups === 'divider' && 'menu-groups-divider'].filter(Boolean).join(' ');
41
+
42
+ // Inside a WAI-ARIA menu (a dropdown menu and its submenus) the items are menu items; elsewhere (the header's pages, a
43
+ // split button's ways) links and buttons in a list.
44
+ const InMenu = createContext(false);
45
+
46
+ // A CSS anchor's name from an id React made (only letters, digits, - and _).
47
+ const anchorOf = (id: string) => `--menu-${id.replace(/[^\w-]/g, '')}`;
48
+
49
+ export function Menu({
50
+ color,
51
+ groups,
52
+ className,
53
+ children,
54
+ ...rest
55
+ }: { color?: MenuColor; groups?: MenuGroups; className?: string; children: ReactNode } & Record<string, unknown>) {
56
+ const inMenu = useContext(InMenu) || rest.role === 'menu';
57
+ return (
58
+ <InMenu.Provider value={inMenu}>
59
+ <ul className={[menuClasses(color, groups), className].filter(Boolean).join(' ')} {...rest}>
60
+ {children}
61
+ </ul>
62
+ </InMenu.Provider>
63
+ );
64
+ }
65
+
66
+ /** A group of a menu's items, evt. under its name (`label`): its own surface, or after a divider (Menu's `groups`). */
67
+ export function MenuGroup({ label, children }: { label?: string; children: ReactNode }) {
68
+ const inMenu = useContext(InMenu);
69
+ const id = useId();
70
+ return (
71
+ <li className="menu-group" role={inMenu ? 'none' : undefined}>
72
+ {label && (
73
+ // In a menu the group is named by it, and only the group is read.
74
+ <span id={id} className="menu-group-label" aria-hidden={inMenu || undefined}>
75
+ {label}
76
+ </span>
77
+ )}
78
+ <ul className="menu-group-items" role={inMenu ? 'group' : undefined} aria-labelledby={label ? id : undefined}>
79
+ {children}
80
+ </ul>
81
+ </li>
82
+ );
83
+ }
84
+
85
+ /** A line between a menu's items (the theme's Divider). */
86
+ export function MenuDivider() {
87
+ return (
88
+ <li className="menu-divider" role="none">
89
+ <Divider />
90
+ </li>
91
+ );
92
+ }
93
+
94
+ export function MenuItem({
95
+ href,
96
+ selected,
97
+ checked,
98
+ disabled,
99
+ icon,
100
+ trailingIcon,
101
+ supporting,
102
+ trailingSupporting,
103
+ submenu,
104
+ open,
105
+ children,
106
+ ...rest
107
+ }: {
108
+ href?: string;
109
+ selected?: boolean;
110
+ checked?: boolean;
111
+ disabled?: boolean;
112
+ icon?: IconRef;
113
+ trailingIcon?: IconRef;
114
+ supporting?: ReactNode;
115
+ trailingSupporting?: ReactNode;
116
+ submenu?: ReactNode;
117
+ open?: boolean;
118
+ children: ReactNode;
119
+ } & Record<string, unknown>) {
120
+ const inMenu = useContext(InMenu);
121
+ const id = useId();
122
+ const action = href === undefined || submenu !== undefined;
123
+ // Its role in a menu, and what it says of its state: a link the open page, an action ticked or chosen.
124
+ const role = !inMenu
125
+ ? undefined
126
+ : submenu === undefined && checked !== undefined
127
+ ? 'menuitemcheckbox'
128
+ : submenu === undefined && action && selected !== undefined
129
+ ? 'menuitemradio'
130
+ : 'menuitem';
131
+ const state =
132
+ role === 'menuitemcheckbox'
133
+ ? { 'aria-checked': checked }
134
+ : role === 'menuitemradio'
135
+ ? { 'aria-checked': Boolean(selected) }
136
+ : !inMenu && action && checked !== undefined
137
+ ? { 'aria-pressed': checked }
138
+ : selected
139
+ ? { 'aria-current': action ? ('true' as const) : ('page' as const) }
140
+ : {};
141
+ const content = (
142
+ <>
143
+ {(icon || checked !== undefined) && (
144
+ <span className="menu-item-leading">
145
+ {icon && <Glyph icon={icon} size={20} className="menu-item-icon" />}
146
+ {checked !== undefined && <Svg name="check" size={20} className="menu-item-check" />}
147
+ </span>
148
+ )}
149
+ <span className="menu-item-text">
150
+ <span className="menu-item-label">{children}</span>
151
+ {supporting != null && supporting !== '' && <span className="menu-item-supporting">{supporting}</span>}
152
+ </span>
153
+ {trailingSupporting != null && trailingSupporting !== '' && (
154
+ <span className="menu-item-trailing-supporting">{trailingSupporting}</span>
155
+ )}
156
+ {trailingIcon && <Glyph icon={trailingIcon} size={20} className="menu-item-trailing-icon" />}
157
+ {submenu !== undefined && <Svg name="caret-right" size={20} className="menu-item-trailing-icon menu-item-submenu-icon" />}
158
+ </>
159
+ );
160
+
161
+ if (submenu !== undefined) {
162
+ const menu = `${id}-menu`;
163
+ const anchor = anchorOf(id);
164
+ return (
165
+ <li className="menu-item-submenu" role={inMenu ? 'none' : undefined}>
166
+ <button
167
+ type="button"
168
+ id={id}
169
+ className={menuItemClass}
170
+ role={role}
171
+ aria-haspopup={inMenu ? 'menu' : undefined}
172
+ aria-expanded={open ? true : undefined}
173
+ aria-controls={menu}
174
+ popoverTarget={open ? undefined : menu}
175
+ disabled={disabled}
176
+ style={{ anchorName: anchor } as CSSProperties}
177
+ {...rest}
178
+ >
179
+ {content}
180
+ </button>
181
+ <ul
182
+ id={menu}
183
+ className={`${menuClass} menu-submenu`}
184
+ role={inMenu ? 'menu' : undefined}
185
+ aria-labelledby={id}
186
+ popover={open ? undefined : 'auto'}
187
+ style={{ positionAnchor: anchor } as CSSProperties}
188
+ >
189
+ {submenu}
190
+ </ul>
191
+ </li>
192
+ );
193
+ }
194
+ return (
195
+ <li role={inMenu ? 'none' : undefined}>
196
+ {!action && !disabled ? (
197
+ <Link href={href!} className={menuItemClass} role={role} {...state} {...rest}>
198
+ {content}
199
+ </Link>
200
+ ) : !action ? (
201
+ // A link that cannot be followed: no address, so it is no link.
202
+ <a className={menuItemClass} role={role} aria-disabled="true" {...state}>
203
+ {content}
204
+ </a>
205
+ ) : (
206
+ <button type="button" className={menuItemClass} role={role} disabled={disabled} {...state} {...rest}>
207
+ {content}
208
+ </button>
209
+ )}
210
+ </li>
211
+ );
212
+ }
213
+
214
+ /** A menu a button opens (see the top of the file): the button (`label`, evt. `icon`, `kind` outlined by default,
215
+ * `size`; `iconButton`: only the icon) and its items (`children`: MenuItem, MenuGroup, MenuDivider). `className` on
216
+ * the whole, the rest on the button. */
217
+ export function DropdownMenu({
218
+ label,
219
+ icon,
220
+ iconButton,
221
+ kind = 'outlined',
222
+ size,
223
+ color,
224
+ groups,
225
+ open,
226
+ className,
227
+ children,
228
+ ...rest
229
+ }: {
230
+ label: string;
231
+ icon?: string;
232
+ iconButton?: boolean;
233
+ kind?: ButtonKind;
234
+ size?: ButtonSize;
235
+ color?: MenuColor;
236
+ groups?: MenuGroups;
237
+ open?: boolean;
238
+ className?: string;
239
+ children: ReactNode;
240
+ } & Record<string, unknown>) {
241
+ const id = useId();
242
+ const menu = `${id}-menu`;
243
+ const anchor = anchorOf(id);
244
+ const button = {
245
+ id,
246
+ 'aria-haspopup': 'menu',
247
+ 'aria-expanded': open ? true : undefined,
248
+ 'aria-controls': menu,
249
+ popoverTarget: open ? undefined : menu,
250
+ style: { anchorName: anchor } as CSSProperties,
251
+ 'data-dropdown-menu-button': '',
252
+ ...rest,
253
+ };
254
+ return (
255
+ <div className={['dropdown-menu', className].filter(Boolean).join(' ')} data-dropdown-menu="">
256
+ {iconButton ? (
257
+ <IconButton icon={icon ?? 'list'} label={label} {...button} />
258
+ ) : (
259
+ <Button kind={kind} size={size} icon={icon} trailingIcon="caret-down" {...button}>
260
+ {label}
261
+ </Button>
262
+ )}
263
+ <Menu
264
+ id={menu}
265
+ role="menu"
266
+ aria-labelledby={id}
267
+ color={color}
268
+ groups={groups}
269
+ className="dropdown-menu-menu"
270
+ popover={open ? undefined : 'auto'}
271
+ style={{ positionAnchor: anchor } as CSSProperties}
272
+ data-dropdown-menu-menu=""
273
+ >
274
+ {children}
275
+ </Menu>
276
+ </div>
277
+ );
278
+ }