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

[SPIKE] Label <button> with aria-labelledby (label + itself) #5652

Draft
wants to merge 1 commit into
base: file-dropzone-design
Choose a base branch
from

Conversation

romaricpascal
Copy link
Member

Reference the <label> and the <button> itself so there's no duplication of content, ensuring that when translated, the accessible name matches what's visible on the screen.

Reference the `<label>` and the `<button>` itself so there's no duplication
of content, ensuring that when translated, the accessible name matches what's
visible on the screen.
Copy link

📋 Stats

File sizes

File Size
dist/govuk-frontend-development.min.css 120.38 KiB
dist/govuk-frontend-development.min.js 47.36 KiB
packages/govuk-frontend/dist/govuk/all.bundle.js 101.58 KiB
packages/govuk-frontend/dist/govuk/all.bundle.mjs 95.43 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 120.36 KiB
packages/govuk-frontend/dist/govuk/govuk-frontend.min.js 47.35 KiB
packages/govuk-frontend/dist/govuk/i18n.mjs 5.55 KiB
packages/govuk-frontend/dist/govuk/init.mjs 7.5 KiB

Modules

File Size (bundled) Size (minified)
all.mjs 89.56 KiB 44.88 KiB
accordion.mjs 26.58 KiB 13.41 KiB
button.mjs 9.09 KiB 3.78 KiB
character-count.mjs 25.39 KiB 10.9 KiB
checkboxes.mjs 7.81 KiB 3.42 KiB
error-summary.mjs 10.99 KiB 4.54 KiB
exit-this-page.mjs 20.2 KiB 10.34 KiB
file-upload.mjs 20.13 KiB 10.47 KiB
header.mjs 6.46 KiB 3.22 KiB
notification-banner.mjs 9.35 KiB 3.7 KiB
password-input.mjs 18.24 KiB 8.33 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 95e45e7

Copy link

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 6b859649b..ba42a373c 100644
--- a/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
+++ b/packages/govuk-frontend/dist/govuk/govuk-frontend.min.js
@@ -754,21 +754,23 @@ class FileUpload extends ConfigurableComponent {
         if (!this.$root.id.length) throw new ElementError(formatErrorMessage(FileUpload, "Form field must specify an `id`."));
         this.id = this.$root.id, this.i18n = new I18n(this.config.i18n, {
             locale: closestAttributeValue(this.$root, "lang")
-        }), this.$label = this.findLabel(), this.$root.id = `${this.id}-input`, this.$label.setAttribute("for", `${this.id}-input`);
-        const n = document.createElement("div");
-        n.className = "govuk-file-upload-wrapper";
-        const i = document.createElement("span");
-        i.className = "govuk-visually-hidden", i.innerText = ", ";
+        });
+        const n = this.findLabel();
+        n.setAttribute("for", `${this.id}-input`), n.id || (n.id = `${this.id}-label`), this.$root.id = `${this.id}-input`;
+        const i = document.createElement("div");
+        i.className = "govuk-file-upload-wrapper";
         const s = document.createElement("button");
         s.classList.add("govuk-file-upload__button"), s.type = "button", s.id = this.id;
         const o = document.createElement("span");
-        o.className = "govuk-body govuk-file-upload__status", o.innerText = this.i18n.t("filesSelectedDefault"), o.setAttribute("aria-hidden", "true"), this.$root.files.length || o.classList.add("govuk-tag--light-blue"), s.appendChild(o), s.appendChild(i.cloneNode(!0));
+        o.className = "govuk-body govuk-file-upload__status", o.innerText = this.i18n.t("filesSelectedDefault"), this.$root.files.length || o.classList.add("govuk-tag--light-blue"), s.appendChild(o);
         const r = document.createElement("span");
-        r.className = "govuk-file-upload__pseudo-button-container";
+        r.className = "govuk-visually-hidden", r.innerText = ", ", r.id = `${this.id}-comma`, s.appendChild(r);
         const a = document.createElement("span");
