Skip to content

Commit 365d825

Browse files
committed
feat: remove aria attributes and leave it to userland
1 parent bc0c5bc commit 365d825

8 files changed

Lines changed: 3 additions & 75 deletions

File tree

docs/content/api/use-field.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,6 @@ type useField = (
8585
errors: Ref<string[]>; // all error messages
8686
errorMessage: Ref<string | undefined>; // the first error message
8787
disabled: Ref<boolean>; // if the field is currently disabled
88-
aria: Ref<{
89-
'aria-invalid': 'true' | 'false';
90-
'aria-describedBy': string;
91-
}>;
9288
reset: () => void; // resets errors and field meta
9389
validate: () => Promise<ValidationResult>; // validates and updates the errors and field meta
9490
handleChange: (e: Event) => void; // updates the value

docs/content/guide/validation.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,7 @@ and if you would like, you could display all error messages for your fields by i
334334

335335
### Using ErrorMessage component
336336

337-
vee-validate offers an `<ErrorMessage />` component that displays your error messages in a convenient manner, as an added bonus vee-validate automatically adds some accessability attributes to both the `<Field />` and the associated `<ErrorMessage />` component.
337+
vee-validate offers an `<ErrorMessage />` component that displays your error messages in a convenient manner.
338338

339339
```vue
340340
<template>

packages/core/src/ErrorMessage.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { inject, h, defineComponent, computed, Ref } from 'vue';
22
import { FormErrorsSymbol } from './symbols';
3-
import { normalizeChildren, genFieldErrorId } from './utils';
3+
import { normalizeChildren } from './utils';
44

55
export const ErrorMessage = defineComponent({
66
props: {
@@ -26,7 +26,6 @@ export const ErrorMessage = defineComponent({
2626

2727
const tag = props.as;
2828
const attrs = {
29-
id: genFieldErrorId(props.name),
3029
role: 'alert',
3130
...ctx.attrs,
3231
};

packages/core/src/Field.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { h, defineComponent, nextTick, toRef, SetupContext } from 'vue';
22
import { getConfig } from './config';
33
import { useField } from './useField';
4-
import { normalizeChildren, isHTMLTag, hasCheckedAttr, isFileInput } from './utils';
4+
import { normalizeChildren, hasCheckedAttr, isFileInput } from './utils';
55

66
export const Field = defineComponent({
77
name: 'Field',
@@ -49,7 +49,6 @@ export const Field = defineComponent({
4949
handleInput,
5050
reset,
5151
meta,
52-
aria,
5352
checked,
5453
} = useField(props.name, rules, {
5554
validateOnMount: props.validateOnMount,
@@ -133,7 +132,6 @@ export const Field = defineComponent({
133132

134133
return {
135134
field: fieldProps,
136-
aria: aria.value,
137135
meta,
138136
errors: errors.value,
139137
errorMessage: errorMessage.value,
@@ -165,7 +163,6 @@ export const Field = defineComponent({
165163
{
166164
...ctx.attrs,
167165
...slotProps.field,
168-
...(isHTMLTag(tag) ? slotProps.aria : {}),
169166
},
170167
children
171168
);

packages/core/src/useField.ts

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ import {
1313
extractLocators,
1414
normalizeEventValue,
1515
unwrap,
16-
genFieldErrorId,
1716
hasCheckedAttr,
1817
getFromPath,
1918
setInPath,
@@ -117,15 +116,12 @@ export function useField(name: string, rules: RuleExpression, opts?: Partial<Fie
117116
return errors.value[0];
118117
});
119118

120-
const aria = useAriAttrs(name, meta);
121-
122119
const field = {
123120
name,
124121
value: value,
125122
meta,
126123
errors,
127124
errorMessage,
128-
aria,
129125
disabled,
130126
type,
131127
valueProp,
@@ -360,15 +356,6 @@ function useMeta() {
360356
};
361357
}
362358

363-
function useAriAttrs(fieldName: string, meta: Record<string, boolean>) {
364-
return computed(() => {
365-
return {
366-
'aria-invalid': meta.failed ? 'true' : 'false',
367-
'aria-describedBy': genFieldErrorId(fieldName),
368-
};
369-
});
370-
}
371-
372359
/**
373360
* Extracts the validation rules from a schema
374361
*/

packages/core/src/utils/common.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,5 @@
11
import { isEmptyContainer, isIndex, isNotNestedPath } from './assertions';
22

3-
export function genFieldErrorId(fieldName: string): string {
4-
return `v_${fieldName}_error`;
5-
}
6-
73
function cleanupNonNestedPath(path: string) {
84
if (isNotNestedPath(path)) {
95
return path.replace(/\[|\]/gi, '');

packages/core/tests/ErrorMessage.spec.ts

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -116,26 +116,4 @@ describe('<ErrorMessage />', () => {
116116

117117
expect(error.textContent).toBe(REQUIRED_MESSAGE);
118118
});
119-
120-
test('is associated using aria-describeBy', async () => {
121-
const wrapper = mountWithHoc({
122-
components: {
123-
ErrorMessage,
124-
},
125-
template: `
126-
<VForm as="form">
127-
<Field name="field" rules="required" as="input" />
128-
<ErrorMessage name="field" as="span" />
129-
130-
<button>Validate</button>
131-
</VForm>
132-
`,
133-
});
134-
135-
await flushPromises();
136-
const error = wrapper.$el.querySelector('span');
137-
const input = wrapper.$el.querySelector('input');
138-
139-
expect(input.getAttribute('aria-describedBy')).toBe(error.id);
140-
});
141119
});

packages/core/tests/Field.spec.ts

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -466,31 +466,6 @@ describe('<Field />', () => {
466466
expect(error.textContent).toBe('');
467467
});
468468

469-
test('generates aria invalid attribute', async () => {
470-
const wrapper = mountWithHoc({
471-
template: `
472-
<div>
473-
<Field name="field" rules="required" v-slot="{ aria, field }">
474-
<input type="text" v-bind="{ ...field, ...aria }">
475-
</Field>
476-
</div>
477-
`,
478-
});
479-
480-
await flushPromises();
481-
const input = wrapper.$el.querySelector('input');
482-
expect(input.getAttribute('aria-invalid')).toBe('false');
483-
484-
setValue(input, '');
485-
await flushPromises();
486-
487-
expect(input.getAttribute('aria-invalid')).toBe('true');
488-
489-
setValue(input, '1');
490-
await flushPromises();
491-
expect(input.getAttribute('aria-invalid')).toBe('false');
492-
});
493-
494469
test('yup abortEarly is set by bails global option', async () => {
495470
configure({
496471
bails: false,

0 commit comments

Comments
 (0)