diff --git a/src/icons/helpers/icon-base.js b/src/icons/helpers/icon-base.js index 1a87fe13643..f98421aef3f 100644 --- a/src/icons/helpers/icon-base.js +++ b/src/icons/helpers/icon-base.js @@ -52,7 +52,7 @@ const baseAttrs = { height: '1em', focusable: 'false', role: 'img', - alt: 'icon' + 'aria-label': 'icon' } // Attributes that are nulled out when stacked @@ -61,7 +61,7 @@ const stackedAttrs = { height: null, focusable: null, role: null, - alt: null + 'aria-label': null } // Shared private base component to reduce bundle/runtime size diff --git a/src/icons/helpers/make-icon.js b/src/icons/helpers/make-icon.js index dd5c25985f2..cecad3f3cff 100644 --- a/src/icons/helpers/make-icon.js +++ b/src/icons/helpers/make-icon.js @@ -13,8 +13,9 @@ import { commonIconProps, BVIconBase } from './icon-base' export const makeIcon = (name, content) => { // For performance reason we pre-compute some values, so that // they are not computed on each render of the icon component + const kebabName = kebabCase(name) const iconName = `BIcon${pascalCase(name)}` - const iconNameClass = `bi-${kebabCase(name)}` + const iconNameClass = `bi-${kebabName}` const svgContent = trim(content || '') // Return the icon component definition return /*#__PURE__*/ Vue.extend({ @@ -30,7 +31,11 @@ export const makeIcon = (name, content) => { render(h, { data, props }) { return h( BVIconBase, - mergeData(data, { staticClass: iconNameClass, props: { ...props, content: svgContent } }) + mergeData(data, { + staticClass: iconNameClass, + props: { ...props, content: svgContent }, + attrs: { 'aria-label': kebabName.replace(/-/g, ' ') } + }) ) } }) diff --git a/src/icons/icons.spec.js b/src/icons/icons.spec.js index 3f00ebb8f0b..3992f1ca2b9 100644 --- a/src/icons/icons.spec.js +++ b/src/icons/icons.spec.js @@ -22,7 +22,7 @@ describe('icons', () => { expect(wrapper.classes()).toContain('bi-alarm-fill') expect(wrapper.classes().length).toBe(3) expect(wrapper.attributes('role')).toBe('img') - expect(wrapper.attributes('alt')).toBe('icon') + expect(wrapper.attributes('aria-label')).toBe('alarm fill') expect(wrapper.attributes('focusable')).toBe('false') expect(wrapper.attributes('xmlns')).toBe('http://www.w3.org/2000/svg') expect(wrapper.attributes('width')).toBe('1em') @@ -54,7 +54,7 @@ describe('icons', () => { expect(wrapper.classes()).toContain('bi-alarm-fill') expect(wrapper.classes().length).toBe(3) expect(wrapper.attributes('role')).not.toBe('img') - expect(wrapper.attributes('alt')).not.toBe('icon') + expect(wrapper.attributes('aria-label')).not.toBe('icon') expect(wrapper.attributes('focusable')).not.toBe('false') expect(wrapper.attributes('focusable')).not.toBe('true') expect(wrapper.attributes('xmlns')).not.toBe('http://www.w3.org/2000/svg') @@ -153,7 +153,7 @@ describe('icons', () => { expect(wrapper.classes()).toContain('text-danger') expect(wrapper.classes().length).toBe(4) expect(wrapper.attributes('role')).toBe('img') - expect(wrapper.attributes('alt')).toBe('icon') + expect(wrapper.attributes('aria-label')).toBe('alarm fill') expect(wrapper.attributes('focusable')).toBe('false') expect(wrapper.find('svg > g').exists()).toBe(true) expect(wrapper.find('svg > g').attributes('transform')).not.toBeDefined() @@ -178,7 +178,7 @@ describe('icons', () => { expect(wrapper.classes()).toContain('bi-alarm-fill') expect(wrapper.classes().length).toBe(3) expect(wrapper.attributes('role')).toBe('img') - expect(wrapper.attributes('alt')).toBe('icon') + expect(wrapper.attributes('aria-label')).toBe('alarm fill') expect(wrapper.attributes('focusable')).toBe('false') expect(wrapper.attributes('style')).toBeDefined() expect(wrapper.element.style.fontSize).toEqual('125%') diff --git a/src/icons/iconstack.spec.js b/src/icons/iconstack.spec.js index 7eed694c270..943f59fea38 100644 --- a/src/icons/iconstack.spec.js +++ b/src/icons/iconstack.spec.js @@ -12,7 +12,7 @@ describe('icons > b-iconstack', () => { expect(wrapper.classes()).toContain('bi') expect(wrapper.classes().length).toBe(3) expect(wrapper.attributes('role')).toBe('img') - expect(wrapper.attributes('alt')).toBe('icon') + expect(wrapper.attributes('aria-label')).toBe('icon') expect(wrapper.attributes('focusable')).toBe('false') expect(wrapper.attributes('xmlns')).toBe('http://www.w3.org/2000/svg') expect(wrapper.attributes('width')).toBe('1em') @@ -43,7 +43,7 @@ describe('icons > b-iconstack', () => { expect(wrapper.classes()).toContain('text-danger') expect(wrapper.classes().length).toBe(4) expect(wrapper.attributes('role')).toBe('img') - expect(wrapper.attributes('alt')).toBe('icon') + expect(wrapper.attributes('aria-label')).toBe('icon') expect(wrapper.attributes('focusable')).toBe('false') expect(wrapper.find('svg > g').exists()).toBe(true) expect(wrapper.find('svg > g').attributes('transform')).not.toBeDefined() @@ -65,7 +65,7 @@ describe('icons > b-iconstack', () => { expect(wrapper.classes()).toContain('bi') expect(wrapper.classes().length).toBe(3) expect(wrapper.attributes('role')).toBe('img') - expect(wrapper.attributes('alt')).toBe('icon') + expect(wrapper.attributes('aria-label')).toBe('icon') expect(wrapper.attributes('focusable')).toBe('false') expect(wrapper.attributes('style')).toBeDefined() expect(wrapper.element.style.fontSize).toEqual('125%')