-        a.className = "govuk-button govuk-button--secondary govuk-file-upload__pseudo-button", a.innerText = this.i18n.t("selectFilesButton"), a.setAttribute("aria-hidden", "true"), r.appendChild(a), r.appendChild(i.cloneNode(!0));
+        a.className = "govuk-file-upload__pseudo-button-container";
         const l = document.createElement("span");
-        l.className = "govuk-body govuk-file-upload__instruction", l.innerText = this.i18n.t("instruction"), r.appendChild(l), s.appendChild(r), s.setAttribute("aria-label", `${this.$label.innerText}, ${this.i18n.t("selectFilesButton")} ${this.i18n.t("instruction")}, ${o.innerText}`), s.addEventListener("click", this.onClick.bind(this)), n.insertAdjacentElement("beforeend", s), this.$root.insertAdjacentElement("afterend", n), this.$root.setAttribute("tabindex", "-1"), this.$root.setAttribute("aria-hidden", "true"), n.insertAdjacentElement("afterbegin", this.$root), this.$wrapper = n, this.$button = s, this.$status = o, this.$root.addEventListener("change", this.onChange.bind(this)), this.updateDisabledState(), this.observeDisabledState(), this.$root.addEventListener("change", this.onChange.bind(this)), this.$announcements = document.createElement("span"), this.$announcements.classList.add("govuk-file-upload-announcements"), this.$announcements.classList.add("govuk-visually-hidden"), this.$announcements.setAttribute("aria-live", "assertive"), this.$wrapper.insertAdjacentElement("afterend", this.$announcements), this.$wrapper.addEventListener("drop", this.hideDropZone.bind(this)), document.addEventListener("dragenter", this.updateDropzoneVisibility.bind(this)), document.addEventListener("dragenter", (() => {
+        l.className = "govuk-button govuk-button--secondary govuk-file-upload__pseudo-button", l.innerText = this.i18n.t("selectFilesButton"), a.appendChild(l), a.appendChild(r.cloneNode(!0));
+        const c = document.createElement("span");
+        c.className = "govuk-body govuk-file-upload__instruction", c.innerText = this.i18n.t("instruction"), a.appendChild(c), s.appendChild(a), s.setAttribute("aria-labelledby", `${n.id} ${r.id} ${s.id}`), s.addEventListener("click", this.onClick.bind(this)), i.insertAdjacentElement("beforeend", s), this.$root.insertAdjacentElement("afterend", i), this.$root.setAttribute("tabindex", "-1"), this.$root.setAttribute("aria-hidden", "true"), i.insertAdjacentElement("afterbegin", this.$root), this.$wrapper = i, this.$button = s, this.$status = o, this.$root.addEventListener("change", this.onChange.bind(this)), this.updateDisabledState(), this.observeDisabledState(), this.$root.addEventListener("change", this.onChange.bind(this)), this.$announcements = document.createElement("span"), this.$announcements.classList.add("govuk-file-upload-announcements"), this.$announcements.classList.add("govuk-visually-hidden"), this.$announcements.setAttribute("aria-live", "assertive"), this.$wrapper.insertAdjacentElement("afterend", this.$announcements), this.$wrapper.addEventListener("drop", this.hideDropZone.bind(this)), document.addEventListener("dragenter", this.updateDropzoneVisibility.bind(this)), document.addEventListener("dragenter", (() => {
             this.enteredAnotherElement = !0
         })), document.addEventListener("dragleave", (() => {
             this.enteredAnotherElement || this.hideDropZone(), this.enteredAnotherElement = !1
@@ -788,7 +790,7 @@ class FileUpload extends ConfigurableComponent {
         const t = this.$root.files.length;
         0 === t ? (this.$status.innerText = this.i18n.t("filesSelectedDefault"), this.$status.classList.add("govuk-tag--light-blue")) : (this.$status.innerText = 1 === t ? this.$root.files[0].name : this.i18n.t("filesSelected", {
             count: t
-        }), this.$status.classList.remove("govuk-tag--light-blue")), this.$button.setAttribute("aria-label", `${this.$label.innerText}, ${this.i18n.t("selectFilesButton")} ${this.i18n.t("instruction")}, ${this.$status.innerText}`)
+        }), this.$status.classList.remove("govuk-tag--light-blue"))
     }
     findLabel() {
         const t = document.querySelector(`label[for="${this.$root.id}"]`);

Action run for 95e45e7

Copy link

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 05abbd7dc..6bb157926 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.js
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.js
@@ -1682,14 +1682,14 @@
       this.i18n = new I18n(this.config.i18n, {
         locale: closestAttributeValue(this.$root, 'lang')
       });
-      this.$label = this.findLabel();
+      const $label = this.findLabel();
+      $label.setAttribute('for', `${this.id}-input`);
+      if (!$label.id) {
+        $label.id = `${this.id}-label`;
+      }
       this.$root.id = `${this.id}-input`;
-      this.$label.setAttribute('for', `${this.id}-input`);
       const $wrapper = document.createElement('div');
       $wrapper.className = 'govuk-file-upload-wrapper';
-      const commaSpan = document.createElement('span');
-      commaSpan.className = 'govuk-visually-hidden';
-      commaSpan.innerText = ', ';
       const $button = document.createElement('button');
       $button.classList.add('govuk-file-upload__button');
       $button.type = 'button';
@@ -1697,18 +1697,20 @@
       const $status = document.createElement('span');
       $status.className = 'govuk-body govuk-file-upload__status';
       $status.innerText = this.i18n.t('filesSelectedDefault');
-      $status.setAttribute('aria-hidden', 'true');
       if (!this.$root.files.length) {
         $status.classList.add('govuk-tag--light-blue');
       }
       $button.appendChild($status);
-      $button.appendChild(commaSpan.cloneNode(true));
+      const commaSpan = document.createElement('span');
+      commaSpan.className = 'govuk-visually-hidden';
+      commaSpan.innerText = ', ';
+      commaSpan.id = `${this.id}-comma`;
+      $button.appendChild(commaSpan);
       const buttonParentSpan = document.createElement('span');
       buttonParentSpan.className = 'govuk-file-upload__pseudo-button-container';
       const buttonSpan = document.createElement('span');
       buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
       buttonSpan.innerText = this.i18n.t('selectFilesButton');
-      buttonSpan.setAttribute('aria-hidden', 'true');
       buttonParentSpan.appendChild(buttonSpan);
       buttonParentSpan.appendChild(commaSpan.cloneNode(true));
       const instructionSpan = document.createElement('span');
@@ -1716,7 +1718,7 @@
       instructionSpan.innerText = this.i18n.t('instruction');
       buttonParentSpan.appendChild(instructionSpan);
       $button.appendChild(buttonParentSpan);
-      $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${$status.innerText}`);
+      $button.setAttribute('aria-labelledby', `${$label.id} ${commaSpan.id} ${$button.id}`);
       $button.addEventListener('click', this.onClick.bind(this));
       $wrapper.insertAdjacentElement('beforeend', $button);
       this.$root.insertAdjacentElement('afterend', $wrapper);
@@ -1788,7 +1790,6 @@
         }
         this.$status.classList.remove('govuk-tag--light-blue');
       }
-      this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${this.$status.innerText}`);
     }
     findLabel() {
       const $label = document.querySelector(`label[for="${this.$root.id}"]`);
diff --git a/packages/govuk-frontend/dist/govuk/all.bundle.mjs b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
index e2c8aba80..b1bc3868d 100644
--- a/packages/govuk-frontend/dist/govuk/all.bundle.mjs
+++ b/packages/govuk-frontend/dist/govuk/all.bundle.mjs
@@ -1676,14 +1676,14 @@ class FileUpload extends ConfigurableComponent {
     this.i18n = new I18n(this.config.i18n, {
       locale: closestAttributeValue(this.$root, 'lang')
     });
-    this.$label = this.findLabel();
+    const $label = this.findLabel();
+    $label.setAttribute('for', `${this.id}-input`);
+    if (!$label.id) {
+      $label.id = `${this.id}-label`;
+    }
     this.$root.id = `${this.id}-input`;
-    this.$label.setAttribute('for', `${this.id}-input`);
     const $wrapper = document.createElement('div');
     $wrapper.className = 'govuk-file-upload-wrapper';
-    const commaSpan = document.createElement('span');
-    commaSpan.className = 'govuk-visually-hidden';
-    commaSpan.innerText = ', ';
     const $button = document.createElement('button');
     $button.classList.add('govuk-file-upload__button');
     $button.type = 'button';
@@ -1691,18 +1691,20 @@ class FileUpload extends ConfigurableComponent {
     const $status = document.createElement('span');
     $status.className = 'govuk-body govuk-file-upload__status';
     $status.innerText = this.i18n.t('filesSelectedDefault');
-    $status.setAttribute('aria-hidden', 'true');
     if (!this.$root.files.length) {
       $status.classList.add('govuk-tag--light-blue');
     }
     $button.appendChild($status);
-    $button.appendChild(commaSpan.cloneNode(true));
+    const commaSpan = document.createElement('span');
+    commaSpan.className = 'govuk-visually-hidden';
+    commaSpan.innerText = ', ';
+    commaSpan.id = `${this.id}-comma`;
+    $button.appendChild(commaSpan);
     const buttonParentSpan = document.createElement('span');
     buttonParentSpan.className = 'govuk-file-upload__pseudo-button-container';
     const buttonSpan = document.createElement('span');
     buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
     buttonSpan.innerText = this.i18n.t('selectFilesButton');
-    buttonSpan.setAttribute('aria-hidden', 'true');
     buttonParentSpan.appendChild(buttonSpan);
     buttonParentSpan.appendChild(commaSpan.cloneNode(true));
     const instructionSpan = document.createElement('span');
@@ -1710,7 +1712,7 @@ class FileUpload extends ConfigurableComponent {
     instructionSpan.innerText = this.i18n.t('instruction');
     buttonParentSpan.appendChild(instructionSpan);
     $button.appendChild(buttonParentSpan);
-    $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${$status.innerText}`);
+    $button.setAttribute('aria-labelledby', `${$label.id} ${commaSpan.id} ${$button.id}`);
     $button.addEventListener('click', this.onClick.bind(this));
     $wrapper.insertAdjacentElement('beforeend', $button);
     this.$root.insertAdjacentElement('afterend', $wrapper);
@@ -1782,7 +1784,6 @@ class FileUpload extends ConfigurableComponent {
       }
       this.$status.classList.remove('govuk-tag--light-blue');
     }
-    this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${this.$status.innerText}`);
   }
   findLabel() {
     const $label = document.querySelector(`label[for="${this.$root.id}"]`);
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 a138ee559..06d7fd821 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
@@ -509,14 +509,14 @@
       this.i18n = new I18n(this.config.i18n, {
         locale: closestAttributeValue(this.$root, 'lang')
       });
-      this.$label = this.findLabel();
+      const $label = this.findLabel();
+      $label.setAttribute('for', `${this.id}-input`);
+      if (!$label.id) {
+        $label.id = `${this.id}-label`;
+      }
       this.$root.id = `${this.id}-input`;
-      this.$label.setAttribute('for', `${this.id}-input`);
       const $wrapper = document.createElement('div');
       $wrapper.className = 'govuk-file-upload-wrapper';
-      const commaSpan = document.createElement('span');
-      commaSpan.className = 'govuk-visually-hidden';
-      commaSpan.innerText = ', ';
       const $button = document.createElement('button');
       $button.classList.add('govuk-file-upload__button');
       $button.type = 'button';
@@ -524,18 +524,20 @@
       const $status = document.createElement('span');
       $status.className = 'govuk-body govuk-file-upload__status';
       $status.innerText = this.i18n.t('filesSelectedDefault');
-      $status.setAttribute('aria-hidden', 'true');
       if (!this.$root.files.length) {
         $status.classList.add('govuk-tag--light-blue');
       }
       $button.appendChild($status);
-      $button.appendChild(commaSpan.cloneNode(true));
+      const commaSpan = document.createElement('span');
+      commaSpan.className = 'govuk-visually-hidden';
+      commaSpan.innerText = ', ';
+      commaSpan.id = `${this.id}-comma`;
+      $button.appendChild(commaSpan);
       const buttonParentSpan = document.createElement('span');
       buttonParentSpan.className = 'govuk-file-upload__pseudo-button-container';
       const buttonSpan = document.createElement('span');
       buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
       buttonSpan.innerText = this.i18n.t('selectFilesButton');
-      buttonSpan.setAttribute('aria-hidden', 'true');
       buttonParentSpan.appendChild(buttonSpan);
       buttonParentSpan.appendChild(commaSpan.cloneNode(true));
       const instructionSpan = document.createElement('span');
@@ -543,7 +545,7 @@
       instructionSpan.innerText = this.i18n.t('instruction');
       buttonParentSpan.appendChild(instructionSpan);
       $button.appendChild(buttonParentSpan);
-      $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${$status.innerText}`);
+      $button.setAttribute('aria-labelledby', `${$label.id} ${commaSpan.id} ${$button.id}`);
       $button.addEventListener('click', this.onClick.bind(this));
       $wrapper.insertAdjacentElement('beforeend', $button);
       this.$root.insertAdjacentElement('afterend', $wrapper);
@@ -615,7 +617,6 @@
         }
         this.$status.classList.remove('govuk-tag--light-blue');
       }
-      this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${this.$status.innerText}`);
     }
     findLabel() {
       const $label = document.querySelector(`label[for="${this.$root.id}"]`);
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 d53f5ef9d..28d92c840 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
@@ -503,14 +503,14 @@ class FileUpload extends ConfigurableComponent {
     this.i18n = new I18n(this.config.i18n, {
       locale: closestAttributeValue(this.$root, 'lang')
     });
-    this.$label = this.findLabel();
+    const $label = this.findLabel();
+    $label.setAttribute('for', `${this.id}-input`);
+    if (!$label.id) {
+      $label.id = `${this.id}-label`;
+    }
     this.$root.id = `${this.id}-input`;
-    this.$label.setAttribute('for', `${this.id}-input`);
     const $wrapper = document.createElement('div');
     $wrapper.className = 'govuk-file-upload-wrapper';
-    const commaSpan = document.createElement('span');
-    commaSpan.className = 'govuk-visually-hidden';
-    commaSpan.innerText = ', ';
     const $button = document.createElement('button');
     $button.classList.add('govuk-file-upload__button');
     $button.type = 'button';
@@ -518,18 +518,20 @@ class FileUpload extends ConfigurableComponent {
     const $status = document.createElement('span');
     $status.className = 'govuk-body govuk-file-upload__status';
     $status.innerText = this.i18n.t('filesSelectedDefault');
-    $status.setAttribute('aria-hidden', 'true');
     if (!this.$root.files.length) {
       $status.classList.add('govuk-tag--light-blue');
     }
     $button.appendChild($status);
-    $button.appendChild(commaSpan.cloneNode(true));
+    const commaSpan = document.createElement('span');
+    commaSpan.className = 'govuk-visually-hidden';
+    commaSpan.innerText = ', ';
+    commaSpan.id = `${this.id}-comma`;
+    $button.appendChild(commaSpan);
     const buttonParentSpan = document.createElement('span');
     buttonParentSpan.className = 'govuk-file-upload__pseudo-button-container';
     const buttonSpan = document.createElement('span');
     buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
     buttonSpan.innerText = this.i18n.t('selectFilesButton');
-    buttonSpan.setAttribute('aria-hidden', 'true');
     buttonParentSpan.appendChild(buttonSpan);
     buttonParentSpan.appendChild(commaSpan.cloneNode(true));
     const instructionSpan = document.createElement('span');
@@ -537,7 +539,7 @@ class FileUpload extends ConfigurableComponent {
     instructionSpan.innerText = this.i18n.t('instruction');
     buttonParentSpan.appendChild(instructionSpan);
     $button.appendChild(buttonParentSpan);
-    $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${$status.innerText}`);
+    $button.setAttribute('aria-labelledby', `${$label.id} ${commaSpan.id} ${$button.id}`);
     $button.addEventListener('click', this.onClick.bind(this));
     $wrapper.insertAdjacentElement('beforeend', $button);
     this.$root.insertAdjacentElement('afterend', $wrapper);
@@ -609,7 +611,6 @@ class FileUpload extends ConfigurableComponent {
       }
       this.$status.classList.remove('govuk-tag--light-blue');
     }
-    this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${this.$status.innerText}`);
   }
   findLabel() {
     const $label = document.querySelector(`label[for="${this.$root.id}"]`);
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 8cae2bfa2..b6805b074 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
@@ -32,14 +32,14 @@ class FileUpload extends ConfigurableComponent {
     this.i18n = new I18n(this.config.i18n, {
       locale: closestAttributeValue(this.$root, 'lang')
     });
-    this.$label = this.findLabel();
+    const $label = this.findLabel();
+    $label.setAttribute('for', `${this.id}-input`);
+    if (!$label.id) {
+      $label.id = `${this.id}-label`;
+    }
     this.$root.id = `${this.id}-input`;
-    this.$label.setAttribute('for', `${this.id}-input`);
     const $wrapper = document.createElement('div');
     $wrapper.className = 'govuk-file-upload-wrapper';
-    const commaSpan = document.createElement('span');
-    commaSpan.className = 'govuk-visually-hidden';
-    commaSpan.innerText = ', ';
     const $button = document.createElement('button');
     $button.classList.add('govuk-file-upload__button');
     $button.type = 'button';
@@ -47,18 +47,20 @@ class FileUpload extends ConfigurableComponent {
     const $status = document.createElement('span');
     $status.className = 'govuk-body govuk-file-upload__status';
     $status.innerText = this.i18n.t('filesSelectedDefault');
-    $status.setAttribute('aria-hidden', 'true');
     if (!this.$root.files.length) {
       $status.classList.add('govuk-tag--light-blue');
     }
     $button.appendChild($status);
-    $button.appendChild(commaSpan.cloneNode(true));
+    const commaSpan = document.createElement('span');
+    commaSpan.className = 'govuk-visually-hidden';
+    commaSpan.innerText = ', ';
+    commaSpan.id = `${this.id}-comma`;
+    $button.appendChild(commaSpan);
     const buttonParentSpan = document.createElement('span');
     buttonParentSpan.className = 'govuk-file-upload__pseudo-button-container';
     const buttonSpan = document.createElement('span');
     buttonSpan.className = 'govuk-button govuk-button--secondary govuk-file-upload__pseudo-button';
     buttonSpan.innerText = this.i18n.t('selectFilesButton');
-    buttonSpan.setAttribute('aria-hidden', 'true');
     buttonParentSpan.appendChild(buttonSpan);
     buttonParentSpan.appendChild(commaSpan.cloneNode(true));
     const instructionSpan = document.createElement('span');
@@ -66,7 +68,7 @@ class FileUpload extends ConfigurableComponent {
     instructionSpan.innerText = this.i18n.t('instruction');
     buttonParentSpan.appendChild(instructionSpan);
     $button.appendChild(buttonParentSpan);
-    $button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${$status.innerText}`);
+    $button.setAttribute('aria-labelledby', `${$label.id} ${commaSpan.id} ${$button.id}`);
     $button.addEventListener('click', this.onClick.bind(this));
     $wrapper.insertAdjacentElement('beforeend', $button);
     this.$root.insertAdjacentElement('afterend', $wrapper);
@@ -138,7 +140,6 @@ class FileUpload extends ConfigurableComponent {
       }
       this.$status.classList.remove('govuk-tag--light-blue');
     }
-    this.$button.setAttribute('aria-label', `${this.$label.innerText}, ${this.i18n.t('selectFilesButton')} ${this.i18n.t('instruction')}, ${this.$status.innerText}`);
   }
   findLabel() {
     const $label = document.querySelector(`label[for="${this.$root.id}"]`);

Action run for 95e45e7

@romaricpascal romaricpascal changed the title Label the <button> using aria-labelledby [SPIKE] Label <button> with aria-labelledby (label + itself) Jan 27, 2025
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.

2 participants