srcdev-nuxt-components 9.0.15 → 9.0.17

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 (112) hide show
  1. package/.claude/settings.json +25 -0
  2. package/.claude/skills/component-aria-landmark.md +68 -0
  3. package/.claude/skills/component-dynamic-slots.md +150 -0
  4. package/.claude/skills/component-export-types.md +61 -0
  5. package/.claude/skills/component-local-style-override.md +126 -0
  6. package/.claude/skills/component-prop-driven-container-layout.md +42 -0
  7. package/.claude/skills/components/accordian-core.md +159 -0
  8. package/.claude/skills/components/contact-section.md +101 -0
  9. package/.claude/skills/components/expanding-panel.md +156 -0
  10. package/.claude/skills/components/eyebrow-text.md +25 -0
  11. package/.claude/skills/components/hero-text.md +25 -0
  12. package/.claude/skills/components/layout-grid-by-cols.md +147 -0
  13. package/.claude/skills/components/layout-row.md +35 -0
  14. package/.claude/skills/components/link-text.md +33 -0
  15. package/.claude/skills/components/page-hero-highlights.md +224 -0
  16. package/.claude/skills/components/services-card.md +28 -0
  17. package/.claude/skills/components/services-section.md +25 -0
  18. package/.claude/skills/components/stepper-list.md +227 -0
  19. package/.claude/skills/css-grid-max-width-gutters.md +67 -0
  20. package/.claude/skills/index.md +15 -3
  21. package/.claude/skills/storybook-add-story.md +60 -0
  22. package/.claude/skills/testing-add-unit-test.md +56 -0
  23. package/app/assets/styles/setup/01.config/index.css +0 -1
  24. package/app/assets/styles/setup/03.theming/default/_dark.css +2 -2
  25. package/app/assets/styles/setup/04.elements/forms/02.typography.css +1 -0
  26. package/app/assets/styles/setup/05.typography/02.utility-classes/_font-classes-page-link.css +14 -14
  27. package/app/assets/styles/setup/index.css +0 -1
  28. package/app/components/01.atoms/card/CardCore.vue +92 -0
  29. package/app/components/01.atoms/card/stories/CardCore.stories.ts +132 -0
  30. package/app/components/01.atoms/card/tests/CardCore.spec.ts +207 -0
  31. package/app/components/01.atoms/card/tests/__snapshots__/CardCore.spec.ts.snap +43 -0
  32. package/app/components/01.atoms/content-wrappers/content-columns-2/ContentColumns2.vue +51 -0
  33. package/app/components/01.atoms/content-wrappers/content-columns-2/stories/ContentColumns2.stories.ts +110 -0
  34. package/app/components/01.atoms/content-wrappers/content-columns-2/tests/ContentColumns2.spec.ts +105 -0
  35. package/app/components/01.atoms/content-wrappers/content-columns-2/tests/__snapshots__/ContentColumns2.spec.ts.snap +14 -0
  36. package/app/components/01.atoms/content-wrappers/content-width/ContentWidth.vue +88 -0
  37. package/app/components/01.atoms/content-wrappers/content-width/stories/ContentWidth.stories.ts +362 -0
  38. package/app/components/01.atoms/content-wrappers/content-width/tests/ContentWidth.spec.ts +132 -0
  39. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/LayoutGridByCols.vue +71 -0
  40. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/stories/LayoutGridByCols.stories.ts +219 -0
  41. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/LayoutGridByCols.spec.ts +174 -0
  42. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGrid.spec.ts.snap +36 -0
  43. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-cols/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +36 -0
  44. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/LayoutGridByWidth.vue +70 -0
  45. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/stories/LayoutGridByWidth.stories.ts +220 -0
  46. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/LayoutGridByWidth.spec.ts +174 -0
  47. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGrid.spec.ts.snap +36 -0
  48. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGridByCols.spec.ts.snap +36 -0
  49. package/app/components/01.atoms/content-wrappers/layout-grid/layout-grid-by-width/tests/__snapshots__/LayoutGridByWidth.spec.ts.snap +36 -0
  50. package/app/components/01.atoms/text-blocks/eyebrow-text/stories/EyebrowText.stories.ts +1 -1
  51. package/app/components/01.atoms/text-blocks/hero-text/stories/HeroText.stories.ts +1 -1
  52. package/app/components/01.atoms/text-blocks/link-text/stories/LinkText.stories.ts +1 -1
  53. package/app/components/02.molecules/contact-section/stories/ContactSection.stories.ts +5 -0
  54. package/app/components/02.molecules/contact-section/tests/ContactSection.spec.ts +15 -0
  55. package/app/components/02.molecules/contact-section/tests/ContactSection.vue +25 -17
  56. package/app/components/{accordian → 02.molecules/expandable/accordian}/stories/AccordianCore.stories.ts +1 -1
  57. package/app/components/02.molecules/expandable/expanding-panel/stories/ExpandingPanel.stories.ts +245 -0
  58. package/app/components/02.molecules/expandable/expanding-panel/tests/ExpandingPanel.spec.ts +351 -0
  59. package/app/components/02.molecules/expandable/expanding-panel/tests/__snapshots__/ExpandingPanel.spec.ts.snap +38 -0
  60. package/app/components/02.molecules/navigation/navigation-horizontal/NavigationHorizontal.vue +162 -0
  61. package/app/components/02.molecules/navigation/navigation-horizontal/stories/NavigationHorizontal.stories.ts +373 -0
  62. package/app/components/02.molecules/navigation/navigation-horizontal/tests/NavigationHorizontal.spec.ts +152 -0
  63. package/app/components/02.molecules/navigation/navigation-horizontal/tests/__snapshots__/NavigationHorizontal.spec.ts.snap +17 -0
  64. package/app/components/02.molecules/profile-section/ProfileSection.vue +2 -3
  65. package/app/components/02.molecules/profile-section/tests/ProfileSection.spec.ts +2 -2
  66. package/app/components/02.molecules/stepper-list/StepperList.vue +131 -92
  67. package/app/components/02.molecules/stepper-list/stories/StepperList.stories.ts +31 -0
  68. package/app/components/02.molecules/stepper-list/tests/StepperList.spec.ts +24 -0
  69. package/app/components/02.molecules/stepper-list/tests/__snapshots__/StepperList.spec.ts.snap +22 -9
  70. package/app/components/03.organisms/image-galleries/slider-gallery/SliderGallery.vue +782 -0
  71. package/app/components/03.organisms/image-galleries/slider-gallery/stories/SliderGallery.stories.ts +233 -0
  72. package/app/components/03.organisms/image-galleries/slider-gallery/tests/SliderGallery.spec.ts +226 -0
  73. package/app/components/03.organisms/image-galleries/slider-gallery/tests/__snapshots__/SliderGallery.spec.ts.snap +69 -0
  74. package/app/components/03.organisms/services/services-grids/ServicesCardGrid.vue +1 -1
  75. package/app/components/03.organisms/services/services-grids/ServicesSectionGrid.vue +1 -1
  76. package/app/components/03.organisms/services/services-section/ServicesSection.vue +2 -3
  77. package/app/components/04.templates/page-hero-highlights/PageHeroHighlights.vue +239 -0
  78. package/app/components/04.templates/page-hero-highlights/stories/PageHeroHighlights.stories.ts +404 -0
  79. package/app/components/04.templates/page-hero-highlights/tests/PageHeroHighlights.spec.ts +198 -0
  80. package/app/components/04.templates/page-hero-highlights/tests/__snapshots__/PageHeroHighlights.spec.ts.snap +19 -0
  81. package/app/components/container-glow/ContainerGlowCore.vue +20 -27
  82. package/app/components/forms/input-button/InputButtonCore.vue +105 -104
  83. package/app/components/glowing-border/stories/GlowingBorder.stories.ts +21 -21
  84. package/app/composables/useAriaLabelledById.ts +13 -0
  85. package/app/layouts/default.vue +8 -3
  86. package/app/pages/forms/examples/buttons/index.vue +6 -6
  87. package/app/pages/forms/examples/material/checkbox-radio-panels.vue +3 -3
  88. package/app/pages/forms/examples/material/text-fields.vue +607 -610
  89. package/app/pages/page-hero-highlights.vue +81 -0
  90. package/app/pages/ui/{display-card.vue → card-core.vue} +15 -15
  91. package/app/pages/ui/contact-section.vue +1 -1
  92. package/app/pages/ui/container-glow.vue +1 -1
  93. package/app/pages/ui/content-width.vue +126 -0
  94. package/app/pages/ui/glowing-border.vue +9 -9
  95. package/app/pages/ui/navigation/navigation-horizontal.vue +484 -0
  96. package/app/pages/ui/services/services-section/[slug].vue +3 -1
  97. package/app/types/components/index.ts +1 -0
  98. package/app/types/components/navigation-horizontal.d.ts +11 -0
  99. package/package.json +2 -2
  100. package/app/assets/styles/setup/01.config/_basic-resets.css +0 -9
  101. package/app/components/content-columns/TwoColumns.vue +0 -59
  102. package/app/components/content-columns/stories/TwoColumns.stories.ts +0 -561
  103. package/app/components/content-containers/ContentContainer.vue +0 -89
  104. package/app/components/content-containers/stories/ContentContainer.stories.ts +0 -465
  105. package/app/components/content-grid/ContentGrid.vue +0 -85
  106. package/app/components/display-card/DisplayCard.vue +0 -122
  107. package/app/components/image-galleries/SliderGallery.vue +0 -786
  108. package/app/pages/ui/content-container.vue +0 -112
  109. /package/app/components/{accordian → 02.molecules/expandable/accordian}/AccordianCore.vue +0 -0
  110. /package/app/components/{accordian → 02.molecules/expandable/accordian}/tests/AccordianCore.spec.ts +0 -0
  111. /package/app/components/{accordian → 02.molecules/expandable/accordian}/tests/__snapshots__/AccordianCore.spec.ts.snap +0 -0
  112. /package/app/components/{expanding-panel → 02.molecules/expandable/expanding-panel}/ExpandingPanel.vue +0 -0
