Skip to content

Commit ab46187

Browse files
authored
docs(linter): Add configuration docs for 6 react rules. (#15198)
Part of #14743. - react/jsx-fragments - react/jsx-filename-extension - react/style-prop-object - react/jsx-curly-brace-presence - react/jsx-no-script-url - react/jsx-pascal-case Generated docs: ```md ## Configuration This rule accepts a configuration object with the following properties: ### allow type: `"always" | "as-needed"` default: `"always"` When to allow a JSX filename extension. By default all files may have a JSX extension. Set this to `as-needed` to only allow JSX file extensions in files that contain JSX syntax. ### extensions type: `string[]` default: `["jsx"]` The set of allowed file extensions. ### ignoreFilesWithoutCode type: `boolean` default: `false` If enabled, files that do not contain code (i.e. are empty, contain only whitespaces or comments) will not be rejected. ``` ```md ## Configuration This rule accepts a configuration object with the following properties: ### children type: `"always" | "never" | "ignore"` default: `"never"` ### propElementValues type: `"always" | "never" | "ignore"` default: `"ignore"` ### props type: `"always" | "never" | "ignore"` default: `"never"` ``` ```md ## Configuration This rule accepts a configuration object with the following properties: ### components type: `Record<string, array>` default: `{}` Additional components to check. ### includeFromSettings type: `boolean` default: `false` Whether to include components from settings. ``` ```md ## Configuration This rule accepts a configuration object with the following properties: ### allowAllCaps type: `boolean` default: `false` Whether to allow all-caps component names. ### allowLeadingUnderscore type: `boolean` default: `false` Whether to allow leading underscores in component names. ### allowNamespace type: `boolean` default: `false` Whether to allow namespaced component names. ### ignore type: `string[]` default: `[]` List of component names to ignore. ``` ```md ## Configuration This rule accepts a configuration object with the following properties: ### mode type: `"syntax" | "element"` default: `"syntax"` `syntax` mode: This is the default mode. It will enforce the shorthand syntax for React fragments, with one exception. Keys or attributes are not supported by the shorthand syntax, so the rule will not warn on standard-form fragments that use those. Examples of **incorrect** code for this rule: \```jsx <React.Fragment><Foo /></React.Fragment> \``` Examples of **correct** code for this rule: \```jsx <><Foo /></> \``` \```jsx <React.Fragment key="key"><Foo /></React.Fragment> \``` `element` mode: This mode enforces the standard form for React fragments. Examples of **incorrect** code for this rule: \```jsx <><Foo /></> \``` Examples of **correct** code for this rule: \```jsx <React.Fragment><Foo /></React.Fragment> \``` \```jsx <React.Fragment key="key"><Foo /></React.Fragment> \``` ``` ```md ## Configuration This rule accepts a configuration object with the following properties: ### allow type: `string[]` default: `[]` List of component names on which to allow style prop values of any type. ```
1 parent 51c8724 commit ab46187

File tree

6 files changed

+76
-102
lines changed

6 files changed

+76
-102
lines changed

crates/oxc_linter/src/rules/react/jsx_curly_brace_presence.rs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use oxc_diagnostics::{Error, LabeledSpan, OxcDiagnostic};
1818
use oxc_macros::declare_oxc_lint;
1919
use oxc_semantic::NodeId;
2020
use oxc_span::{GetSpan as _, Span};
21+
use schemars::JsonSchema;
22+
use serde::{Deserialize, Serialize};
2123
use serde_json::Value;
2224

2325
fn jsx_curly_brace_presence_unnecessary_diagnostic(span: Span) -> OxcDiagnostic {
@@ -32,7 +34,8 @@ fn jsx_curly_brace_presence_necessary_diagnostic(span: Span) -> OxcDiagnostic {
3234
)])
3335
}
3436

35-
#[derive(Debug, Default, Clone, Copy)]
37+
#[derive(Debug, Default, Clone, Copy, JsonSchema, Deserialize, Serialize)]
38+
#[serde(rename_all = "kebab-case")]
3639
enum Allowed {
3740
Always,
3841
Never,
@@ -64,7 +67,8 @@ impl Allowed {
6467
}
6568
}
6669

