srcdev-nuxt-components 9.4.11 → 9.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/skills/component-aria-landmark.md +1 -1
- package/.claude/skills/component-dynamic-slots.md +0 -1
- package/.claude/skills/component-export-types.md +3 -3
- package/.claude/skills/component-inline-action-button.md +7 -7
- package/.claude/skills/component-local-style-override.md +134 -50
- package/.claude/skills/component-naming.md +107 -0
- package/.claude/skills/components/action-menu.md +18 -14
- package/.claude/skills/components/alert-content.md +110 -0
- package/.claude/skills/components/alert-mask-core.md +15 -1
- package/.claude/skills/components/alert-masked-content.md +95 -0
- package/.claude/skills/components/auto-grid.md +21 -13
- package/.claude/skills/components/canvas-switcher.md +3 -3
- package/.claude/skills/components/capture-qr-code.md +19 -9
- package/.claude/skills/components/carousel-flip.md +3 -3
- package/.claude/skills/components/container-glow.md +2 -2
- package/.claude/skills/components/content-docs.md +9 -5
- package/.claude/skills/components/cookie-consent-banner.md +16 -17
- package/.claude/skills/components/dashboard-quad-grid.md +4 -4
- package/.claude/skills/components/decode-qr-code.md +15 -9
- package/.claude/skills/components/display-avatar.md +16 -31
- package/.claude/skills/components/display-chip.md +15 -10
- package/.claude/skills/components/display-dialog.md +3 -1
- package/.claude/skills/components/display-pill.md +17 -75
- package/.claude/skills/components/display-prompt.md +11 -19
- package/.claude/skills/components/display-qr-code.md +5 -0
- package/.claude/skills/components/display-theme-switch.md +7 -6
- package/.claude/skills/components/display-toast.md +5 -6
- package/.claude/skills/components/entry-animation.md +2 -5
- package/.claude/skills/components/eyebrow-text.md +6 -4
- package/.claude/skills/components/form-field.md +79 -0
- package/.claude/skills/components/form-fieldset.md +75 -0
- package/.claude/skills/components/form-wrapper.md +71 -0
- package/.claude/skills/components/glass-panel.md +60 -51
- package/.claude/skills/components/grid-stack.md +8 -2
- package/.claude/skills/components/header-block.md +1 -1
- package/.claude/skills/components/hero-text.md +8 -6
- package/.claude/skills/components/input-button.md +72 -0
- package/.claude/skills/components/input-checkbox-radio.md +149 -0
- package/.claude/skills/components/input-checkbox.md +148 -0
- package/.claude/skills/components/input-description.md +102 -0
- package/.claude/skills/components/input-error.md +105 -0
- package/.claude/skills/components/input-label.md +119 -0
- package/.claude/skills/components/{input-number-core.md → input-number.md} +41 -36
- package/.claude/skills/components/input-radio.md +95 -0
- package/.claude/skills/components/input-range-core.md +4 -4
- package/.claude/skills/components/input-select-core.md +1 -1
- package/.claude/skills/components/input-text-core.md +8 -6
- package/.claude/skills/components/input-textarea-core.md +4 -4
- package/.claude/skills/components/layout-grid-by-cols.md +31 -43
- package/.claude/skills/components/link-text.md +2 -2
- package/.claude/skills/components/opening-hours.md +116 -0
- package/.claude/skills/components/page-hero-highlights.md +35 -35
- package/.claude/skills/components/page-row.md +1 -1
- package/.claude/skills/components/pending-effect.md +63 -0
- package/.claude/skills/components/price-list.md +72 -0
- package/.claude/skills/components/pricing-card.md +3 -3
- package/.claude/skills/components/profile-section.md +6 -4
- package/.claude/skills/components/samaritan-prompt.md +140 -0
- package/.claude/skills/components/scroll-reveal-frame.md +21 -20
- package/.claude/skills/components/scroll-reveal-image.md +31 -21
- package/.claude/skills/components/service-detail.md +2 -2
- package/.claude/skills/components/services-card-grid.md +5 -4
- package/.claude/skills/components/services-card.md +12 -10
- package/.claude/skills/components/site-navigation.md +20 -6
- package/.claude/skills/components/slider-gallery.md +88 -0
- package/.claude/skills/components/social-icons-list.md +12 -6
- package/.claude/skills/components/tab-navigation.md +1 -1
- package/.claude/skills/components/text-block.md +68 -0
- package/.claude/skills/components/toggle-switch-core.md +3 -3
- package/.claude/skills/components/triple-toggle-switch.md +85 -0
- package/.claude/skills/composable-zod-validation.md +1 -1
- package/.claude/skills/consumer-styles-structure.md +153 -0
- package/.claude/skills/icon-sets.md +3 -3
- package/.claude/skills/icon-sizing.md +66 -0
- package/.claude/skills/index.md +35 -16
- package/.claude/skills/new-app-scaffold.md +45 -7
- package/.claude/skills/pull-request-description.md +1 -0
- package/.claude/skills/storybook-add-story.md +53 -5
- package/.claude/skills/testing-add-playwright.md +1 -1
- package/.claude/skills/theming-colour-ramps.md +25 -3
- package/.claude/skills/theming-component-token-pattern.md +16 -16
- package/.claude/skills/theming-override-default.md +7 -0
- package/.claude/skills/theming-partial-override.md +1 -1
- package/.claude/skills/theming-typography-tokens.md +1 -1
- package/.claude/skills/vercel-node-version.md +1 -1
- package/.vscode/srcdev-component-action-menu.code-snippets +42 -0
- package/.vscode/srcdev-component-alert-content.code-snippets +36 -0
- package/.vscode/srcdev-component-alert-masked-content.code-snippets +35 -0
- package/.vscode/srcdev-component-auto-grid.code-snippets +39 -0
- package/.vscode/srcdev-component-capture-decode-qr-code.code-snippets +28 -0
- package/.vscode/srcdev-component-content-docs.code-snippets +4 -4
- package/.vscode/srcdev-component-cookie-consent-banner.code-snippets +33 -0
- package/.vscode/srcdev-component-display-avatar.code-snippets +28 -0
- package/.vscode/srcdev-component-display-chip.code-snippets +27 -0
- package/.vscode/srcdev-component-display-pill.code-snippets +38 -0
- package/.vscode/srcdev-component-display-prompt.code-snippets +10 -54
- package/.vscode/srcdev-component-display-qr-code.code-snippets +22 -0
- package/.vscode/srcdev-component-eyebrow-text.code-snippets +19 -0
- package/.vscode/srcdev-component-form-field.code-snippets +25 -0
- package/.vscode/srcdev-component-form-fieldset.code-snippets +36 -0
- package/.vscode/srcdev-component-form-wrapper.code-snippets +30 -0
- package/.vscode/srcdev-component-glass-panel.code-snippets +38 -0
- package/.vscode/srcdev-component-grid-stack.code-snippets +49 -0
- package/.vscode/srcdev-component-input-button.code-snippets +27 -0
- package/.vscode/srcdev-component-input-checkbox-radio.code-snippets +60 -0
- package/.vscode/srcdev-component-input-checkbox.code-snippets +48 -0
- package/.vscode/srcdev-component-input-description.code-snippets +44 -0
- package/.vscode/srcdev-component-input-error.code-snippets +30 -0
- package/.vscode/srcdev-component-input-label.code-snippets +39 -0
- package/.vscode/srcdev-component-input-number.code-snippets +11 -11
- package/.vscode/srcdev-component-input-radio.code-snippets +58 -0
- package/.vscode/srcdev-component-layout-grid-by-cols.code-snippets +46 -0
- package/.vscode/srcdev-component-link-text.code-snippets +30 -0
- package/.vscode/srcdev-component-opening-hours.code-snippets +40 -0
- package/.vscode/srcdev-component-page-hero-highlights.code-snippets +37 -0
- package/.vscode/srcdev-component-page-row.code-snippets +47 -0
- package/.vscode/srcdev-component-pending-effect.code-snippets +26 -0
- package/.vscode/srcdev-component-price-list.code-snippets +37 -0
- package/.vscode/srcdev-component-pricing-card.code-snippets +2 -2
- package/.vscode/srcdev-component-profile-section.code-snippets +36 -0
- package/.vscode/srcdev-component-samaritan-prompt.code-snippets +60 -0
- package/.vscode/srcdev-component-scroll-reveal-frame.code-snippets +36 -0
- package/.vscode/srcdev-component-scroll-reveal-image.code-snippets +46 -0
- package/.vscode/srcdev-component-services-card.code-snippets +4 -4
- package/.vscode/srcdev-component-services-grids.code-snippets +36 -0
- package/.vscode/srcdev-component-site-navigation.code-snippets +26 -18
- package/.vscode/srcdev-component-slider-gallery.code-snippets +9 -0
- package/.vscode/srcdev-component-social-icons-list.code-snippets +24 -0
- package/.vscode/srcdev-component-stepper-list.code-snippets +39 -0
- package/.vscode/srcdev-component-text-block.code-snippets +31 -0
- package/.vscode/srcdev-component-triple-toggle-switch.code-snippets +30 -0
- package/README.md +2 -2
- package/app/app.config.ts +10 -0
- package/app/assets/styles/setup/02.colours/_orange.css +11 -11
- package/app/assets/styles/setup/02.colours/_theme-params.css +2 -2
- package/app/assets/styles/setup/03.theming/_default.css +1 -22
- package/app/assets/styles/setup/03.theming/_theme-slots.css +1 -1
- package/app/assets/styles/setup/03.theming/_warning.css +8 -10
- package/app/assets/styles/setup/04.elements/forms/02.typography.css +0 -14
- package/app/assets/styles/setup/04.elements/forms/06.button-geometry.css +1 -1
- package/app/assets/styles/setup/index.css +1 -1
- package/app/components/01.atoms/alert-mask/AlertMaskCore.vue +23 -5
- package/app/components/01.atoms/alert-mask/CONSUMER-STYLING.md +23 -5
- package/app/components/01.atoms/alert-mask/stories/AlertMaskCore.stories.ts +45 -19
- package/app/components/01.atoms/alert-mask/tests/AlertMaskCore.spec.ts +35 -1
- package/app/components/01.atoms/animations/animated-svg-text/CONSUMER-STYLING.md +13 -0
- package/app/components/01.atoms/animations/clip-element/CONSUMER-STYLING.md +13 -0
- package/app/components/01.atoms/animations/clip-element/ClipElement.vue +2 -2
- package/app/components/01.atoms/animations/container-glow/CONSUMER-STYLING.md +26 -5
- package/app/components/01.atoms/animations/entry/.nuxt/app.config.mjs +21 -0
- package/app/components/01.atoms/animations/entry/.nuxt/components.d.ts +66 -0
- package/app/components/01.atoms/animations/entry/.nuxt/imports.d.ts +30 -0
- package/app/components/01.atoms/animations/entry/.nuxt/manifest/meta/test.json +1 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/app.config.d.ts +35 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/build.d.ts +23 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/builder-env.d.ts +1 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/components.d.ts +71 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/imports.d.ts +386 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/middleware.d.ts +11 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/modules.d.ts +79 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/nitro-layouts.d.ts +17 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/nitro-nuxt.d.ts +64 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/plugins.d.ts +29 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/runtime-config.d.ts +32 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/shared-imports.d.ts +10 -0
- package/app/components/01.atoms/animations/entry/.nuxt/types/vue-shim.d.ts +0 -0
- package/app/components/01.atoms/animations/entry/.nuxtrc +1 -0
- package/app/components/01.atoms/animations/entry/CONSUMER-STYLING.md +65 -0
- package/app/components/01.atoms/animations/entry/EntryAnimation.vue +6 -5
- package/app/components/01.atoms/animations/entry/node_modules/.cache/nuxt/chrome-workspace.json +1 -0
- package/app/components/01.atoms/animations/entry/node_modules/.cache/vite/client/vitest/da39a3ee5e6b4b0d3255bfef95601890afd80709/results.json +1 -0
- package/app/components/01.atoms/animations/entry/stories/EntryAnimation.stories.ts +1 -1
- package/app/components/01.atoms/animations/entry/tests/EntryAnimation.spec.ts +25 -0
- package/app/components/01.atoms/animations/glowing-border/CONSUMER-STYLING.md +24 -5
- package/app/components/01.atoms/animations/marquee-scroller/CONSUMER-STYLING.md +20 -0
- package/app/components/01.atoms/animations/rotating-carousel-image/CONSUMER-STYLING.md +17 -0
- package/app/components/01.atoms/animations/scroll-reveal-frame/CONSUMER-STYLING.md +77 -0
- package/app/components/01.atoms/animations/scroll-reveal-frame/ScrollRevealFrame.vue +37 -78
- package/app/components/01.atoms/animations/scroll-reveal-frame/stories/ScrollRevealFrame.stories.ts +48 -0
- package/app/components/01.atoms/animations/scroll-reveal-frame/tests/ScrollRevealFrame.spec.ts +40 -33
- package/app/components/01.atoms/animations/scroll-reveal-frame/tests/__snapshots__/ScrollRevealFrame.spec.ts.snap +4 -4
- package/app/components/01.atoms/animations/scroll-reveal-image/CONSUMER-STYLING.md +74 -0
- package/app/components/01.atoms/animations/scroll-reveal-image/ScrollRevealImage.vue +14 -44
- package/app/components/01.atoms/animations/scroll-reveal-image/stories/ScrollRevealImage.stories.ts +50 -1
- package/app/components/01.atoms/animations/scroll-reveal-image/tests/ScrollRevealImage.spec.ts +27 -20
- package/app/components/01.atoms/animations/scroll-reveal-image/tests/__snapshots__/ScrollRevealImage.spec.ts.snap +4 -4
- package/app/components/01.atoms/animations/section-parallax/CONSUMER-STYLING.md +21 -4
- package/app/components/01.atoms/animations/view-timeline/CONSUMER-STYLING.md +25 -0
- package/app/components/01.atoms/banner-video/CONSUMER-STYLING.md +12 -5
- package/app/components/01.atoms/canvas-switcher/CONSUMER-STYLING.md +20 -7
- package/app/components/01.atoms/canvas-switcher/CanvasSwitcher.vue +12 -7
- package/app/components/01.atoms/card/CONSUMER-STYLING.md +47 -42
- package/app/components/01.atoms/card/CardCore.vue +7 -17
- package/app/components/01.atoms/clipped-panel/CONSUMER-STYLING.md +13 -0
- package/app/components/01.atoms/content-wrappers/docs-pages/CONSUMER-STYLING.md +127 -0
- package/app/components/01.atoms/content-wrappers/docs-pages/ContentDocs.vue +44 -77
- package/app/components/01.atoms/content-wrappers/docs-pages/stories/ContentDocs.stories.ts +3 -3
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/CONSUMER-STYLING.md +14 -1
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-quad-grid/stories/DashboardQuadGrid.stories.ts +2 -0
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/CONSUMER-STYLING.md +13 -0
- package/app/components/01.atoms/content-wrappers/layout-grid/dashboard-stats-grid/stories/DashboardStatsGrid.stories.ts +2 -0
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/CONSUMER-STYLING.md +72 -0
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/LayoutGridByCols.vue +26 -25
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/stories/LayoutGridByCols.stories.ts +91 -107
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/LayoutGridByCols.spec.ts +50 -15
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +5 -5
- package/app/components/01.atoms/display-banner/CONSUMER-STYLING.md +13 -0
- package/app/components/01.atoms/display-dialog/CONSUMER-STYLING.md +82 -54
- package/app/components/01.atoms/display-dialog/DisplayDialog.vue +38 -45
- package/app/components/01.atoms/display-dialog/stories/DisplayDialog.stories.ts +25 -0
- package/app/components/01.atoms/display-dialog/tests/DisplayDialog.spec.ts +21 -0
- package/app/components/01.atoms/display-pill/CONSUMER-STYLING.md +112 -0
- package/app/components/01.atoms/display-pill/DisplayPill.vue +88 -50
- package/app/components/01.atoms/display-pill/stories/DisplayPill.stories.ts +56 -3
- package/app/components/01.atoms/display-pill/tests/DisplayPill.spec.ts +104 -4
- package/app/components/01.atoms/display-pill/tests/__snapshots__/DisplayPill.spec.ts.snap +3 -3
- package/app/components/01.atoms/display-tooltip/CONSUMER-STYLING.md +22 -2
- package/app/components/01.atoms/display-tooltip/DisplayTooltip.vue +18 -26
- package/app/components/01.atoms/glass-panel/CONSUMER-STYLING.md +91 -0
- package/app/components/01.atoms/glass-panel/GlassPanel.vue +34 -30
- package/app/components/01.atoms/glass-panel/stories/GlassPanel.stories.ts +121 -0
- package/app/components/01.atoms/glass-panel/tests/GlassPanel.spec.ts +61 -0
- package/app/components/01.atoms/grids/auto-grid/AutoGrid.vue +5 -10
- package/app/components/01.atoms/grids/auto-grid/CONSUMER-STYLING.md +76 -0
- package/app/components/01.atoms/grids/auto-grid/stories/AutoGrid.stories.ts +5 -4
- package/app/components/01.atoms/grids/auto-grid/tests/AutoGrid.spec.ts +8 -0
- package/app/components/01.atoms/grids/column-flow-grid/CONSUMER-STYLING.md +11 -2
- package/app/components/01.atoms/grids/grid-stack/CONSUMER-STYLING.md +76 -0
- package/app/components/01.atoms/grids/grid-stack/GridStack.vue +6 -1
- package/app/components/01.atoms/grids/grid-stack/stories/GridStack.stories.ts +1 -1
- package/app/components/01.atoms/grids/grid-stack/tests/GridStack.spec.ts +35 -0
- package/app/components/01.atoms/grids/masonry-grid/CONSUMER-STYLING.md +11 -2
- package/app/components/01.atoms/navigation/breadcrumb/Breadcrumb.vue +5 -10
- package/app/components/01.atoms/navigation/breadcrumb/CONSUMER-STYLING.md +15 -0
- package/app/components/01.atoms/navigation/skip-links/CONSUMER-STYLING.md +13 -0
- package/app/components/01.atoms/navigation/tabs/CONSUMER-STYLING.md +21 -0
- package/app/components/01.atoms/page-row/CONSUMER-STYLING.md +46 -8
- package/app/components/01.atoms/page-row/PageRow.vue +17 -13
- package/app/components/01.atoms/page-row/stories/PageRow.stories.ts +8 -0
- package/app/components/01.atoms/page-row/tests/PageRow.spec.ts +7 -11
- package/app/components/01.atoms/pop-over/CONSUMER-STYLING.md +13 -0
- package/app/components/01.atoms/qr-code/CONSUMER-STYLING.md +48 -0
- package/app/components/01.atoms/qr-code/DisplayQrCode.vue +5 -1
- package/app/components/01.atoms/qr-code/stories/DisplayQrCode.stories.ts +11 -3
- package/app/components/01.atoms/qr-code/tests/DisplayQrCode.spec.ts +15 -0
- package/app/components/01.atoms/text-block/CONSUMER-STYLING.md +49 -0
- package/app/components/01.atoms/text-block/TextBlock.vue +13 -5
- package/app/components/01.atoms/text-block/stories/TextBlock.stories.ts +84 -0
- package/app/components/01.atoms/text-block/tests/TextBlock.spec.ts +78 -0
- package/app/components/01.atoms/text-block/tests/__snapshots__/TextBlock.spec.ts.snap +7 -0
- package/app/components/01.atoms/text-blocks/eyebrow-text/CONSUMER-STYLING.md +56 -0
- package/app/components/01.atoms/text-blocks/eyebrow-text/EyebrowText.vue +10 -5
- package/app/components/01.atoms/text-blocks/eyebrow-text/tests/EyebrowText.spec.ts +11 -0
- package/app/components/01.atoms/text-blocks/header-block/CONSUMER-STYLING.md +16 -1
- package/app/components/01.atoms/text-blocks/hero-text/CONSUMER-STYLING.md +74 -0
- package/app/components/01.atoms/text-blocks/hero-text/HeroText.vue +14 -9
- package/app/components/01.atoms/text-blocks/hero-text/tests/HeroText.spec.ts +11 -0
- package/app/components/01.atoms/text-blocks/link-text/CONSUMER-STYLING.md +45 -0
- package/app/components/01.atoms/text-blocks/link-text/LinkText.vue +15 -8
- package/app/components/01.atoms/text-blocks/link-text/tests/LinkText.spec.ts +11 -0
- package/app/components/01.atoms/ui-block-decorated/CONSUMER-STYLING.md +13 -0
- package/app/components/02.molecules/action-menu/ActionMenu.vue +28 -30
- package/app/components/02.molecules/action-menu/{ActionMenuItemCore.vue → ActionMenuItem.vue} +12 -14
- package/app/components/02.molecules/action-menu/CONSUMER-STYLING.md +90 -76
- package/app/components/02.molecules/action-menu/stories/ActionMenu.stories.ts +48 -41
- package/app/components/02.molecules/action-menu/tests/ActionMenu.spec.ts +46 -1
- package/app/components/02.molecules/action-menu/tests/{ActionMenuItemCore.spec.ts → ActionMenuItem.spec.ts} +11 -5
- package/app/components/02.molecules/action-menu/tests/__snapshots__/ActionMenuItem.spec.ts.snap +27 -0
- package/app/components/02.molecules/alert-content/AlertContent.vue +17 -8
- package/app/components/02.molecules/alert-content/AlertContentInner.vue +57 -30
- package/app/components/02.molecules/alert-content/CONSUMER-STYLING.md +84 -0
- package/app/components/02.molecules/alert-content/stories/AlertContent.stories.ts +39 -0
- package/app/components/02.molecules/alert-content/tests/AlertContent.spec.ts +32 -0
- package/app/components/02.molecules/alert-content/tests/AlertContentInner.spec.ts +32 -0
- package/app/components/02.molecules/alert-masked-content/AlertMaskedContent.vue +9 -5
- package/app/components/02.molecules/alert-masked-content/CONSUMER-STYLING.md +73 -0
- package/app/components/02.molecules/alert-masked-content/stories/AlertMaskedContent.stories.ts +91 -10
- package/app/components/02.molecules/alert-masked-content/tests/AlertMaskedContent.spec.ts +52 -0
- package/app/components/02.molecules/cookie-consent-banner/CONSUMER-STYLING.md +95 -0
- package/app/components/02.molecules/cookie-consent-banner/CookieConsentBanner.vue +149 -0
- package/app/components/{01.atoms → 02.molecules}/cookie-consent-banner/stories/CookieConsentBanner.stories.ts +22 -3
- package/app/components/{01.atoms → 02.molecules}/cookie-consent-banner/tests/CookieConsentBanner.spec.ts +81 -4
- package/app/components/02.molecules/display-avatar/CONSUMER-STYLING.md +63 -0
- package/app/components/02.molecules/display-avatar/DisplayAvatar.vue +120 -0
- package/app/components/{01.atoms → 02.molecules}/display-avatar/stories/DisplayAvatar.stories.ts +56 -14
- package/app/components/{01.atoms → 02.molecules}/display-avatar/tests/DisplayAvatar.spec.ts +43 -11
- package/app/components/02.molecules/display-avatar/tests/__snapshots__/DisplayAvatar.spec.ts.snap +11 -0
- package/app/components/02.molecules/display-chip/CONSUMER-STYLING.md +57 -0
- package/app/components/02.molecules/display-chip/DisplayChip.vue +50 -83
- package/app/components/02.molecules/display-chip/tests/DisplayChip.spec.ts +10 -10
- package/app/components/02.molecules/display-chip/tests/__snapshots__/DisplayChip.spec.ts.snap +4 -4
- package/app/components/02.molecules/display-theme-switch/CONSUMER-STYLING.md +25 -4
- package/app/components/02.molecules/display-theme-switch/DisplayThemeSwitch.vue +9 -6
- package/app/components/02.molecules/display-theme-switch/stories/DisplayThemeSwitch.stories.ts +6 -1
- package/app/components/02.molecules/display-theme-switch/tests/DisplayThemeSwitch.spec.ts +10 -1
- package/app/components/02.molecules/display-tooltip-defined/CONSUMER-STYLING.md +11 -0
- package/app/components/02.molecules/expandable/accordian/CONSUMER-STYLING.md +11 -4
- package/app/components/02.molecules/expandable/expanding-panel/CONSUMER-STYLING.md +12 -5
- package/app/components/02.molecules/expandable/expanding-panel-classic/CONSUMER-STYLING.md +12 -5
- package/app/components/02.molecules/input-copy/CONSUMER-STYLING.md +12 -5
- package/app/components/02.molecules/input-copy/InputCopy.vue +12 -25
- package/app/components/02.molecules/input-copy/stories/InputCopy.stories.ts +1 -1
- package/app/components/02.molecules/input-copy/tests/InputCopy.spec.ts +1 -1
- package/app/components/02.molecules/navigation/deep-expanding-menu/CONSUMER-STYLING.md +13 -0
- package/app/components/02.molecules/navigation/deep-expanding-menu-classic/CONSUMER-STYLING.md +11 -0
- package/app/components/02.molecules/navigation/site-navigation/CONSUMER-STYLING.md +109 -0
- package/app/components/02.molecules/navigation/site-navigation/SiteNavigation.vue +37 -55
- package/app/components/02.molecules/navigation/site-navigation/stories/SiteNavigation.stories.ts +22 -1
- package/app/components/02.molecules/navigation/site-navigation/tests/SiteNavigation.spec.ts +41 -6
- package/app/components/02.molecules/navigation/tab-navigation/CONSUMER-STYLING.md +13 -8
- package/app/components/02.molecules/navigation/tab-navigation/TabNavigation.vue +18 -36
- package/app/components/02.molecules/navigation/tab-navigation/stories/TabNavigation.stories.ts +1 -1
- package/app/components/02.molecules/navigation/tab-navigation/tests/TabNavigation.spec.ts +1 -1
- package/app/components/02.molecules/opening-hours/CONSUMER-STYLING.md +134 -0
- package/app/components/02.molecules/opening-hours/OpeningHours.vue +352 -0
- package/app/components/02.molecules/opening-hours/stories/OpeningHours.stories.ts +127 -0
- package/app/components/02.molecules/opening-hours/tests/OpeningHours.spec.ts +228 -0
- package/app/components/02.molecules/opening-hours/tests/OpeningHours.structuredData.spec.ts +45 -0
- package/app/components/02.molecules/opening-hours/tests/__snapshots__/OpeningHours.spec.ts.snap +23 -0
- package/app/components/02.molecules/opening-hours/tests/buildOpeningHoursSpecification.spec.ts +52 -0
- package/app/components/02.molecules/price-list/CONSUMER-STYLING.md +106 -0
- package/app/components/02.molecules/price-list/PriceList.vue +48 -40
- package/app/components/02.molecules/price-list/stories/PriceList.stories.ts +15 -2
- package/app/components/02.molecules/price-list/tests/PriceList.spec.ts +39 -2
- package/app/components/02.molecules/price-list/tests/__snapshots__/PriceList.spec.ts.snap +4 -16
- package/app/components/02.molecules/pricing-card/CONSUMER-STYLING.md +23 -5
- package/app/components/02.molecules/pricing-card/PricingCard.vue +31 -61
- package/app/components/02.molecules/pricing-card/stories/PricingCard.stories.ts +2 -0
- package/app/components/02.molecules/pricing-card/tests/PricingCard.spec.ts +14 -1
- package/app/components/02.molecules/profile-section/CONSUMER-STYLING.md +53 -0
- package/app/components/02.molecules/profile-section/ProfileSection.vue +53 -66
- package/app/components/02.molecules/profile-section/tests/ProfileSection.spec.ts +4 -4
- package/app/components/02.molecules/profile-section/tests/__snapshots__/ProfileSection.spec.ts.snap +6 -12
- package/app/components/02.molecules/prompt/CONSUMER-STYLING.md +51 -0
- package/app/components/{01.atoms → 02.molecules}/prompt/DisplayPrompt.vue +23 -8
- package/app/components/{01.atoms → 02.molecules}/prompt/stories/DisplayPrompt.stories.ts +18 -1
- package/app/components/{01.atoms → 02.molecules}/prompt/tests/DisplayPrompt.spec.ts +37 -7
- package/app/components/02.molecules/qr-code/CONSUMER-STYLING.md +66 -0
- package/app/components/02.molecules/qr-code/CaptureQrCode.vue +31 -12
- package/app/components/02.molecules/qr-code/DecodeQrCode.vue +55 -19
- package/app/components/02.molecules/qr-code/stories/CaptureQrCode.stories.ts +56 -0
- package/app/components/02.molecules/qr-code/stories/DecodeQrCode.stories.ts +53 -0
- package/app/components/02.molecules/qr-code/tests/CaptureQrCode.spec.ts +68 -20
- package/app/components/02.molecules/qr-code/tests/DecodeQrCode.spec.ts +44 -8
- package/app/components/02.molecules/samaritan-prompt/CONSUMER-STYLING.md +118 -0
- package/app/components/02.molecules/samaritan-prompt/SamaritanPrompt.vue +108 -51
- package/app/components/02.molecules/samaritan-prompt/SamaritanPromptMixed.vue +63 -62
- package/app/components/02.molecules/samaritan-prompt/stories/SamaritanPrompt.stories.ts +129 -0
- package/app/components/02.molecules/samaritan-prompt/stories/SamaritanPromptMixed.stories.ts +124 -0
- package/app/components/02.molecules/samaritan-prompt/tests/SamaritanPrompt.spec.ts +66 -0
- package/app/components/02.molecules/samaritan-prompt/tests/SamaritanPromptMixed.spec.ts +95 -17
- package/app/components/02.molecules/select-menu/CONSUMER-STYLING.md +11 -2
- package/app/components/02.molecules/social-icons-list/CONSUMER-STYLING.md +43 -0
- package/app/components/02.molecules/social-icons-list/SocialIconsList.vue +15 -15
- package/app/components/02.molecules/social-icons-list/stories/SocialIconsList.stories.ts +6 -1
- package/app/components/02.molecules/social-icons-list/tests/SocialIconsList.spec.ts +22 -1
- package/app/components/02.molecules/social-icons-list/tests/__snapshots__/SocialIconsList.spec.ts.snap +3 -3
- package/app/components/02.molecules/stepper-list/CONSUMER-STYLING.md +44 -5
- package/app/components/02.molecules/stepper-list/StepperList.vue +23 -43
- package/app/components/02.molecules/stepper-list/tests/StepperList.spec.ts +9 -0
- package/app/components/{01.atoms → 02.molecules}/toast/CONSUMER-STYLING.md +14 -0
- package/app/components/{01.atoms → 02.molecules}/toast/DisplayToast.vue +1 -2
- package/app/components/{01.atoms → 02.molecules}/toast/DisplayToastProvider.vue +1 -2
- package/app/components/{01.atoms → 02.molecules}/toast/stories/DisplayToast.stories.ts +1 -1
- package/app/components/{01.atoms → 02.molecules}/toast/stories/DisplayToastProvider.stories.ts +1 -1
- package/app/components/03.organisms/image-galleries/carousel-flip/CONSUMER-STYLING.md +13 -0
- package/app/components/03.organisms/image-galleries/slider-gallery/CONSUMER-STYLING.md +137 -0
- package/app/components/03.organisms/image-galleries/slider-gallery/SliderGallery.vue +378 -343
- package/app/components/03.organisms/image-galleries/slider-gallery/stories/SliderGallery.stories.ts +26 -1
- package/app/components/03.organisms/image-galleries/slider-gallery/tests/SliderGallery.spec.ts +102 -23
- package/app/components/03.organisms/image-galleries/slider-gallery/tests/__snapshots__/SliderGallery.spec.ts.snap +44 -44
- package/app/components/03.organisms/responsive-header/CONSUMER-STYLING.md +12 -1
- package/app/components/03.organisms/responsive-header/ResponsiveHeader.vue +0 -4
- package/app/components/03.organisms/services/service-detail/CONSUMER-STYLING.md +24 -3
- package/app/components/03.organisms/services/service-detail/ServiceDetail.vue +3 -3
- package/app/components/03.organisms/services/service-detail/stories/ServiceDetail.stories.ts +13 -13
- package/app/components/03.organisms/services/service-detail/tests/__snapshots__/ServiceDetail.spec.ts.snap +1 -1
- package/app/components/03.organisms/services/service-summary/CONSUMER-STYLING.md +24 -7
- package/app/components/03.organisms/services/service-summary/ServiceSummary.vue +3 -3
- package/app/components/03.organisms/services/service-summary/stories/ServiceSummary.stories.ts +1 -1
- package/app/components/03.organisms/services/service-summary/tests/__snapshots__/ServiceSummary.spec.ts.snap +1 -1
- package/app/components/03.organisms/services/services-card/CONSUMER-STYLING.md +11 -2
- package/app/components/03.organisms/services/services-card/ServicesCard.vue +17 -26
- package/app/components/03.organisms/services/services-card/tests/ServicesCard.spec.ts +21 -0
- package/app/components/03.organisms/services/services-grids/CONSUMER-STYLING.md +50 -0
- package/app/components/03.organisms/services/services-grids/ServicesCardGrid.vue +9 -16
- package/app/components/03.organisms/services/services-grids/stories/ServicesCardGrid.stories.ts +6 -0
- package/app/components/03.organisms/services/services-grids/tests/ServicesCardGrid.spec.ts +18 -0
- package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServiceSummaryGrid.spec.ts.snap +3 -3
- package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServicesCardGrid.spec.ts.snap +3 -3
- package/app/components/03.organisms/site-header/CONSUMER-STYLING.md +12 -1
- package/app/components/04.templates/page-hero-highlights/CONSUMER-STYLING.md +103 -0
- package/app/components/04.templates/page-hero-highlights/PageHeroHighlights.vue +144 -193
- package/app/components/04.templates/page-hero-highlights/PageHeroHighlightsHeader.vue +27 -37
- package/app/components/04.templates/page-hero-highlights/stories/PageHeroHighlights.stories.ts +56 -60
- package/app/components/04.templates/page-hero-highlights/stories/PageHeroHighlightsHeader.stories.ts +2 -2
- package/app/components/04.templates/page-hero-highlights/tests/PageHeroHighlights.spec.ts +10 -10
- package/app/components/04.templates/page-hero-highlights/tests/PageHeroHighlightsHeader.spec.ts +7 -7
- package/app/components/04.templates/page-hero-highlights/tests/__snapshots__/PageHeroHighlights.spec.ts.snap +6 -6
- package/app/components/05.forms/form-errors/CONSUMER-STYLING.md +112 -0
- package/app/components/05.forms/form-errors/InputError.vue +101 -122
- package/app/components/05.forms/form-errors/stories/InputError.stories.ts +125 -0
- package/app/components/05.forms/form-errors/tests/InputError.spec.ts +82 -31
- package/app/components/05.forms/form-field/CONSUMER-STYLING.md +91 -0
- package/app/components/05.forms/form-field/FormField.vue +26 -35
- package/app/components/05.forms/form-field/stories/FormField.stories.ts +104 -0
- package/app/components/05.forms/form-field/tests/FormField.spec.ts +75 -0
- package/app/components/05.forms/form-fieldset/CONSUMER-STYLING.md +88 -0
- package/app/components/05.forms/form-fieldset/FormFieldset.vue +34 -28
- package/app/components/05.forms/form-fieldset/stories/FormFieldset.stories.ts +84 -0
- package/app/components/05.forms/form-fieldset/tests/FormFieldset.spec.ts +111 -0
- package/app/components/05.forms/form-wrapper/CONSUMER-STYLING.md +101 -0
- package/app/components/05.forms/form-wrapper/FormWrapper.vue +32 -15
- package/app/components/05.forms/form-wrapper/stories/FormWrapper.stories.ts +75 -0
- package/app/components/05.forms/form-wrapper/tests/FormWrapper.spec.ts +57 -0
- package/app/components/05.forms/input-button/CONSUMER-STYLING.md +52 -7
- package/app/components/05.forms/input-button/{InputButtonCore.vue → InputButton.vue} +60 -18
- package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts → input-button.playwright.ts} +5 -5
- package/app/components/05.forms/input-button/stories/{InputButtonCore.stories.ts → InputButton.stories.ts} +8 -10
- package/app/components/05.forms/input-button/tests/{InputButtonCore.spec.ts → InputButton.spec.ts} +75 -19
- package/app/components/05.forms/input-button/tests/__snapshots__/{InputButtonCore.spec.ts.snap → InputButton.spec.ts.snap} +18 -18
- package/app/components/05.forms/input-checkbox/CONSUMER-STYLING.md +93 -0
- package/app/components/05.forms/input-checkbox/MultipleCheckboxes.vue +19 -25
- package/app/components/05.forms/input-checkbox/SingleCheckbox.vue +17 -43
- package/app/components/05.forms/input-checkbox/stories/MultipleCheckboxes.stories.ts +104 -0
- package/app/components/05.forms/input-checkbox/stories/SingleCheckbox.stories.ts +75 -0
- package/app/components/05.forms/input-checkbox/tests/MultipleCheckboxes.spec.ts +91 -53
- package/app/components/05.forms/input-checkbox/tests/SingleCheckbox.spec.ts +112 -0
- package/app/components/05.forms/input-checkbox-radio/CONSUMER-STYLING.md +115 -35
- package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadio.vue +158 -0
- package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioButton.vue +102 -101
- package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioField.vue +100 -0
- package/app/components/05.forms/input-checkbox-radio/stories/{InputCheckboxRadioCore.stories.ts → InputCheckboxRadio.stories.ts} +23 -8
- package/app/components/05.forms/input-checkbox-radio/stories/InputCheckboxRadioButton.stories.ts +60 -16
- package/app/components/05.forms/input-checkbox-radio/stories/InputCheckboxRadioField.stories.ts +93 -0
- package/app/components/05.forms/input-checkbox-radio/tests/InputCheckboxRadio.spec.ts +174 -0
- package/app/components/05.forms/input-checkbox-radio/tests/InputCheckboxRadioButton.spec.ts +87 -0
- package/app/components/05.forms/input-checkbox-radio/tests/InputCheckboxRadioField.spec.ts +87 -0
- package/app/components/05.forms/input-description/CONSUMER-STYLING.md +177 -0
- package/app/components/05.forms/input-description/InputDescription.vue +45 -24
- package/app/components/05.forms/input-description/stories/InputDescription.stories.ts +160 -0
- package/app/components/05.forms/input-description/tests/InputDescription.spec.ts +62 -386
- package/app/components/05.forms/input-label/CONSUMER-STYLING.md +134 -0
- package/app/components/05.forms/input-label/InputLabel.vue +99 -38
- package/app/components/05.forms/input-label/stories/InputLabel.stories.ts +236 -0
- package/app/components/05.forms/input-label/tests/InputLabel.spec.ts +113 -342
- package/app/components/05.forms/input-number/CONSUMER-STYLING.md +16 -7
- package/app/components/05.forms/input-number/{InputNumberCore.vue → InputNumber.vue} +6 -6
- package/app/components/05.forms/input-number/{variants/InputNumberDefault.vue → InputNumberField.vue} +12 -15
- package/app/components/05.forms/input-number/stories/{InputNumberCore.stories.ts → InputNumber.stories.ts} +6 -6
- package/app/components/05.forms/input-number/{variants/stories/InputNumberDefault.stories.ts → stories/InputNumberField.stories.ts} +5 -5
- package/app/components/05.forms/input-number/tests/{InputNumberCore.spec.ts → InputNumber.spec.ts} +2 -2
- package/app/components/05.forms/input-number/{variants/tests/InputNumberDefault.spec.ts → tests/InputNumberField.spec.ts} +8 -8
- package/app/components/05.forms/input-radio/CONSUMER-STYLING.md +70 -0
- package/app/components/05.forms/input-radio/MultipleRadiobuttons.vue +19 -30
- package/app/components/05.forms/input-radio/stories/MultipleRadiobuttons.stories.ts +116 -0
- package/app/components/05.forms/input-radio/tests/MultipleRadioButtons.spec.ts +125 -74
- package/app/components/05.forms/input-range/CONSUMER-STYLING.md +13 -0
- package/app/components/05.forms/input-range/InputRangeCore.vue +1 -1
- package/app/components/05.forms/input-range/{variants/InputRangeDefault.vue → InputRangeDefault.vue} +7 -11
- package/app/components/05.forms/input-range/{variants/tests → tests}/InputRangeDefault.spec.ts +1 -1
- package/app/components/05.forms/input-select/CONSUMER-STYLING.md +11 -2
- package/app/components/05.forms/input-select/{variants/InputSelectWithLabel.vue → InputSelectWithLabel.vue} +6 -9
- package/app/components/05.forms/input-select/stories/InputSelectWithLabel.stories.ts +1 -1
- package/app/components/05.forms/input-text/CONSUMER-STYLING.md +12 -3
- package/app/components/05.forms/input-text/{variants/InputPasswordWithLabel.vue → InputPasswordWithLabel.vue} +3 -3
- package/app/components/05.forms/input-text/{variants/InputTextAsNumberWithLabel.vue → InputTextAsNumberWithLabel.vue} +12 -15
- package/app/components/05.forms/input-text/InputTextCore.vue +8 -11
- package/app/components/05.forms/input-text/{variants/InputTextWithLabel.vue → InputTextWithLabel.vue} +9 -10
- package/app/components/05.forms/input-text/stories/InputPasswordWithLabel.stories.ts +1 -1
- package/app/components/05.forms/input-text/stories/InputTextAsNumberWithLabel.stories.ts +1 -1
- package/app/components/05.forms/input-text/stories/InputTextWithLabel.stories.ts +1 -1
- package/app/components/05.forms/input-text/tests/InputPasswordWithLabel.spec.ts +2 -1
- package/app/components/05.forms/input-text/tests/InputTextAsNumberWithLabel.spec.ts +1 -1
- package/app/components/05.forms/input-text/tests/InputTextWithLabel.spec.ts +2 -1
- package/app/components/05.forms/input-textarea/CONSUMER-STYLING.md +11 -2
- package/app/components/05.forms/input-textarea/{variants/InputTextareaWithLabel.vue → InputTextareaWithLabel.vue} +3 -7
- package/app/components/05.forms/input-textarea/stories/InputTextareaWithLabel.stories.ts +1 -1
- package/app/components/05.forms/patterns/stories/ContactForm.stories.ts +9 -10
- package/app/components/05.forms/patterns/stories/LoginForm.stories.ts +10 -10
- package/app/components/05.forms/patterns/stories/MigratedFieldsForm.stories.ts +246 -101
- package/app/components/05.forms/pending-effect/CONSUMER-STYLING.md +92 -0
- package/app/components/05.forms/pending-effect/PendingEffect.vue +52 -45
- package/app/components/05.forms/pending-effect/stories/PendingEffect.stories.ts +132 -0
- package/app/components/05.forms/pending-effect/tests/PendingEffect.spec.ts +67 -0
- package/app/components/05.forms/toggle-switch/CONSUMER-STYLING.md +11 -2
- package/app/components/05.forms/toggle-switch/ToggleSwitchCore.vue +10 -29
- package/app/components/05.forms/toggle-switch/{variants/ToggleSwitchWithLabel.vue → ToggleSwitchWithLabel.vue} +5 -7
- package/app/components/05.forms/toggle-switch/{variants/ToggleSwitchWithLabelInline.vue → ToggleSwitchWithLabelInline.vue} +2 -4
- package/app/components/05.forms/toggle-switch/stories/ToggleSwitchWithLabel.stories.ts +1 -1
- package/app/components/05.forms/toggle-switch/stories/ToggleSwitchWithLabelInline.stories.ts +4 -1
- package/app/components/05.forms/toggle-switch/{variants/tests → tests}/ToggleSwitchWithLabel.spec.ts +26 -0
- package/app/components/05.forms/triple-toggle-switch/CONSUMER-STYLING.md +75 -62
- package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitch.vue +243 -0
- package/app/components/05.forms/triple-toggle-switch/stories/TripleToggleSwitch.stories.ts +104 -0
- package/app/components/05.forms/triple-toggle-switch/tests/TripleToggleSwitch.spec.ts +138 -0
- package/app/composables/tests/useCancellableTimer.spec.ts +48 -0
- package/app/composables/tests/useMaxChildWidth.spec.ts +67 -0
- package/app/composables/useCancellableTimer.ts +27 -7
- package/app/composables/useMaxChildWidth.ts +4 -6
- package/app/types/app-config.d.ts +10 -0
- package/app/types/components/cookie-consent-banner.d.ts +3 -0
- package/app/types/components/index.ts +6 -1
- package/app/types/components/opening-hours.d.ts +48 -0
- package/app/types/components/price-list.d.ts +11 -0
- package/app/types/components/profile-section.d.ts +6 -0
- package/app/types/components/samaritan-prompt.d.ts +13 -0
- package/app/types/components/services-card.d.ts +9 -0
- package/app/types/components/slider-gallery.d.ts +2 -0
- package/app/types/components/social-icons-list.d.ts +2 -0
- package/app/types/forms/types.forms.d.ts +3 -0
- package/app/types/forms/types.zodFormControl.d.ts +0 -3
- package/app/utils/opening-hours.ts +44 -0
- package/nuxt.config.ts +5 -1
- package/package.json +2 -2
- package/ramps.config.mjs +1 -1
- package/.claude/commands/create-commit-message.md +0 -13
- package/.claude/commands/create-release-notes.md +0 -34
- package/.claude/commands/migrate-component.md +0 -169
- package/.claude/commands/run-commit.md +0 -13
- package/.claude/component-ledger/artifact-url.txt +0 -1
- package/.claude/component-ledger/audit.json +0 -1
- package/.claude/component-ledger/build.mjs +0 -164
- package/.claude/component-ledger/output.html +0 -569
- package/.claude/component-ledger/template.html +0 -569
- package/.claude/hooks/check-component-update.sh +0 -95
- package/.claude/hooks/refresh-component-ledger.sh +0 -32
- package/.claude/settings.json +0 -134
- package/.claude/settings.local.json +0 -38
- package/.claude/skills/components/alert-content-inner.md +0 -60
- package/.claude/skills/components/navigation-horizontal.md +0 -99
- package/.claude/skills/components/samaritan-prompt-mixed.md +0 -139
- package/app/components/01.atoms/content-wrappers/content-columns-2/ContentColumns2.vue +0 -51
- package/app/components/01.atoms/content-wrappers/content-columns-2/stories/ContentColumns2.stories.ts +0 -110
- package/app/components/01.atoms/content-wrappers/content-columns-2/tests/ContentColumns2.spec.ts +0 -105
- package/app/components/01.atoms/content-wrappers/content-columns-2/tests/__snapshots__/ContentColumns2.spec.ts.snap +0 -14
- package/app/components/01.atoms/content-wrappers/content-width/ContentWidth.vue +0 -88
- package/app/components/01.atoms/content-wrappers/content-width/stories/ContentWidth.stories.ts +0 -362
- package/app/components/01.atoms/content-wrappers/content-width/tests/ContentWidth.spec.ts +0 -132
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGrid.spec.ts.snap +0 -36
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/LayoutGridByWidth.vue +0 -70
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/stories/LayoutGridByWidth.stories.ts +0 -220
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/LayoutGridByWidth.spec.ts +0 -174
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGrid.spec.ts.snap +0 -36
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +0 -36
- package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGridByWidth.spec.ts.snap +0 -36
- package/app/components/01.atoms/cookie-consent-banner/CookieConsentBanner.vue +0 -148
- package/app/components/01.atoms/display-avatar/DisplayAvatar.vue +0 -130
- package/app/components/01.atoms/display-avatar/tests/__snapshots__/DisplayAvatar.spec.ts.snap +0 -11
- package/app/components/02.molecules/action-menu/tests/__snapshots__/ActionMenuItemCore.spec.ts.snap +0 -27
- package/app/components/02.molecules/navigation/navigation-horizontal/NavigationHorizontal.vue +0 -162
- package/app/components/02.molecules/navigation/navigation-horizontal/stories/NavigationHorizontal.stories.ts +0 -373
- package/app/components/02.molecules/navigation/navigation-horizontal/tests/NavigationHorizontal.spec.ts +0 -152
- package/app/components/02.molecules/navigation/navigation-horizontal/tests/__snapshots__/NavigationHorizontal.spec.ts.snap +0 -17
- package/app/components/02.molecules/qr-code/stories/QrCode.stories.ts +0 -101
- package/app/components/03.organisms/colour-finder/ColourFinder.vue +0 -1519
- package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioCore.vue +0 -202
- package/app/components/05.forms/input-checkbox-radio/InputCheckboxRadioWithLabel.vue +0 -105
- package/app/components/05.forms/input-checkbox-radio/tests/InputCheckboxRadioCore.spec.ts +0 -320
- package/app/components/05.forms/triple-toggle-switch/TripleToggleSwitchCore.vue +0 -314
- package/app/components/05.forms/triple-toggle-switch/stories/TripleToggleSwitchCore.stories.ts +0 -63
- package/.vscode/{srcdev-component-dialog.code-snippets → srcdev-component-display-dialog.code-snippets} +0 -0
- package/app/components/{01.atoms → 02.molecules}/toast/tests/DisplayToast.spec.ts +1 -1
- /package/app/components/{01.atoms → 02.molecules}/toast/tests/DisplayToastProvider.spec.ts +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-secondary-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-secondary-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-secondary-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-tertiary-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-tertiary-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-icons-tertiary-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-primary-pending-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-primary-pending-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-primary-pending-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-secondary-pill-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-secondary-pill-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-secondary-pill-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-tertiary-readonly-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-tertiary-readonly-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/combo-tertiary-readonly-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-default-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-default-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-default-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-error-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-error-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-error-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-success-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-success-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-success-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-warning-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-warning-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-theme-warning-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-primary-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-primary-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-primary-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-secondary-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-secondary-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-secondary-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-tertiary-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-tertiary-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-variant-tertiary-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/default-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/nuxt-icon-only-component-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/nuxt-icon-only-component-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/nuxt-icon-only-component-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pending-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pending-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pending-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pill-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pill-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-pill-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-readonly-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-readonly-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/state-readonly-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/with-both-nuxt-icon-components-chromium-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/with-both-nuxt-icon-components-firefox-darwin.png +0 -0
- /package/app/components/05.forms/input-button/playwright/{input-button-core.playwright.ts-snapshots → input-button.playwright.ts-snapshots}/with-both-nuxt-icon-components-webkit-darwin.png +0 -0
- /package/app/components/05.forms/input-range/{variants/stories → stories}/InputRangeDefault.stories.ts +0 -0
- /package/app/components/05.forms/input-select/{variants/tests → tests}/InputSelectWithLabel.spec.ts +0 -0
- /package/app/components/05.forms/input-textarea/{variants/tests → tests}/InputTextareaWithLabel.spec.ts +0 -0
- /package/app/components/05.forms/toggle-switch/{variants/tests → tests}/ToggleSwitchWithLabelInline.spec.ts +0 -0
- /package/app/types/components/{navigation-horizontal.d.ts → nav-item.d.ts} +0 -0
|
@@ -88,7 +88,7 @@ Self-bound (the component renders its own heading and binds `headingId` internal
|
|
|
88
88
|
action needed):
|
|
89
89
|
|
|
90
90
|
- `ServiceSummary` (03.organisms) — binds it to its own title `HeroText`
|
|
91
|
-
- `LayoutGridByCols`
|
|
91
|
+
- `LayoutGridByCols` (01.atoms) — renders its own visually-hidden `<p>` from the `label` prop (only when `label` is set; a `section` without one gets no `aria-labelledby`, and the composable warns)
|
|
92
92
|
|
|
93
93
|
Not using this pattern:
|
|
94
94
|
|
|
@@ -77,7 +77,6 @@ Slots are rendered in document order.
|
|
|
77
77
|
|
|
78
78
|
- `app/components/01.atoms/card/CardCore.vue`
|
|
79
79
|
- `app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/LayoutGridByCols.vue`
|
|
80
|
-
- `app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/LayoutGridByWidth.vue`
|
|
81
80
|
- `app/components/container-glow/ContainerGlowCore.vue`
|
|
82
81
|
|
|
83
82
|
---
|
|
@@ -11,7 +11,7 @@ Types defined inline in a `.vue` component file are not easily importable by con
|
|
|
11
11
|
Create `app/types/components/<component-name>.d.ts` with the exported interfaces:
|
|
12
12
|
|
|
13
13
|
```ts
|
|
14
|
-
// app/types/components/
|
|
14
|
+
// app/types/components/nav-item.d.ts
|
|
15
15
|
export interface NavItem {
|
|
16
16
|
text: string;
|
|
17
17
|
href?: string;
|
|
@@ -30,7 +30,7 @@ export interface NavItemData {
|
|
|
30
30
|
In `app/types/components/index.ts`, add an export line:
|
|
31
31
|
|
|
32
32
|
```ts
|
|
33
|
-
export * from "./
|
|
33
|
+
export * from "./nav-item.d"
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
### 3. Update the component
|
|
@@ -43,7 +43,7 @@ export interface NavItem { ... }
|
|
|
43
43
|
export interface NavItemData { ... }
|
|
44
44
|
|
|
45
45
|
// After
|
|
46
|
-
import type { NavItem, NavItemData } from "~/types/components/
|
|
46
|
+
import type { NavItem, NavItemData } from "~/types/components/nav-item.d";
|
|
47
47
|
```
|
|
48
48
|
|
|
49
49
|
## Consuming app usage
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
When a component needs an action button visually attached to an input-like wrapper (e.g. copy-to-clipboard, search-submit), use `
|
|
5
|
+
When a component needs an action button visually attached to an input-like wrapper (e.g. copy-to-clipboard, search-submit), use `InputButton variant="inline"` rather than a raw `<button>`. The `inline` variant applies no built-in styles intentionally — the parent component's CSS provides all context. This keeps the button consistent with the rest of the input system (focus rings, hover tokens, transition timing) without duplicating the button style system.
|
|
6
6
|
|
|
7
7
|
## Pattern
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@ When a component needs an action button visually attached to an input-like wrapp
|
|
|
10
10
|
<template>
|
|
11
11
|
<div class="my-wrapper" :class="{ 'some-state': isActive }">
|
|
12
12
|
<input class="my-field" ... />
|
|
13
|
-
<
|
|
13
|
+
<InputButton
|
|
14
14
|
type="button"
|
|
15
15
|
variant="inline"
|
|
16
16
|
class="my-action-button"
|
|
@@ -21,16 +21,16 @@ When a component needs an action button visually attached to an input-like wrapp
|
|
|
21
21
|
<template v-if="slots.icon" #left>
|
|
22
22
|
<slot name="icon"></slot>
|
|
23
23
|
</template>
|
|
24
|
-
</
|
|
24
|
+
</InputButton>
|
|
25
25
|
</div>
|
|
26
26
|
</template>
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
-
`aria-label` is not a declared prop on
|
|
29
|
+
`aria-label` is not a declared prop on InputButton — it falls through to the root element via Vue's default `inheritAttrs: true`.
|
|
30
30
|
|
|
31
31
|
## CSS
|
|
32
32
|
|
|
33
|
-
Target `.my-action-button.input-button
|
|
33
|
+
Target `.my-action-button.input-button` inside the wrapper to override InputButton's defaults. Use theme tokens — not private `--_` tokens — for colours that already have theme equivalents:
|
|
34
34
|
|
|
35
35
|
```css
|
|
36
36
|
@layer components {
|
|
@@ -41,7 +41,7 @@ Target `.my-action-button.input-button-core` inside the wrapper to override Inpu
|
|
|
41
41
|
border-radius: var(--form-input-border-radius);
|
|
42
42
|
background-color: var(--theme-input-surface);
|
|
43
43
|
|
|
44
|
-
.my-action-button.input-button
|
|
44
|
+
.my-action-button.input-button {
|
|
45
45
|
border-radius: 0;
|
|
46
46
|
border-inline-start: var(--form-element-border-width) solid var(--theme-input-border);
|
|
47
47
|
padding-inline: var(--input-padding-inline);
|
|
@@ -65,7 +65,7 @@ Target `.my-action-button.input-button-core` inside the wrapper to override Inpu
|
|
|
65
65
|
--_state-surface: light-dark(var(--green-01), var(--green-09));
|
|
66
66
|
--_state-text: light-dark(var(--green-08), var(--green-01));
|
|
67
67
|
|
|
68
|
-
.my-action-button.input-button
|
|
68
|
+
.my-action-button.input-button {
|
|
69
69
|
background-color: var(--_state-surface);
|
|
70
70
|
color: var(--_state-text);
|
|
71
71
|
}
|
|
@@ -8,6 +8,16 @@ on context.
|
|
|
8
8
|
|
|
9
9
|
No changes to the layer component are required for either pattern.
|
|
10
10
|
|
|
11
|
+
The main mechanism is the component's **public tokens** (`--component-name-*`, listed in its
|
|
12
|
+
`CONSUMER-STYLING.md`). They're only ever read with a fallback, never declared on the component's
|
|
13
|
+
own elements, so setting them on any ancestor you own reaches the component by normal custom
|
|
14
|
+
property inheritance. Every compliant `CONSUMER-STYLING.md` has a **Local overrides** section
|
|
15
|
+
applying this guide to that component.
|
|
16
|
+
|
|
17
|
+
> **This library's own component styles are never `scoped`.** Everything below about
|
|
18
|
+
> `<style scoped>` concerns the **consumer's** file (a page or component in the app that extends
|
|
19
|
+
> this layer), not the library.
|
|
20
|
+
|
|
11
21
|
> **⚠️ Never wrap consumer-app override `<style>` blocks in a named `@layer`** (e.g.
|
|
12
22
|
> `@layer consumer`), even though library components wrap their own styles in `@layer components`
|
|
13
23
|
> and it's tempting to mirror that. Cascade layer priority is fixed by whichever layer name is
|
|
@@ -23,6 +33,50 @@ No changes to the layer component are required for either pattern.
|
|
|
23
33
|
|
|
24
34
|
---
|
|
25
35
|
|
|
36
|
+
## Site-wide component defaults (the baseline local overrides build on)
|
|
37
|
+
|
|
38
|
+
Before any page or instance override, a consuming app usually sets its own **site-wide** values for
|
|
39
|
+
a component's public tokens: one file per component under `app/assets/styles/setup/03.theming/`,
|
|
40
|
+
each imported from that folder's `index.css` alongside `_default.css` (see
|
|
41
|
+
`consumer-styles-structure.md` for the whole `setup/` tree):
|
|
42
|
+
|
|
43
|
+
```css
|
|
44
|
+
/* app/assets/styles/setup/03.theming/_card-core.css */
|
|
45
|
+
/* CardCore — site-wide card look. */
|
|
46
|
+
:where(html) {
|
|
47
|
+
--card-core-background-color: var(--rose-01);
|
|
48
|
+
--card-core-border: 0.1rem solid var(--rose-03);
|
|
49
|
+
--card-core-border-radius: 1.2rem;
|
|
50
|
+
}
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
```css
|
|
54
|
+
/* app/assets/styles/setup/03.theming/index.css */
|
|
55
|
+
@import "./_default.css";
|
|
56
|
+
@import "./_card-core.css";
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
Why `:where(html)` rather than `:root` or `html`:
|
|
60
|
+
|
|
61
|
+
- `:where()` has **zero specificity**, so this is the weakest possible declaration on `<html>`. Any
|
|
62
|
+
other rule setting the same token on `<html>` wins without a fight: a colour-scheme selector
|
|
63
|
+
(`html[data-color-scheme="dark"] { ... }`), or a page-level `html.checkout-page { ... }`.
|
|
64
|
+
`:root` (0,1,0) would outrank or tie those and force specificity games.
|
|
65
|
+
- Page and instance overrides (the patterns below) set the token on a descendant element, so they
|
|
66
|
+
win through inheritance regardless of specificity: the nearest declaration is what the component
|
|
67
|
+
reads.
|
|
68
|
+
- Keep these files unlayered, same as everything else here (see the warning above).
|
|
69
|
+
|
|
70
|
+
Only set tokens the component's current `CONSUMER-STYLING.md` lists. Components that haven't been
|
|
71
|
+
through `/migrate-component` yet may still rename tokens when they are, so check a site-defaults
|
|
72
|
+
file against the doc after upgrading the layer.
|
|
73
|
+
|
|
74
|
+
Use this for "every instance on the site should look like this"; use the patterns below for
|
|
75
|
+
"this page/section/instance differs from the site default". A component's `CONSUMER-STYLING.md`
|
|
76
|
+
**Global theming** section, when it has one, is a starting point for this file.
|
|
77
|
+
|
|
78
|
+
---
|
|
79
|
+
|
|
26
80
|
## Pattern 1 — Page-level scoping (preferred for single-use or section-scoped instances)
|
|
27
81
|
|
|
28
82
|
The consuming page has a unique wrapper or body class. The `<style>` block is **unscoped** — no
|
|
@@ -34,7 +88,7 @@ scope. No `:deep()` is needed.
|
|
|
34
88
|
<template>
|
|
35
89
|
<div class="contact-page">
|
|
36
90
|
<div class="hero-section">
|
|
37
|
-
<
|
|
91
|
+
<CardCore>...</CardCore>
|
|
38
92
|
</div>
|
|
39
93
|
</div>
|
|
40
94
|
</template>
|
|
@@ -43,19 +97,13 @@ scope. No `:deep()` is needed.
|
|
|
43
97
|
<style lang="css">
|
|
44
98
|
.contact-page {
|
|
45
99
|
.hero-section {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
--theme-social-icon-gap: 2rem;
|
|
50
|
-
color: var(--colour-brand-primary); /* drives currentColor on icons */
|
|
100
|
+
/* Public tokens: set on your own element, inherited by the component */
|
|
101
|
+
--card-core-background-color: var(--colour-brand-surface);
|
|
102
|
+
--card-core-border-radius: 1.6rem;
|
|
51
103
|
|
|
52
|
-
|
|
104
|
+
/* Direct property on the component root, only where no token covers it */
|
|
105
|
+
.card-core {
|
|
53
106
|
margin-block-start: 1.6rem;
|
|
54
|
-
|
|
55
|
-
.social-icon-link {
|
|
56
|
-
border-radius: 0.4rem;
|
|
57
|
-
padding: 0.4rem;
|
|
58
|
-
}
|
|
59
107
|
}
|
|
60
108
|
}
|
|
61
109
|
}
|
|
@@ -66,29 +114,29 @@ scope. No `:deep()` is needed.
|
|
|
66
114
|
use that as the root scope for all page-specific overrides:
|
|
67
115
|
|
|
68
116
|
```ts
|
|
69
|
-
useHead({ bodyAttrs: { class: "contact-page" } })
|
|
117
|
+
useHead({ bodyAttrs: { class: "contact-page" } });
|
|
70
118
|
```
|
|
71
119
|
|
|
72
120
|
```css
|
|
73
121
|
/* All overrides for the page nested under the body class */
|
|
74
122
|
.contact-page {
|
|
75
|
-
|
|
123
|
+
--card-core-border-radius: 1.6rem;
|
|
76
124
|
.hero-text { ... }
|
|
77
125
|
}
|
|
78
126
|
```
|
|
79
127
|
|
|
80
|
-
>
|
|
128
|
+
> \**⚠️ Do not use `bodyAttrs.class` as the scope for a page's *own* local `<style>` overrides if the
|
|
81
129
|
> app uses `pageTransition`/`layoutTransition` (see `page-transitions.md`) — it races and breaks
|
|
82
130
|
> mid-transition. `unhead` swaps `<body>`'s class the instant the *incoming* route's component sets
|
|
83
131
|
> up, which happens as soon as navigation starts — not when the *outgoing* page's leave-transition
|
|
84
132
|
> finishes animating. For a real transition duration (not an instant swap), the outgoing page is
|
|
85
|
-
> still visible and mid-fade while `<body>` already carries the *new
|
|
133
|
+
> still visible and mid-fade while `<body>` already carries the *new\* page's class. Any selector
|
|
86
134
|
> that depends on the old body class as an ancestor (`.contact-page .hero-bg-image { position:
|
|
87
|
-
|
|
135
|
+
absolute; ... }`) stops matching mid-fade, and the affected element snaps to unstyled/intrinsic
|
|
88
136
|
> sizing for the rest of the transition — confirmed via direct DOM/computed-style polling against a
|
|
89
137
|
> real `npm run build` + preview, not dev-server guesswork.
|
|
90
138
|
>
|
|
91
|
-
> Keep `bodyAttrs.class` for its legitimate use — a hook for
|
|
139
|
+
> Keep `bodyAttrs.class` for its legitimate use — a hook for _persistent_ components (header, nav)
|
|
92
140
|
> that live outside the transitioning page to react to "which page is active." For a page's own
|
|
93
141
|
> local overrides, put a matching class directly on the page's own template root instead, so the
|
|
94
142
|
> scope lives on the exact element that's fading and can never desync from what's rendered:
|
|
@@ -114,8 +162,13 @@ useHead({ bodyAttrs: { class: "contact-page" } })
|
|
|
114
162
|
## Pattern 2 — Per-instance modifier via styleClassPassthrough
|
|
115
163
|
|
|
116
164
|
Use when the same component appears multiple times on a page and you need to target a specific
|
|
117
|
-
instance
|
|
118
|
-
|
|
165
|
+
instance.
|
|
166
|
+
|
|
167
|
+
If the component you're rendering is a **wrapper** that doesn't forward `styleClassPassthrough` to
|
|
168
|
+
the inner component you want to style (e.g. `InputDescription` inside `InputTextWithLabel`), put a
|
|
169
|
+
plain `class` on the wrapper instead. Vue falls it through to the wrapper's root element, which is
|
|
170
|
+
an ancestor of the inner component, so tokens set there inherit down. This needs the wrapper to
|
|
171
|
+
have a single root element and not set `inheritAttrs: false`.
|
|
119
172
|
|
|
120
173
|
```vue
|
|
121
174
|
<CardCore :style-class-passthrough="['featured-card']">
|
|
@@ -133,11 +186,11 @@ scoping.
|
|
|
133
186
|
.card-core {
|
|
134
187
|
&.featured-card {
|
|
135
188
|
/* Colours */
|
|
136
|
-
/* --
|
|
137
|
-
/* --
|
|
189
|
+
/* --card-core-background-color: var(--brand-primary); */
|
|
190
|
+
/* --card-core-border: 0.1rem solid var(--brand-secondary); */
|
|
138
191
|
|
|
139
192
|
/* Geometry */
|
|
140
|
-
/* border-radius: 1.6rem; */
|
|
193
|
+
/* --card-core-border-radius: 1.6rem; */
|
|
141
194
|
}
|
|
142
195
|
}
|
|
143
196
|
</style>
|
|
@@ -148,10 +201,40 @@ path: `.card-core.featured-card .card-row-header { ... }`.
|
|
|
148
201
|
|
|
149
202
|
---
|
|
150
203
|
|
|
204
|
+
## Consumer files using `<style scoped>`
|
|
205
|
+
|
|
206
|
+
Vue adds the consuming file's scope attribute (`[data-v-xxxx]`) to the last compound selector of
|
|
207
|
+
every rule in a scoped block. Your own template elements carry that attribute; the library
|
|
208
|
+
component's elements don't. So:
|
|
209
|
+
|
|
210
|
+
| Override | In a consumer's scoped block |
|
|
211
|
+
| --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
|
212
|
+
| Public token set on **your own** element (`.contact-page { --card-core-border-radius: 1.6rem; }`) | Works unchanged: your element matches, and the token inherits into the component |
|
|
213
|
+
| Class/attribute on the component's **root** passed from your template (`:style-class-passthrough`, or `class` fallthrough) | Works: Vue also puts your scope attribute on a child component's root element |
|
|
214
|
+
| Anything **inside** the component (`.card-core-header`, `.input-description[data-invalid]` when the description is nested in a wrapper) | Doesn't match. Wrap it in `:deep()`, or move it to an unscoped `<style>` block |
|
|
215
|
+
|
|
216
|
+
```vue
|
|
217
|
+
<style scoped>
|
|
218
|
+
.contact-page {
|
|
219
|
+
--input-description-font-size: 1.4rem; /* works as-is */
|
|
220
|
+
|
|
221
|
+
:deep(.input-description[data-invalid]) {
|
|
222
|
+
--input-description-color: var(--theme-error-border);
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
</style>
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Prefer tokens on your own element wherever one exists: it works the same in scoped and unscoped
|
|
229
|
+
files and doesn't depend on the component's internal class names.
|
|
230
|
+
|
|
231
|
+
---
|
|
232
|
+
|
|
151
233
|
## When to offer a scaffold
|
|
152
234
|
|
|
153
235
|
After placing a component in a consuming page or component, offer a CSS override scaffold. Use the
|
|
154
|
-
component's own class name and
|
|
236
|
+
component's own class name and the public `--component-name-*` tokens listed in its
|
|
237
|
+
`CONSUMER-STYLING.md` as commented stubs. Cover theming
|
|
155
238
|
(colours, tokens) and geometry (sizes, spacing, borders) — not behaviour (`display`, `pointer-events`,
|
|
156
239
|
`z-index`, animations).
|
|
157
240
|
|
|
@@ -159,11 +242,11 @@ component's own class name and any `--theme-*` tokens it exposes as commented st
|
|
|
159
242
|
|
|
160
243
|
## What to override
|
|
161
244
|
|
|
162
|
-
| Category
|
|
163
|
-
|
|
164
|
-
| Theming
|
|
165
|
-
| Geometry
|
|
166
|
-
| Border / outline | width, style, colour
|
|
245
|
+
| Category | Examples | Approach |
|
|
246
|
+
| ---------------- | -------------------------------------- | ---------------------------------------------------------- |
|
|
247
|
+
| Theming | icon colour, background, border colour | The component's public tokens; otherwise a direct property |
|
|
248
|
+
| Geometry | border-radius, padding, gap, size | The component's public tokens; otherwise a direct property |
|
|
249
|
+
| Border / outline | width, style, colour | The component's public tokens; otherwise a direct property |
|
|
167
250
|
|
|
168
251
|
**Do not override behaviour** — `display`, `visibility`, `pointer-events`, `z-index`, animations.
|
|
169
252
|
Those belong in the component or a structural parent.
|
|
@@ -172,36 +255,34 @@ Those belong in the component or a structural parent.
|
|
|
172
255
|
|
|
173
256
|
## CSS custom property targeting
|
|
174
257
|
|
|
175
|
-
Components expose
|
|
258
|
+
Components expose **public** tokens named after the component (`--card-core-border-radius`,
|
|
259
|
+
`--input-description-color`) and may use **private** `--_` tokens internally:
|
|
176
260
|
|
|
177
261
|
```css
|
|
178
|
-
/*
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
.social-icons-list {
|
|
182
|
-
--theme-social-icon-size: 3.2rem;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/* Override via --_ private token (fragile — may break on component update): */
|
|
186
|
-
.social-icons-list {
|
|
187
|
-
&.my-modifier {
|
|
188
|
-
--_icon-size: 3.2rem;
|
|
189
|
-
}
|
|
262
|
+
/* Public token (stable API, recommended): set on any ancestor you own */
|
|
263
|
+
.contact-page {
|
|
264
|
+
--card-core-border-radius: 1.6rem;
|
|
190
265
|
}
|
|
191
266
|
```
|
|
192
267
|
|
|
193
|
-
|
|
268
|
+
Private `--_` tokens are internal implementation detail and can change or disappear in any
|
|
269
|
+
release. Don't override them. If a value you need has no public token, that's a gap in the
|
|
270
|
+
component: raise it (or fix it in the library) rather than depending on the private name.
|
|
271
|
+
|
|
272
|
+
Some older, not-yet-migrated components still read global `--theme-*` tokens directly instead of
|
|
273
|
+
their own component tokens (see CLAUDE.md pitfall #14). Those work as ancestor overrides too, but
|
|
274
|
+
they're shared by every component reading them, so scope the override tightly.
|
|
194
275
|
|
|
195
276
|
---
|
|
196
277
|
|
|
197
278
|
## When to use this vs other approaches
|
|
198
279
|
|
|
199
|
-
| Situation
|
|
200
|
-
|
|
201
|
-
| One-off visual tweak for a specific page/context
|
|
280
|
+
| Situation | Approach |
|
|
281
|
+
| ---------------------------------------------------- | --------------------------------------------- |
|
|
282
|
+
| One-off visual tweak for a specific page/context | Local style override (this skill) |
|
|
202
283
|
| Consistent appearance across all instances site-wide | Default theme (`theming-override-default.md`) |
|
|
203
|
-
| Variant that belongs in the component itself
|
|
204
|
-
| Structural layout change
|
|
284
|
+
| Variant that belongs in the component itself | Add a `variant` prop value to the component |
|
|
285
|
+
| Structural layout change | Wrapper element or parent component |
|
|
205
286
|
|
|
206
287
|
### Component type guide
|
|
207
288
|
|
|
@@ -211,10 +292,13 @@ Prefer `--theme-*` tokens. Only target `--_` private variables when no `--theme-
|
|
|
211
292
|
- Layout wrappers used in a specific visual context (e.g. a grid section with a tinted background)
|
|
212
293
|
- Any component whose appearance legitimately varies per page or usage context
|
|
213
294
|
|
|
214
|
-
**
|
|
295
|
+
**Usually better themed globally:**
|
|
215
296
|
|
|
216
297
|
- Form elements and interactive controls — inputs, buttons, toggles, checkboxes
|
|
217
298
|
- Typography components used for consistency across the site
|
|
218
299
|
- Anything where visual inconsistency between instances would be a bug
|
|
219
300
|
|
|
220
|
-
|
|
301
|
+
These all expose the same public tokens, so a local override is still available when a context
|
|
302
|
+
genuinely calls for it (e.g. a form on a dark hero section). The point is the default, not a ban.
|
|
303
|
+
|
|
304
|
+
The test: _should all instances of this component look the same?_ If yes → theme. If instances are expected to look different → local override.
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# Component naming: Control / Field convention
|
|
2
|
+
|
|
3
|
+
Adopted 2026-09-25. `input-number` is the first component converted; everything else is backlog
|
|
4
|
+
(see the table below). Apply this convention to every component migrated from now on, and convert
|
|
5
|
+
previously migrated components retrospectively, one family at a time.
|
|
6
|
+
|
|
7
|
+
## The rule
|
|
8
|
+
|
|
9
|
+
| Role | Name | Root DOM class | Example |
|
|
10
|
+
|------|------|----------------|---------|
|
|
11
|
+
| Bare control (native element + its slots, no label/description/error) | `<Name>` | `.<kebab-name>` | `InputNumber` → `.input-number` |
|
|
12
|
+
| Labelled field (label + description + control + error) | `<Name>Field` | `.<kebab-name>-field` | `InputNumberField` → `.input-number-field` |
|
|
13
|
+
|
|
14
|
+
- **No `Core` suffix.** It only ever existed to tell the bare control apart from its wrapper; once
|
|
15
|
+
the wrapper is named `Field`, the control doesn't need a suffix. Components with no wrapper
|
|
16
|
+
sibling at all (`CardCore`, `TabsCore`, ...) never needed it.
|
|
17
|
+
- **No `Default` / `WithLabel` suffix on wrappers.** `Default` says nothing about what the wrapper
|
|
18
|
+
adds; `WithLabel` undersells it (it also renders description and error). "Field" is the
|
|
19
|
+
established term (Material, Radix, Ark UI, Chakra) for "control plus its label and messages".
|
|
20
|
+
- **Layout variations of a Field** are a prop on the Field (e.g. `layout="inline"`), not a new
|
|
21
|
+
suffix, unless the markup genuinely diverges; then `<Name>Field<Variant>`.
|
|
22
|
+
- **Files, stories, tests, skill doc follow the name**: `InputNumber.vue`, `stories/InputNumber.stories.ts`,
|
|
23
|
+
`tests/InputNumber.spec.ts`, `.claude/skills/components/input-number.md` (the Field is documented
|
|
24
|
+
in its control's skill doc under "Variants"). Snippet file stays `srcdev-component-<family>.code-snippets`
|
|
25
|
+
and covers both.
|
|
26
|
+
- **CSS custom properties don't change** on rename; they're already `--<family>-*` (e.g.
|
|
27
|
+
`--input-number-border`). Only the component name and its root/base DOM class change.
|
|
28
|
+
|
|
29
|
+
## Never a single word that is (or could become) a native HTML element
|
|
30
|
+
|
|
31
|
+
Stripping a suffix must never leave a single-word name that matches a native element: `Dialog`,
|
|
32
|
+
`Button`, `Select`, `Input`, `Details`, `Summary`, `Menu`, `Header`, `Footer`, `Nav`, `Form`,
|
|
33
|
+
`Label`, `Table`, `Option`, `Search`, `Slot`, `Template`, and so on. Vue refuses built-in/reserved tag
|
|
34
|
+
names as component names, and templates match tags case-insensitively, so `<Dialog>` can resolve to the
|
|
35
|
+
native `<dialog>` instead of the component. Also watch for names that *could become* an element (the
|
|
36
|
+
HTML spec keeps adding them: `<search>` and `<selectedcontent>` are recent), so don't rely on "it isn't one
|
|
37
|
+
today".
|
|
38
|
+
|
|
39
|
+
This is where the `Core` suffix originally crept in. The fix is a meaningful prefix, not a suffix:
|
|
40
|
+
`DisplayDialog` (not `DialogCore`), and the `Input*` prefix on form controls already covers
|
|
41
|
+
`InputButton`/`InputSelect`/`InputText`. Multi-word names are enforced: `eslint.config.mjs` turns on
|
|
42
|
+
`vue/multi-word-component-names` as an error for `app/components/**/*.vue` (added 2026-09-25; Nuxt's
|
|
43
|
+
base config leaves it off). `Breadcrumb` is the one existing single-word component and sits in that
|
|
44
|
+
rule's `ignores` list; it's not an element, so it's grandfathered, but don't add to that list; pick a
|
|
45
|
+
multi-word name instead. `vue/no-reserved-component-names` (already on via the Nuxt base config)
|
|
46
|
+
separately rejects exact native element names.
|
|
47
|
+
|
|
48
|
+
## Collision caveat (Nuxt layer)
|
|
49
|
+
|
|
50
|
+
This library is a Nuxt layer with `pathPrefix: false`. A consuming app's own component with the same
|
|
51
|
+
name **silently replaces the layer's**, including every place the layer uses it internally. Dropping
|
|
52
|
+
a prefix/suffix makes a name shorter and more generic, so more collision-prone. `InputNumber`,
|
|
53
|
+
`InputSelect` etc. are distinctive enough. A bare common word (`Card`, `Tabs`, `Accordion`) is the
|
|
54
|
+
risky case: marked **decide** in the backlog; consider a more specific name rather than just
|
|
55
|
+
stripping `Core`.
|
|
56
|
+
|
|
57
|
+
## How to rename a family
|
|
58
|
+
|
|
59
|
+
1. `git mv` the `.vue` files, their stories and tests (and the skill doc if it's named after the old
|
|
60
|
+
control name).
|
|
61
|
+
2. `sed` the old names across `app/`, `.claude/`, `.vscode/`, `MIGRATION.md` and `Claude.md`:
|
|
62
|
+
component names, `import` paths, story titles/`*StoryArgs` interfaces, `describe()` names, and the
|
|
63
|
+
root/base DOM class (update `CONSUMER-STYLING.md` and test selectors that use it).
|
|
64
|
+
3. Add a "Renamed YYYY-MM-DD" note at the top of the skill doc listing old → new names and classes.
|
|
65
|
+
4. Grep consumer repos (`/check-component-usage`) and **list** the files/lines that use the old
|
|
66
|
+
names (in the private consumer notes, never in this repo). Don't edit the consumers yet: they pin
|
|
67
|
+
an exact layer version, so a rename applied now breaks them until they bump. Apply the list when
|
|
68
|
+
each consumer upgrades to the release that ships the rename. No deprecated aliases are needed
|
|
69
|
+
(all consumers are the user's own apps); note the rename as breaking in the release notes.
|
|
70
|
+
(Decided 2026-09-28 during the InputButton rename.)
|
|
71
|
+
5. Tick the row off below.
|
|
72
|
+
|
|
73
|
+
## Backlog
|
|
74
|
+
|
|
75
|
+
Consumers column = whether a consuming app used the name as of 2026-09-25 (`yes`), or `-` for no
|
|
76
|
+
external consumer, free to rename. Run `/check-component-usage` for the current list before renaming.
|
|
77
|
+
|
|
78
|
+
| Current | Proposed | Consumers |
|
|
79
|
+
|---------|----------|-----------|
|
|
80
|
+
| ~~InputNumberCore~~ | ✅ `InputNumber` (2026-09-25) | - |
|
|
81
|
+
| ~~InputNumberDefault~~ | ✅ `InputNumberField` (2026-09-25) | - |
|
|
82
|
+
| InputTextCore | `InputText` | yes |
|
|
83
|
+
| InputTextWithLabel | `InputTextField` | yes |
|
|
84
|
+
| InputPasswordWithLabel | `InputPasswordField` | yes |
|
|
85
|
+
| InputTextAsNumberWithLabel | `InputTextAsNumberField` | - |
|
|
86
|
+
| InputRangeCore | `InputRange` | - |
|
|
87
|
+
| InputRangeDefault | `InputRangeField` | - |
|
|
88
|
+
| InputTextareaCore | `InputTextarea` | - |
|
|
89
|
+
| InputTextareaWithLabel | `InputTextareaField` | yes |
|
|
90
|
+
| InputSelectCore | `InputSelect` | yes |
|
|
91
|
+
| InputSelectWithLabel | `InputSelectField` | yes |
|
|
92
|
+
| ToggleSwitchCore | `ToggleSwitch` | yes |
|
|
93
|
+
| ToggleSwitchWithLabel | `ToggleSwitchField` | yes |
|
|
94
|
+
| ToggleSwitchWithLabelInline | `layout` prop on `ToggleSwitchField`, or `ToggleSwitchFieldInline` | - |
|
|
95
|
+
| ~~TripleToggleSwitchCore~~ | ✅ `TripleToggleSwitch` (2026-09-27) | - |
|
|
96
|
+
| ~~InputButtonCore~~ | ✅ `InputButton` (2026-09-28) | yes |
|
|
97
|
+
| ~~InputCheckboxRadioCore~~ | ✅ `InputCheckboxRadio` (2026-09-27) | - |
|
|
98
|
+
| InputCheckboxRadioButton | ✅ kept: button-style option, not a Field (2026-09-27) | - |
|
|
99
|
+
| ~~InputCheckboxRadioWithLabel~~ | ✅ `InputCheckboxRadioField` (2026-09-27) | - |
|
|
100
|
+
| ~~ActionMenuItemCore~~ | ✅ `ActionMenuItem` (2026-09-27) | - |
|
|
101
|
+
| AlertMaskCore | `AlertMask` | - |
|
|
102
|
+
| CardCore | **decide**: `Card` is single-word and collision-prone; prefer a prefixed name (`Display*`, `Content*`) | yes |
|
|
103
|
+
| AccordianCore | **decide**: also fixes the "Accordian" misspelling; bare `Accordion` is single-word and collision-prone, and it is built on `<details>`/`<summary>` | yes |
|
|
104
|
+
| TabsCore | **decide**: `Tabs` is single-word and collision-prone | - |
|
|
105
|
+
|
|
106
|
+
The `input-checkbox` family also has `MultipleCheckboxes`/`SingleCheckbox` on top of the Core; look
|
|
107
|
+
at how the four relate before choosing names there.
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
# ActionMenu
|
|
2
2
|
|
|
3
|
+
> **Renamed 2026-09-27:** `ActionMenuItemCore` → `ActionMenuItem`; root class `.action-menu-item-core` → `.action-menu-item`.
|
|
4
|
+
|
|
3
5
|
## Overview
|
|
4
6
|
|
|
5
7
|
`ActionMenu` is a trigger-and-popover component that shows a compact ellipsis button (`lucide:ellipsis`).
|
|
6
8
|
Clicking it opens an anchored menu list populated via indexed dynamic slots (`item-{n}`). Each slot
|
|
7
|
-
should contain a single `
|
|
9
|
+
should contain a single `ActionMenuItem` — either a `<button>` (for actions) or a link (for
|
|
8
10
|
navigation). The popover API and CSS anchor positioning handle positioning and dismiss behaviour
|
|
9
11
|
natively; no JavaScript click-outside logic is needed.
|
|
10
12
|
|
|
@@ -18,24 +20,25 @@ natively; no JavaScript click-outside logic is needed.
|
|
|
18
20
|
|
|
19
21
|
| Prop | Type | Default | Notes |
|
|
20
22
|
|---|---|---|---|
|
|
21
|
-
| `itemCount` | `number` | `0` | Number of `item-{n}` slots to render. |
|
|
22
23
|
| `label` | `string` | `"Open actions menu"` | Used as `aria-label` on the trigger and `aria-label` on the menu list. |
|
|
24
|
+
| `triggerIcon` | `string` | `"lucide:ellipsis"` | Icon on the trigger button. |
|
|
23
25
|
| `styleClassPassthrough` | `string \| string[]` | `[]` | Extra classes on the root `<div>`. |
|
|
24
26
|
|
|
25
27
|
**Slots**
|
|
26
28
|
|
|
27
29
|
| Slot | When used |
|
|
28
30
|
|---|---|
|
|
29
|
-
| `item-{n}` | One per item,
|
|
31
|
+
| `item-{n}` | One per item, `n` 0-indexed. The row count is derived from which `item-{n}` slots are present (re-evaluated every render, so items added after mount appear). Should contain one `ActionMenuItem`. |
|
|
30
32
|
|
|
31
33
|
---
|
|
32
34
|
|
|
33
|
-
###
|
|
35
|
+
### ActionMenuItem
|
|
34
36
|
|
|
35
37
|
| Prop | Type | Default | Notes |
|
|
36
38
|
|---|---|---|---|
|
|
37
39
|
| `label` | `string` | — | **Required.** Visible text for the row. |
|
|
38
40
|
| `href` | `string` | `undefined` | If set, renders as `<a>` (external) or `NuxtLink` (internal `/…` path). Omit for a `<button>`. |
|
|
41
|
+
| `arrowIcon` | `string` | `"lucide:arrow-right"` | Decorative trailing arrow icon. |
|
|
39
42
|
| `styleClassPassthrough` | `string \| string[]` | `[]` | Extra classes on the root element. |
|
|
40
43
|
|
|
41
44
|
**Slots**
|
|
@@ -62,19 +65,19 @@ natively; no JavaScript click-outside logic is needed.
|
|
|
62
65
|
```vue
|
|
63
66
|
<ActionMenu :item-count="3" label="Row actions">
|
|
64
67
|
<template #item-0>
|
|
65
|
-
<
|
|
68
|
+
<ActionMenuItem label="Edit" @click="handleEdit">
|
|
66
69
|
<template #icon><Icon name="lucide:pencil" /></template>
|
|
67
|
-
</
|
|
70
|
+
</ActionMenuItem>
|
|
68
71
|
</template>
|
|
69
72
|
<template #item-1>
|
|
70
|
-
<
|
|
73
|
+
<ActionMenuItem label="View detail" href="/records/123">
|
|
71
74
|
<template #icon><Icon name="lucide:eye" /></template>
|
|
72
|
-
</
|
|
75
|
+
</ActionMenuItem>
|
|
73
76
|
</template>
|
|
74
77
|
<template #item-2>
|
|
75
|
-
<
|
|
78
|
+
<ActionMenuItem label="Delete" @click="handleDelete">
|
|
76
79
|
<template #icon><Icon name="lucide:trash-2" /></template>
|
|
77
|
-
</
|
|
80
|
+
</ActionMenuItem>
|
|
78
81
|
</template>
|
|
79
82
|
</ActionMenu>
|
|
80
83
|
```
|
|
@@ -119,9 +122,10 @@ Quick reference:
|
|
|
119
122
|
|
|
120
123
|
## Notes
|
|
121
124
|
|
|
122
|
-
- **Popover API + CSS anchor positioning** — the menu uses `popover` attribute
|
|
123
|
-
|
|
124
|
-
|
|
125
|
+
- **Popover API + CSS anchor positioning** — the menu uses the `popover` attribute (broadly supported)
|
|
126
|
+
and `position-anchor` (newer: Chromium 125+, Safari 26+). Without anchor positioning the popover
|
|
127
|
+
still opens, just not anchored to the trigger. No polyfill is included.
|
|
128
|
+
- **Auto-close** — clicking any `<li>` row fires `hidePopover()` on the menu. The `ActionMenuItem`
|
|
125
129
|
emitting `click` triggers normally before the menu closes.
|
|
126
130
|
- **Focus management** — on open the `toggle` event fires `handleToggle`, which moves focus to the
|
|
127
131
|
first `[role="menuitem"]` inside the popover.
|
|
@@ -136,6 +140,6 @@ Quick reference:
|
|
|
136
140
|
- **`anchorName` format** — internally generated as `--action-menu-anchor-{id}` (a valid CSS
|
|
137
141
|
`<dashed-ident>`). Set via a CSS custom property on the root element so both the trigger's
|
|
138
142
|
`anchor-name` and the popover's `position-anchor` can reference the same value.
|
|
139
|
-
- **Dynamic slots stability** — `item-{n}` slots enforce that only `
|
|
143
|
+
- **Dynamic slots stability** — `item-{n}` slots enforce that only `ActionMenuItem` content
|
|
140
144
|
enters the list; arbitrary HTML inside the popover is not supported and will break the ARIA
|
|
141
145
|
`menu` / `menuitem` pattern.
|