srcdev-nuxt-components 9.6.12 → 9.6.14

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 (111) hide show
  1. package/.claude/rules/consumer/ids-from-useid.md +2 -1
  2. package/.claude/rules/consumer/story-register-components.md +1 -1
  3. package/.claude/rules/consumer/vfor-keys-from-data.md +14 -0
  4. package/.claude/skills/component-compliance-checklist.md +24 -1
  5. package/.claude/skills/component-naming.md +1 -0
  6. package/.claude/skills/components/banner-video.md +24 -30
  7. package/.claude/skills/components/content-docs.md +18 -5
  8. package/.claude/skills/components/display-dialog.md +16 -6
  9. package/.claude/skills/components/display-qr-code.md +22 -4
  10. package/.claude/skills/components/{display-tooltip-defined.md → display-tooltip-rich.md} +40 -42
  11. package/.claude/skills/components/display-tooltip.md +17 -6
  12. package/.claude/skills/components/eyebrow-text.md +9 -5
  13. package/.claude/skills/components/header-block.md +13 -5
  14. package/.claude/skills/components/hero-text.md +13 -9
  15. package/.claude/skills/components/link-text.md +8 -5
  16. package/.claude/skills/components/pop-over.md +17 -3
  17. package/.claude/skills/components/skip-links.md +16 -0
  18. package/.claude/skills/composable-tooltips-guide.md +4 -4
  19. package/.claude/skills/index.md +6 -6
  20. package/.claude/skills/storybook-add-story.md +5 -2
  21. package/.claude/skills/testing-add-playwright.md +12 -7
  22. package/.claude/skills/testing-add-unit-test.md +8 -0
  23. package/.vscode/srcdev-component-banner-video.code-snippets +38 -25
  24. package/.vscode/srcdev-component-content-docs.code-snippets +69 -60
  25. package/.vscode/srcdev-component-display-dialog.code-snippets +7 -5
  26. package/.vscode/srcdev-component-display-qr-code.code-snippets +12 -1
  27. package/.vscode/srcdev-component-display-tooltip-rich.code-snippets +50 -0
  28. package/.vscode/srcdev-component-display-tooltip.code-snippets +31 -0
  29. package/.vscode/srcdev-component-hero-text.code-snippets +21 -5
  30. package/.vscode/srcdev-component-link-text.code-snippets +3 -3
  31. package/.vscode/srcdev-component-pop-over.code-snippets +28 -0
  32. package/.vscode/srcdev-component-skip-links.code-snippets +1 -1
  33. package/app/components/01.atoms/banner-video/BannerVideo.vue +51 -19
  34. package/app/components/01.atoms/banner-video/CONSUMER-STYLING.md +59 -40
  35. package/app/components/01.atoms/banner-video/stories/BannerVideo.stories.ts +88 -1
  36. package/app/components/01.atoms/banner-video/tests/BannerVideo.spec.ts +127 -78
  37. package/app/components/01.atoms/banner-video/tests/__snapshots__/BannerVideo.spec.ts.snap +12 -4
  38. package/app/components/01.atoms/content-wrappers/docs-pages/CONSUMER-STYLING.md +42 -14
  39. package/app/components/01.atoms/content-wrappers/docs-pages/ContentDocs.vue +86 -112
  40. package/app/components/01.atoms/content-wrappers/docs-pages/stories/ContentDocs.stories.ts +134 -8
  41. package/app/components/01.atoms/content-wrappers/docs-pages/tests/ContentDocs.spec.ts +131 -65
  42. package/app/components/01.atoms/display-dialog/CONSUMER-STYLING.md +28 -3
  43. package/app/components/01.atoms/display-dialog/DisplayDialog.vue +39 -31
  44. package/app/components/01.atoms/display-dialog/stories/DisplayDialog.stories.ts +92 -1
  45. package/app/components/01.atoms/display-dialog/tests/DisplayDialog.spec.ts +87 -41
  46. package/app/components/01.atoms/display-dialog/tests/__snapshots__/DisplayDialog.spec.ts.snap +5 -1
  47. package/app/components/01.atoms/display-tooltip/CONSUMER-STYLING.md +70 -24
  48. package/app/components/01.atoms/display-tooltip/DisplayTooltip.vue +24 -12
  49. package/app/components/01.atoms/display-tooltip/stories/DisplayTooltip.stories.ts +89 -2
  50. package/app/components/01.atoms/display-tooltip/tests/DisplayTooltip.spec.ts +65 -18
  51. package/app/components/01.atoms/display-tooltip/tests/__snapshots__/DisplayTooltip.spec.ts.snap +3 -3
  52. package/app/components/01.atoms/navigation/skip-links/CONSUMER-STYLING.md +65 -19
  53. package/app/components/01.atoms/navigation/skip-links/SkipLinks.vue +20 -14
  54. package/app/components/01.atoms/navigation/skip-links/stories/SkipLinks.stories.ts +89 -20
  55. package/app/components/01.atoms/navigation/skip-links/tests/SkipLinks.spec.ts +70 -10
  56. package/app/components/01.atoms/pop-over/CONSUMER-STYLING.md +42 -9
  57. package/app/components/01.atoms/pop-over/PopOver.vue +28 -12
  58. package/app/components/01.atoms/pop-over/stories/PopOver.stories.ts +114 -2
  59. package/app/components/01.atoms/pop-over/tests/PopOver.spec.ts +35 -0
  60. package/app/components/01.atoms/pop-over/tests/__snapshots__/PopOver.spec.ts.snap +5 -1
  61. package/app/components/01.atoms/qr-code/CONSUMER-STYLING.md +16 -3
  62. package/app/components/01.atoms/qr-code/DisplayQrCode.vue +31 -0
  63. package/app/components/01.atoms/qr-code/stories/DisplayQrCode.stories.ts +190 -157
  64. package/app/components/01.atoms/qr-code/tests/DisplayQrCode.spec.ts +58 -0
  65. package/app/components/01.atoms/text-blocks/eyebrow-text/CONSUMER-STYLING.md +9 -1
  66. package/app/components/01.atoms/text-blocks/eyebrow-text/EyebrowText.vue +5 -4
  67. package/app/components/01.atoms/text-blocks/eyebrow-text/playwright/eyebrow-text.playwright.ts +1 -1
  68. package/app/components/01.atoms/text-blocks/eyebrow-text/stories/EyebrowText.stories.ts +104 -17
  69. package/app/components/01.atoms/text-blocks/eyebrow-text/tests/EyebrowText.spec.ts +68 -118
  70. package/app/components/01.atoms/text-blocks/eyebrow-text/tests/__snapshots__/EyebrowText.spec.ts.snap +8 -8
  71. package/app/components/01.atoms/text-blocks/header-block/CONSUMER-STYLING.md +49 -24
  72. package/app/components/01.atoms/text-blocks/header-block/HeaderBlock.vue +9 -1
  73. package/app/components/01.atoms/text-blocks/header-block/stories/HeaderBlock.stories.ts +96 -26
  74. package/app/components/01.atoms/text-blocks/header-block/tests/HeaderBlock.spec.ts +64 -48
  75. package/app/components/01.atoms/text-blocks/header-block/tests/__snapshots__/HeaderBlock.spec.ts.snap +2 -2
  76. package/app/components/01.atoms/text-blocks/hero-text/CONSUMER-STYLING.md +22 -6
  77. package/app/components/01.atoms/text-blocks/hero-text/HeroText.vue +32 -23
  78. package/app/components/01.atoms/text-blocks/hero-text/playwright/hero-text.playwright.ts +1 -1
  79. package/app/components/01.atoms/text-blocks/hero-text/stories/HeroText.stories.ts +176 -23
  80. package/app/components/01.atoms/text-blocks/hero-text/tests/HeroText.spec.ts +129 -123
  81. package/app/components/01.atoms/text-blocks/hero-text/tests/__snapshots__/HeroText.spec.ts.snap +2 -2
  82. package/app/components/01.atoms/text-blocks/link-text/CONSUMER-STYLING.md +17 -0
  83. package/app/components/01.atoms/text-blocks/link-text/LinkText.vue +9 -3
  84. package/app/components/01.atoms/text-blocks/link-text/stories/LinkText.stories.ts +96 -99
  85. package/app/components/01.atoms/text-blocks/link-text/tests/LinkText.spec.ts +84 -93
  86. package/app/components/02.molecules/display-tooltip-rich/CONSUMER-STYLING.md +110 -0
  87. package/app/components/02.molecules/display-tooltip-rich/DisplayTooltipRich.vue +148 -0
  88. package/app/components/02.molecules/display-tooltip-rich/stories/DisplayTooltipRich.stories.ts +254 -0
  89. package/app/components/02.molecules/display-tooltip-rich/tests/DisplayTooltipRich.spec.ts +156 -0
  90. package/app/components/02.molecules/display-tooltip-rich/tests/__snapshots__/DisplayTooltipRich.spec.ts.snap +22 -0
  91. package/app/components/02.molecules/navigation/deep-expanding-menu/DeepExpandingMenu.vue +1 -0
  92. package/app/components/02.molecules/navigation/deep-expanding-menu/tests/__snapshots__/DeepExpandingMenu.spec.ts.snap +1 -1
  93. package/app/components/02.molecules/price-list/tests/__snapshots__/PriceList.spec.ts.snap +8 -8
  94. package/app/components/03.organisms/image-galleries/carousel-flip/CarouselFlip.vue +1 -0
  95. package/app/components/03.organisms/services/service-detail/tests/__snapshots__/ServiceDetail.spec.ts.snap +15 -15
  96. package/app/components/03.organisms/services/service-summary/tests/__snapshots__/ServiceSummary.spec.ts.snap +3 -3
  97. package/app/components/03.organisms/services/services-card/tests/ServicesCard.spec.ts +3 -3
  98. package/app/components/03.organisms/services/services-card/tests/__snapshots__/ServicesCard.spec.ts.snap +3 -3
  99. package/app/components/03.organisms/services/services-grids/tests/ServicesCardGrid.spec.ts +1 -1
  100. package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServiceSummaryGrid.spec.ts.snap +9 -9
  101. package/app/components/03.organisms/services/services-grids/tests/__snapshots__/ServicesCardGrid.spec.ts.snap +9 -9
  102. package/app/composables/tests/useTooltips.spec.ts +3 -3
  103. package/app/types/components/index.ts +1 -1
  104. package/package.json +1 -1
  105. package/.vscode/srcdev-component-display-tooltip-defined.code-snippets +0 -29
  106. package/app/components/02.molecules/display-tooltip-defined/CONSUMER-STYLING.md +0 -53
  107. package/app/components/02.molecules/display-tooltip-defined/DisplayTooltipDefined.vue +0 -117
  108. package/app/components/02.molecules/display-tooltip-defined/stories/DisplayTooltipDefined.stories.ts +0 -129
  109. package/app/components/02.molecules/display-tooltip-defined/tests/DisplayTooltipDefined.spec.ts +0 -85
  110. package/app/components/02.molecules/display-tooltip-defined/tests/__snapshots__/DisplayTooltipDefined.spec.ts.snap +0 -17
  111. /package/app/types/components/{display-tooltip-defined.d.ts → display-tooltip-rich.d.ts} +0 -0