67-
#[derive(Debug, Clone)]
70+
#[derive(Debug, Clone, JsonSchema, Deserialize, Serialize)]
71+
#[serde(rename_all = "camelCase", default)]
6872
pub struct JsxCurlyBracePresence {
6973
props: Allowed,
7074
children: Allowed,
@@ -82,12 +86,10 @@ impl Default for JsxCurlyBracePresence {
8286
}
8387

8488
declare_oxc_lint!(
85-
/// # Disallow unnecessary JSX expressions when literals alone are
89+
/// Disallow unnecessary JSX expressions when literals alone are
8690
/// sufficient or enforce JSX expressions on literals in JSX children or
8791
/// attributes (`react/jsx-curly-brace-presence`)
8892
///
89-
/// 🔧 This rule is automatically fixable by the [`--fix` CLI option](https://oxc-project.github.io/docs/guide/usage/linter/cli.html#fix-problems).
90-
///
9193
/// This rule allows you to enforce curly braces or disallow unnecessary
9294
/// curly braces in JSX props and/or children.
9395
///
@@ -300,7 +302,8 @@ declare_oxc_lint!(
300302
JsxCurlyBracePresence,
301303
react,
302304
style,
303-
fix
305+
fix,
306+
config = JsxCurlyBracePresence,
304307
);
305308

306309
impl Rule for JsxCurlyBracePresence {

crates/oxc_linter/src/rules/react/jsx_filename_extension.rs

Lines changed: 12 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ use oxc_ast::AstKind;
66
use oxc_diagnostics::OxcDiagnostic;
77
use oxc_macros::declare_oxc_lint;
88
use oxc_span::{CompactStr, GetSpan, Span};
9+
use schemars::JsonSchema;
10+
use serde::{Deserialize, Serialize};
911

1012
use crate::{context::LintContext, rule::Rule};
1113

@@ -22,7 +24,8 @@ fn extension_only_for_jsx_diagnostic(ext: &str) -> OxcDiagnostic {
2224
.with_help("Rename the file with a good extension.")
2325
}
2426

25-
#[derive(Debug, Default, Clone)]
27+
#[derive(Debug, Default, Clone, JsonSchema, Deserialize, Serialize)]
28+
#[serde(rename_all = "kebab-case")]
2629
enum AllowType {
2730
#[default]
2831
Always,
@@ -41,10 +44,15 @@ impl AllowType {
4144
#[derive(Debug, Default, Clone)]
4245
pub struct JsxFilenameExtension(Box<JsxFilenameExtensionConfig>);
4346

44-
#[derive(Debug, Clone)]
47+
#[derive(Debug, Clone, JsonSchema, Deserialize, Serialize)]
48+
#[serde(rename_all = "camelCase", default)]
4549
pub struct JsxFilenameExtensionConfig {
50+
/// When to allow a JSX filename extension. By default all files may have a JSX extension.
51+
/// Set this to `as-needed` to only allow JSX file extensions in files that contain JSX syntax.
4652
allow: AllowType,
53+
/// The set of allowed file extensions.
4754
extensions: Vec<CompactStr>,
55+
/// If enabled, files that do not contain code (i.e. are empty, contain only whitespaces or comments) will not be rejected.
4856
ignore_files_without_code: bool,
4957
}
5058

@@ -92,37 +100,11 @@ declare_oxc_lint!(
92100
/// return <div />;
93101
/// }
94102
/// ```
95-
///
96-
/// ### Rule options
97-
///
98-
/// #### `allow` (default: `"always"`)
99-
/// When to allow a JSX filename extension. By default all files may have a JSX extension.
100-
/// Set this to `as-needed` to only allow JSX file extensions in files that contain JSX syntax.
101-
/// ```js
102-
/// "rules": {
103-
/// "react/jsx-filename-extension": ["error", { "allow": "as-needed" }]
104-
/// }
105-
/// ```
106-
///
107-
/// #### `extensions` (default: `[".jsx"]`)
108-
/// The set of allowed extensions is configurable. By default `'.jsx'` is allowed. If you wanted to allow both `'.jsx'` and `'.tsx'`, the configuration would be:
109-
/// ```js
110-
/// "rules": {
111-
/// "react/jsx-filename-extension": ["error", { "extensions": [".jsx", ".tsx"] }]
112-
/// }
113-
/// ```
114-
///
115-
/// #### `ignoreFilesWithoutCode` (default: `false`)
116-
/// If enabled, files that do not contain code (i.e. are empty, contain only whitespaces or comments) will not be rejected.
117-
/// ```js
118-
/// "rules": {
119-
/// "react/jsx-filename-extension": ["error", { "ignoreFilesWithoutCode": true }]
120-
/// }
121-
/// ```
122103
JsxFilenameExtension,
123104
react,
124105
restriction,
125-
pending
106+
pending,
107+
config = JsxFilenameExtensionConfig,
126108
);
127109

128110
impl Rule for JsxFilenameExtension {

crates/oxc_linter/src/rules/react/jsx_fragments.rs

Lines changed: 33 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ use oxc_ast::AstKind;
22
use oxc_diagnostics::OxcDiagnostic;
33
use oxc_macros::declare_oxc_lint;
44
use oxc_span::{GetSpan, Span};
5+
use schemars::JsonSchema;
6+
use serde::{Deserialize, Serialize};
57
use serde_json::Value;
68

79
use crate::{AstNode, context::LintContext, rule::Rule, utils::is_jsx_fragment};
@@ -20,38 +22,11 @@ fn jsx_fragments_diagnostic(span: Span, mode: FragmentMode) -> OxcDiagnostic {
2022
OxcDiagnostic::warn(msg).with_help(help).with_label(span)
2123
}
2224

23-
#[derive(Debug, Default, Clone)]
25+
#[derive(Debug, Default, Clone, JsonSchema, Deserialize, Serialize)]
26+
#[serde(rename_all = "camelCase", default)]
2427
pub struct JsxFragments {
25-
mode: FragmentMode,
26-
}
27-
28-
#[derive(Debug, Default, Clone, PartialEq, Eq, Copy)]
29-
pub enum FragmentMode {
30-
#[default]
31-
Syntax,
32-
Element,
33-
}
34-
35-
impl From<&str> for FragmentMode {
36-
fn from(value: &str) -> Self {
37-
if value == "element" { Self::Element } else { Self::Syntax }
38-
}
39-
}
40-
41-
declare_oxc_lint!(
42-
/// ### What it does
43-
///
44-
/// Enforces the shorthand or standard form for React Fragments.
45-
///
46-
/// ### Why is this bad?
47-
///
48-
/// Makes code using fragments more consistent one way or the other.
49-
///
50-
/// ### Options
28+
/// `syntax` mode:
5129
///
52-
/// `{ "mode": "syntax" | "element" }`
53-
///
54-
/// #### `syntax` mode
5530
/// This is the default mode. It will enforce the shorthand syntax for React fragments, with one exception.
5631
/// Keys or attributes are not supported by the shorthand syntax, so the rule will not warn on standard-form fragments that use those.
5732
///
@@ -69,7 +44,7 @@ declare_oxc_lint!(
6944
/// <React.Fragment key="key"><Foo /></React.Fragment>
7045
/// ```
7146
///
72-
/// #### `element` mode
47+
/// `element` mode:
7348
/// This mode enforces the standard form for React fragments.
7449
///
7550
/// Examples of **incorrect** code for this rule:
@@ -85,10 +60,36 @@ declare_oxc_lint!(
8560
/// ```jsx
8661
/// <React.Fragment key="key"><Foo /></React.Fragment>
8762
/// ```
63+
mode: FragmentMode,
64+
}
65+
66+
#[derive(Debug, Default, Clone, PartialEq, Eq, Copy, JsonSchema, Deserialize, Serialize)]
67+
#[serde(rename_all = "kebab-case")]
68+
pub enum FragmentMode {
69+
#[default]
70+
Syntax,
71+
Element,
72+
}
73+
74+
impl From<&str> for FragmentMode {
75+
fn from(value: &str) -> Self {
76+
if value == "element" { Self::Element } else { Self::Syntax }
77+
}
78+
}
79+
80+
declare_oxc_lint!(
81+
/// ### What it does
82+
///
83+
/// Enforces the shorthand or standard form for React Fragments.
84+
///
85+
/// ### Why is this bad?
86+
///
87+
/// Makes code using fragments more consistent one way or the other.
8888
JsxFragments,
8989
react,
9090
style,
91-
fix
91+
fix,
92+
config = JsxFragments,
9293
);
9394

9495
impl Rule for JsxFragments {

crates/oxc_linter/src/rules/react/jsx_no_script_url.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use lazy_regex::{Lazy, Regex, lazy_regex};
22
use rustc_hash::FxHashMap;
3+
use schemars::JsonSchema;
34
use serde_json::Value;
45

56
use oxc_ast::{AstKind, ast::JSXAttributeItem};
@@ -14,7 +15,6 @@ use crate::{
1415
};
1516

1617
fn jsx_no_script_url_diagnostic(span: Span) -> OxcDiagnostic {
17-
// See <https://oxc.rs/docs/contribute/linter/adding-rules.html#diagnostics> for details
1818
OxcDiagnostic::warn("A future version of React will block javascript: URLs as a security precaution.")
1919
.with_help("Use event handlers instead if you can. If you need to generate unsafe HTML, try using dangerouslySetInnerHTML instead.")
2020
.with_label(span)
@@ -27,9 +27,12 @@ static JS_SCRIPT_REGEX: Lazy<Regex> = lazy_regex!(
2727
#[derive(Debug, Default, Clone)]
2828
pub struct JsxNoScriptUrl(Box<JsxNoScriptUrlConfig>);
2929

30-
#[derive(Debug, Default, Clone)]
30+
#[derive(Debug, Default, Clone, JsonSchema)]
31+
#[serde(rename_all = "camelCase", default)]
3132
pub struct JsxNoScriptUrlConfig {
33+
/// Whether to include components from settings.
3234
include_from_settings: bool,
35+
/// Additional components to check.
3336
components: FxHashMap<String, Vec<String>>,
3437
}
3538

@@ -66,7 +69,8 @@ declare_oxc_lint!(
6669
JsxNoScriptUrl,
6770
react,
6871
suspicious,
69-
pending
72+
pending,
73+
config = JsxNoScriptUrlConfig,
7074
);
7175

7276
fn is_link_attribute(tag_name: &str, prop_value_literal: String, ctx: &LintContext) -> bool {

crates/oxc_linter/src/rules/react/jsx_pascal_case.rs

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use oxc_ast::{AstKind, ast::JSXElementName};
33
use oxc_diagnostics::OxcDiagnostic;
44
use oxc_macros::declare_oxc_lint;
55
use oxc_span::{CompactStr, Span};
6+
use schemars::JsonSchema;
67

78
use crate::{AstNode, context::LintContext, rule::Rule};
89

@@ -23,11 +24,16 @@ fn jsx_pascal_case_diagnostic(
2324
#[derive(Debug, Default, Clone)]
2425
pub struct JsxPascalCase(Box<JsxPascalCaseConfig>);
2526

26-
#[derive(Debug, Default, Clone)]
27+
#[derive(Debug, Default, Clone, JsonSchema)]
28+
#[serde(rename_all = "camelCase", default)]
2729
pub struct JsxPascalCaseConfig {
30+
/// Whether to allow all-caps component names.
2831
pub allow_all_caps: bool,
32+
/// Whether to allow namespaced component names.
2933
pub allow_namespace: bool,
34+
/// Whether to allow leading underscores in component names.
3035
pub allow_leading_underscore: bool,
36+
/// List of component names to ignore.
3137
pub ignore: Vec<CompactStr>,
3238
}
3339

@@ -92,36 +98,10 @@ declare_oxc_lint!(
9298
/// <div />
9399
/// </_AllowedComponent>
94100
/// ```
95-
///
96-
/// ### Options
97-
///
98-
/// #### allowAllCaps
99-
///
100-
/// `{ type: boolean, default: false }`
101-
///
102-
/// Optional boolean set to true to allow components name in all caps
103-
///
104-
/// #### allowLeadingUnderscore
105-
///
106-
/// `{ type: boolean, default: false }`
107-
///
108-
/// Optional boolean set to true to allow components name with that starts with an underscore
109-
///
110-
/// #### allowNamespace
111-
///
112-
/// `{ type: boolean, default: false }`
113-
///
114-
/// Optional boolean set to true to ignore namespaced components
115-
///
116-
/// #### ignore
117-
///
118-
/// `{ type: Array<string | RegExp>, default: [] }`
119-
///
120-
/// Optional string-array of component names to ignore during validation
121-
///
122101
JsxPascalCase,
123102
react,
124-
style
103+
style,
104+
config = JsxPascalCaseConfig,
125105
);
126106

127107
impl Rule for JsxPascalCase {

crates/oxc_linter/src/rules/react/style_prop_object.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use oxc_ast::{
88
use oxc_diagnostics::OxcDiagnostic;
99
use oxc_macros::declare_oxc_lint;
1010
use oxc_span::{CompactStr, GetSpan, Span};
11+
use schemars::JsonSchema;
1112

1213
use crate::{
1314
AstNode,
@@ -24,8 +25,10 @@ fn style_prop_object_diagnostic(span: Span) -> OxcDiagnostic {
2425
#[derive(Debug, Default, Clone)]
2526
pub struct StylePropObject(Box<StylePropObjectConfig>);
2627

27-
#[derive(Debug, Default, Clone)]
28+
#[derive(Debug, Default, Clone, JsonSchema)]
29+
#[serde(rename_all = "camelCase", default)]
2830
pub struct StylePropObjectConfig {
31+
/// List of component names on which to allow style prop values of any type.
2932
allow: Vec<CompactStr>,
3033
}
3134

@@ -77,7 +80,8 @@ declare_oxc_lint!(
7780
/// ```
7881
StylePropObject,
7982
react,
80-
suspicious
83+
suspicious,
84+
config = StylePropObjectConfig,
8185
);
8286

8387
fn is_invalid_type(ty: &TSType) -> bool {

0 commit comments

Comments
 (0)