From df143ca7bb4f695b2b93f8c6946b75d0369da6d9 Mon Sep 17 00:00:00 2001 From: DonIsaac <22823424+DonIsaac@users.noreply.github.com> Date: Thu, 21 Nov 2024 08:08:30 +0000 Subject: [PATCH] docs(linter): add docs for config settings (#4827) --- .../src/config/settings/jsx_a11y.rs | 36 +++++++++++- crates/oxc_linter/src/config/settings/mod.rs | 29 +++++++++- crates/oxc_linter/src/config/settings/next.rs | 17 ++++++ .../oxc_linter/src/config/settings/react.rs | 43 ++++++++++++++- .../oxc_linter/src/snapshots/schema_json.snap | 11 +++- npm/oxlint/configuration_schema.json | 11 +++- .../src/linter/snapshots/schema_markdown.snap | 55 ++++++++++++++++++- 7 files changed, 195 insertions(+), 7 deletions(-) diff --git a/crates/oxc_linter/src/config/settings/jsx_a11y.rs b/crates/oxc_linter/src/config/settings/jsx_a11y.rs index be81c6d17896d..e2744ee5ba8c3 100644 --- a/crates/oxc_linter/src/config/settings/jsx_a11y.rs +++ b/crates/oxc_linter/src/config/settings/jsx_a11y.rs @@ -3,12 +3,46 @@ use rustc_hash::FxHashMap; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -// +/// Configure JSX A11y plugin rules. +/// +/// See +/// [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#configurations)'s +/// configuration for a full reference. #[derive(Debug, Clone, Deserialize, Default, Serialize, JsonSchema)] #[cfg_attr(test, derive(PartialEq))] pub struct JSXA11yPluginSettings { + /// An optional setting that define the prop your code uses to create polymorphic components. + /// This setting will be used to determine the element type in rules that + /// require semantic context. + /// + /// For example, if you set the `polymorphicPropName` to `as`, then this element: + /// + /// ```jsx + /// Hello + /// ``` + /// + /// Will be treated as an `h3`. If not set, this component will be treated + /// as a `Box`. #[serde(rename = "polymorphicPropName")] pub polymorphic_prop_name: Option, + + /// To have your custom components be checked as DOM elements, you can + /// provide a mapping of your component names to the DOM element name. + /// + /// ## Example + /// + /// ```json + /// { + /// "settings": { + /// "jsx-a11y": { + /// "components": { + /// "Link": "a", + /// "IconButton": "button" + /// } + /// } + /// } + /// } + /// ``` #[serde(default)] pub components: FxHashMap, } diff --git a/crates/oxc_linter/src/config/settings/mod.rs b/crates/oxc_linter/src/config/settings/mod.rs index 6cc38c0a83ed4..0aed87547a34c 100644 --- a/crates/oxc_linter/src/config/settings/mod.rs +++ b/crates/oxc_linter/src/config/settings/mod.rs @@ -11,7 +11,34 @@ use self::{ react::ReactPluginSettings, }; -/// Shared settings for plugins +/// # Oxlint Plugin Settings +/// +/// Configure the behavior of linter plugins. +/// +/// ## Example +/// +/// Here's an example if you're using Next.js in a monorepo: +/// +/// ```json +/// { +/// "settings": { +/// "next": { +/// "rootDir": "apps/dashboard/" +/// }, +/// "react": { +/// "linkComponents": [ +/// { "name": "Link", "linkAttribute": "to" } +/// ] +/// }, +/// "jsx-a11y": { +/// "components": { +/// "Link": "a", +/// "Button": "button" +/// } +/// } +/// } +/// } +/// ``` #[derive(Debug, Clone, Deserialize, Serialize, Default, JsonSchema)] #[cfg_attr(test, derive(PartialEq))] pub struct OxlintSettings { diff --git a/crates/oxc_linter/src/config/settings/next.rs b/crates/oxc_linter/src/config/settings/next.rs index e9bde3d9dcf9b..7e0f1b31e9193 100644 --- a/crates/oxc_linter/src/config/settings/next.rs +++ b/crates/oxc_linter/src/config/settings/next.rs @@ -3,9 +3,26 @@ use std::borrow::Cow; use schemars::JsonSchema; use serde::{Deserialize, Serialize, Serializer}; +/// Configure Next.js plugin rules. #[derive(Debug, Clone, Deserialize, Default, Serialize, JsonSchema)] #[cfg_attr(test, derive(PartialEq))] pub struct NextPluginSettings { + /// The root directory of the Next.js project. + /// + /// This is particularly useful when you have a monorepo and your Next.js + /// project is in a subfolder. + /// + /// ## Example + /// + /// ```json + /// { + /// "settings": { + /// "next": { + /// "rootDir": "apps/dashboard/" + /// } + /// } + /// } + /// ``` #[serde(default)] #[serde(rename = "rootDir")] root_dir: OneOrMany, diff --git a/crates/oxc_linter/src/config/settings/react.rs b/crates/oxc_linter/src/config/settings/react.rs index 770b71a15add9..0432189c7d2d1 100644 --- a/crates/oxc_linter/src/config/settings/react.rs +++ b/crates/oxc_linter/src/config/settings/react.rs @@ -4,14 +4,55 @@ use oxc_span::CompactStr; use schemars::JsonSchema; use serde::{Deserialize, Serialize}; -// +/// Configure React plugin rules. +/// +/// Derived from [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react#configuration-legacy-eslintrc-) #[derive(Debug, Clone, Deserialize, Default, Serialize, JsonSchema)] #[cfg_attr(test, derive(PartialEq))] pub struct ReactPluginSettings { + /// Components used as alternatives to `
` for forms, such as ``. + /// + /// ## Example + /// + /// ```jsonc + /// { + /// "settings": { + /// "react": { + /// "formComponents": [ + /// "CustomForm", + /// // OtherForm is considered a form component and has an endpoint attribute + /// { "name": "OtherForm", "formAttribute": "endpoint" }, + /// // allows specifying multiple properties if necessary + /// { "name": "Form", "formAttribute": ["registerEndpoint", "loginEndpoint"] } + /// ] + /// } + /// } + /// } + /// ``` #[serde(default)] #[serde(rename = "formComponents")] form_components: Vec, + /// Components used as alternatives to `` for linking, such as ``. + /// + /// ## Example + /// + /// ```jsonc + /// { + /// "settings": { + /// "react": { + /// "linkComponents": [ + /// "HyperLink", + /// // Use `linkAttribute` for components that use a different prop name + /// // than `href`. + /// { "name": "MyLink", "linkAttribute": "to" }, + /// // allows specifying multiple properties if necessary + /// { "name": "Link", "linkAttribute": ["to", "href"] } + /// ] + /// } + /// } + /// } + /// ``` #[serde(default)] #[serde(rename = "linkComponents")] link_components: Vec, diff --git a/crates/oxc_linter/src/snapshots/schema_json.snap b/crates/oxc_linter/src/snapshots/schema_json.snap index 37bbd50691bf8..2e159c9487d35 100644 --- a/crates/oxc_linter/src/snapshots/schema_json.snap +++ b/crates/oxc_linter/src/snapshots/schema_json.snap @@ -241,9 +241,11 @@ snapshot_kind: text } }, "JSXA11yPluginSettings": { + "description": "Configure JSX A11y plugin rules.\n\nSee [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#configurations)'s configuration for a full reference.", "type": "object", "properties": { "components": { + "description": "To have your custom components be checked as DOM elements, you can provide a mapping of your component names to the DOM element name.\n\n## Example\n\n```json { \"settings\": { \"jsx-a11y\": { \"components\": { \"Link\": \"a\", \"IconButton\": \"button\" } } } } ```", "default": {}, "type": "object", "additionalProperties": { @@ -251,6 +253,7 @@ snapshot_kind: text } }, "polymorphicPropName": { + "description": "An optional setting that define the prop your code uses to create polymorphic components. This setting will be used to determine the element type in rules that require semantic context.\n\nFor example, if you set the `polymorphicPropName` to `as`, then this element:\n\n```jsx Hello ```\n\nWill be treated as an `h3`. If not set, this component will be treated as a `Box`.", "type": [ "string", "null" @@ -265,9 +268,11 @@ snapshot_kind: text } }, "NextPluginSettings": { + "description": "Configure Next.js plugin rules.", "type": "object", "properties": { "rootDir": { + "description": "The root directory of the Next.js project.\n\nThis is particularly useful when you have a monorepo and your Next.js project is in a subfolder.\n\n## Example\n\n```json { \"settings\": { \"next\": { \"rootDir\": \"apps/dashboard/\" } } } ```", "default": [], "allOf": [ { @@ -383,7 +388,8 @@ snapshot_kind: text "$ref": "#/definitions/DummyRuleMap" }, "OxlintSettings": { - "description": "Shared settings for plugins", + "title": "Oxlint Plugin Settings", + "description": "Configure the behavior of linter plugins.\n\n## Example\n\nHere's an example if you're using Next.js in a monorepo:\n\n```json { \"settings\": { \"next\": { \"rootDir\": \"apps/dashboard/\" }, \"react\": { \"linkComponents\": [ { \"name\": \"Link\", \"linkAttribute\": \"to\" } ] }, \"jsx-a11y\": { \"components\": { \"Link\": \"a\", \"Button\": \"button\" } } } } ```", "type": "object", "properties": { "jsdoc": { @@ -438,9 +444,11 @@ snapshot_kind: text } }, "ReactPluginSettings": { + "description": "Configure React plugin rules.\n\nDerived from [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react#configuration-legacy-eslintrc-)", "type": "object", "properties": { "formComponents": { + "description": "Components used as alternatives to `` for forms, such as ``.\n\n## Example\n\n```jsonc { \"settings\": { \"react\": { \"formComponents\": [ \"CustomForm\", // OtherForm is considered a form component and has an endpoint attribute { \"name\": \"OtherForm\", \"formAttribute\": \"endpoint\" }, // allows specifying multiple properties if necessary { \"name\": \"Form\", \"formAttribute\": [\"registerEndpoint\", \"loginEndpoint\"] } ] } } } ```", "default": [], "type": "array", "items": { @@ -448,6 +456,7 @@ snapshot_kind: text } }, "linkComponents": { + "description": "Components used as alternatives to `` for linking, such as ``.\n\n## Example\n\n```jsonc { \"settings\": { \"react\": { \"linkComponents\": [ \"HyperLink\", // Use `linkAttribute` for components that use a different prop name // than `href`. { \"name\": \"MyLink\", \"linkAttribute\": \"to\" }, // allows specifying multiple properties if necessary { \"name\": \"Link\", \"linkAttribute\": [\"to\", \"href\"] } ] } } } ```", "default": [], "type": "array", "items": { diff --git a/npm/oxlint/configuration_schema.json b/npm/oxlint/configuration_schema.json index ab64f15e56b3b..2a1452e8de273 100644 --- a/npm/oxlint/configuration_schema.json +++ b/npm/oxlint/configuration_schema.json @@ -236,9 +236,11 @@ } }, "JSXA11yPluginSettings": { + "description": "Configure JSX A11y plugin rules.\n\nSee [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#configurations)'s configuration for a full reference.", "type": "object", "properties": { "components": { + "description": "To have your custom components be checked as DOM elements, you can provide a mapping of your component names to the DOM element name.\n\n## Example\n\n```json { \"settings\": { \"jsx-a11y\": { \"components\": { \"Link\": \"a\", \"IconButton\": \"button\" } } } } ```", "default": {}, "type": "object", "additionalProperties": { @@ -246,6 +248,7 @@ } }, "polymorphicPropName": { + "description": "An optional setting that define the prop your code uses to create polymorphic components. This setting will be used to determine the element type in rules that require semantic context.\n\nFor example, if you set the `polymorphicPropName` to `as`, then this element:\n\n```jsx Hello ```\n\nWill be treated as an `h3`. If not set, this component will be treated as a `Box`.", "type": [ "string", "null" @@ -260,9 +263,11 @@ } }, "NextPluginSettings": { + "description": "Configure Next.js plugin rules.", "type": "object", "properties": { "rootDir": { + "description": "The root directory of the Next.js project.\n\nThis is particularly useful when you have a monorepo and your Next.js project is in a subfolder.\n\n## Example\n\n```json { \"settings\": { \"next\": { \"rootDir\": \"apps/dashboard/\" } } } ```", "default": [], "allOf": [ { @@ -378,7 +383,8 @@ "$ref": "#/definitions/DummyRuleMap" }, "OxlintSettings": { - "description": "Shared settings for plugins", + "title": "Oxlint Plugin Settings", + "description": "Configure the behavior of linter plugins.\n\n## Example\n\nHere's an example if you're using Next.js in a monorepo:\n\n```json { \"settings\": { \"next\": { \"rootDir\": \"apps/dashboard/\" }, \"react\": { \"linkComponents\": [ { \"name\": \"Link\", \"linkAttribute\": \"to\" } ] }, \"jsx-a11y\": { \"components\": { \"Link\": \"a\", \"Button\": \"button\" } } } } ```", "type": "object", "properties": { "jsdoc": { @@ -433,9 +439,11 @@ } }, "ReactPluginSettings": { + "description": "Configure React plugin rules.\n\nDerived from [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react#configuration-legacy-eslintrc-)", "type": "object", "properties": { "formComponents": { + "description": "Components used as alternatives to `` for forms, such as ``.\n\n## Example\n\n```jsonc { \"settings\": { \"react\": { \"formComponents\": [ \"CustomForm\", // OtherForm is considered a form component and has an endpoint attribute { \"name\": \"OtherForm\", \"formAttribute\": \"endpoint\" }, // allows specifying multiple properties if necessary { \"name\": \"Form\", \"formAttribute\": [\"registerEndpoint\", \"loginEndpoint\"] } ] } } } ```", "default": [], "type": "array", "items": { @@ -443,6 +451,7 @@ } }, "linkComponents": { + "description": "Components used as alternatives to `` for linking, such as ``.\n\n## Example\n\n```jsonc { \"settings\": { \"react\": { \"linkComponents\": [ \"HyperLink\", // Use `linkAttribute` for components that use a different prop name // than `href`. { \"name\": \"MyLink\", \"linkAttribute\": \"to\" }, // allows specifying multiple properties if necessary { \"name\": \"Link\", \"linkAttribute\": [\"to\", \"href\"] } ] } } } ```", "default": [], "type": "array", "items": { diff --git a/tasks/website/src/linter/snapshots/schema_markdown.snap b/tasks/website/src/linter/snapshots/schema_markdown.snap index 0e832d15d2757..fcda4fbef941e 100644 --- a/tasks/website/src/linter/snapshots/schema_markdown.snap +++ b/tasks/website/src/linter/snapshots/schema_markdown.snap @@ -1,6 +1,7 @@ --- source: tasks/website/src/linter/json_schema.rs expression: snapshot +snapshot_kind: text --- # Oxlint Configuration File @@ -214,7 +215,35 @@ See [Oxlint Rules](https://oxc.rs/docs/guide/usage/linter/rules.html) type: `object` -Shared settings for plugins +Configure the behavior of linter plugins. + +## Example + +Here's an example if you're using Next.js in a monorepo: + +```json +{ + "settings": { + "next": { + "rootDir": "apps/dashboard/" + }, + "react": { + "linkComponents": [ + { + "name": "Link", + "linkAttribute": "to" + } + ] + }, + "jsx-a11y": { + "components": { + "Link": "a", + "Button": "button" + } + } + } +} +``` ### settings.jsdoc @@ -302,7 +331,9 @@ default: `{}` type: `object` +Configure JSX A11y plugin rules. +See [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y#configurations)'s configuration for a full reference. #### settings.jsx-a11y.components @@ -311,7 +342,11 @@ type: `Record` default: `{}` +To have your custom components be checked as DOM elements, you can provide a mapping of your component names to the DOM element name. +## Example + +```json { "settings": { "jsx-a11y": { "components": { "Link": "a", "IconButton": "button" } } } } ``` #### settings.jsx-a11y.polymorphicPropName @@ -322,7 +357,13 @@ type: `[ ]` +An optional setting that define the prop your code uses to create polymorphic components. This setting will be used to determine the element type in rules that require semantic context. + +For example, if you set the `polymorphicPropName` to `as`, then this element: +```jsx Hello ``` + +Will be treated as an `h3`. If not set, this component will be treated as a `Box`. ### settings.next @@ -330,7 +371,7 @@ type: `[ type: `object` - +Configure Next.js plugin rules. #### settings.next.rootDir @@ -345,7 +386,9 @@ type: `object` type: `object` +Configure React plugin rules. +Derived from [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react#configuration-legacy-eslintrc-) #### settings.react.formComponents @@ -354,7 +397,11 @@ type: `array` default: `[]` +Components used as alternatives to `` for forms, such as ``. +## Example + +```jsonc { "settings": { "react": { "formComponents": [ "CustomForm", // OtherForm is considered a form component and has an endpoint attribute { "name": "OtherForm", "formAttribute": "endpoint" }, // allows specifying multiple properties if necessary { "name": "Form", "formAttribute": ["registerEndpoint", "loginEndpoint"] } ] } } } ``` ##### settings.react.formComponents[n] @@ -370,7 +417,11 @@ type: `array` default: `[]` +Components used as alternatives to `` for linking, such as ``. + +## Example +```jsonc { "settings": { "react": { "linkComponents": [ "HyperLink", // Use `linkAttribute` for components that use a different prop name // than `href`. { "name": "MyLink", "linkAttribute": "to" }, // allows specifying multiple properties if necessary { "name": "Link", "linkAttribute": ["to", "href"] } ] } } } ``` ##### settings.react.linkComponents[n]