Skip to content

Commit 33a1f94

Browse files
committed
[fix] - Purely decorative emojis do not need descriptions.
1 parent 4186f91 commit 33a1f94

File tree

2 files changed

+11
-0
lines changed

2 files changed

+11
-0
lines changed

__tests__/src/rules/accessible-emoji-test.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ ruleTester.run('accessible-emoji', rule, {
3434
{ code: '<span role="img" aria-labelledby="id1">&#9731;</span>' },
3535
{ code: '<span role="img" aria-labelledby="id1" aria-label="Snowman">&#9731;</span>' },
3636
{ code: '<span>{props.emoji}</span>' },
37+
{ code: '<span aria-hidden>{props.emoji}</span>' },
38+
{ code: '<span aria-hidden="true">🐼</span>' },
39+
{ code: '<span aria-hidden>🐼</span>' },
40+
{ code: '<div aria-hidden="true">🐼</div>' },
3741
].map(parserOptionsMapper),
3842
invalid: [
3943
{ code: '<span>🐼</span>', errors: [expectedError] },
@@ -42,5 +46,6 @@ ruleTester.run('accessible-emoji', rule, {
4246
{ code: '<i role="img" aria-label="Panda face">🐼</i>', errors: [expectedError] },
4347
{ code: '<i role="img" aria-labelledby="id1">🐼</i>', errors: [expectedError] },
4448
{ code: '<Foo>🐼</Foo>', errors: [expectedError] },
49+
{ code: '<span aria-hidden="false">🐼</span>', errors: [expectedError] },
4550
].map(parserOptionsMapper),
4651
});

src/rules/accessible-emoji.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import emojiRegex from 'emoji-regex';
1111
import { getProp, getLiteralPropValue, elementType } from 'jsx-ast-utils';
1212
import { generateObjSchema } from '../util/schemas';
13+
import isHiddenFromScreenReader from '../util/isHiddenFromScreenReader';
1314

1415
const errorMessage = 'Emojis should be wrapped in <span>, have role="img", and have an accessible description with aria-label or aria-labelledby.';
1516

@@ -28,6 +29,11 @@ module.exports = {
2829
const literalChildValue = node.parent.children.find(child => child.type === 'Literal' || child.type === 'JSXText');
2930

3031
if (literalChildValue && emojiRegex().test(literalChildValue.value)) {
32+
const elementIsHidden = isHiddenFromScreenReader(elementType(node), node.attributes);
33+
if (elementIsHidden) {
34+
return; // emoji is decorative
35+
}
36+
3137
const rolePropValue = getLiteralPropValue(getProp(node.attributes, 'role'));
3238
const ariaLabelProp = getProp(node.attributes, 'aria-label');
3339
const arialLabelledByProp = getProp(node.attributes, 'aria-labelledby');

0 commit comments

Comments
 (0)