@@ -0,0 +1,17 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`NavigationHorizontal > renders correct HTML structure 1`] = `
4
+ "<nav class="navigation-horizontal">
5
+ <ul class="navigation-horizontal-list">
6
+ <li class=""><a href="/">
7
+ <!--v-if--> Home
8
+ </a></li>
9
+ <li class=""><a href="/about">
10
+ <!--v-if--> About
11
+ </a></li>
12
+ <li class=""><a href="/contact">
13
+ <!--v-if--> Contact
14
+ </a></li>
15
+ </ul>
16
+ </nav>"
17
+ `;
@@ -3,7 +3,7 @@
3
3
  :is="tag"
4
4
  class="profile-section"
5
5
  :class="[elementClasses]"
6
- :aria-labelledby="needsLabel ? headingId : undefined"
6
+ :aria-labelledby="ariaLabelledby"
7
7
  >
8
8
  <header class="profile-section-header">
9
9
  <slot v-if="hasEyebrowTextSlot" name="eyebrowText"></slot>
@@ -51,8 +51,7 @@ const props = withDefaults(defineProps<Props>(), {
51
51
  styleClassPassthrough: () => [],
52
52
  });
53
53
 
54
- const headingId = useId();
55
- const needsLabel = computed(() => props.tag === "section" || props.tag === "article");
54
+ const { headingId, ariaLabelledby } = useAriaLabelledById(() => props.tag);
56
55
 
