@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.
- package/CHANGELOG.md +12 -0
- package/LICENSE +21 -21
- package/README.md +51 -51
- package/astro.mjs +162 -162
- package/bin/morpheme.mjs +38 -38
- package/client.d.ts +10 -10
- package/defaults/blockTexts.ts +33 -33
- package/defaults/collections.ts +774 -774
- package/defaults/colors.ts +125 -125
- package/defaults/company.ts +20 -20
- package/defaults/editor.ts +178 -178
- package/defaults/internalLinks.ts +30 -30
- package/defaults/opens.ts +18 -18
- package/defaults/popup.tsx +93 -93
- package/defaults/privacy.ts +79 -79
- package/defaults/rules.ts +450 -450
- package/defaults/schema.ts +16 -16
- package/defaults/sitedata.ts +129 -129
- package/defaults/standard.ts +106 -106
- package/defaults/standardPages.ts +87 -87
- package/defaults/texts.ts +481 -481
- package/demo/README.md +26 -26
- package/demo/src/content/blog/build-a-page-from-blocks.md +19 -19
- package/demo/src/content/blog/colors-everyone-can-read.md +19 -19
- package/demo/src/content/blog/edit-your-website-from-your-phone.md +21 -21
- package/demo/src/content/blog/every-save-is-a-version.md +21 -21
- package/demo/src/content/blog/schedule-a-post.md +17 -17
- package/demo/src/content/blog/secure-from-day-one.md +17 -17
- package/demo/src/content/blog/seo-without-the-guesswork.md +23 -23
- package/demo/src/content/blog/switch-themes-without-losing-anything.md +23 -23
- package/demo/src/content/blog/the-app-store.md +21 -21
- package/demo/src/content/pages/about.md +22 -22
- package/demo/src/content/pages/app-store.md +30 -30
- package/demo/src/content/pages/blocks.md +98 -98
- package/demo/src/content/pages/blog-page.md +11 -11
- package/demo/src/content/pages/contact.md +16 -16
- package/demo/src/content/pages/get-started.md +20 -20
- package/demo/src/content/pages/home.md +26 -26
- package/demo/src/content/pages/page-not-found.md +11 -11
- package/demo/src/content/pages/privacy-policy.md +24 -24
- package/demo/src/data/blocks.json +25 -25
- package/demo/src/data/booking.json +6 -6
- package/demo/src/data/categories/apps.json +6 -6
- package/demo/src/data/categories/design.json +6 -6
- package/demo/src/data/categories/editing.json +6 -6
- package/demo/src/data/categories/security.json +6 -6
- package/demo/src/data/categories/seo.json +6 -6
- package/demo/src/data/colors.json +75 -75
- package/demo/src/data/contact.json +8 -8
- package/demo/src/data/cookies.json +21 -21
- package/demo/src/data/footer.json +27 -27
- package/demo/src/data/menu.json +35 -35
- package/demo/src/data/mobile-menu.json +25 -25
- package/demo/src/data/popups/booking-bar.json +13 -13
- package/demo/src/data/popups/try-the-editor.json +16 -16
- package/demo/src/data/standard-pages.json +8 -8
- package/demo/src/data/testimonials/sample-bakery.json +10 -10
- package/demo/src/data/testimonials/sample-clinic.json +10 -10
- package/demo/src/data/testimonials/sample-studio.json +10 -10
- package/demo/src/site/colors.ts +11 -11
- package/demo/src/site/config.ts +19 -19
- package/icons/lucide/LICENSE +43 -43
- package/icons/lucide/address-book.svg +1 -1
- package/icons/lucide/app-window.svg +1 -1
- package/icons/lucide/arrow-counter-clockwise.svg +1 -1
- package/icons/lucide/arrow-down.svg +1 -1
- package/icons/lucide/arrow-left.svg +1 -1
- package/icons/lucide/arrow-right.svg +1 -1
- package/icons/lucide/arrow-square-out.svg +1 -1
- package/icons/lucide/arrow-u-up-left.svg +1 -1
- package/icons/lucide/arrow-u-up-right.svg +1 -1
- package/icons/lucide/arrow-up-right.svg +1 -1
- package/icons/lucide/arrow-up.svg +1 -1
- package/icons/lucide/arrows-down-up.svg +1 -1
- package/icons/lucide/arrows-in-line-horizontal.svg +1 -1
- package/icons/lucide/arrows-out-line-horizontal.svg +1 -1
- package/icons/lucide/article.svg +1 -1
- package/icons/lucide/bank.svg +1 -1
- package/icons/lucide/bell.svg +1 -1
- package/icons/lucide/bicycle.svg +1 -1
- package/icons/lucide/binoculars.svg +1 -1
- package/icons/lucide/book-open-text.svg +1 -1
- package/icons/lucide/book-open.svg +1 -1
- package/icons/lucide/browser.svg +1 -1
- package/icons/lucide/buildings.svg +1 -1
- package/icons/lucide/bus.svg +1 -1
- package/icons/lucide/calendar-blank.svg +1 -1
- package/icons/lucide/calendar-check.svg +1 -1
- package/icons/lucide/car.svg +1 -1
- package/icons/lucide/cards.svg +1 -1
- package/icons/lucide/caret-down.svg +1 -1
- package/icons/lucide/caret-left.svg +1 -1
- package/icons/lucide/caret-right.svg +1 -1
- package/icons/lucide/caret-up.svg +1 -1
- package/icons/lucide/certificate.svg +1 -1
- package/icons/lucide/chart-line-up.svg +1 -1
- package/icons/lucide/chats.svg +1 -1
- package/icons/lucide/check-circle.svg +1 -1
- package/icons/lucide/check.svg +1 -1
- package/icons/lucide/circle-half.svg +1 -1
- package/icons/lucide/circle.svg +1 -1
- package/icons/lucide/clock-counter-clockwise.svg +1 -1
- package/icons/lucide/clock.svg +1 -1
- package/icons/lucide/code.svg +1 -1
- package/icons/lucide/coffee.svg +1 -1
- package/icons/lucide/columns.svg +1 -1
- package/icons/lucide/cookie.svg +1 -1
- package/icons/lucide/copy.svg +1 -1
- package/icons/lucide/credit-card.svg +1 -1
- package/icons/lucide/currency-circle-dollar.svg +1 -1
- package/icons/lucide/cursor-click.svg +1 -1
- package/icons/lucide/database.svg +1 -1
- package/icons/lucide/desktop.svg +1 -1
- package/icons/lucide/device-mobile.svg +1 -1
- package/icons/lucide/door-open.svg +1 -1
- package/icons/lucide/download-simple.svg +1 -1
- package/icons/lucide/envelope-simple.svg +1 -1
- package/icons/lucide/eye-slash.svg +1 -1
- package/icons/lucide/eye.svg +1 -1
- package/icons/lucide/file-pdf.svg +1 -1
- package/icons/lucide/file-text.svg +1 -1
- package/icons/lucide/file-video.svg +1 -1
- package/icons/lucide/file-zip.svg +1 -1
- package/icons/lucide/flower-lotus.svg +1 -1
- package/icons/lucide/folder-simple.svg +1 -1
- package/icons/lucide/funnel.svg +1 -1
- package/icons/lucide/gauge.svg +1 -1
- package/icons/lucide/gear.svg +1 -1
- package/icons/lucide/github-logo.svg +1 -1
- package/icons/lucide/globe.svg +1 -1
- package/icons/lucide/google-logo.svg +1 -1
- package/icons/lucide/graduation-cap.svg +1 -1
- package/icons/lucide/hammer.svg +1 -1
- package/icons/lucide/hand-heart.svg +1 -1
- package/icons/lucide/handshake.svg +1 -1
- package/icons/lucide/hard-drives.svg +1 -1
- package/icons/lucide/heart.svg +1 -1
- package/icons/lucide/house.svg +1 -1
- package/icons/lucide/image-square.svg +1 -1
- package/icons/lucide/image.svg +1 -1
- package/icons/lucide/info.svg +1 -1
- package/icons/lucide/keyboard.svg +1 -1
- package/icons/lucide/leaf.svg +1 -1
- package/icons/lucide/lifebuoy.svg +1 -1
- package/icons/lucide/lightbulb.svg +1 -1
- package/icons/lucide/link-break.svg +1 -1
- package/icons/lucide/link-simple.svg +1 -1
- package/icons/lucide/list-bullets.svg +1 -1
- package/icons/lucide/list-checks.svg +1 -1
- package/icons/lucide/list-numbers.svg +1 -1
- package/icons/lucide/list.svg +1 -1
- package/icons/lucide/lock-simple-open.svg +1 -1
- package/icons/lucide/lock-simple.svg +1 -1
- package/icons/lucide/magnifying-glass.svg +1 -1
- package/icons/lucide/map-pin.svg +1 -1
- package/icons/lucide/map-trifold.svg +1 -1
- package/icons/lucide/medal.svg +1 -1
- package/icons/lucide/megaphone.svg +1 -1
- package/icons/lucide/minus.svg +1 -1
- package/icons/lucide/moon.svg +1 -1
- package/icons/lucide/newspaper.svg +1 -1
- package/icons/lucide/pack.json +23 -23
- package/icons/lucide/paint-brush-broad.svg +1 -1
- package/icons/lucide/palette.svg +1 -1
- package/icons/lucide/paper-plane-tilt.svg +1 -1
- package/icons/lucide/pencil-simple.svg +1 -1
- package/icons/lucide/phone.svg +1 -1
- package/icons/lucide/play-fill.svg +1 -1
- package/icons/lucide/plus.svg +1 -1
- package/icons/lucide/prohibit.svg +1 -1
- package/icons/lucide/puzzle-piece.svg +1 -1
- package/icons/lucide/question.svg +1 -1
- package/icons/lucide/quotes.svg +1 -1
- package/icons/lucide/rows.svg +1 -1
- package/icons/lucide/ruler.svg +1 -1
- package/icons/lucide/scan.svg +1 -1
- package/icons/lucide/shapes.svg +1 -1
- package/icons/lucide/share-network.svg +1 -1
- package/icons/lucide/shield-check.svg +1 -1
- package/icons/lucide/sidebar-simple.svg +1 -1
- package/icons/lucide/sign-out.svg +1 -1
- package/icons/lucide/signpost.svg +1 -1
- package/icons/lucide/sliders-horizontal.svg +1 -1
- package/icons/lucide/smiley.svg +1 -1
- package/icons/lucide/sparkle.svg +1 -1
- package/icons/lucide/square-half-bottom.svg +1 -1
- package/icons/lucide/square.svg +1 -1
- package/icons/lucide/squares-four.svg +1 -1
- package/icons/lucide/sticker.svg +1 -1
- package/icons/lucide/storefront.svg +1 -1
- package/icons/lucide/sun.svg +1 -1
- package/icons/lucide/swatches.svg +1 -1
- package/icons/lucide/tag.svg +1 -1
- package/icons/lucide/text-aa.svg +1 -1
- package/icons/lucide/text-align-left.svg +1 -1
- package/icons/lucide/text-b.svg +1 -1
- package/icons/lucide/text-h-one.svg +1 -1
- package/icons/lucide/text-h-three.svg +1 -1
- package/icons/lucide/text-h-two.svg +1 -1
- package/icons/lucide/text-italic.svg +1 -1
- package/icons/lucide/text-t.svg +1 -1
- package/icons/lucide/ticket.svg +1 -1
- package/icons/lucide/toggle-right.svg +1 -1
- package/icons/lucide/train.svg +1 -1
- package/icons/lucide/trash.svg +1 -1
- package/icons/lucide/upload-simple.svg +1 -1
- package/icons/lucide/user-circle.svg +1 -1
- package/icons/lucide/user.svg +1 -1
- package/icons/lucide/users-three.svg +1 -1
- package/icons/lucide/users.svg +1 -1
- package/icons/lucide/video-camera.svg +1 -1
- package/icons/lucide/warning-circle.svg +1 -1
- package/icons/lucide/warning.svg +1 -1
- package/icons/lucide/wave-sine.svg +1 -1
- package/icons/lucide/wheelchair.svg +1 -1
- package/icons/lucide/wrench.svg +1 -1
- package/icons/lucide/x.svg +1 -1
- package/icons/material-symbols/LICENSE +201 -201
- package/icons/material-symbols/address-book.svg +1 -1
- package/icons/material-symbols/app-window.svg +1 -1
- package/icons/material-symbols/arrow-counter-clockwise.svg +1 -1
- package/icons/material-symbols/arrow-down.svg +1 -1
- package/icons/material-symbols/arrow-left.svg +1 -1
- package/icons/material-symbols/arrow-right.svg +1 -1
- package/icons/material-symbols/arrow-square-out.svg +1 -1
- package/icons/material-symbols/arrow-u-up-left.svg +1 -1
- package/icons/material-symbols/arrow-u-up-right.svg +1 -1
- package/icons/material-symbols/arrow-up-right.svg +1 -1
- package/icons/material-symbols/arrow-up.svg +1 -1
- package/icons/material-symbols/arrows-down-up.svg +1 -1
- package/icons/material-symbols/arrows-in-line-horizontal.svg +1 -1
- package/icons/material-symbols/arrows-out-line-horizontal.svg +1 -1
- package/icons/material-symbols/article.svg +1 -1
- package/icons/material-symbols/bank.svg +1 -1
- package/icons/material-symbols/bell.svg +1 -1
- package/icons/material-symbols/bicycle.svg +1 -1
- package/icons/material-symbols/binoculars.svg +1 -1
- package/icons/material-symbols/book-open-text.svg +1 -1
- package/icons/material-symbols/book-open.svg +1 -1
- package/icons/material-symbols/browser.svg +1 -1
- package/icons/material-symbols/buildings.svg +1 -1
- package/icons/material-symbols/bus.svg +1 -1
- package/icons/material-symbols/calendar-blank.svg +1 -1
- package/icons/material-symbols/calendar-check.svg +1 -1
- package/icons/material-symbols/car.svg +1 -1
- package/icons/material-symbols/cards.svg +1 -1
- package/icons/material-symbols/caret-down.svg +1 -1
- package/icons/material-symbols/caret-left.svg +1 -1
- package/icons/material-symbols/caret-right.svg +1 -1
- package/icons/material-symbols/caret-up.svg +1 -1
- package/icons/material-symbols/certificate.svg +1 -1
- package/icons/material-symbols/chart-line-up.svg +1 -1
- package/icons/material-symbols/chats.svg +1 -1
- package/icons/material-symbols/check-circle.svg +1 -1
- package/icons/material-symbols/check.svg +1 -1
- package/icons/material-symbols/circle-half.svg +1 -1
- package/icons/material-symbols/circle.svg +1 -1
- package/icons/material-symbols/clock-counter-clockwise.svg +1 -1
- package/icons/material-symbols/clock.svg +1 -1
- package/icons/material-symbols/code.svg +1 -1
- package/icons/material-symbols/coffee.svg +1 -1
- package/icons/material-symbols/columns.svg +1 -1
- package/icons/material-symbols/cookie.svg +1 -1
- package/icons/material-symbols/copy.svg +1 -1
- package/icons/material-symbols/credit-card.svg +1 -1
- package/icons/material-symbols/currency-circle-dollar.svg +1 -1
- package/icons/material-symbols/cursor-click.svg +1 -1
- package/icons/material-symbols/database.svg +1 -1
- package/icons/material-symbols/desktop.svg +1 -1
- package/icons/material-symbols/device-mobile.svg +1 -1
- package/icons/material-symbols/door-open.svg +1 -1
- package/icons/material-symbols/download-simple.svg +1 -1
- package/icons/material-symbols/envelope-simple.svg +1 -1
- package/icons/material-symbols/eye-slash.svg +1 -1
- package/icons/material-symbols/eye.svg +1 -1
- package/icons/material-symbols/file-pdf.svg +1 -1
- package/icons/material-symbols/file-text.svg +1 -1
- package/icons/material-symbols/file-video.svg +1 -1
- package/icons/material-symbols/file-zip.svg +1 -1
- package/icons/material-symbols/flower-lotus.svg +1 -1
- package/icons/material-symbols/folder-simple.svg +1 -1
- package/icons/material-symbols/funnel.svg +1 -1
- package/icons/material-symbols/gauge.svg +1 -1
- package/icons/material-symbols/gear.svg +1 -1
- package/icons/material-symbols/github-logo.svg +1 -1
- package/icons/material-symbols/globe.svg +1 -1
- package/icons/material-symbols/google-logo.svg +1 -1
- package/icons/material-symbols/graduation-cap.svg +1 -1
- package/icons/material-symbols/hammer.svg +1 -1
- package/icons/material-symbols/hand-heart.svg +1 -1
- package/icons/material-symbols/handshake.svg +1 -1
- package/icons/material-symbols/hard-drives.svg +1 -1
- package/icons/material-symbols/heart.svg +1 -1
- package/icons/material-symbols/house.svg +1 -1
- package/icons/material-symbols/image-square.svg +1 -1
- package/icons/material-symbols/image.svg +1 -1
- package/icons/material-symbols/info.svg +1 -1
- package/icons/material-symbols/keyboard.svg +1 -1
- package/icons/material-symbols/leaf.svg +1 -1
- package/icons/material-symbols/lifebuoy.svg +1 -1
- package/icons/material-symbols/lightbulb.svg +1 -1
- package/icons/material-symbols/link-break.svg +1 -1
- package/icons/material-symbols/link-simple.svg +1 -1
- package/icons/material-symbols/list-bullets.svg +1 -1
- package/icons/material-symbols/list-checks.svg +1 -1
- package/icons/material-symbols/list-numbers.svg +1 -1
- package/icons/material-symbols/list.svg +1 -1
- package/icons/material-symbols/lock-simple-open.svg +1 -1
- package/icons/material-symbols/lock-simple.svg +1 -1
- package/icons/material-symbols/magnifying-glass.svg +1 -1
- package/icons/material-symbols/map-pin.svg +1 -1
- package/icons/material-symbols/map-trifold.svg +1 -1
- package/icons/material-symbols/medal.svg +1 -1
- package/icons/material-symbols/megaphone.svg +1 -1
- package/icons/material-symbols/minus.svg +1 -1
- package/icons/material-symbols/moon.svg +1 -1
- package/icons/material-symbols/newspaper.svg +1 -1
- package/icons/material-symbols/pack.json +29 -29
- package/icons/material-symbols/paint-brush-broad.svg +1 -1
- package/icons/material-symbols/palette.svg +1 -1
- package/icons/material-symbols/paper-plane-tilt.svg +1 -1
- package/icons/material-symbols/pencil-simple.svg +1 -1
- package/icons/material-symbols/phone.svg +1 -1
- package/icons/material-symbols/play-fill.svg +1 -1
- package/icons/material-symbols/plus.svg +1 -1
- package/icons/material-symbols/prohibit.svg +1 -1
- package/icons/material-symbols/puzzle-piece.svg +1 -1
- package/icons/material-symbols/question.svg +1 -1
- package/icons/material-symbols/quotes.svg +1 -1
- package/icons/material-symbols/rows.svg +1 -1
- package/icons/material-symbols/ruler.svg +1 -1
- package/icons/material-symbols/scan.svg +1 -1
- package/icons/material-symbols/shapes.svg +1 -1
- package/icons/material-symbols/share-network.svg +1 -1
- package/icons/material-symbols/shield-check.svg +1 -1
- package/icons/material-symbols/sidebar-simple.svg +1 -1
- package/icons/material-symbols/sign-out.svg +1 -1
- package/icons/material-symbols/signpost.svg +1 -1
- package/icons/material-symbols/sliders-horizontal.svg +1 -1
- package/icons/material-symbols/smiley.svg +1 -1
- package/icons/material-symbols/sparkle.svg +1 -1
- package/icons/material-symbols/square-half-bottom.svg +1 -1
- package/icons/material-symbols/square.svg +1 -1
- package/icons/material-symbols/squares-four.svg +1 -1
- package/icons/material-symbols/sticker.svg +1 -1
- package/icons/material-symbols/storefront.svg +1 -1
- package/icons/material-symbols/sun.svg +1 -1
- package/icons/material-symbols/swatches.svg +1 -1
- package/icons/material-symbols/tag.svg +1 -1
- package/icons/material-symbols/text-aa.svg +1 -1
- package/icons/material-symbols/text-align-left.svg +1 -1
- package/icons/material-symbols/text-b.svg +1 -1
- package/icons/material-symbols/text-h-one.svg +1 -1
- package/icons/material-symbols/text-h-three.svg +1 -1
- package/icons/material-symbols/text-h-two.svg +1 -1
- package/icons/material-symbols/text-italic.svg +1 -1
- package/icons/material-symbols/text-t.svg +1 -1
- package/icons/material-symbols/ticket.svg +1 -1
- package/icons/material-symbols/toggle-right.svg +1 -1
- package/icons/material-symbols/train.svg +1 -1
- package/icons/material-symbols/trash.svg +1 -1
- package/icons/material-symbols/upload-simple.svg +1 -1
- package/icons/material-symbols/user-circle.svg +1 -1
- package/icons/material-symbols/user.svg +1 -1
- package/icons/material-symbols/users-three.svg +1 -1
- package/icons/material-symbols/users.svg +1 -1
- package/icons/material-symbols/video-camera.svg +1 -1
- package/icons/material-symbols/warning-circle.svg +1 -1
- package/icons/material-symbols/warning.svg +1 -1
- package/icons/material-symbols/wave-sine.svg +1 -1
- package/icons/material-symbols/wheelchair.svg +1 -1
- package/icons/material-symbols/wrench.svg +1 -1
- package/icons/material-symbols/x.svg +1 -1
- package/icons/phosphor/pack.json +8 -8
- package/lib/apps.mjs +142 -139
- package/lib/apps.test.d.mts +1 -0
- package/lib/apps.test.mjs +50 -0
- package/lib/blocks.mjs +90 -90
- package/lib/caseCollisions.d.mts +4 -0
- package/lib/caseCollisions.mjs +62 -0
- package/lib/caseCollisions.test.d.mts +1 -0
- package/lib/caseCollisions.test.mjs +74 -0
- package/lib/colors.ts +86 -86
- package/lib/contactBar.ts +18 -18
- package/lib/contracts.d.mts +15 -0
- package/lib/contracts.mjs +17 -0
- package/lib/cookieCategories.mjs +28 -28
- package/lib/crop.mjs +83 -83
- package/lib/csp.mjs +130 -130
- package/lib/cspSources.mjs +60 -60
- package/lib/dynamic-colors.ts +426 -426
- package/lib/git.mjs +64 -64
- package/lib/hooks.ts +51 -51
- package/lib/inline.ts +20 -20
- package/lib/license-texts/Apache-2.0.txt +190 -190
- package/lib/license-texts/BSD-2-Clause.txt +24 -24
- package/lib/license-texts/BSD-3-Clause.txt +28 -28
- package/lib/license-texts/ISC.txt +15 -15
- package/lib/license-texts/MIT.txt +21 -21
- package/lib/licenses.d.mts +1 -1
- package/lib/licenses.mjs +683 -683
- package/lib/markdown.ts +42 -42
- package/lib/motion-schemes.mjs +5 -5
- package/lib/motion.ts +131 -131
- package/lib/notice.mjs +34 -34
- package/lib/scheduled.mjs +37 -37
- package/lib/snackbar.ts +149 -149
- package/lib/status.mjs +18 -18
- package/lib/storeEntries.d.mts +18 -0
- package/lib/storeEntries.mjs +64 -0
- package/lib/storeEntries.test.d.mts +1 -0
- package/lib/storeEntries.test.mjs +71 -0
- package/lib/svg.mjs +231 -231
- package/lib/text-colors.mjs +43 -43
- package/lib/video-id.mjs +72 -72
- package/lib/video.mjs +91 -91
- package/package.json +136 -131
- package/pages/404.astro +10 -10
- package/pages/[...slug].astro +51 -51
- package/pages/_headers.txt +31 -31
- package/pages/blog/index.astro +10 -10
- package/pages/blog/kategori/[category].astro +18 -18
- package/pages/editor/code-images.json.js +25 -25
- package/pages/editor/index.astro +75 -75
- package/pages/editor/manifest.webmanifest.js +23 -23
- package/pages/editor/sw.js +33 -33
- package/pages/editor/sw.js.js +4 -4
- package/pages/editor/thumbnails.json.js +21 -21
- package/pages/editor/version.json.js +22 -22
- package/pages/headers.js +4 -4
- package/pages/index.astro +10 -10
- package/pages/ny.astro +6 -6
- package/pages/robots.txt.js +3 -3
- package/pages/rss.xml.js +20 -20
- package/scripts/app-screenshots.mjs +164 -164
- package/scripts/app-workers.mjs +6 -6
- package/scripts/bin.mjs +12 -12
- package/scripts/built-site.mjs +134 -99
- package/scripts/check-consent.mjs +113 -113
- package/scripts/check-content.mjs +151 -149
- package/scripts/check-demo.mjs +24 -24
- package/scripts/check-store.mjs +160 -0
- package/scripts/check-themes.mjs +45 -45
- package/scripts/check-worker.mjs +569 -569
- package/scripts/compare-html.mjs +81 -81
- package/scripts/declarations.mjs +10 -0
- package/scripts/declarations.test.mjs +32 -0
- package/scripts/demo-site.mjs +42 -42
- package/scripts/editor-icons.mjs +56 -56
- package/scripts/editor-roundtrip.mjs +134 -134
- package/scripts/editor-screens.mjs +101 -101
- package/scripts/git-env.mjs +9 -9
- package/scripts/icon-packs.mjs +151 -151
- package/scripts/link-counts.mjs +22 -22
- package/scripts/page-colors.mjs +42 -42
- package/scripts/releases.mjs +80 -80
- package/scripts/responsive-images.mjs +94 -94
- package/scripts/scheduled-list.mjs +15 -15
- package/scripts/theme-screenshots.mjs +88 -88
- package/scripts/types.mjs +17 -21
- package/scripts/video-thumbnails.mjs +89 -89
- package/scripts/worker-modules.mjs +34 -34
- package/site/appCookies.mjs +74 -74
- package/site/apps.ts +21 -21
- package/site/autolinks.mjs +200 -200
- package/site/blockScripts.ts +31 -31
- package/site/categories.ts +16 -16
- package/site/consent.ts +26 -26
- package/site/content.config.ts +84 -84
- package/site/content.ts +104 -104
- package/site/cookieList.ts +17 -17
- package/site/defineSite.d.mts +2 -14
- package/site/defineSite.mjs +131 -136
- package/site/directives/interact.mjs +31 -31
- package/site/editor-version.mjs +26 -26
- package/site/fill.ts +13 -13
- package/site/format.ts +11 -11
- package/site/home.ts +66 -66
- package/site/iconPacks.mjs +43 -43
- package/site/icons.mjs +605 -605
- package/site/images.mjs +157 -157
- package/site/motion.ts +13 -13
- package/site/noindex.mjs +21 -21
- package/site/pageColors.ts +110 -110
- package/site/popups.ts +98 -98
- package/site/schema.ts +189 -189
- package/site/sections.ts +3 -3
- package/site/seo.ts +28 -28
- package/site/site.ts +76 -76
- package/site/siteConfig.mjs +8 -8
- package/site/siteCsp.mjs +75 -75
- package/site/siteModules.mjs +27 -27
- package/site/standardPages.ts +59 -59
- package/site/storeTheme.d.mts +6 -0
- package/site/storeTheme.mjs +29 -0
- package/site/storeTheme.test.d.mts +1 -0
- package/site/storeTheme.test.mjs +53 -0
- package/site/testimonials.ts +48 -48
- package/site/text.ts +43 -43
- package/site/theme.mjs +483 -472
- package/site/tracking.client.ts +225 -225
- package/site/tracking.ts +9 -9
- package/src/ActionParts.tsx +205 -205
- package/src/Advanced.tsx +152 -152
- package/src/App.tsx +901 -904
- package/src/AppList.tsx +1362 -1345
- package/src/BlockDialog.tsx +360 -360
- package/src/BlockParts.tsx +652 -652
- package/src/BlockSettings.tsx +533 -533
- package/src/BrandForm.tsx +164 -164
- package/src/Colors.tsx +476 -476
- package/src/CommunicationParts.tsx +199 -199
- package/src/CompanyForm.tsx +209 -209
- package/src/Consents.tsx +175 -175
- package/src/ContainmentParts.tsx +185 -185
- package/src/Crop.tsx +152 -152
- package/src/DataForm.tsx +434 -434
- package/src/Deleted.tsx +177 -177
- package/src/EntryForm.tsx +740 -740
- package/src/FileView.tsx +30 -30
- package/src/FormFrame.tsx +237 -237
- package/src/Keywords.tsx +225 -225
- package/src/Library.tsx +1563 -1563
- package/src/Licenses.tsx +336 -336
- package/src/LinkSheet.tsx +138 -138
- package/src/MarkdownEditor.tsx +1075 -1075
- package/src/Media.tsx +677 -677
- package/src/NavigationParts.tsx +350 -350
- package/src/NavigationRestParts.tsx +247 -247
- package/src/Notifications.tsx +59 -59
- package/src/PagePicker.tsx +136 -136
- package/src/Parts.tsx +991 -991
- package/src/PartsShown.tsx +168 -168
- package/src/PickerParts.tsx +183 -183
- package/src/Redirects.tsx +450 -450
- package/src/Screen.tsx +184 -184
- package/src/SectionsField.tsx +65 -65
- package/src/SelectionParts.tsx +134 -134
- package/src/SeoScores.tsx +184 -184
- package/src/Sheet.tsx +35 -35
- package/src/ThemeStore.tsx +376 -376
- package/src/Tokens.tsx +346 -346
- package/src/Versions.tsx +214 -214
- package/src/addresses.ts +75 -75
- package/src/allIcons.ts +7 -7
- package/src/appFiles.ts +29 -29
- package/src/apps.ts +281 -281
- package/src/ask.tsx +123 -123
- package/src/blocks.ts +251 -251
- package/src/brand.ts +153 -153
- package/src/cache.ts +42 -42
- package/src/check.ts +285 -285
- package/src/checkSite.ts +256 -256
- package/src/{consents.ts → consentData.ts} +26 -26
- package/src/cookieList.ts +70 -70
- package/src/countries.ts +59 -59
- package/src/deploy.ts +155 -155
- package/src/editor.css +602 -602
- package/src/examples.ts +85 -85
- package/src/fields.tsx +942 -942
- package/src/frontmatter.mjs +42 -42
- package/src/github.ts +376 -376
- package/src/i18n/da-DK/advanced.ts +28 -28
- package/src/i18n/da-DK/app.ts +71 -71
- package/src/i18n/da-DK/apps.ts +90 -90
- package/src/i18n/da-DK/blockSettings.ts +38 -38
- package/src/i18n/da-DK/blocks.ts +408 -408
- package/src/i18n/da-DK/check.ts +25 -25
- package/src/i18n/da-DK/colors.ts +64 -64
- package/src/i18n/da-DK/common.ts +118 -118
- package/src/i18n/da-DK/company.ts +24 -24
- package/src/i18n/da-DK/consents.ts +23 -23
- package/src/i18n/da-DK/forms.ts +116 -116
- package/src/i18n/da-DK/history.ts +35 -35
- package/src/i18n/da-DK/index.ts +49 -49
- package/src/i18n/da-DK/keywords.ts +19 -19
- package/src/i18n/da-DK/library.ts +135 -135
- package/src/i18n/da-DK/licenses.ts +25 -25
- package/src/i18n/da-DK/media.ts +79 -79
- package/src/i18n/da-DK/parts.ts +696 -696
- package/src/i18n/da-DK/preview.ts +13 -13
- package/src/i18n/da-DK/redirects.ts +51 -51
- package/src/i18n/da-DK/seo.ts +20 -20
- package/src/i18n/da-DK/text.ts +35 -35
- package/src/i18n/da-DK/theme.ts +41 -41
- package/src/i18n/en-US/advanced.ts +32 -32
- package/src/i18n/en-US/app.ts +84 -84
- package/src/i18n/en-US/apps.ts +134 -134
- package/src/i18n/en-US/blockSettings.ts +48 -48
- package/src/i18n/en-US/blocks.ts +441 -441
- package/src/i18n/en-US/check.ts +31 -31
- package/src/i18n/en-US/colors.ts +82 -82
- package/src/i18n/en-US/common.ts +144 -144
- package/src/i18n/en-US/company.ts +25 -25
- package/src/i18n/en-US/consents.ts +25 -25
- package/src/i18n/en-US/forms.ts +145 -145
- package/src/i18n/en-US/history.ts +43 -43
- package/src/i18n/en-US/index.ts +51 -51
- package/src/i18n/en-US/keywords.ts +24 -24
- package/src/i18n/en-US/library.ts +176 -176
- package/src/i18n/en-US/licenses.ts +36 -36
- package/src/i18n/en-US/media.ts +80 -80
- package/src/i18n/en-US/parts.ts +718 -718
- package/src/i18n/en-US/preview.ts +15 -15
- package/src/i18n/en-US/redirects.ts +66 -66
- package/src/i18n/en-US/seo.ts +26 -26
- package/src/i18n/en-US/text.ts +41 -41
- package/src/i18n/en-US/theme.ts +41 -41
- package/src/i18n/index.ts +124 -124
- package/src/icon.tsx +160 -160
- package/src/iconPacks.ts +89 -89
- package/src/images.ts +163 -163
- package/src/{licenses.ts → licenseData.ts} +79 -79
- package/src/markdown.mjs +204 -204
- package/src/nav.ts +68 -68
- package/src/notFound.ts +28 -28
- package/src/{notifications.ts → notificationData.ts} +223 -223
- package/src/pagePreview.tsx +204 -204
- package/src/r2Caching.ts +55 -55
- package/src/{redirects.ts → redirectData.ts} +149 -149
- package/src/registry.tsx +188 -188
- package/src/schema.ts +417 -417
- package/src/sections.mjs +303 -303
- package/src/seo.ts +333 -333
- package/src/shared.ts +44 -44
- package/src/sidebar.ts +31 -31
- package/src/site.ts +317 -317
- package/src/standard/Block.astro +19 -19
- package/src/standard/BlockSite.astro +18 -18
- package/src/standard/accordion/index.tsx +47 -47
- package/src/standard/accordion/load.ts +23 -23
- package/src/standard/accordion/shared.ts +15 -15
- package/src/standard/accordion/view.ts +32 -32
- package/src/standard/buttons/fields.ts +98 -98
- package/src/standard/buttons/index.tsx +23 -23
- package/src/standard/buttons/load.ts +34 -34
- package/src/standard/buttons/shared.ts +12 -12
- package/src/standard/buttons/view.ts +30 -30
- package/src/standard/cards/index.tsx +71 -71
- package/src/standard/cards/load.ts +17 -17
- package/src/standard/cards/shared.ts +27 -27
- package/src/standard/cards/view.ts +29 -29
- package/src/standard/checklist/index.tsx +27 -27
- package/src/standard/checklist/load.ts +5 -5
- package/src/standard/checklist/view.ts +13 -13
- package/src/standard/cookies/index.tsx +17 -17
- package/src/standard/cookies/list.ts +56 -56
- package/src/standard/cookies/load.ts +11 -11
- package/src/standard/cookies/shared.ts +20 -20
- package/src/standard/cookies/view.ts +28 -28
- package/src/standard/faq/index.tsx +29 -29
- package/src/standard/faq/load.ts +14 -14
- package/src/standard/faq/view.ts +21 -21
- package/src/standard/head.ts +23 -23
- package/src/standard/hero/fields.ts +48 -48
- package/src/standard/hero/index.tsx +57 -57
- package/src/standard/hero/load.ts +23 -23
- package/src/standard/hero/view.ts +38 -38
- package/src/standard/links/index.tsx +41 -41
- package/src/standard/links/load.ts +17 -17
- package/src/standard/links/view.ts +25 -25
- package/src/standard/list/index.tsx +50 -50
- package/src/standard/list/load.ts +5 -5
- package/src/standard/list/view.ts +18 -18
- package/src/standard/load.ts +7 -7
- package/src/standard/notice/index.tsx +30 -30
- package/src/standard/notice/load.ts +16 -16
- package/src/standard/notice/view.ts +10 -10
- package/src/standard/points/index.tsx +42 -42
- package/src/standard/points/load.ts +5 -5
- package/src/standard/points/view.ts +12 -12
- package/src/standard/posts/index.tsx +132 -132
- package/src/standard/posts/load.ts +36 -36
- package/src/standard/posts/shared.ts +21 -21
- package/src/standard/posts/view.ts +63 -63
- package/src/standard/pricecards/index.tsx +57 -57
- package/src/standard/pricecards/load.ts +11 -11
- package/src/standard/pricecards/view.ts +50 -50
- package/src/standard/sharedTexts.ts +6 -6
- package/src/standard/site.ts +124 -124
- package/src/standard/siteLooks.ts +19 -19
- package/src/standard/sites.ts +13 -13
- package/src/standard/steps/index.tsx +28 -28
- package/src/standard/steps/load.ts +5 -5
- package/src/standard/steps/view.ts +11 -11
- package/src/standard/testimonials/index.tsx +87 -87
- package/src/standard/testimonials/list.ts +43 -43
- package/src/standard/testimonials/load.ts +58 -58
- package/src/standard/testimonials/shared.ts +13 -13
- package/src/standard/testimonials/view.ts +76 -76
- package/src/standard/themeBlocks.ts +13 -13
- package/src/standard/video/index.tsx +23 -23
- package/src/standard/video/load.ts +10 -10
- package/src/standard/video/view.ts +42 -42
- package/src/standard/view.tsx +105 -105
- package/src/standard/views.ts +37 -37
- package/src/store.ts +479 -499
- package/src/theme.ts +90 -90
- package/src/themeUi.ts +97 -97
- package/src/themes.ts +91 -91
- package/src/ui.tsx +3402 -3402
- package/src/virtual.d.ts +5 -5
- package/src/when.ts +22 -22
- package/starter/.githooks/pre-push +4 -4
- package/starter/.nvmrc +1 -1
- package/starter/.prettierignore +11 -11
- package/starter/.prettierrc.json +7 -7
- package/starter/README.md +27 -26
- package/starter/astro.config.mjs +5 -5
- package/starter/package.json +67 -67
- package/starter/public/_redirects +1 -1
- package/starter/public/favicon.svg +1 -1
- package/starter/public/logo.svg +1 -1
- package/starter/src/content/pages/blog.md +8 -8
- package/starter/src/content/pages/forside.md +9 -9
- package/starter/src/content/pages/kontakt.md +7 -7
- package/starter/src/content/pages/privatlivspolitik.md +9 -9
- package/starter/src/content/pages/siden-findes-ikke.md +7 -7
- package/starter/src/content.config.ts +2 -2
- package/starter/src/data/apps.json +1 -1
- package/starter/src/data/block-settings.json +3 -3
- package/starter/src/data/blocks.json +1 -1
- package/starter/src/data/booking.json +6 -6
- package/starter/src/data/colors.json +70 -70
- package/starter/src/data/contact.json +8 -8
- package/starter/src/data/cookies.json +21 -21
- package/starter/src/data/csp.json +1 -1
- package/starter/src/data/footer.json +15 -15
- package/starter/src/data/internal-links.json +4 -4
- package/starter/src/data/menu.json +4 -4
- package/starter/src/data/mobile-menu.json +4 -4
- package/starter/src/data/old-addresses.json +1 -1
- package/starter/src/data/redirects.json +1 -1
- package/starter/src/data/standard-pages.json +8 -8
- package/starter/src/data/theme.json +1 -1
- package/starter/src/env.d.ts +2 -2
- package/starter/src/site/config.ts +13 -13
- package/starter/src/site/worker.js +14 -14
- package/starter/tsconfig.json +17 -17
- package/starter/worker/apps.js +6 -6
- package/starter/wrangler.jsonc +39 -39
- package/theme/LICENSE +21 -21
- package/theme/blocks/ArrowLink.tsx +14 -14
- package/theme/blocks/BlockHead.tsx +26 -26
- package/theme/blocks/Panel.tsx +32 -32
- package/theme/blocks/Person.tsx +26 -26
- package/theme/blocks/accordion/PageRow.tsx +25 -25
- package/theme/blocks/accordion/View.tsx +17 -17
- package/theme/blocks/buttons/Buttons.tsx +28 -28
- package/theme/blocks/buttons/View.tsx +12 -12
- package/theme/blocks/cards/LinkCards.tsx +72 -72
- package/theme/blocks/cards/View.tsx +20 -20
- package/theme/blocks/checklist/Checks.tsx +15 -15
- package/theme/blocks/checklist/View.tsx +14 -14
- package/theme/blocks/cookies/View.tsx +36 -36
- package/theme/blocks/faq/Accordion.tsx +34 -34
- package/theme/blocks/faq/View.tsx +16 -16
- package/theme/blocks/faq/script.ts +56 -56
- package/theme/blocks/hero/View.tsx +44 -44
- package/theme/blocks/links/LinkGroups.tsx +24 -24
- package/theme/blocks/links/View.tsx +17 -17
- package/theme/blocks/list/Rows.tsx +24 -24
- package/theme/blocks/list/View.tsx +14 -14
- package/theme/blocks/notice/View.tsx +13 -13
- package/theme/blocks/points/PointList.tsx +34 -34
- package/theme/blocks/points/View.tsx +14 -14
- package/theme/blocks/posts/View.tsx +26 -26
- package/theme/blocks/pricecards/View.tsx +40 -40
- package/theme/blocks/steps/StepList.tsx +23 -23
- package/theme/blocks/steps/View.tsx +14 -14
- package/theme/blocks/testimonials/List.tsx +46 -46
- package/theme/blocks/testimonials/Slider.tsx +44 -44
- package/theme/blocks/testimonials/Testimonial.tsx +124 -124
- package/theme/blocks/testimonials/View.tsx +21 -21
- package/theme/blocks/testimonials/script.ts +52 -52
- package/theme/blocks/video/View.tsx +41 -41
- package/theme/components/ActionBar.astro +63 -63
- package/theme/components/AppSlot.astro +21 -21
- package/theme/components/ArrowLink.tsx +21 -21
- package/theme/components/BlogIndex.astro +48 -48
- package/theme/components/BlogPosts.astro +18 -18
- package/theme/components/BlogPosts.tsx +45 -45
- package/theme/components/BookButton.tsx +22 -22
- package/theme/components/Container.astro +11 -11
- package/theme/components/CookieConsent.astro +121 -121
- package/theme/components/EndBlock.astro +21 -21
- package/theme/components/FontPreload.astro +6 -6
- package/theme/components/Footer.astro +85 -85
- package/theme/components/Header.astro +186 -186
- package/theme/components/Icon.astro +16 -16
- package/theme/components/Img.astro +29 -29
- package/theme/components/Img.tsx +33 -33
- package/theme/components/Inline.astro +11 -11
- package/theme/components/Logo.astro +23 -23
- package/theme/components/LogoMark.astro +10 -10
- package/theme/components/Markdown.astro +17 -17
- package/theme/components/MobileMenu.tsx +224 -224
- package/theme/components/MobileNav.astro +33 -33
- package/theme/components/PageHeader.astro +22 -22
- package/theme/components/PageSection.astro +24 -24
- package/theme/components/PhoneButton.tsx +11 -11
- package/theme/components/Popup.astro +145 -145
- package/theme/components/PopupButton.tsx +24 -24
- package/theme/components/PopupView.tsx +48 -48
- package/theme/components/PostList.tsx +58 -58
- package/theme/components/PostMeta.tsx +17 -17
- package/theme/components/RichText.astro +28 -28
- package/theme/components/Section.astro +29 -29
- package/theme/components/SectionHeading.tsx +8 -8
- package/theme/components/TextSection.astro +16 -16
- package/theme/components/home/PageBlock.astro +19 -19
- package/theme/components/home/Text.astro +13 -13
- package/theme/components/loadPopup.ts +22 -22
- package/theme/components/loadPosts.ts +16 -16
- package/theme/components/posts.ts +15 -15
- package/theme/editor/looks.mjs +7 -7
- package/theme/editor/previews.tsx +56 -56
- package/theme/layouts/Base.astro +273 -273
- package/theme/layouts/PageLayout.astro +126 -126
- package/theme/layouts/PostLayout.astro +137 -137
- package/theme/scripts/motion.ts +29 -29
- package/theme/styles/base.css +320 -320
- package/theme/styles/blocks.css +1808 -1808
- package/theme/styles/components.css +206 -206
- package/theme/styles/global.css +1302 -1302
- package/theme/styles/ui.css +6544 -6544
- package/theme/templates/Blog.astro +38 -38
- package/theme/templates/Category.astro +19 -19
- package/theme/templates/Home.astro +36 -36
- package/theme/templates/New.astro +68 -68
- package/theme/templates/NotFound.astro +117 -117
- package/theme/theme.json +28 -28
- package/theme/ui/Badge.tsx +45 -45
- package/theme/ui/BottomSheet.tsx +148 -148
- package/theme/ui/Button.tsx +79 -79
- package/theme/ui/ButtonGroup.tsx +31 -31
- package/theme/ui/Card.tsx +45 -45
- package/theme/ui/Carousel.tsx +124 -124
- package/theme/ui/Checkbox.tsx +59 -59
- package/theme/ui/Chip.tsx +101 -101
- package/theme/ui/ChipSet.tsx +27 -27
- package/theme/ui/DatePicker.tsx +149 -149
- package/theme/ui/DatePickerContainer.tsx +316 -316
- package/theme/ui/Dialog.tsx +100 -100
- package/theme/ui/Divider.tsx +27 -27
- package/theme/ui/ExposedDropdownMenu.tsx +77 -77
- package/theme/ui/Fab.tsx +88 -88
- package/theme/ui/FabMenu.tsx +67 -67
- package/theme/ui/IconButton.tsx +78 -78
- package/theme/ui/List.tsx +287 -287
- package/theme/ui/LoadingIndicator.tsx +29 -29
- package/theme/ui/Menu.tsx +278 -278
- package/theme/ui/NavigationBar.tsx +62 -62
- package/theme/ui/NavigationDrawer.tsx +80 -80
- package/theme/ui/NavigationRail.tsx +154 -154
- package/theme/ui/ProgressIndicator.tsx +162 -162
- package/theme/ui/RadioButton.tsx +50 -50
- package/theme/ui/Search.tsx +129 -129
- package/theme/ui/SegmentedButton.tsx +49 -49
- package/theme/ui/SideSheet.tsx +54 -54
- package/theme/ui/Slider.tsx +155 -155
- package/theme/ui/Snackbar.tsx +67 -67
- package/theme/ui/SplitButton.tsx +67 -67
- package/theme/ui/Switch.tsx +60 -60
- package/theme/ui/Tabs.tsx +114 -114
- package/theme/ui/TextField.tsx +278 -278
- package/theme/ui/TimePicker.tsx +128 -128
- package/theme/ui/TimePickerContainer.tsx +234 -234
- package/theme/ui/Toolbar.tsx +67 -67
- package/theme/ui/Tooltip.tsx +58 -58
- package/theme/ui/TopAppBar.tsx +77 -77
- package/theme/ui/bottomSheet.script.ts +8 -8
- package/theme/ui/{bottomSheet.ts → bottomSheetControl.ts} +211 -211
- package/theme/ui/carousel.script.ts +28 -28
- package/theme/ui/carouselLayout.ts +229 -229
- package/theme/ui/checkbox.script.ts +8 -8
- package/theme/ui/datePicker.script.ts +302 -302
- package/theme/ui/dates.ts +185 -185
- package/theme/ui/{dialog.ts → dialogControl.ts} +48 -48
- package/theme/ui/dropdownMenu.script.ts +166 -166
- package/theme/ui/fabMenu.script.ts +57 -57
- package/theme/ui/navigationRail.script.ts +47 -47
- package/theme/ui/ripple.script.ts +159 -159
- package/theme/ui/search.script.ts +92 -92
- package/theme/ui/{sideSheet.ts → sideSheetControl.ts} +48 -48
- package/theme/ui/slider.script.ts +12 -12
- package/theme/ui/sliderUpdate.ts +52 -52
- package/theme/ui/snackbar.script.ts +16 -16
- package/theme/ui/splitButton.script.ts +63 -63
- package/theme/ui/tabs.script.ts +48 -48
- package/theme/ui/textField.script.ts +17 -17
- package/theme/ui/textFieldUpdate.ts +44 -44
- package/theme/ui/timePicker.script.ts +248 -248
- package/theme/ui/toolbar.script.ts +43 -43
- package/theme/ui/tooltip.script.ts +68 -68
- package/worker/consent.js +141 -141
- package/worker/editor-github.js +167 -167
- package/worker/editor-host.js +74 -74
- package/worker/files.js +401 -401
- package/worker/github.js +36 -36
- package/worker/index.js +188 -184
- package/worker/not-found.js +97 -97
- package/worker/oauth.js +95 -95
- package/worker/publish.js +52 -52
- package/worker/push.js +270 -270
- package/worker/r2-status.js +50 -50
- package/worker/session.js +58 -58
- package/worker/store.js +46 -0
package/lib/markdown.ts
CHANGED
|
@@ -1,42 +1,42 @@
|
|
|
1
|
-
// Markdown as HTML in the editor, at once: as the site makes it (Astro's pipeline, inline.ts: GitHub's Markdown,
|
|
2
|
-
// typographic quotes, the HTML written in it) with what runs in a browser, so a block drawn in the editor shows its
|
|
3
|
-
// text as on the site (bold, italic, links, lists). The site itself uses Astro's (inline.ts), which does not run in a
|
|
4
|
-
// browser.
|
|
5
|
-
import { unified } from 'unified';
|
|
6
|
-
import remarkParse from 'remark-parse';
|
|
7
|
-
import remarkGfm from 'remark-gfm';
|
|
8
|
-
import remarkSmartypants from 'remark-smartypants';
|
|
9
|
-
import remarkRehype from 'remark-rehype';
|
|
10
|
-
import rehypeRaw from 'rehype-raw';
|
|
11
|
-
import rehypeStringify from 'rehype-stringify';
|
|
12
|
-
|
|
13
|
-
/** The pipeline, also for a whole page's text (pagePreview.tsx). */
|
|
14
|
-
export const processor = unified()
|
|
15
|
-
.use(remarkParse)
|
|
16
|
-
.use(remarkGfm)
|
|
17
|
-
.use(remarkSmartypants)
|
|
18
|
-
.use(remarkRehype, { allowDangerousHtml: true })
|
|
19
|
-
.use(rehypeRaw)
|
|
20
|
-
.use(rehypeStringify, { allowDangerousHtml: true });
|
|
21
|
-
|
|
22
|
-
/** A short text's HTML made to stand inside a <p> of its own: its paragraphs separated by a line break, and anything
|
|
23
|
-
* that cannot stand there (a list, a picture) as its text, still escaped HTML. */
|
|
24
|
-
export function inlineOf(html: string): string {
|
|
25
|
-
const paragraphs = [...html.matchAll(/<p>([\s\S]*?)<\/p>/g)];
|
|
26
|
-
if (paragraphs.map((m) => m[0]).join('\n') === html) return paragraphs.map((m) => m[1]).join('<br>');
|
|
27
|
-
return html
|
|
28
|
-
.replace(/<img\b[^>]*>/g, '')
|
|
29
|
-
.replace(/<[^>]+>/g, ' ')
|
|
30
|
-
.replace(/\s+/g, ' ')
|
|
31
|
-
.trim();
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// A link only drawn: without its address it looks as one, but leads nowhere from the editor.
|
|
35
|
-
const drawn = (html: string) => html.replace(/<a\b([^>]*?)\s+href="[^"]*"/g, '<a$1');
|
|
36
|
-
|
|
37
|
-
/** A longer text (an answer, a hero's text) as HTML to draw in the editor: paragraphs, lists, bold, italic and links
|
|
38
|
-
* (only drawn). */
|
|
39
|
-
export const markdownNow = (markdown: string) => drawn(String(processor.processSync(markdown)).trim());
|
|
40
|
-
|
|
41
|
-
/** A short text for a component that shows it inside its own <p> (inlineHtml on the site). */
|
|
42
|
-
export const inlineNow = (markdown: string) => inlineOf(markdownNow(markdown));
|
|
1
|
+
// Markdown as HTML in the editor, at once: as the site makes it (Astro's pipeline, inline.ts: GitHub's Markdown,
|
|
2
|
+
// typographic quotes, the HTML written in it) with what runs in a browser, so a block drawn in the editor shows its
|
|
3
|
+
// text as on the site (bold, italic, links, lists). The site itself uses Astro's (inline.ts), which does not run in a
|
|
4
|
+
// browser.
|
|
5
|
+
import { unified } from 'unified';
|
|
6
|
+
import remarkParse from 'remark-parse';
|
|
7
|
+
import remarkGfm from 'remark-gfm';
|
|
8
|
+
import remarkSmartypants from 'remark-smartypants';
|
|
9
|
+
import remarkRehype from 'remark-rehype';
|
|
10
|
+
import rehypeRaw from 'rehype-raw';
|
|
11
|
+
import rehypeStringify from 'rehype-stringify';
|
|
12
|
+
|
|
13
|
+
/** The pipeline, also for a whole page's text (pagePreview.tsx). */
|
|
14
|
+
export const processor = unified()
|
|
15
|
+
.use(remarkParse)
|
|
16
|
+
.use(remarkGfm)
|
|
17
|
+
.use(remarkSmartypants)
|
|
18
|
+
.use(remarkRehype, { allowDangerousHtml: true })
|
|
19
|
+
.use(rehypeRaw)
|
|
20
|
+
.use(rehypeStringify, { allowDangerousHtml: true });
|
|
21
|
+
|
|
22
|
+
/** A short text's HTML made to stand inside a <p> of its own: its paragraphs separated by a line break, and anything
|
|
23
|
+
* that cannot stand there (a list, a picture) as its text, still escaped HTML. */
|
|
24
|
+
export function inlineOf(html: string): string {
|
|
25
|
+
const paragraphs = [...html.matchAll(/<p>([\s\S]*?)<\/p>/g)];
|
|
26
|
+
if (paragraphs.map((m) => m[0]).join('\n') === html) return paragraphs.map((m) => m[1]).join('<br>');
|
|
27
|
+
return html
|
|
28
|
+
.replace(/<img\b[^>]*>/g, '')
|
|
29
|
+
.replace(/<[^>]+>/g, ' ')
|
|
30
|
+
.replace(/\s+/g, ' ')
|
|
31
|
+
.trim();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// A link only drawn: without its address it looks as one, but leads nowhere from the editor.
|
|
35
|
+
const drawn = (html: string) => html.replace(/<a\b([^>]*?)\s+href="[^"]*"/g, '<a$1');
|
|
36
|
+
|
|
37
|
+
/** A longer text (an answer, a hero's text) as HTML to draw in the editor: paragraphs, lists, bold, italic and links
|
|
38
|
+
* (only drawn). */
|
|
39
|
+
export const markdownNow = (markdown: string) => drawn(String(processor.processSync(markdown)).trim());
|
|
40
|
+
|
|
41
|
+
/** A short text for a component that shows it inside its own <p> (inlineHtml on the site). */
|
|
42
|
+
export const inlineNow = (markdown: string) => inlineOf(markdownNow(markdown));
|
package/lib/motion-schemes.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
// The motion schemes by name (lib/motion.ts has their springs), here alone so what checks a theme's or the site's choice
|
|
2
|
-
// in plain Node can read them (themeProblems and motionProblems in site/theme.mjs, check:content).
|
|
3
|
-
|
|
4
|
-
/** @type {readonly ['expressive', 'standard', 'calm']} */
|
|
5
|
-
export const MOTION_SCHEMES = ['expressive', 'standard', 'calm'];
|
|
1
|
+
// The motion schemes by name (lib/motion.ts has their springs), here alone so what checks a theme's or the site's choice
|
|
2
|
+
// in plain Node can read them (themeProblems and motionProblems in site/theme.mjs, check:content).
|
|
3
|
+
|
|
4
|
+
/** @type {readonly ['expressive', 'standard', 'calm']} */
|
|
5
|
+
export const MOTION_SCHEMES = ['expressive', 'standard', 'calm'];
|
package/lib/motion.ts
CHANGED
|
@@ -1,131 +1,131 @@
|
|
|
1
|
-
// How the site moves: Material 3's motion schemes (m3.material.io/styles/motion/overview/how-it-works), springs that
|
|
2
|
-
// say how something moves (spatial: a sheet that slides in, a button that changes shape) and how something changes
|
|
3
|
-
// (effects: a colour, something that fades), each fast, default or slow. A scheme is the owner's choice under
|
|
4
|
-
// "Udseende" › "Bevægelse" (config.motion, e.g. src/data/motion.json: `{ "scheme": "expressive" }`), else the theme's
|
|
5
|
-
// ("motion" in its theme.json), else the standard theme's (schemeInUse):
|
|
6
|
-
// expressive Material 3 Expressive's: what moves overshoots a little and settles, as on a phone
|
|
7
|
-
// standard Material 3's standard: what moves glides into place
|
|
8
|
-
// calm ours: what moves does so quickly without overshooting, and the sections are shown at once (no reveal)
|
|
9
|
-
// The site writes the scheme's springs into the <head> of its pages as CSS variables (motionCss, with data-motion on
|
|
10
|
-
// <html>), which every transition and animation of the theme takes (ui.css, blocks.css: `transition: transform
|
|
11
|
-
// var(--motion-spatial-fast)`), and its scripts animate with the same springs (motionSpring, for Motion). A visitor who
|
|
12
|
-
// has asked for reduced motion gets less, whatever the scheme. No React or browser here: the build uses it too.
|
|
13
|
-
|
|
14
|
-
import { MOTION_SCHEMES } from './motion-schemes.mjs';
|
|
15
|
-
|
|
16
|
-
export { MOTION_SCHEMES };
|
|
17
|
-
export type MotionScheme = (typeof MOTION_SCHEMES)[number];
|
|
18
|
-
/** The standard theme's, when neither the owner nor the theme has chosen one. */
|
|
19
|
-
export const DEFAULT_SCHEME: MotionScheme = 'standard';
|
|
20
|
-
|
|
21
|
-
export const MOTION_KINDS = ['spatial', 'effects'] as const;
|
|
22
|
-
export type MotionKind = (typeof MOTION_KINDS)[number];
|
|
23
|
-
export const MOTION_SPEEDS = ['fast', 'default', 'slow'] as const;
|
|
24
|
-
export type MotionSpeed = (typeof MOTION_SPEEDS)[number];
|
|
25
|
-
|
|
26
|
-
/** A spring with a mass of 1: how damped it is (1: it does not overshoot; less: it does, and settles) and how stiff. */
|
|
27
|
-
export type Spring = { damping: number; stiffness: number };
|
|
28
|
-
type Springs = Record<MotionKind, Record<MotionSpeed, Spring>>;
|
|
29
|
-
|
|
30
|
-
// Material's effects springs, the same in both of its schemes: they never overshoot (a colour cannot).
|
|
31
|
-
const EFFECTS: Record<MotionSpeed, Spring> = {
|
|
32
|
-
fast: { damping: 1, stiffness: 3800 },
|
|
33
|
-
default: { damping: 1, stiffness: 1600 },
|
|
34
|
-
slow: { damping: 1, stiffness: 800 },
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
/** Each scheme's springs: Material 3's tokens (md.sys.motion.spring.*) for expressive and standard. */
|
|
38
|
-
export const SPRINGS: Record<MotionScheme, Springs> = {
|
|
39
|
-
expressive: {
|
|
40
|
-
spatial: { fast: { damping: 0.6, stiffness: 800 }, default: { damping: 0.8, stiffness: 380 }, slow: { damping: 0.8, stiffness: 200 } },
|
|
41
|
-
effects: EFFECTS,
|
|
42
|
-
},
|
|
43
|
-
standard: {
|
|
44
|
-
spatial: { fast: { damping: 0.9, stiffness: 1400 }, default: { damping: 0.9, stiffness: 700 }, slow: { damping: 0.9, stiffness: 300 } },
|
|
45
|
-
effects: EFFECTS,
|
|
46
|
-
},
|
|
47
|
-
calm: { spatial: EFFECTS, effects: EFFECTS },
|
|
48
|
-
};
|
|
49
|
-
|
|
50
|
-
/** Whether a value is one of the schemes. */
|
|
51
|
-
export const isMotionScheme = (value: unknown): value is MotionScheme => MOTION_SCHEMES.includes(value as MotionScheme);
|
|
52
|
-
|
|
53
|
-
/** The scheme the site moves by: the one chosen (config.motion's `scheme`), else the theme's ("motion" in its theme.json),
|
|
54
|
-
* else the standard theme's, else DEFAULT_SCHEME. One that is not a scheme counts as none (check:content says so). */
|
|
55
|
-
export function schemeInUse(chosen: unknown, theme: unknown, standard?: unknown): MotionScheme {
|
|
56
|
-
return [chosen, theme, standard].find(isMotionScheme) ?? DEFAULT_SCHEME;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
// How far from where it is going a spring counts as there, and how often the curve is drawn.
|
|
60
|
-
const SETTLED = 0.001;
|
|
61
|
-
const STEP = 1 / 60;
|
|
62
|
-
|
|
63
|
-
/** Where a spring that starts still at 0 is at `t` seconds, on its way to 1. */
|
|
64
|
-
function position({ damping, stiffness }: Spring, t: number): number {
|
|
65
|
-
const w = Math.sqrt(stiffness);
|
|
66
|
-
if (damping >= 1) return 1 - Math.exp(-w * t) * (1 + w * t);
|
|
67
|
-
const wd = w * Math.sqrt(1 - damping * damping);
|
|
68
|
-
return 1 - Math.exp(-damping * w * t) * (Math.cos(wd * t) + ((damping * w) / wd) * Math.sin(wd * t));
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/** A spring as CSS: how long it takes to settle, and its curve as a linear() easing (the spring's own way there, overshoot
|
|
72
|
-
* and all), for `transition` and `animation`. */
|
|
73
|
-
export function springCss(spring: Spring): { duration: number; easing: string } {
|
|
74
|
-
// The last moment it is not yet there, to the millisecond.
|
|
75
|
-
let settled = 0;
|
|
76
|
-
for (let t = 0; t < 3; t += 0.001) if (Math.abs(1 - position(spring, t)) >= SETTLED) settled = t;
|
|
77
|
-
const duration = Math.ceil(settled * 100) / 100;
|
|
78
|
-
const steps = Math.max(Math.round(duration / STEP), 8);
|
|
79
|
-
const points = Array.from({ length: steps + 1 }, (_, i) => (i === steps ? 1 : +position(spring, (i / steps) * duration).toFixed(3)));
|
|
80
|
-
return { duration: Math.round(duration * 1000), easing: `linear(${points.join(',')})` };
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
/** A spring's CSS variable: `--motion-spatial-fast`, `--motion-effects` (default), `--motion-effects-slow`. */
|
|
84
|
-
export const motionVariable = (kind: MotionKind, speed: MotionSpeed) => `--motion-${kind}${speed === 'default' ? '' : `-${speed}`}`;
|
|
85
|
-
|
|
86
|
-
/** A scheme as CSS for a <style> in the <head>: each spring as its duration and curve
|
|
87
|
-
* (`--motion-spatial-fast: 290ms linear(…)`), to use as `transition: transform var(--motion-spatial-fast)`, and its
|
|
88
|
-
* duration alone (`--motion-spatial-fast-duration`), for what must last as long as it (a `visibility` that waits for it,
|
|
89
|
-
* a `display … allow-discrete`); and the default spatial and effects curves alone (--motion-ease, --motion-ease-quick),
|
|
90
|
-
* for what has its own duration (--block-ease and --block-ease-quick in blocks.css, --ease in base.css). */
|
|
91
|
-
export function motionCss(scheme: MotionScheme): string {
|
|
92
|
-
const springs = SPRINGS[scheme];
|
|
93
|
-
const declarations = MOTION_KINDS.flatMap((kind) =>
|
|
94
|
-
MOTION_SPEEDS.map((speed) => {
|
|
95
|
-
const { duration, easing } = springCss(springs[kind][speed]);
|
|
96
|
-
const name = motionVariable(kind, speed);
|
|
97
|
-
return `${name}:${duration}ms ${easing};${name}-duration:${duration}ms;`;
|
|
98
|
-
}),
|
|
99
|
-
);
|
|
100
|
-
const ease = springCss(springs.spatial.default).easing;
|
|
101
|
-
const quick = springCss(springs.effects.default).easing;
|
|
102
|
-
return `:root{${declarations.join('')}--motion-ease:${ease};--motion-ease-quick:${quick};}`;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
/** A spring as Motion takes it (motion.dev: `animate(el, …, motionSpring('spatial'))`), in the scheme on the page
|
|
106
|
-
* (data-motion-scheme on <html>, set where motionCss is), else DEFAULT_SCHEME: its stiffness and its damping as a force, for a
|
|
107
|
-
* mass of 1. */
|
|
108
|
-
export function motionSpring(kind: MotionKind, speed: MotionSpeed = 'default', scheme: MotionScheme = pageScheme()) {
|
|
109
|
-
const { damping, stiffness } = SPRINGS[scheme][kind][speed];
|
|
110
|
-
return { type: 'spring' as const, stiffness, damping: 2 * damping * Math.sqrt(stiffness), mass: 1 };
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
/** A spring as the browser's own animations take it (`el.animate(keyframes, motionTiming('spatial'))`), in the scheme on
|
|
114
|
-
* the page: how long it takes, and its curve. */
|
|
115
|
-
export function motionTiming(kind: MotionKind, speed: MotionSpeed = 'default', scheme: MotionScheme = pageScheme()) {
|
|
116
|
-
return springCss(SPRINGS[scheme][kind][speed]);
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/** The scheme the page moves by (data-motion-scheme on <html>), else DEFAULT_SCHEME; without a browser, DEFAULT_SCHEME. */
|
|
120
|
-
export function pageScheme(): MotionScheme {
|
|
121
|
-
if (typeof document === 'undefined') return DEFAULT_SCHEME;
|
|
122
|
-
const scheme = document.documentElement.dataset.motionScheme;
|
|
123
|
-
return isMotionScheme(scheme) ? scheme : DEFAULT_SCHEME;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/** Whether the page's things should only appear, not move in: the calm scheme, or a visitor who has asked for reduced
|
|
127
|
-
* motion. */
|
|
128
|
-
export function motionReduced(): boolean {
|
|
129
|
-
if (typeof document === 'undefined') return true;
|
|
130
|
-
return pageScheme() === 'calm' || matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
131
|
-
}
|
|
1
|
+
// How the site moves: Material 3's motion schemes (m3.material.io/styles/motion/overview/how-it-works), springs that
|
|
2
|
+
// say how something moves (spatial: a sheet that slides in, a button that changes shape) and how something changes
|
|
3
|
+
// (effects: a colour, something that fades), each fast, default or slow. A scheme is the owner's choice under
|
|
4
|
+
// "Udseende" › "Bevægelse" (config.motion, e.g. src/data/motion.json: `{ "scheme": "expressive" }`), else the theme's
|
|
5
|
+
// ("motion" in its theme.json), else the standard theme's (schemeInUse):
|
|
6
|
+
// expressive Material 3 Expressive's: what moves overshoots a little and settles, as on a phone
|
|
7
|
+
// standard Material 3's standard: what moves glides into place
|
|
8
|
+
// calm ours: what moves does so quickly without overshooting, and the sections are shown at once (no reveal)
|
|
9
|
+
// The site writes the scheme's springs into the <head> of its pages as CSS variables (motionCss, with data-motion on
|
|
10
|
+
// <html>), which every transition and animation of the theme takes (ui.css, blocks.css: `transition: transform
|
|
11
|
+
// var(--motion-spatial-fast)`), and its scripts animate with the same springs (motionSpring, for Motion). A visitor who
|
|
12
|
+
// has asked for reduced motion gets less, whatever the scheme. No React or browser here: the build uses it too.
|
|
13
|
+
|
|
14
|
+
import { MOTION_SCHEMES } from './motion-schemes.mjs';
|
|
15
|
+
|
|
16
|
+
export { MOTION_SCHEMES };
|
|
17
|
+
export type MotionScheme = (typeof MOTION_SCHEMES)[number];
|
|
18
|
+
/** The standard theme's, when neither the owner nor the theme has chosen one. */
|
|
19
|
+
export const DEFAULT_SCHEME: MotionScheme = 'standard';
|
|
20
|
+
|
|
21
|
+
export const MOTION_KINDS = ['spatial', 'effects'] as const;
|
|
22
|
+
export type MotionKind = (typeof MOTION_KINDS)[number];
|
|
23
|
+
export const MOTION_SPEEDS = ['fast', 'default', 'slow'] as const;
|
|
24
|
+
export type MotionSpeed = (typeof MOTION_SPEEDS)[number];
|
|
25
|
+
|
|
26
|
+
/** A spring with a mass of 1: how damped it is (1: it does not overshoot; less: it does, and settles) and how stiff. */
|
|
27
|
+
export type Spring = { damping: number; stiffness: number };
|
|
28
|
+
type Springs = Record<MotionKind, Record<MotionSpeed, Spring>>;
|
|
29
|
+
|
|
30
|
+
// Material's effects springs, the same in both of its schemes: they never overshoot (a colour cannot).
|
|
31
|
+
const EFFECTS: Record<MotionSpeed, Spring> = {
|
|
32
|
+
fast: { damping: 1, stiffness: 3800 },
|
|
33
|
+
default: { damping: 1, stiffness: 1600 },
|
|
34
|
+
slow: { damping: 1, stiffness: 800 },
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** Each scheme's springs: Material 3's tokens (md.sys.motion.spring.*) for expressive and standard. */
|
|
38
|
+
export const SPRINGS: Record<MotionScheme, Springs> = {
|
|
39
|
+
expressive: {
|
|
40
|
+
spatial: { fast: { damping: 0.6, stiffness: 800 }, default: { damping: 0.8, stiffness: 380 }, slow: { damping: 0.8, stiffness: 200 } },
|
|
41
|
+
effects: EFFECTS,
|
|
42
|
+
},
|
|
43
|
+
standard: {
|
|
44
|
+
spatial: { fast: { damping: 0.9, stiffness: 1400 }, default: { damping: 0.9, stiffness: 700 }, slow: { damping: 0.9, stiffness: 300 } },
|
|
45
|
+
effects: EFFECTS,
|
|
46
|
+
},
|
|
47
|
+
calm: { spatial: EFFECTS, effects: EFFECTS },
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
/** Whether a value is one of the schemes. */
|
|
51
|
+
export const isMotionScheme = (value: unknown): value is MotionScheme => MOTION_SCHEMES.includes(value as MotionScheme);
|
|
52
|
+
|
|
53
|
+
/** The scheme the site moves by: the one chosen (config.motion's `scheme`), else the theme's ("motion" in its theme.json),
|
|
54
|
+
* else the standard theme's, else DEFAULT_SCHEME. One that is not a scheme counts as none (check:content says so). */
|
|
55
|
+
export function schemeInUse(chosen: unknown, theme: unknown, standard?: unknown): MotionScheme {
|
|
56
|
+
return [chosen, theme, standard].find(isMotionScheme) ?? DEFAULT_SCHEME;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// How far from where it is going a spring counts as there, and how often the curve is drawn.
|
|
60
|
+
const SETTLED = 0.001;
|
|
61
|
+
const STEP = 1 / 60;
|
|
62
|
+
|
|
63
|
+
/** Where a spring that starts still at 0 is at `t` seconds, on its way to 1. */
|
|
64
|
+
function position({ damping, stiffness }: Spring, t: number): number {
|
|
65
|
+
const w = Math.sqrt(stiffness);
|
|
66
|
+
if (damping >= 1) return 1 - Math.exp(-w * t) * (1 + w * t);
|
|
67
|
+
const wd = w * Math.sqrt(1 - damping * damping);
|
|
68
|
+
return 1 - Math.exp(-damping * w * t) * (Math.cos(wd * t) + ((damping * w) / wd) * Math.sin(wd * t));
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** A spring as CSS: how long it takes to settle, and its curve as a linear() easing (the spring's own way there, overshoot
|
|
72
|
+
* and all), for `transition` and `animation`. */
|
|
73
|
+
export function springCss(spring: Spring): { duration: number; easing: string } {
|
|
74
|
+
// The last moment it is not yet there, to the millisecond.
|
|
75
|
+
let settled = 0;
|
|
76
|
+
for (let t = 0; t < 3; t += 0.001) if (Math.abs(1 - position(spring, t)) >= SETTLED) settled = t;
|
|
77
|
+
const duration = Math.ceil(settled * 100) / 100;
|
|
78
|
+
const steps = Math.max(Math.round(duration / STEP), 8);
|
|
79
|
+
const points = Array.from({ length: steps + 1 }, (_, i) => (i === steps ? 1 : +position(spring, (i / steps) * duration).toFixed(3)));
|
|
80
|
+
return { duration: Math.round(duration * 1000), easing: `linear(${points.join(',')})` };
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/** A spring's CSS variable: `--motion-spatial-fast`, `--motion-effects` (default), `--motion-effects-slow`. */
|
|
84
|
+
export const motionVariable = (kind: MotionKind, speed: MotionSpeed) => `--motion-${kind}${speed === 'default' ? '' : `-${speed}`}`;
|
|
85
|
+
|
|
86
|
+
/** A scheme as CSS for a <style> in the <head>: each spring as its duration and curve
|
|
87
|
+
* (`--motion-spatial-fast: 290ms linear(…)`), to use as `transition: transform var(--motion-spatial-fast)`, and its
|
|
88
|
+
* duration alone (`--motion-spatial-fast-duration`), for what must last as long as it (a `visibility` that waits for it,
|
|
89
|
+
* a `display … allow-discrete`); and the default spatial and effects curves alone (--motion-ease, --motion-ease-quick),
|
|
90
|
+
* for what has its own duration (--block-ease and --block-ease-quick in blocks.css, --ease in base.css). */
|
|
91
|
+
export function motionCss(scheme: MotionScheme): string {
|
|
92
|
+
const springs = SPRINGS[scheme];
|
|
93
|
+
const declarations = MOTION_KINDS.flatMap((kind) =>
|
|
94
|
+
MOTION_SPEEDS.map((speed) => {
|
|
95
|
+
const { duration, easing } = springCss(springs[kind][speed]);
|
|
96
|
+
const name = motionVariable(kind, speed);
|
|
97
|
+
return `${name}:${duration}ms ${easing};${name}-duration:${duration}ms;`;
|
|
98
|
+
}),
|
|
99
|
+
);
|
|
100
|
+
const ease = springCss(springs.spatial.default).easing;
|
|
101
|
+
const quick = springCss(springs.effects.default).easing;
|
|
102
|
+
return `:root{${declarations.join('')}--motion-ease:${ease};--motion-ease-quick:${quick};}`;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/** A spring as Motion takes it (motion.dev: `animate(el, …, motionSpring('spatial'))`), in the scheme on the page
|
|
106
|
+
* (data-motion-scheme on <html>, set where motionCss is), else DEFAULT_SCHEME: its stiffness and its damping as a force, for a
|
|
107
|
+
* mass of 1. */
|
|
108
|
+
export function motionSpring(kind: MotionKind, speed: MotionSpeed = 'default', scheme: MotionScheme = pageScheme()) {
|
|
109
|
+
const { damping, stiffness } = SPRINGS[scheme][kind][speed];
|
|
110
|
+
return { type: 'spring' as const, stiffness, damping: 2 * damping * Math.sqrt(stiffness), mass: 1 };
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
/** A spring as the browser's own animations take it (`el.animate(keyframes, motionTiming('spatial'))`), in the scheme on
|
|
114
|
+
* the page: how long it takes, and its curve. */
|
|
115
|
+
export function motionTiming(kind: MotionKind, speed: MotionSpeed = 'default', scheme: MotionScheme = pageScheme()) {
|
|
116
|
+
return springCss(SPRINGS[scheme][kind][speed]);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/** The scheme the page moves by (data-motion-scheme on <html>), else DEFAULT_SCHEME; without a browser, DEFAULT_SCHEME. */
|
|
120
|
+
export function pageScheme(): MotionScheme {
|
|
121
|
+
if (typeof document === 'undefined') return DEFAULT_SCHEME;
|
|
122
|
+
const scheme = document.documentElement.dataset.motionScheme;
|
|
123
|
+
return isMotionScheme(scheme) ? scheme : DEFAULT_SCHEME;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** Whether the page's things should only appear, not move in: the calm scheme, or a visitor who has asked for reduced
|
|
127
|
+
* motion. */
|
|
128
|
+
export function motionReduced(): boolean {
|
|
129
|
+
if (typeof document === 'undefined') return true;
|
|
130
|
+
return pageScheme() === 'calm' || matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
131
|
+
}
|
package/lib/notice.mjs
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
// "Besked", a notice in the text (the standard block in standard/notice/), can be shown until a date and time,
|
|
2
|
-
// written in Danish time ("2026-03-01T12:00"). The site leaves it out when it is built after that time,
|
|
3
|
-
// and a visitor's browser removes it once the time has come between two builds (its load.ts), so it
|
|
4
|
-
// goes at the time without the site being built again.
|
|
5
|
-
const ZONE = 'Europe/Copenhagen';
|
|
6
|
-
const parts = new Intl.DateTimeFormat('en-US', {
|
|
7
|
-
timeZone: ZONE,
|
|
8
|
-
hourCycle: 'h23',
|
|
9
|
-
year: 'numeric',
|
|
10
|
-
month: '2-digit',
|
|
11
|
-
day: '2-digit',
|
|
12
|
-
hour: '2-digit',
|
|
13
|
-
minute: '2-digit',
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
// How far Danish time is ahead of UTC at a moment (one or two hours), in milliseconds.
|
|
17
|
-
function offset(at) {
|
|
18
|
-
const p = Object.fromEntries(parts.formatToParts(at).map((x) => [x.type, x.value]));
|
|
19
|
-
return Date.UTC(+p.year, +p.month - 1, +p.day, +p.hour, +p.minute) - at;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/** A Danish date and time ("2026-03-01T12:00") as milliseconds since 1970, or null. */
|
|
23
|
-
export function untilTime(local) {
|
|
24
|
-
const m = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/.exec(local ?? '');
|
|
25
|
-
if (!m) return null;
|
|
26
|
-
const wall = Date.UTC(+m[1], +m[2] - 1, +m[3], +m[4], +m[5]);
|
|
27
|
-
return wall - offset(wall - offset(wall));
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** Whether a notice shown until `local` is over. */
|
|
31
|
-
export const isOver = (local, now = Date.now()) => {
|
|
32
|
-
const at = untilTime(local);
|
|
33
|
-
return at !== null && now >= at;
|
|
34
|
-
};
|
|
1
|
+
// "Besked", a notice in the text (the standard block in standard/notice/), can be shown until a date and time,
|
|
2
|
+
// written in Danish time ("2026-03-01T12:00"). The site leaves it out when it is built after that time,
|
|
3
|
+
// and a visitor's browser removes it once the time has come between two builds (its load.ts), so it
|
|
4
|
+
// goes at the time without the site being built again.
|
|
5
|
+
const ZONE = 'Europe/Copenhagen';
|
|
6
|
+
const parts = new Intl.DateTimeFormat('en-US', {
|
|
7
|
+
timeZone: ZONE,
|
|
8
|
+
hourCycle: 'h23',
|
|
9
|
+
year: 'numeric',
|
|
10
|
+
month: '2-digit',
|
|
11
|
+
day: '2-digit',
|
|
12
|
+
hour: '2-digit',
|
|
13
|
+
minute: '2-digit',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// How far Danish time is ahead of UTC at a moment (one or two hours), in milliseconds.
|
|
17
|
+
function offset(at) {
|
|
18
|
+
const p = Object.fromEntries(parts.formatToParts(at).map((x) => [x.type, x.value]));
|
|
19
|
+
return Date.UTC(+p.year, +p.month - 1, +p.day, +p.hour, +p.minute) - at;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** A Danish date and time ("2026-03-01T12:00") as milliseconds since 1970, or null. */
|
|
23
|
+
export function untilTime(local) {
|
|
24
|
+
const m = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2})$/.exec(local ?? '');
|
|
25
|
+
if (!m) return null;
|
|
26
|
+
const wall = Date.UTC(+m[1], +m[2] - 1, +m[3], +m[4], +m[5]);
|
|
27
|
+
return wall - offset(wall - offset(wall));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** Whether a notice shown until `local` is over. */
|
|
31
|
+
export const isOver = (local, now = Date.now()) => {
|
|
32
|
+
const at = untilTime(local);
|
|
33
|
+
return at !== null && now >= at;
|
|
34
|
+
};
|
package/lib/scheduled.mjs
CHANGED
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
// The pages and blog posts that are Planlagt (`status: "scheduled"` with `publishAt`, packages/editor/lib/status.mjs), for
|
|
2
|
-
// publishing them once their time has come: the build lists them (packages/editor/scripts/scheduled-list.mjs), and each hour the
|
|
3
|
-
// site's Worker makes those whose time has come Udgivet in one commit on main (packages/editor/worker/publish.js), which builds the
|
|
4
|
-
// site. No dependencies, so the Worker can use it.
|
|
5
|
-
import { stateOf } from './status.mjs';
|
|
6
|
-
|
|
7
|
-
const FENCE = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
8
|
-
// The two fields as the editor writes them (packages/editor/src/frontmatter.mjs), one line each.
|
|
9
|
-
const line = (name) => new RegExp(`^${name}: *"?([^"\\r\\n]*)"?\\r?\\n`, 'm');
|
|
10
|
-
|
|
11
|
-
/** The folders with pages and posts, and what one is called in a commit. */
|
|
12
|
-
export const KINDS = [
|
|
13
|
-
{ dir: 'src/content/blog', name: 'blogindlæg' },
|
|
14
|
-
{ dir: 'src/content/pages', name: 'side' },
|
|
15
|
-
];
|
|
16
|
-
|
|
17
|
-
/** The status and time in a file's front matter. */
|
|
18
|
-
export function scheduleOf(text) {
|
|
19
|
-
const yaml = text.match(FENCE)?.[1] ?? '';
|
|
20
|
-
return { status: yaml.match(line('status'))?.[1], publishAt: yaml.match(line('publishAt'))?.[1] };
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
/** Whether a Planlagt page or post with this time is to be published at `now`. */
|
|
24
|
-
export const isDue = (publishAt, now = Date.now()) => stateOf({ status: 'scheduled', publishAt }, now) === 'published';
|
|
25
|
-
|
|
26
|
-
/** The file Udgivet: its front matter without `status` and `publishAt`. */
|
|
27
|
-
export function published(text) {
|
|
28
|
-
const yaml = text.match(FENCE)?.[1] ?? '';
|
|
29
|
-
const rest = `${yaml}\n`.replace(line('status'), '').replace(line('publishAt'), '').replace(/\n$/, '');
|
|
30
|
-
return text.replace(FENCE, `---\n${rest}\n---`);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
/** A file as a commit names it: `blogindlæg "x"`. */
|
|
34
|
-
export function nameOf(path) {
|
|
35
|
-
const kind = KINDS.find((k) => path.startsWith(`${k.dir}/`));
|
|
36
|
-
return `${kind?.name ?? 'fil'} "${path.slice((kind?.dir.length ?? -1) + 1).replace(/(\/index)?\.md$/, '')}"`;
|
|
37
|
-
}
|
|
1
|
+
// The pages and blog posts that are Planlagt (`status: "scheduled"` with `publishAt`, packages/editor/lib/status.mjs), for
|
|
2
|
+
// publishing them once their time has come: the build lists them (packages/editor/scripts/scheduled-list.mjs), and each hour the
|
|
3
|
+
// site's Worker makes those whose time has come Udgivet in one commit on main (packages/editor/worker/publish.js), which builds the
|
|
4
|
+
// site. No dependencies, so the Worker can use it.
|
|
5
|
+
import { stateOf } from './status.mjs';
|
|
6
|
+
|
|
7
|
+
const FENCE = /^---\r?\n([\s\S]*?)\r?\n---/;
|
|
8
|
+
// The two fields as the editor writes them (packages/editor/src/frontmatter.mjs), one line each.
|
|
9
|
+
const line = (name) => new RegExp(`^${name}: *"?([^"\\r\\n]*)"?\\r?\\n`, 'm');
|
|
10
|
+
|
|
11
|
+
/** The folders with pages and posts, and what one is called in a commit. */
|
|
12
|
+
export const KINDS = [
|
|
13
|
+
{ dir: 'src/content/blog', name: 'blogindlæg' },
|
|
14
|
+
{ dir: 'src/content/pages', name: 'side' },
|
|
15
|
+
];
|
|
16
|
+
|
|
17
|
+
/** The status and time in a file's front matter. */
|
|
18
|
+
export function scheduleOf(text) {
|
|
19
|
+
const yaml = text.match(FENCE)?.[1] ?? '';
|
|
20
|
+
return { status: yaml.match(line('status'))?.[1], publishAt: yaml.match(line('publishAt'))?.[1] };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** Whether a Planlagt page or post with this time is to be published at `now`. */
|
|
24
|
+
export const isDue = (publishAt, now = Date.now()) => stateOf({ status: 'scheduled', publishAt }, now) === 'published';
|
|
25
|
+
|
|
26
|
+
/** The file Udgivet: its front matter without `status` and `publishAt`. */
|
|
27
|
+
export function published(text) {
|
|
28
|
+
const yaml = text.match(FENCE)?.[1] ?? '';
|
|
29
|
+
const rest = `${yaml}\n`.replace(line('status'), '').replace(line('publishAt'), '').replace(/\n$/, '');
|
|
30
|
+
return text.replace(FENCE, `---\n${rest}\n---`);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
/** A file as a commit names it: `blogindlæg "x"`. */
|
|
34
|
+
export function nameOf(path) {
|
|
35
|
+
const kind = KINDS.find((k) => path.startsWith(`${k.dir}/`));
|
|
36
|
+
return `${kind?.name ?? 'fil'} "${path.slice((kind?.dir.length ?? -1) + 1).replace(/(\/index)?\.md$/, '')}"`;
|
|
37
|
+
}
|