srcdev-nuxt-components 9.4.5 → 9.4.6
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/commands/migrate-component.md +40 -2
- package/.claude/component-ledger/audit.json +1 -1
- package/.claude/component-ledger/output.html +1 -1
- package/.claude/skills/components/breadcrumb.md +1 -0
- package/.claude/skills/components/content-docs.md +2 -0
- package/.claude/skills/components/display-tooltip-defined.md +3 -0
- package/.claude/skills/components/display-tooltip.md +1 -0
- package/.claude/skills/components/marquee-scroller.md +130 -0
- package/.claude/skills/components/navigation-items.md +1 -0
- package/.claude/skills/components/responsive-header.md +3 -0
- package/.claude/skills/components/site-header.md +4 -0
- package/.claude/skills/components/site-navigation.md +1 -0
- package/.claude/skills/components/tab-navigation.md +1 -0
- package/.claude/skills/index.md +1 -0
- package/.vscode/srcdev-component-breadcrumb.code-snippets +13 -0
- package/.vscode/srcdev-component-content-docs.code-snippets +18 -0
- package/.vscode/srcdev-component-display-tooltip-defined.code-snippets +15 -0
- package/.vscode/srcdev-component-display-tooltip.code-snippets +11 -0
- package/.vscode/srcdev-component-marquee-scroller.code-snippets +93 -0
- package/.vscode/srcdev-component-responsive-header.code-snippets +12 -0
- package/.vscode/srcdev-component-site-header.code-snippets +17 -0
- package/.vscode/srcdev-component-site-navigation.code-snippets +30 -0
- package/.vscode/srcdev-component-slider-gallery.code-snippets +38 -0
- package/.vscode/srcdev-component-tab-navigation.code-snippets +30 -0
- package/app/components/01.atoms/animations/marquee-scroller/CONSUMER-STYLING.md +94 -0
- package/app/components/01.atoms/animations/marquee-scroller/MarqueeScroller.vue +331 -0
- package/app/components/01.atoms/animations/marquee-scroller/stories/MarqueeScroller.stories.ts +151 -0
- package/app/components/01.atoms/animations/marquee-scroller/tests/MarqueeScroller.spec.ts +315 -0
- package/app/components/01.atoms/animations/marquee-scroller/tests/__snapshots__/MarqueeScroller.spec.ts.snap +28 -0
- package/app/components/01.atoms/content-wrappers/docs-pages/ContentDocs.vue +8 -2
- package/app/components/01.atoms/display-tooltip/DisplayTooltip.vue +4 -1
- package/app/components/01.atoms/navigation/breadcrumb/Breadcrumb.vue +4 -1
- package/app/components/02.molecules/display-tooltip-defined/DisplayTooltipDefined.vue +16 -3
- package/app/components/02.molecules/display-tooltip-defined/tests/__snapshots__/DisplayTooltipDefined.spec.ts.snap +1 -1
- package/app/components/02.molecules/navigation/site-navigation/SiteNavigation.vue +4 -1
- package/app/components/02.molecules/navigation/tab-navigation/TabNavigation.vue +4 -1
- package/app/components/03.organisms/image-galleries/slider-gallery/SliderGallery.vue +16 -4
- package/app/components/03.organisms/responsive-header/NavigationItems.vue +4 -1
- package/app/components/03.organisms/responsive-header/ResponsiveHeader.vue +16 -3
- package/app/components/03.organisms/site-header/SiteHeader.vue +16 -1
- package/app/components/03.organisms/site-header/tests/__snapshots__/SiteHeader.spec.ts.snap +1 -1
- package/app/types/components/index.ts +1 -0
- package/app/types/components/marquee-scroller.d.ts +10 -0
- package/package.json +1 -1
- package/app/components/marquee-scroller/MarqueeScroller.vue +0 -289
|
@@ -16,6 +16,7 @@ Both the horizontal list and the panel include animated active/hover indicator d
|
|
|
16
16
|
|---|---|---|---|
|
|
17
17
|
| `navItemData` | `NavItemData` | — (required) | Navigation items — see type below |
|
|
18
18
|
| `navAlign` | `"left" \| "center" \| "right"` | `"left"` | Alignment of the horizontal nav list |
|
|
19
|
+
| `ariaLabel` | `string` | `"Site navigation"` | aria-label on the root `<nav>` landmark — override for localisation |
|
|
19
20
|
| `styleClassPassthrough` | `string \| string[]` | `[]` | Extra classes applied to the root `<nav>` |
|
|
20
21
|
|
|
21
22
|
## NavItemData type
|
|
@@ -40,6 +40,7 @@ interface NavItemData {
|
|
|
40
40
|
| `nav-item-data` | `NavItemData` | required | Navigation link data — only `main` key is read |
|
|
41
41
|
| `nav-align` | `"left" \| "center" \| "right"` | `"left"` | Positions the tab list within the nav container |
|
|
42
42
|
| `anchor-scroll-offset` | `number \| (() => number)` | — | Pixel offset subtracted from scroll target; pass a getter so it is re-evaluated at click time |
|
|
43
|
+
| `aria-label` | `string` | `"Site navigation"` | aria-label on the root `<nav>` landmark — override for localisation |
|
|
43
44
|
| `:style-class-passthrough` | `string \| string[]` | `[]` | Extra classes on the root `<nav>` element |
|
|
44
45
|
|
|
45
46
|
---
|
package/.claude/skills/index.md
CHANGED
|
@@ -89,6 +89,7 @@ Each skill is a single markdown file named `<area>-<task>.md`.
|
|
|
89
89
|
├── grid-stack.md — GridStack: CSS Grid z-axis stacking, slot API, z-order rules, sizing, video+overlay and image+text patterns
|
|
90
90
|
├── scroll-reveal-frame.md — ScrollRevealFrame: generic parallax clipping frame, slot API, image grid pattern, CSS tokens, browser support
|
|
91
91
|
├── scroll-reveal-image.md — ScrollRevealImage: single-image parallax reveal, focalX, imgWidth/imgHeight, responsive frame height
|
|
92
|
+
├── marquee-scroller.md — MarqueeScroller: infinite logo/badge scroller, per-item dynamic slots (marqueeData id), hover/focus/keyboard pause, reduced-motion, CSS tokens
|
|
92
93
|
├── site-navigation.md — SiteNavigation: responsive nav with auto-collapse, burger menu, decorator indicators, CSS token API
|
|
93
94
|
├── tab-navigation.md — TabNavigation: horizontal tab nav with CSS anchor-positioning indicators, anchor scroll, burger collapse, full CSS token API
|
|
94
95
|
├── social-icons-list.md — SocialIconsList: data-driven social icon links, ISocialIcon type, logos: icon names, CSS tokens
|
|
@@ -10,5 +10,18 @@
|
|
|
10
10
|
" ]\"",
|
|
11
11
|
"/>"
|
|
12
12
|
]
|
|
13
|
+
},
|
|
14
|
+
"SRCDEV Breadcrumb Localised": {
|
|
15
|
+
"description": "Breadcrumb with a localised aria-label",
|
|
16
|
+
"scope": "vue,html",
|
|
17
|
+
"body": [
|
|
18
|
+
"<Breadcrumb",
|
|
19
|
+
" :items=\"[",
|
|
20
|
+
" { label: '$1Services', to: '$2/services' },",
|
|
21
|
+
" { label: '$3${TM_FILENAME_BASE}' },",
|
|
22
|
+
" ]\"",
|
|
23
|
+
" aria-label=\"${4:Breadcrumb}\"",
|
|
24
|
+
"/>"
|
|
25
|
+
]
|
|
13
26
|
}
|
|
14
27
|
}
|
|
@@ -33,6 +33,24 @@
|
|
|
33
33
|
"</ContentDocs>"
|
|
34
34
|
]
|
|
35
35
|
},
|
|
36
|
+
"SRCDEV ContentDocs Localised Nav Labels": {
|
|
37
|
+
"description": "ContentDocs with localised aria-labels on the docsNav/docsPageNav <nav> landmarks",
|
|
38
|
+
"scope": "vue,html",
|
|
39
|
+
"body": [
|
|
40
|
+
"<ContentDocs",
|
|
41
|
+
" v-model:active-nav-item=\"$1activeNavItem\"",
|
|
42
|
+
" v-model:active-page-nav-item=\"$2activePageNavItem\"",
|
|
43
|
+
" :docs-nav-items=\"$3docsNavItems\"",
|
|
44
|
+
" :docs-page-nav-items=\"$4docsPageNavItems\"",
|
|
45
|
+
" docs-nav-aria-label=\"${5:Docs navigation}\"",
|
|
46
|
+
" docs-page-nav-aria-label=\"${6:On this page}\"",
|
|
47
|
+
">",
|
|
48
|
+
" <template #docsContent>",
|
|
49
|
+
" <p>$7Page content goes here.</p>",
|
|
50
|
+
" </template>",
|
|
51
|
+
"</ContentDocs>"
|
|
52
|
+
]
|
|
53
|
+
},
|
|
36
54
|
"SRCDEV ContentDocs Items Script": {
|
|
37
55
|
"description": "docsNavItems / docsPageNavItems + active-item refs for ContentDocs",
|
|
38
56
|
"scope": "typescript,vue",
|
|
@@ -10,5 +10,20 @@
|
|
|
10
10
|
" }\"",
|
|
11
11
|
"/>"
|
|
12
12
|
]
|
|
13
|
+
},
|
|
14
|
+
"SRCDEV DisplayTooltipDefined Localised Copy": {
|
|
15
|
+
"description": "DisplayTooltipDefined with localised trigger/close-button copy",
|
|
16
|
+
"scope": "vue,html",
|
|
17
|
+
"body": [
|
|
18
|
+
"<DisplayTooltipDefined",
|
|
19
|
+
" :content-text=\"{",
|
|
20
|
+
" tooltipTitle: { tag: 'h4', text: '$1' },",
|
|
21
|
+
" tooltipContent: { tag: 'p', text: '$2' },",
|
|
22
|
+
" }\"",
|
|
23
|
+
" trigger-aria-label=\"${3:Toggle the popover}\"",
|
|
24
|
+
" close-button-text=\"${4:Close}\"",
|
|
25
|
+
" close-button-aria-label=\"${5:Close tool tip}\"",
|
|
26
|
+
"/>"
|
|
27
|
+
]
|
|
13
28
|
}
|
|
14
29
|
}
|
|
@@ -23,5 +23,16 @@
|
|
|
23
23
|
" </template>",
|
|
24
24
|
"</DisplayTooltip>"
|
|
25
25
|
]
|
|
26
|
+
},
|
|
27
|
+
"SRCDEV DisplayTooltip Localised Trigger Label": {
|
|
28
|
+
"description": "DisplayTooltip with a localised triggerAriaLabel",
|
|
29
|
+
"scope": "vue,html",
|
|
30
|
+
"body": [
|
|
31
|
+
"<DisplayTooltip trigger-aria-label=\"${1:Toggle the popover}\">",
|
|
32
|
+
" <template #tooltipContent>",
|
|
33
|
+
" <p>$0</p>",
|
|
34
|
+
" </template>",
|
|
35
|
+
"</DisplayTooltip>"
|
|
36
|
+
]
|
|
26
37
|
}
|
|
27
38
|
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
{
|
|
2
|
+
"SRCDEV MarqueeScroller Basic": {
|
|
3
|
+
"description": "MarqueeScroller — infinite horizontal logo/badge scroller with per-item slots",
|
|
4
|
+
"scope": "vue,html",
|
|
5
|
+
"body": [
|
|
6
|
+
"<MarqueeScroller",
|
|
7
|
+
" :marquee-data=\"[",
|
|
8
|
+
" { id: 1, content: '$1logo-a' },",
|
|
9
|
+
" { id: 2, content: '$2logo-b' },",
|
|
10
|
+
" ]\"",
|
|
11
|
+
" :item-config=\"{ width: '${3:120px}', height: '${4:60px}', gap: '${5:24px}' }\"",
|
|
12
|
+
">",
|
|
13
|
+
" <template #1>",
|
|
14
|
+
" $6",
|
|
15
|
+
" </template>",
|
|
16
|
+
" <template #2>",
|
|
17
|
+
" $7",
|
|
18
|
+
" </template>",
|
|
19
|
+
"</MarqueeScroller>"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"SRCDEV MarqueeScroller With Controls": {
|
|
23
|
+
"description": "MarqueeScroller with the visible pause/play control button (WCAG 2.2.2)",
|
|
24
|
+
"scope": "vue,html",
|
|
25
|
+
"body": [
|
|
26
|
+
"<MarqueeScroller",
|
|
27
|
+
" :marquee-data=\"$1items\"",
|
|
28
|
+
" show-controls",
|
|
29
|
+
" aria-label=\"$2Scrolling client logos\"",
|
|
30
|
+
">",
|
|
31
|
+
" <template v-for=\"item in $1items\" #[item.id] :key=\"item.id\">",
|
|
32
|
+
" $3",
|
|
33
|
+
" </template>",
|
|
34
|
+
"</MarqueeScroller>"
|
|
35
|
+
]
|
|
36
|
+
},
|
|
37
|
+
"SRCDEV MarqueeScroller Custom Control Icon/Copy": {
|
|
38
|
+
"description": "MarqueeScroller control button with custom icons and localised aria-labels",
|
|
39
|
+
"scope": "vue,html",
|
|
40
|
+
"body": [
|
|
41
|
+
"<MarqueeScroller",
|
|
42
|
+
" :marquee-data=\"$1items\"",
|
|
43
|
+
" show-controls",
|
|
44
|
+
" play-icon=\"${2:mdi:play-circle}\"",
|
|
45
|
+
" pause-icon=\"${3:mdi:pause-circle}\"",
|
|
46
|
+
" play-label=\"${4:Play}\"",
|
|
47
|
+
" pause-label=\"${5:Pause}\"",
|
|
48
|
+
">",
|
|
49
|
+
" <template v-for=\"item in $1items\" #[item.id] :key=\"item.id\">",
|
|
50
|
+
" $6",
|
|
51
|
+
" </template>",
|
|
52
|
+
"</MarqueeScroller>"
|
|
53
|
+
]
|
|
54
|
+
},
|
|
55
|
+
"SRCDEV MarqueeScroller Custom Toggle Icon Slot": {
|
|
56
|
+
"description": "MarqueeScroller with the toggle-icon slot fully replacing the control button's icon",
|
|
57
|
+
"scope": "vue,html",
|
|
58
|
+
"body": [
|
|
59
|
+
"<MarqueeScroller :marquee-data=\"$1items\" show-controls>",
|
|
60
|
+
" <template #toggle-icon=\"{ isPaused }\">",
|
|
61
|
+
" $2",
|
|
62
|
+
" </template>",
|
|
63
|
+
"</MarqueeScroller>"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
"SRCDEV MarqueeScroller CSS Override": {
|
|
67
|
+
"description": "CSS override scaffold for MarqueeScroller — scope to a page or section class",
|
|
68
|
+
"scope": "css",
|
|
69
|
+
"body": [
|
|
70
|
+
".$1my-page {",
|
|
71
|
+
" .marquee-scroller {",
|
|
72
|
+
" --marquee-scroller-fade-width: ;",
|
|
73
|
+
" --marquee-scroller-focus-outline-width: ;",
|
|
74
|
+
" --marquee-scroller-focus-outline-offset: ;",
|
|
75
|
+
" --marquee-scroller-item-border-colour: ;",
|
|
76
|
+
" --marquee-scroller-item-border-width: ;",
|
|
77
|
+
" --marquee-scroller-item-border-radius: ;",
|
|
78
|
+
" --marquee-scroller-item-transition-duration: ;",
|
|
79
|
+
" --marquee-scroller-group-hover-filter: ;",
|
|
80
|
+
" --marquee-scroller-item-hover-filter: ;",
|
|
81
|
+
" --marquee-scroller-control-offset: ;",
|
|
82
|
+
" --marquee-scroller-control-background-colour: ;",
|
|
83
|
+
" --marquee-scroller-control-background-colour-hover: ;",
|
|
84
|
+
" --marquee-scroller-control-text-colour: ;",
|
|
85
|
+
" --marquee-scroller-control-border-radius: ;",
|
|
86
|
+
" --marquee-scroller-control-border-width: ;",
|
|
87
|
+
" --marquee-scroller-control-padding: ;",
|
|
88
|
+
" --marquee-scroller-control-font-size: ;",
|
|
89
|
+
" }",
|
|
90
|
+
"}"
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -15,6 +15,18 @@
|
|
|
15
15
|
"</ResponsiveHeader>"
|
|
16
16
|
]
|
|
17
17
|
},
|
|
18
|
+
"SRCDEV ResponsiveHeader Localised Nav Labels": {
|
|
19
|
+
"description": "ResponsiveHeader with localised aria-labels on the main/secondary nav landmarks and overflow menu",
|
|
20
|
+
"scope": "vue,html",
|
|
21
|
+
"body": [
|
|
22
|
+
"<ResponsiveHeader",
|
|
23
|
+
" :responsive-nav-links=\"$1responsiveNavLinks\"",
|
|
24
|
+
" main-nav-aria-label=\"${2:Main navigation}\"",
|
|
25
|
+
" secondary-nav-aria-label=\"${3:Secondary navigation}\"",
|
|
26
|
+
" overflow-menu-aria-label=\"${4:Overflow navigation menu}\"",
|
|
27
|
+
"/>"
|
|
28
|
+
]
|
|
29
|
+
},
|
|
18
30
|
"SRCDEV ResponsiveHeader Nav Data (with dropdown)": {
|
|
19
31
|
"description": "responsiveNavLinks data with a dropdown group",
|
|
20
32
|
"scope": "typescript,vue",
|
|
@@ -30,6 +30,23 @@
|
|
|
30
30
|
"</SiteHeader>"
|
|
31
31
|
]
|
|
32
32
|
},
|
|
33
|
+
"SRCDEV SiteHeader Localised Nav Labels": {
|
|
34
|
+
"description": "SiteHeader with localised aria-labels on all its nav landmarks (home, main, secondary, overflow)",
|
|
35
|
+
"scope": "vue,html",
|
|
36
|
+
"body": [
|
|
37
|
+
"<SiteHeader",
|
|
38
|
+
" :responsive-nav-links=\"$1responsiveNavLinks\"",
|
|
39
|
+
" home-nav-aria-label=\"${2:Home Navigation}\"",
|
|
40
|
+
" main-nav-aria-label=\"${3:Main navigation}\"",
|
|
41
|
+
" secondary-nav-aria-label=\"${4:Secondary navigation}\"",
|
|
42
|
+
" overflow-menu-aria-label=\"${5:Overflow navigation menu}\"",
|
|
43
|
+
">",
|
|
44
|
+
" <template #branding>",
|
|
45
|
+
" <NuxtLink to=\"/\" class=\"home-link\">$6Brand</NuxtLink>",
|
|
46
|
+
" </template>",
|
|
47
|
+
"</SiteHeader>"
|
|
48
|
+
]
|
|
49
|
+
},
|
|
33
50
|
"SRCDEV SiteHeader Nav Data (flat)": {
|
|
34
51
|
"description": "Simple flat responsiveNavLinks data with no dropdowns, for a few-page site",
|
|
35
52
|
"scope": "typescript,vue",
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"SRCDEV SiteNavigation Basic": {
|
|
3
|
+
"description": "SiteNavigation horizontal nav with sliding active/hover indicator",
|
|
4
|
+
"scope": "vue,html",
|
|
5
|
+
"body": [
|
|
6
|
+
"<SiteNavigation :nav-item-data=\"$1navData\" nav-align=\"${2:left}\" />"
|
|
7
|
+
]
|
|
8
|
+
},
|
|
9
|
+
"SRCDEV SiteNavigation Localised": {
|
|
10
|
+
"description": "SiteNavigation with a localised aria-label",
|
|
11
|
+
"scope": "vue,html",
|
|
12
|
+
"body": [
|
|
13
|
+
"<SiteNavigation :nav-item-data=\"$1navData\" aria-label=\"${2:Site navigation}\" />"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"SRCDEV SiteNavigation Nav Data Script": {
|
|
17
|
+
"description": "navItemData for SiteNavigation",
|
|
18
|
+
"scope": "typescript,vue",
|
|
19
|
+
"body": [
|
|
20
|
+
"import type { NavItemData } from \"srcdev-nuxt-components\";",
|
|
21
|
+
"",
|
|
22
|
+
"const $1navData: NavItemData = {",
|
|
23
|
+
" main: [",
|
|
24
|
+
" { text: \"$2Home\", href: \"$3/\" },",
|
|
25
|
+
" { text: \"$4About\", href: \"$5/about\" },",
|
|
26
|
+
" ],",
|
|
27
|
+
"};"
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
{
|
|
2
|
+
"SRCDEV SliderGallery Basic": {
|
|
3
|
+
"description": "SliderGallery full-screen image slider with thumbnails and prev/next arrows",
|
|
4
|
+
"scope": "vue,html",
|
|
5
|
+
"body": [
|
|
6
|
+
"<SliderGallery v-model:gallery-data=\"$1galleryData\" />"
|
|
7
|
+
]
|
|
8
|
+
},
|
|
9
|
+
"SRCDEV SliderGallery Localised": {
|
|
10
|
+
"description": "SliderGallery with localised loading/CTA/arrow copy",
|
|
11
|
+
"scope": "vue,html",
|
|
12
|
+
"body": [
|
|
13
|
+
"<SliderGallery",
|
|
14
|
+
" v-model:gallery-data=\"$1galleryData\"",
|
|
15
|
+
" loading-text=\"${2:Loading gallery...}\"",
|
|
16
|
+
" see-more-text=\"${3:SEE MORE}\"",
|
|
17
|
+
" prev-aria-label=\"${4:Previous image}\"",
|
|
18
|
+
" next-aria-label=\"${5:Next image}\"",
|
|
19
|
+
"/>"
|
|
20
|
+
]
|
|
21
|
+
},
|
|
22
|
+
"SRCDEV SliderGallery Data Script": {
|
|
23
|
+
"description": "galleryData ref for SliderGallery",
|
|
24
|
+
"scope": "typescript,vue",
|
|
25
|
+
"body": [
|
|
26
|
+
"import type { IGalleryData } from \"srcdev-nuxt-components\";",
|
|
27
|
+
"",
|
|
28
|
+
"const $1galleryData = ref<IGalleryData[]>([",
|
|
29
|
+
" {",
|
|
30
|
+
" src: \"$2/images/slide-1.jpg\",",
|
|
31
|
+
" alt: \"$3\",",
|
|
32
|
+
" title: \"$4\",",
|
|
33
|
+
" textBrightness: \"${5:light}\",",
|
|
34
|
+
" },",
|
|
35
|
+
"]);"
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"SRCDEV TabNavigation Basic": {
|
|
3
|
+
"description": "TabNavigation with route/hash links",
|
|
4
|
+
"scope": "vue,html",
|
|
5
|
+
"body": [
|
|
6
|
+
"<TabNavigation :nav-item-data=\"$1navData\" nav-align=\"${2:center}\" />"
|
|
7
|
+
]
|
|
8
|
+
},
|
|
9
|
+
"SRCDEV TabNavigation Localised": {
|
|
10
|
+
"description": "TabNavigation with a localised aria-label",
|
|
11
|
+
"scope": "vue,html",
|
|
12
|
+
"body": [
|
|
13
|
+
"<TabNavigation :nav-item-data=\"$1navData\" aria-label=\"${2:Site navigation}\" />"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"SRCDEV TabNavigation Nav Data Script": {
|
|
17
|
+
"description": "navItemData for TabNavigation",
|
|
18
|
+
"scope": "typescript,vue",
|
|
19
|
+
"body": [
|
|
20
|
+
"import type { NavItemData } from \"srcdev-nuxt-components\";",
|
|
21
|
+
"",
|
|
22
|
+
"const $1navData: NavItemData = {",
|
|
23
|
+
" main: [",
|
|
24
|
+
" { text: \"$2Home\", href: \"$3/\" },",
|
|
25
|
+
" { text: \"$4Overview\", href: \"$5#overview\" },",
|
|
26
|
+
" ],",
|
|
27
|
+
"};"
|
|
28
|
+
]
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# MarqueeScroller — Consumer Styling Guide
|
|
2
|
+
|
|
3
|
+
## Public token API
|
|
4
|
+
|
|
5
|
+
| Token | Default | Controls |
|
|
6
|
+
|---|---|---|
|
|
7
|
+
| `--marquee-scroller-fade-width` | `10%` | Width of the transparent fade at each edge of the track (`mask-image`) |
|
|
8
|
+
| `--marquee-scroller-focus-outline-width` | `2px` | Outline width on the root region and the control button when keyboard-focused (colour is `--theme-ring`) |
|
|
9
|
+
| `--marquee-scroller-focus-outline-offset` | `2px` | Outline offset on the same two focus states |
|
|
10
|
+
| `--marquee-scroller-group-hover-filter` | `grayscale(1)` | Filter applied to every item when the pointer hovers anywhere over the scroller |
|
|
11
|
+
| `--marquee-scroller-item-hover-filter` | `grayscale(0)` | Filter applied to a single item when it is individually hovered (overrides the group filter for that item) |
|
|
12
|
+
| `--marquee-scroller-item-transition-duration` | `0.5s` | Transition duration for the item hover filter change |
|
|
13
|
+
| `--marquee-scroller-item-border-width` | `1px` | Item border width |
|
|
14
|
+
| `--marquee-scroller-item-border-colour` | `light-dark(var(--slate-10), var(--slate-00))` | Item border colour |
|
|
15
|
+
| `--marquee-scroller-item-border-radius` | `4px` | Item border radius |
|
|
16
|
+
| `--marquee-scroller-control-offset` | `8px` | Distance of the pause/play button from the top and end edges |
|
|
17
|
+
| `--marquee-scroller-control-background-colour` | `rgba(0, 0, 0, 0.7)` | Pause/play button background |
|
|
18
|
+
| `--marquee-scroller-control-background-colour-hover` | `rgba(0, 0, 0, 0.9)` | Pause/play button background on hover |
|
|
19
|
+
| `--marquee-scroller-control-text-colour` | `white` | Pause/play button icon colour |
|
|
20
|
+
| `--marquee-scroller-control-border-radius` | `4px` | Pause/play button border radius |
|
|
21
|
+
| `--marquee-scroller-control-padding` | `8px` | Pause/play button padding |
|
|
22
|
+
| `--marquee-scroller-control-font-size` | `14px` | Pause/play button icon font size |
|
|
23
|
+
| `--marquee-scroller-control-transition-duration` | `0.2s` | Pause/play button background-colour transition duration |
|
|
24
|
+
| `--marquee-scroller-control-border-width` | `1px` | Pause/play button border width in forced-colors/high-contrast mode (`prefers-contrast: high`). The border colour itself stays the system `ButtonText` keyword — see note below. |
|
|
25
|
+
|
|
26
|
+
```css
|
|
27
|
+
.my-page {
|
|
28
|
+
--marquee-scroller-item-border-colour: #b5651d;
|
|
29
|
+
--marquee-scroller-control-background-colour: #1a1a1a;
|
|
30
|
+
--marquee-scroller-fade-width: 20%;
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## High-contrast mode colours are not tokenised
|
|
35
|
+
|
|
36
|
+
Under `prefers-contrast: high`, the control button switches to the system colour keywords
|
|
37
|
+
`ButtonFace`/`ButtonText` rather than the component's own background/text tokens. These aren't
|
|
38
|
+
exposed as overridable tokens on purpose — they're meant to track the user's OS-level high-contrast
|
|
39
|
+
theme, which a component-level override would defeat. Only the border *width* in that mode is a
|
|
40
|
+
token (`--marquee-scroller-control-border-width`), since it's a plain dimension with no such
|
|
41
|
+
constraint.
|
|
42
|
+
|
|
43
|
+
## Item size and spacing are prop-driven, not tokens
|
|
44
|
+
|
|
45
|
+
Item `width`/`height`/`gap` and the animation duration are set via the `itemConfig` and
|
|
46
|
+
`animationRuntime` props (not CSS custom properties), since they also drive the component's own
|
|
47
|
+
layout math (`aspect-ratio`, track width). Override those through props:
|
|
48
|
+
|
|
49
|
+
```vue
|
|
50
|
+
<MarqueeScroller
|
|
51
|
+
:item-config="{ width: '80px', height: '80px', gap: '24px' }"
|
|
52
|
+
animation-runtime="60s"
|
|
53
|
+
/>
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Item content via slots
|
|
57
|
+
|
|
58
|
+
Each entry in `marqueeData` (`{ id, content }`) renders a slot named after its `id`. Provide the
|
|
59
|
+
markup for each item via that dynamically-named slot:
|
|
60
|
+
|
|
61
|
+
```vue
|
|
62
|
+
<MarqueeScroller :marquee-data="[{ id: 1, content: 'logo-a' }, { id: 2, content: 'logo-b' }]">
|
|
63
|
+
<template #1>
|
|
64
|
+
<img src="/logos/a.svg" alt="Logo A" />
|
|
65
|
+
</template>
|
|
66
|
+
<template #2>
|
|
67
|
+
<img src="/logos/b.svg" alt="Logo B" />
|
|
68
|
+
</template>
|
|
69
|
+
</MarqueeScroller>
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
## Control button icon and copy
|
|
73
|
+
|
|
74
|
+
The pause/play button's icon and its `aria-label` copy are all overridable — see `playIcon`/
|
|
75
|
+
`pauseIcon`/`playLabel`/`pauseLabel` props, or the `toggle-icon` slot for a fully custom icon
|
|
76
|
+
(scoped with `isPaused`):
|
|
77
|
+
|
|
78
|
+
```vue
|
|
79
|
+
<MarqueeScroller
|
|
80
|
+
show-controls
|
|
81
|
+
play-icon="mdi:play-circle"
|
|
82
|
+
pause-icon="mdi:pause-circle"
|
|
83
|
+
play-label="Reproduire"
|
|
84
|
+
pause-label="Suspendre"
|
|
85
|
+
/>
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
```vue
|
|
89
|
+
<MarqueeScroller show-controls>
|
|
90
|
+
<template #toggle-icon="{ isPaused }">
|
|
91
|
+
<Icon :name="isPaused ? 'lucide:play' : 'lucide:pause'" />
|
|
92
|
+
</template>
|
|
93
|
+
</MarqueeScroller>
|
|
94
|
+
```
|