UNPKG

@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
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 };