@@ -17,9 +17,9 @@ exports[`ServiceDetail > renders correct HTML structure 1`] = `
17
17
  </li>
18
18
  </ol>
19
19
  </nav>
20
- <div class="eyebrow-text large">Freehand colour artistry</div>
21
- <h1 id="v-0-0" class="hero-text display axis-horizontal">
22
- <!--v-if--><span class="text-block-0 normal">Balayage</span>
20
+ <div class="eyebrow-text" data-font-size="large">Freehand colour artistry</div>
21
+ <h1 id="v-0-0" class="hero-text" data-font-size="display" data-axis="horizontal">
22
+ <!--v-if--><span class="hero-text-segment normal">Balayage</span>
23
23
  </h1>
24
24
  <div class="service-detail__hero-pills"><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">2.5 - 3.5 hours</span></span><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">From £95</span></span></div>
25
25
  </div>
@@ -30,12 +30,12 @@ exports[`ServiceDetail > renders correct HTML structure 1`] = `
30
30
  <div class="service-detail__body">
31
31
  <div class="service-detail__main">
32
32
  <p class="page-body-normal">Balayage is a freehand hair colouring technique that creates a soft gradient.</p>
33
- <h2 class="hero-text mb-20 subheading axis-horizontal">
34
- <!--v-if--><span class="text-block-0 normal">What is Balayage?</span>
33
+ <h2 class="hero-text mb-20" data-font-size="subheading" data-axis="horizontal">
34
+ <!--v-if--><span class="hero-text-segment normal">What is Balayage?</span>
35
35
  </h2>
