srcdev-nuxt-components 9.6.12 → 9.6.13

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.
Files changed (60) hide show
  1. package/.claude/rules/consumer/ids-from-useid.md +2 -1
  2. package/.claude/rules/consumer/vfor-keys-from-data.md +14 -0
  3. package/.claude/skills/component-compliance-checklist.md +19 -1
  4. package/.claude/skills/component-naming.md +1 -0
  5. package/.claude/skills/components/banner-video.md +24 -30
  6. package/.claude/skills/components/content-docs.md +18 -5
  7. package/.claude/skills/components/display-dialog.md +16 -6
  8. package/.claude/skills/components/{display-tooltip-defined.md → display-tooltip-rich.md} +40 -42
  9. package/.claude/skills/components/display-tooltip.md +17 -6
  10. package/.claude/skills/components/skip-links.md +16 -0
  11. package/.claude/skills/composable-tooltips-guide.md +4 -4
  12. package/.claude/skills/index.md +6 -6
  13. package/.claude/skills/testing-add-unit-test.md +8 -0
  14. package/.vscode/srcdev-component-banner-video.code-snippets +38 -25
  15. package/.vscode/srcdev-component-content-docs.code-snippets +69 -60
  16. package/.vscode/srcdev-component-display-dialog.code-snippets +7 -5
  17. package/.vscode/srcdev-component-display-tooltip-rich.code-snippets +50 -0
  18. package/.vscode/srcdev-component-display-tooltip.code-snippets +31 -0
  19. package/.vscode/srcdev-component-skip-links.code-snippets +1 -1
  20. package/app/components/01.atoms/banner-video/BannerVideo.vue +51 -19
  21. package/app/components/01.atoms/banner-video/CONSUMER-STYLING.md +59 -40
  22. package/app/components/01.atoms/banner-video/stories/BannerVideo.stories.ts +88 -1
  23. package/app/components/01.atoms/banner-video/tests/BannerVideo.spec.ts +127 -78
  24. package/app/components/01.atoms/banner-video/tests/__snapshots__/BannerVideo.spec.ts.snap +12 -4
  25. package/app/components/01.atoms/content-wrappers/docs-pages/CONSUMER-STYLING.md +42 -14
  26. package/app/components/01.atoms/content-wrappers/docs-pages/ContentDocs.vue +86 -112
  27. package/app/components/01.atoms/content-wrappers/docs-pages/stories/ContentDocs.stories.ts +134 -8
  28. package/app/components/01.atoms/content-wrappers/docs-pages/tests/ContentDocs.spec.ts +131 -65
  29. package/app/components/01.atoms/display-dialog/CONSUMER-STYLING.md +28 -3
  30. package/app/components/01.atoms/display-dialog/DisplayDialog.vue +39 -31
  31. package/app/components/01.atoms/display-dialog/stories/DisplayDialog.stories.ts +92 -1
  32. package/app/components/01.atoms/display-dialog/tests/DisplayDialog.spec.ts +87 -41
  33. package/app/components/01.atoms/display-dialog/tests/__snapshots__/DisplayDialog.spec.ts.snap +5 -1
  34. package/app/components/01.atoms/display-tooltip/CONSUMER-STYLING.md +70 -24
  35. package/app/components/01.atoms/display-tooltip/DisplayTooltip.vue +24 -12
  36. package/app/components/01.atoms/display-tooltip/stories/DisplayTooltip.stories.ts +89 -2
  37. package/app/components/01.atoms/display-tooltip/tests/DisplayTooltip.spec.ts +65 -18
  38. package/app/components/01.atoms/display-tooltip/tests/__snapshots__/DisplayTooltip.spec.ts.snap +3 -3
  39. package/app/components/01.atoms/navigation/skip-links/CONSUMER-STYLING.md +65 -19
  40. package/app/components/01.atoms/navigation/skip-links/SkipLinks.vue +20 -14
  41. package/app/components/01.atoms/navigation/skip-links/stories/SkipLinks.stories.ts +89 -20
  42. package/app/components/01.atoms/navigation/skip-links/tests/SkipLinks.spec.ts +70 -10
  43. package/app/components/02.molecules/display-tooltip-rich/CONSUMER-STYLING.md +110 -0
  44. package/app/components/02.molecules/display-tooltip-rich/DisplayTooltipRich.vue +148 -0
  45. package/app/components/02.molecules/display-tooltip-rich/stories/DisplayTooltipRich.stories.ts +254 -0
  46. package/app/components/02.molecules/display-tooltip-rich/tests/DisplayTooltipRich.spec.ts +156 -0
  47. package/app/components/02.molecules/display-tooltip-rich/tests/__snapshots__/DisplayTooltipRich.spec.ts.snap +22 -0
  48. package/app/components/02.molecules/navigation/deep-expanding-menu/DeepExpandingMenu.vue +1 -0
  49. package/app/components/02.molecules/navigation/deep-expanding-menu/tests/__snapshots__/DeepExpandingMenu.spec.ts.snap +1 -1
  50. package/app/components/03.organisms/image-galleries/carousel-flip/CarouselFlip.vue +1 -0
  51. package/app/composables/tests/useTooltips.spec.ts +3 -3
  52. package/app/types/components/index.ts +1 -1
  53. package/package.json +1 -1
  54. package/.vscode/srcdev-component-display-tooltip-defined.code-snippets +0 -29
  55. package/app/components/02.molecules/display-tooltip-defined/CONSUMER-STYLING.md +0 -53
  56. package/app/components/02.molecules/display-tooltip-defined/DisplayTooltipDefined.vue +0 -117
  57. package/app/components/02.molecules/display-tooltip-defined/stories/DisplayTooltipDefined.stories.ts +0 -129
  58. package/app/components/02.molecules/display-tooltip-defined/tests/DisplayTooltipDefined.spec.ts +0 -85
  59. package/app/components/02.molecules/display-tooltip-defined/tests/__snapshots__/DisplayTooltipDefined.spec.ts.snap +0 -17
  60. /package/app/types/components/{display-tooltip-defined.d.ts → display-tooltip-rich.d.ts} +0 -0
