@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/theme/ui/Slider.tsx
CHANGED
|
@@ -1,155 +1,155 @@
|
|
|
1
|
-
// A slider (m3.material.io/components/sliders, .slider in ../styles/ui.css): a value chosen between `min` and `max`
|
|
2
|
-
// (`value`; the standard slider, its active track from the start), in steps of `step` with a stop at each (`stops`),
|
|
3
|
-
// from the middle (`centered`: the active track from the middle to the handle, for a value below and above a middle
|
|
4
|
-
// one), or a range (`range`, its start and end, with two handles that cannot pass each other; `handleLabels` says what
|
|
5
|
-
// each is to a screen reader). Its size (`size`: xsmall, the default, small, medium, large or xlarge, as M3 Expressive
|
|
6
|
-
// names them: how thick the track is) and its direction (`orientation`: horizontal, the default, or vertical, from
|
|
7
|
-
// the bottom up) are Material's names; how they look is the theme's. A standard slider of size medium or larger can
|
|
8
|
-
// have an icon in its track (`icon`, the theme's icon by its name: in the active track at its start, after the
|
|
9
|
-
// handle while there is no room for it there). Its name (`label`) stands over it (`hideLabel`: only screen readers say
|
|
10
|
-
// it), and a label with the value over a handle while it is moved or has the focus (`valueLabel`; 'always': all the
|
|
11
|
-
// time). The handles are native range inputs, so the keyboard moves them (the arrow keys, Home, End, Page Up and Page
|
|
12
|
-
// Down) and screen readers say the value; the active track, the stops and the value labels follow them on the site
|
|
13
|
-
// with slider.script.ts and in the editor here (both with updateSlider in sliderUpdate.ts). `onChange` (the editor): the value is the editor's, and a
|
|
14
|
-
// handle moved gives its new value (and which handle, 0 or 1); else the value is the one it starts with. `disabled`: it
|
|
15
|
-
// cannot be moved; `name` is the input's (a range's: one for each); `className` goes after its own classes. An Astro component
|
|
16
|
-
// gives an element the same classes with sliderClass.
|
|
17
|
-
import type { ChangeEvent, CSSProperties, FormEvent } from 'react';
|
|
18
|
-
import { Svg } from '@morphemecms/cms/src/icon';
|
|
19
|
-
import { sliderPlace, stopState, updateSlider } from './sliderUpdate';
|
|
20
|
-
|
|
21
|
-
/** A slider's sizes, as M3 Expressive names them. */
|
|
22
|
-
export type SliderSize = 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge';
|
|
23
|
-
export type SliderOrientation = 'horizontal' | 'vertical';
|
|
24
|
-
|
|
25
|
-
/** A slider's classes: a range, `slider-range`; centered, `slider-centered`; its size but the default; vertical. */
|
|
26
|
-
export const sliderClass = (range = false, size: SliderSize = 'xsmall', centered = false, orientation: SliderOrientation = 'horizontal') =>
|
|
27
|
-
[
|
|
28
|
-
'slider',
|
|
29
|
-
range && 'slider-range',
|
|
30
|
-
centered && !range && 'slider-centered',
|
|
31
|
-
size !== 'xsmall' && `slider-${size}`,
|
|
32
|
-
orientation === 'vertical' && 'slider-vertical',
|
|
33
|
-
]
|
|
34
|
-
.filter(Boolean)
|
|
35
|
-
.join(' ');
|
|
36
|
-
|
|
37
|
-
export default function Slider({
|
|
38
|
-
label,
|
|
39
|
-
hideLabel,
|
|
40
|
-
min = 0,
|
|
41
|
-
max = 100,
|
|
42
|
-
step = 1,
|
|
43
|
-
value,
|
|
44
|
-
range,
|
|
45
|
-
centered,
|
|
46
|
-
handleLabels,
|
|
47
|
-
stops,
|
|
48
|
-
size = 'xsmall',
|
|
49
|
-
orientation = 'horizontal',
|
|
50
|
-
icon,
|
|
51
|
-
valueLabel,
|
|
52
|
-
disabled,
|
|
53
|
-
name,
|
|
54
|
-
onChange,
|
|
55
|
-
className,
|
|
56
|
-
}: {
|
|
57
|
-
label: string;
|
|
58
|
-
hideLabel?: boolean;
|
|
59
|
-
min?: number;
|
|
60
|
-
max?: number;
|
|
61
|
-
step?: number;
|
|
62
|
-
value?: number;
|
|
63
|
-
range?: [number, number];
|
|
64
|
-
centered?: boolean;
|
|
65
|
-
handleLabels?: [string, string];
|
|
66
|
-
stops?: boolean;
|
|
67
|
-
size?: SliderSize;
|
|
68
|
-
orientation?: SliderOrientation;
|
|
69
|
-
icon?: string;
|
|
70
|
-
valueLabel?: boolean | 'always';
|
|
71
|
-
disabled?: boolean;
|
|
72
|
-
name?: string | [string, string];
|
|
73
|
-
onChange?: (value: number, handle: number) => void;
|
|
74
|
-
className?: string;
|
|
75
|
-
}) {
|
|
76
|
-
const middle = centered && !range;
|
|
77
|
-
const values = range ?? [value ?? (middle ? (min + max) / 2 : min)];
|
|
78
|
-
const { start, end } = sliderPlace(values, min, max, middle);
|
|
79
|
-
const count = Math.round((max - min) / step);
|
|
80
|
-
// A stop at each step, when there are not so many that they run together.
|
|
81
|
-
const stopValues = stops && count > 0 && count <= 50 ? Array.from({ length: count + 1 }, (_, i) => min + i * step) : [];
|
|
82
|
-
// The icon only in a standard slider's track, and only where the track is thick enough to hold it.
|
|
83
|
-
const inset = icon && !range && !middle && ['medium', 'large', 'xlarge'].includes(size) ? icon : undefined;
|
|
84
|
-
const vertical = orientation === 'vertical';
|
|
85
|
-
const place = { '--slider-start': start, '--slider-end': end } as CSSProperties;
|
|
86
|
-
return (
|
|
87
|
-
<div
|
|
88
|
-
className={[sliderClass(Boolean(range), size, middle, orientation), className].filter(Boolean).join(' ')}
|
|
89
|
-
style={place}
|
|
90
|
-
role={range ? 'group' : undefined}
|
|
91
|
-
aria-label={range ? label : undefined}
|
|
92
|
-
data-slider=""
|
|
93
|
-
data-start-on-top={range && start > 0.5 ? '' : undefined}
|
|
94
|
-
data-below-center={middle && values[0] < (min + max) / 2 ? '' : undefined}
|
|
95
|
-
onInput={(e: FormEvent<HTMLDivElement>) => updateSlider(e.currentTarget, e.target)}
|
|
96
|
-
>
|
|
97
|
-
{!hideLabel && (
|
|
98
|
-
<span className="slider-label" aria-hidden="true">
|
|
99
|
-
{label}
|
|
100
|
-
</span>
|
|
101
|
-
)}
|
|
102
|
-
<div className="slider-control">
|
|
103
|
-
<span className="slider-track" aria-hidden="true">
|
|
104
|
-
{(range || middle) && <span className="slider-inactive-track slider-inactive-track-start" />}
|
|
105
|
-
<span className="slider-active-track">
|
|
106
|
-
{inset && <Svg name={inset} size={24} className="slider-icon" />}
|
|
107
|
-
{inset && <Svg name={inset} size={24} className="slider-icon slider-icon-inactive" />}
|
|
108
|
-
</span>
|
|
109
|
-
<span className="slider-inactive-track slider-inactive-track-end" />
|
|
110
|
-
{stopValues.map((v) => {
|
|
111
|
-
const { active, under } = stopState(v, values, min, max, middle);
|
|
112
|
-
return (
|
|
113
|
-
<span
|
|
114
|
-
key={v}
|
|
115
|
-
className="slider-stop"
|
|
116
|
-
style={{ '--slider-stop': (v - min) / (max - min) } as CSSProperties}
|
|
117
|
-
data-slider-stop={v}
|
|
118
|
-
data-active={active ? '' : undefined}
|
|
119
|
-
data-under={under ? '' : undefined}
|
|
120
|
-
/>
|
|
121
|
-
);
|
|
122
|
-
})}
|
|
123
|
-
</span>
|
|
124
|
-
{values.map((v, i) => [
|
|
125
|
-
<input
|
|
126
|
-
key={`input-${i}`}
|
|
127
|
-
type="range"
|
|
128
|
-
className="slider-input"
|
|
129
|
-
min={min}
|
|
130
|
-
max={max}
|
|
131
|
-
step={step}
|
|
132
|
-
{...(onChange
|
|
133
|
-
? { value: v, onChange: (e: ChangeEvent<HTMLInputElement>) => onChange(Number(e.target.value), i) }
|
|
134
|
-
: { defaultValue: v })}
|
|
135
|
-
disabled={disabled}
|
|
136
|
-
name={Array.isArray(name) ? name[i] : name}
|
|
137
|
-
aria-label={range ? (handleLabels?.[i] ?? label) : label}
|
|
138
|
-
aria-orientation={vertical ? 'vertical' : undefined}
|
|
139
|
-
data-slider-input=""
|
|
140
|
-
/>,
|
|
141
|
-
valueLabel && (
|
|
142
|
-
<output
|
|
143
|
-
key={`value-${i}`}
|
|
144
|
-
className={valueLabel === 'always' ? 'slider-value slider-value-always' : 'slider-value'}
|
|
145
|
-
aria-hidden="true"
|
|
146
|
-
data-slider-value=""
|
|
147
|
-
>
|
|
148
|
-
{v}
|
|
149
|
-
</output>
|
|
150
|
-
),
|
|
151
|
-
])}
|
|
152
|
-
</div>
|
|
153
|
-
</div>
|
|
154
|
-
);
|
|
155
|
-
}
|
|
1
|
+
// A slider (m3.material.io/components/sliders, .slider in ../styles/ui.css): a value chosen between `min` and `max`
|
|
2
|
+
// (`value`; the standard slider, its active track from the start), in steps of `step` with a stop at each (`stops`),
|
|
3
|
+
// from the middle (`centered`: the active track from the middle to the handle, for a value below and above a middle
|
|
4
|
+
// one), or a range (`range`, its start and end, with two handles that cannot pass each other; `handleLabels` says what
|
|
5
|
+
// each is to a screen reader). Its size (`size`: xsmall, the default, small, medium, large or xlarge, as M3 Expressive
|
|
6
|
+
// names them: how thick the track is) and its direction (`orientation`: horizontal, the default, or vertical, from
|
|
7
|
+
// the bottom up) are Material's names; how they look is the theme's. A standard slider of size medium or larger can
|
|
8
|
+
// have an icon in its track (`icon`, the theme's icon by its name: in the active track at its start, after the
|
|
9
|
+
// handle while there is no room for it there). Its name (`label`) stands over it (`hideLabel`: only screen readers say
|
|
10
|
+
// it), and a label with the value over a handle while it is moved or has the focus (`valueLabel`; 'always': all the
|
|
11
|
+
// time). The handles are native range inputs, so the keyboard moves them (the arrow keys, Home, End, Page Up and Page
|
|
12
|
+
// Down) and screen readers say the value; the active track, the stops and the value labels follow them on the site
|
|
13
|
+
// with slider.script.ts and in the editor here (both with updateSlider in sliderUpdate.ts). `onChange` (the editor): the value is the editor's, and a
|
|
14
|
+
// handle moved gives its new value (and which handle, 0 or 1); else the value is the one it starts with. `disabled`: it
|
|
15
|
+
// cannot be moved; `name` is the input's (a range's: one for each); `className` goes after its own classes. An Astro component
|
|
16
|
+
// gives an element the same classes with sliderClass.
|
|
17
|
+
import type { ChangeEvent, CSSProperties, FormEvent } from 'react';
|
|
18
|
+
import { Svg } from '@morphemecms/cms/src/icon';
|
|
19
|
+
import { sliderPlace, stopState, updateSlider } from './sliderUpdate';
|
|
20
|
+
|
|
21
|
+
/** A slider's sizes, as M3 Expressive names them. */
|
|
22
|
+
export type SliderSize = 'xsmall' | 'small' | 'medium' | 'large' | 'xlarge';
|
|
23
|
+
export type SliderOrientation = 'horizontal' | 'vertical';
|
|
24
|
+
|
|
25
|
+
/** A slider's classes: a range, `slider-range`; centered, `slider-centered`; its size but the default; vertical. */
|
|
26
|
+
export const sliderClass = (range = false, size: SliderSize = 'xsmall', centered = false, orientation: SliderOrientation = 'horizontal') =>
|
|
27
|
+
[
|
|
28
|
+
'slider',
|
|
29
|
+
range && 'slider-range',
|
|
30
|
+
centered && !range && 'slider-centered',
|
|
31
|
+
size !== 'xsmall' && `slider-${size}`,
|
|
32
|
+
orientation === 'vertical' && 'slider-vertical',
|
|
33
|
+
]
|
|
34
|
+
.filter(Boolean)
|
|
35
|
+
.join(' ');
|
|
36
|
+
|
|
37
|
+
export default function Slider({
|
|
38
|
+
label,
|
|
39
|
+
hideLabel,
|
|
40
|
+
min = 0,
|
|
41
|
+
max = 100,
|
|
42
|
+
step = 1,
|
|
43
|
+
value,
|
|
44
|
+
range,
|
|
45
|
+
centered,
|
|
46
|
+
handleLabels,
|
|
47
|
+
stops,
|
|
48
|
+
size = 'xsmall',
|
|
49
|
+
orientation = 'horizontal',
|
|
50
|
+
icon,
|
|
51
|
+
valueLabel,
|
|
52
|
+
disabled,
|
|
53
|
+
name,
|
|
54
|
+
onChange,
|
|
55
|
+
className,
|
|
56
|
+
}: {
|
|
57
|
+
label: string;
|
|
58
|
+
hideLabel?: boolean;
|
|
59
|
+
min?: number;
|
|
60
|
+
max?: number;
|
|
61
|
+
step?: number;
|
|
62
|
+
value?: number;
|
|
63
|
+
range?: [number, number];
|
|
64
|
+
centered?: boolean;
|
|
65
|
+
handleLabels?: [string, string];
|
|
66
|
+
stops?: boolean;
|
|
67
|
+
size?: SliderSize;
|
|
68
|
+
orientation?: SliderOrientation;
|
|
69
|
+
icon?: string;
|
|
70
|
+
valueLabel?: boolean | 'always';
|
|
71
|
+
disabled?: boolean;
|
|
72
|
+
name?: string | [string, string];
|
|
73
|
+
onChange?: (value: number, handle: number) => void;
|
|
74
|
+
className?: string;
|
|
75
|
+
}) {
|
|
76
|
+
const middle = centered && !range;
|
|
77
|
+
const values = range ?? [value ?? (middle ? (min + max) / 2 : min)];
|
|
78
|
+
const { start, end } = sliderPlace(values, min, max, middle);
|
|
79
|
+
const count = Math.round((max - min) / step);
|
|
80
|
+
// A stop at each step, when there are not so many that they run together.
|
|
81
|
+
const stopValues = stops && count > 0 && count <= 50 ? Array.from({ length: count + 1 }, (_, i) => min + i * step) : [];
|
|
82
|
+
// The icon only in a standard slider's track, and only where the track is thick enough to hold it.
|
|
83
|
+
const inset = icon && !range && !middle && ['medium', 'large', 'xlarge'].includes(size) ? icon : undefined;
|
|
84
|
+
const vertical = orientation === 'vertical';
|
|
85
|
+
const place = { '--slider-start': start, '--slider-end': end } as CSSProperties;
|
|
86
|
+
return (
|
|
87
|
+
<div
|
|
88
|
+
className={[sliderClass(Boolean(range), size, middle, orientation), className].filter(Boolean).join(' ')}
|
|
89
|
+
style={place}
|
|
90
|
+
role={range ? 'group' : undefined}
|
|
91
|
+
aria-label={range ? label : undefined}
|
|
92
|
+
data-slider=""
|
|
93
|
+
data-start-on-top={range && start > 0.5 ? '' : undefined}
|
|
94
|
+
data-below-center={middle && values[0] < (min + max) / 2 ? '' : undefined}
|
|
95
|
+
onInput={(e: FormEvent<HTMLDivElement>) => updateSlider(e.currentTarget, e.target)}
|
|
96
|
+
>
|
|
97
|
+
{!hideLabel && (
|
|
98
|
+
<span className="slider-label" aria-hidden="true">
|
|
99
|
+
{label}
|
|
100
|
+
</span>
|
|
101
|
+
)}
|
|
102
|
+
<div className="slider-control">
|
|
103
|
+
<span className="slider-track" aria-hidden="true">
|
|
104
|
+
{(range || middle) && <span className="slider-inactive-track slider-inactive-track-start" />}
|
|
105
|
+
<span className="slider-active-track">
|
|
106
|
+
{inset && <Svg name={inset} size={24} className="slider-icon" />}
|
|
107
|
+
{inset && <Svg name={inset} size={24} className="slider-icon slider-icon-inactive" />}
|
|
108
|
+
</span>
|
|
109
|
+
<span className="slider-inactive-track slider-inactive-track-end" />
|
|
110
|
+
{stopValues.map((v) => {
|
|
111
|
+
const { active, under } = stopState(v, values, min, max, middle);
|
|
112
|
+
return (
|
|
113
|
+
<span
|
|
114
|
+
key={v}
|
|
115
|
+
className="slider-stop"
|
|
116
|
+
style={{ '--slider-stop': (v - min) / (max - min) } as CSSProperties}
|
|
117
|
+
data-slider-stop={v}
|
|
118
|
+
data-active={active ? '' : undefined}
|
|
119
|
+
data-under={under ? '' : undefined}
|
|
120
|
+
/>
|
|
121
|
+
);
|
|
122
|
+
})}
|
|
123
|
+
</span>
|
|
124
|
+
{values.map((v, i) => [
|
|
125
|
+
<input
|
|
126
|
+
key={`input-${i}`}
|
|
127
|
+
type="range"
|
|
128
|
+
className="slider-input"
|
|
129
|
+
min={min}
|
|
130
|
+
max={max}
|
|
131
|
+
step={step}
|
|
132
|
+
{...(onChange
|
|
133
|
+
? { value: v, onChange: (e: ChangeEvent<HTMLInputElement>) => onChange(Number(e.target.value), i) }
|
|
134
|
+
: { defaultValue: v })}
|
|
135
|
+
disabled={disabled}
|
|
136
|
+
name={Array.isArray(name) ? name[i] : name}
|
|
137
|
+
aria-label={range ? (handleLabels?.[i] ?? label) : label}
|
|
138
|
+
aria-orientation={vertical ? 'vertical' : undefined}
|
|
139
|
+
data-slider-input=""
|
|
140
|
+
/>,
|
|
141
|
+
valueLabel && (
|
|
142
|
+
<output
|
|
143
|
+
key={`value-${i}`}
|
|
144
|
+
className={valueLabel === 'always' ? 'slider-value slider-value-always' : 'slider-value'}
|
|
145
|
+
aria-hidden="true"
|
|
146
|
+
data-slider-value=""
|
|
147
|
+
>
|
|
148
|
+
{v}
|
|
149
|
+
</output>
|
|
150
|
+
),
|
|
151
|
+
])}
|
|
152
|
+
</div>
|
|
153
|
+
</div>
|
|
154
|
+
);
|
|
155
|
+
}
|
package/theme/ui/Snackbar.tsx
CHANGED
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
// A snackbar (m3.material.io/components/snackbar, .snackbar in ../styles/ui.css): a short message at the bottom of the
|
|
2
|
-
// screen, what the site says with one (a new version of a page: layouts/PageLayout.astro). Its supporting text (`text`,
|
|
3
|
-
// on one line or two), evt. links in it, each with an arrow (`links`), evt. an action, a text button (`action`, with
|
|
4
|
-
// its `label` and `href` or other attributes on it), under the text when it is long (`longerAction`), and evt. a
|
|
5
|
-
// button that closes it (`closeLabel`, its name). Read by screen readers as a status (`error`: an alert). On the site
|
|
6
|
-
// it is drawn in a <template data-snackbar> (with `data-ms` for how long it stays), and ui/snackbar.script.ts shows it
|
|
7
|
-
// at the bottom with the editor's snackbar() (@morphemecms/cms/lib/snackbar.ts: where messages stand, how long, and how
|
|
8
|
-
// they are swiped away, the same as the editor's messages); in the editor only drawn. How it looks is the theme's
|
|
9
|
-
// (--snackbar-*). An Astro component gives an element the same classes with snackbarClass.
|
|
10
|
-
import { Fragment } from 'react';
|
|
11
|
-
import { Svg } from '@morphemecms/cms/src/icon';
|
|
12
|
-
import { Link } from '@morphemecms/cms/src/standard/view';
|
|
13
|
-
import Button from '@theme/ui/Button';
|
|
14
|
-
import IconButton from '@theme/ui/IconButton';
|
|
15
|
-
|
|
16
|
-
export type SnackbarLink = { text: string; href: string };
|
|
17
|
-
export type SnackbarAction = { label: string; href?: string } & Record<string, unknown>;
|
|
18
|
-
|
|
19
|
-
/** A snackbar's classes: with its action under the text, or beside it. */
|
|
20
|
-
export const snackbarClass = (longerAction?: boolean) => ['snackbar', longerAction && 'snackbar-longer-action'].filter(Boolean).join(' ');
|
|
21
|
-
|
|
22
|
-
export default function Snackbar({
|
|
23
|
-
text,
|
|
24
|
-
links = [],
|
|
25
|
-
action,
|
|
26
|
-
longerAction,
|
|
27
|
-
closeLabel,
|
|
28
|
-
error,
|
|
29
|
-
className,
|
|
30
|
-
...rest
|
|
31
|
-
}: {
|
|
32
|
-
text: string;
|
|
33
|
-
links?: SnackbarLink[];
|
|
34
|
-
action?: SnackbarAction;
|
|
35
|
-
longerAction?: boolean;
|
|
36
|
-
closeLabel?: string;
|
|
37
|
-
error?: boolean;
|
|
38
|
-
className?: string;
|
|
39
|
-
} & Record<string, unknown>) {
|
|
40
|
-
const { label, ...actionRest } = action ?? { label: '' };
|
|
41
|
-
return (
|
|
42
|
-
<div role={error ? 'alert' : 'status'} className={[snackbarClass(longerAction), className].filter(Boolean).join(' ')} {...rest}>
|
|
43
|
-
<p className="snackbar-supporting-text">
|
|
44
|
-
{text}
|
|
45
|
-
{links.map((link) => (
|
|
46
|
-
<Fragment key={link.href + link.text}>
|
|
47
|
-
{' '}
|
|
48
|
-
<Link href={link.href} className="snackbar-link">
|
|
49
|
-
{link.text}
|
|
50
|
-
<Svg name="arrow-right" size={14} />
|
|
51
|
-
</Link>
|
|
52
|
-
</Fragment>
|
|
53
|
-
))}
|
|
54
|
-
</p>
|
|
55
|
-
{(action || closeLabel) && (
|
|
56
|
-
<div className="snackbar-actions">
|
|
57
|
-
{action && (
|
|
58
|
-
<Button kind="text" size="small" className="snackbar-action" {...actionRest}>
|
|
59
|
-
{label}
|
|
60
|
-
</Button>
|
|
61
|
-
)}
|
|
62
|
-
{closeLabel && <IconButton icon="x" label={closeLabel} className="snackbar-close" data-snackbar-close="" />}
|
|
63
|
-
</div>
|
|
64
|
-
)}
|
|
65
|
-
</div>
|
|
66
|
-
);
|
|
67
|
-
}
|
|
1
|
+
// A snackbar (m3.material.io/components/snackbar, .snackbar in ../styles/ui.css): a short message at the bottom of the
|
|
2
|
+
// screen, what the site says with one (a new version of a page: layouts/PageLayout.astro). Its supporting text (`text`,
|
|
3
|
+
// on one line or two), evt. links in it, each with an arrow (`links`), evt. an action, a text button (`action`, with
|
|
4
|
+
// its `label` and `href` or other attributes on it), under the text when it is long (`longerAction`), and evt. a
|
|
5
|
+
// button that closes it (`closeLabel`, its name). Read by screen readers as a status (`error`: an alert). On the site
|
|
6
|
+
// it is drawn in a <template data-snackbar> (with `data-ms` for how long it stays), and ui/snackbar.script.ts shows it
|
|
7
|
+
// at the bottom with the editor's snackbar() (@morphemecms/cms/lib/snackbar.ts: where messages stand, how long, and how
|
|
8
|
+
// they are swiped away, the same as the editor's messages); in the editor only drawn. How it looks is the theme's
|
|
9
|
+
// (--snackbar-*). An Astro component gives an element the same classes with snackbarClass.
|
|
10
|
+
import { Fragment } from 'react';
|
|
11
|
+
import { Svg } from '@morphemecms/cms/src/icon';
|
|
12
|
+
import { Link } from '@morphemecms/cms/src/standard/view';
|
|
13
|
+
import Button from '@theme/ui/Button';
|
|
14
|
+
import IconButton from '@theme/ui/IconButton';
|
|
15
|
+
|
|
16
|
+
export type SnackbarLink = { text: string; href: string };
|
|
17
|
+
export type SnackbarAction = { label: string; href?: string } & Record<string, unknown>;
|
|
18
|
+
|
|
19
|
+
/** A snackbar's classes: with its action under the text, or beside it. */
|
|
20
|
+
export const snackbarClass = (longerAction?: boolean) => ['snackbar', longerAction && 'snackbar-longer-action'].filter(Boolean).join(' ');
|
|
21
|
+
|
|
22
|
+
export default function Snackbar({
|
|
23
|
+
text,
|
|
24
|
+
links = [],
|
|
25
|
+
action,
|
|
26
|
+
longerAction,
|
|
27
|
+
closeLabel,
|
|
28
|
+
error,
|
|
29
|
+
className,
|
|
30
|
+
...rest
|
|
31
|
+
}: {
|
|
32
|
+
text: string;
|
|
33
|
+
links?: SnackbarLink[];
|
|
34
|
+
action?: SnackbarAction;
|
|
35
|
+
longerAction?: boolean;
|
|
36
|
+
closeLabel?: string;
|
|
37
|
+
error?: boolean;
|
|
38
|
+
className?: string;
|
|
39
|
+
} & Record<string, unknown>) {
|
|
40
|
+
const { label, ...actionRest } = action ?? { label: '' };
|
|
41
|
+
return (
|
|
42
|
+
<div role={error ? 'alert' : 'status'} className={[snackbarClass(longerAction), className].filter(Boolean).join(' ')} {...rest}>
|
|
43
|
+
<p className="snackbar-supporting-text">
|
|
44
|
+
{text}
|
|
45
|
+
{links.map((link) => (
|
|
46
|
+
<Fragment key={link.href + link.text}>
|
|
47
|
+
{' '}
|
|
48
|
+
<Link href={link.href} className="snackbar-link">
|
|
49
|
+
{link.text}
|
|
50
|
+
<Svg name="arrow-right" size={14} />
|
|
51
|
+
</Link>
|
|
52
|
+
</Fragment>
|
|
53
|
+
))}
|
|
54
|
+
</p>
|
|
55
|
+
{(action || closeLabel) && (
|
|
56
|
+
<div className="snackbar-actions">
|
|
57
|
+
{action && (
|
|
58
|
+
<Button kind="text" size="small" className="snackbar-action" {...actionRest}>
|
|
59
|
+
{label}
|
|
60
|
+
</Button>
|
|
61
|
+
)}
|
|
62
|
+
{closeLabel && <IconButton icon="x" label={closeLabel} className="snackbar-close" data-snackbar-close="" />}
|
|
63
|
+
</div>
|
|
64
|
+
)}
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
}
|
package/theme/ui/SplitButton.tsx
CHANGED
|
@@ -1,67 +1,67 @@
|
|
|
1
|
-
// A split button (m3.material.io/components/split-button, .split-button in ../styles/ui.css): the main action (the
|
|
2
|
-
// theme's Button: `label`, evt. `icon`, with `href` a link) and joined to it a button with an arrow (its name
|
|
3
|
-
// `menuLabel`, read by screen readers) that opens a menu with the other ways to do it, the theme's Menu with its
|
|
4
|
-
// MenuItems (`children`). Its kind (`kind`: filled, the default, tonal, elevated or outlined) and its size (`size`:
|
|
5
|
-
// xsmall, small, medium, the default, large or xlarge) are the Button's, and so is its look, with the corners between
|
|
6
|
-
// the two small (larger with the size); the arrow's button is as wide as the button is high, and fully round while its
|
|
7
|
-
// menu is open (aria-expanded). `open` draws it open (the editor). On the site ui/splitButton.script.ts opens and closes the
|
|
8
|
-
// menu. Other attributes (data-…) go on the main action, and `className` on the whole.
|
|
9
|
-
import { useId, type ReactNode } from 'react';
|
|
10
|
-
import { Svg } from '@morphemecms/cms/src/icon';
|
|
11
|
-
import type { ButtonKind } from '@morphemecms/cms/src/standard/view';
|
|
12
|
-
import Button, { buttonClass, type ButtonSize } from '@theme/ui/Button';
|
|
13
|
-
import { Menu } from '@theme/ui/Menu';
|
|
14
|
-
|
|
15
|
-
export type SplitButtonKind = Exclude<ButtonKind, 'text'>;
|
|
16
|
-
export const splitButtonKinds: SplitButtonKind[] = ['filled', 'tonal', 'elevated', 'outlined'];
|
|
17
|
-
|
|
18
|
-
/** A split button's class (the whole: its main action and its arrow have the Button's classes). */
|
|
19
|
-
export const splitButtonClass = 'split-button';
|
|
20
|
-
|
|
21
|
-
export default function SplitButton({
|
|
22
|
-
kind = 'filled',
|
|
23
|
-
size,
|
|
24
|
-
icon,
|
|
25
|
-
label,
|
|
26
|
-
href,
|
|
27
|
-
menuLabel,
|
|
28
|
-
open,
|
|
29
|
-
disabled,
|
|
30
|
-
className,
|
|
31
|
-
children,
|
|
32
|
-
...rest
|
|
33
|
-
}: {
|
|
34
|
-
kind?: SplitButtonKind;
|
|
35
|
-
size?: ButtonSize;
|
|
36
|
-
icon?: string;
|
|
37
|
-
label: string;
|
|
38
|
-
href?: string;
|
|
39
|
-
menuLabel: string;
|
|
40
|
-
open?: boolean;
|
|
41
|
-
disabled?: boolean;
|
|
42
|
-
className?: string;
|
|
43
|
-
children: ReactNode;
|
|
44
|
-
} & Record<string, unknown>) {
|
|
45
|
-
const menu = useId();
|
|
46
|
-
return (
|
|
47
|
-
<div className={[splitButtonClass, className].filter(Boolean).join(' ')} data-split-button="">
|
|
48
|
-
<Button kind={kind} size={size} icon={icon} href={href} disabled={disabled} className="split-button-leading" {...rest}>
|
|
49
|
-
{label}
|
|
50
|
-
</Button>
|
|
51
|
-
<button
|
|
52
|
-
type="button"
|
|
53
|
-
className={`${buttonClass(kind, size)} split-button-trailing`}
|
|
54
|
-
aria-label={menuLabel}
|
|
55
|
-
aria-expanded={Boolean(open)}
|
|
56
|
-
aria-controls={menu}
|
|
57
|
-
disabled={disabled}
|
|
58
|
-
data-split-button-toggle=""
|
|
59
|
-
>
|
|
60
|
-
<Svg name="caret-down" size={20} className="split-button-arrow" />
|
|
61
|
-
</button>
|
|
62
|
-
<Menu id={menu} className="split-button-menu" aria-label={menuLabel} hidden={!open} data-split-button-menu="">
|
|
63
|
-
{children}
|
|
64
|
-
</Menu>
|
|
65
|
-
</div>
|
|
66
|
-
);
|
|
67
|
-
}
|
|
1
|
+
// A split button (m3.material.io/components/split-button, .split-button in ../styles/ui.css): the main action (the
|
|
2
|
+
// theme's Button: `label`, evt. `icon`, with `href` a link) and joined to it a button with an arrow (its name
|
|
3
|
+
// `menuLabel`, read by screen readers) that opens a menu with the other ways to do it, the theme's Menu with its
|
|
4
|
+
// MenuItems (`children`). Its kind (`kind`: filled, the default, tonal, elevated or outlined) and its size (`size`:
|
|
5
|
+
// xsmall, small, medium, the default, large or xlarge) are the Button's, and so is its look, with the corners between
|
|
6
|
+
// the two small (larger with the size); the arrow's button is as wide as the button is high, and fully round while its
|
|
7
|
+
// menu is open (aria-expanded). `open` draws it open (the editor). On the site ui/splitButton.script.ts opens and closes the
|
|
8
|
+
// menu. Other attributes (data-…) go on the main action, and `className` on the whole.
|
|
9
|
+
import { useId, type ReactNode } from 'react';
|
|
10
|
+
import { Svg } from '@morphemecms/cms/src/icon';
|
|
11
|
+
import type { ButtonKind } from '@morphemecms/cms/src/standard/view';
|
|
12
|
+
import Button, { buttonClass, type ButtonSize } from '@theme/ui/Button';
|
|
13
|
+
import { Menu } from '@theme/ui/Menu';
|
|
14
|
+
|
|
15
|
+
export type SplitButtonKind = Exclude<ButtonKind, 'text'>;
|
|
16
|
+
export const splitButtonKinds: SplitButtonKind[] = ['filled', 'tonal', 'elevated', 'outlined'];
|
|
17
|
+
|
|
18
|
+
/** A split button's class (the whole: its main action and its arrow have the Button's classes). */
|
|
19
|
+
export const splitButtonClass = 'split-button';
|
|
20
|
+
|
|
21
|
+
export default function SplitButton({
|
|
22
|
+
kind = 'filled',
|
|
23
|
+
size,
|
|
24
|
+
icon,
|
|
25
|
+
label,
|
|
26
|
+
href,
|
|
27
|
+
menuLabel,
|
|
28
|
+
open,
|
|
29
|
+
disabled,
|
|
30
|
+
className,
|
|
31
|
+
children,
|
|
32
|
+
...rest
|
|
33
|
+
}: {
|
|
34
|
+
kind?: SplitButtonKind;
|
|
35
|
+
size?: ButtonSize;
|
|
36
|
+
icon?: string;
|
|
37
|
+
label: string;
|
|
38
|
+
href?: string;
|
|
39
|
+
menuLabel: string;
|
|
40
|
+
open?: boolean;
|
|
41
|
+
disabled?: boolean;
|
|
42
|
+
className?: string;
|
|
43
|
+
children: ReactNode;
|
|
44
|
+
} & Record<string, unknown>) {
|
|
45
|
+
const menu = useId();
|
|
46
|
+
return (
|
|
47
|
+
<div className={[splitButtonClass, className].filter(Boolean).join(' ')} data-split-button="">
|
|
48
|
+
<Button kind={kind} size={size} icon={icon} href={href} disabled={disabled} className="split-button-leading" {...rest}>
|
|
49
|
+
{label}
|
|
50
|
+
</Button>
|
|
51
|
+
<button
|
|
52
|
+
type="button"
|
|
53
|
+
className={`${buttonClass(kind, size)} split-button-trailing`}
|
|
54
|
+
aria-label={menuLabel}
|
|
55
|
+
aria-expanded={Boolean(open)}
|
|
56
|
+
aria-controls={menu}
|
|
57
|
+
disabled={disabled}
|
|
58
|
+
data-split-button-toggle=""
|
|
59
|
+
>
|
|
60
|
+
<Svg name="caret-down" size={20} className="split-button-arrow" />
|
|
61
|
+
</button>
|
|
62
|
+
<Menu id={menu} className="split-button-menu" aria-label={menuLabel} hidden={!open} data-split-button-menu="">
|
|
63
|
+
{children}
|
|
64
|
+
</Menu>
|
|
65
|
+
</div>
|
|
66
|
+
);
|
|
67
|
+
}
|