36
36
  <p class="page-body-normal">The word balayage comes from the French for 'to sweep'.</p>
37
- <h2 class="hero-text mb-20 subheading axis-horizontal">
38
- <!--v-if--><span class="text-block-0 normal">The Process</span>
37
+ <h2 class="hero-text mb-20" data-font-size="subheading" data-axis="horizontal">
38
+ <!--v-if--><span class="hero-text-segment normal">The Process</span>
39
39
  </h2>
40
40
  <ol role="list" class="stepper-list has-connectors service-detail__process">
41
41
  <li class="stepper-list-item indicator-top indicator-circle" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
@@ -57,8 +57,8 @@ exports[`ServiceDetail > renders correct HTML structure 1`] = `
57
57
  </div>
58
58
  </li>
59
59
  </ol>
60
- <h2 class="hero-text mb-20 subheading axis-horizontal">
61
- <!--v-if--><span class="text-block-0 normal">Ideal For</span>
60
+ <h2 class="hero-text mb-20" data-font-size="subheading" data-axis="horizontal">
61
+ <!--v-if--><span class="hero-text-segment normal">Ideal For</span>
62
62
  </h2>
63
63
  <ul class="service-detail__ideal-for">
64
64
  <li class="service-detail__ideal-for-item"><span class="iconify i-mdi:diamond-stone service-detail__ideal-for-icon" aria-hidden="true"></span>
@@ -68,12 +68,12 @@ exports[`ServiceDetail > renders correct HTML structure 1`] = `
68
68
  <p class="page-body-normal">Low-maintenance colour</p>
69
69
  </li>
70
70
  </ul>
71
- <h2 class="hero-text mb-20 subheading axis-horizontal">
72
- <!--v-if--><span class="text-block-0 normal">Aftercare &amp; Maintenance</span>
71
+ <h2 class="hero-text mb-20" data-font-size="subheading" data-axis="horizontal">
72
+ <!--v-if--><span class="hero-text-segment normal">Aftercare &amp; Maintenance</span>
73
73
  </h2>
74
74
  <p class="page-body-normal">Balayage is low maintenance since regrowth is soft and natural.</p>
75
- <h2 class="hero-text mb-20 subheading axis-horizontal">
76
- <!--v-if--><span class="text-block-0 normal">Frequently Asked Questions</span>
75
+ <h2 class="hero-text mb-20" data-font-size="subheading" data-axis="horizontal">
76
+ <!--v-if--><span class="hero-text-segment normal">Frequently Asked Questions</span>
77
77
  </h2>
78
78
  <div class="service-detail__faqs">
79
79
  <div class="service-detail__faq">
@@ -98,8 +98,8 @@ exports[`ServiceDetail > renders correct HTML structure 1`] = `
98
98
  <div class="page-row content service-detail__final-cta-row">
99
99
  <div class="service-detail__final-cta">
100
100
  <div class="service-detail__final-cta-copy">
101
- <h2 class="hero-text subheading axis-horizontal">
102
- <!--v-if--><span class="text-block-0 normal">Ready to book your appointment?</span>
101
+ <h2 class="hero-text" data-font-size="subheading" data-axis="horizontal">
102
+ <!--v-if--><span class="hero-text-segment normal">Ready to book your appointment?</span>
103
103
  </h2>
104
104
  <p class="page-body-normal">Get in touch to book your appointment.</p>
105
105
  </div>
@@ -5,9 +5,9 @@ exports[`ServiceSummary > renders correct HTML structure 1`] = `
5
5
  <div class="service-summary__grid">
6
6
  <div class="service-summary__image-wrapper"><img width="1080" height="1080" data-nuxt-img="" srcset="/_ipx/s_1080x1080/images/test.jpg 1x, /_ipx/s_2160x2160/images/test.jpg 2x" alt="Test Service" loading="eager" fetchpriority="high" class="service-summary__image" src="/_ipx/s_1080x1080/images/test.jpg"></div>
