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
|
@@ -1,13 +1,17 @@
|
|
|
1
|
-
#
|
|
1
|
+
# InputNumber Component
|
|
2
|
+
|
|
3
|
+
> **Renamed 2026-09-25**: `InputNumberCore` → `InputNumber`, `InputNumberDefault` → `InputNumberField`
|
|
4
|
+
> (DOM classes `.input-number-core` → `.input-number`, `.input-number-with-label` → `.input-number-field`).
|
|
5
|
+
> First component moved to the Control/Field naming convention, see `.claude/skills/component-naming.md`.
|
|
2
6
|
|
|
3
7
|
## Overview
|
|
4
8
|
|
|
5
|
-
`
|
|
9
|
+
`InputNumber` is the low-level native `<input type="number">` primitive for the `05.forms`
|
|
6
10
|
number-input family. It renders a single native number input with left/right button slots (for
|
|
7
11
|
step-down/step-up controls). It has no label, description, or error-message rendering of its
|
|
8
|
-
own — that's composed by the `
|
|
12
|
+
own — that's composed by the `InputNumberField` variant below.
|
|
9
13
|
|
|
10
|
-
Most consumers should reach for **
|
|
14
|
+
Most consumers should reach for **InputNumberField** rather than `InputNumber` directly.
|
|
11
15
|
|
|
12
16
|
---
|
|
13
17
|
|
|
@@ -46,10 +50,10 @@ as `InputRangeCore`'s `v-model` (see that skill doc) — this also satisfies `vu
|
|
|
46
50
|
| `left` | Rendered before the input (e.g. a step-down button). Adds `has-left-slot` to the wrapper. |
|
|
47
51
|
| `right` | Rendered after the input (e.g. a step-up button). Adds `has-right-slot` to the wrapper. |
|
|
48
52
|
|
|
49
|
-
Any `.input-button
|
|
53
|
+
Any `.input-button` inside `.slot` gets its own border/outline stripped and is sized to
|
|
50
54
|
match the input (`aspect-ratio: 1`, `width: var(--input-min-height)`) regardless of which slot
|
|
51
55
|
it's in. The divider border is then added directly to that button element specifically when its
|
|
52
|
-
slot is present — `&.has-left-slot .left-slot .input-button
|
|
56
|
+
slot is present — `&.has-left-slot .left-slot .input-button { border-right: ... }` and the
|
|
53
57
|
right-hand mirror — so it sits flush against the button's own edge rather than around the
|
|
54
58
|
containing `.slot` div. This makes step buttons read as embedded segments of the same control
|
|
55
59
|
rather than separate floating buttons. The divider reuses the wrapper's own border colour token
|
|
@@ -63,6 +67,7 @@ See [CONSUMER-STYLING.md](../../app/components/05.forms/input-number/CONSUMER-ST
|
|
|
63
67
|
full table with defaults.
|
|
64
68
|
|
|
65
69
|
**Common tokens:**
|
|
70
|
+
|
|
66
71
|
- `--input-number-surface` / `-surface-hover` — wrapper/input/embedded-button background, resting and hover, falls back to `--theme-input-surface`/`-surface-hover`
|
|
67
72
|
- `--input-number-border` / `-border-hover` / `-border-focus` — border colour resting, mouse-hover outline, and `:focus-visible` outline (also the divider colour and the embedded button's own focus outline), falls back to `--theme-border`/`--theme-border-focus`
|
|
68
73
|
- `--input-number-text-color` — input text colour, falls back to `--theme-input-text-color-normal`
|
|
@@ -72,11 +77,11 @@ full table with defaults.
|
|
|
72
77
|
|
|
73
78
|
## Fixed 2026-09-22: dead CSS from a missing base class and mismatched selectors
|
|
74
79
|
|
|
75
|
-
`
|
|
80
|
+
`InputNumber` migrated to full compliance from a `variants:true`, `eslint_issues:true`,
|
|
76
81
|
score-1/5 state. Several latent bugs were fixed alongside the standard checklist:
|
|
77
82
|
|
|
78
|
-
- The native `<input>` had no static `input-number
|
|
79
|
-
`elementClasses` passthrough — so the entire `.input-number
|
|
83
|
+
- The native `<input>` had no static `input-number` class — only the dynamic
|
|
84
|
+
`elementClasses` passthrough — so the entire `.input-number { ... }` style block (font,
|
|
80
85
|
padding, colour, focus box-shadow) never matched anything. Fixed by adding the class directly.
|
|
81
86
|
- `placeholder` was declared as a prop but never bound on the `<input>` — unlike `InputRangeCore`
|
|
82
87
|
(where a range input genuinely has no placeholder concept and the no-op is intentional and
|
|
@@ -89,20 +94,20 @@ score-1/5 state. Several latent bugs were fixed alongside the standard checklist
|
|
|
89
94
|
`slot left-slot`/`slot right-slot` and adding `has-left-slot`/`has-right-slot` to the wrapper
|
|
90
95
|
directly from `slots.left`/`slots.right` (Vue's own `useSlots()`), rather than a fragile,
|
|
91
96
|
cross-component class-toggling relay.
|
|
92
|
-
- Relatedly, `
|
|
97
|
+
- Relatedly, `InputNumberField` called `updateElementClasses(["has-left-button",
|
|
93
98
|
"has-right-button"])` unconditionally on mount, which permanently added those two classes to
|
|
94
|
-
its own outer `.input-number-
|
|
95
|
-
`
|
|
99
|
+
its own outer `.input-number-field` wrapper — a different element than
|
|
100
|
+
`InputNumber`'s `.input-number-wrapper`, so the `:has()` selector that was meant to key off
|
|
96
101
|
those classes could never match (the class lived on an ancestor, not a descendant). Replaced
|
|
97
|
-
entirely: `
|
|
98
|
-
`:has(.left-slot .input-button
|
|
102
|
+
entirely: `InputNumber` now detects an embedded button directly via
|
|
103
|
+
`:has(.left-slot .input-button)` / `:has(.right-slot .input-button)`, so no
|
|
99
104
|
JS-driven class relay is needed at all.
|
|
100
105
|
- `theme` was typed as an inline `"default" | "success" | "error" | "warning"` union in both
|
|
101
|
-
`
|
|
106
|
+
`InputNumber` and `InputNumberField` instead of importing the shared `FormUiTheme` type —
|
|
102
107
|
aligned with the rest of `05.forms`.
|
|
103
|
-
- `weight` was passed from `
|
|
108
|
+
- `weight` was passed from `InputNumberField` to `InputNumber` but `InputNumber` had no
|
|
104
109
|
matching prop, so it fell through as a raw, meaningless `weight="normal"` HTML attribute on the
|
|
105
|
-
wrapper `<div>`. Fixed by declaring the prop on `
|
|
110
|
+
wrapper `<div>`. Fixed by declaring the prop on `InputNumber` too, matching `InputRangeCore`.
|
|
106
111
|
- `defineModel()` had no default, tripping `vue/require-default-prop` — fixed the same way as
|
|
107
112
|
`InputRangeCore`: `defineModel({ required: true })`, not a rule disable or an artificial default.
|
|
108
113
|
- A single-use private token, `--_border`, was inlined to the public
|
|
@@ -114,18 +119,18 @@ score-1/5 state. Several latent bugs were fixed alongside the standard checklist
|
|
|
114
119
|
|
|
115
120
|
## Fixed 2026-09-22 (follow-up): rewritten to visually mirror InputTextCore
|
|
116
121
|
|
|
117
|
-
The first migration pass above only made `
|
|
122
|
+
The first migration pass above only made `InputNumber`'s *own* (pre-existing, previously dead)
|
|
118
123
|
CSS active — it didn't reconsider whether that CSS was actually the right design. Once live, it
|
|
119
124
|
was visually inconsistent with the rest of `05.forms`: no border-radius, no hover/focus outline
|
|
120
125
|
state, wrong padding-token family (`--form-textarea-padding-*` instead of the shared input
|
|
121
126
|
padding tokens), and a box-shadow-toggle focus mechanism instead of the `:has()`-based outline
|
|
122
|
-
approach every other input in this library uses. `
|
|
127
|
+
approach every other input in this library uses. `InputNumber` is meant to be a native
|
|
123
128
|
`<input type="number">` sibling to the text-based `InputTextAsNumberWithLabel` variant (see
|
|
124
129
|
`input-text-core.md`'s Variants section) — both should look and behave the same. The CSS was rewritten
|
|
125
130
|
to mirror `InputTextCore` directly:
|
|
126
131
|
|
|
127
132
|
- Added `:input-variant` (`"normal"` / `"outlined"` / `"underlined"`), matching `InputTextCore`'s
|
|
128
|
-
prop and wrapper-class shape (`
|
|
133
|
+
prop and wrapper-class shape (`InputNumberField` forwards it the same way
|
|
129
134
|
`InputTextWithLabel` forwards it to `InputTextCore`, including to `InputLabel`).
|
|
130
135
|
- Replaced the flat, unconditional border/radius/box-shadow with `InputTextCore`'s `.normal`
|
|
131
136
|
variant shape: border + `border-radius: var(--form-input-border-radius)` (previously this read
|
|
@@ -152,18 +157,18 @@ to mirror `InputTextCore` directly:
|
|
|
152
157
|
private wrappers. `--_border-focus` stayed private since it's now genuinely reused (the
|
|
153
158
|
wrapper's own focus outline *and* the embedded button's focus outline both read it).
|
|
154
159
|
|
|
155
|
-
**Separately found in the same investigation** (not an `
|
|
160
|
+
**Separately found in the same investigation** (not an `InputNumber` bug, but what the visual
|
|
156
161
|
comparison was originally checking against): `InputTextAsNumberWithLabel.vue` had its own,
|
|
157
162
|
unrelated pre-existing bug — see `input-text-core.md`'s Variants section for the fix.
|
|
158
163
|
|
|
159
164
|
**Correction, same day**: the first version of this rewrite still didn't visually match — the
|
|
160
165
|
divider border and button sizing (`aspect-ratio: 1`, `width: var(--input-min-height)`) had been
|
|
161
|
-
put on the `.left-slot`/`.right-slot` *wrapper divs*, not on `.input-button
|
|
166
|
+
put on the `.left-slot`/`.right-slot` *wrapper divs*, not on `.input-button` itself, unlike
|
|
162
167
|
`InputTextCore`'s equivalent block. That left an unstyled gap between the button and the border
|
|
163
168
|
line instead of a flush edge, and the buttons weren't sized to match the input's height. Fixed by
|
|
164
|
-
moving the divider border and all button sizing/colour rules onto `.input-button
|
|
165
|
-
(`&.has-left-slot .left-slot .input-button
|
|
166
|
-
`InputTextAsNumberWithLabel`'s `.left-slot .input-button
|
|
169
|
+
moving the divider border and all button sizing/colour rules onto `.input-button` directly
|
|
170
|
+
(`&.has-left-slot .left-slot .input-button { border-right: ... }`, matching
|
|
171
|
+
`InputTextAsNumberWithLabel`'s `.left-slot .input-button { border-right: ... }` exactly)
|
|
167
172
|
rather than the containing `.slot` div. When mirroring another component's CSS structure, check
|
|
168
173
|
*which element* a rule targets, not just that an equivalent rule exists somewhere in the block —
|
|
169
174
|
a border/sizing rule one level off in the DOM tree produces a visually-close-but-not-matching
|
|
@@ -173,28 +178,28 @@ result that's easy to miss without a side-by-side screenshot comparison.
|
|
|
173
178
|
|
|
174
179
|
## Variants
|
|
175
180
|
|
|
176
|
-
###
|
|
181
|
+
### InputNumberField
|
|
177
182
|
|
|
178
|
-
`
|
|
183
|
+
`InputNumberField` (`InputNumberField.vue`) composes `InputNumber` with
|
|
179
184
|
`InputLabel`, `InputDescription`, and `InputError`, plus optional step-down/step-up buttons
|
|
180
|
-
(`
|
|
185
|
+
(`InputButton`) wired into the `left`/`right` slots.
|
|
181
186
|
|
|
182
|
-
**Additional props over
|
|
187
|
+
**Additional props over InputNumber:**
|
|
183
188
|
|
|
184
189
|
| Prop (template form) | Type | Default | Notes |
|
|
185
190
|
|------|------|---------|-------|
|
|
186
191
|
| `:label` | `string` | (required) | Rendered via `InputLabel`. |
|
|
187
192
|
| `:error-message` | `object \| string` | (required) | Rendered via `InputError` when `field-has-error` is true. |
|
|
188
|
-
| `:step-down-label` | `string` | `"Step down"` | `button-text` on the step-down `
|
|
189
|
-
| `:step-up-label` | `string` | `"Step up"` | `button-text` on the step-up `
|
|
193
|
+
| `:step-down-label` | `string` | `"Step down"` | `button-text` on the step-down `InputButton` — override for localisation. |
|
|
194
|
+
| `:step-up-label` | `string` | `"Step up"` | `button-text` on the step-up `InputButton` — override for localisation. |
|
|
190
195
|
|
|
191
196
|
**Slots**: `descriptionHtml`, `descriptionText` (both forwarded to `InputDescription`), plus
|
|
192
|
-
`left`/`right` (forwarded straight through to the underlying `
|
|
197
|
+
`left`/`right` (forwarded straight through to the underlying `InputNumber` — the
|
|
193
198
|
step-down/step-up buttons only render when you use the `left`/`right` slots yourself, since the
|
|
194
199
|
button icon content itself is consumer-supplied).
|
|
195
200
|
|
|
196
201
|
```vue
|
|
197
|
-
<
|
|
202
|
+
<InputNumberField
|
|
198
203
|
name="quantity"
|
|
199
204
|
label="Quantity"
|
|
200
205
|
v-model="quantity"
|
|
@@ -205,10 +210,10 @@ button icon content itself is consumer-supplied).
|
|
|
205
210
|
>
|
|
206
211
|
<template #left><Icon name="mdi:minus" /></template>
|
|
207
212
|
<template #right><Icon name="mdi:plus" /></template>
|
|
208
|
-
</
|
|
213
|
+
</InputNumberField>
|
|
209
214
|
```
|
|
210
215
|
|
|
211
|
-
`v-model` is `number | readonly number[]`, **required** — same as `
|
|
216
|
+
`v-model` is `number | readonly number[]`, **required** — same as `InputNumber` above.
|
|
212
217
|
|
|
213
|
-
Step-down is disabled (`readonly` on its `
|
|
218
|
+
Step-down is disabled (`readonly` on its `InputButton`) once the value reaches `min`, and
|
|
214
219
|
step-up once it reaches `max`; clicking either button while at that boundary is a no-op.
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# MultipleRadiobuttons Component
|
|
2
|
+
|
|
3
|
+
## Overview
|
|
4
|
+
|
|
5
|
+
`MultipleRadiobuttons` (folder `05.forms/input-radio`) renders a single-choice group: a
|
|
6
|
+
`FormFieldset` with `role="radiogroup"` and a legend, an optional description, one radio per
|
|
7
|
+
option in `fieldData.data`, and an `InputError`. It's the single-choice sibling of
|
|
8
|
+
`MultipleCheckboxes` (see `input-checkbox.md`) and takes the same shape of props and data.
|
|
9
|
+
|
|
10
|
+
```vue
|
|
11
|
+
<MultipleRadiobuttons
|
|
12
|
+
v-model="state.enquiryType"
|
|
13
|
+
v-model:field-data="enquiryTypeOptions"
|
|
14
|
+
name="enquiryType"
|
|
15
|
+
legend="What's your enquiry about?"
|
|
16
|
+
:required="true"
|
|
17
|
+
:error-message="errors.enquiryType ?? ''"
|
|
18
|
+
:field-has-error="Boolean(errors.enquiryType)"
|
|
19
|
+
options-layout="inline"
|
|
20
|
+
>
|
|
21
|
+
<template #descriptionText>Pick the closest match.</template>
|
|
22
|
+
</MultipleRadiobuttons>
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## Props reference
|
|
28
|
+
|
|
29
|
+
> **Hyphenation rule**: write camelCase props hyphenated in templates: `:field-has-error`, `:is-button`, `:is-pill`, `:options-layout`, `:input-variant`, `:style-class-passthrough`.
|
|
30
|
+
|
|
31
|
+
| Prop (template form) | Type | Default | Notes |
|
|
32
|
+
|---|---|---|---|
|
|
33
|
+
| `name` | `string` | (required) | Shared `name` of every radio (so they form one native group: arrow-key navigation, one tab stop), and the base for the description/error ids. |
|
|
34
|
+
| `legend` | `string` | (required) | Fieldset `<legend>` text. |
|
|
35
|
+
| `:error-message` | `string \| object` | (required) | Pass `""` when there's no error. |
|
|
36
|
+
| `:field-has-error` | `boolean` | `false` | Shows the error and links it from each radio's `aria-describedby`. |
|
|
37
|
+
| `:required` | `boolean` | `false` | Native `required` on every radio. |
|
|
38
|
+
| `:is-button` | `boolean` | `false` | Button-style options (`InputCheckboxRadioButton`) instead of radio + label. |
|
|
39
|
+
| `:is-pill` | `boolean` | `false` | Pill shape, only with `is-button`. |
|
|
40
|
+
| `:direction` | `"row" \| "row-reverse"` | `"row"` | Icon/label order, only with `is-button`. |
|
|
41
|
+
| `:options-layout` | `OptionsLayout` | `"equal-widths"` | `"equal-widths"` (auto-fit grid sized to the longest label), `"inline"` (wrapping row) or `"block"` (column). Rendered as `data-options-layout` on the items container. |
|
|
42
|
+
| `:theme` | `FormUiTheme` | `"default"` | Passed to each radio. |
|
|
43
|
+
| `:input-variant` | `InputUiVariant` | `"normal"` | Passed to each radio, the description and the error. |
|
|
44
|
+
| `:style-class-passthrough` | `string \| string[]` | `[]` | Classes on the root `<fieldset>`. Read once at mount. |
|
|
45
|
+
| `data-testid` | `string` | `"multiple-radio-buttons"` | On the root `<fieldset>`. |
|
|
46
|
+
|
|
47
|
+
### v-model
|
|
48
|
+
|
|
49
|
+
- `v-model`: the selected option's `value`, **required**. Start it at `""` (or `undefined`) for no selection.
|
|
50
|
+
- `v-model:field-data`: `IFormMultipleOptions` (`{ data: [{ id, name, value, label }], ... }`), **required**. Keep it a plain `ref`, not a `computed`, since it's a two-way model. Each item's `name` is ignored: the group `name` prop is used for every radio.
|
|
51
|
+
|
|
52
|
+
### Slots
|
|
53
|
+
|
|
54
|
+
| Slot | Notes |
|
|
55
|
+
|---|---|
|
|
56
|
+
| `descriptionText` / `descriptionHtml` | Help text between the legend and the options, linked via `aria-describedby`. Nothing renders without them. |
|
|
57
|
+
| `checkedIcon` | Icon inside the checked radio. |
|
|
58
|
+
| `itemIcon` | Icon in button-style options (default `material-symbols:add-2`). |
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## Accessibility
|
|
63
|
+
|
|
64
|
+
- `role="radiogroup"` on the fieldset, named by its `<legend>`.
|
|
65
|
+
- All radios share one `name`, so the browser treats them as one group: a single tab stop and
|
|
66
|
+
arrow keys to move the selection.
|
|
67
|
+
- Each radio is labelled by its option label (`label[for]`). Description and error ids are on
|
|
68
|
+
every radio's `aria-describedby`.
|
|
69
|
+
- No hardcoded copy: legend, labels, description and error text all come from props, data or slots.
|
|
70
|
+
|
|
71
|
+
---
|
|
72
|
+
|
|
73
|
+
## Styling
|
|
74
|
+
|
|
75
|
+
Full detail in `app/components/05.forms/input-radio/CONSUMER-STYLING.md`. Public tokens:
|
|
76
|
+
`--multiple-radiobuttons-gap`, `--multiple-radiobuttons-margin-block-start`. Hook:
|
|
77
|
+
`.multiple-radiobuttons-items[data-options-layout]`. Radio visuals are `--input-checkbox-*`
|
|
78
|
+
tokens from `input-checkbox-radio`.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## History
|
|
83
|
+
|
|
84
|
+
**Migrated 2026-09-27** (1/5 → full compliance):
|
|
85
|
+
|
|
86
|
+
- Each radio's `name` was `${name}-${item.name}`, so grouping (single tab stop, arrow keys,
|
|
87
|
+
`required` validation) only worked when every data item repeated the same `name`. It's now
|
|
88
|
+
the group `name` prop for every radio. Native form submissions see `name` instead of the old
|
|
89
|
+
doubled value (e.g. `enquiryType` rather than `enquiryType-enquiryType`).
|
|
90
|
+
- Removed props that were never read: `label` (was required), `placeholder`, `multipleOptions`,
|
|
91
|
+
`equalCols`, `displayAsLozenge`. Consumers still passing `label` should drop it.
|
|
92
|
+
- `options-layout` moved from a bare class (`.inline`/`.block`/`.equal-widths`, collision-prone)
|
|
93
|
+
to `data-options-layout`; `MultipleCheckboxes` and `SingleCheckbox` got the same change.
|
|
94
|
+
- Gap and top margin are public tokens. The label-width measurement no longer includes a
|
|
95
|
+
selector for a class that doesn't exist. `fieldData` is a typed required model.
|
|
@@ -95,8 +95,8 @@ was itself commented out.
|
|
|
95
95
|
|
|
96
96
|
### InputRangeDefault
|
|
97
97
|
|
|
98
|
-
`InputRangeDefault` (`
|
|
99
|
-
`InputDescription`, and `InputError`, plus optional step-down/step-up buttons (`
|
|
98
|
+
`InputRangeDefault` (`InputRangeDefault.vue`) composes `InputRangeCore` with `InputLabel`,
|
|
99
|
+
`InputDescription`, and `InputError`, plus optional step-down/step-up buttons (`InputButton`)
|
|
100
100
|
wired into the `left`/`right` slots.
|
|
101
101
|
|
|
102
102
|
**Additional props over InputRangeCore:**
|
|
@@ -105,8 +105,8 @@ wired into the `left`/`right` slots.
|
|
|
105
105
|
|------|------|---------|-------|
|
|
106
106
|
| `:label` | `string` | (required) | Rendered via `InputLabel`. |
|
|
107
107
|
| `:error-message` | `object \| string` | (required) | Rendered via `InputError` when `field-has-error` is true. |
|
|
108
|
-
| `:step-down-label` | `string` | `"Step down"` | `button-text` on the step-down `
|
|
109
|
-
| `:step-up-label` | `string` | `"Step up"` | `button-text` on the step-up `
|
|
108
|
+
| `:step-down-label` | `string` | `"Step down"` | `button-text` on the step-down `InputButton` — override for localisation. |
|
|
109
|
+
| `:step-up-label` | `string` | `"Step up"` | `button-text` on the step-up `InputButton` — override for localisation. |
|
|
110
110
|
|
|
111
111
|
**Slots**: `descriptionHtml`, `descriptionText` (both forwarded to `InputDescription`), plus
|
|
112
112
|
`left`/`right`/`markers`/`datalist` (forwarded straight through to the underlying
|
|
@@ -116,7 +116,7 @@ score-2/5 state (no tests, no skill doc, no snippet).
|
|
|
116
116
|
|
|
117
117
|
### InputSelectWithLabel
|
|
118
118
|
|
|
119
|
-
`InputSelectWithLabel` (`
|
|
119
|
+
`InputSelectWithLabel` (`InputSelectWithLabel.vue`) composes `InputSelectCore` with
|
|
120
120
|
`InputLabel`, `InputDescription` (positioned before or after the field depending on
|
|
121
121
|
`inputVariant === "outlined"`, matching `InputTextWithLabel`'s exact placement rule), and
|
|
122
122
|
`InputError`.
|
|
@@ -36,7 +36,7 @@ Most consumers should reach for one of the **Variants** rather than `InputTextCo
|
|
|
36
36
|
|
|
37
37
|
| Model | Type | Notes |
|
|
38
38
|
| ----------------- | --------- | ---------------------------------------------------------- |
|
|
39
|
-
| `v-model` | `string` | The input value.
|
|
39
|
+
| `v-model` | `string` | The input value. **Required** (`defineModel({ required: true })`, 2026-09-25), same for `InputTextWithLabel` and `InputPasswordWithLabel`. |
|
|
40
40
|
| `v-model:is-dirty` | `boolean` | Set to `true` once the wrapper variant detects a non-empty value at mount or on change. |
|
|
41
41
|
| `v-model:is-active`| `boolean` | Tracks focus state (`focusin`/`focusout`). |
|
|
42
42
|
|
|
@@ -46,7 +46,7 @@ Most consumers should reach for one of the **Variants** rather than `InputTextCo
|
|
|
46
46
|
|
|
47
47
|
| Slot | Notes |
|
|
48
48
|
| ------- | ---------------------------------------------------------------------- |
|
|
49
|
-
| `left` | Rendered before the input, inside the bordered wrapper (e.g. an icon or `
|
|
49
|
+
| `left` | Rendered before the input, inside the bordered wrapper (e.g. an icon or `InputButton variant="inline"`). |
|
|
50
50
|
| `right` | Rendered after the input, inside the bordered wrapper. |
|
|
51
51
|
|
|
52
52
|
---
|
|
@@ -89,7 +89,7 @@ constraint is a UX affordance, not a substitute for validating the submitted val
|
|
|
89
89
|
|
|
90
90
|
## Variants
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
Three sibling wrappers compose `InputTextCore` with `InputLabel`, `InputDescription`, and
|
|
93
93
|
`InputError` for the common "labelled field" case. Each forwards `min`/`max` straight through if
|
|
94
94
|
you pass them.
|
|
95
95
|
|
|
@@ -119,7 +119,7 @@ Slots: `left`, `right`, `descriptionHtml`, `descriptionText`.
|
|
|
119
119
|
|
|
120
120
|
### InputPasswordWithLabel
|
|
121
121
|
|
|
122
|
-
Adds a show/hide toggle button (`
|
|
122
|
+
Adds a show/hide toggle button (`InputButton variant="inline"` in the `right` slot) that swaps
|
|
123
123
|
`type` between `"password"` and `"text"`.
|
|
124
124
|
|
|
125
125
|
```vue
|
|
@@ -140,7 +140,7 @@ here for a non-English consumer app; there is no built-in i18n framework depende
|
|
|
140
140
|
|
|
141
141
|
### InputTextAsNumberWithLabel
|
|
142
142
|
|
|
143
|
-
A numeric stepper: left/right `
|
|
143
|
+
A numeric stepper: left/right `InputButton variant="inline"` buttons decrement/increment the
|
|
144
144
|
value by `step`, disabled once `min`/`max` is reached.
|
|
145
145
|
|
|
146
146
|
```vue
|
|
@@ -159,6 +159,8 @@ value by `step`, disabled once `min`/`max` is reached.
|
|
|
159
159
|
</InputTextAsNumberWithLabel>
|
|
160
160
|
```
|
|
161
161
|
|
|
162
|
+
`v-model` is `number | undefined` (`defineModel({ default: undefined })`): clearing the field sets it to `undefined`, so bind a `ref<number | undefined>` rather than assuming a number.
|
|
163
|
+
|
|
162
164
|
Extra props: `min: number` (required), `max: number` (required), `step?: number` (default `1`),
|
|
163
165
|
`stepDownText`/`stepUpText` (default `"Step down"`/`"Step up"`) — the decrement/increment buttons'
|
|
164
166
|
accessible names. Requires `left`/`right` slot content for the step icons (no default icon).
|
|
@@ -190,7 +192,7 @@ the prop of that exact name, never a same-named local composable output.
|
|
|
190
192
|
- Focus is tracked via native `focusin`/`focusout`, not a custom keyboard handler — `:focus-visible`
|
|
191
193
|
styling is preserved.
|
|
192
194
|
- The password/number variants give their icon-only toggle/step buttons a real accessible name via
|
|
193
|
-
`
|
|
195
|
+
`InputButton`'s `buttonText` (visually hidden via `.sr-only` when an icon-only slot is used).
|
|
194
196
|
|
|
195
197
|
---
|
|
196
198
|
|
|
@@ -33,7 +33,7 @@ directly.
|
|
|
33
33
|
|
|
34
34
|
- `v-model` — `string | number | readonly string[] | null | undefined`, **required**
|
|
35
35
|
(`defineModel({ required: true })`, satisfying `vue/require-default-prop` the same way as
|
|
36
|
-
`InputRangeCore`/`
|
|
36
|
+
`InputRangeCore`/`InputNumber` — see `project_ledger_eslint_issues_column` in memory).
|
|
37
37
|
"Required" here means a consumer must bind `v-model`, not that the value can't be an empty
|
|
38
38
|
string — `""` is a perfectly valid textarea value.
|
|
39
39
|
- `v-model:is-dirty` — `boolean`. Set once by `InputTextareaWithLabel` the first time the value
|
|
@@ -50,7 +50,7 @@ directly.
|
|
|
50
50
|
| `left` | Rendered before the textarea (decorative — e.g. an icon). Adds `has-left-slot` to the wrapper. |
|
|
51
51
|
| `right` | Rendered after the textarea (decorative). Adds `has-right-slot` to the wrapper. |
|
|
52
52
|
|
|
53
|
-
Unlike `
|
|
53
|
+
Unlike `InputNumber`/`InputRangeCore`, these slots have no built-in `InputButton`
|
|
54
54
|
divider/embedded-button styling — they're plain decorative content (see the Storybook stories,
|
|
55
55
|
which use emoji), not a stepper control.
|
|
56
56
|
|
|
@@ -105,7 +105,7 @@ score-1/5 state (no public tokens, no CONSUMER-STYLING.md, no tests, no skill do
|
|
|
105
105
|
`InputLabel` (which does have a real `label` concept) already renders it correctly. Covered by
|
|
106
106
|
a regression test.
|
|
107
107
|
- **`defineModel()` had no default**, tripping `vue/require-default-prop` in both files — fixed
|
|
108
|
-
with `{ required: true }`, same pattern as `InputRangeCore`/`
|
|
108
|
+
with `{ required: true }`, same pattern as `InputRangeCore`/`InputNumber` (see the v-model
|
|
109
109
|
note above for why this is still correct even though an empty string is a valid value here).
|
|
110
110
|
- **`InputTextareaWithLabel.stories.ts` used `reactive()` in two render functions
|
|
111
111
|
(`AllVariants`/`FormExamples`) without importing it** — only `computed` was imported from
|
|
@@ -119,7 +119,7 @@ score-1/5 state (no public tokens, no CONSUMER-STYLING.md, no tests, no skill do
|
|
|
119
119
|
|
|
120
120
|
### InputTextareaWithLabel
|
|
121
121
|
|
|
122
|
-
`InputTextareaWithLabel` (`
|
|
122
|
+
`InputTextareaWithLabel` (`InputTextareaWithLabel.vue`) composes `InputTextareaCore` with
|
|
123
123
|
`InputLabel`, `InputDescription` (positioned before or after the field depending on
|
|
124
124
|
`inputVariant === "outlined"`, matching `InputTextWithLabel`'s exact placement rule), and
|
|
125
125
|
`InputError`.
|
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
`LayoutGridByCols` is a CSS grid layout wrapper that arranges content into a fixed number of equal-width columns. It uses **named dynamic slots** — the component renders whatever slots the consumer passes, in the order they appear. It collapses to a single column
|
|
5
|
+
`LayoutGridByCols` is a CSS grid layout wrapper that arranges content into a fixed number of equal-width columns. It uses **named dynamic slots** — the component renders whatever slots the consumer passes, in the order they appear. It collapses to a single column when the grid is narrower than a configurable threshold.
|
|
6
|
+
|
|
7
|
+
For columns that auto-fit by a minimum width instead of a fixed count, use `AutoGrid`.
|
|
6
8
|
|
|
7
9
|
---
|
|
8
10
|
|
|
@@ -34,13 +36,15 @@ When filling from a data array, use a dynamic slot name in a `v-for`:
|
|
|
34
36
|
|
|
35
37
|
> **Hyphenation rule**: Vue's ESLint config enforces `vue/attribute-hyphenation`. Always write camelCase prop names hyphenated in templates: `:column-count`, `:single-col-below`, `:style-class-passthrough`.
|
|
36
38
|
|
|
39
|
+
The three layout props have **no default**. When passed, each writes its public token inline on the root (so it beats CSS). When omitted, the token comes from CSS, falling back to the default shown.
|
|
40
|
+
|
|
37
41
|
| Prop (template form) | Type | Default | Notes |
|
|
38
42
|
|------|------|---------|-------|
|
|
39
|
-
| `:column-count` | `2 \| 3 \| 4 \| 5 \| 6` | `2` |
|
|
40
|
-
|
|
|
41
|
-
|
|
|
43
|
+
| `:column-count` | `2 \| 3 \| 4 \| 5 \| 6` | unset (CSS `2`) | Equal columns above the threshold. Clamped to a minimum of 2. Writes `--layout-grid-by-cols-column-count`. |
|
|
44
|
+
| `gap` | `string` | unset (CSS `1rem`) | Row and column gap, a **single** CSS length. Writes `--layout-grid-by-cols-gap`. |
|
|
45
|
+
| `single-col-below` | `string` | unset (CSS `768px`) | Grid width below which it becomes one column. `"0px"` never collapses. Writes `--layout-grid-by-cols-single-col-below`. |
|
|
42
46
|
| `tag` | `"div" \| "section"` | `"div"` | Use `"section"` for semantic page regions. |
|
|
43
|
-
| `label` | `string` | `""` |
|
|
47
|
+
| `label` | `string` | `""` | Accessible name when `tag="section"`, rendered as a visually hidden `<p>` linked via `aria-labelledby`. |
|
|
44
48
|
| `:style-class-passthrough` | `string \| string[]` | `[]` | Extra CSS classes on the root element. |
|
|
45
49
|
|
|
46
50
|
---
|
|
@@ -81,67 +85,51 @@ When filling from a data array, use a dynamic slot name in a `v-for`:
|
|
|
81
85
|
</LayoutGridByCols>
|
|
82
86
|
```
|
|
83
87
|
|
|
84
|
-
###
|
|
88
|
+
### Column count from CSS (responsive)
|
|
89
|
+
|
|
90
|
+
Leave `column-count` off and set the token:
|
|
85
91
|
|
|
86
92
|
```vue
|
|
87
|
-
<LayoutGridByCols
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
93
|
+
<LayoutGridByCols style-class-passthrough="team-grid">...</LayoutGridByCols>
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
```css
|
|
97
|
+
.team-grid {
|
|
98
|
+
--layout-grid-by-cols-column-count: 2;
|
|
99
|
+
|
|
100
|
+
@media (width >= 1024px) {
|
|
101
|
+
--layout-grid-by-cols-column-count: 4;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
92
104
|
```
|
|
93
105
|
|
|
94
106
|
---
|
|
95
107
|
|
|
96
108
|
## Accessibility
|
|
97
109
|
|
|
98
|
-
- When `tag="section"
|
|
99
|
-
- Always
|
|
110
|
+
- When `tag="section"` and `label` is set, the root gets `aria-labelledby` pointing to a visually hidden `<p>` with the label.
|
|
111
|
+
- A `section` without a `label` gets no `aria-labelledby` and no hidden text; `useAriaLabelledById` logs a dev console warning. Always pass a meaningful `label` with `tag="section"`.
|
|
100
112
|
- When `tag="div"`, no label or ARIA attributes are added.
|
|
101
113
|
|
|
102
114
|
---
|
|
103
115
|
|
|
104
116
|
## Responsive behaviour
|
|
105
117
|
|
|
106
|
-
|
|
118
|
+
The collapse compares the **grid's own width** (not the viewport) with the threshold, like a container query, but without one: it's a `repeat(auto-fill, minmax(...))` calculation, which is what lets the threshold be a CSS token. See `CONSUMER-STYLING.md` for the sizing model and full token list.
|
|
107
119
|
|
|
108
|
-
- **
|
|
109
|
-
- **At or
|
|
120
|
+
- **Narrower than `singleColBelow`**: single column.
|
|
121
|
+
- **At or wider**: `columnCount` equal columns.
|
|
110
122
|
|
|
111
123
|
---
|
|
112
124
|
|
|
113
|
-
##
|
|
114
|
-
|
|
115
|
-
When consuming this component, scaffold a style block using `styleClassPassthrough`. Delete the block if unused.
|
|
116
|
-
|
|
117
|
-
See [component-local-style-override.md](../component-local-style-override.md) for the full pattern.
|
|
118
|
-
|
|
119
|
-
```vue
|
|
120
|
-
<LayoutGridByCols :style-class-passthrough="['my-grid']" :column-count="3">
|
|
121
|
-
...
|
|
122
|
-
</LayoutGridByCols>
|
|
123
|
-
|
|
124
|
-
<style>
|
|
125
|
-
/* ─── LayoutGridByCols local overrides ─────────────────────────────
|
|
126
|
-
Colours, borders, geometry only — do not override behaviour.
|
|
127
|
-
Delete this block if no overrides are needed.
|
|
128
|
-
─────────────────────────────────────────────────────────────────── */
|
|
129
|
-
.layout-grid-by-cols {
|
|
130
|
-
&.my-grid {
|
|
131
|
-
/* Colours */
|
|
132
|
-
/* background: var(--brand-surface); */
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
</style>
|
|
136
|
-
```
|
|
125
|
+
## Styling
|
|
137
126
|
|
|
138
|
-
|
|
127
|
+
Tokens: `--layout-grid-by-cols-column-count`, `-single-col-below`, `-gap`, `-row-gap`, `-column-gap`. Classes: `.layout-grid-by-cols`, `.layout-grid-by-cols-inner`. Full detail in `CONSUMER-STYLING.md` next to the component; overrides follow [component-local-style-override.md](../component-local-style-override.md).
|
|
139
128
|
|
|
140
129
|
---
|
|
141
130
|
|
|
142
131
|
## Notes
|
|
143
132
|
|
|
144
133
|
- Auto-imported in Nuxt — no manual import needed.
|
|
145
|
-
- `column-count` is clamped to a minimum of 2 internally.
|
|
146
|
-
- `gap` accepts any CSS value including compound values like `"1rem 2rem"`.
|
|
147
134
|
- Slot names can be anything — semantic or indexed. Document order determines render order.
|
|
135
|
+
- 2026-09-27 migration: `singleColBelow` never worked before (the breakpoint was a hardcoded `768px` container query); it does now. `gap`/`columnCount` moved from `v-bind()` to public tokens, and the layout props lost their defaults (defaults now live in CSS). A `section` without a `label` used to read the placeholder "If tag='section' then a label is required" to screen readers; it now renders nothing and relies on the composable's dev warning. `gap` must be a single length (compound values were claimed before but break the column calculation). Inner class `.layout-grid-inner` → `.layout-grid-by-cols-inner`; root no longer a `layoutGrid` size container. No consumer app used the component at the time.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Overview
|
|
4
4
|
|
|
5
|
-
`LinkText` renders a `NuxtLink` styled as a standalone text link, with optional left and/or right icon slots. Icons are vertically centred with the label text. Intended as a CTA-style link — distinct from `
|
|
5
|
+
`LinkText` renders a `NuxtLink` styled as a standalone text link, with optional left and/or right icon slots. Icons are vertically centred with the label text. Intended as a CTA-style link — distinct from `InputButton` (which is a button/link hybrid with button styling).
|
|
6
6
|
|
|
7
7
|
## Props
|
|
8
8
|
|
|
@@ -84,7 +84,7 @@ Key CSS custom properties — define these in your consuming app to control appe
|
|
|
84
84
|
| Property | Default | Purpose |
|
|
85
85
|
|----------|---------|---------|
|
|
86
86
|
| `--link-text-colour` | `currentColor` | Link text/icon colour |
|
|
87
|
-
| `--link-text-colour-hover` | `
|
|
87
|
+
| `--link-text-colour-hover` | `--link-text-colour` | Colour on hover/focus (falls back to the resting colour; before 2026-09-27 it fell back to the parent text colour) |
|
|
88
88
|
| `--link-text-gap` | `0.4em` | Gap between icon and label |
|
|
89
89
|
| `--link-text-font-size` | `inherit` | Font size |
|
|
90
90
|
| `--link-text-decoration` | `underline` | Text decoration |
|