@jsxtools/eslint-plugin-jsx-a11y
Version:
Static AST checker for accessibility rules on JSX elements for flat ESLint Config.
48 lines (45 loc) • 2.04 kB
JavaScript
import emojiRegex from 'emoji-regex';
import safeRegexTest from 'safe-regex-test';
import { getLiteralPropValue, getProp } from '../util/module/jsx-ast-utils.js';
import { generateObjSchema } from '../util/schemas.js';
import getElementType from '../util/getElementType.js';
import isHiddenFromScreenReader from '../util/isHiddenFromScreenReader.js';
const errorMessage = 'Emojis should be wrapped in <span>, have role="img", and have an accessible description with aria-label or aria-labelledby.';
const schema = generateObjSchema();
const ruleOfAccessibleEmoji = {
meta: {
docs: {
description: "Enforce emojis are wrapped in `<span>` and provide screenreader access.",
url: "https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/tree/HEAD/docs/rules/accessible-emoji.md"
},
deprecated: true,
schema: [schema]
},
create: (context) => {
const elementType = getElementType(context);
const testEmoji = safeRegexTest(emojiRegex());
return {
JSXOpeningElement: (node) => {
const literalChildValue = node.parent.children.find((child) => child.type === "Literal" || child.type === "JSXText");
if (literalChildValue && testEmoji(literalChildValue.value)) {
const elementIsHidden = isHiddenFromScreenReader(elementType(node), node.attributes);
if (elementIsHidden) {
return;
}
const rolePropValue = getLiteralPropValue(getProp(node.attributes, "role"));
const ariaLabelProp = getProp(node.attributes, "aria-label");
const arialLabelledByProp = getProp(node.attributes, "aria-labelledby");
const hasLabel = ariaLabelProp !== void 0 || arialLabelledByProp !== void 0;
const isSpan = elementType(node) === "span";
if (hasLabel === false || rolePropValue !== "img" || isSpan === false) {
context.report({
node,
message: errorMessage
});
}
}
}
};
}
};
export { ruleOfAccessibleEmoji as default };