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