diff --git a/its/ruling/src/test/expected/jsts/desktop/typescript-S6842.json b/its/ruling/src/test/expected/jsts/desktop/typescript-S6842.json new file mode 100644 index 00000000000..f31846c0ecd --- /dev/null +++ b/its/ruling/src/test/expected/jsts/desktop/typescript-S6842.json @@ -0,0 +1,8 @@ +{ +"desktop:app/src/ui/lib/vertical-segmented-control/segmented-item.tsx": [ +71 +], +"desktop:app/src/ui/lib/vertical-segmented-control/vertical-segmented-control.tsx": [ +215 +] +} diff --git a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java index 6d99f7ac6d5..f9fecfb292c 100644 --- a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java +++ b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/CheckList.java @@ -291,6 +291,7 @@ public static List> getAllChecks() { NoNestedTemplateLiteralsCheck.class, NoNewNativeNonconstructorCheck.class, NoNonNullAssertionCheck.class, + NoNoninteractiveElementToInteractiveRoleCheck.class, NoOctalEscapeCheck.class, NoOneIterationLoopCheck.class, NoOsCommandsFromPathCheck.class, diff --git a/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoNoninteractiveElementToInteractiveRoleCheck.java b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoNoninteractiveElementToInteractiveRoleCheck.java new file mode 100644 index 00000000000..4c40d1d1636 --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/java/org/sonar/javascript/checks/NoNoninteractiveElementToInteractiveRoleCheck.java @@ -0,0 +1,36 @@ +/** + * SonarQube JavaScript Plugin + * Copyright (C) 2011-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.javascript.checks; + +import org.sonar.check.Rule; +import org.sonar.plugins.javascript.api.EslintBasedCheck; +import org.sonar.plugins.javascript.api.JavaScriptRule; +import org.sonar.plugins.javascript.api.TypeScriptRule; + +@JavaScriptRule +@TypeScriptRule +@Rule(key = "S6842") +public class NoNoninteractiveElementToInteractiveRoleCheck implements EslintBasedCheck { + + @Override + public String eslintKey() { + return "no-noninteractive-element-to-interactive-role"; + } +} diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6842.html b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6842.html new file mode 100644 index 00000000000..da7e960be84 --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6842.html @@ -0,0 +1,37 @@ +

Why is this an issue?

+

Non-interactive DOM elements are those that do not have built-in interactivity or do not require user interaction. Examples include +<div>, <p>, <img>, <h1> to <h6>, and +<ul>, among others. These elements are typically used to structure content and layout but do not have any inherent interactive +behavior.

+

Interactive ARIA roles, on the other hand, are used to make elements interactive and accessible. These roles include button, +link, checkbox, menuitem, tab, and others. They are used to communicate the type of interaction +that users can expect from an element.

+

Non-interactive DOM elements should not use interactive ARIA roles because it can confuse assistive technologies and their users. For example, if a +<div> (a non-interactive element) is given an interactive role like "button", assistive technologies like screen readers will +announce it as a button. However, since <div> doesn’t have the inherent behavior of a button, it can confuse users who expect it to +behave like a button when interacted with.

+

This can lead to a poor user experience and can make the website less accessible for users relying on assistive technologies. Therefore, it’s +important to ensure that non-interactive DOM elements are not given interactive ARIA roles.

+

How to fix it

+

Ensure that non-interactive DOM elements do not use interactive ARIA roles.

+

Code examples

+

Noncompliant code example

+
+function myListElement() {
+    return <li role="button">Foo</li>; // Noncompliant; "li" isn't interactive, but "button" is
+}
+
+

Compliant solution

+
+function myListElement() {
+    return <li role="listitem">Foo</li>;
+}
+
+

Resources

+

Documentation

+ + diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6842.json b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6842.json new file mode 100644 index 00000000000..b8bfc0001e4 --- /dev/null +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/S6842.json @@ -0,0 +1,29 @@ +{ + "title": "Non-interactive DOM elements should not have interactive ARIA roles", + "type": "CODE_SMELL", + "status": "ready", + "remediation": { + "func": "Constant\/Issue", + "constantCost": "5min" + }, + "tags": [ + "accessibility", + "react" + ], + "defaultSeverity": "Major", + "ruleSpecification": "RSPEC-6842", + "sqKey": "S6842", + "scope": "All", + "quickfix": "infeasible", + "code": { + "impacts": { + "MAINTAINABILITY": "LOW", + "RELIABILITY": "MEDIUM" + }, + "attribute": "CONVENTIONAL" + }, + "compatibleLanguages": [ + "JAVASCRIPT", + "TYPESCRIPT" + ] +} diff --git a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json index 259df844f08..1fc75232bd8 100644 --- a/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json +++ b/sonar-plugin/javascript-checks/src/main/resources/org/sonar/l10n/javascript/rules/javascript/Sonar_way_profile.json @@ -307,6 +307,7 @@ "S6825", "S6827", "S6836", - "S6841" + "S6841", + "S6842" ] }