From 7cfaf392e0f3edbbf37fde0fb237ee7b972d19be Mon Sep 17 00:00:00 2001 From: Denis Bezrukov <6227442+denbezrukov@users.noreply.github.com> Date: Sat, 15 Apr 2023 09:07:53 +0300 Subject: [PATCH 01/18] fix(vscode): Text duplication when using VSCode git utilities #4338 (#4376) fix(vscode): Text duplication when using VSCode git utilities #4338 --- CHANGELOG.md | 1 + editors/vscode/src/main.ts | 10 +++++----- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f22cfa317d..229be0c083c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ when there are breaking changes. ### Configuration ### Editors + - Fixed an issue where the VSCode extension duplicates text when using VSCode git utilities [#4338] ### Formatter - Fix an issue where formatting of JSX string literals property values were using incorrect quotes [#4054](https://github.com/rome/tools/issues/4054) diff --git a/editors/vscode/src/main.ts b/editors/vscode/src/main.ts index a84a37b8178..0dff0a8feef 100644 --- a/editors/vscode/src/main.ts +++ b/editors/vscode/src/main.ts @@ -59,11 +59,11 @@ export async function activate(context: ExtensionContext) { ); const documentSelector: DocumentFilter[] = [ - { language: "javascript" }, - { language: "typescript" }, - { language: "javascriptreact" }, - { language: "typescriptreact" }, - { language: "json" }, + { language: "javascript", scheme: "file" }, + { language: "typescript", scheme: "file" }, + { language: "javascriptreact", scheme: "file" }, + { language: "typescriptreact", scheme: "file" }, + { language: "json", scheme: "file" }, ]; const clientOptions: LanguageClientOptions = { From 75af95e564b01622a38e70c7b228b626eeba0853 Mon Sep 17 00:00:00 2001 From: Daiki Nishikawa Date: Mon, 17 Apr 2023 05:33:15 +0900 Subject: [PATCH 02/18] refactor(rome_js_analyze): add more tests and docs for a11y rules through refactoring (#4377) --- .../src/analyzers/a11y/no_access_key.rs | 71 ++---- .../src/analyzers/a11y/no_auto_focus.rs | 23 +- .../src/analyzers/a11y/no_blank_target.rs | 124 +++------- .../analyzers/a11y/no_distracting_elements.rs | 11 +- .../src/analyzers/a11y/no_header_scope.rs | 12 +- .../tests/specs/a11y/noAccessKey/invalid.jsx | 8 + .../specs/a11y/noAccessKey/invalid.jsx.snap | 180 ++++++++++++++- .../tests/specs/a11y/noAutofocus/invalid.jsx | 5 +- .../specs/a11y/noAutofocus/invalid.jsx.snap | 69 +++++- .../tests/specs/a11y/noAutofocus/valid.jsx | 8 +- .../specs/a11y/noAutofocus/valid.jsx.snap | 9 +- .../specs/a11y/noBlankTarget/invalid.jsx | 19 +- .../specs/a11y/noBlankTarget/invalid.jsx.snap | 212 +++++++++++++----- .../tests/specs/a11y/noBlankTarget/valid.jsx | 41 +++- .../specs/a11y/noBlankTarget/valid.jsx.snap | 40 +++- .../a11y/noDistractingElements/invalid.jsx | 8 +- .../noDistractingElements/invalid.jsx.snap | 32 +-- crates/rome_js_syntax/src/expr_ext.rs | 12 +- crates/rome_js_syntax/src/jsx_ext.rs | 35 ++- .../src/configuration/linter/rules.rs | 4 +- editors/vscode/configuration_schema.json | 4 +- npm/backend-jsonrpc/src/workspace.ts | 4 +- npm/rome/configuration_schema.json | 4 +- website/src/pages/lint/rules/index.mdx | 4 +- website/src/pages/lint/rules/noAutofocus.md | 9 +- website/src/pages/lint/rules/noBlankTarget.md | 27 +-- .../pages/lint/rules/noDistractingElements.md | 26 ++- website/src/pages/lint/rules/noHeaderScope.md | 9 +- 28 files changed, 683 insertions(+), 327 deletions(-) diff --git a/crates/rome_js_analyze/src/analyzers/a11y/no_access_key.rs b/crates/rome_js_analyze/src/analyzers/a11y/no_access_key.rs index 8f9c9addcea..de422fc1306 100644 --- a/crates/rome_js_analyze/src/analyzers/a11y/no_access_key.rs +++ b/crates/rome_js_analyze/src/analyzers/a11y/no_access_key.rs @@ -2,10 +2,8 @@ use crate::JsRuleAction; use rome_analyze::{context::RuleContext, declare_rule, ActionCategory, Ast, Rule, RuleDiagnostic}; use rome_console::markup; use rome_diagnostics::Applicability; -use rome_js_syntax::{ - AnyJsxAttributeValue, JsxAttribute, JsxAttributeList, JsxOpeningElement, JsxSelfClosingElement, -}; -use rome_rowan::{declare_node_union, AstNode, BatchMutationExt}; +use rome_js_syntax::{jsx_ext::AnyJsxElement, JsxAttribute, JsxAttributeList}; +use rome_rowan::{AstNode, BatchMutationExt}; declare_rule! { /// Enforce that the `accessKey` attribute is not used on any HTML element. @@ -43,24 +41,6 @@ declare_rule! { } } -declare_node_union! { - pub(crate) AnyJsxElement = JsxOpeningElement | JsxSelfClosingElement -} - -impl AnyJsxElement { - /// Check if the given element is a HTML element, not a user-created React component - fn is_html_element(&self) -> Option { - Some(match self { - AnyJsxElement::JsxOpeningElement(element) => { - element.name().ok()?.as_jsx_name().is_some() - } - AnyJsxElement::JsxSelfClosingElement(element) => { - element.name().ok()?.as_jsx_name().is_some() - } - }) - } -} - impl Rule for NoAccessKey { type Query = Ast; type State = (); @@ -69,10 +49,7 @@ impl Rule for NoAccessKey { fn run(ctx: &RuleContext) -> Self::Signals { let node = ctx.query(); - let attribute_name = node.name().ok()?; - let name = attribute_name.as_jsx_name()?; - let name_token = name.value_token().ok()?; - if name_token.text_trimmed() != "accessKey" { + if node.name_value_token()?.text_trimmed() != "accessKey" { return None; } @@ -82,19 +59,13 @@ impl Rule for NoAccessKey { // We do not know if the `accessKey` prop is used for HTML elements // or for user-created React components - if !element.is_html_element()? { + if element.is_custom_component() { return None; } - let attribute_value = node.initializer()?.value().ok(); - if let Some(AnyJsxAttributeValue::JsxExpressionAttributeValue(expression)) = attribute_value - { - let expression = expression.expression().ok()?; - let name = expression.as_js_identifier_expression()?.name().ok()?; - let name_token = name.value_token().ok()?; - if name_token.text_trimmed() == "undefined" { - return None; - } + let attribute_value = node.initializer()?.value().ok()?; + if attribute_value.is_value_null_or_undefined() { + return None; } Some(()) @@ -103,20 +74,20 @@ impl Rule for NoAccessKey { fn diagnostic(ctx: &RuleContext, _state: &Self::State) -> Option { let node = ctx.query(); Some( - RuleDiagnostic::new( - rule_category!(), - node.syntax().text_trimmed_range(), - markup! { - "Avoid the ""accessKey"" attribute to reduce inconsistencies between \ - keyboard shortcuts and screen reader keyboard comments." - }, - ).note( - markup! { - "Assigning keyboard shortcuts using the ""accessKey"" attribute leads to \ - inconsistent keyboard actions across applications." - }, - ) - ) + RuleDiagnostic::new( + rule_category!(), + node.syntax().text_trimmed_range(), + markup! { + "Avoid the ""accessKey"" attribute to reduce inconsistencies between \ + keyboard shortcuts and screen reader keyboard comments." + }, + ).note( + markup! { + "Assigning keyboard shortcuts using the ""accessKey"" attribute leads to \ + inconsistent keyboard actions across applications." + }, + ) + ) } fn action(ctx: &RuleContext, _state: &Self::State) -> Option { diff --git a/crates/rome_js_analyze/src/analyzers/a11y/no_auto_focus.rs b/crates/rome_js_analyze/src/analyzers/a11y/no_auto_focus.rs index 70e4658dcd2..5da3350b9b6 100644 --- a/crates/rome_js_analyze/src/analyzers/a11y/no_auto_focus.rs +++ b/crates/rome_js_analyze/src/analyzers/a11y/no_auto_focus.rs @@ -6,7 +6,9 @@ use rome_js_syntax::{jsx_ext::AnyJsxElement, JsxAttribute}; use rome_rowan::{AstNode, BatchMutationExt}; declare_rule! { - /// Avoid the `autoFocus` attribute + /// Enforce that autoFocus prop is not used on elements. + /// + /// Autofocusing elements can cause usability issues for sighted and non-sighted users, alike. /// /// ## Examples /// @@ -46,6 +48,12 @@ declare_rule! { /// // `autoFocus` prop in user created component is valid /// ///``` + /// + /// ## Resources + /// + /// - [WHATWG HTML Standard, The autofocus attribute](https://html.spec.whatwg.org/multipage/interaction.html#attr-fe-autofocus) + /// - [The accessibility of HTML 5 autofocus](https://brucelawson.co.uk/2009/the-accessibility-of-html-5-autofocus/) + /// pub(crate) NoAutoFocus { version: "10.0.0", name: "noAutofocus", @@ -61,16 +69,11 @@ impl Rule for NoAutoFocus { fn run(ctx: &RuleContext) -> Self::Signals { let node = ctx.query(); - match node { - AnyJsxElement::JsxOpeningElement(element) => { - element.name().ok()?.as_jsx_name()?; - element.find_attribute_by_name("autoFocus").ok()? - } - AnyJsxElement::JsxSelfClosingElement(element) => { - element.name().ok()?.as_jsx_name()?; - element.find_attribute_by_name("autoFocus").ok()? - } + if node.is_custom_component() { + return None; } + + node.find_attribute_by_name("autoFocus") } fn diagnostic(_ctx: &RuleContext, attr: &Self::State) -> Option { diff --git a/crates/rome_js_analyze/src/analyzers/a11y/no_blank_target.rs b/crates/rome_js_analyze/src/analyzers/a11y/no_blank_target.rs index fb0f9c6b0f2..86365ea71e5 100644 --- a/crates/rome_js_analyze/src/analyzers/a11y/no_blank_target.rs +++ b/crates/rome_js_analyze/src/analyzers/a11y/no_blank_target.rs @@ -7,11 +7,11 @@ use rome_js_factory::make::{ jsx_attribute, jsx_attribute_initializer_clause, jsx_attribute_list, jsx_ident, jsx_name, jsx_string, token, }; +use rome_js_syntax::jsx_ext::AnyJsxElement; use rome_js_syntax::{ - AnyJsxAttribute, AnyJsxAttributeName, AnyJsxAttributeValue, JsxAttribute, JsxAttributeList, - JsxElement, JsxSelfClosingElement, T, + AnyJsxAttribute, AnyJsxAttributeName, AnyJsxAttributeValue, JsxAttribute, JsxAttributeList, T, }; -use rome_rowan::{declare_node_union, AstNode, AstNodeList, BatchMutationExt, TriviaPieceKind}; +use rome_rowan::{AstNode, AstNodeList, BatchMutationExt, TriviaPieceKind}; declare_rule! { /// Disallow `target="_blank"` attribute without `rel="noreferrer"` @@ -39,15 +39,14 @@ declare_rule! { /// child /// ``` /// - /// ```jsx,expect_diagnostic - /// // case-insensitive - /// child - /// ``` /// ### Valid /// /// ```jsx - /// let a = child; - /// let a = child; + /// child + /// ``` + /// + /// ```jsx + /// child /// ``` pub(crate) NoBlankTarget { version: "10.0.0", @@ -56,29 +55,8 @@ declare_rule! { } } -declare_node_union! { - pub(crate) NoBlankTargetQuery = JsxElement | JsxSelfClosingElement -} - -impl NoBlankTargetQuery { - fn has_trailing_spread_attribute( - &self, - current_attribute: impl Into, - ) -> Option { - Some(match self { - NoBlankTargetQuery::JsxElement(element) => element - .opening_element() - .ok()? - .has_trailing_spread_prop(current_attribute), - NoBlankTargetQuery::JsxSelfClosingElement(element) => { - element.has_trailing_spread_prop(current_attribute) - } - }) - } -} - impl Rule for NoBlankTarget { - type Query = Ast; + type Query = Ast; /// Two attributes: /// 1. The attribute `target=` /// 2. The attribute `rel=`, if present @@ -88,64 +66,34 @@ impl Rule for NoBlankTarget { fn run(ctx: &RuleContext) -> Self::Signals { let node = ctx.query(); - let (target_attribute, rel_attribute) = match node { - NoBlankTargetQuery::JsxElement(element) => { - let opening_element = element.opening_element().ok()?; - if opening_element.name().ok()?.text() != "a" - || opening_element - .find_attribute_by_name("href") - .ok() - .is_none() - { - return None; - } - - ( - opening_element.find_attribute_by_name("target").ok()?, - opening_element.find_attribute_by_name("rel").ok()?, - ) - } - NoBlankTargetQuery::JsxSelfClosingElement(element) => { - if element.name().ok()?.text() != "a" - || element.find_attribute_by_name("href").ok().is_none() - { - return None; - } - ( - element.find_attribute_by_name("target").ok()?, - element.find_attribute_by_name("rel").ok()?, - ) - } - }; - - let target_attribute = target_attribute?; + if node.name_value_token()?.text_trimmed() != "a" + || node.find_attribute_by_name("href").is_none() + { + return None; + } - let text = target_attribute - .initializer()? - .value() - .ok()? - .as_jsx_string()? - .inner_string_text() - .ok()?; + let target_attribute = node.find_attribute_by_name("target")?; + let rel_attribute = node.find_attribute_by_name("rel"); - if text.to_lowercase() == "_blank" { + if target_attribute + .as_static_value()? + .is_string_constant("_blank") + { match rel_attribute { None => { - if !node.has_trailing_spread_attribute(target_attribute.clone())? { + if !node.has_trailing_spread_prop(target_attribute.clone()) { return Some((target_attribute, None)); } } Some(rel_attribute) => { - let rel_text = rel_attribute - .initializer()? - .value() - .ok()? - .as_jsx_string()? - .inner_string_text() - .ok()?; - if !rel_text.text().contains("noreferrer") - && !node.has_trailing_spread_attribute(target_attribute.clone())? - && !node.has_trailing_spread_attribute(rel_attribute.clone())? + if rel_attribute.initializer().is_none() + || (!rel_attribute + .as_static_value()? + .text() + .split_ascii_whitespace() + .any(|f| f == "noreferrer") + && !node.has_trailing_spread_prop(target_attribute.clone()) + && !node.has_trailing_spread_prop(rel_attribute.clone())) { return Some((target_attribute, Some(rel_attribute))); } @@ -162,13 +110,13 @@ impl Rule for NoBlankTarget { ) -> Option { let mut mutation = ctx.root().begin(); let message = if let Some(rel_attribute) = rel_attribute { - let old_jsx_string = rel_attribute.initializer()?.value().ok()?; - let old_jsx_string = old_jsx_string.as_jsx_string()?; - let rel_quoted_string = old_jsx_string.inner_string_text().ok()?; - let rel_text = rel_quoted_string.text(); - let new_text = format!("\"noreferrer {rel_text}\""); - let new_jsx_string = jsx_string(jsx_ident(&new_text)); - mutation.replace_node(old_jsx_string.clone(), new_jsx_string); + let prev_jsx_attribute = rel_attribute.initializer()?.value().ok()?; + let prev_jsx_string = prev_jsx_attribute.as_jsx_string()?; + let new_text = format!( + "\"noreferrer {}\"", + prev_jsx_string.inner_string_text().ok()?.text() + ); + mutation.replace_node(prev_jsx_string.clone(), jsx_string(jsx_ident(&new_text))); (markup! { "Add the ""\"noreferrer\""" to the existing attribute." diff --git a/crates/rome_js_analyze/src/analyzers/a11y/no_distracting_elements.rs b/crates/rome_js_analyze/src/analyzers/a11y/no_distracting_elements.rs index 4e328bf99e2..9be634a1d9e 100644 --- a/crates/rome_js_analyze/src/analyzers/a11y/no_distracting_elements.rs +++ b/crates/rome_js_analyze/src/analyzers/a11y/no_distracting_elements.rs @@ -20,18 +20,23 @@ declare_rule! { /// ### Invalid /// /// ```jsx,expect_diagnostic - /// + /// /// ``` /// /// ```jsx,expect_diagnostic - /// + /// /// ``` /// /// ### Valid /// /// ```jsx - ///
+ ///
/// ``` + /// + /// ## Accessibility guidelines + /// + /// - [WCAG 2.2.2](https://www.w3.org/WAI/WCAG21/Understanding/pause-stop-hide) + /// pub(crate) NoDistractingElements { version: "11.0.0", name: "noDistractingElements", diff --git a/crates/rome_js_analyze/src/analyzers/a11y/no_header_scope.rs b/crates/rome_js_analyze/src/analyzers/a11y/no_header_scope.rs index 4765fc79018..c08d4cc8ca2 100644 --- a/crates/rome_js_analyze/src/analyzers/a11y/no_header_scope.rs +++ b/crates/rome_js_analyze/src/analyzers/a11y/no_header_scope.rs @@ -9,9 +9,7 @@ use rome_rowan::{AstNode, BatchMutationExt}; use crate::JsRuleAction; declare_rule! { - /// Check that the scope attribute is only used on `th` elements. - /// - /// ESLint Equivalent: [scope](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/master/docs/rules/scope.md) + /// The scope prop should be used only on `` elements. /// /// ## Examples /// @@ -34,6 +32,12 @@ declare_rule! { /// ```jsx /// /// ``` + /// + /// ## Accessibility guidelines + /// + /// - [WCAG 1.3.1](https://www.w3.org/WAI/WCAG21/Understanding/info-and-relationships) + /// - [WCAG 4.1.1](https://www.w3.org/WAI/WCAG21/Understanding/parsing) + /// pub(crate) NoHeaderScope { version: "11.0.0", name: "noHeaderScope", @@ -50,7 +54,7 @@ impl Rule for NoHeaderScope { fn run(ctx: &RuleContext) -> Self::Signals { let attr = ctx.query(); - if attr.name().ok()?.syntax().text_trimmed() != "scope" { + if attr.name_value_token()?.text_trimmed() != "scope" { return None; } diff --git a/crates/rome_js_analyze/tests/specs/a11y/noAccessKey/invalid.jsx b/crates/rome_js_analyze/tests/specs/a11y/noAccessKey/invalid.jsx index 4ca89f2aa8c..5f2550bba15 100644 --- a/crates/rome_js_analyze/tests/specs/a11y/noAccessKey/invalid.jsx +++ b/crates/rome_js_analyze/tests/specs/a11y/noAccessKey/invalid.jsx @@ -1,2 +1,10 @@ ; ; +
; +
; +
; +
; +
; +
; +
; +
; diff --git a/crates/rome_js_analyze/tests/specs/a11y/noAccessKey/invalid.jsx.snap b/crates/rome_js_analyze/tests/specs/a11y/noAccessKey/invalid.jsx.snap index 0bf6489dc6d..713c8cdd035 100644 --- a/crates/rome_js_analyze/tests/specs/a11y/noAccessKey/invalid.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/a11y/noAccessKey/invalid.jsx.snap @@ -6,6 +6,14 @@ expression: invalid.jsx ```js ; ; +
; +
; +
; +
; +
; +
; +
; +
; ``` @@ -18,7 +26,7 @@ invalid.jsx:1:22 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━ > 1 │ ; │ ^^^^^^^^^^^^^ 2 │ ; - 3 │ + 3 │
; i Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications. @@ -37,7 +45,8 @@ invalid.jsx:2:9 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━ 1 │ ; > 2 │ ; │ ^^^^^^^^^^^^^ - 3 │ + 3 │
; + 4 │
; i Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications. @@ -48,4 +57,171 @@ invalid.jsx:2:9 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━ ``` +``` +invalid.jsx:3:6 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the accessKey attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments. + + 1 │ ; + 2 │ ; + > 3 │
; + │ ^^^^^^^^^^^^^ + 4 │
; + 5 │
; + + i Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications. + + i Suggested fix: Remove the accessKey attribute. + + 3 │ ; + │ -------------- + +``` + +``` +invalid.jsx:4:6 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the accessKey attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments. + + 2 │ ; + 3 │
; + > 4 │
; + │ ^^^^^^^^^^^^^^^ + 5 │
; + 6 │
; + + i Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications. + + i Suggested fix: Remove the accessKey attribute. + + 4 │ ; + │ ---------------- + +``` + +``` +invalid.jsx:5:6 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the accessKey attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments. + + 3 │
; + 4 │
; + > 5 │
; + │ ^^^^^^^^^^^^^^^^^^ + 6 │
; + 7 │
; + + i Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications. + + i Suggested fix: Remove the accessKey attribute. + + 5 │ ; + │ ------------------- + +``` + +``` +invalid.jsx:6:6 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the accessKey attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments. + + 4 │
; + 5 │
; + > 6 │
; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 7 │
; + 8 │
; + + i Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications. + + i Suggested fix: Remove the accessKey attribute. + + 6 │ ; + │ ---------------------------------------- + +``` + +``` +invalid.jsx:7:6 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the accessKey attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments. + + 5 │
; + 6 │
; + > 7 │
; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 8 │
; + 9 │
; + + i Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications. + + i Suggested fix: Remove the accessKey attribute. + + 7 │ ; + │ ----------------------------- + +``` + +``` +invalid.jsx:8:6 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the accessKey attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments. + + 6 │
; + 7 │
; + > 8 │
; + │ ^^^^^^^^^^^^^^^^^^^^^ + 9 │
; + 10 │
; + + i Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications. + + i Suggested fix: Remove the accessKey attribute. + + 8 │ ; + │ ---------------------- + +``` + +``` +invalid.jsx:9:6 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the accessKey attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments. + + 7 │
; + 8 │
; + > 9 │
; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^ + 10 │
; + 11 │ + + i Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications. + + i Suggested fix: Remove the accessKey attribute. + + 9 │ ; + │ --------------------------- + +``` + +``` +invalid.jsx:10:6 lint/a11y/noAccessKey FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the accessKey attribute to reduce inconsistencies between keyboard shortcuts and screen reader keyboard comments. + + 8 │
; + 9 │
; + > 10 │
; + │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + 11 │ + + i Assigning keyboard shortcuts using the accessKey attribute leads to inconsistent keyboard actions across applications. + + i Suggested fix: Remove the accessKey attribute. + + 10 │ ; + │ --------------------------------------- + +``` + diff --git a/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/invalid.jsx b/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/invalid.jsx index cd5926cc961..f4e2b6cb22e 100644 --- a/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/invalid.jsx +++ b/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/invalid.jsx @@ -8,4 +8,7 @@ - \ No newline at end of file +
+
+
+ diff --git a/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/invalid.jsx.snap b/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/invalid.jsx.snap index 51cdd4bcfad..20d59969e24 100644 --- a/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/invalid.jsx.snap +++ b/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/invalid.jsx.snap @@ -14,7 +14,11 @@ expression: invalid.jsx +
+
+
+ ``` # Diagnostics @@ -165,7 +169,7 @@ invalid.jsx:9:12 lint/a11y/noAutofocus FIXABLE ━━━━━━━━━━ > 9 │ │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 10 │ - 11 │ + 11 │
i Suggested fix: Remove the autoFocus attribute. @@ -183,7 +187,8 @@ invalid.jsx:10:24 lint/a11y/noAutofocus FIXABLE ━━━━━━━━━━ 9 │ > 10 │ │ ^^^^^^^^^^^^^^^^^^^ - 11 │ + 11 │
+ 12 │
i Suggested fix: Remove the autoFocus attribute. @@ -191,8 +196,66 @@ invalid.jsx:10:24 lint/a11y/noAutofocus FIXABLE ━━━━━━━━━━ 9 9 │ 10 │ - ···· 10 │ + ···· - 11 11 │ + 11 11 │
+ 12 12 │
+ + +``` + +``` +invalid.jsx:11:10 lint/a11y/noAutofocus FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the autoFocus attribute. + + 9 │ + 10 │ + > 11 │
+ │ ^^^^^^^^^ + 12 │
+ 13 │
+ + i Suggested fix: Remove the autoFocus attribute. + + 11 │ ···· + │ ---------- + +``` + +``` +invalid.jsx:12:10 lint/a11y/noAutofocus FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the autoFocus attribute. + + 10 │ + 11 │
+ > 12 │
+ │ ^^^^^^^^^^^^^^^^ + 13 │
+ 14 │ + + i Suggested fix: Remove the autoFocus attribute. + + 12 │ ···· + │ ----------------- + +``` + +``` +invalid.jsx:13:10 lint/a11y/noAutofocus FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + + ! Avoid the autoFocus attribute. + + 11 │
+ 12 │
+ > 13 │
+ │ ^^^^^^^^^^^^^^^^^ + 14 │ + 15 │ + + i Suggested fix: Remove the autoFocus attribute. + 13 │ ···· + │ ------------------ ``` diff --git a/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/valid.jsx b/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/valid.jsx index 90711e8b11a..9fcd23f52ff 100644 --- a/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/valid.jsx +++ b/crates/rome_js_analyze/tests/specs/a11y/noAutofocus/valid.jsx @@ -1,6 +1,8 @@ <> -
-