From 1c119d3782647af047579fa475ed42ed285ec5ac Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Sat, 1 Oct 2022 01:30:04 -0400 Subject: [PATCH 1/2] chore(website): move rule attributes to top of docs pages --- .../website/plugins/generated-rule-docs.ts | 61 ++++--- .../theme/MDXComponents/Feature.module.css | 22 +++ .../src/theme/MDXComponents/Feature.tsx | 17 ++ .../MDXComponents/RuleAttributes.module.css | 10 +- .../theme/MDXComponents/RuleAttributes.tsx | 162 +++++++++++------- 5 files changed, 176 insertions(+), 96 deletions(-) create mode 100644 packages/website/src/theme/MDXComponents/Feature.module.css create mode 100644 packages/website/src/theme/MDXComponents/Feature.tsx 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 ( +
+
{emoji}
+

{children}

+
+ ); +} 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..fec80e87d7a2 100644 --- a/packages/website/src/theme/MDXComponents/RuleAttributes.tsx +++ b/packages/website/src/theme/MDXComponents/RuleAttributes.tsx @@ -1,73 +1,113 @@ +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

-
    -
  • - - Included in configs -
      -
    • - - ✅ Recommended -
    • -
    • - - 🔒 Strict -
    • -
    -
  • -
  • - - Fixable -
      -
    • - - 🔧 Automated Fixer -
    • -
    • - - 💡 Suggestion Fixer -
    • -
    -
  • -
  • - - 💭 Requires type information -
  • -
- +
+ {features.map(feature => ( + + ))} +
); } From 02e55a0ea3149221ce2e30b523e3bcbd2836537b Mon Sep 17 00:00:00 2001 From: Josh Goldberg Date: Tue, 4 Oct 2022 07:52:08 -0400 Subject: [PATCH 2/2] Fix RuleAttributes links --- .../website/src/theme/MDXComponents/RuleAttributes.tsx | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/website/src/theme/MDXComponents/RuleAttributes.tsx b/packages/website/src/theme/MDXComponents/RuleAttributes.tsx index fec80e87d7a2..c7632e25a9f8 100644 --- a/packages/website/src/theme/MDXComponents/RuleAttributes.tsx +++ b/packages/website/src/theme/MDXComponents/RuleAttributes.tsx @@ -29,10 +29,7 @@ export function RuleAttributes({ name }: { name: string }): React.ReactNode { children: ( <> Extending{' '} - + "plugin:@typescript-eslint/{recommendation}" @@ -56,12 +53,11 @@ export function RuleAttributes({ name }: { name: string }): React.ReactNode { children: ( <> Some problems reported by this rule are automatically fixable by the{' '} - --fix{' '} - ESLint command line option + --fix ESLint command line option . 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