@@ -97,19 +97,19 @@ Each skill is a single markdown file named `<area>-<task>.md`.
97
97
  ├── service-summary.md — ServiceSummary props, summary-link slot, DisplayPill duration/price (renamed/stripped from ServicesSection — full mode is now ServiceDetail)
98
98
  ├── service-detail.md — ServiceDetail: full service detail page (hero banner, sticky sidebar booking card + related services, closing CTA), headerTag vs subheadingTag split, book-cta/sidebar-note/related-service/final-cta slots
99
99
  ├── breadcrumb.md — Breadcrumb: items (BreadcrumbItem[]) trail, link vs current-page text, CSS token API
100
- ├── skip-links.md — SkipLinks: focus-revealed accessibility skip-nav, links (SkipLink[]) data-driven, homeLink slot, CSS token API
100
+ ├── skip-links.md — SkipLinks: focus-revealed accessibility skip-nav, links (SkipLink[]) data-driven, homeLink slot, empty entries dropped, index-safe keys, theme-token colours, viewport-capped wrapping panel, CSS token API
101
101
  ├── tabbed-content.md — TabbedContent (was TabsCore): tablist + panels from indexed slots (itemCount), arrow-key nav, moving hover/active/underline indicators, CSS token API
102
102
  ├── contact-section.md — ContactSection props (stepperIndicatorSize pass-through), 3-item info+form layout, slot API
103
103
  ├── stepper-list.md — StepperList dynamic slots (item-{n}/indicator-{n}), props, measured connectors (gap, dashed image tokens), per-step state recipe
104
104
  ├── progress-tracker.md — ProgressTracker: steps (ProgressTrackerStep[]) + v-model current index over StepperList, header label + progressbar, current-step #step-{n} slot for wizard forms, focus on change, CSS token API
105
105
  ├── expanding-panel.md — ExpandingPanel v-model, forceOpened, contentIsOnTop overlay mode, slots (summary/icon/content), ARIA wiring, CSS token API
106
- ├── content-docs.md — ContentDocs docs-page shell: prop-driven docsNav/docsPageNav (not slots), DocsNavItem icons, container-width breakpoint behaviour, shared/per-side CSS token API
106
+ ├── content-docs.md — ContentDocs docs-page shell: prop-driven docsNav/docsPageNav (not slots), DocsNavItem icons, container-width breakpoint behaviour, shared/per-side CSS token API, content-docs-* classes, aria-current active state
107
107
  ├── glass-panel.md — GlassPanel: frosted-glass container, light-only token defaults in-component (light-dark() block removed from _default.css, no built-in dark glass), highlight behind content, section/article labelled via headingId slot prop, CSS token API
108
108
  ├── pricing-card.md — PricingCard: plan card with highlight badge, corner ribbon, feature list, #cta slot, heading-tag, line-clamp tokens
109
109
  ├── price-list.md — PriceList: service/menu price columns (dl rows), PriceListData type, headingTag/fromLabel props, CSS token API
