1111 class =" m-form-step__icon"
1212 :class =" { disabled: disabled }"
1313 :tabindex =" getTabindex"
14+ :aria-labelledby =" ariaLabelledby"
1415 :aria-label =" getAriaLabel"
16+ :aria-setsize =" total"
17+ :aria-posinset =" position"
18+ :aria-current =" isActive ? 'step' : false"
1519 >
1620 <muc-icon :icon =" getIcon" />
1721 </div >
1822 <div
1923 class =" m-form-step__title"
2024 :class =" { disabled: disabled }"
2125 >
22- <span aria-disabled =" true" > {{ item.label }}</span >
26+ <span
27+ :id =" labelId"
28+ aria-disabled =" true"
29+ >
30+ {{ item.label }}</span
31+ >
32+
33+ <span
34+ class =" visually-hidden"
35+ :id =" prefixId"
36+ >
37+ Schritt {{ position }} von {{ total }}:
38+ </span >
39+
40+ <span
41+ v-if =" isDone"
42+ class =" visually-hidden"
43+ :id =" statusId"
44+ >
45+ – erledigt
46+ </span >
2347 </div >
48+ <span
49+ v-if =" isActive"
50+ class =" visually-hidden"
51+ role =" status"
52+ aria-live =" polite"
53+ aria-atomic =" true"
54+ :aria-labelledby =" ariaLabelledby"
55+ >
56+ </span >
2457 </li >
2558</template >
2659
@@ -30,7 +63,7 @@ import { computed } from "vue";
3063import { MucIcon } from " ../Icon" ;
3164import { StepperItem } from " ./MucStepperTypes" ;
3265
33- const { item, isActive, isDone, disabled } = defineProps <{
66+ const { item, isActive, isDone, disabled, position, total } = defineProps <{
3467 /**
3568 * Individual item to display inside the MucStepper component
3669 */
@@ -50,6 +83,16 @@ const { item, isActive, isDone, disabled } = defineProps<{
5083 * Disabled stepper
5184 */
5285 disabled: boolean ;
86+
87+ /**
88+ * position of the item in the step sequence
89+ */
90+ position: number ;
91+
92+ /**
93+ * total number of steps
94+ */
95+ total: number ;
5396}>();
5497
5598const emit = defineEmits <{
@@ -81,6 +124,22 @@ const getAriaLabel = computed(() =>
81124 : " Zurück zu Schritt: " + item .label
82125);
83126
127+ /**
128+ * Stable element IDs used to compose the accessible name via aria-labelledby
129+ */
130+ const labelId = computed (() => ` m-step-label-${item .id } ` );
131+ const prefixId = computed (() => ` m-step-prefix-${item .id } ` );
132+ const statusId = computed (() => ` m-step-status-${item .id } ` );
133+
134+ /**
135+ * Compose the accessible name in order: prefix -> visible label -> optional status
136+ */
137+ const ariaLabelledby = computed (() => {
138+ const ids = [prefixId .value , labelId .value ];
139+ if (isDone ) ids .push (statusId .value );
140+ return ids .join (" " );
141+ });
142+
84143const handleClick = () => {
85144 if (isDone && ! disabled ) {
86145 emit (" click" , item .id );
0 commit comments