Skip to content

Commit d991fed

Browse files
committed
fix(linter): fix jsx-a11y/label-has-associated-control default values (#11832)
`LabelHasAssociatedControl.from_configuration` never got called. Only the `LabelHasAssociatedControlConfig::default()`. closes #11644
1 parent a0a4aa1 commit d991fed

File tree

5 files changed

+95
-17
lines changed

5 files changed

+95
-17
lines changed
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
{
2+
"plugins": [
3+
"eslint",
4+
"import",
5+
"jsx-a11y",
6+
"nextjs",
7+
"node",
8+
"oxc",
9+
"promise",
10+
"react",
11+
"react-perf",
12+
"typescript",
13+
"unicorn"
14+
],
15+
"rules": {
16+
"import/no-default-export": 0,
17+
"no-console": 1,
18+
"react/button-has-type": 0,
19+
"react/rules-of-hooks": 2,
20+
"typescript/explicit-function-return-type": 0,
21+
"typescript/no-non-null-assertion": 0,
22+
"unicorn/filename-case": [2, { "case": "kebabCase" }],
23+
"unicorn/no-nested-ternary": 0,
24+
// "jsx-a11y/label-has-associated-control": ["warn", { "depth": 0}]
25+
}
26+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
// oxlint-disable-next-line no-unused-vars
2+
function Foo() {
3+
return (
4+
<template>
5+
<label>
6+
<span>name</span>
7+
<input
8+
defaultValue={
9+
actionState.payload?.get("name")?.toString() ?? "Pool party"
10+
}
11+
name="name"
12+
placeholder="name"
13+
type="text"
14+
/>
15+
</label>
16+
</template>
17+
)
18+
}

apps/oxlint/src/lint.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1159,4 +1159,10 @@ mod test {
11591159
let args = &["-c", ".oxlintrc.json"];
11601160
Tester::new().with_cwd("fixtures/issue_10394".into()).test_and_snapshot(args);
11611161
}
1162+
1163+
#[test]
1164+
fn test_jsx_a11y_label_has_associated_control() {
1165+
let args = &["-c", ".oxlintrc.json"];
1166+
Tester::new().with_cwd("fixtures/issue_11644".into()).test_and_snapshot(args);
1167+
}
11621168
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
source: apps/oxlint/src/tester.rs
3+
---
4+
##########
5+
arguments: -c .oxlintrc.json
6+
working directory: fixtures/issue_11644
7+
----------
8+
Found 0 warnings and 0 errors.
9+
Finished in <variable>ms on 1 file with 158 rules using 1 threads.
10+
----------
11+
CLI result: LintSucceeded
12+
----------

crates/oxc_linter/src/rules/jsx_a11y/label_has_associated_control.rs

Lines changed: 33 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -58,12 +58,20 @@ impl Deref for LabelHasAssociatedControl {
5858

5959
impl Default for LabelHasAssociatedControlConfig {
6060
fn default() -> Self {
61+
let mut control_builder = GlobSetBuilder::new();
62+
control_builder.add(Glob::new("input").unwrap());
63+
control_builder.add(Glob::new("meter").unwrap());
64+
control_builder.add(Glob::new("output").unwrap());
65+
control_builder.add(Glob::new("progress").unwrap());
66+
control_builder.add(Glob::new("select").unwrap());
67+
control_builder.add(Glob::new("textarea").unwrap());
68+
6169
Self {
6270
depth: 2,
6371
assert: Assert::Either,
6472
label_components: vec!["label".into()],
6573
label_attributes: vec!["alt".into(), "aria-label".into(), "aria-labelledby".into()],
66-
control_components: GlobSet::empty(),
74+
control_components: control_builder.build().unwrap(),
6775
}
6876
}
6977
}
@@ -114,16 +122,7 @@ impl Rule for LabelHasAssociatedControl {
114122
fn from_configuration(value: serde_json::Value) -> Self {
115123
let mut config = LabelHasAssociatedControlConfig::default();
116124

117-
let mut control_builder = GlobSetBuilder::new();
118-
control_builder.add(Glob::new("input").unwrap());
119-
control_builder.add(Glob::new("meter").unwrap());
120-
control_builder.add(Glob::new("output").unwrap());
121-
control_builder.add(Glob::new("progress").unwrap());
122-
control_builder.add(Glob::new("select").unwrap());
123-
control_builder.add(Glob::new("textarea").unwrap());
124-
125125
let Some(options) = value.get(0) else {
126-
config.control_components = control_builder.build().unwrap();
127126
return Self(Box::new(config));
128127
};
129128

@@ -166,6 +165,14 @@ impl Rule for LabelHasAssociatedControl {
166165
}
167166
}
168167

168+
let mut control_builder = GlobSetBuilder::new();
169+
control_builder.add(Glob::new("input").unwrap());
170+
control_builder.add(Glob::new("meter").unwrap());
171+
control_builder.add(Glob::new("output").unwrap());
172+
control_builder.add(Glob::new("progress").unwrap());
173+
control_builder.add(Glob::new("select").unwrap());
174+
control_builder.add(Glob::new("textarea").unwrap());
175+
169176
if let Some(control_components) =
170177
options.get("controlComponents").and_then(serde_json::Value::as_array)
171178
{
@@ -185,13 +192,6 @@ impl Rule for LabelHasAssociatedControl {
185192
config.control_components = if let Ok(controls) = control_builder.build() {
186193
controls
187194
} else {
188-
let mut control_builder = GlobSetBuilder::new();
189-
control_builder.add(Glob::new("input").unwrap());
190-
control_builder.add(Glob::new("meter").unwrap());
191-
control_builder.add(Glob::new("output").unwrap());
192-
control_builder.add(Glob::new("progress").unwrap());
193-
control_builder.add(Glob::new("select").unwrap());
194-
control_builder.add(Glob::new("textarea").unwrap());
195195
control_builder.build().unwrap()
196196
};
197197

@@ -918,6 +918,22 @@ fn test() {
918918
),
919919
// Issue: <https://github.com/oxc-project/oxc/issues/7849>
920920
("<FilesContext.Provider value={{ addAlert, cwdInfo }} />", None, None),
921+
// Issue: <https://github.com/oxc-project/oxc/issues/11644>
922+
(
923+
r#"<label>
924+
<span>name</span>
925+
<input
926+
defaultValue={
927+
actionState.payload?.get("name")?.toString() ?? "Pool party"
928+
}
929+
name="name"
930+
placeholder="name"
931+
type="text"
932+
/>
933+
</label>"#,
934+
None,
935+
None,
936+
),
921937
];
922938

923939
let fail = vec![

0 commit comments

Comments
 (0)