diff --git a/packages/website/plugins/generated-rule-docs.ts b/packages/website/plugins/generated-rule-docs.ts index 90f0b3fa6f70..d29d240c91fc 100644 --- a/packages/website/plugins/generated-rule-docs.ts +++ b/packages/website/plugins/generated-rule-docs.ts @@ -4,6 +4,7 @@ import * as fs from 'fs'; import type { JSONSchema7 } from 'json-schema'; import type { JSONSchema } from 'json-schema-to-typescript'; import { compile } from 'json-schema-to-typescript'; +import * as lz from 'lzstring.ts'; import type * as mdast from 'mdast'; import { EOL } from 'os'; import * as path from 'path'; @@ -193,35 +194,62 @@ export const generatedRuleDocs: Plugin = () => { type: 'paragraph', } as mdast.Paragraph); + /** + * @param withComment Whether to include a full comment note. + * @remarks `withComment` can't be used inside a JSON object which is needed for eslintrc in the playground + */ + const getEslintrcString = (withComment: boolean): string => { + return `{ + "rules": {${ + withComment + ? '\n // Note: you must disable the base rule as it can report incorrect errors' + : '' + } + "${extendsBaseRuleName}": "off", + "@typescript-eslint/${file.stem}": "${optionLevel}" + } +}`; + }; + root.children.splice(howToUseH2Index + 1, 0, { lang: 'js', type: 'code', meta: 'title=".eslintrc.cjs"', - value: `module.exports = { - "rules": { - // Note: you must disable the base rule as it can report incorrect errors - "${extendsBaseRuleName}": "off", - "@typescript-eslint/${file.stem}": "${optionLevel}" - } -};`, + value: `module.exports = ${getEslintrcString(true)};`, } as mdast.Code); + + root.children.splice(howToUseH2Index + 2, 0, { + value: ``, + type: 'jsx', + } as unist.Node); } else { // 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, ); + + const getEslintrcString = `{ + "rules": { + "@typescript-eslint/${file.stem}": "${optionLevel}" + } +}`; root.children.splice(firstH2Index, 0, { lang: 'js', type: 'code', meta: 'title=".eslintrc.cjs"', - value: `module.exports = { - "rules": { - "@typescript-eslint/${file.stem}": "${optionLevel}" - } -};`, + value: `module.exports = ${getEslintrcString};`, } as mdast.Code); + root.children.splice(firstH2Index + 1, 0, { + value: ``, + type: 'jsx', + } as unist.Node); + if (meta.schema.length === 0) { root.children.splice(optionsH2Index + 1, 0, { children: [ @@ -395,6 +423,10 @@ export const generatedRuleDocs: Plugin = () => { }; }; +function convertToPlaygroundHash(eslintrc: string): string { + return lz.LZString.compressToEncodedURIComponent(eslintrc); +} + function nodeIsHeading(node: unist.Node): node is mdast.Heading { return node.type === 'heading'; } diff --git a/packages/website/src/theme/MDXComponents/TryInPlayground.module.css b/packages/website/src/theme/MDXComponents/TryInPlayground.module.css new file mode 100644 index 000000000000..2830e4da6ec0 --- /dev/null +++ b/packages/website/src/theme/MDXComponents/TryInPlayground.module.css @@ -0,0 +1,3 @@ +.tryInPlaygroundLink { + float: right; +} diff --git a/packages/website/src/theme/MDXComponents/TryInPlayground.tsx b/packages/website/src/theme/MDXComponents/TryInPlayground.tsx new file mode 100644 index 000000000000..d9b096f1d909 --- /dev/null +++ b/packages/website/src/theme/MDXComponents/TryInPlayground.tsx @@ -0,0 +1,19 @@ +import React from 'react'; + +import styles from './TryInPlayground.module.css'; + +export function TryInPlayground({ + eslintrcHash, +}: { + eslintrcHash: string; +}): React.ReactNode { + return ( + + Try this rule in the playground ↗ + + ); +} diff --git a/packages/website/src/theme/MDXComponents/index.tsx b/packages/website/src/theme/MDXComponents/index.tsx index 70fa555536b5..c810e8b72833 100644 --- a/packages/website/src/theme/MDXComponents/index.tsx +++ b/packages/website/src/theme/MDXComponents/index.tsx @@ -1,9 +1,11 @@ import MDXComponents from '@theme-original/MDXComponents'; import { RuleAttributes } from './RuleAttributes'; +import { TryInPlayground } from './TryInPlayground'; // eslint-disable-next-line import/no-default-export export default { ...MDXComponents, 'rule-attributes': RuleAttributes, + 'try-in-playground': TryInPlayground, };