From 79191c838feaf5bf038d0fb858767fe9cd68865a Mon Sep 17 00:00:00 2001 From: fkakatie Date: Thu, 5 Feb 2026 14:38:29 -0800 Subject: [PATCH 1/2] fix: add aria-label to icon-only links --- src/decorate.js | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/decorate.js b/src/decorate.js index 25d778f..7530266 100644 --- a/src/decorate.js +++ b/src/decorate.js @@ -60,6 +60,12 @@ export function decorateIcon(span, prefix = '', alt = '') { img.width = 16; img.height = 16; span.append(img); + // add accessible label to icon-only links + const link = span.closest('a'); + if (link && !link.textContent.trim() && !link.getAttribute('aria-label')) { + const label = alt || iconName; + link.setAttribute('aria-label', label); + } } /** From 6a2b33e26c6d73cbbe955f9ea27326a327269885 Mon Sep 17 00:00:00 2001 From: fkakatie Date: Thu, 5 Feb 2026 14:38:51 -0800 Subject: [PATCH 2/2] test: add coverage for icon-only link accessibility --- test/decorate/decorateIcon.test.html | 48 ++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/test/decorate/decorateIcon.test.html b/test/decorate/decorateIcon.test.html index 02c22ac..b1b30ae 100644 --- a/test/decorate/decorateIcon.test.html +++ b/test/decorate/decorateIcon.test.html @@ -58,6 +58,54 @@ expect(img.length).to.be.equal(1); }); }); + + it('adds aria-label to parent link', async () => { + window.hlx.codeBasePath = '/test/fixtures'; + + const link = document.createElement('a'); + link.href = '/'; + const icon = document.createElement('span'); + icon.className = 'icon icon-logo'; + link.appendChild(icon); + document.body.appendChild(link); + + decorateIcon(icon); + + expect(link.getAttribute('aria-label')).to.equal('logo'); + expect(icon.querySelector('img')).to.exist; + }); + + it('does not overwrite existing aria-label on parent link', async () => { + window.hlx.codeBasePath = '/test/fixtures'; + + const link = document.createElement('a'); + link.href = '/'; + link.setAttribute('aria-label', 'Custom Label'); + const icon = document.createElement('span'); + icon.className = 'icon icon-logo'; + link.appendChild(icon); + document.body.appendChild(link); + + decorateIcon(icon); + + expect(link.getAttribute('aria-label')).to.equal('Custom Label'); + }); + + it('does not add aria-label to links with text content', async () => { + window.hlx.codeBasePath = '/test/fixtures'; + + const link = document.createElement('a'); + link.href = '/'; + link.textContent = 'Home '; + const icon = document.createElement('span'); + icon.className = 'icon icon-arrow'; + link.appendChild(icon); + document.body.appendChild(link); + + decorateIcon(icon); + + expect(link.getAttribute('aria-label')).to.be.null; + }); });