@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/src/BlockParts.tsx
CHANGED
|
@@ -1,652 +1,652 @@
|
|
|
1
|
-
// "Dele" › "UI-komponenter" (#udseende/dele/ui), "Dele" › "Blokke" (#udseende/dele/blokke) and "Dele" › a list of kinds
|
|
2
|
-
// ("Promovering", #udseende/dele/liste/<id>): how the site looks, every part in every version, to see and agree on it.
|
|
3
|
-
// "UI-komponenter" has the theme's UI components (its buttons and icon buttons, text fields and checkboxes …,
|
|
4
|
-
// packages/editor/theme/ui/, through @site/editor) in every kind, size and state; "Blokke" every block, the standard
|
|
5
|
-
// ones (packages/editor/src/standard/), which every theme styles, and then the apps', each in its own group; a list of
|
|
6
|
-
// kinds each of its kinds as the site draws an entry of it, the list's own (the pop-up, the bars) and the apps' (a
|
|
7
|
-
// pop-up, once for each of its states), the kind a group. A block's versions are the
|
|
8
|
-
// options of its choices side by side (a field with `segments`: the designs of "Kort"), the first choice's all, each
|
|
9
|
-
// other's but the one a new block has (its default, else the empty one: the backgrounds of "Kort", with the first's empty
|
|
10
|
-
// option; the width of "Banner", as wide as the text). All of it is drawn with the
|
|
11
|
-
// made-up site of examples.ts, never the site's own, with the search, the order and the filter of "Editor"
|
|
12
|
-
// (PartsShown.tsx). Nothing here is saved.
|
|
13
|
-
import { useMemo } from 'react';
|
|
14
|
-
import Screen from './Screen';
|
|
15
|
-
import { Part, PartGroup, PartsShown } from './PartsShown';
|
|
16
|
-
import { Preview } from './ui';
|
|
17
|
-
import {
|
|
18
|
-
SiteButton,
|
|
19
|
-
SiteCard,
|
|
20
|
-
SiteCheckbox,
|
|
21
|
-
SiteChip,
|
|
22
|
-
SiteIconButton,
|
|
23
|
-
SiteList,
|
|
24
|
-
SiteListItem,
|
|
25
|
-
SiteTextField,
|
|
26
|
-
buttonShapes,
|
|
27
|
-
buttonSizes,
|
|
28
|
-
cardKinds,
|
|
29
|
-
chipKinds,
|
|
30
|
-
chipSetLayouts,
|
|
31
|
-
SiteChipSet,
|
|
32
|
-
iconButtonWidths,
|
|
33
|
-
} from './themeUi';
|
|
34
|
-
import ContainmentParts from './ContainmentParts';
|
|
35
|
-
import NavigationParts from './NavigationParts';
|
|
36
|
-
import ActionParts from './ActionParts';
|
|
37
|
-
import SelectionParts from './SelectionParts';
|
|
38
|
-
import CommunicationParts from './CommunicationParts';
|
|
39
|
-
import NavigationRestParts from './NavigationRestParts';
|
|
40
|
-
import PickerParts from './PickerParts';
|
|
41
|
-
import { exampleOf, type BlockData, type BlockProps, type SiteBlock } from './blocks';
|
|
42
|
-
import { apps, preview, siteBlocks, standardTypes } from './registry';
|
|
43
|
-
import { examplePicture, exampleData, kindExample } from './examples';
|
|
44
|
-
import type { Field, FolderCollection, PreviewVariant } from './schema';
|
|
45
|
-
import { buttonKinds, iconButtonKinds } from './standard/view';
|
|
46
|
-
import { kindDraw } from './apps';
|
|
47
|
-
import { collections } from './site';
|
|
48
|
-
import { t } from './i18n';
|
|
49
|
-
import { Svg } from './icon';
|
|
50
|
-
|
|
51
|
-
const { screens } = t.parts;
|
|
52
|
-
const back = { href: '#udseende/dele', label: t.common.parts.editorParts };
|
|
53
|
-
|
|
54
|
-
// The fields filled in with the plain picture where they have none (a card's, a list's items').
|
|
55
|
-
function pictured(fields: Field[], props: BlockProps): BlockProps {
|
|
56
|
-
const filled = { ...props };
|
|
57
|
-
for (const f of fields) {
|
|
58
|
-
const v = filled[f.name];
|
|
59
|
-
if (f.type === 'image' && !v) filled[f.name] = examplePicture;
|
|
60
|
-
else if (f.type === 'object' && f.fields) filled[f.name] = pictured(f.fields, (v ?? {}) as BlockProps);
|
|
61
|
-
else if (f.type === 'list' && f.fields && Array.isArray(v)) filled[f.name] = v.map((item) => pictured(f.fields!, item as BlockProps));
|
|
62
|
-
}
|
|
63
|
-
return filled;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// A block's versions: one for each option of its first choice side by side and for each other option of the others
|
|
67
|
-
// than the one a new block has, else only itself.
|
|
68
|
-
function versionsOf(block: SiteBlock): PreviewVariant[] {
|
|
69
|
-
const [first, ...rest] = block.fields.filter((f) => f.type === 'select' && f.segments && !f.only);
|
|
70
|
-
if (!first?.options) return [{ label: '', props: {} }];
|
|
71
|
-
return [
|
|
72
|
-
...first.options.map((o) => ({ label: o.label, props: { [first.name]: o.value } })),
|
|
73
|
-
...rest.flatMap((c) =>
|
|
74
|
-
(c.options ?? []).filter((o) => o.value !== String(c.default ?? '')).map((o) => ({ label: o.label, props: { [c.name]: o.value } })),
|
|
75
|
-
),
|
|
76
|
-
];
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
/** A block in each of its versions, filled in as an example, under its name (and the version's). */
|
|
80
|
-
function BlockShown({ block, data }: { block: SiteBlock; data: BlockData }) {
|
|
81
|
-
const example = exampleOf(block, data);
|
|
82
|
-
return versionsOf(block).map((v) => (
|
|
83
|
-
<Part key={v.label} name={v.label ? `${block.label} · ${v.label}` : block.label} use={block.hint}>
|
|
84
|
-
<Preview>{preview(block.type, pictured(block.fields, { ...example, ...v.props }), data)}</Preview>
|
|
85
|
-
</Part>
|
|
86
|
-
));
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** The theme's chips, as the site draws them: every kind, elevated on a picture, in every state (chosen, with an icon or
|
|
90
|
-
* a picture, with the button that removes it, dragged, only shown) and disabled. */
|
|
91
|
-
function ChipParts() {
|
|
92
|
-
const row = 'flex flex-wrap items-center gap-3';
|
|
93
|
-
const { input, filter, suggestion, assist } = screens.chipKinds;
|
|
94
|
-
return (
|
|
95
|
-
<Part name="Chip" use={screens.chip}>
|
|
96
|
-
<Preview>
|
|
97
|
-
<div className="space-y-4 p-4">
|
|
98
|
-
<div className={row}>
|
|
99
|
-
{chipKinds.map((k) => (
|
|
100
|
-
<SiteChip key={k} kind={k} label={screens.chipKinds[k]} />
|
|
101
|
-
))}
|
|
102
|
-
</div>
|
|
103
|
-
<div className={`${row} rounded-xl bg-cover bg-center p-4`} style={{ backgroundImage: `url("${examplePicture}")` }}>
|
|
104
|
-
<SiteChip elevated icon="calendar-blank" label={`${assist} · ${screens.elevated}`} />
|
|
105
|
-
<SiteChip elevated kind="filter" label={`${filter} · ${screens.elevated}`} />
|
|
106
|
-
<SiteChip elevated kind="filter" selected label={screens.selected} />
|
|
107
|
-
<SiteChip elevated kind="suggestion" label={`${suggestion} · ${screens.elevated}`} />
|
|
108
|
-
</div>
|
|
109
|
-
<div className={row}>
|
|
110
|
-
<SiteChip kind="filter" selected label={screens.selected} />
|
|
111
|
-
<SiteChip kind="filter" label={filter} />
|
|
112
|
-
<SiteChip kind="suggestion" selected label={`${suggestion} · ${screens.selected}`} />
|
|
113
|
-
<SiteChip icon="calendar-blank" label={screens.withIcon} />
|
|
114
|
-
<SiteChip kind="input" trailingIcon="x" label={input} />
|
|
115
|
-
<SiteChip kind="input" avatar={examplePicture} removeLabel={screens.remove(screens.withAvatar)} label={screens.withAvatar} />
|
|
116
|
-
<SiteChip kind="input" selected removeLabel={screens.remove(screens.selected)} label={screens.selected} />
|
|
117
|
-
<SiteChip kind="input" dragged avatar={examplePicture} label={screens.dragged} />
|
|
118
|
-
<SiteChip plain label={screens.plain} />
|
|
119
|
-
</div>
|
|
120
|
-
<div className={row}>
|
|
121
|
-
{chipKinds.map((k) => (
|
|
122
|
-
<SiteChip key={k} kind={k} disabled label={screens.disabled} />
|
|
123
|
-
))}
|
|
124
|
-
<SiteChip kind="input" disabled removeLabel={screens.remove(screens.disabled)} label={screens.disabled} />
|
|
125
|
-
<SiteChip elevated disabled label={`${screens.elevated} · ${screens.disabled}`} />
|
|
126
|
-
<SiteChip href="" disabled label={screens.disabled} />
|
|
127
|
-
</div>
|
|
128
|
-
</div>
|
|
129
|
-
</Preview>
|
|
130
|
-
</Part>
|
|
131
|
-
);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
/** The theme's chip sets, as the site draws them: each layout, with more chips than there is room for on one line. */
|
|
135
|
-
function ChipSetParts() {
|
|
136
|
-
return (
|
|
137
|
-
<Part name="ChipSet" use={screens.chipSet}>
|
|
138
|
-
<Preview>
|
|
139
|
-
<div className="max-w-sm space-y-4 p-4">
|
|
140
|
-
{chipSetLayouts.map((layout) => (
|
|
141
|
-
<SiteChipSet key={layout} layout={layout} label={screens.chipSetLayouts[layout]}>
|
|
142
|
-
{[...chipKinds, ...chipKinds].map((k, i) => (
|
|
143
|
-
<SiteChip key={i} kind="filter" selected={!i} label={`${screens.chipSetLayouts[layout]} ${i + 1}`} />
|
|
144
|
-
))}
|
|
145
|
-
</SiteChipSet>
|
|
146
|
-
))}
|
|
147
|
-
</div>
|
|
148
|
-
</Preview>
|
|
149
|
-
</Part>
|
|
150
|
-
);
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
// The standard blocks (not HTML, which has no look of its own).
|
|
154
|
-
const standardBlocks = siteBlocks.filter((b) => standardTypes.has(b.type));
|
|
155
|
-
|
|
156
|
-
// The kinds a toggle button can be (Material: never a text button).
|
|
157
|
-
const toggleKinds = buttonKinds.filter((k) => k !== 'text');
|
|
158
|
-
|
|
159
|
-
/** The theme's buttons and icon buttons, as the site draws them: every kind, the five sizes, both shapes, each kind
|
|
160
|
-
* that can be a toggle off and on in both shapes, the icon buttons' widths, with an icon, and disabled. */
|
|
161
|
-
function ButtonParts() {
|
|
162
|
-
const row = 'flex flex-wrap items-center gap-3';
|
|
163
|
-
const kinds = t.blocks.buttons.kinds;
|
|
164
|
-
return (
|
|
165
|
-
<>
|
|
166
|
-
<Part name="Button" use={screens.button}>
|
|
167
|
-
<Preview>
|
|
168
|
-
<div className="space-y-4 p-4">
|
|
169
|
-
<div className={row}>
|
|
170
|
-
{buttonKinds.map((k) => (
|
|
171
|
-
<SiteButton key={k} kind={k}>
|
|
172
|
-
{kinds[k]}
|
|
173
|
-
</SiteButton>
|
|
174
|
-
))}
|
|
175
|
-
</div>
|
|
176
|
-
<div className={row}>
|
|
177
|
-
{buttonSizes.map((size) => (
|
|
178
|
-
<SiteButton key={size} size={size}>
|
|
179
|
-
{screens.sizes[size]}
|
|
180
|
-
</SiteButton>
|
|
181
|
-
))}
|
|
182
|
-
</div>
|
|
183
|
-
<div className={row}>
|
|
184
|
-
{buttonSizes.map((size) => (
|
|
185
|
-
<SiteButton key={size} size={size} shape="square" kind="tonal">
|
|
186
|
-
{screens.sizes[size]}
|
|
187
|
-
</SiteButton>
|
|
188
|
-
))}
|
|
189
|
-
</div>
|
|
190
|
-
{buttonShapes.map((shape) => (
|
|
191
|
-
<div key={shape} className={row} role="group" aria-label={screens.shapes[shape]}>
|
|
192
|
-
{toggleKinds.map((k) =>
|
|
193
|
-
([false, true] as const).map((on) => (
|
|
194
|
-
<SiteButton key={`${k}-${on}`} kind={k} shape={shape} selected={on} icon="heart">
|
|
195
|
-
{on ? screens.toggle.on : screens.toggle.off}
|
|
196
|
-
</SiteButton>
|
|
197
|
-
)),
|
|
198
|
-
)}
|
|
199
|
-
</div>
|
|
200
|
-
))}
|
|
201
|
-
<div className={row}>
|
|
202
|
-
<SiteButton icon="phone">{screens.withIcon}</SiteButton>
|
|
203
|
-
<SiteButton kind="outlined" trailingIcon="arrow-right">
|
|
204
|
-
{screens.withIcon}
|
|
205
|
-
</SiteButton>
|
|
206
|
-
{buttonKinds.map((k) => (
|
|
207
|
-
<SiteButton key={k} kind={k} disabled>
|
|
208
|
-
{screens.disabled}
|
|
209
|
-
</SiteButton>
|
|
210
|
-
))}
|
|
211
|
-
<SiteButton selected disabled>
|
|
212
|
-
{screens.disabled}
|
|
213
|
-
</SiteButton>
|
|
214
|
-
</div>
|
|
215
|
-
</div>
|
|
216
|
-
</Preview>
|
|
217
|
-
</Part>
|
|
218
|
-
<Part name="IconButton" use={screens.iconButton}>
|
|
219
|
-
<Preview>
|
|
220
|
-
<div className="space-y-4 p-4">
|
|
221
|
-
<div className={row}>
|
|
222
|
-
{iconButtonKinds.map((k) => (
|
|
223
|
-
<SiteIconButton key={k} kind={k} icon="x" label={screens.iconKinds[k]} title={screens.iconKinds[k]} />
|
|
224
|
-
))}
|
|
225
|
-
</div>
|
|
226
|
-
<div className={row}>
|
|
227
|
-
{buttonSizes.map((size) => (
|
|
228
|
-
<SiteIconButton key={size} kind="filled" size={size} icon="phone" label={screens.sizes[size]} title={screens.sizes[size]} />
|
|
229
|
-
))}
|
|
230
|
-
</div>
|
|
231
|
-
<div className={row}>
|
|
232
|
-
{buttonSizes.map((size) => (
|
|
233
|
-
<SiteIconButton
|
|
234
|
-
key={size}
|
|
235
|
-
kind="tonal"
|
|
236
|
-
size={size}
|
|
237
|
-
shape="square"
|
|
238
|
-
icon="phone"
|
|
239
|
-
label={`${screens.sizes[size]}, ${screens.shapes.square}`}
|
|
240
|
-
title={`${screens.sizes[size]}, ${screens.shapes.square}`}
|
|
241
|
-
/>
|
|
242
|
-
))}
|
|
243
|
-
</div>
|
|
244
|
-
<div className={row}>
|
|
245
|
-
{(['small', 'medium'] as const).flatMap((size) =>
|
|
246
|
-
iconButtonWidths.map((width) => (
|
|
247
|
-
<SiteIconButton
|
|
248
|
-
key={`${size}-${width}`}
|
|
249
|
-
kind="outlined"
|
|
250
|
-
size={size}
|
|
251
|
-
width={width}
|
|
252
|
-
icon="phone"
|
|
253
|
-
label={`${screens.sizes[size]}, ${screens.widths[width]}`}
|
|
254
|
-
title={`${screens.sizes[size]}, ${screens.widths[width]}`}
|
|
255
|
-
/>
|
|
256
|
-
)),
|
|
257
|
-
)}
|
|
258
|
-
</div>
|
|
259
|
-
{buttonShapes.map((shape) => (
|
|
260
|
-
<div key={shape} className={row} role="group" aria-label={screens.shapes[shape]}>
|
|
261
|
-
{iconButtonKinds.map((k) =>
|
|
262
|
-
([false, true] as const).map((on) => (
|
|
263
|
-
<SiteIconButton
|
|
264
|
-
key={`${k}-${on}`}
|
|
265
|
-
kind={k}
|
|
266
|
-
shape={shape}
|
|
267
|
-
selected={on}
|
|
268
|
-
icon="heart"
|
|
269
|
-
label={`${screens.iconKinds[k]}, ${on ? screens.toggle.on : screens.toggle.off}`}
|
|
270
|
-
title={`${screens.iconKinds[k]}, ${on ? screens.toggle.on : screens.toggle.off}`}
|
|
271
|
-
/>
|
|
272
|
-
)),
|
|
273
|
-
)}
|
|
274
|
-
</div>
|
|
275
|
-
))}
|
|
276
|
-
<div className={row}>
|
|
277
|
-
{iconButtonKinds.map((k) => (
|
|
278
|
-
<SiteIconButton key={k} kind={k} icon="phone" label={screens.disabled} disabled />
|
|
279
|
-
))}
|
|
280
|
-
<SiteIconButton kind="filled" icon="phone" label={screens.disabled} selected disabled />
|
|
281
|
-
</div>
|
|
282
|
-
</div>
|
|
283
|
-
</Preview>
|
|
284
|
-
</Part>
|
|
285
|
-
</>
|
|
286
|
-
);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
/** The theme's form controls, as the site draws them: each kind of text field empty, filled in, with a line under it,
|
|
290
|
-
* with an error, with only a placeholder and disabled, with an icon before it, a search field with its clear button, a
|
|
291
|
-
* prefix and a suffix, the error's icon, a password with its button, a counter, read-only, and several lines (growing,
|
|
292
|
-
* and three rows); and a checkbox empty, ticked, with a line, disabled, indeterminate and wrong. */
|
|
293
|
-
function FieldParts() {
|
|
294
|
-
const fields = 'grid gap-6 sm:grid-cols-2';
|
|
295
|
-
return (
|
|
296
|
-
<>
|
|
297
|
-
<Part name="TextField" use={screens.textField}>
|
|
298
|
-
<Preview>
|
|
299
|
-
<div className="space-y-6 p-4">
|
|
300
|
-
{(['outlined', 'filled'] as const).map((kind) => (
|
|
301
|
-
<div key={kind} className={fields} aria-label={screens.fieldKinds[kind]} role="group">
|
|
302
|
-
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" />
|
|
303
|
-
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" defaultValue={screens.fieldValue} />
|
|
304
|
-
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" supporting={screens.fieldSupporting} />
|
|
305
|
-
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" defaultValue="navn@" error={screens.fieldError} />
|
|
306
|
-
<SiteTextField kind={kind} label={screens.fieldLabel} hideLabel type="email" placeholder={screens.fieldPlaceholder} />
|
|
307
|
-
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" disabled />
|
|
308
|
-
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" leadingIcon="envelope-simple" />
|
|
309
|
-
<SiteTextField
|
|
310
|
-
kind={kind}
|
|
311
|
-
label={screens.fieldSearch}
|
|
312
|
-
hideLabel
|
|
313
|
-
type="search"
|
|
314
|
-
placeholder={screens.fieldSearch}
|
|
315
|
-
leadingIcon="magnifying-glass"
|
|
316
|
-
clearLabel={screens.fieldClear}
|
|
317
|
-
defaultValue={screens.fieldNote}
|
|
318
|
-
/>
|
|
319
|
-
<SiteTextField kind={kind} label={screens.fieldPhone} type="tel" prefix={screens.fieldPrefix} defaultValue="12 34 56 78" />
|
|
320
|
-
<SiteTextField kind={kind} label={screens.fieldPrice} inputMode="numeric" suffix={screens.fieldSuffix} defaultValue="450" />
|
|
321
|
-
<SiteTextField
|
|
322
|
-
kind={kind}
|
|
323
|
-
label={screens.fieldLabel}
|
|
324
|
-
type="email"
|
|
325
|
-
defaultValue="navn@"
|
|
326
|
-
error={screens.fieldError}
|
|
327
|
-
leadingIcon="envelope-simple"
|
|
328
|
-
errorIcon
|
|
329
|
-
/>
|
|
330
|
-
<SiteTextField
|
|
331
|
-
kind={kind}
|
|
332
|
-
label={screens.fieldPassword}
|
|
333
|
-
type="password"
|
|
334
|
-
defaultValue={screens.fieldPasswordValue}
|
|
335
|
-
passwordLabel={screens.fieldShowPassword}
|
|
336
|
-
/>
|
|
337
|
-
<SiteTextField
|
|
338
|
-
kind={kind}
|
|
339
|
-
label={screens.fieldName}
|
|
340
|
-
supporting={screens.fieldNameSupporting}
|
|
341
|
-
counter
|
|
342
|
-
maxLength={30}
|
|
343
|
-
defaultValue={screens.fieldValue}
|
|
344
|
-
/>
|
|
345
|
-
<SiteTextField kind={kind} label={screens.fieldReadOnly} readOnly defaultValue={screens.fieldReadOnlyValue} />
|
|
346
|
-
<SiteTextField kind={kind} label={screens.fieldMessage} multiline defaultValue={screens.fieldMessageValue} />
|
|
347
|
-
<SiteTextField kind={kind} label={screens.fieldNote} rows={3} counter maxLength={200} />
|
|
348
|
-
</div>
|
|
349
|
-
))}
|
|
350
|
-
</div>
|
|
351
|
-
</Preview>
|
|
352
|
-
</Part>
|
|
353
|
-
<Part name="Checkbox" use={screens.checkbox}>
|
|
354
|
-
<Preview>
|
|
355
|
-
<div className={`${fields} p-4`}>
|
|
356
|
-
<SiteCheckbox label={screens.checkboxLabel} />
|
|
357
|
-
<SiteCheckbox label={screens.checkboxLabel} checked />
|
|
358
|
-
<SiteCheckbox label={screens.checkboxLabel} supporting={screens.checkboxSupporting} />
|
|
359
|
-
<SiteCheckbox label={screens.checkboxLabel} supporting={screens.checkboxSupporting} checked disabled />
|
|
360
|
-
<SiteCheckbox label={screens.checkboxParent} supporting={screens.checkboxSupporting} indeterminate />
|
|
361
|
-
<SiteCheckbox label={screens.checkboxParent} indeterminate disabled />
|
|
362
|
-
<SiteCheckbox label={screens.checkboxLabel} error={screens.checkboxError} />
|
|
363
|
-
<SiteCheckbox label={screens.checkboxLabel} error checked />
|
|
364
|
-
</div>
|
|
365
|
-
</Preview>
|
|
366
|
-
</Part>
|
|
367
|
-
</>
|
|
368
|
-
);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
/** The theme's cards in each kind, one a link, and lists: one line, a link and an icon with a text under it; one, two
|
|
372
|
-
* and three lines; each leading kind; the choices; selected and disabled; each kind of dividers; and segmented. */
|
|
373
|
-
function CardParts() {
|
|
374
|
-
const say = screens.cardsAndLists;
|
|
375
|
-
const [one, link, withIcon] = say.items;
|
|
376
|
-
const lists = say.lists;
|
|
377
|
-
const [icon, avatar, avatarPicture, image, video] = lists.headlines;
|
|
378
|
-
const [checkbox, radio, switchItem, after] = lists.choices;
|
|
379
|
-
return (
|
|
380
|
-
<>
|
|
381
|
-
<Part name="Card" use={say.card}>
|
|
382
|
-
<Preview>
|
|
383
|
-
<div className="grid gap-4 p-4 sm:grid-cols-2">
|
|
384
|
-
{cardKinds.map((k) => (
|
|
385
|
-
<SiteCard key={k} kind={k}>
|
|
386
|
-
<p className="font-medium">{say.kinds[k]}</p>
|
|
387
|
-
<p className="mt-1 text-muted">{say.text}</p>
|
|
388
|
-
</SiteCard>
|
|
389
|
-
))}
|
|
390
|
-
<SiteCard href="">
|
|
391
|
-
<p className="font-medium">{say.link}</p>
|
|
392
|
-
<p className="mt-1 text-muted">{say.text}</p>
|
|
393
|
-
</SiteCard>
|
|
394
|
-
{cardKinds.map((k) => (
|
|
395
|
-
<SiteCard key={k} kind={k} dragged>
|
|
396
|
-
<p className="font-medium">{`${say.kinds[k]} · ${screens.dragged}`}</p>
|
|
397
|
-
<p className="mt-1 text-muted">{say.text}</p>
|
|
398
|
-
</SiteCard>
|
|
399
|
-
))}
|
|
400
|
-
</div>
|
|
401
|
-
</Preview>
|
|
402
|
-
</Part>
|
|
403
|
-
<Part name="List" use={say.list}>
|
|
404
|
-
<Preview>
|
|
405
|
-
<div className="grid items-start gap-4 p-4 lg:grid-cols-2">
|
|
406
|
-
<SiteCard>
|
|
407
|
-
<SiteList>
|
|
408
|
-
<SiteListItem headline={one} />
|
|
409
|
-
<SiteListItem href="" headline={link} trailing={<Svg name="arrow-right" size={18} />} />
|
|
410
|
-
<SiteListItem
|
|
411
|
-
href=""
|
|
412
|
-
leading={<Svg name="phone" size={24} />}
|
|
413
|
-
headline={withIcon}
|
|
414
|
-
supporting={say.supporting}
|
|
415
|
-
trailing={<Svg name="caret-right" size={20} />}
|
|
416
|
-
/>
|
|
417
|
-
</SiteList>
|
|
418
|
-
</SiteCard>
|
|
419
|
-
<SiteCard>
|
|
420
|
-
<SiteList aria-label={lists.lines}>
|
|
421
|
-
<SiteListItem href="" headline={one} trailingSupporting={lists.trailing} />
|
|
422
|
-
<SiteListItem href="" headline={one} supporting={say.supporting} trailingIcon="caret-right" />
|
|
423
|
-
<SiteListItem href="" overline={lists.overline} headline={one} supporting={say.supporting} trailingIcon="caret-right" />
|
|
424
|
-
<SiteListItem
|
|
425
|
-
href=""
|
|
426
|
-
lines={3}
|
|
427
|
-
leadingIcon="calendar-blank"
|
|
428
|
-
headline={one}
|
|
429
|
-
supporting={lists.long}
|
|
430
|
-
trailingSupporting={lists.trailing}
|
|
431
|
-
/>
|
|
432
|
-
</SiteList>
|
|
433
|
-
</SiteCard>
|
|
434
|
-
<SiteCard>
|
|
435
|
-
<SiteList dividers="inset" aria-label={lists.leading}>
|
|
436
|
-
<SiteListItem href="" leadingIcon="phone" headline={icon} supporting={say.supporting} trailingIcon="caret-right" />
|
|
437
|
-
<SiteListItem
|
|
438
|
-
href=""
|
|
439
|
-
leadingAvatar={lists.letter}
|
|
440
|
-
headline={avatar}
|
|
441
|
-
supporting={say.supporting}
|
|
442
|
-
trailingSupporting={lists.trailing}
|
|
443
|
-
/>
|
|
444
|
-
<SiteListItem href="" leadingAvatar={{ src: examplePicture }} headline={avatarPicture} supporting={say.supporting} />
|
|
445
|
-
<SiteListItem href="" leadingImage={{ src: examplePicture }} headline={image} supporting={say.supporting} />
|
|
446
|
-
<SiteListItem href="" leadingVideo={{ src: examplePicture }} lines={3} headline={video} supporting={lists.long} />
|
|
447
|
-
</SiteList>
|
|
448
|
-
</SiteCard>
|
|
449
|
-
<SiteCard>
|
|
450
|
-
<SiteList aria-label={lists.controls}>
|
|
451
|
-
<SiteListItem control={{ type: 'checkbox', checked: true }} headline={checkbox} supporting={say.supporting} />
|
|
452
|
-
<SiteListItem control={{ type: 'radio-button', name: 'parts-list-radio', checked: true }} headline={radio} />
|
|
453
|
-
<SiteListItem control={{ type: 'radio-button', name: 'parts-list-radio' }} headline={radio} />
|
|
454
|
-
<SiteListItem control={{ type: 'switch', checked: true, icons: 'selected' }} leadingIcon="moon" headline={switchItem} />
|
|
455
|
-
<SiteListItem control={{ type: 'checkbox', at: 'trailing' }} leadingAvatar={lists.letter} headline={after} />
|
|
456
|
-
</SiteList>
|
|
457
|
-
</SiteCard>
|
|
458
|
-
<SiteCard>
|
|
459
|
-
<SiteList aria-label={lists.states}>
|
|
460
|
-
<SiteListItem href="" selected leadingIcon="house" headline={lists.selected} supporting={say.supporting} />
|
|
461
|
-
<SiteListItem href="" disabled leadingIcon="house" headline={lists.disabled} supporting={say.supporting} />
|
|
462
|
-
<SiteListItem control={{ type: 'switch' }} disabled headline={lists.disabled} />
|
|
463
|
-
</SiteList>
|
|
464
|
-
</SiteCard>
|
|
465
|
-
<SiteCard>
|
|
466
|
-
<SiteList aria-label={lists.more}>
|
|
467
|
-
<SiteListItem
|
|
468
|
-
onClick={() => {}}
|
|
469
|
-
leadingIcon="pencil-simple"
|
|
470
|
-
headline={lists.tapped}
|
|
471
|
-
supporting={say.supporting}
|
|
472
|
-
trailingIcon="caret-right"
|
|
473
|
-
/>
|
|
474
|
-
<SiteListItem
|
|
475
|
-
href=""
|
|
476
|
-
headline={lists.withActions}
|
|
477
|
-
supporting={lists.long}
|
|
478
|
-
truncate
|
|
479
|
-
actions={<SiteIconButton icon="trash" label={lists.remove} />}
|
|
480
|
-
/>
|
|
481
|
-
<SiteListItem href="" headline={lists.address} supporting={lists.sendsTo} columns />
|
|
482
|
-
</SiteList>
|
|
483
|
-
</SiteCard>
|
|
484
|
-
{(['middle-inset', 'none'] as const).map((dividers) => (
|
|
485
|
-
<SiteCard key={dividers}>
|
|
486
|
-
<SiteList dividers={dividers} aria-label={lists.dividers[dividers]}>
|
|
487
|
-
{[icon, avatar, image].map((h) => (
|
|
488
|
-
<SiteListItem
|
|
489
|
-
key={h}
|
|
490
|
-
href=""
|
|
491
|
-
leadingIcon="phone"
|
|
492
|
-
headline={`${lists.dividers[dividers]} · ${h}`}
|
|
493
|
-
trailingIcon="caret-right"
|
|
494
|
-
/>
|
|
495
|
-
))}
|
|
496
|
-
</SiteList>
|
|
497
|
-
</SiteCard>
|
|
498
|
-
))}
|
|
499
|
-
<SiteList kind="segmented" aria-label={lists.segmented}>
|
|
500
|
-
<SiteListItem href="" leadingIcon="phone" headline={lists.segmented} supporting={say.supporting} trailingIcon="caret-right" />
|
|
501
|
-
<SiteListItem
|
|
502
|
-
href=""
|
|
503
|
-
selected
|
|
504
|
-
leadingIcon="envelope-simple"
|
|
505
|
-
headline={lists.selected}
|
|
506
|
-
supporting={say.supporting}
|
|
507
|
-
trailingIcon="caret-right"
|
|
508
|
-
/>
|
|
509
|
-
<SiteListItem control={{ type: 'checkbox', checked: true }} headline={checkbox} />
|
|
510
|
-
<SiteListItem control={{ type: 'switch' }} leadingIcon="moon" headline={switchItem} />
|
|
511
|
-
<SiteListItem href="" disabled leadingIcon="map-pin" headline={lists.disabled} />
|
|
512
|
-
</SiteList>
|
|
513
|
-
</div>
|
|
514
|
-
</Preview>
|
|
515
|
-
</Part>
|
|
516
|
-
</>
|
|
517
|
-
);
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
/** "Dele" › "UI-komponenter" (#udseende/dele/ui): the theme's UI components in every kind, size and state. */
|
|
521
|
-
export function ComponentParts() {
|
|
522
|
-
const groups = [
|
|
523
|
-
{ id: 'ui', title: screens.ui },
|
|
524
|
-
{ id: 'fields', title: screens.fields },
|
|
525
|
-
{ id: 'chips', title: screens.chips },
|
|
526
|
-
{ id: 'containment', title: screens.containment.title },
|
|
527
|
-
{ id: 'cards', title: screens.cardsAndLists.title },
|
|
528
|
-
{ id: 'navigation', title: screens.navigation.title },
|
|
529
|
-
{ id: 'actions', title: screens.actions.title },
|
|
530
|
-
{ id: 'selection', title: screens.selection.title },
|
|
531
|
-
{ id: 'communication', title: screens.communication.title },
|
|
532
|
-
{ id: 'navigationRest', title: screens.navigationRest.title },
|
|
533
|
-
{ id: 'pickers', title: screens.pickers.title },
|
|
534
|
-
];
|
|
535
|
-
return (
|
|
536
|
-
<Screen title={screens.components} back={back}>
|
|
537
|
-
<div className="space-y-10">
|
|
538
|
-
<p className="text-muted">{screens.componentsIntro}</p>
|
|
539
|
-
<PartsShown groups={groups} keep="parts-components" search={screens.search} none={screens.none}>
|
|
540
|
-
<PartGroup group="ui">
|
|
541
|
-
<ButtonParts />
|
|
542
|
-
</PartGroup>
|
|
543
|
-
<PartGroup group="fields">
|
|
544
|
-
<FieldParts />
|
|
545
|
-
</PartGroup>
|
|
546
|
-
<PartGroup group="chips">
|
|
547
|
-
<ChipParts />
|
|
548
|
-
<ChipSetParts />
|
|
549
|
-
</PartGroup>
|
|
550
|
-
<PartGroup group="containment">
|
|
551
|
-
<ContainmentParts />
|
|
552
|
-
</PartGroup>
|
|
553
|
-
<PartGroup group="cards">
|
|
554
|
-
<CardParts />
|
|
555
|
-
</PartGroup>
|
|
556
|
-
<PartGroup group="navigation">
|
|
557
|
-
<NavigationParts />
|
|
558
|
-
</PartGroup>
|
|
559
|
-
<PartGroup group="actions">
|
|
560
|
-
<ActionParts />
|
|
561
|
-
</PartGroup>
|
|
562
|
-
<PartGroup group="selection">
|
|
563
|
-
<SelectionParts />
|
|
564
|
-
</PartGroup>
|
|
565
|
-
<PartGroup group="communication">
|
|
566
|
-
<CommunicationParts />
|
|
567
|
-
</PartGroup>
|
|
568
|
-
<PartGroup group="navigationRest">
|
|
569
|
-
<NavigationRestParts />
|
|
570
|
-
</PartGroup>
|
|
571
|
-
<PartGroup group="pickers">
|
|
572
|
-
<PickerParts />
|
|
573
|
-
</PartGroup>
|
|
574
|
-
</PartsShown>
|
|
575
|
-
</div>
|
|
576
|
-
</Screen>
|
|
577
|
-
);
|
|
578
|
-
}
|
|
579
|
-
|
|
580
|
-
/** "Dele" › "Blokke" (#udseende/dele/blokke): every block, the standard ones and then the apps', each a group of its
|
|
581
|
-
* own, in all its versions. */
|
|
582
|
-
export function BlocksParts() {
|
|
583
|
-
const data = useMemo(exampleData, []);
|
|
584
|
-
const blocks = [...standardBlocks, ...apps.flatMap((app) => siteBlocks.filter((b) => b.app === app.id))];
|
|
585
|
-
return (
|
|
586
|
-
<Screen title={screens.blocks} back={back}>
|
|
587
|
-
<div className="space-y-10">
|
|
588
|
-
<p className="text-muted">{screens.blocksIntro}</p>
|
|
589
|
-
<PartsShown
|
|
590
|
-
groups={blocks.map((b) => ({ id: b.type, title: b.label }))}
|
|
591
|
-
keep="parts-blocks"
|
|
592
|
-
search={screens.search}
|
|
593
|
-
none={screens.none}
|
|
594
|
-
>
|
|
595
|
-
{blocks.map((b) => (
|
|
596
|
-
<PartGroup key={b.type} group={b.type}>
|
|
597
|
-
<BlockShown block={b} data={data} />
|
|
598
|
-
</PartGroup>
|
|
599
|
-
))}
|
|
600
|
-
</PartsShown>
|
|
601
|
-
</div>
|
|
602
|
-
</Screen>
|
|
603
|
-
);
|
|
604
|
-
}
|
|
605
|
-
|
|
606
|
-
/** The lists of kinds ("Promovering"), each a screen of "Dele". */
|
|
607
|
-
export const kindLists = () => collections.filter((c): c is FolderCollection => c.kind === 'folder' && !!c.kinds && !!c.fields?.length);
|
|
608
|
-
|
|
609
|
-
/** "Dele" › a list of kinds ("Promovering", #udseende/dele/liste/<id>): each of its kinds as the site draws it, its own
|
|
610
|
-
* (FolderCollection.draws: the pop-up, the bars) and the apps' (AppKind: Mailchimp's signup, once for each of its
|
|
611
|
-
* states), each a group of its own, as a new one of the kind with the made-up texts (kindExample). */
|
|
612
|
-
export function KindParts({ id }: { id: string }) {
|
|
613
|
-
const data = useMemo(exampleData, []);
|
|
614
|
-
const list = kindLists().find((c) => c.id === id);
|
|
615
|
-
const kindField = list?.fields.find((f) => f.name === list.kinds);
|
|
616
|
-
if (!list || !kindField) return null;
|
|
617
|
-
const own = (kindField.options ?? []).flatMap((o) => {
|
|
618
|
-
const draw = list.draws?.[o.value];
|
|
619
|
-
return draw ? [{ id: o.value, label: o.label, hint: o.hint, variants: [{ label: '', props: {} }], draw }] : [];
|
|
620
|
-
});
|
|
621
|
-
const added = apps.flatMap((app) => {
|
|
622
|
-
const kind = app.kinds?.[list.id];
|
|
623
|
-
const draw = kind && kindDraw(kind, list);
|
|
624
|
-
return kind && draw
|
|
625
|
-
? [{ id: app.id, label: kind.label, hint: kind.hint, variants: kind.variants ?? [{ label: '', props: {} }], draw }]
|
|
626
|
-
: [];
|
|
627
|
-
});
|
|
628
|
-
const kinds = [...own, ...added];
|
|
629
|
-
return (
|
|
630
|
-
<Screen title={list.label} back={back}>
|
|
631
|
-
<div className="space-y-10">
|
|
632
|
-
<p className="text-muted">{screens.kindsIntro(list.singular)}</p>
|
|
633
|
-
<PartsShown
|
|
634
|
-
groups={kinds.map((k) => ({ id: k.id, title: k.label }))}
|
|
635
|
-
keep={`parts-list-${list.id}`}
|
|
636
|
-
search={screens.search}
|
|
637
|
-
none={screens.none}
|
|
638
|
-
>
|
|
639
|
-
{kinds.map((k) => (
|
|
640
|
-
<PartGroup key={k.id} group={k.id}>
|
|
641
|
-
{k.variants.map((v) => (
|
|
642
|
-
<Part key={v.label} name={v.label ? `${k.label} · ${v.label}` : k.label} use={k.hint}>
|
|
643
|
-
<Preview>{k.draw({ ...kindExample(list, k.id), ...v.props }, data)}</Preview>
|
|
644
|
-
</Part>
|
|
645
|
-
))}
|
|
646
|
-
</PartGroup>
|
|
647
|
-
))}
|
|
648
|
-
</PartsShown>
|
|
649
|
-
</div>
|
|
650
|
-
</Screen>
|
|
651
|
-
);
|
|
652
|
-
}
|
|
1
|
+
// "Dele" › "UI-komponenter" (#udseende/dele/ui), "Dele" › "Blokke" (#udseende/dele/blokke) and "Dele" › a list of kinds
|
|
2
|
+
// ("Promovering", #udseende/dele/liste/<id>): how the site looks, every part in every version, to see and agree on it.
|
|
3
|
+
// "UI-komponenter" has the theme's UI components (its buttons and icon buttons, text fields and checkboxes …,
|
|
4
|
+
// packages/editor/theme/ui/, through @site/editor) in every kind, size and state; "Blokke" every block, the standard
|
|
5
|
+
// ones (packages/editor/src/standard/), which every theme styles, and then the apps', each in its own group; a list of
|
|
6
|
+
// kinds each of its kinds as the site draws an entry of it, the list's own (the pop-up, the bars) and the apps' (a
|
|
7
|
+
// pop-up, once for each of its states), the kind a group. A block's versions are the
|
|
8
|
+
// options of its choices side by side (a field with `segments`: the designs of "Kort"), the first choice's all, each
|
|
9
|
+
// other's but the one a new block has (its default, else the empty one: the backgrounds of "Kort", with the first's empty
|
|
10
|
+
// option; the width of "Banner", as wide as the text). All of it is drawn with the
|
|
11
|
+
// made-up site of examples.ts, never the site's own, with the search, the order and the filter of "Editor"
|
|
12
|
+
// (PartsShown.tsx). Nothing here is saved.
|
|
13
|
+
import { useMemo } from 'react';
|
|
14
|
+
import Screen from './Screen';
|
|
15
|
+
import { Part, PartGroup, PartsShown } from './PartsShown';
|
|
16
|
+
import { Preview } from './ui';
|
|
17
|
+
import {
|
|
18
|
+
SiteButton,
|
|
19
|
+
SiteCard,
|
|
20
|
+
SiteCheckbox,
|
|
21
|
+
SiteChip,
|
|
22
|
+
SiteIconButton,
|
|
23
|
+
SiteList,
|
|
24
|
+
SiteListItem,
|
|
25
|
+
SiteTextField,
|
|
26
|
+
buttonShapes,
|
|
27
|
+
buttonSizes,
|
|
28
|
+
cardKinds,
|
|
29
|
+
chipKinds,
|
|
30
|
+
chipSetLayouts,
|
|
31
|
+
SiteChipSet,
|
|
32
|
+
iconButtonWidths,
|
|
33
|
+
} from './themeUi';
|
|
34
|
+
import ContainmentParts from './ContainmentParts';
|
|
35
|
+
import NavigationParts from './NavigationParts';
|
|
36
|
+
import ActionParts from './ActionParts';
|
|
37
|
+
import SelectionParts from './SelectionParts';
|
|
38
|
+
import CommunicationParts from './CommunicationParts';
|
|
39
|
+
import NavigationRestParts from './NavigationRestParts';
|
|
40
|
+
import PickerParts from './PickerParts';
|
|
41
|
+
import { exampleOf, type BlockData, type BlockProps, type SiteBlock } from './blocks';
|
|
42
|
+
import { apps, preview, siteBlocks, standardTypes } from './registry';
|
|
43
|
+
import { examplePicture, exampleData, kindExample } from './examples';
|
|
44
|
+
import type { Field, FolderCollection, PreviewVariant } from './schema';
|
|
45
|
+
import { buttonKinds, iconButtonKinds } from './standard/view';
|
|
46
|
+
import { kindDraw } from './apps';
|
|
47
|
+
import { collections } from './site';
|
|
48
|
+
import { t } from './i18n';
|
|
49
|
+
import { Svg } from './icon';
|
|
50
|
+
|
|
51
|
+
const { screens } = t.parts;
|
|
52
|
+
const back = { href: '#udseende/dele', label: t.common.parts.editorParts };
|
|
53
|
+
|
|
54
|
+
// The fields filled in with the plain picture where they have none (a card's, a list's items').
|
|
55
|
+
function pictured(fields: Field[], props: BlockProps): BlockProps {
|
|
56
|
+
const filled = { ...props };
|
|
57
|
+
for (const f of fields) {
|
|
58
|
+
const v = filled[f.name];
|
|
59
|
+
if (f.type === 'image' && !v) filled[f.name] = examplePicture;
|
|
60
|
+
else if (f.type === 'object' && f.fields) filled[f.name] = pictured(f.fields, (v ?? {}) as BlockProps);
|
|
61
|
+
else if (f.type === 'list' && f.fields && Array.isArray(v)) filled[f.name] = v.map((item) => pictured(f.fields!, item as BlockProps));
|
|
62
|
+
}
|
|
63
|
+
return filled;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// A block's versions: one for each option of its first choice side by side and for each other option of the others
|
|
67
|
+
// than the one a new block has, else only itself.
|
|
68
|
+
function versionsOf(block: SiteBlock): PreviewVariant[] {
|
|
69
|
+
const [first, ...rest] = block.fields.filter((f) => f.type === 'select' && f.segments && !f.only);
|
|
70
|
+
if (!first?.options) return [{ label: '', props: {} }];
|
|
71
|
+
return [
|
|
72
|
+
...first.options.map((o) => ({ label: o.label, props: { [first.name]: o.value } })),
|
|
73
|
+
...rest.flatMap((c) =>
|
|
74
|
+
(c.options ?? []).filter((o) => o.value !== String(c.default ?? '')).map((o) => ({ label: o.label, props: { [c.name]: o.value } })),
|
|
75
|
+
),
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** A block in each of its versions, filled in as an example, under its name (and the version's). */
|
|
80
|
+
function BlockShown({ block, data }: { block: SiteBlock; data: BlockData }) {
|
|
81
|
+
const example = exampleOf(block, data);
|
|
82
|
+
return versionsOf(block).map((v) => (
|
|
83
|
+
<Part key={v.label} name={v.label ? `${block.label} · ${v.label}` : block.label} use={block.hint}>
|
|
84
|
+
<Preview>{preview(block.type, pictured(block.fields, { ...example, ...v.props }), data)}</Preview>
|
|
85
|
+
</Part>
|
|
86
|
+
));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/** The theme's chips, as the site draws them: every kind, elevated on a picture, in every state (chosen, with an icon or
|
|
90
|
+
* a picture, with the button that removes it, dragged, only shown) and disabled. */
|
|
91
|
+
function ChipParts() {
|
|
92
|
+
const row = 'flex flex-wrap items-center gap-3';
|
|
93
|
+
const { input, filter, suggestion, assist } = screens.chipKinds;
|
|
94
|
+
return (
|
|
95
|
+
<Part name="Chip" use={screens.chip}>
|
|
96
|
+
<Preview>
|
|
97
|
+
<div className="space-y-4 p-4">
|
|
98
|
+
<div className={row}>
|
|
99
|
+
{chipKinds.map((k) => (
|
|
100
|
+
<SiteChip key={k} kind={k} label={screens.chipKinds[k]} />
|
|
101
|
+
))}
|
|
102
|
+
</div>
|
|
103
|
+
<div className={`${row} rounded-xl bg-cover bg-center p-4`} style={{ backgroundImage: `url("${examplePicture}")` }}>
|
|
104
|
+
<SiteChip elevated icon="calendar-blank" label={`${assist} · ${screens.elevated}`} />
|
|
105
|
+
<SiteChip elevated kind="filter" label={`${filter} · ${screens.elevated}`} />
|
|
106
|
+
<SiteChip elevated kind="filter" selected label={screens.selected} />
|
|
107
|
+
<SiteChip elevated kind="suggestion" label={`${suggestion} · ${screens.elevated}`} />
|
|
108
|
+
</div>
|
|
109
|
+
<div className={row}>
|
|
110
|
+
<SiteChip kind="filter" selected label={screens.selected} />
|
|
111
|
+
<SiteChip kind="filter" label={filter} />
|
|
112
|
+
<SiteChip kind="suggestion" selected label={`${suggestion} · ${screens.selected}`} />
|
|
113
|
+
<SiteChip icon="calendar-blank" label={screens.withIcon} />
|
|
114
|
+
<SiteChip kind="input" trailingIcon="x" label={input} />
|
|
115
|
+
<SiteChip kind="input" avatar={examplePicture} removeLabel={screens.remove(screens.withAvatar)} label={screens.withAvatar} />
|
|
116
|
+
<SiteChip kind="input" selected removeLabel={screens.remove(screens.selected)} label={screens.selected} />
|
|
117
|
+
<SiteChip kind="input" dragged avatar={examplePicture} label={screens.dragged} />
|
|
118
|
+
<SiteChip plain label={screens.plain} />
|
|
119
|
+
</div>
|
|
120
|
+
<div className={row}>
|
|
121
|
+
{chipKinds.map((k) => (
|
|
122
|
+
<SiteChip key={k} kind={k} disabled label={screens.disabled} />
|
|
123
|
+
))}
|
|
124
|
+
<SiteChip kind="input" disabled removeLabel={screens.remove(screens.disabled)} label={screens.disabled} />
|
|
125
|
+
<SiteChip elevated disabled label={`${screens.elevated} · ${screens.disabled}`} />
|
|
126
|
+
<SiteChip href="" disabled label={screens.disabled} />
|
|
127
|
+
</div>
|
|
128
|
+
</div>
|
|
129
|
+
</Preview>
|
|
130
|
+
</Part>
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/** The theme's chip sets, as the site draws them: each layout, with more chips than there is room for on one line. */
|
|
135
|
+
function ChipSetParts() {
|
|
136
|
+
return (
|
|
137
|
+
<Part name="ChipSet" use={screens.chipSet}>
|
|
138
|
+
<Preview>
|
|
139
|
+
<div className="max-w-sm space-y-4 p-4">
|
|
140
|
+
{chipSetLayouts.map((layout) => (
|
|
141
|
+
<SiteChipSet key={layout} layout={layout} label={screens.chipSetLayouts[layout]}>
|
|
142
|
+
{[...chipKinds, ...chipKinds].map((k, i) => (
|
|
143
|
+
<SiteChip key={i} kind="filter" selected={!i} label={`${screens.chipSetLayouts[layout]} ${i + 1}`} />
|
|
144
|
+
))}
|
|
145
|
+
</SiteChipSet>
|
|
146
|
+
))}
|
|
147
|
+
</div>
|
|
148
|
+
</Preview>
|
|
149
|
+
</Part>
|
|
150
|
+
);
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
// The standard blocks (not HTML, which has no look of its own).
|
|
154
|
+
const standardBlocks = siteBlocks.filter((b) => standardTypes.has(b.type));
|
|
155
|
+
|
|
156
|
+
// The kinds a toggle button can be (Material: never a text button).
|
|
157
|
+
const toggleKinds = buttonKinds.filter((k) => k !== 'text');
|
|
158
|
+
|
|
159
|
+
/** The theme's buttons and icon buttons, as the site draws them: every kind, the five sizes, both shapes, each kind
|
|
160
|
+
* that can be a toggle off and on in both shapes, the icon buttons' widths, with an icon, and disabled. */
|
|
161
|
+
function ButtonParts() {
|
|
162
|
+
const row = 'flex flex-wrap items-center gap-3';
|
|
163
|
+
const kinds = t.blocks.buttons.kinds;
|
|
164
|
+
return (
|
|
165
|
+
<>
|
|
166
|
+
<Part name="Button" use={screens.button}>
|
|
167
|
+
<Preview>
|
|
168
|
+
<div className="space-y-4 p-4">
|
|
169
|
+
<div className={row}>
|
|
170
|
+
{buttonKinds.map((k) => (
|
|
171
|
+
<SiteButton key={k} kind={k}>
|
|
172
|
+
{kinds[k]}
|
|
173
|
+
</SiteButton>
|
|
174
|
+
))}
|
|
175
|
+
</div>
|
|
176
|
+
<div className={row}>
|
|
177
|
+
{buttonSizes.map((size) => (
|
|
178
|
+
<SiteButton key={size} size={size}>
|
|
179
|
+
{screens.sizes[size]}
|
|
180
|
+
</SiteButton>
|
|
181
|
+
))}
|
|
182
|
+
</div>
|
|
183
|
+
<div className={row}>
|
|
184
|
+
{buttonSizes.map((size) => (
|
|
185
|
+
<SiteButton key={size} size={size} shape="square" kind="tonal">
|
|
186
|
+
{screens.sizes[size]}
|
|
187
|
+
</SiteButton>
|
|
188
|
+
))}
|
|
189
|
+
</div>
|
|
190
|
+
{buttonShapes.map((shape) => (
|
|
191
|
+
<div key={shape} className={row} role="group" aria-label={screens.shapes[shape]}>
|
|
192
|
+
{toggleKinds.map((k) =>
|
|
193
|
+
([false, true] as const).map((on) => (
|
|
194
|
+
<SiteButton key={`${k}-${on}`} kind={k} shape={shape} selected={on} icon="heart">
|
|
195
|
+
{on ? screens.toggle.on : screens.toggle.off}
|
|
196
|
+
</SiteButton>
|
|
197
|
+
)),
|
|
198
|
+
)}
|
|
199
|
+
</div>
|
|
200
|
+
))}
|
|
201
|
+
<div className={row}>
|
|
202
|
+
<SiteButton icon="phone">{screens.withIcon}</SiteButton>
|
|
203
|
+
<SiteButton kind="outlined" trailingIcon="arrow-right">
|
|
204
|
+
{screens.withIcon}
|
|
205
|
+
</SiteButton>
|
|
206
|
+
{buttonKinds.map((k) => (
|
|
207
|
+
<SiteButton key={k} kind={k} disabled>
|
|
208
|
+
{screens.disabled}
|
|
209
|
+
</SiteButton>
|
|
210
|
+
))}
|
|
211
|
+
<SiteButton selected disabled>
|
|
212
|
+
{screens.disabled}
|
|
213
|
+
</SiteButton>
|
|
214
|
+
</div>
|
|
215
|
+
</div>
|
|
216
|
+
</Preview>
|
|
217
|
+
</Part>
|
|
218
|
+
<Part name="IconButton" use={screens.iconButton}>
|
|
219
|
+
<Preview>
|
|
220
|
+
<div className="space-y-4 p-4">
|
|
221
|
+
<div className={row}>
|
|
222
|
+
{iconButtonKinds.map((k) => (
|
|
223
|
+
<SiteIconButton key={k} kind={k} icon="x" label={screens.iconKinds[k]} title={screens.iconKinds[k]} />
|
|
224
|
+
))}
|
|
225
|
+
</div>
|
|
226
|
+
<div className={row}>
|
|
227
|
+
{buttonSizes.map((size) => (
|
|
228
|
+
<SiteIconButton key={size} kind="filled" size={size} icon="phone" label={screens.sizes[size]} title={screens.sizes[size]} />
|
|
229
|
+
))}
|
|
230
|
+
</div>
|
|
231
|
+
<div className={row}>
|
|
232
|
+
{buttonSizes.map((size) => (
|
|
233
|
+
<SiteIconButton
|
|
234
|
+
key={size}
|
|
235
|
+
kind="tonal"
|
|
236
|
+
size={size}
|
|
237
|
+
shape="square"
|
|
238
|
+
icon="phone"
|
|
239
|
+
label={`${screens.sizes[size]}, ${screens.shapes.square}`}
|
|
240
|
+
title={`${screens.sizes[size]}, ${screens.shapes.square}`}
|
|
241
|
+
/>
|
|
242
|
+
))}
|
|
243
|
+
</div>
|
|
244
|
+
<div className={row}>
|
|
245
|
+
{(['small', 'medium'] as const).flatMap((size) =>
|
|
246
|
+
iconButtonWidths.map((width) => (
|
|
247
|
+
<SiteIconButton
|
|
248
|
+
key={`${size}-${width}`}
|
|
249
|
+
kind="outlined"
|
|
250
|
+
size={size}
|
|
251
|
+
width={width}
|
|
252
|
+
icon="phone"
|
|
253
|
+
label={`${screens.sizes[size]}, ${screens.widths[width]}`}
|
|
254
|
+
title={`${screens.sizes[size]}, ${screens.widths[width]}`}
|
|
255
|
+
/>
|
|
256
|
+
)),
|
|
257
|
+
)}
|
|
258
|
+
</div>
|
|
259
|
+
{buttonShapes.map((shape) => (
|
|
260
|
+
<div key={shape} className={row} role="group" aria-label={screens.shapes[shape]}>
|
|
261
|
+
{iconButtonKinds.map((k) =>
|
|
262
|
+
([false, true] as const).map((on) => (
|
|
263
|
+
<SiteIconButton
|
|
264
|
+
key={`${k}-${on}`}
|
|
265
|
+
kind={k}
|
|
266
|
+
shape={shape}
|
|
267
|
+
selected={on}
|
|
268
|
+
icon="heart"
|
|
269
|
+
label={`${screens.iconKinds[k]}, ${on ? screens.toggle.on : screens.toggle.off}`}
|
|
270
|
+
title={`${screens.iconKinds[k]}, ${on ? screens.toggle.on : screens.toggle.off}`}
|
|
271
|
+
/>
|
|
272
|
+
)),
|
|
273
|
+
)}
|
|
274
|
+
</div>
|
|
275
|
+
))}
|
|
276
|
+
<div className={row}>
|
|
277
|
+
{iconButtonKinds.map((k) => (
|
|
278
|
+
<SiteIconButton key={k} kind={k} icon="phone" label={screens.disabled} disabled />
|
|
279
|
+
))}
|
|
280
|
+
<SiteIconButton kind="filled" icon="phone" label={screens.disabled} selected disabled />
|
|
281
|
+
</div>
|
|
282
|
+
</div>
|
|
283
|
+
</Preview>
|
|
284
|
+
</Part>
|
|
285
|
+
</>
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/** The theme's form controls, as the site draws them: each kind of text field empty, filled in, with a line under it,
|
|
290
|
+
* with an error, with only a placeholder and disabled, with an icon before it, a search field with its clear button, a
|
|
291
|
+
* prefix and a suffix, the error's icon, a password with its button, a counter, read-only, and several lines (growing,
|
|
292
|
+
* and three rows); and a checkbox empty, ticked, with a line, disabled, indeterminate and wrong. */
|
|
293
|
+
function FieldParts() {
|
|
294
|
+
const fields = 'grid gap-6 sm:grid-cols-2';
|
|
295
|
+
return (
|
|
296
|
+
<>
|
|
297
|
+
<Part name="TextField" use={screens.textField}>
|
|
298
|
+
<Preview>
|
|
299
|
+
<div className="space-y-6 p-4">
|
|
300
|
+
{(['outlined', 'filled'] as const).map((kind) => (
|
|
301
|
+
<div key={kind} className={fields} aria-label={screens.fieldKinds[kind]} role="group">
|
|
302
|
+
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" />
|
|
303
|
+
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" defaultValue={screens.fieldValue} />
|
|
304
|
+
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" supporting={screens.fieldSupporting} />
|
|
305
|
+
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" defaultValue="navn@" error={screens.fieldError} />
|
|
306
|
+
<SiteTextField kind={kind} label={screens.fieldLabel} hideLabel type="email" placeholder={screens.fieldPlaceholder} />
|
|
307
|
+
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" disabled />
|
|
308
|
+
<SiteTextField kind={kind} label={screens.fieldLabel} type="email" leadingIcon="envelope-simple" />
|
|
309
|
+
<SiteTextField
|
|
310
|
+
kind={kind}
|
|
311
|
+
label={screens.fieldSearch}
|
|
312
|
+
hideLabel
|
|
313
|
+
type="search"
|
|
314
|
+
placeholder={screens.fieldSearch}
|
|
315
|
+
leadingIcon="magnifying-glass"
|
|
316
|
+
clearLabel={screens.fieldClear}
|
|
317
|
+
defaultValue={screens.fieldNote}
|
|
318
|
+
/>
|
|
319
|
+
<SiteTextField kind={kind} label={screens.fieldPhone} type="tel" prefix={screens.fieldPrefix} defaultValue="12 34 56 78" />
|
|
320
|
+
<SiteTextField kind={kind} label={screens.fieldPrice} inputMode="numeric" suffix={screens.fieldSuffix} defaultValue="450" />
|
|
321
|
+
<SiteTextField
|
|
322
|
+
kind={kind}
|
|
323
|
+
label={screens.fieldLabel}
|
|
324
|
+
type="email"
|
|
325
|
+
defaultValue="navn@"
|
|
326
|
+
error={screens.fieldError}
|
|
327
|
+
leadingIcon="envelope-simple"
|
|
328
|
+
errorIcon
|
|
329
|
+
/>
|
|
330
|
+
<SiteTextField
|
|
331
|
+
kind={kind}
|
|
332
|
+
label={screens.fieldPassword}
|
|
333
|
+
type="password"
|
|
334
|
+
defaultValue={screens.fieldPasswordValue}
|
|
335
|
+
passwordLabel={screens.fieldShowPassword}
|
|
336
|
+
/>
|
|
337
|
+
<SiteTextField
|
|
338
|
+
kind={kind}
|
|
339
|
+
label={screens.fieldName}
|
|
340
|
+
supporting={screens.fieldNameSupporting}
|
|
341
|
+
counter
|
|
342
|
+
maxLength={30}
|
|
343
|
+
defaultValue={screens.fieldValue}
|
|
344
|
+
/>
|
|
345
|
+
<SiteTextField kind={kind} label={screens.fieldReadOnly} readOnly defaultValue={screens.fieldReadOnlyValue} />
|
|
346
|
+
<SiteTextField kind={kind} label={screens.fieldMessage} multiline defaultValue={screens.fieldMessageValue} />
|
|
347
|
+
<SiteTextField kind={kind} label={screens.fieldNote} rows={3} counter maxLength={200} />
|
|
348
|
+
</div>
|
|
349
|
+
))}
|
|
350
|
+
</div>
|
|
351
|
+
</Preview>
|
|
352
|
+
</Part>
|
|
353
|
+
<Part name="Checkbox" use={screens.checkbox}>
|
|
354
|
+
<Preview>
|
|
355
|
+
<div className={`${fields} p-4`}>
|
|
356
|
+
<SiteCheckbox label={screens.checkboxLabel} />
|
|
357
|
+
<SiteCheckbox label={screens.checkboxLabel} checked />
|
|
358
|
+
<SiteCheckbox label={screens.checkboxLabel} supporting={screens.checkboxSupporting} />
|
|
359
|
+
<SiteCheckbox label={screens.checkboxLabel} supporting={screens.checkboxSupporting} checked disabled />
|
|
360
|
+
<SiteCheckbox label={screens.checkboxParent} supporting={screens.checkboxSupporting} indeterminate />
|
|
361
|
+
<SiteCheckbox label={screens.checkboxParent} indeterminate disabled />
|
|
362
|
+
<SiteCheckbox label={screens.checkboxLabel} error={screens.checkboxError} />
|
|
363
|
+
<SiteCheckbox label={screens.checkboxLabel} error checked />
|
|
364
|
+
</div>
|
|
365
|
+
</Preview>
|
|
366
|
+
</Part>
|
|
367
|
+
</>
|
|
368
|
+
);
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
/** The theme's cards in each kind, one a link, and lists: one line, a link and an icon with a text under it; one, two
|
|
372
|
+
* and three lines; each leading kind; the choices; selected and disabled; each kind of dividers; and segmented. */
|
|
373
|
+
function CardParts() {
|
|
374
|
+
const say = screens.cardsAndLists;
|
|
375
|
+
const [one, link, withIcon] = say.items;
|
|
376
|
+
const lists = say.lists;
|
|
377
|
+
const [icon, avatar, avatarPicture, image, video] = lists.headlines;
|
|
378
|
+
const [checkbox, radio, switchItem, after] = lists.choices;
|
|
379
|
+
return (
|
|
380
|
+
<>
|
|
381
|
+
<Part name="Card" use={say.card}>
|
|
382
|
+
<Preview>
|
|
383
|
+
<div className="grid gap-4 p-4 sm:grid-cols-2">
|
|
384
|
+
{cardKinds.map((k) => (
|
|
385
|
+
<SiteCard key={k} kind={k}>
|
|
386
|
+
<p className="font-medium">{say.kinds[k]}</p>
|
|
387
|
+
<p className="mt-1 text-muted">{say.text}</p>
|
|
388
|
+
</SiteCard>
|
|
389
|
+
))}
|
|
390
|
+
<SiteCard href="">
|
|
391
|
+
<p className="font-medium">{say.link}</p>
|
|
392
|
+
<p className="mt-1 text-muted">{say.text}</p>
|
|
393
|
+
</SiteCard>
|
|
394
|
+
{cardKinds.map((k) => (
|
|
395
|
+
<SiteCard key={k} kind={k} dragged>
|
|
396
|
+
<p className="font-medium">{`${say.kinds[k]} · ${screens.dragged}`}</p>
|
|
397
|
+
<p className="mt-1 text-muted">{say.text}</p>
|
|
398
|
+
</SiteCard>
|
|
399
|
+
))}
|
|
400
|
+
</div>
|
|
401
|
+
</Preview>
|
|
402
|
+
</Part>
|
|
403
|
+
<Part name="List" use={say.list}>
|
|
404
|
+
<Preview>
|
|
405
|
+
<div className="grid items-start gap-4 p-4 lg:grid-cols-2">
|
|
406
|
+
<SiteCard>
|
|
407
|
+
<SiteList>
|
|
408
|
+
<SiteListItem headline={one} />
|
|
409
|
+
<SiteListItem href="" headline={link} trailing={<Svg name="arrow-right" size={18} />} />
|
|
410
|
+
<SiteListItem
|
|
411
|
+
href=""
|
|
412
|
+
leading={<Svg name="phone" size={24} />}
|
|
413
|
+
headline={withIcon}
|
|
414
|
+
supporting={say.supporting}
|
|
415
|
+
trailing={<Svg name="caret-right" size={20} />}
|
|
416
|
+
/>
|
|
417
|
+
</SiteList>
|
|
418
|
+
</SiteCard>
|
|
419
|
+
<SiteCard>
|
|
420
|
+
<SiteList aria-label={lists.lines}>
|
|
421
|
+
<SiteListItem href="" headline={one} trailingSupporting={lists.trailing} />
|
|
422
|
+
<SiteListItem href="" headline={one} supporting={say.supporting} trailingIcon="caret-right" />
|
|
423
|
+
<SiteListItem href="" overline={lists.overline} headline={one} supporting={say.supporting} trailingIcon="caret-right" />
|
|
424
|
+
<SiteListItem
|
|
425
|
+
href=""
|
|
426
|
+
lines={3}
|
|
427
|
+
leadingIcon="calendar-blank"
|
|
428
|
+
headline={one}
|
|
429
|
+
supporting={lists.long}
|
|
430
|
+
trailingSupporting={lists.trailing}
|
|
431
|
+
/>
|
|
432
|
+
</SiteList>
|
|
433
|
+
</SiteCard>
|
|
434
|
+
<SiteCard>
|
|
435
|
+
<SiteList dividers="inset" aria-label={lists.leading}>
|
|
436
|
+
<SiteListItem href="" leadingIcon="phone" headline={icon} supporting={say.supporting} trailingIcon="caret-right" />
|
|
437
|
+
<SiteListItem
|
|
438
|
+
href=""
|
|
439
|
+
leadingAvatar={lists.letter}
|
|
440
|
+
headline={avatar}
|
|
441
|
+
supporting={say.supporting}
|
|
442
|
+
trailingSupporting={lists.trailing}
|
|
443
|
+
/>
|
|
444
|
+
<SiteListItem href="" leadingAvatar={{ src: examplePicture }} headline={avatarPicture} supporting={say.supporting} />
|
|
445
|
+
<SiteListItem href="" leadingImage={{ src: examplePicture }} headline={image} supporting={say.supporting} />
|
|
446
|
+
<SiteListItem href="" leadingVideo={{ src: examplePicture }} lines={3} headline={video} supporting={lists.long} />
|
|
447
|
+
</SiteList>
|
|
448
|
+
</SiteCard>
|
|
449
|
+
<SiteCard>
|
|
450
|
+
<SiteList aria-label={lists.controls}>
|
|
451
|
+
<SiteListItem control={{ type: 'checkbox', checked: true }} headline={checkbox} supporting={say.supporting} />
|
|
452
|
+
<SiteListItem control={{ type: 'radio-button', name: 'parts-list-radio', checked: true }} headline={radio} />
|
|
453
|
+
<SiteListItem control={{ type: 'radio-button', name: 'parts-list-radio' }} headline={radio} />
|
|
454
|
+
<SiteListItem control={{ type: 'switch', checked: true, icons: 'selected' }} leadingIcon="moon" headline={switchItem} />
|
|
455
|
+
<SiteListItem control={{ type: 'checkbox', at: 'trailing' }} leadingAvatar={lists.letter} headline={after} />
|
|
456
|
+
</SiteList>
|
|
457
|
+
</SiteCard>
|
|
458
|
+
<SiteCard>
|
|
459
|
+
<SiteList aria-label={lists.states}>
|
|
460
|
+
<SiteListItem href="" selected leadingIcon="house" headline={lists.selected} supporting={say.supporting} />
|
|
461
|
+
<SiteListItem href="" disabled leadingIcon="house" headline={lists.disabled} supporting={say.supporting} />
|
|
462
|
+
<SiteListItem control={{ type: 'switch' }} disabled headline={lists.disabled} />
|
|
463
|
+
</SiteList>
|
|
464
|
+
</SiteCard>
|
|
465
|
+
<SiteCard>
|
|
466
|
+
<SiteList aria-label={lists.more}>
|
|
467
|
+
<SiteListItem
|
|
468
|
+
onClick={() => {}}
|
|
469
|
+
leadingIcon="pencil-simple"
|
|
470
|
+
headline={lists.tapped}
|
|
471
|
+
supporting={say.supporting}
|
|
472
|
+
trailingIcon="caret-right"
|
|
473
|
+
/>
|
|
474
|
+
<SiteListItem
|
|
475
|
+
href=""
|
|
476
|
+
headline={lists.withActions}
|
|
477
|
+
supporting={lists.long}
|
|
478
|
+
truncate
|
|
479
|
+
actions={<SiteIconButton icon="trash" label={lists.remove} />}
|
|
480
|
+
/>
|
|
481
|
+
<SiteListItem href="" headline={lists.address} supporting={lists.sendsTo} columns />
|
|
482
|
+
</SiteList>
|
|
483
|
+
</SiteCard>
|
|
484
|
+
{(['middle-inset', 'none'] as const).map((dividers) => (
|
|
485
|
+
<SiteCard key={dividers}>
|
|
486
|
+
<SiteList dividers={dividers} aria-label={lists.dividers[dividers]}>
|
|
487
|
+
{[icon, avatar, image].map((h) => (
|
|
488
|
+
<SiteListItem
|
|
489
|
+
key={h}
|
|
490
|
+
href=""
|
|
491
|
+
leadingIcon="phone"
|
|
492
|
+
headline={`${lists.dividers[dividers]} · ${h}`}
|
|
493
|
+
trailingIcon="caret-right"
|
|
494
|
+
/>
|
|
495
|
+
))}
|
|
496
|
+
</SiteList>
|
|
497
|
+
</SiteCard>
|
|
498
|
+
))}
|
|
499
|
+
<SiteList kind="segmented" aria-label={lists.segmented}>
|
|
500
|
+
<SiteListItem href="" leadingIcon="phone" headline={lists.segmented} supporting={say.supporting} trailingIcon="caret-right" />
|
|
501
|
+
<SiteListItem
|
|
502
|
+
href=""
|
|
503
|
+
selected
|
|
504
|
+
leadingIcon="envelope-simple"
|
|
505
|
+
headline={lists.selected}
|
|
506
|
+
supporting={say.supporting}
|
|
507
|
+
trailingIcon="caret-right"
|
|
508
|
+
/>
|
|
509
|
+
<SiteListItem control={{ type: 'checkbox', checked: true }} headline={checkbox} />
|
|
510
|
+
<SiteListItem control={{ type: 'switch' }} leadingIcon="moon" headline={switchItem} />
|
|
511
|
+
<SiteListItem href="" disabled leadingIcon="map-pin" headline={lists.disabled} />
|
|
512
|
+
</SiteList>
|
|
513
|
+
</div>
|
|
514
|
+
</Preview>
|
|
515
|
+
</Part>
|
|
516
|
+
</>
|
|
517
|
+
);
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/** "Dele" › "UI-komponenter" (#udseende/dele/ui): the theme's UI components in every kind, size and state. */
|
|
521
|
+
export function ComponentParts() {
|
|
522
|
+
const groups = [
|
|
523
|
+
{ id: 'ui', title: screens.ui },
|
|
524
|
+
{ id: 'fields', title: screens.fields },
|
|
525
|
+
{ id: 'chips', title: screens.chips },
|
|
526
|
+
{ id: 'containment', title: screens.containment.title },
|
|
527
|
+
{ id: 'cards', title: screens.cardsAndLists.title },
|
|
528
|
+
{ id: 'navigation', title: screens.navigation.title },
|
|
529
|
+
{ id: 'actions', title: screens.actions.title },
|
|
530
|
+
{ id: 'selection', title: screens.selection.title },
|
|
531
|
+
{ id: 'communication', title: screens.communication.title },
|
|
532
|
+
{ id: 'navigationRest', title: screens.navigationRest.title },
|
|
533
|
+
{ id: 'pickers', title: screens.pickers.title },
|
|
534
|
+
];
|
|
535
|
+
return (
|
|
536
|
+
<Screen title={screens.components} back={back}>
|
|
537
|
+
<div className="space-y-10">
|
|
538
|
+
<p className="text-muted">{screens.componentsIntro}</p>
|
|
539
|
+
<PartsShown groups={groups} keep="parts-components" search={screens.search} none={screens.none}>
|
|
540
|
+
<PartGroup group="ui">
|
|
541
|
+
<ButtonParts />
|
|
542
|
+
</PartGroup>
|
|
543
|
+
<PartGroup group="fields">
|
|
544
|
+
<FieldParts />
|
|
545
|
+
</PartGroup>
|
|
546
|
+
<PartGroup group="chips">
|
|
547
|
+
<ChipParts />
|
|
548
|
+
<ChipSetParts />
|
|
549
|
+
</PartGroup>
|
|
550
|
+
<PartGroup group="containment">
|
|
551
|
+
<ContainmentParts />
|
|
552
|
+
</PartGroup>
|
|
553
|
+
<PartGroup group="cards">
|
|
554
|
+
<CardParts />
|
|
555
|
+
</PartGroup>
|
|
556
|
+
<PartGroup group="navigation">
|
|
557
|
+
<NavigationParts />
|
|
558
|
+
</PartGroup>
|
|
559
|
+
<PartGroup group="actions">
|
|
560
|
+
<ActionParts />
|
|
561
|
+
</PartGroup>
|
|
562
|
+
<PartGroup group="selection">
|
|
563
|
+
<SelectionParts />
|
|
564
|
+
</PartGroup>
|
|
565
|
+
<PartGroup group="communication">
|
|
566
|
+
<CommunicationParts />
|
|
567
|
+
</PartGroup>
|
|
568
|
+
<PartGroup group="navigationRest">
|
|
569
|
+
<NavigationRestParts />
|
|
570
|
+
</PartGroup>
|
|
571
|
+
<PartGroup group="pickers">
|
|
572
|
+
<PickerParts />
|
|
573
|
+
</PartGroup>
|
|
574
|
+
</PartsShown>
|
|
575
|
+
</div>
|
|
576
|
+
</Screen>
|
|
577
|
+
);
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/** "Dele" › "Blokke" (#udseende/dele/blokke): every block, the standard ones and then the apps', each a group of its
|
|
581
|
+
* own, in all its versions. */
|
|
582
|
+
export function BlocksParts() {
|
|
583
|
+
const data = useMemo(exampleData, []);
|
|
584
|
+
const blocks = [...standardBlocks, ...apps.flatMap((app) => siteBlocks.filter((b) => b.app === app.id))];
|
|
585
|
+
return (
|
|
586
|
+
<Screen title={screens.blocks} back={back}>
|
|
587
|
+
<div className="space-y-10">
|
|
588
|
+
<p className="text-muted">{screens.blocksIntro}</p>
|
|
589
|
+
<PartsShown
|
|
590
|
+
groups={blocks.map((b) => ({ id: b.type, title: b.label }))}
|
|
591
|
+
keep="parts-blocks"
|
|
592
|
+
search={screens.search}
|
|
593
|
+
none={screens.none}
|
|
594
|
+
>
|
|
595
|
+
{blocks.map((b) => (
|
|
596
|
+
<PartGroup key={b.type} group={b.type}>
|
|
597
|
+
<BlockShown block={b} data={data} />
|
|
598
|
+
</PartGroup>
|
|
599
|
+
))}
|
|
600
|
+
</PartsShown>
|
|
601
|
+
</div>
|
|
602
|
+
</Screen>
|
|
603
|
+
);
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
/** The lists of kinds ("Promovering"), each a screen of "Dele". */
|
|
607
|
+
export const kindLists = () => collections.filter((c): c is FolderCollection => c.kind === 'folder' && !!c.kinds && !!c.fields?.length);
|
|
608
|
+
|
|
609
|
+
/** "Dele" › a list of kinds ("Promovering", #udseende/dele/liste/<id>): each of its kinds as the site draws it, its own
|
|
610
|
+
* (FolderCollection.draws: the pop-up, the bars) and the apps' (AppKind: Mailchimp's signup, once for each of its
|
|
611
|
+
* states), each a group of its own, as a new one of the kind with the made-up texts (kindExample). */
|
|
612
|
+
export function KindParts({ id }: { id: string }) {
|
|
613
|
+
const data = useMemo(exampleData, []);
|
|
614
|
+
const list = kindLists().find((c) => c.id === id);
|
|
615
|
+
const kindField = list?.fields.find((f) => f.name === list.kinds);
|
|
616
|
+
if (!list || !kindField) return null;
|
|
617
|
+
const own = (kindField.options ?? []).flatMap((o) => {
|
|
618
|
+
const draw = list.draws?.[o.value];
|
|
619
|
+
return draw ? [{ id: o.value, label: o.label, hint: o.hint, variants: [{ label: '', props: {} }], draw }] : [];
|
|
620
|
+
});
|
|
621
|
+
const added = apps.flatMap((app) => {
|
|
622
|
+
const kind = app.kinds?.[list.id];
|
|
623
|
+
const draw = kind && kindDraw(kind, list);
|
|
624
|
+
return kind && draw
|
|
625
|
+
? [{ id: app.id, label: kind.label, hint: kind.hint, variants: kind.variants ?? [{ label: '', props: {} }], draw }]
|
|
626
|
+
: [];
|
|
627
|
+
});
|
|
628
|
+
const kinds = [...own, ...added];
|
|
629
|
+
return (
|
|
630
|
+
<Screen title={list.label} back={back}>
|
|
631
|
+
<div className="space-y-10">
|
|
632
|
+
<p className="text-muted">{screens.kindsIntro(list.singular)}</p>
|
|
633
|
+
<PartsShown
|
|
634
|
+
groups={kinds.map((k) => ({ id: k.id, title: k.label }))}
|
|
635
|
+
keep={`parts-list-${list.id}`}
|
|
636
|
+
search={screens.search}
|
|
637
|
+
none={screens.none}
|
|
638
|
+
>
|
|
639
|
+
{kinds.map((k) => (
|
|
640
|
+
<PartGroup key={k.id} group={k.id}>
|
|
641
|
+
{k.variants.map((v) => (
|
|
642
|
+
<Part key={v.label} name={v.label ? `${k.label} · ${v.label}` : k.label} use={k.hint}>
|
|
643
|
+
<Preview>{k.draw({ ...kindExample(list, k.id), ...v.props }, data)}</Preview>
|
|
644
|
+
</Part>
|
|
645
|
+
))}
|
|
646
|
+
</PartGroup>
|
|
647
|
+
))}
|
|
648
|
+
</PartsShown>
|
|
649
|
+
</div>
|
|
650
|
+
</Screen>
|
|
651
|
+
);
|
|
652
|
+
}
|