srcdev-nuxt-components 9.6.4 → 9.6.5

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 (27) hide show
  1. package/.claude/skills/component-compliance-checklist.md +9 -1
  2. package/.claude/skills/components/progress-tracker.md +140 -0
  3. package/.claude/skills/components/stepper-list.md +10 -3
  4. package/.claude/skills/components/tabbed-content.md +4 -0
  5. package/.claude/skills/index.md +2 -1
  6. package/.claude/skills/storybook-add-story.md +6 -0
  7. package/.vscode/srcdev-component-progress-tracker.code-snippets +45 -0
  8. package/.vscode/srcdev-component-stepper-list.code-snippets +3 -2
  9. package/.vscode/srcdev-component-tabbed-content.code-snippets +1 -0
  10. package/app/components/01.atoms/tabbed-content/CONSUMER-STYLING.md +5 -1
  11. package/app/components/01.atoms/tabbed-content/TabbedContent.vue +2 -2
  12. package/app/components/01.atoms/tabbed-content/stories/TabbedContent.stories.ts +26 -0
  13. package/app/components/02.molecules/contact-section/tests/__snapshots__/ContactSection.spec.ts.snap +28 -28
  14. package/app/components/02.molecules/progress-tracker/CONSUMER-STYLING.md +116 -0
  15. package/app/components/02.molecules/progress-tracker/ProgressTracker.vue +275 -0
  16. package/app/components/02.molecules/progress-tracker/stories/ProgressTracker.stories.ts +424 -0
  17. package/app/components/02.molecules/progress-tracker/tests/ProgressTracker.spec.ts +253 -0
  18. package/app/components/02.molecules/progress-tracker/tests/__snapshots__/ProgressTracker.spec.ts.snap +46 -0
  19. package/app/components/02.molecules/stepper-list/CONSUMER-STYLING.md +42 -7
  20. package/app/components/02.molecules/stepper-list/StepperList.vue +42 -19
  21. package/app/components/02.molecules/stepper-list/stories/StepperList.stories.ts +288 -2
  22. package/app/components/02.molecules/stepper-list/tests/StepperList.spec.ts +161 -34
  23. package/app/components/02.molecules/stepper-list/tests/__snapshots__/StepperList.spec.ts.snap +40 -40
  24. package/app/components/03.organisms/services/service-detail/tests/__snapshots__/ServiceDetail.spec.ts.snap +7 -7
  25. package/app/types/components/index.ts +1 -0
  26. package/app/types/components/progress-tracker.d.ts +6 -0
  27. package/package.json +1 -1
@@ -1,12 +1,21 @@
1
- import { describe, it, expect } from "vitest";
1
+ import { describe, it, expect, vi, afterEach } from "vitest";
2
+ import { nextTick } from "vue";
2
3
  import { mountSuspended } from "@nuxt/test-utils/runtime";
4
+ import type { VueWrapper } from "@vue/test-utils";
3
5
  import StepperList from "../StepperList.vue";
4
6
 
