Error
diff --git a/packages/email-field/test/dom/__snapshots__/email-field.test.snap.js b/packages/email-field/test/dom/__snapshots__/email-field.test.snap.js
index ec188748bee..0df452dd8fe 100644
--- a/packages/email-field/test/dom/__snapshots__/email-field.test.snap.js
+++ b/packages/email-field/test/dom/__snapshots__/email-field.test.snap.js
@@ -311,7 +311,6 @@ snapshots["vaadin-email-field host error"] =
Error
diff --git a/packages/field-base/src/error-controller.js b/packages/field-base/src/error-controller.js
index 12d5ba511a2..f4022246b83 100644
--- a/packages/field-base/src/error-controller.js
+++ b/packages/field-base/src/error-controller.js
@@ -3,6 +3,7 @@
* Copyright (c) 2021 - 2024 Vaadin Ltd.
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
*/
+import { announce } from '@vaadin/a11y-base/src/announce.js';
import { SlotChildObserveController } from '@vaadin/component-base/src/slot-child-observe-controller.js';
/**
@@ -108,12 +109,10 @@ export class ErrorController extends SlotChildObserveController {
errorNode.textContent = hasError ? errorMessage : '';
errorNode.hidden = !hasError;
- // Role alert will make the error message announce immediately
- // as the field becomes invalid
if (hasError) {
- errorNode.setAttribute('role', 'alert');
- } else {
- errorNode.removeAttribute('role');
+ // Assertive mode ensures VoiceOver reads
+ // the error message on commit with Enter.
+ announce(errorMessage, { mode: 'assertive' });
}
}
diff --git a/packages/field-base/test/field-mixin.test.js b/packages/field-base/test/field-mixin.test.js
index dbfbd4e95d7..963c45d702f 100644
--- a/packages/field-base/test/field-mixin.test.js
+++ b/packages/field-base/test/field-mixin.test.js
@@ -1,5 +1,6 @@
import { expect } from '@vaadin/chai-plugins';
import { aTimeout, defineLit, definePolymer, fixtureSync, nextRender, nextUpdate } from '@vaadin/testing-helpers';
+import sinon from 'sinon';
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
import { PolylitMixin } from '@vaadin/component-base/src/polylit-mixin.js';
import { FieldMixin } from '../src/field-mixin.js';
@@ -142,30 +143,46 @@ const runTests = (defineHelper, baseMixin) => {
await nextUpdate(element);
expect(element.hasAttribute('has-error-message')).to.be.false;
});
+ });
+
+ describe('announcements', () => {
+ let announceRegion, clock;
+
+ beforeEach(async () => {
+ element = fixtureSync(`<${tag}>${tag}>`);
+ await nextRender();
+ clock = sinon.useFakeTimers({ toFake: ['setTimeout'] });
+ announceRegion = document.querySelector('[aria-live]');
+ announceRegion.textContent = '';
+ });
- it('should not set alert role with no error', () => {
- expect(error.hasAttribute('role')).to.be.false;
+ afterEach(() => {
+ clock.restore();
});
- it('should set alert role when attribute is set', async () => {
+ it('should announce error message set via attribute when field is invalid', async () => {
+ element.invalid = true;
element.setAttribute('error-message', 'This field is required');
await nextUpdate(element);
- expect(error.getAttribute('role')).to.equal('alert');
+ clock.tick(150);
+ expect(announceRegion.textContent).to.equal('This field is required');
+ expect(announceRegion.getAttribute('aria-live')).to.equal('assertive');
});
- it('should set alert role when property is set', async () => {
+ it('should announce error message set via property when field is invalid', async () => {
+ element.invalid = true;
element.errorMessage = 'This field is required';
await nextUpdate(element);
- expect(error.getAttribute('role')).to.equal('alert');
+ clock.tick(150);
+ expect(announceRegion.textContent).to.equal('This field is required');
+ expect(announceRegion.getAttribute('aria-live')).to.equal('assertive');
});
- it('should remove alert role when field is valid', async () => {
+ it('should not announce error message when field is valid', async () => {
element.errorMessage = 'This field is required';
await nextUpdate(element);
-
- element.invalid = false;
- await nextUpdate(element);
- expect(error.hasAttribute('role')).to.be.false;
+ clock.tick(150);
+ expect(announceRegion.textContent).to.equal('');
});
});
diff --git a/packages/integer-field/test/dom/__snapshots__/integer-field.test.snap.js b/packages/integer-field/test/dom/__snapshots__/integer-field.test.snap.js
index e6ba140f470..3aafc8ca0f1 100644
--- a/packages/integer-field/test/dom/__snapshots__/integer-field.test.snap.js
+++ b/packages/integer-field/test/dom/__snapshots__/integer-field.test.snap.js
@@ -73,7 +73,6 @@ snapshots["vaadin-integer-field host error"] =
Error
diff --git a/packages/login/test/dom/__snapshots__/login-form.test.snap.js b/packages/login/test/dom/__snapshots__/login-form.test.snap.js
index 3bbc5d0bfc0..aa4968d5f34 100644
--- a/packages/login/test/dom/__snapshots__/login-form.test.snap.js
+++ b/packages/login/test/dom/__snapshots__/login-form.test.snap.js
@@ -156,7 +156,6 @@ snapshots["vaadin-login-form host required"] =
Username is required
@@ -192,7 +191,6 @@ snapshots["vaadin-login-form host required"] =
Password is required
@@ -383,7 +381,6 @@ snapshots["vaadin-login-form host i18n-required"] =
Käyttäjätunnus vaaditaan
@@ -419,7 +416,6 @@ snapshots["vaadin-login-form host i18n-required"] =
Salasana vaaditaan
diff --git a/packages/multi-select-combo-box/test/dom/__snapshots__/multi-select-combo-box.test.snap.js b/packages/multi-select-combo-box/test/dom/__snapshots__/multi-select-combo-box.test.snap.js
index 701b2a40641..7e197172344 100644
--- a/packages/multi-select-combo-box/test/dom/__snapshots__/multi-select-combo-box.test.snap.js
+++ b/packages/multi-select-combo-box/test/dom/__snapshots__/multi-select-combo-box.test.snap.js
@@ -131,7 +131,6 @@ snapshots["vaadin-multi-select-combo-box host error"] =
Error
diff --git a/packages/number-field/test/dom/__snapshots__/number-field.test.snap.js b/packages/number-field/test/dom/__snapshots__/number-field.test.snap.js
index 0736978d42c..21e31d17206 100644
--- a/packages/number-field/test/dom/__snapshots__/number-field.test.snap.js
+++ b/packages/number-field/test/dom/__snapshots__/number-field.test.snap.js
@@ -73,7 +73,6 @@ snapshots["vaadin-number-field host error"] =
Error
diff --git a/packages/password-field/test/dom/__snapshots__/password-field.test.snap.js b/packages/password-field/test/dom/__snapshots__/password-field.test.snap.js
index 3bb2bdacfa1..dfd650471b6 100644
--- a/packages/password-field/test/dom/__snapshots__/password-field.test.snap.js
+++ b/packages/password-field/test/dom/__snapshots__/password-field.test.snap.js
@@ -85,7 +85,6 @@ snapshots["vaadin-password-field host error"] =
Error
diff --git a/packages/radio-group/test/dom/__snapshots__/radio-group.test.snap.js b/packages/radio-group/test/dom/__snapshots__/radio-group.test.snap.js
index 548b09ec1ad..923510025e2 100644
--- a/packages/radio-group/test/dom/__snapshots__/radio-group.test.snap.js
+++ b/packages/radio-group/test/dom/__snapshots__/radio-group.test.snap.js
@@ -394,7 +394,6 @@ snapshots["vaadin-radio-group host error"] =
Error
diff --git a/packages/select/test/dom/__snapshots__/select.test.snap.js b/packages/select/test/dom/__snapshots__/select.test.snap.js
index ccfc8fd6f4c..0c30a4af83d 100644
--- a/packages/select/test/dom/__snapshots__/select.test.snap.js
+++ b/packages/select/test/dom/__snapshots__/select.test.snap.js
@@ -250,7 +250,6 @@ snapshots["vaadin-select host error"] =
Error
diff --git a/packages/text-area/test/dom/__snapshots__/text-area.test.snap.js b/packages/text-area/test/dom/__snapshots__/text-area.test.snap.js
index ea2d1be8c91..3b1afd71c22 100644
--- a/packages/text-area/test/dom/__snapshots__/text-area.test.snap.js
+++ b/packages/text-area/test/dom/__snapshots__/text-area.test.snap.js
@@ -67,7 +67,6 @@ snapshots["vaadin-text-area host error"] =
Error
diff --git a/packages/text-field/test/dom/__snapshots__/text-field.test.snap.js b/packages/text-field/test/dom/__snapshots__/text-field.test.snap.js
index b1c36152b0e..eb011db3bae 100644
--- a/packages/text-field/test/dom/__snapshots__/text-field.test.snap.js
+++ b/packages/text-field/test/dom/__snapshots__/text-field.test.snap.js
@@ -67,7 +67,6 @@ snapshots["vaadin-text-field host error"] =
Error
diff --git a/packages/time-picker/test/dom/__snapshots__/time-picker.test.snap.js b/packages/time-picker/test/dom/__snapshots__/time-picker.test.snap.js
index 16ccfa9bb2f..0a7b95ee5b8 100644
--- a/packages/time-picker/test/dom/__snapshots__/time-picker.test.snap.js
+++ b/packages/time-picker/test/dom/__snapshots__/time-picker.test.snap.js
@@ -110,7 +110,6 @@ snapshots["vaadin-time-picker host error"] =
Error