@morphemecms/cms 0.0.0-stage → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +51 -3
- package/astro.d.mts +2 -0
- package/astro.mjs +162 -0
- package/bin/morpheme.mjs +38 -0
- package/client.d.ts +10 -0
- package/defaults/blockTexts.ts +33 -0
- package/defaults/collections.ts +774 -0
- package/defaults/colors.ts +125 -0
- package/defaults/company.ts +20 -0
- package/defaults/editor.ts +178 -0
- package/defaults/internalLinks.ts +30 -0
- package/defaults/opens.ts +18 -0
- package/defaults/popup.tsx +93 -0
- package/defaults/privacy.ts +79 -0
- package/defaults/rules.ts +450 -0
- package/defaults/schema.ts +16 -0
- package/defaults/sitedata.ts +129 -0
- package/defaults/standard.ts +106 -0
- package/defaults/standardPages.ts +87 -0
- package/defaults/texts.ts +481 -0
- package/demo/README.md +26 -0
- package/demo/public/apple-touch-icon.png +0 -0
- package/demo/public/editor/apple-touch-icon.png +0 -0
- package/demo/public/editor/icon-192.png +0 -0
- package/demo/public/editor/icon-512.png +0 -0
- package/demo/public/editor/icon-maskable-512.png +0 -0
- package/demo/public/favicon.ico +0 -0
- package/demo/public/favicon.svg +1 -0
- package/demo/public/images/uploads/2026/10/andromeda.webp +0 -0
- package/demo/public/images/uploads/2026/10/earth-from-space.webp +0 -0
- package/demo/public/images/uploads/2026/10/editor-blog.webp +0 -0
- package/demo/public/images/uploads/2026/10/editor-colors.webp +0 -0
- package/demo/public/images/uploads/2026/10/editor-home.webp +0 -0
- package/demo/public/images/uploads/2026/10/editor-page.webp +0 -0
- package/demo/public/images/uploads/2026/10/editor-pages.webp +0 -0
- package/demo/public/images/uploads/2026/10/editor-seo.webp +0 -0
- package/demo/public/images/uploads/2026/10/editor-start.webp +0 -0
- package/demo/public/images/uploads/2026/10/editor-themes.webp +0 -0
- package/demo/public/images/uploads/2026/10/moon.webp +0 -0
- package/demo/public/images/uploads/2026/10/saturn.webp +0 -0
- package/demo/public/logo.svg +1 -0
- package/demo/src/content/blog/build-a-page-from-blocks.md +19 -0
- package/demo/src/content/blog/colors-everyone-can-read.md +19 -0
- package/demo/src/content/blog/edit-your-website-from-your-phone.md +21 -0
- package/demo/src/content/blog/every-save-is-a-version.md +21 -0
- package/demo/src/content/blog/schedule-a-post.md +17 -0
- package/demo/src/content/blog/secure-from-day-one.md +17 -0
- package/demo/src/content/blog/seo-without-the-guesswork.md +23 -0
- package/demo/src/content/blog/switch-themes-without-losing-anything.md +23 -0
- package/demo/src/content/blog/the-app-store.md +21 -0
- package/demo/src/content/pages/about.md +22 -0
- package/demo/src/content/pages/app-store.md +30 -0
- package/demo/src/content/pages/blocks.md +98 -0
- package/demo/src/content/pages/blog-page.md +11 -0
- package/demo/src/content/pages/contact.md +16 -0
- package/demo/src/content/pages/get-started.md +20 -0
- package/demo/src/content/pages/home.md +26 -0
- package/demo/src/content/pages/page-not-found.md +11 -0
- package/demo/src/content/pages/privacy-policy.md +24 -0
- package/demo/src/data/blocks.json +25 -0
- package/demo/src/data/booking.json +6 -0
- package/demo/src/data/categories/apps.json +6 -0
- package/demo/src/data/categories/design.json +6 -0
- package/demo/src/data/categories/editing.json +6 -0
- package/demo/src/data/categories/security.json +6 -0
- package/demo/src/data/categories/seo.json +6 -0
- package/demo/src/data/colors.json +75 -0
- package/demo/src/data/contact.json +8 -0
- package/demo/src/data/cookies.json +21 -0
- package/demo/src/data/footer.json +27 -0
- package/demo/src/data/menu.json +35 -0
- package/demo/src/data/mobile-menu.json +25 -0
- package/demo/src/data/popups/booking-bar.json +13 -0
- package/demo/src/data/popups/try-the-editor.json +16 -0
- package/demo/src/data/standard-pages.json +8 -0
- package/demo/src/data/testimonials/sample-bakery.json +10 -0
- package/demo/src/data/testimonials/sample-clinic.json +10 -0
- package/demo/src/data/testimonials/sample-studio.json +10 -0
- package/demo/src/site/colors.ts +11 -0
- package/demo/src/site/config.ts +19 -0
- package/icons/lucide/LICENSE +43 -0
- package/icons/lucide/LICENSE-material-design-icons +20 -0
- package/icons/lucide/address-book.svg +1 -0
- package/icons/lucide/app-window.svg +1 -0
- package/icons/lucide/arrow-counter-clockwise.svg +1 -0
- package/icons/lucide/arrow-down.svg +1 -0
- package/icons/lucide/arrow-left.svg +1 -0
- package/icons/lucide/arrow-right.svg +1 -0
- package/icons/lucide/arrow-square-out.svg +1 -0
- package/icons/lucide/arrow-u-up-left.svg +1 -0
- package/icons/lucide/arrow-u-up-right.svg +1 -0
- package/icons/lucide/arrow-up-right.svg +1 -0
- package/icons/lucide/arrow-up.svg +1 -0
- package/icons/lucide/arrows-down-up.svg +1 -0
- package/icons/lucide/arrows-in-line-horizontal.svg +1 -0
- package/icons/lucide/arrows-out-line-horizontal.svg +1 -0
- package/icons/lucide/article.svg +1 -0
- package/icons/lucide/bank.svg +1 -0
- package/icons/lucide/bell.svg +1 -0
- package/icons/lucide/bicycle.svg +1 -0
- package/icons/lucide/binoculars.svg +1 -0
- package/icons/lucide/book-open-text.svg +1 -0
- package/icons/lucide/book-open.svg +1 -0
- package/icons/lucide/browser.svg +1 -0
- package/icons/lucide/buildings.svg +1 -0
- package/icons/lucide/bus.svg +1 -0
- package/icons/lucide/calendar-blank.svg +1 -0
- package/icons/lucide/calendar-check.svg +1 -0
- package/icons/lucide/car.svg +1 -0
- package/icons/lucide/cards.svg +1 -0
- package/icons/lucide/caret-down.svg +1 -0
- package/icons/lucide/caret-left.svg +1 -0
- package/icons/lucide/caret-right.svg +1 -0
- package/icons/lucide/caret-up.svg +1 -0
- package/icons/lucide/certificate.svg +1 -0
- package/icons/lucide/chart-line-up.svg +1 -0
- package/icons/lucide/chats.svg +1 -0
- package/icons/lucide/check-circle.svg +1 -0
- package/icons/lucide/check.svg +1 -0
- package/icons/lucide/circle-half.svg +1 -0
- package/icons/lucide/circle.svg +1 -0
- package/icons/lucide/clock-counter-clockwise.svg +1 -0
- package/icons/lucide/clock.svg +1 -0
- package/icons/lucide/code.svg +1 -0
- package/icons/lucide/coffee.svg +1 -0
- package/icons/lucide/columns.svg +1 -0
- package/icons/lucide/cookie.svg +1 -0
- package/icons/lucide/copy.svg +1 -0
- package/icons/lucide/credit-card.svg +1 -0
- package/icons/lucide/currency-circle-dollar.svg +1 -0
- package/icons/lucide/cursor-click.svg +1 -0
- package/icons/lucide/database.svg +1 -0
- package/icons/lucide/desktop.svg +1 -0
- package/icons/lucide/device-mobile.svg +1 -0
- package/icons/lucide/door-open.svg +1 -0
- package/icons/lucide/download-simple.svg +1 -0
- package/icons/lucide/envelope-simple.svg +1 -0
- package/icons/lucide/eye-slash.svg +1 -0
- package/icons/lucide/eye.svg +1 -0
- package/icons/lucide/file-pdf.svg +1 -0
- package/icons/lucide/file-text.svg +1 -0
- package/icons/lucide/file-video.svg +1 -0
- package/icons/lucide/file-zip.svg +1 -0
- package/icons/lucide/flower-lotus.svg +1 -0
- package/icons/lucide/folder-simple.svg +1 -0
- package/icons/lucide/funnel.svg +1 -0
- package/icons/lucide/gauge.svg +1 -0
- package/icons/lucide/gear.svg +1 -0
- package/icons/lucide/github-logo.svg +1 -0
- package/icons/lucide/globe.svg +1 -0
- package/icons/lucide/google-logo.svg +1 -0
- package/icons/lucide/graduation-cap.svg +1 -0
- package/icons/lucide/hammer.svg +1 -0
- package/icons/lucide/hand-heart.svg +1 -0
- package/icons/lucide/handshake.svg +1 -0
- package/icons/lucide/hard-drives.svg +1 -0
- package/icons/lucide/heart.svg +1 -0
- package/icons/lucide/house.svg +1 -0
- package/icons/lucide/image-square.svg +1 -0
- package/icons/lucide/image.svg +1 -0
- package/icons/lucide/info.svg +1 -0
- package/icons/lucide/keyboard.svg +1 -0
- package/icons/lucide/leaf.svg +1 -0
- package/icons/lucide/lifebuoy.svg +1 -0
- package/icons/lucide/lightbulb.svg +1 -0
- package/icons/lucide/link-break.svg +1 -0
- package/icons/lucide/link-simple.svg +1 -0
- package/icons/lucide/list-bullets.svg +1 -0
- package/icons/lucide/list-checks.svg +1 -0
- package/icons/lucide/list-numbers.svg +1 -0
- package/icons/lucide/list.svg +1 -0
- package/icons/lucide/lock-simple-open.svg +1 -0
- package/icons/lucide/lock-simple.svg +1 -0
- package/icons/lucide/magnifying-glass.svg +1 -0
- package/icons/lucide/map-pin.svg +1 -0
- package/icons/lucide/map-trifold.svg +1 -0
- package/icons/lucide/medal.svg +1 -0
- package/icons/lucide/megaphone.svg +1 -0
- package/icons/lucide/minus.svg +1 -0
- package/icons/lucide/moon.svg +1 -0
- package/icons/lucide/newspaper.svg +1 -0
- package/icons/lucide/pack.json +23 -0
- package/icons/lucide/paint-brush-broad.svg +1 -0
- package/icons/lucide/palette.svg +1 -0
- package/icons/lucide/paper-plane-tilt.svg +1 -0
- package/icons/lucide/pencil-simple.svg +1 -0
- package/icons/lucide/phone.svg +1 -0
- package/icons/lucide/play-fill.svg +1 -0
- package/icons/lucide/plus.svg +1 -0
- package/icons/lucide/prohibit.svg +1 -0
- package/icons/lucide/puzzle-piece.svg +1 -0
- package/icons/lucide/question.svg +1 -0
- package/icons/lucide/quotes.svg +1 -0
- package/icons/lucide/rows.svg +1 -0
- package/icons/lucide/ruler.svg +1 -0
- package/icons/lucide/scan.svg +1 -0
- package/icons/lucide/shapes.svg +1 -0
- package/icons/lucide/share-network.svg +1 -0
- package/icons/lucide/shield-check.svg +1 -0
- package/icons/lucide/sidebar-simple.svg +1 -0
- package/icons/lucide/sign-out.svg +1 -0
- package/icons/lucide/signpost.svg +1 -0
- package/icons/lucide/sliders-horizontal.svg +1 -0
- package/icons/lucide/smiley.svg +1 -0
- package/icons/lucide/sparkle.svg +1 -0
- package/icons/lucide/square-half-bottom.svg +1 -0
- package/icons/lucide/square.svg +1 -0
- package/icons/lucide/squares-four.svg +1 -0
- package/icons/lucide/sticker.svg +1 -0
- package/icons/lucide/storefront.svg +1 -0
- package/icons/lucide/sun.svg +1 -0
- package/icons/lucide/swatches.svg +1 -0
- package/icons/lucide/tag.svg +1 -0
- package/icons/lucide/text-aa.svg +1 -0
- package/icons/lucide/text-align-left.svg +1 -0
- package/icons/lucide/text-b.svg +1 -0
- package/icons/lucide/text-h-one.svg +1 -0
- package/icons/lucide/text-h-three.svg +1 -0
- package/icons/lucide/text-h-two.svg +1 -0
- package/icons/lucide/text-italic.svg +1 -0
- package/icons/lucide/text-t.svg +1 -0
- package/icons/lucide/ticket.svg +1 -0
- package/icons/lucide/toggle-right.svg +1 -0
- package/icons/lucide/train.svg +1 -0
- package/icons/lucide/trash.svg +1 -0
- package/icons/lucide/upload-simple.svg +1 -0
- package/icons/lucide/user-circle.svg +1 -0
- package/icons/lucide/user.svg +1 -0
- package/icons/lucide/users-three.svg +1 -0
- package/icons/lucide/users.svg +1 -0
- package/icons/lucide/video-camera.svg +1 -0
- package/icons/lucide/warning-circle.svg +1 -0
- package/icons/lucide/warning.svg +1 -0
- package/icons/lucide/wave-sine.svg +1 -0
- package/icons/lucide/wheelchair.svg +1 -0
- package/icons/lucide/wrench.svg +1 -0
- package/icons/lucide/x.svg +1 -0
- package/icons/material-symbols/LICENSE +201 -0
- package/icons/material-symbols/LICENSE-material-design-icons +20 -0
- package/icons/material-symbols/address-book.svg +1 -0
- package/icons/material-symbols/app-window.svg +1 -0
- package/icons/material-symbols/arrow-counter-clockwise.svg +1 -0
- package/icons/material-symbols/arrow-down.svg +1 -0
- package/icons/material-symbols/arrow-left.svg +1 -0
- package/icons/material-symbols/arrow-right.svg +1 -0
- package/icons/material-symbols/arrow-square-out.svg +1 -0
- package/icons/material-symbols/arrow-u-up-left.svg +1 -0
- package/icons/material-symbols/arrow-u-up-right.svg +1 -0
- package/icons/material-symbols/arrow-up-right.svg +1 -0
- package/icons/material-symbols/arrow-up.svg +1 -0
- package/icons/material-symbols/arrows-down-up.svg +1 -0
- package/icons/material-symbols/arrows-in-line-horizontal.svg +1 -0
- package/icons/material-symbols/arrows-out-line-horizontal.svg +1 -0
- package/icons/material-symbols/article.svg +1 -0
- package/icons/material-symbols/bank.svg +1 -0
- package/icons/material-symbols/bell.svg +1 -0
- package/icons/material-symbols/bicycle.svg +1 -0
- package/icons/material-symbols/binoculars.svg +1 -0
- package/icons/material-symbols/book-open-text.svg +1 -0
- package/icons/material-symbols/book-open.svg +1 -0
- package/icons/material-symbols/browser.svg +1 -0
- package/icons/material-symbols/buildings.svg +1 -0
- package/icons/material-symbols/bus.svg +1 -0
- package/icons/material-symbols/calendar-blank.svg +1 -0
- package/icons/material-symbols/calendar-check.svg +1 -0
- package/icons/material-symbols/car.svg +1 -0
- package/icons/material-symbols/cards.svg +1 -0
- package/icons/material-symbols/caret-down.svg +1 -0
- package/icons/material-symbols/caret-left.svg +1 -0
- package/icons/material-symbols/caret-right.svg +1 -0
- package/icons/material-symbols/caret-up.svg +1 -0
- package/icons/material-symbols/certificate.svg +1 -0
- package/icons/material-symbols/chart-line-up.svg +1 -0
- package/icons/material-symbols/chats.svg +1 -0
- package/icons/material-symbols/check-circle.svg +1 -0
- package/icons/material-symbols/check.svg +1 -0
- package/icons/material-symbols/circle-half.svg +1 -0
- package/icons/material-symbols/circle.svg +1 -0
- package/icons/material-symbols/clock-counter-clockwise.svg +1 -0
- package/icons/material-symbols/clock.svg +1 -0
- package/icons/material-symbols/code.svg +1 -0
- package/icons/material-symbols/coffee.svg +1 -0
- package/icons/material-symbols/columns.svg +1 -0
- package/icons/material-symbols/cookie.svg +1 -0
- package/icons/material-symbols/copy.svg +1 -0
- package/icons/material-symbols/credit-card.svg +1 -0
- package/icons/material-symbols/currency-circle-dollar.svg +1 -0
- package/icons/material-symbols/cursor-click.svg +1 -0
- package/icons/material-symbols/database.svg +1 -0
- package/icons/material-symbols/desktop.svg +1 -0
- package/icons/material-symbols/device-mobile.svg +1 -0
- package/icons/material-symbols/door-open.svg +1 -0
- package/icons/material-symbols/download-simple.svg +1 -0
- package/icons/material-symbols/envelope-simple.svg +1 -0
- package/icons/material-symbols/eye-slash.svg +1 -0
- package/icons/material-symbols/eye.svg +1 -0
- package/icons/material-symbols/file-pdf.svg +1 -0
- package/icons/material-symbols/file-text.svg +1 -0
- package/icons/material-symbols/file-video.svg +1 -0
- package/icons/material-symbols/file-zip.svg +1 -0
- package/icons/material-symbols/flower-lotus.svg +1 -0
- package/icons/material-symbols/folder-simple.svg +1 -0
- package/icons/material-symbols/funnel.svg +1 -0
- package/icons/material-symbols/gauge.svg +1 -0
- package/icons/material-symbols/gear.svg +1 -0
- package/icons/material-symbols/github-logo.svg +1 -0
- package/icons/material-symbols/globe.svg +1 -0
- package/icons/material-symbols/google-logo.svg +1 -0
- package/icons/material-symbols/graduation-cap.svg +1 -0
- package/icons/material-symbols/hammer.svg +1 -0
- package/icons/material-symbols/hand-heart.svg +1 -0
- package/icons/material-symbols/handshake.svg +1 -0
- package/icons/material-symbols/hard-drives.svg +1 -0
- package/icons/material-symbols/heart.svg +1 -0
- package/icons/material-symbols/house.svg +1 -0
- package/icons/material-symbols/image-square.svg +1 -0
- package/icons/material-symbols/image.svg +1 -0
- package/icons/material-symbols/info.svg +1 -0
- package/icons/material-symbols/keyboard.svg +1 -0
- package/icons/material-symbols/leaf.svg +1 -0
- package/icons/material-symbols/lifebuoy.svg +1 -0
- package/icons/material-symbols/lightbulb.svg +1 -0
- package/icons/material-symbols/link-break.svg +1 -0
- package/icons/material-symbols/link-simple.svg +1 -0
- package/icons/material-symbols/list-bullets.svg +1 -0
- package/icons/material-symbols/list-checks.svg +1 -0
- package/icons/material-symbols/list-numbers.svg +1 -0
- package/icons/material-symbols/list.svg +1 -0
- package/icons/material-symbols/lock-simple-open.svg +1 -0
- package/icons/material-symbols/lock-simple.svg +1 -0
- package/icons/material-symbols/magnifying-glass.svg +1 -0
- package/icons/material-symbols/map-pin.svg +1 -0
- package/icons/material-symbols/map-trifold.svg +1 -0
- package/icons/material-symbols/medal.svg +1 -0
- package/icons/material-symbols/megaphone.svg +1 -0
- package/icons/material-symbols/minus.svg +1 -0
- package/icons/material-symbols/moon.svg +1 -0
- package/icons/material-symbols/newspaper.svg +1 -0
- package/icons/material-symbols/pack.json +29 -0
- package/icons/material-symbols/paint-brush-broad.svg +1 -0
- package/icons/material-symbols/palette.svg +1 -0
- package/icons/material-symbols/paper-plane-tilt.svg +1 -0
- package/icons/material-symbols/pencil-simple.svg +1 -0
- package/icons/material-symbols/phone.svg +1 -0
- package/icons/material-symbols/play-fill.svg +1 -0
- package/icons/material-symbols/plus.svg +1 -0
- package/icons/material-symbols/prohibit.svg +1 -0
- package/icons/material-symbols/puzzle-piece.svg +1 -0
- package/icons/material-symbols/question.svg +1 -0
- package/icons/material-symbols/quotes.svg +1 -0
- package/icons/material-symbols/rows.svg +1 -0
- package/icons/material-symbols/ruler.svg +1 -0
- package/icons/material-symbols/scan.svg +1 -0
- package/icons/material-symbols/shapes.svg +1 -0
- package/icons/material-symbols/share-network.svg +1 -0
- package/icons/material-symbols/shield-check.svg +1 -0
- package/icons/material-symbols/sidebar-simple.svg +1 -0
- package/icons/material-symbols/sign-out.svg +1 -0
- package/icons/material-symbols/signpost.svg +1 -0
- package/icons/material-symbols/sliders-horizontal.svg +1 -0
- package/icons/material-symbols/smiley.svg +1 -0
- package/icons/material-symbols/sparkle.svg +1 -0
- package/icons/material-symbols/square-half-bottom.svg +1 -0
- package/icons/material-symbols/square.svg +1 -0
- package/icons/material-symbols/squares-four.svg +1 -0
- package/icons/material-symbols/sticker.svg +1 -0
- package/icons/material-symbols/storefront.svg +1 -0
- package/icons/material-symbols/sun.svg +1 -0
- package/icons/material-symbols/swatches.svg +1 -0
- package/icons/material-symbols/tag.svg +1 -0
- package/icons/material-symbols/text-aa.svg +1 -0
- package/icons/material-symbols/text-align-left.svg +1 -0
- package/icons/material-symbols/text-b.svg +1 -0
- package/icons/material-symbols/text-h-one.svg +1 -0
- package/icons/material-symbols/text-h-three.svg +1 -0
- package/icons/material-symbols/text-h-two.svg +1 -0
- package/icons/material-symbols/text-italic.svg +1 -0
- package/icons/material-symbols/text-t.svg +1 -0
- package/icons/material-symbols/ticket.svg +1 -0
- package/icons/material-symbols/toggle-right.svg +1 -0
- package/icons/material-symbols/train.svg +1 -0
- package/icons/material-symbols/trash.svg +1 -0
- package/icons/material-symbols/upload-simple.svg +1 -0
- package/icons/material-symbols/user-circle.svg +1 -0
- package/icons/material-symbols/user.svg +1 -0
- package/icons/material-symbols/users-three.svg +1 -0
- package/icons/material-symbols/users.svg +1 -0
- package/icons/material-symbols/video-camera.svg +1 -0
- package/icons/material-symbols/warning-circle.svg +1 -0
- package/icons/material-symbols/warning.svg +1 -0
- package/icons/material-symbols/wave-sine.svg +1 -0
- package/icons/material-symbols/wheelchair.svg +1 -0
- package/icons/material-symbols/wrench.svg +1 -0
- package/icons/material-symbols/x.svg +1 -0
- package/icons/phosphor/LICENSE +21 -0
- package/icons/phosphor/address-book.svg +1 -0
- package/icons/phosphor/app-window.svg +1 -0
- package/icons/phosphor/arrow-counter-clockwise.svg +1 -0
- package/icons/phosphor/arrow-down.svg +1 -0
- package/icons/phosphor/arrow-left.svg +1 -0
- package/icons/phosphor/arrow-right.svg +1 -0
- package/icons/phosphor/arrow-square-out.svg +1 -0
- package/icons/phosphor/arrow-u-up-left.svg +1 -0
- package/icons/phosphor/arrow-u-up-right.svg +1 -0
- package/icons/phosphor/arrow-up-right.svg +1 -0
- package/icons/phosphor/arrow-up.svg +1 -0
- package/icons/phosphor/arrows-down-up.svg +1 -0
- package/icons/phosphor/arrows-in-line-horizontal.svg +1 -0
- package/icons/phosphor/arrows-out-line-horizontal.svg +1 -0
- package/icons/phosphor/article.svg +1 -0
- package/icons/phosphor/bank.svg +1 -0
- package/icons/phosphor/bell.svg +1 -0
- package/icons/phosphor/bicycle.svg +1 -0
- package/icons/phosphor/binoculars.svg +1 -0
- package/icons/phosphor/book-open-text.svg +1 -0
- package/icons/phosphor/book-open.svg +1 -0
- package/icons/phosphor/browser.svg +1 -0
- package/icons/phosphor/buildings.svg +1 -0
- package/icons/phosphor/bus.svg +1 -0
- package/icons/phosphor/calendar-blank.svg +1 -0
- package/icons/phosphor/calendar-check.svg +1 -0
- package/icons/phosphor/car.svg +1 -0
- package/icons/phosphor/cards.svg +1 -0
- package/icons/phosphor/caret-down.svg +1 -0
- package/icons/phosphor/caret-left.svg +1 -0
- package/icons/phosphor/caret-right.svg +1 -0
- package/icons/phosphor/caret-up.svg +1 -0
- package/icons/phosphor/certificate.svg +1 -0
- package/icons/phosphor/chart-line-up.svg +1 -0
- package/icons/phosphor/chats.svg +1 -0
- package/icons/phosphor/check-circle.svg +1 -0
- package/icons/phosphor/check.svg +1 -0
- package/icons/phosphor/circle-half.svg +1 -0
- package/icons/phosphor/circle.svg +1 -0
- package/icons/phosphor/clock-counter-clockwise.svg +1 -0
- package/icons/phosphor/clock.svg +1 -0
- package/icons/phosphor/code.svg +1 -0
- package/icons/phosphor/coffee.svg +1 -0
- package/icons/phosphor/columns.svg +1 -0
- package/icons/phosphor/cookie.svg +1 -0
- package/icons/phosphor/copy.svg +1 -0
- package/icons/phosphor/credit-card.svg +1 -0
- package/icons/phosphor/currency-circle-dollar.svg +1 -0
- package/icons/phosphor/cursor-click.svg +1 -0
- package/icons/phosphor/database.svg +1 -0
- package/icons/phosphor/desktop.svg +1 -0
- package/icons/phosphor/device-mobile.svg +1 -0
- package/icons/phosphor/door-open.svg +1 -0
- package/icons/phosphor/download-simple.svg +1 -0
- package/icons/phosphor/envelope-simple.svg +1 -0
- package/icons/phosphor/eye-slash.svg +1 -0
- package/icons/phosphor/eye.svg +1 -0
- package/icons/phosphor/file-pdf.svg +1 -0
- package/icons/phosphor/file-text.svg +1 -0
- package/icons/phosphor/file-video.svg +1 -0
- package/icons/phosphor/file-zip.svg +1 -0
- package/icons/phosphor/flower-lotus.svg +1 -0
- package/icons/phosphor/folder-simple.svg +1 -0
- package/icons/phosphor/funnel.svg +1 -0
- package/icons/phosphor/gauge.svg +1 -0
- package/icons/phosphor/gear.svg +1 -0
- package/icons/phosphor/github-logo.svg +1 -0
- package/icons/phosphor/globe.svg +1 -0
- package/icons/phosphor/google-logo.svg +1 -0
- package/icons/phosphor/graduation-cap.svg +1 -0
- package/icons/phosphor/hammer.svg +1 -0
- package/icons/phosphor/hand-heart.svg +1 -0
- package/icons/phosphor/handshake.svg +1 -0
- package/icons/phosphor/hard-drives.svg +1 -0
- package/icons/phosphor/heart.svg +1 -0
- package/icons/phosphor/house.svg +1 -0
- package/icons/phosphor/image-square.svg +1 -0
- package/icons/phosphor/image.svg +1 -0
- package/icons/phosphor/info.svg +1 -0
- package/icons/phosphor/keyboard.svg +1 -0
- package/icons/phosphor/leaf.svg +1 -0
- package/icons/phosphor/lifebuoy.svg +1 -0
- package/icons/phosphor/lightbulb.svg +1 -0
- package/icons/phosphor/link-break.svg +1 -0
- package/icons/phosphor/link-simple.svg +1 -0
- package/icons/phosphor/list-bullets.svg +1 -0
- package/icons/phosphor/list-checks.svg +1 -0
- package/icons/phosphor/list-numbers.svg +1 -0
- package/icons/phosphor/list.svg +1 -0
- package/icons/phosphor/lock-simple-open.svg +1 -0
- package/icons/phosphor/lock-simple.svg +1 -0
- package/icons/phosphor/magnifying-glass.svg +1 -0
- package/icons/phosphor/map-pin.svg +1 -0
- package/icons/phosphor/map-trifold.svg +1 -0
- package/icons/phosphor/medal.svg +1 -0
- package/icons/phosphor/megaphone.svg +1 -0
- package/icons/phosphor/minus.svg +1 -0
- package/icons/phosphor/moon.svg +1 -0
- package/icons/phosphor/newspaper.svg +1 -0
- package/icons/phosphor/pack.json +8 -0
- package/icons/phosphor/paint-brush-broad.svg +1 -0
- package/icons/phosphor/palette.svg +1 -0
- package/icons/phosphor/paper-plane-tilt.svg +1 -0
- package/icons/phosphor/pencil-simple.svg +1 -0
- package/icons/phosphor/phone.svg +1 -0
- package/icons/phosphor/play-fill.svg +1 -0
- package/icons/phosphor/plus.svg +1 -0
- package/icons/phosphor/prohibit.svg +1 -0
- package/icons/phosphor/puzzle-piece.svg +1 -0
- package/icons/phosphor/question.svg +1 -0
- package/icons/phosphor/quotes.svg +1 -0
- package/icons/phosphor/rows.svg +1 -0
- package/icons/phosphor/ruler.svg +1 -0
- package/icons/phosphor/scan.svg +1 -0
- package/icons/phosphor/shapes.svg +1 -0
- package/icons/phosphor/share-network.svg +1 -0
- package/icons/phosphor/shield-check.svg +1 -0
- package/icons/phosphor/sidebar-simple.svg +1 -0
- package/icons/phosphor/sign-out.svg +1 -0
- package/icons/phosphor/signpost.svg +1 -0
- package/icons/phosphor/sliders-horizontal.svg +1 -0
- package/icons/phosphor/smiley.svg +1 -0
- package/icons/phosphor/sparkle.svg +1 -0
- package/icons/phosphor/square-half-bottom.svg +1 -0
- package/icons/phosphor/square.svg +1 -0
- package/icons/phosphor/squares-four.svg +1 -0
- package/icons/phosphor/sticker.svg +1 -0
- package/icons/phosphor/storefront.svg +1 -0
- package/icons/phosphor/sun.svg +1 -0
- package/icons/phosphor/swatches.svg +1 -0
- package/icons/phosphor/tag.svg +1 -0
- package/icons/phosphor/text-aa.svg +1 -0
- package/icons/phosphor/text-align-left.svg +1 -0
- package/icons/phosphor/text-b.svg +1 -0
- package/icons/phosphor/text-h-one.svg +1 -0
- package/icons/phosphor/text-h-three.svg +1 -0
- package/icons/phosphor/text-h-two.svg +1 -0
- package/icons/phosphor/text-italic.svg +1 -0
- package/icons/phosphor/text-t.svg +1 -0
- package/icons/phosphor/ticket.svg +1 -0
- package/icons/phosphor/toggle-right.svg +1 -0
- package/icons/phosphor/train.svg +1 -0
- package/icons/phosphor/trash.svg +1 -0
- package/icons/phosphor/upload-simple.svg +1 -0
- package/icons/phosphor/user-circle.svg +1 -0
- package/icons/phosphor/user.svg +1 -0
- package/icons/phosphor/users-three.svg +1 -0
- package/icons/phosphor/users.svg +1 -0
- package/icons/phosphor/video-camera.svg +1 -0
- package/icons/phosphor/warning-circle.svg +1 -0
- package/icons/phosphor/warning.svg +1 -0
- package/icons/phosphor/wave-sine.svg +1 -0
- package/icons/phosphor/wheelchair.svg +1 -0
- package/icons/phosphor/wrench.svg +1 -0
- package/icons/phosphor/x.svg +1 -0
- package/lib/apps.d.mts +28 -0
- package/lib/apps.mjs +139 -0
- package/lib/blocks.d.mts +23 -0
- package/lib/blocks.mjs +90 -0
- package/lib/colors.ts +86 -0
- package/lib/contactBar.ts +18 -0
- package/lib/cookieCategories.d.mts +17 -0
- package/lib/cookieCategories.mjs +28 -0
- package/lib/crop.d.mts +34 -0
- package/lib/crop.mjs +83 -0
- package/lib/csp.d.mts +22 -0
- package/lib/csp.mjs +130 -0
- package/lib/cspSources.d.mts +24 -0
- package/lib/cspSources.mjs +60 -0
- package/lib/dynamic-colors.ts +426 -0
- package/lib/git.d.mts +24 -0
- package/lib/git.mjs +64 -0
- package/lib/hooks.ts +51 -0
- package/lib/inline.ts +20 -0
- package/lib/license-texts/Apache-2.0.txt +191 -0
- package/lib/license-texts/BSD-2-Clause.txt +24 -0
- package/lib/license-texts/BSD-3-Clause.txt +28 -0
- package/lib/license-texts/ISC.txt +15 -0
- package/lib/license-texts/MIT.txt +21 -0
- package/lib/licenses.d.mts +190 -0
- package/lib/licenses.mjs +683 -0
- package/lib/markdown.ts +42 -0
- package/lib/motion-schemes.d.mts +2 -0
- package/lib/motion-schemes.mjs +5 -0
- package/lib/motion.ts +131 -0
- package/lib/notice.d.mts +3 -0
- package/lib/notice.mjs +34 -0
- package/lib/scheduled.d.mts +15 -0
- package/lib/scheduled.mjs +37 -0
- package/lib/snackbar.ts +149 -0
- package/lib/status.d.mts +7 -0
- package/lib/status.mjs +18 -0
- package/lib/svg.d.mts +22 -0
- package/lib/svg.mjs +231 -0
- package/lib/text-colors.d.mts +11 -0
- package/lib/text-colors.mjs +43 -0
- package/lib/video-id.d.mts +14 -0
- package/lib/video-id.mjs +72 -0
- package/lib/video.d.mts +20 -0
- package/lib/video.mjs +91 -0
- package/package.json +131 -6
- package/pages/404.astro +10 -0
- package/pages/[...slug].astro +51 -0
- package/pages/_headers.txt +31 -0
- package/pages/blog/index.astro +10 -0
- package/pages/blog/kategori/[category].astro +18 -0
- package/pages/editor/code-images.json.js +25 -0
- package/pages/editor/index.astro +75 -0
- package/pages/editor/manifest.webmanifest.js +23 -0
- package/pages/editor/sw.js +33 -0
- package/pages/editor/sw.js.js +4 -0
- package/pages/editor/thumbnails.json.js +21 -0
- package/pages/editor/version.json.js +22 -0
- package/pages/headers.js +4 -0
- package/pages/index.astro +10 -0
- package/pages/ny.astro +6 -0
- package/pages/robots.txt.js +3 -0
- package/pages/rss.xml.js +20 -0
- package/scripts/app-screenshots.mjs +164 -0
- package/scripts/app-workers.mjs +6 -0
- package/scripts/bin.mjs +12 -0
- package/scripts/built-site.mjs +99 -0
- package/scripts/check-consent.mjs +113 -0
- package/scripts/check-content.mjs +149 -0
- package/scripts/check-demo.mjs +24 -0
- package/scripts/check-themes.mjs +45 -0
- package/scripts/check-worker.mjs +569 -0
- package/scripts/compare-html.mjs +81 -0
- package/scripts/demo-site.mjs +42 -0
- package/scripts/editor-icons.mjs +56 -0
- package/scripts/editor-roundtrip.mjs +134 -0
- package/scripts/editor-screens.mjs +101 -0
- package/scripts/git-env.mjs +9 -0
- package/scripts/icon-packs.mjs +151 -0
- package/scripts/link-counts.mjs +22 -0
- package/scripts/page-colors.mjs +42 -0
- package/scripts/releases.d.mts +10 -0
- package/scripts/releases.mjs +80 -0
- package/scripts/responsive-images.mjs +94 -0
- package/scripts/scheduled-list.mjs +15 -0
- package/scripts/theme-screenshots.mjs +88 -0
- package/scripts/types.mjs +21 -0
- package/scripts/video-thumbnails.mjs +89 -0
- package/scripts/worker-modules.mjs +34 -0
- package/site/appCookies.d.mts +9 -0
- package/site/appCookies.mjs +74 -0
- package/site/apps.ts +21 -0
- package/site/autolinks.d.mts +11 -0
- package/site/autolinks.mjs +200 -0
- package/site/blockScripts.ts +31 -0
- package/site/categories.ts +16 -0
- package/site/consent.ts +26 -0
- package/site/content.config.ts +84 -0
- package/site/content.ts +104 -0
- package/site/cookieList.ts +17 -0
- package/site/defineSite.d.mts +142 -0
- package/site/defineSite.mjs +136 -0
- package/site/directives/interact.d.mts +2 -0
- package/site/directives/interact.mjs +31 -0
- package/site/editor-version.d.mts +1 -0
- package/site/editor-version.mjs +26 -0
- package/site/fill.ts +13 -0
- package/site/format.ts +11 -0
- package/site/home.ts +66 -0
- package/site/iconPacks.d.mts +20 -0
- package/site/iconPacks.mjs +43 -0
- package/site/icons.d.mts +693 -0
- package/site/icons.mjs +605 -0
- package/site/images.d.mts +43 -0
- package/site/images.mjs +157 -0
- package/site/motion.ts +13 -0
- package/site/noindex.d.mts +6 -0
- package/site/noindex.mjs +21 -0
- package/site/pageColors.ts +110 -0
- package/site/popups.ts +98 -0
- package/site/schema.ts +189 -0
- package/site/sections.ts +3 -0
- package/site/seo.ts +28 -0
- package/site/site.ts +76 -0
- package/site/siteConfig.d.mts +1 -0
- package/site/siteConfig.mjs +8 -0
- package/site/siteCsp.d.mts +10 -0
- package/site/siteCsp.mjs +75 -0
- package/site/siteModules.d.mts +7 -0
- package/site/siteModules.mjs +27 -0
- package/site/standardPages.ts +59 -0
- package/site/testimonials.ts +48 -0
- package/site/text.ts +43 -0
- package/site/theme.d.mts +83 -0
- package/site/theme.mjs +472 -0
- package/site/tracking.client.ts +225 -0
- package/site/tracking.ts +9 -0
- package/src/ActionParts.tsx +205 -0
- package/src/Advanced.tsx +152 -0
- package/src/App.tsx +904 -0
- package/src/AppList.tsx +1345 -0
- package/src/BlockDialog.tsx +360 -0
- package/src/BlockParts.tsx +652 -0
- package/src/BlockSettings.tsx +533 -0
- package/src/BrandForm.tsx +164 -0
- package/src/Colors.tsx +476 -0
- package/src/CommunicationParts.tsx +199 -0
- package/src/CompanyForm.tsx +209 -0
- package/src/Consents.tsx +175 -0
- package/src/ContainmentParts.tsx +185 -0
- package/src/Crop.tsx +152 -0
- package/src/DataForm.tsx +434 -0
- package/src/Deleted.tsx +177 -0
- package/src/EntryForm.tsx +740 -0
- package/src/FileView.tsx +30 -0
- package/src/FormFrame.tsx +237 -0
- package/src/Keywords.tsx +225 -0
- package/src/Library.tsx +1563 -0
- package/src/Licenses.tsx +336 -0
- package/src/LinkSheet.tsx +138 -0
- package/src/MarkdownEditor.tsx +1075 -0
- package/src/Media.tsx +677 -0
- package/src/NavigationParts.tsx +350 -0
- package/src/NavigationRestParts.tsx +247 -0
- package/src/Notifications.tsx +59 -0
- package/src/PagePicker.tsx +136 -0
- package/src/Parts.tsx +991 -0
- package/src/PartsShown.tsx +168 -0
- package/src/PickerParts.tsx +183 -0
- package/src/Redirects.tsx +450 -0
- package/src/Screen.tsx +184 -0
- package/src/SectionsField.tsx +65 -0
- package/src/SelectionParts.tsx +134 -0
- package/src/SeoScores.tsx +184 -0
- package/src/Sheet.tsx +35 -0
- package/src/ThemeStore.tsx +376 -0
- package/src/Tokens.tsx +346 -0
- package/src/Versions.tsx +214 -0
- package/src/addresses.ts +75 -0
- package/src/allIcons.ts +7 -0
- package/src/appFiles.ts +29 -0
- package/src/apps.ts +281 -0
- package/src/ask.tsx +123 -0
- package/src/blocks.ts +251 -0
- package/src/brand.ts +153 -0
- package/src/cache.ts +42 -0
- package/src/check.ts +285 -0
- package/src/checkSite.ts +256 -0
- package/src/consents.ts +26 -0
- package/src/cookieList.ts +70 -0
- package/src/countries.ts +59 -0
- package/src/deploy.ts +155 -0
- package/src/editor.css +602 -0
- package/src/examples.ts +85 -0
- package/src/fields.tsx +942 -0
- package/src/frontmatter.d.mts +6 -0
- package/src/frontmatter.mjs +42 -0
- package/src/github.ts +376 -0
- package/src/i18n/da-DK/advanced.ts +28 -0
- package/src/i18n/da-DK/app.ts +71 -0
- package/src/i18n/da-DK/apps.ts +90 -0
- package/src/i18n/da-DK/blockSettings.ts +38 -0
- package/src/i18n/da-DK/blocks.ts +408 -0
- package/src/i18n/da-DK/check.ts +25 -0
- package/src/i18n/da-DK/colors.ts +64 -0
- package/src/i18n/da-DK/common.ts +118 -0
- package/src/i18n/da-DK/company.ts +24 -0
- package/src/i18n/da-DK/consents.ts +23 -0
- package/src/i18n/da-DK/forms.ts +116 -0
- package/src/i18n/da-DK/history.ts +35 -0
- package/src/i18n/da-DK/index.ts +49 -0
- package/src/i18n/da-DK/keywords.ts +19 -0
- package/src/i18n/da-DK/library.ts +135 -0
- package/src/i18n/da-DK/licenses.ts +25 -0
- package/src/i18n/da-DK/media.ts +79 -0
- package/src/i18n/da-DK/parts.ts +696 -0
- package/src/i18n/da-DK/preview.ts +13 -0
- package/src/i18n/da-DK/redirects.ts +51 -0
- package/src/i18n/da-DK/seo.ts +20 -0
- package/src/i18n/da-DK/text.ts +35 -0
- package/src/i18n/da-DK/theme.ts +41 -0
- package/src/i18n/en-US/advanced.ts +32 -0
- package/src/i18n/en-US/app.ts +84 -0
- package/src/i18n/en-US/apps.ts +134 -0
- package/src/i18n/en-US/blockSettings.ts +48 -0
- package/src/i18n/en-US/blocks.ts +441 -0
- package/src/i18n/en-US/check.ts +31 -0
- package/src/i18n/en-US/colors.ts +82 -0
- package/src/i18n/en-US/common.ts +144 -0
- package/src/i18n/en-US/company.ts +25 -0
- package/src/i18n/en-US/consents.ts +25 -0
- package/src/i18n/en-US/forms.ts +145 -0
- package/src/i18n/en-US/history.ts +43 -0
- package/src/i18n/en-US/index.ts +51 -0
- package/src/i18n/en-US/keywords.ts +24 -0
- package/src/i18n/en-US/library.ts +176 -0
- package/src/i18n/en-US/licenses.ts +36 -0
- package/src/i18n/en-US/media.ts +80 -0
- package/src/i18n/en-US/parts.ts +718 -0
- package/src/i18n/en-US/preview.ts +15 -0
- package/src/i18n/en-US/redirects.ts +66 -0
- package/src/i18n/en-US/seo.ts +26 -0
- package/src/i18n/en-US/text.ts +41 -0
- package/src/i18n/en-US/theme.ts +41 -0
- package/src/i18n/index.ts +124 -0
- package/src/icon.tsx +160 -0
- package/src/iconPacks.ts +89 -0
- package/src/images.ts +163 -0
- package/src/licenses.ts +79 -0
- package/src/markdown.d.mts +12 -0
- package/src/markdown.mjs +204 -0
- package/src/nav.ts +68 -0
- package/src/notFound.ts +28 -0
- package/src/notifications.ts +223 -0
- package/src/pagePreview.tsx +204 -0
- package/src/r2Caching.ts +55 -0
- package/src/redirects.ts +149 -0
- package/src/registry.tsx +188 -0
- package/src/schema.ts +417 -0
- package/src/sections.d.mts +45 -0
- package/src/sections.mjs +303 -0
- package/src/seo.ts +333 -0
- package/src/shared.ts +44 -0
- package/src/sidebar.ts +31 -0
- package/src/site.ts +317 -0
- package/src/standard/Block.astro +19 -0
- package/src/standard/BlockSite.astro +18 -0
- package/src/standard/accordion/index.tsx +47 -0
- package/src/standard/accordion/load.ts +23 -0
- package/src/standard/accordion/shared.ts +15 -0
- package/src/standard/accordion/view.ts +32 -0
- package/src/standard/buttons/fields.ts +98 -0
- package/src/standard/buttons/index.tsx +23 -0
- package/src/standard/buttons/load.ts +34 -0
- package/src/standard/buttons/shared.ts +12 -0
- package/src/standard/buttons/view.ts +30 -0
- package/src/standard/cards/index.tsx +71 -0
- package/src/standard/cards/load.ts +17 -0
- package/src/standard/cards/shared.ts +27 -0
- package/src/standard/cards/view.ts +29 -0
- package/src/standard/checklist/index.tsx +27 -0
- package/src/standard/checklist/load.ts +5 -0
- package/src/standard/checklist/view.ts +13 -0
- package/src/standard/cookies/index.tsx +17 -0
- package/src/standard/cookies/list.ts +56 -0
- package/src/standard/cookies/load.ts +11 -0
- package/src/standard/cookies/shared.ts +20 -0
- package/src/standard/cookies/view.ts +28 -0
- package/src/standard/faq/index.tsx +29 -0
- package/src/standard/faq/load.ts +14 -0
- package/src/standard/faq/view.ts +21 -0
- package/src/standard/head.ts +23 -0
- package/src/standard/hero/fields.ts +48 -0
- package/src/standard/hero/index.tsx +57 -0
- package/src/standard/hero/load.ts +23 -0
- package/src/standard/hero/view.ts +38 -0
- package/src/standard/links/index.tsx +41 -0
- package/src/standard/links/load.ts +17 -0
- package/src/standard/links/view.ts +25 -0
- package/src/standard/list/index.tsx +50 -0
- package/src/standard/list/load.ts +5 -0
- package/src/standard/list/view.ts +18 -0
- package/src/standard/load.ts +7 -0
- package/src/standard/notice/index.tsx +30 -0
- package/src/standard/notice/load.ts +16 -0
- package/src/standard/notice/view.ts +10 -0
- package/src/standard/points/index.tsx +42 -0
- package/src/standard/points/load.ts +5 -0
- package/src/standard/points/view.ts +12 -0
- package/src/standard/posts/index.tsx +132 -0
- package/src/standard/posts/load.ts +36 -0
- package/src/standard/posts/shared.ts +21 -0
- package/src/standard/posts/view.ts +63 -0
- package/src/standard/pricecards/index.tsx +57 -0
- package/src/standard/pricecards/load.ts +11 -0
- package/src/standard/pricecards/view.ts +50 -0
- package/src/standard/sharedTexts.ts +6 -0
- package/src/standard/site.ts +124 -0
- package/src/standard/siteLooks.ts +19 -0
- package/src/standard/sites.ts +13 -0
- package/src/standard/steps/index.tsx +28 -0
- package/src/standard/steps/load.ts +5 -0
- package/src/standard/steps/view.ts +11 -0
- package/src/standard/testimonials/index.tsx +87 -0
- package/src/standard/testimonials/list.ts +43 -0
- package/src/standard/testimonials/load.ts +58 -0
- package/src/standard/testimonials/shared.ts +13 -0
- package/src/standard/testimonials/view.ts +76 -0
- package/src/standard/themeBlocks.ts +13 -0
- package/src/standard/video/index.tsx +23 -0
- package/src/standard/video/load.ts +10 -0
- package/src/standard/video/view.ts +42 -0
- package/src/standard/view.tsx +105 -0
- package/src/standard/views.ts +37 -0
- package/src/store.ts +499 -0
- package/src/theme.ts +90 -0
- package/src/themeUi.ts +97 -0
- package/src/themes.ts +91 -0
- package/src/ui.tsx +3402 -0
- package/src/virtual.d.ts +5 -0
- package/src/when.ts +22 -0
- package/starter/.githooks/pre-push +4 -0
- package/starter/.nvmrc +1 -0
- package/starter/.prettierignore +11 -0
- package/starter/.prettierrc.json +7 -0
- package/starter/README.md +26 -0
- package/starter/astro.config.mjs +5 -0
- package/starter/package.json +67 -0
- package/starter/public/_redirects +1 -0
- package/starter/public/apple-touch-icon.png +0 -0
- package/starter/public/editor/apple-touch-icon.png +0 -0
- package/starter/public/editor/icon-192.png +0 -0
- package/starter/public/editor/icon-512.png +0 -0
- package/starter/public/editor/icon-maskable-512.png +0 -0
- package/starter/public/favicon.ico +0 -0
- package/starter/public/favicon.svg +1 -0
- package/starter/public/logo.svg +1 -0
- package/starter/src/content/pages/blog.md +8 -0
- package/starter/src/content/pages/forside.md +9 -0
- package/starter/src/content/pages/kontakt.md +7 -0
- package/starter/src/content/pages/privatlivspolitik.md +9 -0
- package/starter/src/content/pages/siden-findes-ikke.md +7 -0
- package/starter/src/content.config.ts +2 -0
- package/starter/src/data/apps.json +1 -0
- package/starter/src/data/block-settings.json +3 -0
- package/starter/src/data/blocks.json +1 -0
- package/starter/src/data/booking.json +6 -0
- package/starter/src/data/colors.json +70 -0
- package/starter/src/data/contact.json +8 -0
- package/starter/src/data/cookies.json +21 -0
- package/starter/src/data/csp.json +1 -0
- package/starter/src/data/footer.json +15 -0
- package/starter/src/data/internal-links.json +4 -0
- package/starter/src/data/menu.json +4 -0
- package/starter/src/data/mobile-menu.json +4 -0
- package/starter/src/data/old-addresses.json +1 -0
- package/starter/src/data/redirects.json +1 -0
- package/starter/src/data/standard-pages.json +8 -0
- package/starter/src/data/theme.json +1 -0
- package/starter/src/env.d.ts +2 -0
- package/starter/src/site/config.ts +13 -0
- package/starter/src/site/worker.js +14 -0
- package/starter/tsconfig.json +17 -0
- package/starter/worker/apps.js +6 -0
- package/starter/wrangler.jsonc +39 -0
- package/theme/LICENSE +21 -0
- package/theme/blocks/ArrowLink.tsx +14 -0
- package/theme/blocks/BlockHead.tsx +26 -0
- package/theme/blocks/Panel.tsx +32 -0
- package/theme/blocks/Person.tsx +26 -0
- package/theme/blocks/accordion/PageRow.tsx +25 -0
- package/theme/blocks/accordion/View.tsx +17 -0
- package/theme/blocks/buttons/Buttons.tsx +28 -0
- package/theme/blocks/buttons/View.tsx +12 -0
- package/theme/blocks/cards/LinkCards.tsx +72 -0
- package/theme/blocks/cards/View.tsx +20 -0
- package/theme/blocks/checklist/Checks.tsx +15 -0
- package/theme/blocks/checklist/View.tsx +14 -0
- package/theme/blocks/cookies/View.tsx +36 -0
- package/theme/blocks/faq/Accordion.tsx +34 -0
- package/theme/blocks/faq/View.tsx +16 -0
- package/theme/blocks/faq/script.ts +56 -0
- package/theme/blocks/hero/View.tsx +44 -0
- package/theme/blocks/links/LinkGroups.tsx +24 -0
- package/theme/blocks/links/View.tsx +17 -0
- package/theme/blocks/list/Rows.tsx +24 -0
- package/theme/blocks/list/View.tsx +14 -0
- package/theme/blocks/notice/View.tsx +13 -0
- package/theme/blocks/points/PointList.tsx +34 -0
- package/theme/blocks/points/View.tsx +14 -0
- package/theme/blocks/posts/View.tsx +26 -0
- package/theme/blocks/pricecards/View.tsx +40 -0
- package/theme/blocks/steps/StepList.tsx +23 -0
- package/theme/blocks/steps/View.tsx +14 -0
- package/theme/blocks/testimonials/List.tsx +46 -0
- package/theme/blocks/testimonials/Slider.tsx +44 -0
- package/theme/blocks/testimonials/Testimonial.tsx +124 -0
- package/theme/blocks/testimonials/View.tsx +21 -0
- package/theme/blocks/testimonials/script.ts +52 -0
- package/theme/blocks/video/View.tsx +41 -0
- package/theme/components/ActionBar.astro +63 -0
- package/theme/components/AppSlot.astro +21 -0
- package/theme/components/ArrowLink.tsx +21 -0
- package/theme/components/BlogIndex.astro +48 -0
- package/theme/components/BlogPosts.astro +18 -0
- package/theme/components/BlogPosts.tsx +45 -0
- package/theme/components/BookButton.tsx +22 -0
- package/theme/components/Container.astro +11 -0
- package/theme/components/CookieConsent.astro +121 -0
- package/theme/components/EndBlock.astro +21 -0
- package/theme/components/FontPreload.astro +6 -0
- package/theme/components/Footer.astro +85 -0
- package/theme/components/Header.astro +186 -0
- package/theme/components/Icon.astro +16 -0
- package/theme/components/Img.astro +29 -0
- package/theme/components/Img.tsx +33 -0
- package/theme/components/Inline.astro +11 -0
- package/theme/components/Logo.astro +23 -0
- package/theme/components/LogoMark.astro +10 -0
- package/theme/components/Markdown.astro +17 -0
- package/theme/components/MobileMenu.tsx +224 -0
- package/theme/components/MobileNav.astro +33 -0
- package/theme/components/PageHeader.astro +22 -0
- package/theme/components/PageSection.astro +24 -0
- package/theme/components/PhoneButton.tsx +11 -0
- package/theme/components/Popup.astro +145 -0
- package/theme/components/PopupButton.tsx +24 -0
- package/theme/components/PopupView.tsx +48 -0
- package/theme/components/PostList.tsx +58 -0
- package/theme/components/PostMeta.tsx +17 -0
- package/theme/components/RichText.astro +28 -0
- package/theme/components/Section.astro +29 -0
- package/theme/components/SectionHeading.tsx +8 -0
- package/theme/components/TextSection.astro +16 -0
- package/theme/components/home/PageBlock.astro +19 -0
- package/theme/components/home/Text.astro +13 -0
- package/theme/components/loadPopup.ts +22 -0
- package/theme/components/loadPosts.ts +16 -0
- package/theme/components/posts.ts +15 -0
- package/theme/editor/looks.mjs +7 -0
- package/theme/editor/previews.tsx +56 -0
- package/theme/layouts/Base.astro +273 -0
- package/theme/layouts/PageLayout.astro +126 -0
- package/theme/layouts/PostLayout.astro +137 -0
- package/theme/screenshots/1-front.jpg +0 -0
- package/theme/screenshots/2-front-dark.jpg +0 -0
- package/theme/screenshots/3-blog.jpg +0 -0
- package/theme/screenshots/4-contact.jpg +0 -0
- package/theme/scripts/motion.ts +29 -0
- package/theme/styles/base.css +320 -0
- package/theme/styles/blocks.css +1808 -0
- package/theme/styles/components.css +206 -0
- package/theme/styles/global.css +1302 -0
- package/theme/styles/ui.css +6544 -0
- package/theme/templates/Blog.astro +38 -0
- package/theme/templates/Category.astro +19 -0
- package/theme/templates/Home.astro +36 -0
- package/theme/templates/New.astro +68 -0
- package/theme/templates/NotFound.astro +117 -0
- package/theme/theme.json +28 -0
- package/theme/ui/Badge.tsx +45 -0
- package/theme/ui/BottomSheet.tsx +148 -0
- package/theme/ui/Button.tsx +79 -0
- package/theme/ui/ButtonGroup.tsx +31 -0
- package/theme/ui/Card.tsx +45 -0
- package/theme/ui/Carousel.tsx +124 -0
- package/theme/ui/Checkbox.tsx +59 -0
- package/theme/ui/Chip.tsx +101 -0
- package/theme/ui/ChipSet.tsx +27 -0
- package/theme/ui/DatePicker.tsx +149 -0
- package/theme/ui/DatePickerContainer.tsx +316 -0
- package/theme/ui/Dialog.tsx +100 -0
- package/theme/ui/Divider.tsx +27 -0
- package/theme/ui/ExposedDropdownMenu.tsx +77 -0
- package/theme/ui/Fab.tsx +88 -0
- package/theme/ui/FabMenu.tsx +67 -0
- package/theme/ui/IconButton.tsx +78 -0
- package/theme/ui/List.tsx +287 -0
- package/theme/ui/LoadingIndicator.tsx +29 -0
- package/theme/ui/Menu.tsx +278 -0
- package/theme/ui/NavigationBar.tsx +62 -0
- package/theme/ui/NavigationDrawer.tsx +80 -0
- package/theme/ui/NavigationRail.tsx +154 -0
- package/theme/ui/ProgressIndicator.tsx +162 -0
- package/theme/ui/RadioButton.tsx +50 -0
- package/theme/ui/Search.tsx +129 -0
- package/theme/ui/SegmentedButton.tsx +49 -0
- package/theme/ui/SideSheet.tsx +54 -0
- package/theme/ui/Slider.tsx +155 -0
- package/theme/ui/Snackbar.tsx +67 -0
- package/theme/ui/SplitButton.tsx +67 -0
- package/theme/ui/Switch.tsx +60 -0
- package/theme/ui/Tabs.tsx +114 -0
- package/theme/ui/TextField.tsx +278 -0
- package/theme/ui/TimePicker.tsx +128 -0
- package/theme/ui/TimePickerContainer.tsx +234 -0
- package/theme/ui/Toolbar.tsx +67 -0
- package/theme/ui/Tooltip.tsx +58 -0
- package/theme/ui/TopAppBar.tsx +77 -0
- package/theme/ui/bottomSheet.script.ts +8 -0
- package/theme/ui/bottomSheet.ts +211 -0
- package/theme/ui/carousel.script.ts +28 -0
- package/theme/ui/carouselLayout.ts +229 -0
- package/theme/ui/checkbox.script.ts +8 -0
- package/theme/ui/datePicker.script.ts +302 -0
- package/theme/ui/dates.ts +185 -0
- package/theme/ui/dialog.ts +48 -0
- package/theme/ui/dropdownMenu.script.ts +166 -0
- package/theme/ui/fabMenu.script.ts +57 -0
- package/theme/ui/navigationRail.script.ts +47 -0
- package/theme/ui/ripple.script.ts +159 -0
- package/theme/ui/search.script.ts +92 -0
- package/theme/ui/sideSheet.ts +48 -0
- package/theme/ui/slider.script.ts +12 -0
- package/theme/ui/sliderUpdate.ts +52 -0
- package/theme/ui/snackbar.script.ts +16 -0
- package/theme/ui/splitButton.script.ts +63 -0
- package/theme/ui/tabs.script.ts +48 -0
- package/theme/ui/textField.script.ts +17 -0
- package/theme/ui/textFieldUpdate.ts +44 -0
- package/theme/ui/timePicker.script.ts +248 -0
- package/theme/ui/toolbar.script.ts +43 -0
- package/theme/ui/tooltip.script.ts +68 -0
- package/worker/consent.js +141 -0
- package/worker/editor-github.js +167 -0
- package/worker/editor-host.js +74 -0
- package/worker/files.js +401 -0
- package/worker/github.js +36 -0
- package/worker/index.js +184 -0
- package/worker/not-found.js +97 -0
- package/worker/oauth.js +95 -0
- package/worker/publish.js +52 -0
- package/worker/push.js +270 -0
- package/worker/r2-status.js +50 -0
- package/worker/session.js +58 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
// A navigation bar (m3.material.io/components/navigation-bar, .navigation-bar in ../styles/ui.css): the few main
|
|
2
|
+
// destinations side by side at the bottom of a phone's screen (NavigationBar, a <nav> with its name, `label`), each
|
|
3
|
+
// (NavigationBarItem) with its icon and its label, the open one (`selected`, aria-current) with the indicator behind its
|
|
4
|
+
// icon, and evt. a badge on the icon (`badge`: true for a dot, else the number it shows; the theme's Badge). Where the
|
|
5
|
+
// icon stands (`iconPosition`) is M3 Expressive's item configuration: `top`, the default, over the label (vertical
|
|
6
|
+
// items, each as wide as the others), `start` beside it (horizontal items, as wide as their content, together in the
|
|
7
|
+
// middle of the bar, the indicator behind both), or `auto`: over it while the bar is narrower than 600px (a phone) and
|
|
8
|
+
// beside it from there (a tablet and wider), as Material recommends. Where it stands (fixed at the bottom of the screen)
|
|
9
|
+
// is the component's own; how it looks is the theme's. Links are Link (on the site; in the editor only drawn); other
|
|
10
|
+
// attributes go on them. An Astro component gives its elements the classes with navigationBarClass,
|
|
11
|
+
// navigationBarClasses and navigationBarItemClass.
|
|
12
|
+
import type { ReactNode } from 'react';
|
|
13
|
+
import { Svg } from '@morphemecms/cms/src/icon';
|
|
14
|
+
import { Link } from '@morphemecms/cms/src/standard/view';
|
|
15
|
+
import Badge from '@theme/ui/Badge';
|
|
16
|
+
|
|
17
|
+
export type NavigationBarIconPosition = 'top' | 'start' | 'auto';
|
|
18
|
+
|
|
19
|
+
/** The bar's class, and a destination's. */
|
|
20
|
+
export const navigationBarClass = 'navigation-bar';
|
|
21
|
+
export const navigationBarItemClass = 'navigation-bar-item';
|
|
22
|
+
|
|
23
|
+
/** The bar's classes with where its items' icons stand. */
|
|
24
|
+
export const navigationBarClasses = (iconPosition: NavigationBarIconPosition = 'top') =>
|
|
25
|
+
iconPosition === 'top' ? navigationBarClass : `${navigationBarClass} navigation-bar-${iconPosition}`;
|
|
26
|
+
|
|
27
|
+
export default function NavigationBar({
|
|
28
|
+
label,
|
|
29
|
+
iconPosition,
|
|
30
|
+
className,
|
|
31
|
+
children,
|
|
32
|
+
...rest
|
|
33
|
+
}: { label: string; iconPosition?: NavigationBarIconPosition; className?: string; children: ReactNode } & Record<string, unknown>) {
|
|
34
|
+
return (
|
|
35
|
+
<nav aria-label={label} className={[navigationBarClasses(iconPosition), className].filter(Boolean).join(' ')} {...rest}>
|
|
36
|
+
{children}
|
|
37
|
+
</nav>
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/** A destination: its icon (a Phosphor name, the theme's icon) and its label, `selected` when it is the open page,
|
|
42
|
+
* and evt. a badge on the icon. */
|
|
43
|
+
export function NavigationBarItem({
|
|
44
|
+
href,
|
|
45
|
+
icon,
|
|
46
|
+
label,
|
|
47
|
+
selected,
|
|
48
|
+
badge,
|
|
49
|
+
...rest
|
|
50
|
+
}: { href: string; icon: string; label: ReactNode; selected?: boolean; badge?: true | number } & Record<string, unknown>) {
|
|
51
|
+
return (
|
|
52
|
+
<Link href={href} className={navigationBarItemClass} aria-current={selected ? 'page' : undefined} {...rest}>
|
|
53
|
+
<span className="navigation-bar-indicator">
|
|
54
|
+
<span className="navigation-bar-icon">
|
|
55
|
+
<Svg name={icon} size={24} />
|
|
56
|
+
{badge !== undefined && <Badge count={badge === true ? undefined : badge} className="navigation-bar-badge" />}
|
|
57
|
+
</span>
|
|
58
|
+
<span className="navigation-bar-label">{label}</span>
|
|
59
|
+
</span>
|
|
60
|
+
</Link>
|
|
61
|
+
);
|
|
62
|
+
}
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
// A modal navigation drawer (m3.material.io/components/navigation-drawer, .navigation-drawer in ../styles/ui.css): the
|
|
2
|
+
// site's pages in a panel over the page (components/MobileMenu.tsx, and a theme's own menu), over its scrim
|
|
3
|
+
// (navigationDrawerScrimClass). Its pages are items (NavigationDrawerItem, `active`: the open page or the one holding
|
|
4
|
+
// it), an item with sub-pages is a row (NavigationDrawerRow) with the button that unfolds them after it
|
|
5
|
+
// (NavigationDrawerToggle, `expanded`), and a sub-page a subitem (NavigationDrawerSubitem). Where it comes from, how it
|
|
6
|
+
// moves and what else is in it (the logo, the buttons) is the menu's own: it gives its own element (a motion.div) the
|
|
7
|
+
// class with navigationDrawerClass; in a <dialog> (the editor's), the dialog has navigationDrawerDialogClass and its
|
|
8
|
+
// scrim is the dialog's. Links are Link (on the site; in the editor's previews only drawn), an item without `href` a
|
|
9
|
+
// button (the editor's: a part of a form); other attributes (onClick, aria-…) go on them.
|
|
10
|
+
import type { ReactNode } from 'react';
|
|
11
|
+
import { Svg } from '@morphemecms/cms/src/icon';
|
|
12
|
+
import { Link } from '@morphemecms/cms/src/standard/view';
|
|
13
|
+
|
|
14
|
+
/** The drawer's class, and its scrim's. */
|
|
15
|
+
export const navigationDrawerClass = 'navigation-drawer';
|
|
16
|
+
export const navigationDrawerScrimClass = 'navigation-drawer-scrim';
|
|
17
|
+
/** The class of a <dialog> the drawer is in: at the end of the screen, as high as it, over its scrim. */
|
|
18
|
+
export const navigationDrawerDialogClass = 'navigation-drawer-dialog';
|
|
19
|
+
|
|
20
|
+
export function NavigationDrawer({ className, children, ...rest }: { className?: string; children: ReactNode } & Record<string, unknown>) {
|
|
21
|
+
return (
|
|
22
|
+
<div className={[navigationDrawerClass, className].filter(Boolean).join(' ')} {...rest}>
|
|
23
|
+
{children}
|
|
24
|
+
</div>
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** A page in the drawer, `active` when it is the open page or holds it; without `href` a button. */
|
|
29
|
+
export function NavigationDrawerItem({
|
|
30
|
+
href,
|
|
31
|
+
active,
|
|
32
|
+
children,
|
|
33
|
+
...rest
|
|
34
|
+
}: { href?: string; active?: boolean; children: ReactNode } & Record<string, unknown>) {
|
|
35
|
+
return href === undefined ? (
|
|
36
|
+
<button type="button" className="navigation-drawer-item" data-active={active || undefined} {...rest}>
|
|
37
|
+
{children}
|
|
38
|
+
</button>
|
|
39
|
+
) : (
|
|
40
|
+
<Link href={href} className="navigation-drawer-item" data-active={active || undefined} {...rest}>
|
|
41
|
+
{children}
|
|
42
|
+
</Link>
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** An item and what stands after it (the toggle of its sub-pages). */
|
|
47
|
+
export function NavigationDrawerRow({
|
|
48
|
+
className,
|
|
49
|
+
children,
|
|
50
|
+
...rest
|
|
51
|
+
}: { className?: string; children: ReactNode } & Record<string, unknown>) {
|
|
52
|
+
return (
|
|
53
|
+
<div className={['navigation-drawer-row', className].filter(Boolean).join(' ')} {...rest}>
|
|
54
|
+
{children}
|
|
55
|
+
</div>
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/** The button that unfolds an item's sub-pages: a caret, turned while they are open (`expanded`). */
|
|
60
|
+
export function NavigationDrawerToggle({ label, expanded, ...rest }: { label: string; expanded: boolean } & Record<string, unknown>) {
|
|
61
|
+
return (
|
|
62
|
+
<button type="button" className="navigation-drawer-toggle" aria-expanded={expanded} aria-label={label} {...rest}>
|
|
63
|
+
<Svg name="caret-down" size={20} />
|
|
64
|
+
</button>
|
|
65
|
+
);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** A sub-page, `active` when it is the open page. */
|
|
69
|
+
export function NavigationDrawerSubitem({
|
|
70
|
+
href,
|
|
71
|
+
active,
|
|
72
|
+
children,
|
|
73
|
+
...rest
|
|
74
|
+
}: { href: string; active?: boolean; children: ReactNode } & Record<string, unknown>) {
|
|
75
|
+
return (
|
|
76
|
+
<Link href={href} className="navigation-drawer-subitem" data-active={active || undefined} {...rest}>
|
|
77
|
+
{children}
|
|
78
|
+
</Link>
|
|
79
|
+
);
|
|
80
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
// A navigation rail (m3.material.io/components/navigation-rail, M3 Expressive; .navigation-rail in ../styles/ui.css):
|
|
2
|
+
// the main destinations down the side of a larger screen (NavigationRail, a <nav> with its name, `label`), collapsed
|
|
3
|
+
// (each destination's icon over its label) or expanded (`expanded`: the icon and the label side by side), with its menu
|
|
4
|
+
// button at the top (`menuLabel`, which expands and collapses it: on the site navigationRail.script.ts) and evt. the
|
|
5
|
+
// screen's main action under it (`fab`: an extended FAB, ExtendedFab, with only its icon while the rail is collapsed).
|
|
6
|
+
// Material's two configurations of the expanded rail: its modality (`modality`: `standard`, the default, beside the
|
|
7
|
+
// content, which makes room for it, or `modal`, over the page with a scrim behind it, which closes it, as Escape does)
|
|
8
|
+
// and its behaviour (`expandedBehavior`: `collapse`, the default, back into the collapsed rail, or `hide`, nothing while
|
|
9
|
+
// it is collapsed; then a button elsewhere opens it: an icon button with data-navigation-rail-menu and aria-controls,
|
|
10
|
+
// the rail's id). Each destination (NavigationRailItem) has its icon, its label, `selected` (aria-current) when it is
|
|
11
|
+
// the open page, and evt. a badge on the icon (`badge`: true for a dot, else the number it shows; the theme's Badge) and,
|
|
12
|
+
// while the rail is expanded, a text at its end (`trailingSupporting`: how many there are). The destinations can stand in
|
|
13
|
+
// sections (NavigationRailSection, M3 Expressive's), each with its name over it while the rail is expanded and a line
|
|
14
|
+
// between them while it is collapsed. Evt. something under the menu button while the rail is expanded (`header`: the
|
|
15
|
+
// editor's logo and the site's name). With `onExpandedChange` the rail is expanded and collapsed by whoever draws it (the
|
|
16
|
+
// editor) instead of by its script; a modal one without `scrim` has none (one that expands while the mouse is over it:
|
|
17
|
+
// the editor's).
|
|
18
|
+
// Where it stands (beside the content, in a row) is the component's own; how it looks is the theme's. Links are Link (on
|
|
19
|
+
// the site; in the editor only drawn). An Astro component gives its elements the classes with navigationRailClass,
|
|
20
|
+
// navigationRailClasses and navigationRailItemClass.
|
|
21
|
+
import type { ReactNode } from 'react';
|
|
22
|
+
import { Glyph, Svg, type IconRef } from '@morphemecms/cms/src/icon';
|
|
23
|
+
import { Link } from '@morphemecms/cms/src/standard/view';
|
|
24
|
+
import { ExtendedFab } from '@theme/ui/Fab';
|
|
25
|
+
import { iconButtonClass } from '@theme/ui/IconButton';
|
|
26
|
+
import Badge from '@theme/ui/Badge';
|
|
27
|
+
|
|
28
|
+
export type NavigationRailModality = 'standard' | 'modal';
|
|
29
|
+
export type NavigationRailExpandedBehavior = 'collapse' | 'hide';
|
|
30
|
+
|
|
31
|
+
/** The rail's class, and a destination's. */
|
|
32
|
+
export const navigationRailClass = 'navigation-rail';
|
|
33
|
+
export const navigationRailItemClass = 'navigation-rail-item';
|
|
34
|
+
|
|
35
|
+
/** The rail's classes with its expanded modality and behaviour. */
|
|
36
|
+
export const navigationRailClasses = (
|
|
37
|
+
modality: NavigationRailModality = 'standard',
|
|
38
|
+
expandedBehavior: NavigationRailExpandedBehavior = 'collapse',
|
|
39
|
+
) =>
|
|
40
|
+
[navigationRailClass, modality === 'modal' && 'navigation-rail-modal', expandedBehavior === 'hide' && 'navigation-rail-hide']
|
|
41
|
+
.filter(Boolean)
|
|
42
|
+
.join(' ');
|
|
43
|
+
|
|
44
|
+
/** The scrim's class, behind a modal rail while it is expanded. */
|
|
45
|
+
export const navigationRailScrimClass = 'navigation-rail-scrim';
|
|
46
|
+
|
|
47
|
+
export default function NavigationRail({
|
|
48
|
+
label,
|
|
49
|
+
menuLabel,
|
|
50
|
+
expanded,
|
|
51
|
+
modality = 'standard',
|
|
52
|
+
expandedBehavior = 'collapse',
|
|
53
|
+
fab,
|
|
54
|
+
header,
|
|
55
|
+
scrim = true,
|
|
56
|
+
onExpandedChange,
|
|
57
|
+
className,
|
|
58
|
+
children,
|
|
59
|
+
...rest
|
|
60
|
+
}: {
|
|
61
|
+
label: string;
|
|
62
|
+
menuLabel: string;
|
|
63
|
+
expanded?: boolean;
|
|
64
|
+
modality?: NavigationRailModality;
|
|
65
|
+
expandedBehavior?: NavigationRailExpandedBehavior;
|
|
66
|
+
fab?: { icon: string; label: string; href?: string } & Record<string, unknown>;
|
|
67
|
+
header?: ReactNode;
|
|
68
|
+
scrim?: boolean;
|
|
69
|
+
onExpandedChange?: (expanded: boolean) => void;
|
|
70
|
+
className?: string;
|
|
71
|
+
children: ReactNode;
|
|
72
|
+
} & Record<string, unknown>) {
|
|
73
|
+
const rail = (
|
|
74
|
+
<nav
|
|
75
|
+
aria-label={label}
|
|
76
|
+
className={[navigationRailClasses(modality, expandedBehavior), className].filter(Boolean).join(' ')}
|
|
77
|
+
data-navigation-rail=""
|
|
78
|
+
data-expanded={expanded || undefined}
|
|
79
|
+
{...rest}
|
|
80
|
+
>
|
|
81
|
+
<div className="navigation-rail-header">
|
|
82
|
+
<button
|
|
83
|
+
type="button"
|
|
84
|
+
className={`${iconButtonClass('standard')} navigation-rail-menu`}
|
|
85
|
+
aria-label={menuLabel}
|
|
86
|
+
aria-expanded={!!expanded}
|
|
87
|
+
data-navigation-rail-menu={onExpandedChange ? undefined : ''}
|
|
88
|
+
onClick={onExpandedChange && (() => onExpandedChange(!expanded))}
|
|
89
|
+
>
|
|
90
|
+
<Svg name="list" size={24} />
|
|
91
|
+
<Svg name="caret-left" size={24} />
|
|
92
|
+
</button>
|
|
93
|
+
{fab && <ExtendedFab {...fab} collapsed={!expanded} />}
|
|
94
|
+
{header != null && <div className="navigation-rail-header-content">{header}</div>}
|
|
95
|
+
</div>
|
|
96
|
+
<div className="navigation-rail-items">{children}</div>
|
|
97
|
+
</nav>
|
|
98
|
+
);
|
|
99
|
+
// A modal one's scrim just before it, over the page and under the rail (navigationRail.script.ts shows it).
|
|
100
|
+
return modality === 'modal' && scrim ? (
|
|
101
|
+
<>
|
|
102
|
+
<div className={navigationRailScrimClass} data-navigation-rail-scrim="" hidden={!expanded} />
|
|
103
|
+
{rail}
|
|
104
|
+
</>
|
|
105
|
+
) : (
|
|
106
|
+
rail
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** Destinations under each other in a section, with its name (`label`) over them while the rail is expanded. */
|
|
111
|
+
export function NavigationRailSection({ label, children }: { label: string; children: ReactNode }) {
|
|
112
|
+
return (
|
|
113
|
+
<div className="navigation-rail-section" role="group" aria-label={label}>
|
|
114
|
+
<span className="navigation-rail-section-label" aria-hidden="true">
|
|
115
|
+
{label}
|
|
116
|
+
</span>
|
|
117
|
+
{children}
|
|
118
|
+
</div>
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/** A destination: its icon (a Phosphor name, the theme's icon, or an icon made: IconRef) and its label, `selected` when
|
|
123
|
+
* it is the open page, evt. a badge on the icon, and a text at its end while the rail is expanded. */
|
|
124
|
+
export function NavigationRailItem({
|
|
125
|
+
href,
|
|
126
|
+
icon,
|
|
127
|
+
label,
|
|
128
|
+
selected,
|
|
129
|
+
badge,
|
|
130
|
+
trailingSupporting,
|
|
131
|
+
...rest
|
|
132
|
+
}: {
|
|
133
|
+
href: string;
|
|
134
|
+
icon: IconRef;
|
|
135
|
+
label: ReactNode;
|
|
136
|
+
selected?: boolean;
|
|
137
|
+
badge?: true | number;
|
|
138
|
+
trailingSupporting?: ReactNode;
|
|
139
|
+
} & Record<string, unknown>) {
|
|
140
|
+
return (
|
|
141
|
+
<Link href={href} className={navigationRailItemClass} aria-current={selected ? 'page' : undefined} {...rest}>
|
|
142
|
+
<span className="navigation-rail-indicator">
|
|
143
|
+
<span className="navigation-rail-icon">
|
|
144
|
+
<Glyph icon={icon} size={24} />
|
|
145
|
+
{badge !== undefined && <Badge count={badge === true ? undefined : badge} className="navigation-rail-badge" />}
|
|
146
|
+
</span>
|
|
147
|
+
<span className="navigation-rail-label">{label}</span>
|
|
148
|
+
{trailingSupporting != null && trailingSupporting !== '' && (
|
|
149
|
+
<span className="navigation-rail-trailing-supporting">{trailingSupporting}</span>
|
|
150
|
+
)}
|
|
151
|
+
</span>
|
|
152
|
+
</Link>
|
|
153
|
+
);
|
|
154
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
// Progress indicators (m3.material.io/components/progress-indicators, .linear-progress-indicator and
|
|
2
|
+
// .circular-progress-indicator in ../styles/ui.css): how far something has come (`value`, 0 to 1: determinate), as a
|
|
3
|
+
// line that fills up (LinearProgressIndicator) or a ring (CircularProgressIndicator, where there is no room for a
|
|
4
|
+
// line), the active indicator on its track; without `value` (indeterminate), that it is on its way, as stretches that
|
|
5
|
+
// run along the line or round the ring. M3 Expressive's shape (`shape`: flat, the default, or wavy, the active
|
|
6
|
+
// indicator a wave that flows along it) and its thick track (`thick`) are Material's names; how they look is the
|
|
7
|
+
// theme's (--linear-progress-indicator-*, --circular-progress-indicator-*). The wave is drawn here as an SVG path (a
|
|
8
|
+
// line, not an icon), Material's: 3px high and 40px long on a line (24px while indeterminate), nine waves round a ring
|
|
9
|
+
// (six round a thick one).
|
|
10
|
+
// Screen readers read a progress bar named by `label`, with its value in percent when it is known. With reduced motion
|
|
11
|
+
// the indeterminate ones move slowly, the wave stands still and a value changes at once. The value is the custom
|
|
12
|
+
// property --progress on the element, so a script can change it (with aria-valuenow).
|
|
13
|
+
import type { CSSProperties } from 'react';
|
|
14
|
+
|
|
15
|
+
/** A progress indicator's shapes, as M3 Expressive names them. */
|
|
16
|
+
export type ProgressIndicatorShape = 'flat' | 'wavy';
|
|
17
|
+
|
|
18
|
+
const clamp = (v: number) => Math.min(1, Math.max(0, v));
|
|
19
|
+
|
|
20
|
+
// What a progress bar is to screen readers, and its value for the CSS (with the wave's measures for a wavy one).
|
|
21
|
+
function progressbar(value: number | undefined, label: string, wave?: Record<string, string | number>) {
|
|
22
|
+
const known = value !== undefined;
|
|
23
|
+
const style = { ...(known ? { '--progress': clamp(value) } : {}), ...wave } as CSSProperties;
|
|
24
|
+
return {
|
|
25
|
+
role: 'progressbar',
|
|
26
|
+
'aria-label': label,
|
|
27
|
+
'aria-valuemin': 0,
|
|
28
|
+
'aria-valuemax': 100,
|
|
29
|
+
'aria-valuenow': known ? Math.round(clamp(value) * 100) : undefined,
|
|
30
|
+
style: Object.keys(style).length ? style : undefined,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const classes = (part: string, indeterminate?: boolean, shape: ProgressIndicatorShape = 'flat', thick = false) =>
|
|
35
|
+
[part, indeterminate && `${part}-indeterminate`, shape === 'wavy' && `${part}-wavy`, thick && `${part}-thick`].filter(Boolean).join(' ');
|
|
36
|
+
|
|
37
|
+
/** A linear progress indicator's classes: determinate or not, its shape and a thick track. */
|
|
38
|
+
export const linearProgressIndicatorClass = (indeterminate?: boolean, shape?: ProgressIndicatorShape, thick?: boolean) =>
|
|
39
|
+
classes('linear-progress-indicator', indeterminate, shape, thick);
|
|
40
|
+
/** A circular progress indicator's classes: determinate or not, its shape and a thick track. */
|
|
41
|
+
export const circularProgressIndicatorClass = (indeterminate?: boolean, shape?: ProgressIndicatorShape, thick?: boolean) =>
|
|
42
|
+
classes('circular-progress-indicator', indeterminate, shape, thick);
|
|
43
|
+
|
|
44
|
+
// The line's wave, in px: its height (amplitude) and length (wavelength), and a path of it long enough for any line,
|
|
45
|
+
// from one wavelength before its start (where it flows in from), in quadratic curves, a peak and a trough each.
|
|
46
|
+
const AMPLITUDE = 3;
|
|
47
|
+
const WAVELENGTH = { determinate: 40, indeterminate: 24 };
|
|
48
|
+
const LENGTH = 4096;
|
|
49
|
+
function linePath(wavelength: number) {
|
|
50
|
+
const half = wavelength / 2;
|
|
51
|
+
const turns = Math.ceil((LENGTH + wavelength) / half);
|
|
52
|
+
return `M${-wavelength} 0q${half / 2} ${-2 * AMPLITUDE} ${half} 0${` t${half} 0`.repeat(turns - 1)}`;
|
|
53
|
+
}
|
|
54
|
+
// How much longer the wave is than the line it runs along (for its dashes, which CSS measures along the path).
|
|
55
|
+
function stretch(wavelength: number) {
|
|
56
|
+
const half = wavelength / 2;
|
|
57
|
+
let length = 0;
|
|
58
|
+
let last = [0, 0];
|
|
59
|
+
for (let i = 1; i <= 64; i++) {
|
|
60
|
+
const t = i / 64;
|
|
61
|
+
const point = [2 * (1 - t) * t * (half / 2) + t * t * half, 2 * (1 - t) * t * -2 * AMPLITUDE];
|
|
62
|
+
length += Math.hypot(point[0] - last[0], point[1] - last[1]);
|
|
63
|
+
last = point;
|
|
64
|
+
}
|
|
65
|
+
return length / half;
|
|
66
|
+
}
|
|
67
|
+
const lines = {
|
|
68
|
+
determinate: { d: linePath(WAVELENGTH.determinate), stretch: stretch(WAVELENGTH.determinate) },
|
|
69
|
+
indeterminate: { d: linePath(WAVELENGTH.indeterminate), stretch: stretch(WAVELENGTH.indeterminate) },
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
// The ring's wave in its 48 wide box: nine waves round it (a thick one six, longer for its thicker line), its radius
|
|
73
|
+
// in from the box's edge for its height and thickness, as a path of points (pathLength 100, as the ring's).
|
|
74
|
+
function ringPath(r: number, amplitude: number, waves: number) {
|
|
75
|
+
const points = Array.from({ length: 180 }, (_, i) => {
|
|
76
|
+
const angle = (i / 180) * 2 * Math.PI;
|
|
77
|
+
const at = r + amplitude * Math.sin(waves * angle);
|
|
78
|
+
return `${(24 + at * Math.cos(angle)).toFixed(2)} ${(24 + at * Math.sin(angle)).toFixed(2)}`;
|
|
79
|
+
});
|
|
80
|
+
return `M${points.join('L')}Z`;
|
|
81
|
+
}
|
|
82
|
+
const rings = { wavy: ringPath(19, 1.25, 9), wavyThick: ringPath(17.5, 1.5, 6) };
|
|
83
|
+
|
|
84
|
+
export function LinearProgressIndicator({
|
|
85
|
+
value,
|
|
86
|
+
label,
|
|
87
|
+
shape = 'flat',
|
|
88
|
+
thick,
|
|
89
|
+
className,
|
|
90
|
+
...rest
|
|
91
|
+
}: { value?: number; label: string; shape?: ProgressIndicatorShape; thick?: boolean; className?: string } & Record<string, unknown>) {
|
|
92
|
+
const indeterminate = value === undefined;
|
|
93
|
+
const wavy = shape === 'wavy';
|
|
94
|
+
const line = lines[indeterminate ? 'indeterminate' : 'determinate'];
|
|
95
|
+
const wave = wavy
|
|
96
|
+
? {
|
|
97
|
+
'--linear-progress-indicator-amplitude': `${AMPLITUDE}px`,
|
|
98
|
+
'--linear-progress-indicator-wavelength': `${WAVELENGTH[indeterminate ? 'indeterminate' : 'determinate']}px`,
|
|
99
|
+
'--linear-progress-indicator-stretch': line.stretch.toFixed(4),
|
|
100
|
+
}
|
|
101
|
+
: undefined;
|
|
102
|
+
return (
|
|
103
|
+
<div
|
|
104
|
+
className={[linearProgressIndicatorClass(indeterminate, shape, thick), className].filter(Boolean).join(' ')}
|
|
105
|
+
{...progressbar(value, label, wave)}
|
|
106
|
+
{...rest}
|
|
107
|
+
>
|
|
108
|
+
{wavy ? (
|
|
109
|
+
<>
|
|
110
|
+
{!indeterminate && <span className="linear-progress-indicator-track"></span>}
|
|
111
|
+
<svg className="linear-progress-indicator-wave" aria-hidden="true">
|
|
112
|
+
<path className="linear-progress-indicator-active" d={line.d} />
|
|
113
|
+
{indeterminate && <path className="linear-progress-indicator-active" d={line.d} />}
|
|
114
|
+
</svg>
|
|
115
|
+
{!indeterminate && <span className="linear-progress-indicator-stop"></span>}
|
|
116
|
+
</>
|
|
117
|
+
) : indeterminate ? (
|
|
118
|
+
<>
|
|
119
|
+
<span className="linear-progress-indicator-active"></span>
|
|
120
|
+
<span className="linear-progress-indicator-active"></span>
|
|
121
|
+
</>
|
|
122
|
+
) : (
|
|
123
|
+
<>
|
|
124
|
+
<span className="linear-progress-indicator-active"></span>
|
|
125
|
+
<span className="linear-progress-indicator-track"></span>
|
|
126
|
+
<span className="linear-progress-indicator-stop"></span>
|
|
127
|
+
</>
|
|
128
|
+
)}
|
|
129
|
+
</div>
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
export function CircularProgressIndicator({
|
|
134
|
+
value,
|
|
135
|
+
label,
|
|
136
|
+
shape = 'flat',
|
|
137
|
+
thick,
|
|
138
|
+
className,
|
|
139
|
+
...rest
|
|
140
|
+
}: { value?: number; label: string; shape?: ProgressIndicatorShape; thick?: boolean; className?: string } & Record<string, unknown>) {
|
|
141
|
+
const indeterminate = value === undefined;
|
|
142
|
+
const wavy = shape === 'wavy';
|
|
143
|
+
// A ring 48 wide, its stroke inside it (a thick or wavy one further in); the lengths along it in percent
|
|
144
|
+
// (pathLength).
|
|
145
|
+
const ring = { cx: 24, cy: 24, r: wavy ? (thick ? 17.5 : 19) : thick ? 19 : 20, pathLength: 100, fill: 'none' };
|
|
146
|
+
return (
|
|
147
|
+
<span
|
|
148
|
+
className={[circularProgressIndicatorClass(indeterminate, shape, thick), className].filter(Boolean).join(' ')}
|
|
149
|
+
{...progressbar(value, label)}
|
|
150
|
+
{...rest}
|
|
151
|
+
>
|
|
152
|
+
<svg viewBox="0 0 48 48" aria-hidden="true">
|
|
153
|
+
{!indeterminate && <circle className="circular-progress-indicator-track" {...ring} />}
|
|
154
|
+
{wavy ? (
|
|
155
|
+
<path className="circular-progress-indicator-active" d={thick ? rings.wavyThick : rings.wavy} pathLength={100} fill="none" />
|
|
156
|
+
) : (
|
|
157
|
+
<circle className="circular-progress-indicator-active" {...ring} />
|
|
158
|
+
)}
|
|
159
|
+
</svg>
|
|
160
|
+
</span>
|
|
161
|
+
);
|
|
162
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// A radio button (m3.material.io/components/radio-button, .radio-button in ../styles/ui.css): one of a few choices,
|
|
2
|
+
// of which only one can be chosen. As the checkbox (Checkbox.tsx): the round button, its name (`label`) beside it and
|
|
3
|
+
// a line under the name (`supporting`), all of it one <label>, so a click anywhere chooses it. The buttons of one
|
|
4
|
+
// choice have the same `name` (on the <input>, with its `value`) and stand in a RadioGroup, the choice's name
|
|
5
|
+
// (`label`) over them: native radio buttons, so the arrow keys move between them and Tab moves past the group.
|
|
6
|
+
// `checked`: chosen from the start; `disabled`: it cannot be chosen. The browser draws the button in the accent; a
|
|
7
|
+
// theme that draws it itself (appearance: none) draws its dot too. Other attributes (`name`, `value`, data-…) go on
|
|
8
|
+
// the <input>, and `className` on the label. An Astro component gives an element the same classes with
|
|
9
|
+
// radioButtonClass and radioGroupClass.
|
|
10
|
+
import type { ReactNode } from 'react';
|
|
11
|
+
|
|
12
|
+
/** A radio button's classes, and a group's. */
|
|
13
|
+
export const radioButtonClass = () => 'radio-button';
|
|
14
|
+
export const radioGroupClass = () => 'radio-group';
|
|
15
|
+
|
|
16
|
+
export default function RadioButton({
|
|
17
|
+
label,
|
|
18
|
+
supporting,
|
|
19
|
+
checked,
|
|
20
|
+
className,
|
|
21
|
+
...rest
|
|
22
|
+
}: { label: string; supporting?: string; checked?: boolean; className?: string } & Record<string, unknown>) {
|
|
23
|
+
return (
|
|
24
|
+
<label className={[radioButtonClass(), className].filter(Boolean).join(' ')}>
|
|
25
|
+
<span className="radio-button-box">
|
|
26
|
+
<input type="radio" className="radio-button-input" defaultChecked={checked} {...rest} />
|
|
27
|
+
</span>
|
|
28
|
+
<span className="radio-button-text">
|
|
29
|
+
<span className="radio-button-label">{label}</span>
|
|
30
|
+
{supporting && <span className="radio-button-supporting">{supporting}</span>}
|
|
31
|
+
</span>
|
|
32
|
+
</label>
|
|
33
|
+
);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/** The radio buttons of one choice under its name (`label`): a <fieldset> with its <legend>. Other attributes go on
|
|
37
|
+
* the <fieldset>, and `className` after its own class. */
|
|
38
|
+
export function RadioGroup({
|
|
39
|
+
label,
|
|
40
|
+
className,
|
|
41
|
+
children,
|
|
42
|
+
...rest
|
|
43
|
+
}: { label: string; className?: string; children: ReactNode } & Record<string, unknown>) {
|
|
44
|
+
return (
|
|
45
|
+
<fieldset className={[radioGroupClass(), className].filter(Boolean).join(' ')} {...rest}>
|
|
46
|
+
<legend className="radio-group-label">{label}</legend>
|
|
47
|
+
{children}
|
|
48
|
+
</fieldset>
|
|
49
|
+
);
|
|
50
|
+
}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
// A search (m3.material.io/components/search, .search in ../styles/ui.css): the search bar (its leading icon,
|
|
2
|
+
// `leadingIcon`, the theme's magnifying glass if it has none, the placeholder, `label`, and what stands after it,
|
|
3
|
+
// `trailing`: icon buttons, an avatar) and the search view it opens (a <dialog>: over the whole screen on a phone, docked
|
|
4
|
+
// where the bar is from 48rem), with the button back (`backLabel`), the field (a role="combobox"), the button that
|
|
5
|
+
// empties it (`clearLabel`), and the results (`results`, the theme's list, List and ListItem, as a role="listbox" of
|
|
6
|
+
// links, each its headline, evt. its supporting text and its icon) or, when none fits, `emptyText`. On the site
|
|
7
|
+
// search.script.ts opens and closes it (the back button, Escape, a tap outside), narrows the results to what is
|
|
8
|
+
// written, and moves through them with the arrow keys (Enter follows the one it is on). In the editor only drawn:
|
|
9
|
+
// `open` draws the view (as docked) with `query` in the field instead of the bar. How it looks is the theme's.
|
|
10
|
+
import { useId, type ReactNode } from 'react';
|
|
11
|
+
import { Svg } from '@morphemecms/cms/src/icon';
|
|
12
|
+
import IconButton from '@theme/ui/IconButton';
|
|
13
|
+
import List, { ListItem } from '@theme/ui/List';
|
|
14
|
+
|
|
15
|
+
export type SearchResult = { href: string; headline: ReactNode; supporting?: ReactNode; icon?: string };
|
|
16
|
+
|
|
17
|
+
/** The class of a search (the bar and its view). */
|
|
18
|
+
export const searchClass = 'search';
|
|
19
|
+
|
|
20
|
+
export default function Search({
|
|
21
|
+
label,
|
|
22
|
+
backLabel,
|
|
23
|
+
clearLabel,
|
|
24
|
+
emptyText,
|
|
25
|
+
results,
|
|
26
|
+
leadingIcon = 'magnifying-glass',
|
|
27
|
+
trailing,
|
|
28
|
+
open,
|
|
29
|
+
query,
|
|
30
|
+
className,
|
|
31
|
+
...rest
|
|
32
|
+
}: {
|
|
33
|
+
label: string;
|
|
34
|
+
backLabel: string;
|
|
35
|
+
clearLabel: string;
|
|
36
|
+
emptyText: string;
|
|
37
|
+
results: SearchResult[];
|
|
38
|
+
leadingIcon?: string;
|
|
39
|
+
trailing?: ReactNode;
|
|
40
|
+
open?: boolean;
|
|
41
|
+
query?: string;
|
|
42
|
+
className?: string;
|
|
43
|
+
} & Record<string, unknown>) {
|
|
44
|
+
const id = useId();
|
|
45
|
+
const view = `${id}-view`;
|
|
46
|
+
const list = `${id}-results`;
|
|
47
|
+
return (
|
|
48
|
+
<div className={[searchClass, className].filter(Boolean).join(' ')} data-search="" {...rest}>
|
|
49
|
+
{!open && (
|
|
50
|
+
<div className="search-bar">
|
|
51
|
+
<button
|
|
52
|
+
type="button"
|
|
53
|
+
className="search-bar-field"
|
|
54
|
+
aria-haspopup="dialog"
|
|
55
|
+
aria-expanded="false"
|
|
56
|
+
aria-controls={view}
|
|
57
|
+
data-search-open=""
|
|
58
|
+
>
|
|
59
|
+
<span className="search-bar-leading">
|
|
60
|
+
<Svg name={leadingIcon} size={24} />
|
|
61
|
+
</span>
|
|
62
|
+
<span className="search-bar-placeholder">{label}</span>
|
|
63
|
+
</button>
|
|
64
|
+
{trailing && <span className="search-bar-trailing">{trailing}</span>}
|
|
65
|
+
</div>
|
|
66
|
+
)}
|
|
67
|
+
<dialog id={view} className="search-view" aria-label={label} open={open} data-search-view="">
|
|
68
|
+
<div className="search-view-header">
|
|
69
|
+
<IconButton icon="arrow-left" label={backLabel} data-search-close="" />
|
|
70
|
+
<input
|
|
71
|
+
type="search"
|
|
72
|
+
className="search-view-input"
|
|
73
|
+
role="combobox"
|
|
74
|
+
aria-label={label}
|
|
75
|
+
aria-expanded="true"
|
|
76
|
+
aria-controls={list}
|
|
77
|
+
aria-autocomplete="list"
|
|
78
|
+
autoComplete="off"
|
|
79
|
+
enterKeyHint="search"
|
|
80
|
+
placeholder={label}
|
|
81
|
+
defaultValue={query}
|
|
82
|
+
data-search-input=""
|
|
83
|
+
/>
|
|
84
|
+
<IconButton icon="x" label={clearLabel} className="search-view-clear" data-search-clear="" />
|
|
85
|
+
</div>
|
|
86
|
+
<List id={list} role="listbox" aria-label={label} className="search-view-results">
|
|
87
|
+
{results.map((r, i) => (
|
|
88
|
+
<ListItem
|
|
89
|
+
key={i}
|
|
90
|
+
href={r.href}
|
|
91
|
+
leading={r.icon ? <Svg name={r.icon} size={24} /> : undefined}
|
|
92
|
+
headline={r.headline}
|
|
93
|
+
supporting={r.supporting}
|
|
94
|
+
presentation
|
|
95
|
+
role="option"
|
|
96
|
+
id={`${list}-${i}`}
|
|
97
|
+
aria-selected="false"
|
|
98
|
+
data-search-option=""
|
|
99
|
+
/>
|
|
100
|
+
))}
|
|
101
|
+
</List>
|
|
102
|
+
<p className="search-view-empty" hidden data-search-empty="">
|
|
103
|
+
{emptyText}
|
|
104
|
+
</p>
|
|
105
|
+
</dialog>
|
|
106
|
+
</div>
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/** The search bar alone, searching in place (the editor's lists, narrowed as it is written in): the bar with its
|
|
111
|
+
* leading icon and a field (an <input type="search">, `label` its name and placeholder) instead of the button that opens
|
|
112
|
+
* the view. Other attributes (`value`, `onChange`, `ref`) go on the <input>, and `className` on the bar. */
|
|
113
|
+
export function SearchBar({
|
|
114
|
+
label,
|
|
115
|
+
leadingIcon = 'magnifying-glass',
|
|
116
|
+
className,
|
|
117
|
+
...rest
|
|
118
|
+
}: { label: string; leadingIcon?: string; className?: string } & Record<string, unknown>) {
|
|
119
|
+
return (
|
|
120
|
+
<label className={['search-bar', className].filter(Boolean).join(' ')}>
|
|
121
|
+
<span className="search-bar-field">
|
|
122
|
+
<span className="search-bar-leading">
|
|
123
|
+
<Svg name={leadingIcon} size={24} />
|
|
124
|
+
</span>
|
|
125
|
+
<input type="search" className="search-bar-input" aria-label={label} placeholder={label} {...rest} />
|
|
126
|
+
</span>
|
|
127
|
+
</label>
|
|
128
|
+
);
|
|
129
|
+
}
|