7
7
  <div class="service-summary__info-wrapper service-summary__info-wrapper--align-center">
8
- <div class="eyebrow-text large">A subtitle</div>
9
- <h2 id="v-0-0" class="hero-text mb-20 title axis-horizontal">
10
- <!--v-if--><span class="text-block-0 normal">Test Service</span>
8
+ <div class="eyebrow-text" data-font-size="large">A subtitle</div>
9
+ <h2 id="v-0-0" class="hero-text mb-20" data-font-size="title" data-axis="horizontal">
10
+ <!--v-if--><span class="hero-text-segment normal">Test Service</span>
11
11
  </h2>
12
12
  <div class="service-summary__pills"><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">60 mins</span></span><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">From £50</span></span></div>
13
13
  <p class="page-body-normal">What this service is</p>
@@ -217,14 +217,14 @@ describe("ServicesCard", () => {
217
217
  const wrapper = await mountSuspended(ServicesCard, {
218
218
  props: { serviceData: mockService },
219
219
  });
220
- expect(wrapper.find(".eyebrow-text").classes()).toContain("large");
220
+ expect(wrapper.find(".eyebrow-text").attributes("data-font-size")).toBe("large");
221
221
  });
222
222
 
223
223
  it("applies eyebrowConfig.fontSize override", async () => {
224
224
  const wrapper = await mountSuspended(ServicesCard, {
225
225
  props: { serviceData: mockService, eyebrowConfig: { fontSize: "small" } },
226
226
  });
227
- expect(wrapper.find(".eyebrow-text").classes()).toContain("small");
227
+ expect(wrapper.find(".eyebrow-text").attributes("data-font-size")).toBe("small");
228
228
  });
229
229
 