110
110
  ├── opening-hours.md — OpeningHours: per-day data auto-grouped into ranges, split sessions, 24h/appointment, exceptions, Intl formatting, today highlight, JSON-LD, CSS token API
111
111
  ├── input-copy.md — InputCopy: readonly copy-to-clipboard input with an inline InputButton, copied state + status announcement, translatable labels/icons, container-query icon-only button, --input-copy-* tokens
112
- ├── banner-video.md — BannerVideo: full-width hero video banner, depth tier system, objectFit/objectPosition, playIcon/pauseIcon/toggle-icon slot, reduced-motion fallback, CSS tokens
112
+ ├── banner-video.md — BannerVideo: full-width hero video banner, depth tier system, objectFit/objectPosition, playIcon/pauseIcon/toggle-icon slot, playLabel/pauseLabel, reduced-motion fallback, CSS tokens
113
113
  ├── grid-stack.md — GridStack: CSS Grid z-axis stacking, slot API, z-order rules, sizing, video+overlay and image+text patterns
114
114
  ├── scroll-reveal-frame.md — ScrollRevealFrame: generic parallax clipping frame, slot API, image grid pattern, public --scroll-reveal-frame-* tokens (props only write them when passed), browser support
115
115
  ├── scroll-reveal-image.md — ScrollRevealImage: single-image parallax reveal, imgWidth/imgHeight, public focal-x/focal-y crop tokens, frame tokens settable from CSS
@@ -127,7 +127,7 @@ Each skill is a single markdown file named `<area>-<task>.md`.
127
127
  ├── card-core.md — CardCore: generic card container, dynamic named slots as rows, 4 variants, blurred backdrop layer, full CSS token API
128
128
  ├── action-menu.md — ActionMenu + ActionMenuItem: ellipsis trigger + anchored popover menu, indexed item-{n} slots, link/button items, full CSS token API
129
129
  ├── select-menu.md — SelectMenu: v-model single-select listbox popover (ActionMenu's popover mechanics, InputSelect's selected-option semantics), icon/text/chevron trigger toggles, checkmark on selected option, options-array driven, full CSS token API
130
- ├── display-dialog.md — DisplayDialog: native <dialog> overlay, 5 variants (dialog/modal/confirm/alert/fullscreen), useDialogControls integration, CSS token API
130
+ ├── display-dialog.md — DisplayDialog: native <dialog> overlay, 5 variants (dialog/modal/confirm/alert/fullscreen), useDialogControls integration, InputButton close button, viewport-capped panel with wrapping title/content/footer, aria-label fallthrough when untitled, CSS token API
131
131
  ├── display-chip.md — DisplayChip: status indicator chip overlay, CSS trig positioning, circle/square shapes, status colours, icon/label content
132
132
  ├── display-pill.md — DisplayPill: pill/badge label with icon slot, 6 variants, 3 sizes, reversible order, --display-pill-* tokens (variants fall back to base colour/border/ring tokens); data-size/data-variant/data-reversed hooks (2026-10-08, were bare classes), label line-clamp token, -02 ring and outlined-monochrome recipes, StressTest story
133
133
  ├── carousel-flip.md — CarouselFlip: FLIP-animated carousel, carouselDataIds slot API, buttonLayout variants (sides/controls-flanking/controls-grouped-right/overlay), CSS tokens
@@ -142,8 +142,8 @@ Each skill is a single markdown file named `<area>-<task>.md`.
142
142
  ├── display-banner.md — DisplayBanner: canvas/content stacked overlay banner, conditional slot wrappers, CSS token API
143
143
  ├── deep-expanding-menu.md — DeepExpandingMenu: anchor-positioned popover nav panels, browser support caveat, CSS token API
144
144
  ├── deep-expanding-menu-classic.md — DeepExpandingMenuClassic: <details>-based fallback nav, click-outside close, CSS token API
145
- ├── display-tooltip.md — DisplayTooltip: anchor-positioned popover trigger, browser support caveat, CSS token API
146
- ├── display-tooltip-defined.md — DisplayTooltipDefined: structured title/body/action tooltip content with close button, composes DisplayTooltip
145
+ ├── display-tooltip.md — DisplayTooltip: anchor-positioned popover trigger, browser support caveat, triggerIcon prop, type="button" trigger, hideTrigger removes it from tab order (data-hidden), CSS token API
146
+ ├── display-tooltip-rich.md — DisplayTooltipRich (Material 3 rich tooltip, renamed from DisplayTooltipDefined 2026-10-18): structured title/body/action content with InputButton close button, per-field line-clamp tokens, composes DisplayTooltip
147
147
  ├── pop-over.md — PopOver: generic anchor-positioned disclosure panel, consumer-supplied trigger/content slots, placement prop, CSS token API