7
+ let wrapper: VueWrapper | undefined;
8
+
5
9
  describe("StepperList", () => {
10
+ afterEach(() => {
11
+ wrapper?.unmount();
12
+ wrapper = undefined;
13
+ vi.restoreAllMocks();
14
+ });
6
15
  // ─── Mount ───────────────────────────────────────────────────────────────
7
16
 
8
17
  it("mounts without error", async () => {
9
- const wrapper = await mountSuspended(StepperList, {
18
+ wrapper = await mountSuspended(StepperList, {
10
19
  props: { itemCount: 3 },
11
20
  });
12
21
  expect(wrapper.vm).toBeTruthy();
@@ -15,21 +24,21 @@ describe("StepperList", () => {
15
24
  // ─── Snapshots ───────────────────────────────────────────────────────────
16
25
 
17
26
  it("renders correct HTML structure (ul, 3 items)", async () => {
18
- const wrapper = await mountSuspended(StepperList, {
27
+ wrapper = await mountSuspended(StepperList, {
19
28
  props: { tag: "ul", itemCount: 3 },
20
29
  });
21
30
  expect(wrapper.html()).toMatchSnapshot();
22
31
  });
23
32
 
24
33
  it("renders correct HTML structure (ol, 5 items)", async () => {
25
- const wrapper = await mountSuspended(StepperList, {
34
+ wrapper = await mountSuspended(StepperList, {
26
35
  props: { tag: "ol", itemCount: 5 },
27
36
  });
28
37
  expect(wrapper.html()).toMatchSnapshot();
29
38
  });
30
39
 
31
40
  it("renders correct HTML structure with styleClassPassthrough", async () => {
32
- const wrapper = await mountSuspended(StepperList, {
41
+ wrapper = await mountSuspended(StepperList, {
33
42
  props: {
34
43
  itemCount: 2,
35
44
  styleClassPassthrough: ["custom-class", "another-class"],
@@ -39,7 +48,7 @@ describe("StepperList", () => {
39
48
  });
40
49
 
41
50
  it("renders correct HTML structure with indicator slots", async () => {
42
- const wrapper = await mountSuspended(StepperList, {
51
+ wrapper = await mountSuspended(StepperList, {
43
52
  props: { itemCount: 2 },
44
53
  slots: {
45
54
  "indicator-0": '<span class="indicator-icon">✓</span>',
@@ -53,21 +62,21 @@ describe("StepperList", () => {
53
62
  // ─── Tag rendering ───────────────────────────────────────────────────────
54
63
 
55
64
  it("renders as <ul> by default", async () => {
56
- const wrapper = await mountSuspended(StepperList, {
65
+ wrapper = await mountSuspended(StepperList, {
57
66
  props: { itemCount: 1 },
58
67
  });
59
68
  expect(wrapper.element.tagName).toBe("UL");
60
69
  });
61
70
 
62
71
  it("renders as <ul> when tag='ul'", async () => {
63
- const wrapper = await mountSuspended(StepperList, {
72
+ wrapper = await mountSuspended(StepperList, {
64
73
  props: { tag: "ul", itemCount: 1 },
65
74
  });
66
75
  expect(wrapper.element.tagName).toBe("UL");
67
76
  });
68
77
 
69
78
  it("renders as <ol> when tag='ol'", async () => {
70
- const wrapper = await mountSuspended(StepperList, {
79
+ wrapper = await mountSuspended(StepperList, {
71
80
  props: { tag: "ol", itemCount: 1 },
72
81
  });
73
82
  expect(wrapper.element.tagName).toBe("OL");
@@ -76,23 +85,70 @@ describe("StepperList", () => {
76
85
  // ─── Item count ──────────────────────────────────────────────────────────
77
86
 
78
87
  it("renders the correct number of <li> elements", async () => {
79
- const wrapper = await mountSuspended(StepperList, {
88
+ wrapper = await mountSuspended(StepperList, {
80
89
  props: { itemCount: 4 },
81
90
  });
82
91
  expect(wrapper.findAll("li").length).toBe(4);
83
92
  });
84
93
 
85
94
  it("renders zero <li> elements when itemCount is 0", async () => {
86
- const wrapper = await mountSuspended(StepperList, {
95
+ wrapper = await mountSuspended(StepperList, {
87
96
  props: { itemCount: 0 },
88
97
  });
89
98
  expect(wrapper.findAll("li").length).toBe(0);
90
99
  });
91
100
 
101
+ it("floors a fractional itemCount instead of rendering nothing", async () => {
102
+ wrapper = await mountSuspended(StepperList, {
103
+ props: { itemCount: 2.7 },
104
+ });
105
+ expect(wrapper.findAll("li").length).toBe(2);
106
+ });
107
+
108
+ it("renders zero <li> elements for a negative itemCount", async () => {
109
+ wrapper = await mountSuspended(StepperList, {
110
+ props: { itemCount: -3 },
111
+ });
112
+ expect(wrapper.findAll("li").length).toBe(0);
113
+ });
114
+
115
+ it("renders zero <li> elements for a NaN itemCount", async () => {
116
+ wrapper = await mountSuspended(StepperList, {
117
+ props: { itemCount: Number.NaN },
118
+ });
119
+ expect(wrapper.findAll("li").length).toBe(0);
120
+ });
121
+
122
+ it("updates the number of <li> elements when itemCount changes", async () => {
123
+ wrapper = await mountSuspended(StepperList, {
124
+ props: { itemCount: 2 },
125
+ });
126
+ await wrapper.setProps({ itemCount: 5 });
127
+ expect(wrapper.findAll("li").length).toBe(5);
128
+ });
129
+
130
+ // ─── Semantics ───────────────────────────────────────────────────────────
131
+
132
+ it("keeps list semantics with role='list' despite list-style: none", async () => {
133
+ wrapper = await mountSuspended(StepperList, {
134
+ props: { tag: "ol", itemCount: 1 },
135
+ });
136
+ expect(wrapper.attributes("role")).toBe("list");
137
+ });
138
+
139
+ it("wraps each item slot in .stepper-list-content", async () => {
140
+ wrapper = await mountSuspended(StepperList, {
141
+ props: { itemCount: 2 },
142
+ slots: { "item-1": "<span class='second'>Second</span>" },
143
+ });
144
+ expect(wrapper.findAll(".stepper-list-item").length).toBe(2);
145
+ expect(wrapper.findAll(".stepper-list-content")[1]!.find(".second").exists()).toBe(true);
146
+ });
147
+
92
148
  // ─── Base classes ────────────────────────────────────────────────────────
93
149
 
94
150
  it("always has the indicator-list class", async () => {
95
- const wrapper = await mountSuspended(StepperList, {
151
+ wrapper = await mountSuspended(StepperList, {
96
152
  props: { itemCount: 1 },
97
153
  });
98
154
  expect(wrapper.classes()).toContain("stepper-list");
@@ -101,14 +157,14 @@ describe("StepperList", () => {
101
157
  // ─── styleClassPassthrough ───────────────────────────────────────────────
102
158
 
103
159
  it("applies a single styleClassPassthrough string", async () => {
104
- const wrapper = await mountSuspended(StepperList, {
160
+ wrapper = await mountSuspended(StepperList, {
105
161
  props: { itemCount: 1, styleClassPassthrough: "my-class" },
106
162
  });
107
163
  expect(wrapper.classes()).toContain("my-class");
108
164
  });
109
165
 
110
166
  it("applies multiple styleClassPassthrough classes from an array", async () => {
111
- const wrapper = await mountSuspended(StepperList, {
167
+ wrapper = await mountSuspended(StepperList, {
112
168
  props: {
113
169
  itemCount: 1,
114
170
  styleClassPassthrough: ["class-a", "class-b"],
@@ -119,7 +175,7 @@ describe("StepperList", () => {
119
175
  });
120
176
 
121
177
  it("updates classes when styleClassPassthrough changes after mount", async () => {
122
- const wrapper = await mountSuspended(StepperList, {
178
+ wrapper = await mountSuspended(StepperList, {
123
179
  props: { itemCount: 1, styleClassPassthrough: ["original"] },
124
180
  });
125
181
  await wrapper.setProps({ styleClassPassthrough: ["updated"] });
@@ -128,7 +184,7 @@ describe("StepperList", () => {
128
184
  });
129
185
 
130
186
  it("renders cleanly with no styleClassPassthrough prop", async () => {
131
- const wrapper = await mountSuspended(StepperList, {
187
+ wrapper = await mountSuspended(StepperList, {
132
188
  props: { itemCount: 1 },
133
189
  });
134
190
  // Only the base class should be present (and any passthrough-derived ones)
@@ -138,7 +194,7 @@ describe("StepperList", () => {
138
194
  // ─── Slot: item-N ────────────────────────────────────────────────────────
139
195
 
140
196
  it("renders item slot content inside each <li>", async () => {
141
- const wrapper = await mountSuspended(StepperList, {
197
+ wrapper = await mountSuspended(StepperList, {
142
198
  props: { itemCount: 2 },
143
199
  slots: {
144
200
  "item-0": "<span>First</span>",
@@ -153,7 +209,7 @@ describe("StepperList", () => {
153
209
  // ─── Slot: indicator-N ───────────────────────────────────────────────────
154
210
 
155
211
  it("adds has-indicator class to <li> when indicator slot is provided", async () => {
156
- const wrapper = await mountSuspended(StepperList, {
212
+ wrapper = await mountSuspended(StepperList, {
157
213
  props: { itemCount: 3 },
158
214
  slots: {
159
215
  "indicator-1": '<span class="indicator-icon">★</span>',
@@ -166,7 +222,7 @@ describe("StepperList", () => {
166
222
  });
167
223
 
168
224
  it("renders the custom indicator wrapper when indicator slot is provided", async () => {
169
- const wrapper = await mountSuspended(StepperList, {
225
+ wrapper = await mountSuspended(StepperList, {
170
226
  props: { itemCount: 2 },
171
227
  slots: {
172
228
  "indicator-0": '<span class="indicator-icon">✓</span>',
@@ -177,7 +233,7 @@ describe("StepperList", () => {
177
233
  });
178
234
 
179
235
  it("renders the counter wrapper when no indicator slot is provided", async () => {
180
- const wrapper = await mountSuspended(StepperList, {
236
+ wrapper = await mountSuspended(StepperList, {
181
237
  props: { itemCount: 2 },
182
238
  });
183
239
  const items = wrapper.findAll("li");
@@ -186,7 +242,7 @@ describe("StepperList", () => {
186
242
  });
187
243
 
188
244
  it("renders indicator slot content inside the custom indicator wrapper", async () => {
189
- const wrapper = await mountSuspended(StepperList, {
245
+ wrapper = await mountSuspended(StepperList, {
190
246
  props: { itemCount: 1 },
191
247
  slots: {
192
248
  "indicator-0": '<span class="indicator-icon">✓</span>',
@@ -197,7 +253,7 @@ describe("StepperList", () => {
197
253
  });
198
254
 
199
255
  it("only items with indicator slots receive has-indicator; others do not", async () => {
200
- const wrapper = await mountSuspended(StepperList, {
256
+ wrapper = await mountSuspended(StepperList, {
201
257
  props: { itemCount: 4 },
202
258
  slots: {
203
259
  "indicator-0": "<span>A</span>",
@@ -214,37 +270,108 @@ describe("StepperList", () => {
214
270
  // ─── connected ──────────────────────────────────────────────────────
215
271
 
216
272
  it("has has-connectors class by default", async () => {
217
- const wrapper = await mountSuspended(StepperList, {
273
+ wrapper = await mountSuspended(StepperList, {
218
274
  props: { itemCount: 1 },
219
275
  });
220
276
  expect(wrapper.classes()).toContain("has-connectors");
221
277
  });
222
278
 
223
279
  it("has has-connectors class when connected is true", async () => {
224
- const wrapper = await mountSuspended(StepperList, {
280
+ wrapper = await mountSuspended(StepperList, {
225
281
  props: { itemCount: 1, connected: true },
226
282
  });
227
283
  expect(wrapper.classes()).toContain("has-connectors");
228
284
  });
229
285
 
230
286
  it("does not have has-connectors class when connected is false", async () => {
231
- const wrapper = await mountSuspended(StepperList, {
287
+ wrapper = await mountSuspended(StepperList, {
232
288
  props: { itemCount: 1, connected: false },
233
289
  });
234
290
  expect(wrapper.classes()).not.toContain("has-connectors");
235
291
  });
236
292
 
293
+ it("centres each connector on its measured indicator, not on --_counter-size", async () => {
294
+ const rect = (left: number, width: number, top: number, height: number) =>
295
+ ({ left, width, top, height, right: left + width, bottom: top + height, x: left, y: top }) as DOMRect;
296
+ vi.spyOn(HTMLElement.prototype, "getBoundingClientRect").mockImplementation(function (
297
+ this: HTMLElement
298
+ ) {
299
+ if (this.tagName === "LI") return rect(100, 400, this.previousElementSibling ? 80 : 0, 80);
300
+ return rect(110, 60, this.closest("li")?.previousElementSibling ? 90 : 10, 30);
301
+ });
302
+
303
+ wrapper = await mountSuspended(StepperList, {
304
+ props: { itemCount: 2 },
305
+ slots: { "indicator-0": "<span>Wide custom indicator</span>" },
306
+ });
307
+ const first = wrapper.findAll("li")[0]!.element as HTMLElement;
308
+ expect(first.style.getPropertyValue("--_connector-left")).toBe("40px");
309
+ expect(first.style.getPropertyValue("--_connector-top")).toBe("40px");
310
+ expect(first.style.getPropertyValue("--_connector-height")).toBe("50px");
311
+ });
312
+
313
+ it("re-measures connectors when a class changes inside the list, even if nothing resizes", async () => {
314
+ let secondIndicatorTop = 90;
315
+ const rect = (top: number, height: number) =>
316
+ ({ left: 100, width: 30, top, height, right: 130, bottom: top + height, x: 100, y: top }) as DOMRect;
317
+ vi.spyOn(HTMLElement.prototype, "getBoundingClientRect").mockImplementation(function (this: HTMLElement) {
318
+ if (this.tagName === "LI") return rect(this.previousElementSibling ? 80 : 0, 80);
319
+ return this.closest("li")?.previousElementSibling ? rect(secondIndicatorTop, 30) : rect(10, 30);
320
+ });
321
+
322
+ wrapper = await mountSuspended(StepperList, {
323
+ props: { itemCount: 2 },
324
+ slots: { "indicator-1": "<span class='marker'>2</span>" },
325
+ });
326
+ const first = wrapper.findAll("li")[0]!.element as HTMLElement;
327
+ expect(first.style.getPropertyValue("--_connector-height")).toBe("50px");
328
+
329
+ secondIndicatorTop = 120;
330
+ wrapper.find(".marker").element.classList.add("is-current");
331
+ await Promise.resolve();
332
+ expect(first.style.getPropertyValue("--_connector-height")).toBe("80px");
333
+ });
334
+
335
+ it("observes every item for size changes, not only the list", async () => {
336
+ const observed: Element[] = [];
337
+ const originalResizeObserver = globalThis.ResizeObserver;
338
+ vi.stubGlobal(
339
+ "ResizeObserver",
340
+ class {
341
+ observe(el: Element) {
342
+ observed.push(el);
343
+ }
344
+ disconnect() {
345
+ observed.length = 0;
346
+ }
347
+ unobserve() {}
348
+ }
349
+ );
350
+
351
+ try {
352
+ wrapper = await mountSuspended(StepperList, { props: { itemCount: 3 } });
353
+ expect(observed.filter((el) => el.tagName === "LI")).toHaveLength(3);
354
+ expect(observed).toContain(wrapper.element);
355
+
356
+ await wrapper.setProps({ itemCount: 4 });
357
+ await nextTick();
358
+ expect(observed.filter((el) => el.tagName === "LI")).toHaveLength(4);
359
+ } finally {
360
+ vi.stubGlobal("ResizeObserver", originalResizeObserver);
361
+ }
362
+ });
363
+
237
364
  // ─── indicatorAlignment ───────────────────────────────────────────────────
238
365
 
239
366
  it("applies indicator-top class by default", async () => {
240
- const wrapper = await mountSuspended(StepperList, {
367
+ wrapper = await mountSuspended(StepperList, {
241
368
  props: { itemCount: 1 },
242
369
  });
243
370
  expect(wrapper.find("li")?.classes()).toContain("indicator-top");
244
371
  });
245
372
 
246
373
  it("applies indicator-center class when indicatorAlignment is center", async () => {
247
- const wrapper = await mountSuspended(StepperList, {
374
+ wrapper = await mountSuspended(StepperList, {
248
375
  props: { itemCount: 1, indicatorAlignment: "center" },
249
376
  });
250
377
  expect(wrapper.find("li")?.classes()).toContain("indicator-center");
@@ -253,21 +380,21 @@ describe("StepperList", () => {
253
380
  // ─── indicatorVariant ─────────────────────────────────────────────────────
254
381
 
255
382
  it("applies indicator-disc class by default", async () => {
256
- const wrapper = await mountSuspended(StepperList, {
383
+ wrapper = await mountSuspended(StepperList, {
257
384
  props: { itemCount: 1 },
258
385
  });
259
386
  expect(wrapper.find("li")?.classes()).toContain("indicator-disc");
260
387
  });
261
388
 
262
389
  it("applies indicator-circle class when indicatorVariant is circle", async () => {
263
- const wrapper = await mountSuspended(StepperList, {
390
+ wrapper = await mountSuspended(StepperList, {
264
391
  props: { itemCount: 1, indicatorVariant: "circle" },
265
392
  });
266
393
  expect(wrapper.find("li")?.classes()).toContain("indicator-circle");
267
394
  });
268
395
 
269
396
  it("applies indicator-square class when indicatorVariant is square", async () => {
270
- const wrapper = await mountSuspended(StepperList, {
397
+ wrapper = await mountSuspended(StepperList, {
271
398
  props: { itemCount: 1, indicatorVariant: "square" },
272
399
  });
273
400
  expect(wrapper.find("li")?.classes()).toContain("indicator-square");
@@ -276,7 +403,7 @@ describe("StepperList", () => {
276
403
  // ─── indicatorSize ────────────────────────────────────────────────────────
277
404
 
278
405
  it("defaults indicatorSize to 3rem", async () => {
279
- const wrapper = await mountSuspended(StepperList, {
406
+ wrapper = await mountSuspended(StepperList, {
280
407
  props: { itemCount: 1 },
281
408
  });
282
409
  const style = (wrapper.element as HTMLElement).style;
@@ -284,14 +411,14 @@ describe("StepperList", () => {
284
411
  });
285
412
 
286
413
  it("accepts a custom indicatorSize prop without error", async () => {
287
- const wrapper = await mountSuspended(StepperList, {
414
+ wrapper = await mountSuspended(StepperList, {
288
415
  props: { itemCount: 1, indicatorSize: "5rem" },
289
416
  });
290
417
  expect(wrapper.vm).toBeTruthy();
291
418
  });
292
419
 
293
420
  it("renders correct HTML structure with custom indicatorSize", async () => {
294
- const wrapper = await mountSuspended(StepperList, {
421
+ wrapper = await mountSuspended(StepperList, {
295
422
  props: { itemCount: 2, indicatorSize: "4rem" },
296
423
  });
297
424
  expect(wrapper.html()).toMatchSnapshot();
@@ -300,7 +427,7 @@ describe("StepperList", () => {
300
427
  // ─── Combined props ───────────────────────────────────────────────────────
301
428
 
302
429
  it("renders correctly with all props and slots combined", async () => {
303
- const wrapper = await mountSuspended(StepperList, {
430
+ wrapper = await mountSuspended(StepperList, {
304
431
  props: {
305
432
  tag: "ol",
306
433
  itemCount: 3,
@@ -1,99 +1,99 @@
1
1
  // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
2
 
3
3
  exports[`StepperList > renders correct HTML structure (ol, 5 items) 1`] = `
4
- "<ol class="stepper-list has-connectors">
5
- <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
4
+ "<ol role="list" class="stepper-list has-connectors">
5
+ <li class="stepper-list-item indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
6
6
  <div class="stepper-list__indicator-counter"></div>
7
- <div></div>
7
+ <div class="stepper-list-content"></div>
8
8
  </li>
9
- <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
9
+ <li class="stepper-list-item indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
10
10
  <div class="stepper-list__indicator-counter"></div>
11
- <div></div>
11
+ <div class="stepper-list-content"></div>
12
12
  </li>
13
- <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
13
+ <li class="stepper-list-item indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
14
14
  <div class="stepper-list__indicator-counter"></div>
15
- <div></div>
15
+ <div class="stepper-list-content"></div>
16
16
  </li>
17
- <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
17
+ <li class="stepper-list-item indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
18
18
  <div class="stepper-list__indicator-counter"></div>
19
- <div></div>
19
+ <div class="stepper-list-content"></div>
20
20
  </li>
21
- <li class="indicator-top indicator-disc">
21
+ <li class="stepper-list-item indicator-top indicator-disc">
22
22
  <div class="stepper-list__indicator-counter"></div>
23
- <div></div>
23
+ <div class="stepper-list-content"></div>
24
24
  </li>
25
25
  </ol>"
26
26
  `;
27
27
 
28
28
  exports[`StepperList > renders correct HTML structure (ul, 3 items) 1`] = `
29
- "<ul class="stepper-list has-connectors">
30
- <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
29
+ "<ul role="list" class="stepper-list has-connectors">
30
+ <li class="stepper-list-item indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
31
31
  <div class="stepper-list__indicator-counter"></div>
32
- <div></div>
32
+ <div class="stepper-list-content"></div>
33
33
  </li>
34
- <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
34
+ <li class="stepper-list-item indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
35
35
  <div class="stepper-list__indicator-counter"></div>
36
- <div></div>
36
+ <div class="stepper-list-content"></div>
37
37
  </li>
38
- <li class="indicator-top indicator-disc">
38
+ <li class="stepper-list-item indicator-top indicator-disc">
39
39
  <div class="stepper-list__indicator-counter"></div>
40
- <div></div>
40
+ <div class="stepper-list-content"></div>
41
41
  </li>
42
42
  </ul>"
43
43
  `;
44
44
 
45
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;">
46
+ "<ul role="list" class="stepper-list has-connectors">
47
+ <li class="stepper-list-item indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
48
48
  <div class="stepper-list__indicator-counter"></div>
49
- <div></div>
49
+ <div class="stepper-list-content"></div>
50
50
  </li>
51
- <li class="indicator-top indicator-disc">
51
+ <li class="stepper-list-item indicator-top indicator-disc">
52
52
  <div class="stepper-list__indicator-counter"></div>
53
- <div></div>
53
+ <div class="stepper-list-content"></div>
54
54
  </li>
55
55
  </ul>"
56
56
  `;
57
57
 
58
58
  exports[`StepperList > renders correct HTML structure with indicator slots 1`] = `
59
- "<ul class="stepper-list has-connectors">
60
- <li class="has-indicator indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
59
+ "<ul role="list" class="stepper-list has-connectors">
60
+ <li class="stepper-list-item has-indicator indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
61
61
  <div class="stepper-list__indicator-custom"><span class="indicator-icon">✓</span></div>
62
- <div><span>First item</span></div>
62
+ <div class="stepper-list-content"><span>First item</span></div>
63
63
  </li>
64
- <li class="indicator-top indicator-disc">
64
+ <li class="stepper-list-item indicator-top indicator-disc">
65
65
  <div class="stepper-list__indicator-counter"></div>
66
- <div><span>Second item</span></div>
66
+ <div class="stepper-list-content"><span>Second item</span></div>
67
67
  </li>
68
68
  </ul>"
69
69
  `;
70
70
 
71
71
  exports[`StepperList > renders correct HTML structure with styleClassPassthrough 1`] = `
72
- "<ul class="stepper-list custom-class another-class has-connectors">
73
- <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
72
+ "<ul role="list" class="stepper-list custom-class another-class has-connectors">
73
+ <li class="stepper-list-item indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
74
74
  <div class="stepper-list__indicator-counter"></div>
75
- <div></div>
75
+ <div class="stepper-list-content"></div>
76
76
  </li>
77
- <li class="indicator-top indicator-disc">
77
+ <li class="stepper-list-item indicator-top indicator-disc">
78
78
  <div class="stepper-list__indicator-counter"></div>
79
- <div></div>
79
+ <div class="stepper-list-content"></div>
80
80
  </li>
81
81
  </ul>"
82
82
  `;
83
83
 
84
84
  exports[`StepperList > renders correctly with all props and slots combined 1`] = `
85
- "<ol class="stepper-list combined-class has-connectors">
86
- <li class="has-indicator indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
85
+ "<ol role="list" class="stepper-list combined-class has-connectors">
86
+ <li class="stepper-list-item has-indicator indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
87
87
  <div class="stepper-list__indicator-custom"><span class="indicator-icon">1</span></div>
88
- <div><span>Step one</span></div>
88
+ <div class="stepper-list-content"><span>Step one</span></div>
89
89
  </li>
90
- <li class="indicator-top indicator-disc" style="--_connector-top: 0px; --_connector-height: 0px;">
90
+ <li class="stepper-list-item indicator-top indicator-disc" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
91
91
  <div class="stepper-list__indicator-counter"></div>
92
- <div><span>Step two</span></div>
92
+ <div class="stepper-list-content"><span>Step two</span></div>
93
93
  </li>
94
- <li class="indicator-top indicator-disc">
94
+ <li class="stepper-list-item indicator-top indicator-disc">
95
95
  <div class="stepper-list__indicator-counter"></div>
96
- <div><span>Step three</span></div>
96
+ <div class="stepper-list-content"><span>Step three</span></div>
97
97
  </li>
98
98
  </ol>"
99
99
  `;
@@ -37,22 +37,22 @@ exports[`ServiceDetail > renders correct HTML structure 1`] = `
37
37
  <h2 class="hero-text mb-20 subheading axis-horizontal">
38
38
  <!--v-if--><span class="text-block-0 normal">The Process</span>
39
39
  </h2>
40
- <ol class="stepper-list has-connectors service-detail__process">
41
- <li class="indicator-top indicator-circle" style="--_connector-top: 0px; --_connector-height: 0px;">
40
+ <ol role="list" class="stepper-list has-connectors service-detail__process">
41
+ <li class="stepper-list-item indicator-top indicator-circle" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
42
42
  <div class="stepper-list__indicator-counter"></div>
43
- <div>
43
+ <div class="stepper-list-content">
44
44
  <p class="page-body-normal">Consultation</p>
45
45
  </div>
46
46
  </li>
47
- <li class="indicator-top indicator-circle" style="--_connector-top: 0px; --_connector-height: 0px;">
47
+ <li class="stepper-list-item indicator-top indicator-circle" style="--_connector-left: 0px; --_connector-top: 0px; --_connector-height: 0px;">
48
48
  <div class="stepper-list__indicator-counter"></div>
49
- <div>
49
+ <div class="stepper-list-content">
50
50
  <p class="page-body-normal">Sectioning</p>
51
51
  </div>
52
52
  </li>
53
- <li class="indicator-top indicator-circle">
53
+ <li class="stepper-list-item indicator-top indicator-circle">
54
54
  <div class="stepper-list__indicator-counter"></div>
55
- <div>
55
+ <div class="stepper-list-content">
56
56
  <p class="page-body-normal">Painting</p>
57
57
  </div>
58
58
  </li>
@@ -26,3 +26,4 @@ export * from "./samaritan-prompt.d"
26
26
  export * from "./profile-section.d"
27
27
  export * from "./services-card.d"
28
28
  export * from "./google-reviews.d"
29
+ export * from "./progress-tracker.d"
@@ -0,0 +1,6 @@
1
+ export interface ProgressTrackerStep {
2
+ title: string;
3
+ body?: string;
4
+ }
5
+
6
+ export type ProgressTrackerStepState = "done" | "current" | "upcoming";
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "srcdev-nuxt-components",
3
3
  "type": "module",
4
- "version": "9.6.4",
4
+ "version": "9.6.5",
5
5
  "main": "nuxt.config.ts",
6
6
  "types": "types.d.ts",
7
7
  "license": "MIT",