Skip to content

Commit

Permalink
💥 395: add new required variable id to all form fields to ensure a11y (
Browse files Browse the repository at this point in the history
…#396)

* 💥 395: add new required variable id to all form fields to ensure a11y

* 💥 395: add new required variable id to all form fields to ensure a11y

* 395: pr feedback
  • Loading branch information
lehju authored Jan 22, 2025
1 parent 3f1b4ea commit 1b5ddee
Show file tree
Hide file tree
Showing 11 changed files with 87 additions and 17 deletions.
1 change: 1 addition & 0 deletions src/components/Form/MucCheckbox.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default {

export const Default = {
args: {
id: "default",
label: "This is a checkbox - click me",
},
};
12 changes: 10 additions & 2 deletions src/components/Form/MucCheckbox.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,17 @@
@click="clickedCheckbox"
>
<input
:id="'checkbox-' + id"
class="m-checkboxes__input"
name="checkbox"
type="checkbox"
:checked="modelValue"
@click.stop="clickedCheckbox"
/>
<label class="m-label m-checkboxes__label">
<label
class="m-label m-checkboxes__label"
:for="'checkbox-' + id"
>
{{ label }}
</label>
</div>
Expand All @@ -22,7 +26,11 @@
*/
const modelValue = defineModel<boolean>({ default: false });
defineProps<{
const { label } = defineProps<{
/**
* Unique identifier for the checkbox. Required property used to associate the checkbox with its label and hint text for accessibility.
*/
id: string;
/**
* Label is displayed to the right of the checkbox as information for the user.
*/
Expand Down
6 changes: 3 additions & 3 deletions src/components/Form/MucCheckboxGroup.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ export const NotCollapsable = () => ({
template: `
<MucCheckboxGroup heading="Collapsable checkbox group ">
<template #checkboxes>
<MucCheckbox v-for="index in 4" :key="index" :label="'not-collapsed-' + index" />
<MucCheckbox v-for="index in 4" :key="index" :label="'not-collapsed-' + index" :id="index"/>
</template>
</MucCheckboxGroup>
`,
Expand All @@ -33,10 +33,10 @@ export const Collapsable = () => ({
template: `
<MucCheckboxGroup heading="Collapsable checkbox group ">
<template #checkboxes>
<MucCheckbox v-for="index in 4" :key="index" :label="'not-collapsed-' + index" />
<MucCheckbox v-for="index in 4" :key="index" :label="'not-collapsed-' + index" :id="'not-collapsed-' + index" />
</template>
<template #collapsableCheckboxes>
<MucCheckbox v-for="index in 4" :key="index" :label="'collapsed-' + index" />
<MucCheckbox v-for="index in 4" :key="index" :label="'collapsed-' + index" :id="'collapsed-' + index" />
</template>
</MucCheckboxGroup>
`,
Expand Down
10 changes: 10 additions & 0 deletions src/components/Form/MucInput.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,15 @@ export default {

export const Default = {
args: {
id: "default",
placeholder: "Please type here",
},
};

export const HintAndLabel = {
args: {
...Default.args,
id: "hint-and-label",
hint: "This is a hint",
label: "This is a label",
},
Expand All @@ -35,6 +37,7 @@ export const HintAndLabel = {
export const Password = {
args: {
...Default.args,
id: "password",
type: "password",
modelValue: "password",
hint: "The input text is 'password'",
Expand All @@ -44,6 +47,7 @@ export const Password = {
export const Error = {
args: {
...Default.args,
id: "error",
errorMsg: "Oops, an error occurred",
hint: "An error message triggers the error state",
},
Expand All @@ -52,39 +56,45 @@ export const Error = {
export const Prefix = {
args: {
...Default.args,
id: "prefix",
prefix: "Prefix",
},
};

export const SuffixIcon = {
args: {
...Default.args,
id: "suffix-icon",
suffixIcon: "search",
},
};

export const Search = {
args: {
...Default.args,
id: "search",
type: "search",
dataList: ["chocolate", "coconut", "vanilla", "mint"],
},
};

export const Color = {
args: {
id: "color",
type: "color",
},
};

export const Date = {
args: {
id: "date",
type: "date",
},
};

export const Datetime_Local = {
args: {
id: "datetime",
type: "datetime-local",
},
};
15 changes: 12 additions & 3 deletions src/components/Form/MucInput.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@
>
<label
v-if="label"
for="search-input"
:for="'input-' + id"
class="m-label"
:class="{ 'm-label--optional': !required }"
>
{{ label }}
</label>
<p
v-if="hint"
class="m-hint"
id="text-input-hint"
:id="'input-hint-' + id"
>
{{ hint }}
</p>
Expand All @@ -27,10 +28,11 @@
</span>
</div>
<input
:id="'input-' + id"
class="m-input autocomplete-input"
:type="type"
v-model="modelValue"
:aria-describedby="type + '-input'"
:aria-describedby="hint ? 'input-hint-' + id : undefined"
:placeholder="placeholder"
:required="required"
/>
Expand Down Expand Up @@ -64,6 +66,9 @@
<form-error-message
id="text-input-error"
v-if="errorMsg"
tabindex="0"
role="alert"
aria-live="polite"
>
{{ errorMsg }}
</form-error-message>
Expand Down Expand Up @@ -96,6 +101,10 @@ const {
type = "text",
dataList = [] as string[],
} = defineProps<{
/**
* Unique identifier for the input. Required property used to associate the input with its label and hint text for accessibility.
*/
id: string;
/**
* Displays error message and highlights the input form with a red border.
*/
Expand Down
4 changes: 2 additions & 2 deletions src/components/Form/MucRadioButton.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ export const Default = () => ({
template: `
<MucRadioButtonGroup heading="Checkbox group" model-value="">
<template v-slot:default>
<MucRadioButton value="first" label="first option" hint="This is a hint for this radiobutton"/>
<MucRadioButton v-for="index in 3" :key="index" :label="'other option-' + index" :value="'val-' + index"/>
<MucRadioButton value="first" label="first option" hint="This is a hint for this radiobutton" id="first"/>
<MucRadioButton v-for="index in 3" :key="index" :label="'other option-' + index" :value="'val-' + index" :id="'other-option' + index"/>
</template>
</MucRadioButtonGroup>
`,
Expand Down
12 changes: 11 additions & 1 deletion src/components/Form/MucRadioButton.vue
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,24 @@
v-if="isInRadioButtonGroup"
>
<input
:id="'radio-' + id"
class="m-radios__input"
type="radio"
:aria-describedby="hint ? 'radio-hint-' + id : undefined"
:checked="isChecked"
:disabled="isDisabled"
@click.stop="clicked"
/>
<label
class="m-label m-radios__label"
:for="'radio-' + id"
@click="clicked"
>
{{ label }}
<span class="m-hint">
<span
:id="'radio-hint-' + id"
class="m-hint"
>
{{ hint }}
</span>
</label>
Expand All @@ -28,6 +34,10 @@ import { computed, inject } from "vue";
import { RadioButtonGroupKey } from "./MucRadioButtonTypes";
const { value, disabled = false } = defineProps<{
/**
* Unique identifier for the radiobutton. Required property used to associate the radiobutton with its label and hint text for accessibility.
*/
id: string;
/**
* value for this radiobutton
*/
Expand Down
3 changes: 3 additions & 0 deletions src/components/Form/MucSelect.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default {

export const Default = {
args: {
id: "default",
modelValue: {
id: "1",
name: "Object 1",
Expand Down Expand Up @@ -54,13 +55,15 @@ export const Default = {
export const MultiSelect = {
args: {
...Default.args,
id: "multi-select",
label: "Select multiple objects",
multiple: true,
},
};

export const StringSelect = {
args: {
id: "string-select",
modelValue: "String 1",
items: ["String 1", "String 2", "String 3", "String 4"],
label: "Select strings",
Expand Down
15 changes: 13 additions & 2 deletions src/components/Form/MucSelect.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,17 @@
class="m-form-group"
ref="selectComponent"
>
<label class="m-label">
<label
v-if="label"
:for="'select-' + id"
class="m-label"
>
{{ label }}
</label>
<p
v-if="!!hint"
v-if="hint"
class="m-hint"
:id="'select-hint-' + id"
>
{{ hint }}
</p>
Expand All @@ -17,8 +22,10 @@
:class="selectType"
>
<input
:id="'select-' + id"
type="text"
class="m-input m-combobox m-combobox--single"
:aria-describedby="hint ? 'select-hint-' + id : undefined"
v-model="searchValue"
@click="openItemList"
/>
Expand Down Expand Up @@ -111,6 +118,10 @@ const {
noItemFoundMessage = "No items found.",
itemTitle = "title",
} = defineProps<{
/**
* Unique identifier for the select. Required property used to associate the select with its label and hint text for accessibility.
*/
id: string;
/**
* List of items to be available
*/
Expand Down
4 changes: 4 additions & 0 deletions src/components/Form/MucTextArea.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,15 @@ export default {

export const Default = {
args: {
id: "default",
placeholder: "Write some very long text here",
},
};

export const Error = {
args: {
...Default.args,
id: "error",
errorMsg: "An error occured",
},
};
Expand All @@ -33,13 +35,15 @@ export const Required = {
args: {
label: "Required textarea",
...Default.args,
id: "required",
required: true,
},
};

export const BigTextArea = {
args: {
...Default.args,
id: "big-text-area",
rows: 7,
label: "Big textarea",
hint: "Write a lot of text",
Expand Down
22 changes: 18 additions & 4 deletions src/components/Form/MucTextArea.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,35 @@
>
<label
v-if="label"
for="textarea"
:for="'textarea-' + id"
class="m-label"
:class="{ 'm-label--optional': !required }"
>
{{ label }}
</label>
<p class="m-hint">
<p
v-if="hint"
:id="'textarea-hint-' + id"
class="m-hint"
>
{{ hint }}
</p>
<div class="m-input-wrapper">
<textarea
:id="'textarea-' + id"
class="m-textarea"
:aria-describedby="hint ? 'textarea-hint-' + id : undefined"
:rows="rows"
aria-describedby="textarea input"
:placeholder="placeholder"
v-model="modelValue"
/>
</div>
<form-error-message v-if="errorMsg">
<form-error-message
v-if="errorMsg"
tabindex="0"
role="alert"
aria-live="polite"
>
{{ errorMsg }}
</form-error-message>
</div>
Expand All @@ -42,6 +52,10 @@ const {
rows = 3,
required = false,
} = defineProps<{
/**
* Unique identifier for the textarea. Required property used to associate the textarea with its label and hint text for accessibility.
*/
id: string;
/**
* Displays error message and highlights the input form with a red border.
*/
Expand Down

0 comments on commit 1b5ddee

Please sign in to comment.