@jsxtools/eslint-plugin-jsx-a11y
Version:
Static AST checker for accessibility rules on JSX elements for flat ESLint Config.
64 lines (61 loc) • 2.93 kB
JavaScript
import { roles, elementRoles, dom } from 'aria-query';
import { AXObjects, elementAXObjects } from 'axobject-query';
import { f as filter, i as iterFrom } from '../index-d79WKvnw.js';
import { s as some } from '../index-FhAWpKDl.js';
import attributesComparator from './attributesComparator.js';
const roleKeys = [...roles.keys()];
const elementRoleEntries = [...elementRoles];
const nonInteractiveRoles = new Set(roleKeys.filter((name) => {
const role = roles.get(name);
return !role.abstract && name !== "toolbar" && name !== "generic" && name !== "cell" && !role.superClass.some((classes) => classes.includes("widget"));
}).concat(
// The `progressbar` is descended from `widget`, but in practice, its
// value is always `readonly`, so we treat it as a non-interactive role.
"progressbar"
));
const interactiveRoles = new Set(roleKeys.filter((name) => {
const role = roles.get(name);
return !role.abstract && name !== "progressbar" && name !== "generic" && role.superClass.some((classes) => classes.includes("widget"));
}).concat(
// 'toolbar' does not descend from widget, but it does support
// aria-activedescendant, thus in practice we treat it as a widget.
"toolbar"
));
const interactiveElementRoleSchemas = elementRoleEntries.flatMap(
([elementSchema, rolesArr]) => rolesArr.some((role) => interactiveRoles.has(role)) ? [elementSchema] : []
);
const nonInteractiveElementRoleSchemas = elementRoleEntries.flatMap(
([elementSchema, rolesArr]) => rolesArr.every((role) => nonInteractiveRoles.has(role)) ? [elementSchema] : []
);
const nonInteractiveAXObjects = new Set(filter(iterFrom(AXObjects.keys()), (name) => ["window", "structure"].includes(AXObjects.get(name).type)));
const nonInteractiveElementAXObjectSchemas = [...elementAXObjects].flatMap(
([elementSchema, AXObjectsArr]) => AXObjectsArr.every((role) => nonInteractiveAXObjects.has(role)) ? [elementSchema] : []
);
function checkIsNonInteractiveElement(tagName, attributes) {
function elementSchemaMatcher(elementSchema) {
return tagName === elementSchema.name && attributesComparator(elementSchema.attributes, attributes);
}
const isInherentNonInteractiveElement = some(iterFrom(nonInteractiveElementRoleSchemas), elementSchemaMatcher);
if (isInherentNonInteractiveElement) {
return true;
}
const isInherentInteractiveElement = some(iterFrom(interactiveElementRoleSchemas), elementSchemaMatcher);
if (isInherentInteractiveElement) {
return false;
}
const isNonInteractiveAXElement = some(iterFrom(nonInteractiveElementAXObjectSchemas), elementSchemaMatcher);
if (isNonInteractiveAXElement) {
return true;
}
return false;
}
const isNonInteractiveElement = (tagName, attributes) => {
if (!dom.has(tagName)) {
return false;
}
if (tagName === "header") {
return false;
}
return checkIsNonInteractiveElement(tagName, attributes);
};
export { isNonInteractiveElement as default };