diff --git a/packages/website/plugins/generated-rule-docs.ts b/packages/website/plugins/generated-rule-docs.ts
index e21a408dbf42..a05519ab7da6 100644
--- a/packages/website/plugins/generated-rule-docs.ts
+++ b/packages/website/plugins/generated-rule-docs.ts
@@ -52,20 +52,26 @@ export const generatedRuleDocs: Plugin = () => {
);
// 2. Add a description of the rule at the top of the file
- root.children.unshift({
- children: [
- {
- children: meta.docs.description
- .split(/`(.+?)`/)
- .map((value, index, array) => ({
- type: index % 2 === 0 ? 'text' : 'inlineCode',
- value: index === array.length - 1 ? `${value}.` : value,
- })),
- type: 'paragraph',
- },
- ],
- type: 'blockquote',
- } as mdast.Blockquote);
+ root.children.unshift(
+ {
+ children: [
+ {
+ children: meta.docs.description
+ .split(/`(.+?)`/)
+ .map((value, index, array) => ({
+ type: index % 2 === 0 ? 'text' : 'inlineCode',
+ value: index === array.length - 1 ? `${value}.` : value,
+ })),
+ type: 'paragraph',
+ },
+ ],
+ type: 'blockquote',
+ } as mdast.Blockquote,
+ {
+ type: 'jsx',
+ value: ``,
+ } as unist.Node,
+ );
// 3. Add a notice about formatting rules being 🤢
if (meta.type === 'layout') {
@@ -82,19 +88,7 @@ export const generatedRuleDocs: Plugin = () => {
root.children.unshift(warningNode);
}
- // 4. Add a rule attributes list before the first h2.
- const attributesH2Index = root.children.findIndex(
- child => nodeIsHeading(child) && child.depth === 2,
- );
-
- // The actual content will be injected on client side.
- const attributesNode = {
- type: 'jsx',
- value: ``,
- };
- root.children.splice(attributesH2Index, 0, attributesNode);
-
- // 5. Make sure the appropriate headers exist to place content under
+ // 4. Make sure the appropriate headers exist to place content under
const [howToUseH2Index, optionsH2Index] = ((): [number, number] => {
let howToUseH2Index = root.children.findIndex(
createH2TextFilter('How to Use'),
@@ -162,7 +156,7 @@ export const generatedRuleDocs: Plugin = () => {
return [howToUseH2Index, optionsH2Index];
})();
- // 6. Add a description of how to use / options for the rule
+ // 5. Add a description of how to use / options for the rule
const optionLevel = meta.docs.recommended === 'error' ? 'error' : 'warn';
if (meta.docs.extendsBaseRule) {
@@ -210,7 +204,12 @@ export const generatedRuleDocs: Plugin = () => {
};`,
} as mdast.Code);
} else {
- root.children.splice(optionsH2Index, 0, {
+ // For non-extended rules, the code snippet is placed before the first h2
+ // (i.e. at the end of the initial explanation)
+ const firstH2Index = root.children.findIndex(
+ child => nodeIsHeading(child) && child.depth === 2,
+ );
+ root.children.splice(firstH2Index, 0, {
lang: 'js',
type: 'code',
meta: 'title=".eslintrc.cjs"',
@@ -297,7 +296,7 @@ export const generatedRuleDocs: Plugin = () => {
}
}
- // 7. Add a notice about coming from ESLint core for extension rules
+ // 6. Add a notice about coming from ESLint core for extension rules
if (meta.docs.extendsBaseRule) {
root.children.push({
children: [
@@ -329,7 +328,7 @@ export const generatedRuleDocs: Plugin = () => {
} as mdast.Paragraph);
}
- // 8. Also add a link to view the rule's source and test code
+ // 7. Also add a link to view the rule's source and test code
root.children.push(
{
children: [
diff --git a/packages/website/src/theme/MDXComponents/Feature.module.css b/packages/website/src/theme/MDXComponents/Feature.module.css
new file mode 100644
index 000000000000..aeef8f51e0a2
--- /dev/null
+++ b/packages/website/src/theme/MDXComponents/Feature.module.css
@@ -0,0 +1,22 @@
+.feature {
+ background-color: var(--token-background);
+ border-radius: var(--ifm-code-border-radius);
+ box-shadow: var(--ifm-global-shadow-lw);
+ color: var(--token-color) !important;
+ display: flex;
+ flex-basis: 30%;
+ flex-grow: 1;
+ flex-shrink: 3;
+ font-size: 0.8rem;
+ margin: 0 0 1rem;
+ min-width: 15rem;
+ padding: 0.75rem 1rem;
+}
+
+.emoji {
+ margin-right: 0.5rem;
+}
+
+.children {
+ margin: 0;
+}
diff --git a/packages/website/src/theme/MDXComponents/Feature.tsx b/packages/website/src/theme/MDXComponents/Feature.tsx
new file mode 100644
index 000000000000..64aac69a68ed
--- /dev/null
+++ b/packages/website/src/theme/MDXComponents/Feature.tsx
@@ -0,0 +1,17 @@
+import React from 'react';
+
+import styles from './Feature.module.css';
+
+export interface FeatureProps {
+ children: React.ReactNode;
+ emoji: string;
+}
+
+export function Feature({ children, emoji }: FeatureProps): JSX.Element {
+ return (
+
+ );
+}
diff --git a/packages/website/src/theme/MDXComponents/RuleAttributes.module.css b/packages/website/src/theme/MDXComponents/RuleAttributes.module.css
index 97c07287baba..bd8bc627c3b3 100644
--- a/packages/website/src/theme/MDXComponents/RuleAttributes.module.css
+++ b/packages/website/src/theme/MDXComponents/RuleAttributes.module.css
@@ -1,7 +1,9 @@
-.taskList {
- list-style: none;
+.features {
+ display: flex;
+ gap: 0 1rem;
+ flex-wrap: wrap;
}
-:not(.taskList > li) > .taskList {
- padding-left: 0;
+.features + h2 {
+ margin-top: 1rem;
}
diff --git a/packages/website/src/theme/MDXComponents/RuleAttributes.tsx b/packages/website/src/theme/MDXComponents/RuleAttributes.tsx
index 4248270628da..c7632e25a9f8 100644
--- a/packages/website/src/theme/MDXComponents/RuleAttributes.tsx
+++ b/packages/website/src/theme/MDXComponents/RuleAttributes.tsx
@@ -1,73 +1,109 @@
+import type { RuleMetaDataDocs } from '@site/../utils/dist/ts-eslint/Rule';
import { useRulesMeta } from '@site/src/hooks/useRulesMeta';
-import type { TSESLint } from '@typescript-eslint/utils';
import React from 'react';
+import type { FeatureProps } from './Feature';
+import { Feature } from './Feature';
import styles from './RuleAttributes.module.css';
-export function RuleAttributes({ name }: { name: string }): JSX.Element | null {
+const getRecommendation = (docs: RuleMetaDataDocs): [string, string] => {
+ return docs.recommended === 'strict'
+ ? ['🔒', 'strict']
+ : docs.requiresTypeChecking
+ ? ['🧠', 'recommended-requiring-type-checking']
+ : ['✅', 'recommended'];
+};
+
+export function RuleAttributes({ name }: { name: string }): React.ReactNode {
const rules = useRulesMeta();
const rule = rules.find(rule => rule.name === name);
- if (!rule) {
+ if (!rule?.docs) {
return null;
}
+
+ const features: FeatureProps[] = [];
+
+ if (rule.docs.recommended) {
+ const [emoji, recommendation] = getRecommendation(rule.docs);
+ features.push({
+ children: (
+ <>
+ Extending{' '}
+
+
+ "plugin:@typescript-eslint/{recommendation}"
+
+ {' '}
+ in an{' '}
+
+ ESLint configuration
+ {' '}
+ enables this rule.
+ >
+ ),
+ emoji,
+ });
+ }
+
+ if (rule.fixable) {
+ features.push({
+ children: (
+ <>
+ Some problems reported by this rule are automatically fixable by the{' '}
+
+ --fix
ESLint command line option
+
+ .
+ >
+ ),
+ emoji: '🛠',
+ });
+ }
+
+ if (rule.hasSuggestions) {
+ features.push({
+ children: (
+ <>
+ Some problems reported by this rule are manually fixable by editor{' '}
+
+ suggestions
+
+ .
+ >
+ ),
+ emoji: '💡',
+ });
+ }
+
+ if (rule.docs.requiresTypeChecking) {
+ features.push({
+ children: (
+ <>
+ This rule requires{' '}
+
+ type information
+ {' '}
+ to run.
+ >
+ ),
+ emoji: 'ðŸ’',
+ });
+ }
+
return (
- <>
- Attributes
-
- >
+
+ {features.map(feature => (
+
+ ))}
+
);
}
pFad - Phonifier reborn
Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies:
Alternative Proxy
pFad Proxy
pFad v3 Proxy
pFad v4 Proxy