57
56
  const slots = useSlots();
58
57
  const hasEyebrowTextSlot = computed(() => Boolean(slots.eyebrowText));
@@ -152,11 +152,11 @@ describe("ProfileSection", () => {
152
152
  expect(wrapper.find(".profile-section").attributes("aria-labelledby")).toBeUndefined();
153
153
  });
154
154
 
155
- it("does not add aria-labelledby when tag is main", async () => {
155
+ it("adds aria-labelledby when tag is main", async () => {
156
156
  const wrapper = await mountSuspended(ProfileSection, {
157
157
  props: { ...defaultProps, tag: "main" },
158
158
  });
159
- expect(wrapper.find(".profile-section").attributes("aria-labelledby")).toBeUndefined();
159
+ expect(wrapper.find(".profile-section").attributes("aria-labelledby")).toBeTruthy();
160
160
  });
161
161
 
162
162
  it("does not render profile-links section when slot is not provided", async () => {
@@ -1,5 +1,10 @@
1
1
  <template>
2
- <component :is="tag" class="stepper-list" :class="[elementClasses, { 'has-connectors': props.connected }]">
2
+ <component
3
+ :is="tag"
4
+ ref="listEl"
5
+ class="stepper-list"
6
+ :class="[elementClasses, { 'has-connectors': props.connected }]"
7
+ >
3
8
  <li
4
9
  v-for="index in itemCount"
5
10
  :key="index"
@@ -10,9 +15,7 @@
10
15
  ]"
11
16
  >
12
17
  <div
13
- :class="
14
- $slots[`indicator-${index - 1}`] ? 'stepper-list__indicator-custom' : 'stepper-list__indicator-counter'
15
- "
18
+ :class="$slots[`indicator-${index - 1}`] ? 'stepper-list__indicator-custom' : 'stepper-list__indicator-counter'"
16
19
  >
17
20
  <slot :name="`indicator-${index - 1}`"></slot>
18
21
  </div>
@@ -28,6 +31,7 @@ interface Props {
28
31
  tag?: "ul" | "ol";
29
32
  indicatorAlignment?: "top" | "center";
30
33
  indicatorVariant?: "disc" | "square" | "circle";
34
+ indicatorSize?: string;
31
35
  connected?: boolean;
32
36
  itemCount: number;
33
37
  styleClassPassthrough?: string | string[];
@@ -37,122 +41,157 @@ const props = withDefaults(defineProps<Props>(), {
37
41
  tag: "ul",
38
42
  indicatorAlignment: "top",
39
43
  indicatorVariant: "disc",
44
+ indicatorSize: "3rem",
40
45
  connected: true,
41
46
  styleClassPassthrough: () => [],
42
47
  });
43
48
 
44
49
  const { elementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
50
+
51
+ const listEl = ref<HTMLElement | null>(null);
52
+ let resizeObserver: ResizeObserver | null = null;
53
+
54
+ function updateConnectors() {
55
+ if (!listEl.value || !props.connected) return;
56
+ const lis = Array.from(listEl.value.querySelectorAll<HTMLLIElement>(":scope > li"));
57
+
58
+ lis.forEach((li, i) => {
59
+ if (i >= lis.length - 1) return;
60
+
61
+ const indicator = li.querySelector<HTMLElement>(
62
+ ".stepper-list__indicator-counter, .stepper-list__indicator-custom"
63
+ );
64
+ const nextIndicator = lis[i + 1]?.querySelector<HTMLElement>(
65
+ ".stepper-list__indicator-counter, .stepper-list__indicator-custom"
66
+ );
67
+
68
+ if (!indicator || !nextIndicator) return;
69
+
70
+ const liRect = li.getBoundingClientRect();
71
+ const indicatorRect = indicator.getBoundingClientRect();
72
+ const nextIndicatorRect = nextIndicator.getBoundingClientRect();
73
+
74
+ li.style.setProperty("--_connector-top", `${indicatorRect.bottom - liRect.top}px`);
75
+ li.style.setProperty("--_connector-height", `${Math.max(0, nextIndicatorRect.top - indicatorRect.bottom)}px`);
76
+ });
77
+ }
78
+
79
+ onMounted(() => {
80
+ updateConnectors();
81
+ if (typeof ResizeObserver !== "undefined" && listEl.value) {
82
+ resizeObserver = new ResizeObserver(updateConnectors);
83
+ resizeObserver.observe(listEl.value);
84
+ }
85
+ });
86
+
87
+ onBeforeUnmount(() => {
88
+ resizeObserver?.disconnect();
89
+ });
90
+
91
+ watch(
92
+ () => [props.itemCount, props.connected, props.indicatorAlignment],
93
+ async () => {
94
+ await nextTick();
95
+ updateConnectors();
96
+ }
97
+ );
45
98
  </script>
46
99
 
47
100
  <style lang="css">
48
101
  @layer components {
49
- .stepper-list {
50
- --_list-padding-block: 1.2rem;
51
- --_counter-size: 3rem;
52
- --_stepper-list-connector-width: 0.2rem;
53
-
54
- list-style: none;
55
- counter-reset: stepper-list;
56
- padding: 0;
57
-
58
- li {
59
- display: grid;
60
- grid-template-columns: auto 1fr;
61
- gap: 2.2rem;
62
- counter-increment: stepper-list;
63
- padding-inline-start: 0rem;
64
- padding-block: var(--_list-padding-block);
65
- position: relative;
66
-
67
- &.indicator-top {
68
- align-items: start;
69
- }
102
+ .stepper-list {
103
+ --_list-padding-block: 1.2rem;
104
+ --_counter-size: v-bind(indicatorSize);
105
+ --_stepper-list-connector-width: 0.2rem;
70
106
 
71
- &.indicator-center {
72
- align-items: center;
73
- }
74
-
75
- .stepper-list__indicator-counter::before {
76
- content: counter(stepper-list);
107
+ list-style: none;
108
+ counter-reset: stepper-list;
109
+ padding: 0;
77
110
 
111
+ li {
78
112
  display: grid;
79
- place-content: center;
80
- width: var(--_counter-size);
81
- height: var(--_counter-size);
82
- font-size: 1.4rem;
83
- font-weight: 600;
84
- }
113
+ grid-template-columns: auto 1fr;
114
+ gap: 2.2rem;
115
+ counter-increment: stepper-list;
116
+ padding-inline-start: 0rem;
117
+ padding-block: var(--_list-padding-block);
118
+ position: relative;
119
+
120
+ &.indicator-top {
121
+ align-items: start;
122
+ }
85
123
 
86
- &.indicator-circle .stepper-list__indicator-counter::before {
87
- background-color: var(--stepper-list-counter-circle-background);
88
- color: var(--stepper-list-counter-circle-text);
89
- border: 2px solid var(--stepper-list-counter-circle-border);
90
- border-radius: 100vw;
91
- }
124
+ &.indicator-center {
125
+ align-items: center;
126
+ }
92
127
 
93
- &.indicator-disc .stepper-list__indicator-counter::before {
94
- background-color: var(--stepper-list-counter-disc-background);
95
- color: var(--stepper-list-counter-disc-text);
96
- border: 2px solid var(--stepper-list-counter-disc-border);
97
- border-radius: 100vw;
98
- }
128
+ .stepper-list__indicator-counter::before {
129
+ content: counter(stepper-list);
99
130
 
100
- &.indicator-square .stepper-list__indicator-counter::before {
101
- background-color: var(--stepper-list-counter-square-background);
102
- color: var(--stepper-list-counter-square-text);
103
- border: 2px solid var(--stepper-list-counter-square-border);
104
- border-radius: 0.25rem;
105
- }
131
+ display: grid;
132
+ place-content: center;
133
+ width: var(--_counter-size);
134
+ height: var(--_counter-size);
135
+ font-size: 1.4rem;
136
+ font-weight: 600;
137
+ }
106
138
 
107
- &.has-indicator::before {
108
- display: none;
109
- }
139
+ &.indicator-circle .stepper-list__indicator-counter::before {
140
+ background-color: var(--stepper-list-counter-circle-background);
141
+ color: var(--stepper-list-counter-circle-text);
142
+ border: 2px solid var(--stepper-list-counter-circle-border);
143
+ border-radius: 100vw;
144
+ }
110
145
 
111
- .stepper-list__indicator-custom,
112
- .stepper-list__indicator-counter {
113
- anchor-name: --indicator-bubble;
114
- }
146
+ &.indicator-disc .stepper-list__indicator-counter::before {
147
+ background-color: var(--stepper-list-counter-disc-background);
148
+ color: var(--stepper-list-counter-disc-text);
149
+ border: 2px solid var(--stepper-list-counter-disc-border);
150
+ border-radius: 100vw;
151
+ }
115
152
 
116
- .stepper-list__indicator-custom {
117
- display: inline-flex;
118
- align-items: center;
119
- justify-content: center;
153
+ &.indicator-square .stepper-list__indicator-counter::before {
154
+ background-color: var(--stepper-list-counter-square-background);
155
+ color: var(--stepper-list-counter-square-text);
156
+ border: 2px solid var(--stepper-list-counter-square-border);
157
+ border-radius: 0.25rem;
158
+ }
120
159
 
121
- .indicator-icon {
122
- color: var(--stepper-list-icon);
123
- width: var(--_counter-size);
124
- height: var(--_counter-size);
160
+ &.has-indicator::before {
161
+ display: none;
162
+ }
163
+
164
+ .stepper-list__indicator-custom,
165
+ .stepper-list__indicator-counter {
166
+ anchor-name: --indicator-bubble;
167
+ }
168
+
169
+ .stepper-list__indicator-custom {
170
+ display: inline-flex;
171
+ align-items: center;
172
+ justify-content: center;
173
+
174
+ .indicator-icon {
175
+ color: var(--stepper-list-icon);
176
+ width: var(--_counter-size) !important;
177
+ height: var(--_counter-size) !important;
178
+ }
125
179
  }
126
180
  }
127
181
  }
128
- }
129
-
130
- /* Fallback: per-li connectors for browsers without anchor positioning */
131
- /* @supports not (anchor-name: --x) { */
132
- .stepper-list.has-connectors li:not(:last-child)::after {
133
- content: "";
134
- position: absolute;
135
- left: calc(var(--_counter-size) / 2);
136
- transform: translateX(-50%);
137
- top: calc(1.2rem + 3rem);
138
- bottom: calc(-1 * var(--_list-padding-block));
139
- width: var(--_stepper-list-connector-width);
140
- background-color: var(--stepper-list-connector-color, currentColor);
141
- }
142
- /* } */
143
182
 
144
- /* Enhanced: anchor-based connector positioning */
145
- /* @supports (anchor-name: --x) {
146
183
  .stepper-list.has-connectors li:not(:last-child)::after {
147
184
  content: "";
148
185
  position: absolute;
149
- left: anchor(--indicator-bubble, center);
186
+ left: calc(var(--_counter-size) / 2);
150
187
  transform: translateX(-50%);
151
- top: anchor(--indicator-bubble, bottom);
152
- bottom: calc(-1 * var(--stepper-list-item-gap, 2.4rem));
153
- width: var(--stepper-list-connector-width, 2px);
188
+ /* JS sets --_connector-top and --_connector-height from measured indicator positions.
189
+ The fallback values handle the indicator-top case before JS runs. */
190
+ top: var(--_connector-top, calc(var(--_list-padding-block) + var(--_counter-size)));
191
+ height: var(--_connector-height, auto);
192
+ bottom: calc(-1 * var(--_list-padding-block));
193
+ width: var(--_stepper-list-connector-width);
154
194
  background-color: var(--stepper-list-connector-color, currentColor);
155
195
  }
156
- } */
157
196
  }
158
197
  </style>
@@ -24,6 +24,10 @@ const meta: Meta<typeof StepperList> = {
24
24
  options: ["disc", "circle", "square"],
25
25
  description: "Visual style of the counter indicator",
26
26
  },
27
+ indicatorSize: {
28
+ control: "text",
29
+ description: "Size of the indicator bubble — any valid CSS length (e.g. '3rem', '40px')",
30
+ },
27
31
  connected: {
28
32
  control: "boolean",
29
33
  description: "Whether to show connectors between indicators (only visible in supported browsers)",
@@ -38,6 +42,7 @@ const meta: Meta<typeof StepperList> = {
38
42
  itemCount: 3,
39
43
  indicatorAlignment: "top",
40
44
  indicatorVariant: "disc",
45
+ indicatorSize: "3rem",
41
46
  connected: false,
42
47
  styleClassPassthrough: [],
43
48
  },
@@ -289,6 +294,32 @@ export const VariantSquare: Story = {
289
294
  }),
290
295
  };
291
296
 
297
+ /** Custom indicator size — demonstrates a larger indicator bubble. */
298
+ export const CustomIndicatorSize: Story = {
299
+ name: "Custom Indicator Size",
300
+ args: {
301
+ tag: "ul",
302
+ itemCount: 4,
303
+ indicatorSize: "5rem",
304
+ connected: true,
305
+ indicatorAlignment: "center",
306
+ },
307
+ render: (args) => ({
308
+ components: { StepperList },
309
+ setup() {
310
+ return { args };
311
+ },
312
+ template: `
313
+ <StepperList v-bind="args">
314
+ <template #item-0><p class="page-body-normal">Create your account</p></template>
315
+ <template #item-1><p class="page-body-normal">Verify your email and complete your profile with a photo, bio, and preferred contact details</p></template>
316
+ <template #item-2><p class="page-body-normal">Choose a plan</p></template>
317
+ <template #item-3><p class="page-body-normal">Start building</p></template>
318
+ </StepperList>
319
+ `,
320
+ }),
321
+ };
322
+
292
323
  /** Rich content — items contain a mix of heading + body, varying in length. */
293
324
  export const RichContent: Story = {
294
325
  name: "Rich Item Content",
@@ -264,6 +264,30 @@ describe("StepperList", () => {
264
264
  expect(wrapper.find("li")?.classes()).toContain("indicator-square");
265
265
  });
266
266
 
267
+ // ─── indicatorSize ────────────────────────────────────────────────────────
268
+
269
+ it("defaults indicatorSize to 3rem", async () => {
270
+ const wrapper = await mountSuspended(StepperList, {
271
+ props: { itemCount: 1 },
272
+ });
273
+ const style = (wrapper.element as HTMLElement).style;
274
+ expect(style.getPropertyValue("--v-bind-indicatorSize") || wrapper.html()).toBeTruthy();
275
+ });
276
+
277
+ it("accepts a custom indicatorSize prop without error", async () => {
278
+ const wrapper = await mountSuspended(StepperList, {
279
+ props: { itemCount: 1, indicatorSize: "5rem" },
280
+ });
281
+ expect(wrapper.vm).toBeTruthy();
282
+ });
283
+
284
+ it("renders correct HTML structure with custom indicatorSize", async () => {
285
+ const wrapper = await mountSuspended(StepperList, {
286
+ props: { itemCount: 2, indicatorSize: "4rem" },
287
+ });
288
+ expect(wrapper.html()).toMatchSnapshot();
289
+ });
290
+
267
291
  // ─── Combined props ───────────────────────────────────────────────────────
268
292
 
269
293
  it("renders correctly with all props and slots combined", async () => {
@@ -2,19 +2,19 @@
2
2
 
3
3
  exports[`StepperList > renders correct HTML structure (ol, 5 items) 1`] = `
4
4
  "<ol class="stepper-list has-connectors">
5
- <li class="indicator-top indicator-disc">
5
+ <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
6
6
  <div class="stepper-list__indicator-counter"></div>
7
7
  <div></div>
8
8
  </li>
9
- <li class="indicator-top indicator-disc">
9
+ <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
10
10
  <div class="stepper-list__indicator-counter"></div>
11
11
  <div></div>
12
12
  </li>
13
- <li class="indicator-top indicator-disc">
13
+ <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
14
14
  <div class="stepper-list__indicator-counter"></div>
15
15
  <div></div>
16
16
  </li>
17
- <li class="indicator-top indicator-disc">
17
+ <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
18
18
  <div class="stepper-list__indicator-counter"></div>
19
19
  <div></div>
20
20
  </li>
@@ -27,7 +27,11 @@ exports[`StepperList > renders correct HTML structure (ol, 5 items) 1`] = `
27
27
 
28
28
  exports[`StepperList > renders correct HTML structure (ul, 3 items) 1`] = `
29
29
  "<ul class="stepper-list has-connectors">
30
- <li class="indicator-top indicator-disc">
30
+ <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
31
+ <div class="stepper-list__indicator-counter"></div>
32
+ <div></div>
33
+ </li>
34
+ <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
31
35
  <div class="stepper-list__indicator-counter"></div>
32
36
  <div></div>
33
37
  </li>
@@ -35,6 +39,15 @@ exports[`StepperList > renders correct HTML structure (ul, 3 items) 1`] = `
35
39
  <div class="stepper-list__indicator-counter"></div>
36
40
  <div></div>
37
41
  </li>
42
+ </ul>"
43
+ `;
44
+
45
+ exports[`StepperList > renders correct HTML structure with custom indicatorSize 1`] = `
46
+ "<ul class="stepper-list has-connectors">
47
+ <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
48
+ <div class="stepper-list__indicator-counter"></div>
49
+ <div></div>
50
+ </li>
38
51
  <li class="indicator-top indicator-disc">
39
52
  <div class="stepper-list__indicator-counter"></div>
40
53
  <div></div>
@@ -44,7 +57,7 @@ exports[`StepperList > renders correct HTML structure (ul, 3 items) 1`] = `
44
57
 
45
58
  exports[`StepperList > renders correct HTML structure with indicator slots 1`] = `
46
59
  "<ul class="stepper-list has-connectors">
47
- <li class="has-indicator indicator-top indicator-disc">
60
+ <li class="has-indicator indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
48
61
  <div class="stepper-list__indicator-custom"><span class="indicator-icon">✓</span></div>
49
62
  <div><span>First item</span></div>
50
63
  </li>
@@ -57,7 +70,7 @@ exports[`StepperList > renders correct HTML structure with indicator slots 1`] =
57
70
 
58
71
  exports[`StepperList > renders correct HTML structure with styleClassPassthrough 1`] = `
59
72
  "<ul class="stepper-list custom-class another-class has-connectors">
60
- <li class="indicator-top indicator-disc">
73
+ <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
61
74
  <div class="stepper-list__indicator-counter"></div>
62
75
  <div></div>
63
76
  </li>
@@ -70,11 +83,11 @@ exports[`StepperList > renders correct HTML structure with styleClassPassthrough
70
83
 
71
84
  exports[`StepperList > renders correctly with all props and slots combined 1`] = `
72
85
  "<ol class="stepper-list combined-class has-connectors">
73
- <li class="has-indicator indicator-top indicator-disc">
86
+ <li class="has-indicator indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
74
87
  <div class="stepper-list__indicator-custom"><span class="indicator-icon">1</span></div>
75
88
  <div><span>Step one</span></div>
76
89
  </li>
77
- <li class="indicator-top indicator-disc">
90
+ <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
78
91
  <div class="stepper-list__indicator-counter"></div>
79
92
  <div><span>Step two</span></div>
80
93
  </li>