Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add status announcement after file change #5729

Merged

Conversation

romaricpascal
Copy link
Member

@romaricpascal romaricpascal commented Feb 20, 2025

Adds an automatic announcement of the status after users pick a file.

This should reassure JAWS users that their selection has been taken into account, as JAWS announces the accessible name of the button before the file picker was open, sometimes without re-announcing afterwards the accessible name once a file is picked.

Testing confirmed it to be a better option than manipulating which element is focused (see #5726)

@@ -283,7 +284,6 @@ export class FileUpload extends ConfigurableComponent {
// Use a `CustomEvent` so our events are distinguishable from browser's native events
this.$input.dispatchEvent(new CustomEvent('change'))

this.$announcements.innerText = this.$status.innerText
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As the status is a live region, we no longer need to explicitely announce status after dropping.

Copy link

github-actions bot commented Feb 20, 2025

📋 Stats

File sizes

File Size
dist/govuk-frontend-development.min.css 121.49 KiB
dist/govuk-frontend-development.min.js 48.05 KiB
packages/govuk-frontend/dist/govuk/all.bundle.js 102.41 KiB
packages/govuk-frontend/dist/govuk/all.bundle.mjs 96.2 KiB
packages/govuk-frontend/dist/govuk/all.mjs 1.32 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend-component.mjs 1.74 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend.min.css 121.47 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend.min.js 48.04 KiB
packages/govuk-frontend/dist/govuk/i18n.mjs 5.55 KiB
packages/govuk-frontend/dist/govuk/init.mjs 6.89 KiB

Modules

File Size (bundled) Size (minified)
all.mjs 90.38 KiB 45.47 KiB
accordion.mjs 26.63 KiB 13.41 KiB
button.mjs 9.14 KiB 3.79 KiB
character-count.mjs 25.42 KiB 10.91 KiB
checkboxes.mjs 7.81 KiB 3.42 KiB
error-summary.mjs 11.04 KiB 4.55 KiB
exit-this-page.mjs 20.25 KiB 10.34 KiB
file-upload.mjs 21.12 KiB 11.06 KiB
header.mjs 6.46 KiB 3.22 KiB
notification-banner.mjs 9.4 KiB 3.71 KiB
password-input.mjs 18.21 KiB 8.34 KiB
radios.mjs 6.81 KiB 2.98 KiB
service-navigation.mjs 6.44 KiB 3.26 KiB
skip-link.mjs 6.4 KiB 2.76 KiB
tabs.mjs 12.04 KiB 6.67 KiB

View stats and visualisations on the review app


Action run for 9fcde09

Copy link

github-actions bot commented Feb 20, 2025

JavaScript changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
index f6220464f..59ef37dd2 100644
--- a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
+++ b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
@@ -769,7 +769,7 @@ class FileUpload extends ConfigurableComponent {
         const o = this.$input.getAttribute("aria-describedby");
         o && s.setAttribute("aria-describedby", o);
         const r = document.createElement("span");
-        r.className = "govuk-body govuk-file-upload-button__status", r.innerText = this.i18n.t("noFileChosen"), s.appendChild(r);
+        r.className = "govuk-body govuk-file-upload-button__status", r.setAttribute("aria-live", "polite"), r.innerText = this.i18n.t("noFileChosen"), s.appendChild(r);
         const a = document.createElement("span");
         a.className = "govuk-visually-hidden", a.innerText = ", ", a.id = `${this.id}-comma`, s.appendChild(a);
         const l = document.createElement("span");
@@ -795,7 +795,7 @@ class FileUpload extends ConfigurableComponent {
         this.$button.classList.remove("govuk-file-upload-button--dragging")
     }
     onDrop(t) {
-        t.preventDefault(), t.dataTransfer && isContainingFiles(t.dataTransfer) && (this.$input.files = t.dataTransfer.files, this.$input.dispatchEvent(new CustomEvent("change")), this.$announcements.innerText = this.$status.innerText, this.hideDraggingState())
+        t.preventDefault(), t.dataTransfer && isContainingFiles(t.dataTransfer) && (this.$input.files = t.dataTransfer.files, this.$input.dispatchEvent(new CustomEvent("change")), this.hideDraggingState())
     }
     onChange() {
         const t = this.$input.files.length;

Action run for 9fcde09

Copy link

github-actions bot commented Feb 20, 2025

Other changes to npm package

diff --git a/packages/govuk-frontend/dist/govuk/all.bundle.js b/packages/govuk-frontend/dist/govuk/all.bundle.js
index b57e1a9a6..fb3d69a27 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.js
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.js
@@ -1713,6 +1713,7 @@
       }
       const $status = document.createElement('span');
       $status.className = 'govuk-body govuk-file-upload-button__status';
+      $status.setAttribute('aria-live', 'polite');
       $status.innerText = this.i18n.t('noFileChosen');
       $button.appendChild($status);
       const commaSpan = document.createElement('span');
@@ -1804,7 +1805,6 @@
       if (event.dataTransfer && isContainingFiles(event.dataTransfer)) {
         this.$input.files = event.dataTransfer.files;
         this.$input.dispatchEvent(new CustomEvent('change'));
-        this.$announcements.innerText = this.$status.innerText;
         this.hideDraggingState();
       }
     }
diff --git a/packages/govuk-frontend/dist/govuk/all.bundle.mjs b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
index bd59d9bb4..2562e1c2b 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.mjs
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
@@ -1707,6 +1707,7 @@ class FileUpload extends ConfigurableComponent {
     }
     const $status = document.createElement('span');
     $status.className = 'govuk-body govuk-file-upload-button__status';
+    $status.setAttribute('aria-live', 'polite');
     $status.innerText = this.i18n.t('noFileChosen');
     $button.appendChild($status);
     const commaSpan = document.createElement('span');
@@ -1798,7 +1799,6 @@ class FileUpload extends ConfigurableComponent {
     if (event.dataTransfer && isContainingFiles(event.dataTransfer)) {
       this.$input.files = event.dataTransfer.files;
       this.$input.dispatchEvent(new CustomEvent('change'));
-      this.$announcements.innerText = this.$status.innerText;
       this.hideDraggingState();
     }
   }
diff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js
index 6c37a8243..6e9b129eb 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.js
@@ -540,6 +540,7 @@
       }
       const $status = document.createElement('span');
       $status.className = 'govuk-body govuk-file-upload-button__status';
+      $status.setAttribute('aria-live', 'polite');
       $status.innerText = this.i18n.t('noFileChosen');
       $button.appendChild($status);
       const commaSpan = document.createElement('span');
@@ -631,7 +632,6 @@
       if (event.dataTransfer && isContainingFiles(event.dataTransfer)) {
         this.$input.files = event.dataTransfer.files;
         this.$input.dispatchEvent(new CustomEvent('change'));
-        this.$announcements.innerText = this.$status.innerText;
         this.hideDraggingState();
       }
     }