148
148
  ├── input-text.md — InputText (bare control), InputTextField, InputPasswordField, InputTextAsNumberField: renamed from Core/WithLabel, data-* state hooks, readonly/autocomplete props, leak-free digit filtering, wrapper attr-leak/empty-description/passthrough fixes, rounded+clamped stepping, min/max pass-through, CSS token API, stress stories
149
149
  ├── input-button.md — InputButton (renamed from InputButtonCore 2026-09-28): button/NuxtLink/a; primary filled, secondary outlined, tertiary text-only, inline unstyled; data-* state hooks; shadow ring + border-colour hover; wrapping labels; icon slots; readonly (aria-disabled, activation blocked); tokens
@@ -338,6 +338,14 @@ const ids = host.findAll("input").map((input) => input.attributes("id"));
338
338
  expect(new Set(ids).size).toBe(ids.length);
339
339
  ```
340
340
 
341
+ ## Testing duplicate `v-for` keys
342
+
343
+ Duplicate keys don't show on first render, and Vue only warns (and only corrupts the DOM) inside
344
+ the keyed diff's unsorted middle section. A reorder that keeps the first or last item in place can
345
+ be resolved from the ends and never reaches it. Mount with two items sharing the repeatable field,
346
+ then `setProps` with the first and last items swapped, and assert the rendered labels in order
347
+ (`SkipLinks.spec.ts`). With an `href`-only key that test rendered five links instead of four.
348
+
341
349
  ## Mocking browser APIs
342
350
 
343
351
  ### Global constructors (ResizeObserver, IntersectionObserver, etc.)
@@ -4,12 +4,24 @@
4
4
  "scope": "vue,html",
5
5
  "body": [
6
6
  "<BannerVideo",
7
- " src=\"$1/videos/hero.mp4\"",
8
- " poster=\"$2/images/hero-poster.jpg\"",
9
- " alt=\"$3Studio interior\"",
10
- " :img-width=\"1920\"",
11
- " :img-height=\"1080\"",
12
- " depth=\"$4md\"",
7
+ " src=\"${1:/videos/hero.mp4}\"",
8
+ " poster=\"${2:/images/hero-poster.jpg}\"",
9
+ " alt=\"${3:Studio interior}\"",
10
+ " :img-width=\"${4:1920}\"",
11
+ " :img-height=\"${5:1080}\"",
12
+ " depth=\"${6|md,xs,sm,lg,xl|}\"",
13
+ "/>"
14
+ ]
15
+ },
16
+ "SRCDEV BannerVideo Localised Labels": {
17
+ "description": "BannerVideo with translated pause/play toggle labels (the button's visually hidden accessible name)",
18
+ "scope": "vue,html",
19
+ "body": [
20
+ "<BannerVideo",
21
+ " src=\"${1:/videos/hero.mp4}\"",
22
+ " poster=\"${2:/images/hero-poster.jpg}\"",
23
+ " :play-label=\"${3:t('banner.playVideo')}\"",
24
+ " :pause-label=\"${4:t('banner.pauseVideo')}\"",
13
25
  "/>"
14
26
  ]
15
27
  },
@@ -18,10 +30,10 @@
18
30
  "scope": "vue,html",
19
31
  "body": [
20
32
  "<BannerVideo",
21
- " src=\"$1/videos/hero.mp4\"",
22
- " poster=\"$2/images/hero-poster.jpg\"",
23
- " play-icon=\"$3mdi:play-circle\"",
24
- " pause-icon=\"$4mdi:pause-circle\"",
33
+ " src=\"${1:/videos/hero.mp4}\"",
34
+ " poster=\"${2:/images/hero-poster.jpg}\"",
35
+ " play-icon=\"${3:mdi:play-circle}\"",
36
+ " pause-icon=\"${4:mdi:pause-circle}\"",
25
37
  "/>"
26
38
  ]
27
39
  },
@@ -29,7 +41,7 @@
29
41
  "description": "BannerVideo with the toggle-icon slot fully replacing the toggle button's icon",
30
42
  "scope": "vue,html",
31
43
  "body": [
32
- "<BannerVideo src=\"$1/videos/hero.mp4\" poster=\"$2/images/hero-poster.jpg\">",
44
+ "<BannerVideo src=\"${1:/videos/hero.mp4}\" poster=\"${2:/images/hero-poster.jpg}\">",
33
45
  " <template #toggle-icon=\"{ isPlaying }\">",
34
46
  " $3",
35
47
  " </template>",
@@ -37,22 +49,23 @@
37
49
  ]
38
50
  },
39
51
  "SRCDEV BannerVideo CSS Override": {
40
- "description": "CSS override scaffold for BannerVideo — scope to a page or section class",
52
+ "description": "CSS override scaffold for BannerVideo — set tokens on a page or section class you own",
41
53
  "scope": "css",
42
54
  "body": [
43
- ".$1my-page {",
44
- " .banner-video {",
45
- " --banner-video-max-height-xs: ;",
46
- " --banner-video-max-height-sm: ;",
47
- " --banner-video-max-height-md: ;",
48
- " --banner-video-max-height-lg: ;",
49
- " --banner-video-max-height-xl: ;",
50
- " --banner-video-toggle-size: ;",
51
- " --banner-video-toggle-offset: ;",
52
- " --banner-video-toggle-background: ;",
53
- " --banner-video-toggle-background-hover: ;",
54
- " --banner-video-toggle-icon-color: ;",
55
- " }",
55
+ ".${1:my-page} {",
56
+ " --banner-video-max-height-xs: ;",
57
+ " --banner-video-max-height-sm: ;",
58
+ " --banner-video-max-height-md: ;",
59
+ " --banner-video-max-height-lg: ;",
60
+ " --banner-video-max-height-xl: ;",
61
+ " --banner-video-toggle-size: ;",
62
+ " --banner-video-toggle-offset: ;",
63
+ " --banner-video-toggle-background: ;",
64
+ " --banner-video-toggle-background-hover: ;",
65
+ " --banner-video-toggle-icon-color: ;",
66
+ " --banner-video-toggle-focus-outline-width: ;",
67
+ " --banner-video-toggle-focus-outline-color: ;",
68
+ " --banner-video-toggle-focus-outline-offset: ;",
56
69
  "}"
57
70
  ]
58
71
  }
@@ -4,49 +4,51 @@
4
4
  "scope": "vue,html",
5
5
  "body": [
6
6
  "<ContentDocs",
7
- " v-model:active-nav-item=\"$1activeNavItem\"",
8
- " v-model:active-page-nav-item=\"$2activePageNavItem\"",
9
- " :docs-nav-items=\"$3docsNavItems\"",
10
- " :docs-page-nav-items=\"$4docsPageNavItems\"",
7
+ " v-model:active-nav-item=\"${1:activeNavItem}\"",
8
+ " v-model:active-page-nav-item=\"${2:activePageNavItem}\"",
9
+ " :docs-nav-items=\"${3:docsNavItems}\"",
10
+ " :docs-page-nav-items=\"${4:docsPageNavItems}\"",
11
11
  ">",
12
12
  " <template #docsContent>",
13
- " <p>$5Page content goes here.</p>",
13
+ " <p>${5:Page content goes here.}</p>",
14
14
  " </template>",
15
15
  "</ContentDocs>"
16
16
  ]
17
17
  },
18
- "SRCDEV ContentDocs Custom Labels" : {
18
+ "SRCDEV ContentDocs Custom Labels": {
19
19
  "description": "ContentDocs with custom docsNav / docsPageNav panel headings",
20
20
  "scope": "vue,html",
21
21
  "body": [
22
22
  "<ContentDocs",
23
- " v-model:active-nav-item=\"$1activeNavItem\"",
24
- " v-model:active-page-nav-item=\"$2activePageNavItem\"",
25
- " :docs-nav-items=\"$3docsNavItems\"",
26
- " :docs-page-nav-items=\"$4docsPageNavItems\"",
27
- " docs-nav-label=\"$5Sections\"",
28
- " docs-page-nav-label=\"$6Contents\"",
23
+ " v-model:active-nav-item=\"${1:activeNavItem}\"",
24
+ " v-model:active-page-nav-item=\"${2:activePageNavItem}\"",
25
+ " :docs-nav-items=\"${3:docsNavItems}\"",
26
+ " :docs-page-nav-items=\"${4:docsPageNavItems}\"",
27
+ " docs-nav-label=\"${5:Sections}\"",
28
+ " docs-page-nav-label=\"${6:Contents}\"",
29
29
  ">",
30
30
  " <template #docsContent>",
31
- " <p>$7Page content goes here.</p>",
31
+ " <p>${7:Page content goes here.}</p>",
32
32
  " </template>",
33
33
  "</ContentDocs>"
34
34
  ]
35
35
  },
36
36
  "SRCDEV ContentDocs Localised Nav Labels": {
37
- "description": "ContentDocs with localised aria-labels on the docsNav/docsPageNav <nav> landmarks",
37
+ "description": "ContentDocs with localised headings and aria-labels on the docsNav/docsPageNav <nav> landmarks",
38
38
  "scope": "vue,html",
39
39
  "body": [
40
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}\"",
41
+ " v-model:active-nav-item=\"${1:activeNavItem}\"",
42
+ " v-model:active-page-nav-item=\"${2:activePageNavItem}\"",
43
+ " :docs-nav-items=\"${3:docsNavItems}\"",
44
+ " :docs-page-nav-items=\"${4:docsPageNavItems}\"",
45
+ " :docs-nav-label=\"${5:t('docs.navLabel')}\"",
46
+ " :docs-page-nav-label=\"${6:t('docs.pageNavLabel')}\"",
47
+ " :docs-nav-aria-label=\"${7:t('docs.navAriaLabel')}\"",
48
+ " :docs-page-nav-aria-label=\"${8:t('docs.pageNavAriaLabel')}\"",
47
49
  ">",
48
50
  " <template #docsContent>",
49
- " <p>$7Page content goes here.</p>",
51
+ " <p>${9:Page content goes here.}</p>",
50
52
  " </template>",
51
53
  "</ContentDocs>"
52
54
  ]
@@ -56,11 +58,11 @@
56
58
  "scope": "typescript,vue",
57
59
  "body": [
58
60
  "const docsNavItems: DocsNavItem[] = [",
59
- " { label: \"$1Getting started\", to: \"$2/docs\" },",
61
+ " { label: \"${1:Getting started}\", to: \"${2:/docs}\" },",
60
62
  "];",
61
63
  "",
62
64
  "const docsPageNavItems: DocsNavItem[] = [",
63
- " { label: \"$3Overview\", to: \"$2/docs#overview\" },",
65
+ " { label: \"${3:Overview}\", to: \"${2:/docs}#overview\" },",
64
66
  "];",
65
67
  "",
66
68
  "const activeNavItem = ref<string | undefined>(docsNavItems[0]?.to);",
@@ -72,11 +74,11 @@
72
74
  "scope": "typescript,vue",
73
75
  "body": [
74
76
  "const docsNavItems: DocsNavItem[] = [",
75
- " { label: \"$1Getting started\", to: \"$2/docs\", icon: \"$3lucide:rocket\" },",
77
+ " { label: \"${1:Getting started}\", to: \"${2:/docs}\", icon: \"${3:lucide:rocket}\" },",
76
78
  "];",
77
79
  "",
78
80
  "const docsPageNavItems: DocsNavItem[] = [",
79
- " { label: \"$4Overview\", to: \"$2/docs#overview\", icon: \"$5lucide:list\" },",
81
+ " { label: \"${4:Overview}\", to: \"${2:/docs}#overview\", icon: \"${5:lucide:list}\" },",
80
82
  "];",
81
83
  "",
82
84
  "const activeNavItem = ref<string | undefined>(docsNavItems[0]?.to);",
@@ -87,13 +89,11 @@
87
89
  "description": "CSS override scaffold for ContentDocs nav-link icon tokens (gap, size, and start/end order)",
88
90
  "scope": "css",
89
91
  "body": [
90
- ".$1my-content-docs {",
91
- " .content-docs {",
92
- " --content-docs-link-icon-gap: $2;",
93
- " --content-docs-link-icon-size: $3;",
94
- " --content-docs-nav-link-icon-order: $4rtl; /* icon at the end */",
95
- " --content-docs-page-nav-link-icon-order: $5ltr; /* icon at the start (default) */",
96
- " }",
92
+ ".${1:my-content-docs} {",
93
+ " --content-docs-link-icon-gap: $2;",
94
+ " --content-docs-link-icon-size: $3;",
95
+ " --content-docs-nav-link-icon-order: ${4:rtl}; /* icon at the end */",
96
+ " --content-docs-page-nav-link-icon-order: ${5:ltr}; /* icon at the start (default) */",
97
97
  "}"
98
98
  ]
99
99
  },
@@ -101,27 +101,26 @@
101
101
  "description": "CSS override scaffold for ContentDocs heading/panel/link tokens, applied to both docsNav and docsPageNav at once",
102
102
  "scope": "css",
103
103
  "body": [
104
- ".$1my-content-docs {",
105
- " .content-docs {",
106
- " --content-docs-heading-font-size: $2;",
107
- " --content-docs-heading-color: $3;",
108
- " --content-docs-heading-bg: $4;",
109
- " --content-docs-heading-padding-block: $5;",
104
+ ".${1:my-content-docs} {",
105
+ " --content-docs-heading-font-size: $2;",
106
+ " --content-docs-heading-color: $3;",
107
+ " --content-docs-heading-bg: $4;",
108
+ " --content-docs-heading-padding-block: $5;",
110
109
  "",
111
- " --content-docs-panel-bg: $6;",
112
- " --content-docs-panel-padding-block: $7;",
113
- " --content-docs-panel-padding-inline: $8;",
110
+ " --content-docs-panel-bg: $6;",
111
+ " --content-docs-panel-padding-block: $7;",
112
+ " --content-docs-panel-padding-inline: $8;",
114
113
  "",
115
- " --content-docs-link-font-size: $9;",
116
- " --content-docs-link-color: $10;",
117
- " --content-docs-link-hover-bg: $11;",
118
- " --content-docs-link-active-bg: $12;",
119
- " --content-docs-link-active-color: $13;",
114
+ " --content-docs-link-font-size: $9;",
115
+ " --content-docs-link-color: $10;",
116
+ " --content-docs-link-hover-bg: $11;",
117
+ " --content-docs-link-active-bg: $12;",
118
+ " --content-docs-link-active-color: $13;",
119
+ " --content-docs-link-focus-outline-color: $14;",
120
120
  "",
121
- " --content-docs-nav-column-width: $14;",
122
- " --content-docs-page-nav-column-width: $15;",
123
- " --content-docs-page-nav-column-width-tablet: $16;",
124
- " }",
121
+ " --content-docs-nav-column-width: $15;",
122
+ " --content-docs-page-nav-column-width: $16;",
123
+ " --content-docs-page-nav-column-width-tablet: $17;",
125
124
  "}"
126
125
  ]
127
126
  },
@@ -129,17 +128,27 @@
129
128
  "description": "CSS override scaffold for independently theming docsNav vs docsPageNav heading/panel/link tokens",
130
129
  "scope": "css",
131
130
  "body": [
132
- ".$1my-content-docs {",
133
- " .content-docs {",
134
- " /* docsNav (primary) */",
135
- " --content-docs-nav-heading-color: $2;",
136
- " --content-docs-nav-panel-bg: $3;",
137
- " --content-docs-nav-link-active-bg: $4;",
131
+ ".${1:my-content-docs} {",
132
+ " /* docsNav (primary) */",
133
+ " --content-docs-nav-heading-color: $2;",
134
+ " --content-docs-nav-panel-bg: $3;",
135
+ " --content-docs-nav-link-active-bg: $4;",
138
136
  "",
139
- " /* docsPageNav (on-this-page / secondary) */",
140
- " --content-docs-page-nav-heading-color: $5;",
141
- " --content-docs-page-nav-panel-bg: $6;",
142
- " --content-docs-page-nav-link-active-bg: $7;",
137
+ " /* docsPageNav (on-this-page / secondary) */",
138
+ " --content-docs-page-nav-heading-color: $5;",
139
+ " --content-docs-page-nav-panel-bg: $6;",
140
+ " --content-docs-page-nav-link-active-bg: $7;",
141
+ "}"
142
+ ]
143
+ },
144
+ "SRCDEV ContentDocs CSS Override — Active Link": {
145
+ "description": "Style the active ContentDocs link beyond its tokens: select [aria-current=\"page\"], there is no .is-active class",
146
+ "scope": "css",
147
+ "body": [
148
+ ".${1:my-content-docs} {",
149
+ " .content-docs-nav-link[aria-current=\"page\"],",
150
+ " .content-docs-page-nav-link[aria-current=\"page\"] {",
151
+ " $2",
143
152
  " }",
144
153
  "}"
145
154
  ]
@@ -19,7 +19,7 @@
19
19
  ]
20
20
  },
21
21
  "SRCDEV DisplayDialog Confirm Template": {
22
- "description": "DisplayDialog confirm variant — content-sized, requires explicit action",
22
+ "description": "DisplayDialog confirm variant — compact (max 48rem), dismissable with Escape or outside-click",
23
23
  "scope": "vue,html",
24
24
  "body": [
25
25
  "<DisplayDialog",
@@ -114,10 +114,12 @@
114
114
  " --display-dialog-backdrop-blur: ;",
115
115
  " --display-dialog-transition-duration: ;",
116
116
  "",
117
- " .inner {",
118
- " .header {}",
119
- " .dialog-content {}",
120
- " .footer {}",
117
+ " --display-dialog-header-accent-color: ;",
118
+ "",
119
+ " .display-dialog-inner {",
120
+ " .display-dialog-header {}",
121
+ " .display-dialog-content {}",
122
+ " .display-dialog-footer {}",
121
123
  " }",
122
124
  " }",
123
125
  "}"
@@ -0,0 +1,50 @@
1
+ {
2
+ "SRCDEV DisplayTooltipRich Basic": {
3
+ "description": "DisplayTooltipRich — structured title/body/action tooltip",
4
+ "scope": "vue,html",
5
+ "body": [
6
+ "<DisplayTooltipRich",
7
+ " :content-text=\"{",
8
+ " tooltipTitle: { tag: 'h4', text: '$1' },",
9
+ " tooltipContent: { tag: 'p', text: '$0' },",
10
+ " }\"",
11
+ "/>"
12
+ ]
13
+ },
14
+ "SRCDEV DisplayTooltipRich Localised Copy": {
15
+ "description": "DisplayTooltipRich with localised trigger/close-button copy and a custom trigger icon",
16
+ "scope": "vue,html",
17
+ "body": [
18
+ "<DisplayTooltipRich",
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
+ " trigger-icon=\"${6:fa7-solid:circle-question}\"",
27
+ "/>"
28
+ ]
29
+ },
30
+ "SRCDEV DisplayTooltipRich CSS Override": {
31
+ "description": "CSS override scaffold for DisplayTooltipRich, scoped to a page or section class",
32
+ "scope": "css",
33
+ "body": [
34
+ ".${1:my-page} {",
35
+ " .display-tooltip-rich {",
36
+ " --display-tooltip-rich-content-gap: ;",
37
+ " --display-tooltip-rich-title-colour: ;",
38
+ " --display-tooltip-rich-title-font-size: ;",
39
+ " --display-tooltip-rich-title-line-clamp: ${2:none};",
40
+ " --display-tooltip-rich-body-font-size: ;",
41
+ " --display-tooltip-rich-body-line-clamp: ${3:none};",
42
+ " --display-tooltip-rich-action-colour: ;",
43
+ " --display-tooltip-rich-action-line-clamp: ${4:none};",
44
+ " --display-tooltip-popover-background-colour: ;",
45
+ " --display-tooltip-popover-text-colour: ;",
46
+ " }",
47
+ "}"
48
+ ]
49
+ }
50
+ }
@@ -34,5 +34,36 @@
34
34
  " </template>",
35
35
  "</DisplayTooltip>"
36
36
  ]
37
+ },
38
+ "SRCDEV DisplayTooltip Custom Icon": {
39
+ "description": "DisplayTooltip with a custom trigger icon and localised label",
40
+ "scope": "vue,html",
41
+ "body": [
42
+ "<DisplayTooltip trigger-icon=\"${1:lucide:info}\" trigger-aria-label=\"${2:More information}\">",
43
+ " <template #triggerContent>",
44
+ " <span>$3</span>",
45
+ " </template>",
46
+ " <template #tooltipContent>",
47
+ " <p>$0</p>",
48
+ " </template>",
49
+ "</DisplayTooltip>"
50
+ ]
51
+ },
52
+ "SRCDEV DisplayTooltip CSS Override": {
53
+ "description": "CSS override scaffold for DisplayTooltip, scoped to a page or section class",
54
+ "scope": "css",
55
+ "body": [
56
+ ".${1:my-page} {",
57
+ " .display-tooltip {",
58
+ " --display-tooltip-trigger-icon-box-size: ;",
59
+ " --display-tooltip-trigger-icon-colour: ;",
60
+ " --display-tooltip-popover-width: ;",
61
+ " --display-tooltip-popover-background-colour: ;",
62
+ " --display-tooltip-popover-text-colour: ;",
63
+ " --display-tooltip-popover-outline-colour: ;",
64
+ " --display-tooltip-popover-border-radius: ;",
65
+ " }",
66
+ "}"
67
+ ]
37
68
  }
38
69
  }
@@ -34,7 +34,7 @@
34
34
  "description": "CSS override scaffold for SkipLinks — scope to a page or section class",
35
35
  "scope": "css",
36
36
  "body": [
37
- ".$1my-page {",
37
+ ".${1:my-page} {",
38
38
  " .skip-links {",
39
39
  " --skip-links-z-index: ;",
40
40
  " --skip-links-gap: ;",