diff --git a/__tests__/src/util/mayHaveAccessibleLabel-test.js b/__tests__/src/util/mayHaveAccessibleLabel-test.js index 1c7a38d5f..ee85669f7 100644 --- a/__tests__/src/util/mayHaveAccessibleLabel-test.js +++ b/__tests__/src/util/mayHaveAccessibleLabel-test.js @@ -41,6 +41,14 @@ describe('mayHaveAccessibleLabel', () => { JSXAttributeMock('aria-label', ''), ], []))).toBe(false); }); + it('aria-label with only whitespace, should return false', () => { + expect(mayHaveAccessibleLabel(JSXElementMock('div', [ + JSXAttributeMock('aria-label', ' '), + ], []))).toBe(false); + expect(mayHaveAccessibleLabel(JSXElementMock('div', [ + JSXAttributeMock('aria-label', '\n'), + ], []))).toBe(false); + }); it('aria-labelledby, should return true', () => { expect(mayHaveAccessibleLabel(JSXElementMock('div', [ JSXAttributeMock('aria-labelledby', 'elementId'), @@ -78,6 +86,14 @@ describe('mayHaveAccessibleLabel', () => { LiteralMock('A fancy label'), ]))).toBe(true); }); + it('Literal whitespace, should return false', () => { + expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ + LiteralMock(' '), + ]))).toBe(false); + expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ + LiteralMock('\n'), + ]))).toBe(false); + }); it('JSXText, should return true', () => { expect(mayHaveAccessibleLabel(JSXElementMock('div', [], [ JSXTextMock('A fancy label'), diff --git a/src/util/mayHaveAccessibleLabel.js b/src/util/mayHaveAccessibleLabel.js index 4fc04b244..31acee955 100644 --- a/src/util/mayHaveAccessibleLabel.js +++ b/src/util/mayHaveAccessibleLabel.js @@ -12,6 +12,10 @@ import includes from 'array-includes'; import { getPropValue, propName } from 'jsx-ast-utils'; import type { JSXOpeningElement, Node } from 'ast-types-flow'; +function tryTrim(value: any) { + return typeof value === 'string' ? value.trim() : value; +} + function hasLabellingProp( openingElement: JSXOpeningElement, additionalLabellingProps?: Array = [], @@ -30,7 +34,7 @@ function hasLabellingProp( // Attribute matches. if ( includes(labellingProps, propName(attribute)) - && !!getPropValue(attribute) + && !!tryTrim(getPropValue(attribute)) ) { return true; } @@ -52,7 +56,7 @@ export default function mayHaveAccessibleLabel( return false; } // Check for literal text. - if (node.type === 'Literal' && !!node.value) { + if (node.type === 'Literal' && !!tryTrim(node.value)) { return true; } // Assume an expression container renders a label. It is the best we can @@ -62,7 +66,7 @@ export default function mayHaveAccessibleLabel( } // Check for JSXText. // $FlowFixMe Remove after updating ast-types-flow - if (node.type === 'JSXText' && !!node.value) { + if (node.type === 'JSXText' && !!tryTrim(node.value)) { return true; } // Check for labelling props.