diff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs
index 307cbbd67..09263d181 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.bundle.mjs
@@ -534,6 +534,7 @@ class FileUpload extends ConfigurableComponent {
     }
     const $status = document.createElement('span');
     $status.className = 'govuk-body govuk-file-upload-button__status';
+    $status.setAttribute('aria-live', 'polite');
     $status.innerText = this.i18n.t('noFileChosen');
     $button.appendChild($status);
     const commaSpan = document.createElement('span');
@@ -625,7 +626,6 @@ class FileUpload extends ConfigurableComponent {
     if (event.dataTransfer && isContainingFiles(event.dataTransfer)) {
       this.$input.files = event.dataTransfer.files;
       this.$input.dispatchEvent(new CustomEvent('change'));
-      this.$announcements.innerText = this.$status.innerText;
       this.hideDraggingState();
     }
   }
diff --git a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs
index 482b1798c..614cd849a 100644
--- a/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs
+++ b/packages/govuk-frontend/dist/govuk/components/file-upload/file-upload.mjs
@@ -55,6 +55,7 @@ class FileUpload extends ConfigurableComponent {
     }
     const $status = document.createElement('span');
     $status.className = 'govuk-body govuk-file-upload-button__status';
+    $status.setAttribute('aria-live', 'polite');
     $status.innerText = this.i18n.t('noFileChosen');
     $button.appendChild($status);
     const commaSpan = document.createElement('span');
@@ -146,7 +147,6 @@ class FileUpload extends ConfigurableComponent {
     if (event.dataTransfer && isContainingFiles(event.dataTransfer)) {
       this.$input.files = event.dataTransfer.files;
       this.$input.dispatchEvent(new CustomEvent('change'));
-      this.$announcements.innerText = this.$status.innerText;
       this.hideDraggingState();
     }
   }

Action run for 9fcde09

Adds an automatic announcement of the status after users pick a file.

This should reassure JAWS users that their selection has been taken into account,
as JAWS announces the accessible name of the button before the file picker was open,
sometimes without re-announcing afterwards the accessible name once a file is picked.
@romaricpascal romaricpascal force-pushed the spike-announce-status-after-change branch from d3f6fc5 to 9fcde09 Compare February 21, 2025 14:50
@govuk-design-system-ci govuk-design-system-ci temporarily deployed to govuk-frontend-pr-5729 February 21, 2025 14:51 Inactive
@romaricpascal romaricpascal changed the title [SPIKE] Add status announcement after file change Add status announcement after file change Feb 21, 2025
@romaricpascal romaricpascal marked this pull request as ready for review February 21, 2025 14:53
// rather than being in the initial state
await expect(
$announcements.evaluate((e) => e.textContent)
).resolves.toBe('file-upload.puppeteer.test.js')
).resolves.toBe('Entered drop zone')
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note This test changes slightly as we no longer announce the file name in the announcements element, but via the status itself. We can still check that we're no longer in the initial state as the announcements will remain 'Entered drop zone' after the drop.

This also serves as a check that we don't double up the file name announcement with another announcement using the announcements element.

expect(announcementsText).toBe('')
// As the announcement is feedback while user is dragging,
// best to announce it as soon as the user enters the zone
expect(announcementsAriaLive).toBe('assertive')
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

*note That bit is important for the feedback while dragging, so took the opportunity to check this while looking at other tests for aria-live attributes.

@romaricpascal romaricpascal merged commit ef431d2 into spike-enhanced-file-upload Feb 21, 2025
48 checks passed
@romaricpascal romaricpascal deleted the spike-announce-status-after-change branch February 21, 2025 15:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Investigate workaround for screen readers not always announcing the selected file after picking
3 participants