@morphemecms/cms 0.1.0 → 0.2.0-next-20261104150211

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