feat(eslint-plugin): new prefer-docusaurus-heading rule (#8384)

This commit is contained in:
Devansu Yadav 2023-01-19 21:38:24 +05:30 committed by GitHub
parent a53d4cb2b3
commit 90e7e321d1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 254 additions and 52 deletions

10
.eslintrc.js vendored
View file

@ -375,6 +375,7 @@ module.exports = {
'@typescript-eslint/no-unused-vars': [ERROR, {ignoreRestSiblings: true}],
'@typescript-eslint/prefer-optional-chain': ERROR,
'@docusaurus/no-html-links': ERROR,
'@docusaurus/prefer-docusaurus-heading': ERROR,
'@docusaurus/no-untranslated-text': [
WARNING,
{
@ -495,5 +496,14 @@ module.exports = {
files: ['packages/eslint-plugin/**/*.{js,ts}'],
extends: ['plugin:eslint-plugin/recommended'],
},
{
files: [
'packages/docusaurus-plugin-debug/**',
'packages/docusaurus/src/**',
],
rules: {
'@docusaurus/prefer-docusaurus-heading': OFF,
},
},
],
};

View file

@ -1,5 +1,6 @@
import React from 'react';
import clsx from 'clsx';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
type FeatureItem = {
@ -48,7 +49,7 @@ function Feature({title, Svg, description}: FeatureItem) {
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<h3>{title}</h3>
<Heading as="h3">{title}</Heading>
<p>{description}</p>
</div>
</div>

View file

@ -4,6 +4,7 @@ import Link from '@docusaurus/Link';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import HomepageFeatures from '@site/src/components/HomepageFeatures';
import Heading from '@theme/Heading';
import styles from './index.module.css';
@ -12,7 +13,9 @@ function HomepageHeader() {
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<h1 className="hero__title">{siteConfig.title}</h1>
<Heading as="h1" className="hero__title">
{siteConfig.title}
</Heading>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link

View file

@ -1,5 +1,6 @@
import React from 'react';
import clsx from 'clsx';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
const FeatureList = [
@ -42,7 +43,7 @@ function Feature({Svg, title, description}) {
<Svg className={styles.featureSvg} role="img" />
</div>
<div className="text--center padding-horiz--md">
<h3>{title}</h3>
<Heading as="h3">{title}</Heading>
<p>{description}</p>
</div>
</div>

View file

@ -5,6 +5,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import Layout from '@theme/Layout';
import HomepageFeatures from '@site/src/components/HomepageFeatures';
import Heading from '@theme/Heading';
import styles from './index.module.css';
function HomepageHeader() {
@ -12,7 +13,9 @@ function HomepageHeader() {
return (
<header className={clsx('hero hero--primary', styles.heroBanner)}>
<div className="container">
<h1 className="hero__title">{siteConfig.title}</h1>
<Heading as="h1" className="hero__title">
{siteConfig.title}
</Heading>
<p className="hero__subtitle">{siteConfig.tagline}</p>
<div className={styles.buttons}>
<Link

View file

@ -11,6 +11,7 @@ import {translate} from '@docusaurus/Translate';
import {PageMetadata} from '@docusaurus/theme-common';
import Layout from '@theme/Layout';
import type {ArchiveBlogPost, Props} from '@theme/BlogArchivePage';
import Heading from '@theme/Heading';
type YearProp = {
year: string;
@ -20,7 +21,9 @@ type YearProp = {
function Year({year, posts}: YearProp) {
return (
<>
<h3>{year}</h3>
<Heading as="h3" id={year}>
{year}
</Heading>
<ul>
{posts.map((post) => (
<li key={post.metadata.date}>
@ -81,7 +84,9 @@ export default function BlogArchive({archive}: Props): JSX.Element {
<Layout>
<header className="hero hero--primary">
<div className="container">
<h1 className="hero__title">{title}</h1>
<Heading as="h1" className="hero__title">
{title}
</Heading>
<p className="hero__subtitle">{description}</p>
</div>
</header>

View file

@ -17,6 +17,7 @@ import BlogLayout from '@theme/BlogLayout';
import TagsListByLetter from '@theme/TagsListByLetter';
import type {Props} from '@theme/BlogTagsListPage';
import SearchMetadata from '@theme/SearchMetadata';
import Heading from '@theme/Heading';
export default function BlogTagsListPage({tags, sidebar}: Props): JSX.Element {
const title = translateTagsPageTitle();
@ -29,7 +30,7 @@ export default function BlogTagsListPage({tags, sidebar}: Props): JSX.Element {
<PageMetadata title={title} />
<SearchMetadata tag="blog_tags_list" />
<BlogLayout sidebar={sidebar}>
<h1>{title}</h1>
<Heading as="h1">{title}</Heading>
<TagsListByLetter tags={tags} />
</BlogLayout>
</HtmlClassNameProvider>

View file

@ -21,6 +21,7 @@ import SearchMetadata from '@theme/SearchMetadata';
import type {Props} from '@theme/BlogTagsPostsPage';
import BlogPostItems from '@theme/BlogPostItems';
import Unlisted from '@theme/Unlisted';
import Heading from '@theme/Heading';
// Very simple pluralization: probably good enough for now
function useBlogPostsPlural() {
@ -73,7 +74,7 @@ function BlogTagsPostsPageContent({
<BlogLayout sidebar={sidebar}>
{tag.unlisted && <Unlisted />}
<header className="margin-bottom--xl">
<h1>{title}</h1>
<Heading as="h1">{title}</Heading>
<Link href={tag.allTagsPath}>
<Translate
id="theme.tags.tagsPageLink"

View file

@ -16,6 +16,7 @@ import isInternalUrl from '@docusaurus/isInternalUrl';
import {translate} from '@docusaurus/Translate';
import type {Props} from '@theme/DocCard';
import Heading from '@theme/Heading';
import type {
PropSidebarItemCategory,
PropSidebarItemLink,
@ -52,9 +53,12 @@ function CardLayout({
}): JSX.Element {
return (
<CardContainer href={href}>
<h2 className={clsx('text--truncate', styles.cardTitle)} title={title}>
<Heading
as="h2"
className={clsx('text--truncate', styles.cardTitle)}
title={title}>
{icon} {title}
</h2>
</Heading>
{description && (
<p
className={clsx('text--truncate', styles.cardDescription)}

View file

@ -18,6 +18,7 @@ import Translate, {translate} from '@docusaurus/Translate';
import SearchMetadata from '@theme/SearchMetadata';
import type {Props} from '@theme/DocTagDocListPage';
import Unlisted from '@theme/Unlisted';
import Heading from '@theme/Heading';
// Very simple pluralization: probably good enough for now
function useNDocsTaggedPlural() {
@ -53,7 +54,7 @@ function DocItem({doc}: {doc: Props['tag']['items'][number]}): JSX.Element {
return (
<article className="margin-vert--lg">
<Link to={doc.permalink}>
<h2>{doc.title}</h2>
<Heading as="h2">{doc.title}</Heading>
</Link>
{doc.description && <p>{doc.description}</p>}
</article>
@ -83,7 +84,7 @@ function DocTagDocListPageContent({
<main className="col col--8 col--offset-2">
{tag.unlisted && <Unlisted />}
<header className="margin-bottom--xl">
<h1>{title}</h1>
<Heading as="h1">{title}</Heading>
<Link href={tag.allTagsPath}>
<Translate
id="theme.tags.tagsPageLink"

View file

@ -16,6 +16,7 @@ import {
import TagsListByLetter from '@theme/TagsListByLetter';
import SearchMetadata from '@theme/SearchMetadata';
import type {Props} from '@theme/DocTagsListPage';
import Heading from '@theme/Heading';
function DocTagsListPageMetadata({
title,
@ -38,7 +39,7 @@ function DocTagsListPageContent({
<div className="container margin-vert--lg">
<div className="row">
<main className="col col--8 col--offset-2">
<h1>{title}</h1>
<Heading as="h1">{title}</Heading>
<TagsListByLetter tags={tags} />
</main>
</div>

View file

@ -9,6 +9,7 @@ import React from 'react';
import Translate from '@docusaurus/Translate';
import {ErrorBoundaryTryAgainButton} from '@docusaurus/theme-common';
import type {Props} from '@theme/Error';
import Heading from '@theme/Heading';
export default function ErrorPageContent({
error,
@ -18,13 +19,13 @@ export default function ErrorPageContent({
<main className="container margin-vert--xl">
<div className="row">
<div className="col col--6 col--offset-3">
<h1 className="hero__title">
<Heading as="h1" className="hero__title">
<Translate
id="theme.ErrorPageContent.title"
description="The title of the fallback page when the page crashed">
This page crashed.
</Translate>
</h1>
</Heading>
<p>{error.message}</p>
<div>
<ErrorBoundaryTryAgainButton onClick={tryAgain} />

View file

@ -9,19 +9,20 @@ import React from 'react';
import clsx from 'clsx';
import Translate from '@docusaurus/Translate';
import type {Props} from '@theme/NotFound/Content';
import Heading from '@theme/Heading';
export default function NotFoundContent({className}: Props): JSX.Element {
return (
<main className={clsx('container margin-vert--xl', className)}>
<div className="row">
<div className="col col--6 col--offset-3">
<h1 className="hero__title">
<Heading as="h1" className="hero__title">
<Translate
id="theme.NotFound.title"
description="The title of the 404 page">
Page Not Found
</Translate>
</h1>
</Heading>
<p>
<Translate
id="theme.NotFound.p1"

View file

@ -9,13 +9,15 @@ import React from 'react';
import {listTagsByLetters, type TagLetterEntry} from '@docusaurus/theme-common';
import Tag from '@theme/Tag';
import type {Props} from '@theme/TagsListByLetter';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
function TagLetterEntryItem({letterEntry}: {letterEntry: TagLetterEntry}) {
return (
<article>
<h2>{letterEntry.letter}</h2>
<Heading as="h2" id={letterEntry.letter}>
{letterEntry.letter}
</Heading>
<ul className="padding--none">
{letterEntry.tags.map((tag) => (
<li key={tag.permalink} className={styles.tag}>

View file

@ -33,7 +33,7 @@ import {
useSearchResultUrlProcessor,
} from '@docusaurus/theme-search-algolia/client';
import Layout from '@theme/Layout';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
// Very simple pluralization: probably good enough for now
@ -374,7 +374,7 @@ function SearchPageContent(): JSX.Element {
</Head>
<div className="container margin-vert--lg">
<h1>{getTitle()}</h1>
<Heading as="h1">{getTitle()}</Heading>
<form className="row" onSubmit={(e) => e.preventDefault()}>
<div
@ -455,9 +455,9 @@ function SearchPageContent(): JSX.Element {
{searchResultState.items.map(
({title, url, summary, breadcrumbs}, i) => (
<article key={i} className={styles.searchResultItem}>
<h2 className={styles.searchResultItemHeading}>
<Heading as="h2" className={styles.searchResultItemHeading}>
<Link to={url} dangerouslySetInnerHTML={{__html: title}} />
</h2>
</Heading>
{breadcrumbs.length > 0 && (
<nav aria-label="breadcrumbs">

View file

@ -15,6 +15,7 @@ export = {
rules: {
'@docusaurus/string-literal-i18n-messages': 'error',
'@docusaurus/no-html-links': 'warn',
'@docusaurus/prefer-docusaurus-heading': 'warn',
},
},
all: {
@ -23,6 +24,7 @@ export = {
'@docusaurus/string-literal-i18n-messages': 'error',
'@docusaurus/no-untranslated-text': 'warn',
'@docusaurus/no-html-links': 'warn',
'@docusaurus/prefer-docusaurus-heading': 'warn',
},
},
},

View file

@ -0,0 +1,69 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import rule from '../prefer-docusaurus-heading';
import {RuleTester} from './testUtils';
const errorsJSX = [{messageId: 'headings'}] as const;
const ruleTester = new RuleTester({
parser: '@typescript-eslint/parser',
parserOptions: {
ecmaFeatures: {
jsx: true,
},
},
});
ruleTester.run('prefer-docusaurus-heading', rule, {
valid: [
{
code: "<Heading as='h1'>heading 1</Heading>",
},
{
code: "<Heading as='h2'>heading 2</Heading>",
},
{
code: "<Heading as='h3'>heading 3</Heading>",
},
{
code: "<Heading as='h4'>heading 4</Heading>",
},
{
code: "<Heading as='h5'>heading 5</Heading>",
},
{
code: "<Heading as='h6'>heading 6</Heading>",
},
],
invalid: [
{
code: '<h1>heading 1</h1>',
errors: errorsJSX,
},
{
code: '<h2>heading 2</h2>',
errors: errorsJSX,
},
{
code: '<h3>heading 3</h3>',
errors: errorsJSX,
},
{
code: '<h4>heading 4</h4>',
errors: errorsJSX,
},
{
code: '<h5>heading 5</h5>',
errors: errorsJSX,
},
{
code: '<h6>heading 6</h6>',
errors: errorsJSX,
},
],
});

View file

@ -6,6 +6,7 @@
*/
import noHtmlLinks from './no-html-links';
import preferDocusaurusHeading from './prefer-docusaurus-heading';
import noUntranslatedText from './no-untranslated-text';
import stringLiteralI18nMessages from './string-literal-i18n-messages';
@ -13,4 +14,5 @@ export default {
'no-untranslated-text': noUntranslatedText,
'string-literal-i18n-messages': stringLiteralI18nMessages,
'no-html-links': noHtmlLinks,
'prefer-docusaurus-heading': preferDocusaurusHeading,
};

View file

@ -0,0 +1,46 @@
/**
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
import {createRule} from '../util';
import type {TSESTree} from '@typescript-eslint/types/dist/ts-estree';
type Options = [];
type MessageIds = 'headings';
export default createRule<Options, MessageIds>({
name: 'prefer-docusaurus-heading',
meta: {
type: 'problem',
docs: {
description:
'enforce using Docusaurus theme Heading component instead of any <hn> tag',
recommended: false,
},
schema: [],
messages: {
headings:
'Do not use any of the `<hn>` tags for headings. Use the `<Heading />` component from `@theme/Heading` instead.',
},
},
defaultOptions: [],
create(context) {
const headingTypes = ['h1', 'h2', 'h3', 'h4', 'h5', 'h6'];
return {
JSXOpeningElement(node) {
const elementName = (node.name as TSESTree.JSXIdentifier).name;
if (!headingTypes.includes(elementName)) {
return;
}
context.report({node, messageId: 'headings'});
},
};
},
});

View file

@ -7,12 +7,13 @@
import React from 'react';
import Layout from '@theme/Layout';
import Heading from '@theme/Heading';
// See https://github.com/facebook/docusaurus/issues/6337#issuecomment-1012913647
export default function Analytics(): JSX.Element {
return (
<Layout>
<h1>Test Analytics</h1>
<Heading as="h1">Test Analytics</Heading>
<div>
<button
type="button"

View file

@ -8,7 +8,7 @@
import React from 'react';
import Interpolate from '@docusaurus/Interpolate';
import Layout from '@theme/Layout';
import Heading from '@theme/Heading';
import ErrorBoundaryTestButton from '@site/src/components/ErrorBoundaryTestButton';
export default function ErrorBoundaryTests(): JSX.Element {
@ -17,7 +17,7 @@ export default function ErrorBoundaryTests(): JSX.Element {
<ErrorBoundaryTestButton>Crash outside layout</ErrorBoundaryTestButton>
<Layout>
<main className="container margin-vert--xl">
<h1>Error boundary tests</h1>
<Heading as="h1">Error boundary tests</Heading>
<div>
<ErrorBoundaryTestButton>
Crash inside layout

View file

@ -53,6 +53,7 @@ For more fine-grained control, you can also enable the plugin manually and confi
| [`@docusaurus/no-untranslated-text`](./no-untranslated-text.mdx) | Enforce text labels in JSX to be wrapped by translate calls | |
| [`@docusaurus/string-literal-i18n-messages`](./string-literal-i18n-messages.mdx) | Enforce translate APIs to be called on plain text labels | ✅ |
| [`@docusaurus/no-html-links`](./no-html-links.mdx) | Ensures @docusaurus/Link is used instead of `<a>` tags | ✅ |
| [`@docusaurus/prefer-docusaurus-heading`](./prefer-docusaurus-heading.mdx) | Ensures @theme/Heading is used instead of `<hn>` tags for headings | ✅ |
✅ = recommended

View file

@ -0,0 +1,31 @@
---
slug: /api/misc/@docusaurus/eslint-plugin/prefer-docusaurus-heading
---
# prefer-docusaurus-heading
Ensures that the `@theme/Heading` theme component provided by Docusaurus [`theme-classic`](../../themes/theme-classic.mdx) is used instead of `<hn>` tags for headings.
## Rule Details {#details}
Examples of **incorrect** code for this rule:
```html
<h1>This is heading 1</h1>
<h2>This is heading 2</h2>
<h3>This is heading 3</h3>
```
Examples of **correct** code for this rule:
```javascript
import Heading from '@theme/Heading'
<Heading as='h1'>This is heading 1</Heading>
<Heading as='h2'>This is heading 2</Heading>
<Heading as='h3'>This is heading 3</Heading>
```

View file

@ -12,6 +12,7 @@ import clsx from 'clsx';
import Translate from '@docusaurus/Translate';
import Link from '@docusaurus/Link';
import Image from '@theme/IdealImage';
import Heading from '@theme/Heading';
const Playgrounds = [
{
@ -64,7 +65,7 @@ function PlaygroundCard({name, image, url, description}: Props) {
</Link>
</div>
<div className="card__body">
<h3>{name}</h3>
<Heading as="h3">{name}</Heading>
<p>{description}</p>
</div>
<div className="card__footer">

View file

@ -8,6 +8,7 @@
import React, {type ReactNode} from 'react';
import Translate from '@docusaurus/Translate';
import Link from '@docusaurus/Link';
import Heading from '@theme/Heading';
function WebsiteLink({to, children}: {to: string; children?: ReactNode}) {
return (
@ -45,7 +46,9 @@ function TeamProfileCard({
alt={`${name}'s avatar`}
/>
<div className="avatar__intro">
<h3 className="avatar__name">{name}</h3>
<Heading as="h3" className="avatar__name">
{name}
</Heading>
</div>
</div>
</div>

View file

@ -25,12 +25,13 @@ import ProductHuntCard from '@site/src/components/ProductHuntCard';
import HackerNewsIcon from '@site/src/components/HackerNewsIcon';
import styles from './styles.module.css';
import 'react-lite-youtube-embed/dist/LiteYouTubeEmbed.css';
import Heading from '@theme/Heading';
function HeroBanner() {
return (
<div className={styles.hero} data-theme="dark">
<div className={styles.heroInner}>
<h1 className={styles.heroProjectTagline}>
<Heading as="h1" className={styles.heroProjectTagline}>
<img
alt={translate({message: 'Docusaurus with Keytar'})}
className={styles.heroLogo}
@ -51,7 +52,7 @@ function HeroBanner() {
}),
}}
/>
</h1>
</Heading>
<div className={styles.indexCtas}>
<Link className="button button--primary" to="/docs">
<Translate>Get Started</Translate>
@ -109,9 +110,9 @@ function TweetsSection() {
return (
<div className={clsx(styles.section, styles.sectionAlt)}>
<div className="container">
<h2 className={clsx('margin-bottom--lg', 'text--center')}>
<Heading as="h2" className={clsx('margin-bottom--lg', 'text--center')}>
<Translate>Loved by many engineers</Translate>
</h2>
</Heading>
<div className={clsx('row', styles.tweetsSection)}>
{tweetColumns.map((tweetItems, i) => (
<div className="col col--4" key={i}>
@ -161,9 +162,9 @@ function VideoContainer() {
<div className="container text--center margin-bottom--xl">
<div className="row">
<div className="col">
<h2>
<Heading as="h2">
<Translate>Check it out in the intro video</Translate>
</h2>
</Heading>
<div className="video-container">
<LiteYouTubeEmbed
id="_An9EsKPhp0"
@ -198,7 +199,9 @@ function Feature({
src={withBaseUrl(feature.image.src)}
loading="lazy"
/>
<h3 className={clsx(styles.featureHeading)}>{feature.title}</h3>
<Heading as="h3" className={clsx(styles.featureHeading)}>
{feature.title}
</Heading>
<p className="padding-horiz--md">{feature.text}</p>
</div>
);
@ -210,9 +213,9 @@ function FeaturesContainer() {
return (
<div className="container text--center">
<h2>
<Heading as="h2">
<Translate>Main features</Translate>
</h2>
</Heading>
<div className="row margin-bottom--lg">
{firstRow.map((feature, idx) => (
<Feature feature={feature} key={idx} />

View file

@ -19,6 +19,7 @@ import {
type Tag,
} from '@site/src/data/users';
import {sortBy} from '@site/src/utils/jsUtils';
import Heading from '@theme/Heading';
import Tooltip from '../ShowcaseTooltip';
import styles from './styles.module.css';
@ -76,11 +77,11 @@ function ShowcaseCard({user}: {user: User}) {
</div>
<div className="card__body">
<div className={clsx(styles.showcaseCardHeader)}>
<h4 className={styles.showcaseCardTitle}>
<Heading as="h4" className={styles.showcaseCardTitle}>
<Link href={user.website} className={styles.showcaseCardLink}>
{user.title}
</Link>
</h4>
</Heading>
{user.tags.includes('favorite') && (
<FavoriteIcon svgClass={styles.svgIconFavorite} size="small" />
)}

View file

@ -22,6 +22,7 @@ import {
type User,
type TagType,
} from '@site/src/data/users';
import Heading from '@theme/Heading';
import ShowcaseTagSelect, {
readSearchTags,
} from './_components/ShowcaseTagSelect';
@ -122,7 +123,7 @@ function useFilteredUsers() {
function ShowcaseHeader() {
return (
<section className="margin-top--lg margin-bottom--lg text--center">
<h1>{TITLE}</h1>
<Heading as="h1">{TITLE}</Heading>
<p>{DESCRIPTION}</p>
<Link className="button button--primary" to={SUBMIT_URL}>
<Translate id="showcase.header.button">
@ -157,9 +158,9 @@ function ShowcaseFilters() {
<section className="container margin-top--l margin-bottom--lg">
<div className={clsx('margin-bottom--sm', styles.filterCheckbox)}>
<div>
<h2>
<Heading as="h2">
<Translate id="showcase.filters.title">Filters</Translate>
</h2>
</Heading>
<span>{siteCountPlural(filteredUsers.length)}</span>
</div>
<ShowcaseFilterToggle />
@ -255,9 +256,9 @@ function ShowcaseCards() {
return (
<section className="margin-top--lg margin-bottom--xl">
<div className="container padding-vert--md text--center">
<h2>
<Heading as="h2">
<Translate id="showcase.usersList.noResult">No result</Translate>
</h2>
</Heading>
<SearchBar />
</div>
</section>
@ -275,11 +276,11 @@ function ShowcaseCards() {
'margin-bottom--md',
styles.showcaseFavoriteHeader,
)}>
<h2>
<Heading as="h2">
<Translate id="showcase.favoritesList.title">
Our favorites
</Translate>
</h2>
</Heading>
<FavoriteIcon svgClass={styles.svgIconFavorite} />
<SearchBar />
</div>
@ -296,9 +297,9 @@ function ShowcaseCards() {
</div>
</div>
<div className="container margin-top--lg">
<h2 className={styles.showcaseHeader}>
<Heading as="h2" className={styles.showcaseHeader}>
<Translate id="showcase.usersList.allUsers">All sites</Translate>
</h2>
</Heading>
<ul className={clsx('clean-list', styles.showcaseList)}>
{otherUsers.map((user) => (
<ShowcaseCard key={user.title} user={user} />

View file

@ -168,11 +168,11 @@ export default function Version(): JSX.Element {
</div>
)}
<div className="margin-bottom--lg">
<h3 id="legacy">
<Heading as="h3" id="legacy">
<Translate id="versionsPage.legacy.title">
Docusaurus v1 (Legacy)
</Translate>
</h3>
</Heading>
<p>
<Translate id="versionsPage.legacy.description">
Here you can find documentation for legacy version of Docusaurus.

View file

@ -8,6 +8,7 @@
import React from 'react';
import Translate from '@docusaurus/Translate';
import Link from '@docusaurus/Link';
import Heading from '@theme/Heading';
import styles from './styles.module.css';
function TwitterLink() {
@ -63,7 +64,9 @@ export default function ChangelogListHeader({
}): JSX.Element {
return (
<header className="margin-bottom--lg">
<h1 style={{fontSize: '3rem'}}>{blogTitle}</h1>
<Heading as="h1" style={{fontSize: '3rem'}}>
{blogTitle}
</Heading>
<p>
<Translate
id="changelog.description"

View file

@ -8,11 +8,14 @@
import React from 'react';
import type {Props} from '@theme/Admonition';
import DefaultAdmonitionTypes from '@theme-original/Admonition/Types';
import Heading from '@theme/Heading';
function MyCustomAdmonition(props: Props): JSX.Element {
return (
<div style={{border: 'solid red', padding: 10}}>
<h5 style={{color: 'blue', fontSize: 30}}>{props.title}</h5>
<Heading as="h5" style={{color: 'blue', fontSize: 30}}>
{props.title}
</Heading>
<div>{props.children}</div>
</div>
);