From 7395e00f66d802a75d8671b4cdb59ff9333a80d4 Mon Sep 17 00:00:00 2001 From: Jonathan Date: Wed, 24 Apr 2024 16:33:55 +0200 Subject: [PATCH] fix role "switch" requiring "aria-checked" when used with native input element (#1071) * fix #932 not required switch prop * extended comment Closes #932 --- .../role-has-required-aria-props.test.ts | 10 ++++++++ src/rules/role-has-required-aria-props.ts | 25 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/rules/__tests__/role-has-required-aria-props.test.ts b/src/rules/__tests__/role-has-required-aria-props.test.ts index bec5936c..401fc1cc 100644 --- a/src/rules/__tests__/role-has-required-aria-props.test.ts +++ b/src/rules/__tests__/role-has-required-aria-props.test.ts @@ -3,11 +3,21 @@ import makeRuleTester from "./makeRuleTester"; makeRuleTester("role-has-required-aria-props", rule, { valid: [ + "", "", "", "" ], invalid: [ + { + code: "", + errors: [ + { + messageId: "default", + data: { role: "switch", attributes: "aria-checked" } + } + ] + }, { code: "", errors: [ diff --git a/src/rules/role-has-required-aria-props.ts b/src/rules/role-has-required-aria-props.ts index 9ff619be..d7526fba 100644 --- a/src/rules/role-has-required-aria-props.ts +++ b/src/rules/role-has-required-aria-props.ts @@ -18,6 +18,24 @@ function isAriaRoleDefinitionKey(role: any): role is ARIARoleDefinitionKey { return roles.has(role); } +function filterRequiredPropsExceptions( + node: AST.VElement, + role: ARIARoleDefinitionKey, + elementType: string, + requiredProps: string[] +) { + // Based on the pattern recommendation in https://www.w3.org/WAI/ARIA/apg/patterns/switch/#wai-ariaroles,states,andproperties + // "aria-checked" should not be required when elementType is `input` and has the type attribute `checkbox`. + if ( + role.toLowerCase() === "switch" && + elementType === "input" && + getElementAttributeValue(node, "type") === "checkbox" + ) { + return requiredProps.filter((p) => p !== "aria-checked"); + } + return requiredProps; +} + const rule: Rule.RuleModule = { meta: { type: "problem", @@ -48,7 +66,12 @@ const rule: Rule.RuleModule = { .forEach((role) => { if (isAriaRoleDefinitionKey(role)) { const roleDefinition = roles.get(role) as any; - const requiredProps = Object.keys(roleDefinition.requiredProps); + const requiredProps = filterRequiredPropsExceptions( + node, + role, + elementType, + Object.keys(roleDefinition.requiredProps) + ); if (requiredProps && !hasAttributes(node, requiredProps)) { context.report({