230
230
  it("applies eyebrowConfig.tag override", async () => {
@@ -254,7 +254,7 @@ describe("ServicesCard", () => {
254
254
  const wrapper = await mountSuspended(ServicesCard, {
255
255
  props: { serviceData: mockService, heroConfig: { fontSize: "title" } },
256
256
  });
257
- expect(wrapper.find(".hero-text").classes()).toContain("title");
257
+ expect(wrapper.find(".hero-text").attributes("data-font-size")).toBe("title");
258
258
  });
259
259
 
260
260
  // ─── styleClassPassthrough ──────────────────────────────────────────────
@@ -7,9 +7,9 @@ exports[`ServicesCard > renders correct HTML structure 1`] = `
7
7
  <div class="grid-stack__layer"></div>
8
8
  </div>
9
9
  <div class="services-card-details">
10
- <div class="eyebrow-text large">A subtitle</div>
11
- <h2 class="hero-text heading axis-horizontal">
12
- <!--v-if--><span class="text-block-0 normal">Test Service</span>
10
+ <div class="eyebrow-text" data-font-size="large">A subtitle</div>
11
+ <h2 class="hero-text" data-font-size="heading" data-axis="horizontal">
12
+ <!--v-if--><span class="hero-text-segment normal">Test Service</span>
13
13
  </h2>
14
14
  <div class="services-card-description">A short description of the service.</div>
15
15
  <div class="services-card-footer">
@@ -139,7 +139,7 @@ describe("ServicesCardGrid", () => {
139
139
  props: { servicesData: mockServices, eyebrowConfig: { fontSize: "small" } },
140
140
  });
141
141
  wrapper.findAll(".eyebrow-text").forEach((el) => {
142
- expect(el.classes()).toContain("small");
142
+ expect(el.attributes("data-font-size")).toBe("small");
143
143
  });
144
144
  });
145
145
 
@@ -6,9 +6,9 @@ exports[`ServiceSummaryGrid > renders correct HTML structure 1`] = `
6
6
  <div class="service-summary__grid">
7
7
  <div class="service-summary__image-wrapper"><img width="1080" height="1080" data-nuxt-img="" srcset="/_ipx/s_1080x1080/images/locs-installation.jpg 1x, /_ipx/s_2160x2160/images/locs-installation.jpg 2x" alt="Locs Installation" loading="eager" fetchpriority="high" class="service-summary__image" src="/_ipx/s_1080x1080/images/locs-installation.jpg"></div>
8
8
  <div class="service-summary__info-wrapper service-summary__info-wrapper--align-center">
9
- <div class="eyebrow-text large">Subtitle for Locs Installation</div>
10
- <h2 id="v-0-0-0" class="hero-text mb-20 title axis-horizontal">
11
- <!--v-if--><span class="text-block-0 normal">Locs Installation</span>
9
+ <div class="eyebrow-text" data-font-size="large">Subtitle for Locs Installation</div>
10
+ <h2 id="v-0-0-0" class="hero-text mb-20" data-font-size="title" data-axis="horizontal">
11
+ <!--v-if--><span class="hero-text-segment normal">Locs Installation</span>
12
12
  </h2>
13
13
  <div class="service-summary__pills"><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">60 mins</span></span><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">From £50</span></span></div>
14
14
  <p class="page-body-normal">What this service is.</p>
@@ -19,9 +19,9 @@ exports[`ServiceSummaryGrid > renders correct HTML structure 1`] = `
19
19
  <div class="service-summary__grid">
20
20
  <div class="service-summary__image-wrapper"><img width="1080" height="1080" data-nuxt-img="" srcset="/_ipx/s_1080x1080/images/locs-retwist.jpg 1x, /_ipx/s_2160x2160/images/locs-retwist.jpg 2x" alt="Locs Retwist" loading="eager" fetchpriority="auto" class="service-summary__image" src="/_ipx/s_1080x1080/images/locs-retwist.jpg"></div>
21
21
  <div class="service-summary__info-wrapper service-summary__info-wrapper--align-center">
22
- <div class="eyebrow-text large">Subtitle for Locs Retwist</div>
23
- <h2 id="v-0-0-1" class="hero-text mb-20 title axis-horizontal">
24
- <!--v-if--><span class="text-block-0 normal">Locs Retwist</span>
22
+ <div class="eyebrow-text" data-font-size="large">Subtitle for Locs Retwist</div>
23
+ <h2 id="v-0-0-1" class="hero-text mb-20" data-font-size="title" data-axis="horizontal">
24
+ <!--v-if--><span class="hero-text-segment normal">Locs Retwist</span>
25
25
  </h2>
26
26
  <div class="service-summary__pills"><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">60 mins</span></span><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">From £50</span></span></div>
27
27
  <p class="page-body-normal">What this service is.</p>
@@ -32,9 +32,9 @@ exports[`ServiceSummaryGrid > renders correct HTML structure 1`] = `
32
32
  <div class="service-summary__grid">
33
33
  <div class="service-summary__image-wrapper"><img width="1080" height="1080" data-nuxt-img="" srcset="/_ipx/s_1080x1080/images/colour-treatment.jpg 1x, /_ipx/s_2160x2160/images/colour-treatment.jpg 2x" alt="Colour Treatment" loading="lazy" fetchpriority="auto" class="service-summary__image" src="/_ipx/s_1080x1080/images/colour-treatment.jpg"></div>
34
34
  <div class="service-summary__info-wrapper service-summary__info-wrapper--align-center">
35
- <div class="eyebrow-text large">Subtitle for Colour Treatment</div>
36
- <h2 id="v-0-0-2" class="hero-text mb-20 title axis-horizontal">
37
- <!--v-if--><span class="text-block-0 normal">Colour Treatment</span>
35
+ <div class="eyebrow-text" data-font-size="large">Subtitle for Colour Treatment</div>
36
+ <h2 id="v-0-0-2" class="hero-text mb-20" data-font-size="title" data-axis="horizontal">
37
+ <!--v-if--><span class="hero-text-segment normal">Colour Treatment</span>
38
38
  </h2>
39
39
  <div class="service-summary__pills"><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">60 mins</span></span><span class="display-pill" data-size="md" data-variant="neutral"><!--v-if--><span class="display-pill-label">From £50</span></span></div>
40
40
  <p class="page-body-normal">What this service is.</p>
@@ -8,9 +8,9 @@ exports[`ServicesCardGrid > renders correct HTML structure 1`] = `
8
8
  <div class="grid-stack__layer"></div>
9
9
  </div>
10
10
  <div class="services-card-details">
11
- <div class="eyebrow-text large">Subtitle for Locs Installation</div>
12
- <h2 class="hero-text heading axis-horizontal">
13
- <!--v-if--><span class="text-block-0 normal">Locs Installation</span>
11
+ <div class="eyebrow-text" data-font-size="large">Subtitle for Locs Installation</div>
12
+ <h2 class="hero-text" data-font-size="heading" data-axis="horizontal">
13
+ <!--v-if--><span class="hero-text-segment normal">Locs Installation</span>
14
14
  </h2>
15
15
  <div class="services-card-description">Short description for Locs Installation.</div>
16
16
  <div class="services-card-footer">
@@ -31,9 +31,9 @@ exports[`ServicesCardGrid > renders correct HTML structure 1`] = `
31
31
  <div class="grid-stack__layer"></div>
32
32
  </div>
33
33
  <div class="services-card-details">
34
- <div class="eyebrow-text large">Subtitle for Locs Retwist</div>
35
- <h2 class="hero-text heading axis-horizontal">
36
- <!--v-if--><span class="text-block-0 normal">Locs Retwist</span>
34
+ <div class="eyebrow-text" data-font-size="large">Subtitle for Locs Retwist</div>
35
+ <h2 class="hero-text" data-font-size="heading" data-axis="horizontal">
36
+ <!--v-if--><span class="hero-text-segment normal">Locs Retwist</span>
37
37
  </h2>
38
38
  <div class="services-card-description">Short description for Locs Retwist.</div>
39
39
  <div class="services-card-footer">
@@ -54,9 +54,9 @@ exports[`ServicesCardGrid > renders correct HTML structure 1`] = `
54
54
  <div class="grid-stack__layer"></div>
55
55
  </div>
56
56
  <div class="services-card-details">
57
- <div class="eyebrow-text large">Subtitle for Colour Treatment</div>
58
- <h2 class="hero-text heading axis-horizontal">
59
- <!--v-if--><span class="text-block-0 normal">Colour Treatment</span>
57
+ <div class="eyebrow-text" data-font-size="large">Subtitle for Colour Treatment</div>
58
+ <h2 class="hero-text" data-font-size="heading" data-axis="horizontal">
59
+ <!--v-if--><span class="hero-text-segment normal">Colour Treatment</span>
60
60
  </h2>
61
61
  <div class="services-card-description">Short description for Colour Treatment.</div>
62
62
  <div class="services-card-footer">
@@ -2,7 +2,7 @@ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
2
  import { mountSuspended } from "@nuxt/test-utils/runtime";
3
3
  import { defineComponent, h, nextTick, ref } from "vue";
4
4
  import { useTooltipsGuide } from "../useTooltips";
5
- import DisplayTooltipDefined from "~/components/02.molecules/display-tooltip-defined/DisplayTooltipDefined.vue";
5
+ import DisplayTooltipRich from "~/components/02.molecules/display-tooltip-rich/DisplayTooltipRich.vue";
6
6
 
7
7
  const flush = async () => {
8
8
  for (let i = 0; i < 5; i++) await nextTick();
@@ -18,8 +18,8 @@ const mountGuide = () =>
18
18
  },
19
19
  render() {
20
20
  return h("div", { ref: "containerRef" }, [
21
- h(DisplayTooltipDefined, { tooltipId: "one", contentText: { tooltipTitle: { tag: "h4", text: "One" } } }),
22
- h(DisplayTooltipDefined, { tooltipId: "two", contentText: { tooltipTitle: { tag: "h4", text: "Two" } } }),
21
+ h(DisplayTooltipRich, { tooltipId: "one", contentText: { tooltipTitle: { tag: "h4", text: "One" } } }),
22
+ h(DisplayTooltipRich, { tooltipId: "two", contentText: { tooltipTitle: { tag: "h4", text: "Two" } } }),
23
23
  ]);
24
24
  },
25
25
  }),
@@ -15,7 +15,7 @@ export * from "./social-icons-list.d"
15
15
  export * from "./content-docs.d"
16
16
  export * from "./breadcrumb"
17
17
  export * from "./cookie-consent-banner.d"
18
- export * from "./display-tooltip-defined.d"
18
+ export * from "./display-tooltip-rich.d"
19
19
  export * from "./marquee-scroller.d"
20
20
  export * from "./rotating-carousel-image.d"
21
21
  export * from "./skip-links.d"
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "9.6.12",
4
+ "version": "9.6.14",
5
5
  "main": "nuxt.config.ts",
6
6
  "types": "types.d.ts",
7
7
  "license": "MIT",
@@ -1,29 +0,0 @@
1
- {
2
- "SRCDEV DisplayTooltipDefined Basic": {
3
- "description": "DisplayTooltipDefined — structured title/body/action tooltip",
4
- "scope": "vue,html",
5
- "body": [
6
- "<DisplayTooltipDefined",
7
- " :content-text=\"{",
8
- " tooltipTitle: { tag: 'h4', text: '$1' },",
9
- " tooltipContent: { tag: 'p', text: '$0' },",
10
- " }\"",
11
- "/>"
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
- ]
28
- }
29
- }
@@ -1,53 +0,0 @@
1
- # DisplayTooltipDefined — Consumer Styling Guide
2
-
3
- ## Public token API
4
-
5
- | Token | Default | Controls |
6
- |---|---|---|
7
- | `--display-tooltip-defined-content-gap` | `1.2rem` | Gap between title/body/action/close-button |
8
- | `--display-tooltip-defined-title-colour` | `inherit` | `tooltipTitle` text colour |
9
- | `--display-tooltip-defined-title-margin-block` | `0 0` | `tooltipTitle` block margin |
10
- | `--display-tooltip-defined-title-font-size` | `1.6rem` | `tooltipTitle` font size |
11
- | `--display-tooltip-defined-title-font-weight` | `700` | `tooltipTitle` font weight |
12
- | `--display-tooltip-defined-title-line-height` | `120%` | `tooltipTitle` line height |
13
- | `--display-tooltip-defined-title-letter-spacing` | `normal` | `tooltipTitle` letter spacing |
14
- | `--display-tooltip-defined-body-colour` | `inherit` | `tooltipContent` text colour |
15
- | `--display-tooltip-defined-body-margin-block` | `0 0` | `tooltipContent` block margin |
16
- | `--display-tooltip-defined-body-font-size` | `1.3rem` | `tooltipContent` font size |
17
- | `--display-tooltip-defined-body-font-weight` | `inherit` | `tooltipContent` font weight |
18
- | `--display-tooltip-defined-body-line-height` | `140%` | `tooltipContent` line height |
19
- | `--display-tooltip-defined-body-letter-spacing` | `normal` | `tooltipContent` letter spacing |
20
- | `--display-tooltip-defined-action-colour` | `inherit` | `tooltipAction` text colour |
21
- | `--display-tooltip-defined-action-margin-block` | `0 0` | `tooltipAction` block margin |
22
- | `--display-tooltip-defined-action-font-size` | `1.4rem` | `tooltipAction` font size |
23
- | `--display-tooltip-defined-action-font-weight` | `700` | `tooltipAction` font weight |
24
- | `--display-tooltip-defined-action-line-height` | `130%` | `tooltipAction` line height |
25
- | `--display-tooltip-defined-action-letter-spacing` | `normal` | `tooltipAction` letter spacing |
26
- | `--display-tooltip-defined-close-button-margin-block` | `1.2rem 0` | Space above the close button |
27
-
28
- The three `*-colour` tokens default to `inherit`, which resolves to the underlying
29
- `DisplayTooltip` popover's own `--display-tooltip-popover-text-colour` (see its
30
- CONSUMER-STYLING.md) — override there for a uniform colour change, or override one of these three
31
- for a single field.
32
-
33
- ```css
34
- .my-page {
35
- --display-tooltip-defined-title-colour: var(--brand-accent);
36
- --display-tooltip-defined-title-font-size: 1.8rem;
37
- }
38
- ```
39
-
40
- This component also renders (and can override) every `--display-tooltip-*` token from the
41
- underlying `DisplayTooltip` — see its CONSUMER-STYLING.md for the full popover/trigger/close-button
42
- token API.
43
-
44
- ---
45
-
46
- ## Local overrides
47
-
48
- Set the tokens above on an element you own (a page or section class, or a class added with
49
- `:style-class-passthrough`): they inherit down into the component. Keep the block **unlayered** (no
50
- `@layer` wrapper) so it beats the library's `@layer components`. If your own file uses
51
- `<style scoped>`, tokens set on your element still work, but selectors that reach inside the component need
52
- `:deep()`. Patterns and examples: `.claude/skills/component-local-style-override.md`.
53
-
@@ -1,117 +0,0 @@
1
- <template>
2
- <DisplayTooltip
3
- :tooltip-id="tooltipId"
4
- :trigger-aria-label="triggerAriaLabel"
5
- :style-class-passthrough="styleClassPassthrough"
6
- >
7
- <template v-if="$slots.triggerContent" #triggerContent>
8
- <slot name="triggerContent"></slot>
9
- </template>
10
- <template #tooltipContent="{ close }">
11
- <div class="popover-content-defined">
12
- <component
13
- :is="contentText.tooltipTitle?.tag"
14
- v-if="contentText.tooltipTitle"
15
- class="tooltip-title subtitle-sm"
16
- >
17
- {{ contentText.tooltipTitle.text }}
18
- </component>
19
- <component :is="contentText.tooltipContent?.tag" v-if="contentText.tooltipContent" class="tooltip-body body-sm">
20
- {{ contentText.tooltipContent.text }}
21
- </component>
22
- <component
23
- :is="contentText.tooltipAction?.tag"
24
- v-if="contentText.tooltipAction"
25
- class="tooltip-action input-value"
26
- >
27
- {{ contentText.tooltipAction.text }}
28
- </component>
29
- <button
30
- :popovertarget="tooltipId"
31
- popovertargetaction="hide"
32
- class="display-tooltip-close-button"
33
- :aria-label="closeButtonAriaLabel"
34
- @click="close"
35
- >
36
- {{ closeButtonText }}
37
- </button>
38
- </div>
39
- </template>
40
- </DisplayTooltip>
41
- </template>
42
-
43
- <script setup lang="ts">
44
- import type { TooltipContentText } from "~/types/components";
45
-
46
- interface Props {
47
- tooltipId?: string;
48
- contentText?: TooltipContentText;
49
- /** aria-label on the trigger button — override for localisation. */
50
- triggerAriaLabel?: string;
51
- /** Visible text on the close button — override for localisation. */
52
- closeButtonText?: string;
53
- /** aria-label on the close button — override for localisation. */
54
- closeButtonAriaLabel?: string;
55
- styleClassPassthrough?: string | string[];
56
- }
57
-
58
- const props = withDefaults(defineProps<Props>(), {
59
- tooltipId: "",
60
- contentText: () => ({}),
61
- triggerAriaLabel: "Toggle the popover",
62
- closeButtonText: "Close",
63
- closeButtonAriaLabel: "Close tool tip",
64
- styleClassPassthrough: () => [],
65
- });
66
-
67
- const tooltipId = computed(() =>
68
- props.tooltipId.length ? `nuxt-tooltip-${props.tooltipId}` : `nuxt-tooltip-${useId()}`
69
- );
70
- </script>
71
-
72
- <style lang="css">
73
- @layer components {
74
- .display-tooltip-core {
75
- .popover-content-defined {
76
- display: flex;
77
- flex-direction: column;
78
- gap: var(--display-tooltip-defined-content-gap, 1.2rem);
79
-
80
- /* margin-block resets below neutralise the UA default margin of whatever tag the consumer
81
- picks via contentText.*.tag (e.g. h3/h4 carry their own margin-block) — gap is the only
82
- intended spacing mechanism between these three. */
83
- .tooltip-title {
84
- color: var(--display-tooltip-defined-title-colour, inherit);
85
- margin-block: var(--display-tooltip-defined-title-margin-block, 0 0);
86
- font-size: var(--display-tooltip-defined-title-font-size, 1.6rem);
87
- font-weight: var(--display-tooltip-defined-title-font-weight, 700);
88
- line-height: var(--display-tooltip-defined-title-line-height, 120%);
89
- letter-spacing: var(--display-tooltip-defined-title-letter-spacing, normal);
90
- }
91
-
92
- .tooltip-body {
93
- color: var(--display-tooltip-defined-body-colour, inherit);
94
- margin-block: var(--display-tooltip-defined-body-margin-block, 0 0);
95
- font-size: var(--display-tooltip-defined-body-font-size, 1.3rem);
96
- font-weight: var(--display-tooltip-defined-body-font-weight, inherit);
97
- line-height: var(--display-tooltip-defined-body-line-height, 140%);
98
- letter-spacing: var(--display-tooltip-defined-body-letter-spacing, normal);
99
- }
100
-
101
- .tooltip-action {
102
- color: var(--display-tooltip-defined-action-colour, inherit);
103
- margin-block: var(--display-tooltip-defined-action-margin-block, 0 0);
104
- font-size: var(--display-tooltip-defined-action-font-size, 1.4rem);
105
- font-weight: var(--display-tooltip-defined-action-font-weight, 700);
106
- line-height: var(--display-tooltip-defined-action-line-height, 130%);
107
- letter-spacing: var(--display-tooltip-defined-action-letter-spacing, normal);
108
- }
109
-
110
- .display-tooltip-close-button {
111
- align-self: flex-end;
112
- margin-block: var(--display-tooltip-defined-close-button-margin-block, 1.2rem 0);
113
- }
114
- }
115
- }
116
- }
117
- </style>
@@ -1,129 +0,0 @@
1
- import { ref } from "vue";
2
- import DisplayTooltipDefined from "../DisplayTooltipDefined.vue";
3
- import DisplayTooltip from "../../../01.atoms/display-tooltip/DisplayTooltip.vue";
4
- import { useTooltipsGuide } from "~/composables/useTooltips";
5
- import type { Meta, StoryObj } from "@nuxtjs/storybook";
6
- import type { TooltipContentText } from "~/types/components";
7
-
8
- const contentText: TooltipContentText = {
9
- tooltipTitle: { tag: "h4", text: "Free delivery" },
10
- tooltipContent: { tag: "p", text: "Orders over £50 qualify for free standard delivery." },
11
- tooltipAction: { tag: "span", text: "See delivery policy" },
12
- };
13
-
14
- const meta: Meta<typeof DisplayTooltipDefined> = {
15
- title: "Molecules/DisplayTooltipDefined",
16
- component: DisplayTooltipDefined,
17
- argTypes: {
18
- tooltipId: {
19
- control: "text",
20
- description: "Id used to link the trigger button to the popover. Auto-generated when omitted.",
21
- table: { category: "Basic" },
22
- },
23
- contentText: { table: { disable: true } },
24
- styleClassPassthrough: { table: { disable: true } },
25
- },
26
- args: {
27
- contentText,
28
- },
29
- parameters: {
30
- docs: {
31
- description: {
32
- component:
33
- "Structured title/body/action content variant of DisplayTooltip, plus a built-in close button wired to the popover.",
34
- },
35
- },
36
- },
37
- };
38
-
39
- export default meta;
40
- type Story = StoryObj<typeof DisplayTooltipDefined>;
41
-
42
- export const Default: Story = {
43
- render: (args) => ({
44
- components: { DisplayTooltipDefined },
45
- setup() {
46
- return { args };
47
- },
48
- template: `<div style="padding: 8rem;"><DisplayTooltipDefined v-bind="args" /></div>`,
49
- }),
50
- };
51
-
52
- export const TitleOnly: Story = {
53
- args: {
54
- contentText: { tooltipTitle: { tag: "h4", text: "Just a title" } },
55
- },
56
- render: (args) => ({
57
- components: { DisplayTooltipDefined },
58
- setup() {
59
- return { args };
60
- },
61
- template: `<div style="padding: 8rem;"><DisplayTooltipDefined v-bind="args" /></div>`,
62
- }),
63
- };
64
-
65
- export const GuidedTour: Story = {
66
- parameters: {
67
- docs: {
68
- description: {
69
- story:
70
- "Recreates the deleted `app/pages/ui/tooltips.vue` demo: `useTooltipsGuide` walks a container's `[popover]` elements in DOM order, opening each and waiting for its close button before advancing — the autoplay-through-steps pattern seen on some guide intros. Mixes a `DisplayTooltipDefined` step (its close button relabelled \"Next\" via `closeButtonText`) with a plain `DisplayTooltip` step. A hand-written close button must call the `tooltipContent` slot's `close()` as well as carrying `popovertargetaction=\"hide\"`: the attribute alone does nothing on Safari 16, which has no Popover API. Guide auto-starts 800ms after mount in this story; use \"Run guide again\" to replay it.",
71
- },
72
- },
73
- },
74
- render: () => ({
75
- components: { DisplayTooltipDefined, DisplayTooltip },
76
- setup() {
77
- const guideContainer = ref<HTMLElement | null>(null);
78
- const { isGuideRunning, restartGuide, currentTooltipIndex, totalPopovers } = useTooltipsGuide(guideContainer, {
79
- autoStart: true,
80
- startDelay: 800,
81
- });
82
-
83
- return { guideContainer, isGuideRunning, restartGuide, currentTooltipIndex, totalPopovers };
84
- },
85
- template: `
86
- <div style="padding: 4rem; display: grid; gap: 2rem; max-width: 48rem;">
87
- <div style="display: flex; align-items: center; gap: 1.2rem;">
88
- <button @click="restartGuide" :disabled="isGuideRunning" style="padding: 0.6rem 1.2rem;">
89
- {{ isGuideRunning ? 'Guide running…' : 'Run guide again' }}
90
- </button>
91
- <span v-if="isGuideRunning" style="font-size: 1.3rem; color: #666;">
92
- Step {{ currentTooltipIndex + 1 }} of {{ totalPopovers }} — click Next (Close on the last step) to advance
93
- </span>
94
- </div>
95
-
96
- <div ref="guideContainer" style="display: grid; gap: 2rem;">
97
- <DisplayTooltipDefined
98
- close-button-text="Next"
99
- close-button-aria-label="Next step"
100
- :content-text="{
101
- tooltipTitle: { tag: 'h3', text: 'Step 1' },
102
- tooltipContent: { tag: 'p', text: 'This step uses DisplayTooltipDefined — structured title/body/action content plus a built-in close button.' },
103
- tooltipAction: { tag: 'p', text: 'Step 1 of 2' },
104
- }"
105
- >
106
- <template #triggerContent>Trigger from DisplayTooltipDefined</template>
107
- </DisplayTooltipDefined>
108
-
109
- <DisplayTooltip tooltip-id="guided-tour-step-2">
110
- <template #triggerContent>Trigger from plain DisplayTooltip</template>
111
- <template #tooltipContent="{ close }">
112
- <p>This step uses plain DisplayTooltip — you supply the close button yourself via the tooltipContent slot.</p>
113
- <button
114
- popovertarget="guided-tour-step-2"
115
- popovertargetaction="hide"
116
- class="display-tooltip-close-button"
117
- style="align-self: flex-end;"
118
- aria-label="Close tool tip"
119
- @click="close"
120
- >
121
- Close
122
- </button>
123
- </template>
124
- </DisplayTooltip>
125
- </div>
126
- </div>
127
- `,
128
- }),
129
- };