feat(lint): noAccessKey for JSX and HTML
MODIFY
internal/compiler/lint/rules/a11y/noAccessKey.test.rjson
internal/compiler/lint/rules/a11y/noAccessKey.test.rjson
{
filename: "file.tsx"
invalid: [
- "<input accessKey='key' />"
+ "<input accessKey=\"key\" />"
"<input accessKey={key} />"
]
valid: [
{
filename: "file.html"
invalid: [
- "<input accesskey=\"h\" />"
+ "<input accesskey=\"key\" />"
]
valid: [
"<input />"

MODIFY
internal/compiler/lint/rules/a11y/noAccessKey.ts
internal/compiler/lint/rules/a11y/noAccessKey.ts
@@ -3,7 +3,6 @@ import {createVisitor, signals} from "@internal/compiler";
import {getJSXAttribute, hasJSXAttribute} from "@internal/js-ast-utils";
import {isJSXDOMElement} from "@internal/js-ast-utils/isJSXDOMElement";
import isHTMLElement from "@internal/js-ast-utils/isHTMLElement";
-import hasHTMLAttribute from "@internal/js-ast-utils/hasHTMLAttribute";
import getHTMLAttribute from "@internal/js-ast-utils/getHTMLAttribute";
export default createVisitor({
@@ -12,35 +11,38 @@ export default createVisitor({
enter(path) {
const {node} = path;
- if (isHTMLElement(node) && hasHTMLAttribute(node, "accesskey")) {
+ if (isJSXDOMElement(node) && hasJSXAttribute(node, "accessKey")) {
return path.addFixableDiagnostic(
{
- target: getHTMLAttribute(node, "accesskey"),
+ target: getJSXAttribute(node, "accessKey"),
fixed: signals.replace({
...node,
attributes: node.attributes.filter((attribute) =>
- attribute.type !== "HTMLAttribute" ||
- attribute.name.name !== "accesskey"
+ attribute.type !== "JSXAttribute" ||
+ attribute.name.name !== "accessKey"
),
}),
},
- descriptions.LINT.A11_Y_NO_ACCESS_KEY,
+ descriptions.LINT.A11Y_NO_ACCESS_KEY,
);
- } else if (isJSXDOMElement(node) && hasJSXAttribute(node, "accessKey")) {
+ } else if (isHTMLElement(node)) {
+ const accessKeyAttribute = getHTMLAttribute(node, "accesskey");
+ if (accessKeyAttribute) {
return path.addFixableDiagnostic(
{
- target: getJSXAttribute(node, "accessKey"),
+ target: accessKeyAttribute,
fixed: signals.replace({
...node,
attributes: node.attributes.filter((attribute) =>
- attribute.type !== "JSXAttribute" ||
- attribute.name.name !== "accessKey"
+ attribute.type !== "HTMLAttribute" ||
+ attribute.name.name !== "accesskey"
),
}),
},
- descriptions.LINT.A11_Y_NO_ACCESS_KEY,
+ descriptions.LINT.A11Y_NO_ACCESS_KEY,
);
}
+ }
return signals.retain;
},

MODIFY
internal/diagnostics/descriptions/lint.ts
internal/diagnostics/descriptions/lint.ts
@@ -497,7 +497,17 @@ export const lint = createDiagnosticsCategory({
},
],
},
-
+ A11Y_NO_ACCESS_KEY: {
+ category: DIAGNOSTIC_CATEGORIES["lint/a11y/noAccessKey"],
+ message: markup`Avoid the <emphasis>accessKey</emphasis> attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments.`,
+ advice: [
+ {
+ type: "log",
+ category: "info",
+ text: markup`Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications.`,
+ },
+ ],
+ },
JSX_A11Y_NO_ON_CHANGE: {
category: DIAGNOSTIC_CATEGORIES["lint/jsx-a11y/noOnChange"],
message: markup`Provide an <emphasis>onBlur</emphasis> event instead of an <emphasis>onChange</emphasis> event unless absolutely necessary.`,

feat(lint): noAccessKey for JSX and HTML (#1442)

Co-authored-by: Ng'ethe Maina <ngethe@mradi.co.ke>