mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-10 23:57:22 +02:00
feat(eslint-plugin): new prefer-docusaurus-heading rule (#8384)
This commit is contained in:
parent
a53d4cb2b3
commit
90e7e321d1
31 changed files with 254 additions and 52 deletions
10
.eslintrc.js
vendored
10
.eslintrc.js
vendored
|
@ -375,6 +375,7 @@ module.exports = {
|
||||||
'@typescript-eslint/no-unused-vars': [ERROR, {ignoreRestSiblings: true}],
|
'@typescript-eslint/no-unused-vars': [ERROR, {ignoreRestSiblings: true}],
|
||||||
'@typescript-eslint/prefer-optional-chain': ERROR,
|
'@typescript-eslint/prefer-optional-chain': ERROR,
|
||||||
'@docusaurus/no-html-links': ERROR,
|
'@docusaurus/no-html-links': ERROR,
|
||||||
|
'@docusaurus/prefer-docusaurus-heading': ERROR,
|
||||||
'@docusaurus/no-untranslated-text': [
|
'@docusaurus/no-untranslated-text': [
|
||||||
WARNING,
|
WARNING,
|
||||||
{
|
{
|
||||||
|
@ -495,5 +496,14 @@ module.exports = {
|
||||||
files: ['packages/eslint-plugin/**/*.{js,ts}'],
|
files: ['packages/eslint-plugin/**/*.{js,ts}'],
|
||||||
extends: ['plugin:eslint-plugin/recommended'],
|
extends: ['plugin:eslint-plugin/recommended'],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
files: [
|
||||||
|
'packages/docusaurus-plugin-debug/**',
|
||||||
|
'packages/docusaurus/src/**',
|
||||||
|
],
|
||||||
|
rules: {
|
||||||
|
'@docusaurus/prefer-docusaurus-heading': OFF,
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
type FeatureItem = {
|
type FeatureItem = {
|
||||||
|
@ -48,7 +49,7 @@ function Feature({title, Svg, description}: FeatureItem) {
|
||||||
<Svg className={styles.featureSvg} role="img" />
|
<Svg className={styles.featureSvg} role="img" />
|
||||||
</div>
|
</div>
|
||||||
<div className="text--center padding-horiz--md">
|
<div className="text--center padding-horiz--md">
|
||||||
<h3>{title}</h3>
|
<Heading as="h3">{title}</Heading>
|
||||||
<p>{description}</p>
|
<p>{description}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -4,6 +4,7 @@ import Link from '@docusaurus/Link';
|
||||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
import HomepageFeatures from '@site/src/components/HomepageFeatures';
|
import HomepageFeatures from '@site/src/components/HomepageFeatures';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
import styles from './index.module.css';
|
import styles from './index.module.css';
|
||||||
|
|
||||||
|
@ -12,7 +13,9 @@ function HomepageHeader() {
|
||||||
return (
|
return (
|
||||||
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
||||||
<div className="container">
|
<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>
|
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||||
<div className={styles.buttons}>
|
<div className={styles.buttons}>
|
||||||
<Link
|
<Link
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
const FeatureList = [
|
const FeatureList = [
|
||||||
|
@ -42,7 +43,7 @@ function Feature({Svg, title, description}) {
|
||||||
<Svg className={styles.featureSvg} role="img" />
|
<Svg className={styles.featureSvg} role="img" />
|
||||||
</div>
|
</div>
|
||||||
<div className="text--center padding-horiz--md">
|
<div className="text--center padding-horiz--md">
|
||||||
<h3>{title}</h3>
|
<Heading as="h3">{title}</Heading>
|
||||||
<p>{description}</p>
|
<p>{description}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,6 +5,7 @@ import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
import HomepageFeatures from '@site/src/components/HomepageFeatures';
|
import HomepageFeatures from '@site/src/components/HomepageFeatures';
|
||||||
|
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
import styles from './index.module.css';
|
import styles from './index.module.css';
|
||||||
|
|
||||||
function HomepageHeader() {
|
function HomepageHeader() {
|
||||||
|
@ -12,7 +13,9 @@ function HomepageHeader() {
|
||||||
return (
|
return (
|
||||||
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
||||||
<div className="container">
|
<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>
|
<p className="hero__subtitle">{siteConfig.tagline}</p>
|
||||||
<div className={styles.buttons}>
|
<div className={styles.buttons}>
|
||||||
<Link
|
<Link
|
||||||
|
|
|
@ -11,6 +11,7 @@ import {translate} from '@docusaurus/Translate';
|
||||||
import {PageMetadata} from '@docusaurus/theme-common';
|
import {PageMetadata} from '@docusaurus/theme-common';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
import type {ArchiveBlogPost, Props} from '@theme/BlogArchivePage';
|
import type {ArchiveBlogPost, Props} from '@theme/BlogArchivePage';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
type YearProp = {
|
type YearProp = {
|
||||||
year: string;
|
year: string;
|
||||||
|
@ -20,7 +21,9 @@ type YearProp = {
|
||||||
function Year({year, posts}: YearProp) {
|
function Year({year, posts}: YearProp) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<h3>{year}</h3>
|
<Heading as="h3" id={year}>
|
||||||
|
{year}
|
||||||
|
</Heading>
|
||||||
<ul>
|
<ul>
|
||||||
{posts.map((post) => (
|
{posts.map((post) => (
|
||||||
<li key={post.metadata.date}>
|
<li key={post.metadata.date}>
|
||||||
|
@ -81,7 +84,9 @@ export default function BlogArchive({archive}: Props): JSX.Element {
|
||||||
<Layout>
|
<Layout>
|
||||||
<header className="hero hero--primary">
|
<header className="hero hero--primary">
|
||||||
<div className="container">
|
<div className="container">
|
||||||
<h1 className="hero__title">{title}</h1>
|
<Heading as="h1" className="hero__title">
|
||||||
|
{title}
|
||||||
|
</Heading>
|
||||||
<p className="hero__subtitle">{description}</p>
|
<p className="hero__subtitle">{description}</p>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
|
@ -17,6 +17,7 @@ import BlogLayout from '@theme/BlogLayout';
|
||||||
import TagsListByLetter from '@theme/TagsListByLetter';
|
import TagsListByLetter from '@theme/TagsListByLetter';
|
||||||
import type {Props} from '@theme/BlogTagsListPage';
|
import type {Props} from '@theme/BlogTagsListPage';
|
||||||
import SearchMetadata from '@theme/SearchMetadata';
|
import SearchMetadata from '@theme/SearchMetadata';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
export default function BlogTagsListPage({tags, sidebar}: Props): JSX.Element {
|
export default function BlogTagsListPage({tags, sidebar}: Props): JSX.Element {
|
||||||
const title = translateTagsPageTitle();
|
const title = translateTagsPageTitle();
|
||||||
|
@ -29,7 +30,7 @@ export default function BlogTagsListPage({tags, sidebar}: Props): JSX.Element {
|
||||||
<PageMetadata title={title} />
|
<PageMetadata title={title} />
|
||||||
<SearchMetadata tag="blog_tags_list" />
|
<SearchMetadata tag="blog_tags_list" />
|
||||||
<BlogLayout sidebar={sidebar}>
|
<BlogLayout sidebar={sidebar}>
|
||||||
<h1>{title}</h1>
|
<Heading as="h1">{title}</Heading>
|
||||||
<TagsListByLetter tags={tags} />
|
<TagsListByLetter tags={tags} />
|
||||||
</BlogLayout>
|
</BlogLayout>
|
||||||
</HtmlClassNameProvider>
|
</HtmlClassNameProvider>
|
||||||
|
|
|
@ -21,6 +21,7 @@ import SearchMetadata from '@theme/SearchMetadata';
|
||||||
import type {Props} from '@theme/BlogTagsPostsPage';
|
import type {Props} from '@theme/BlogTagsPostsPage';
|
||||||
import BlogPostItems from '@theme/BlogPostItems';
|
import BlogPostItems from '@theme/BlogPostItems';
|
||||||
import Unlisted from '@theme/Unlisted';
|
import Unlisted from '@theme/Unlisted';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
// Very simple pluralization: probably good enough for now
|
// Very simple pluralization: probably good enough for now
|
||||||
function useBlogPostsPlural() {
|
function useBlogPostsPlural() {
|
||||||
|
@ -73,7 +74,7 @@ function BlogTagsPostsPageContent({
|
||||||
<BlogLayout sidebar={sidebar}>
|
<BlogLayout sidebar={sidebar}>
|
||||||
{tag.unlisted && <Unlisted />}
|
{tag.unlisted && <Unlisted />}
|
||||||
<header className="margin-bottom--xl">
|
<header className="margin-bottom--xl">
|
||||||
<h1>{title}</h1>
|
<Heading as="h1">{title}</Heading>
|
||||||
<Link href={tag.allTagsPath}>
|
<Link href={tag.allTagsPath}>
|
||||||
<Translate
|
<Translate
|
||||||
id="theme.tags.tagsPageLink"
|
id="theme.tags.tagsPageLink"
|
||||||
|
|
|
@ -16,6 +16,7 @@ import isInternalUrl from '@docusaurus/isInternalUrl';
|
||||||
import {translate} from '@docusaurus/Translate';
|
import {translate} from '@docusaurus/Translate';
|
||||||
|
|
||||||
import type {Props} from '@theme/DocCard';
|
import type {Props} from '@theme/DocCard';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
import type {
|
import type {
|
||||||
PropSidebarItemCategory,
|
PropSidebarItemCategory,
|
||||||
PropSidebarItemLink,
|
PropSidebarItemLink,
|
||||||
|
@ -52,9 +53,12 @@ function CardLayout({
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<CardContainer href={href}>
|
<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}
|
{icon} {title}
|
||||||
</h2>
|
</Heading>
|
||||||
{description && (
|
{description && (
|
||||||
<p
|
<p
|
||||||
className={clsx('text--truncate', styles.cardDescription)}
|
className={clsx('text--truncate', styles.cardDescription)}
|
||||||
|
|
|
@ -18,6 +18,7 @@ import Translate, {translate} from '@docusaurus/Translate';
|
||||||
import SearchMetadata from '@theme/SearchMetadata';
|
import SearchMetadata from '@theme/SearchMetadata';
|
||||||
import type {Props} from '@theme/DocTagDocListPage';
|
import type {Props} from '@theme/DocTagDocListPage';
|
||||||
import Unlisted from '@theme/Unlisted';
|
import Unlisted from '@theme/Unlisted';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
// Very simple pluralization: probably good enough for now
|
// Very simple pluralization: probably good enough for now
|
||||||
function useNDocsTaggedPlural() {
|
function useNDocsTaggedPlural() {
|
||||||
|
@ -53,7 +54,7 @@ function DocItem({doc}: {doc: Props['tag']['items'][number]}): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<article className="margin-vert--lg">
|
<article className="margin-vert--lg">
|
||||||
<Link to={doc.permalink}>
|
<Link to={doc.permalink}>
|
||||||
<h2>{doc.title}</h2>
|
<Heading as="h2">{doc.title}</Heading>
|
||||||
</Link>
|
</Link>
|
||||||
{doc.description && <p>{doc.description}</p>}
|
{doc.description && <p>{doc.description}</p>}
|
||||||
</article>
|
</article>
|
||||||
|
@ -83,7 +84,7 @@ function DocTagDocListPageContent({
|
||||||
<main className="col col--8 col--offset-2">
|
<main className="col col--8 col--offset-2">
|
||||||
{tag.unlisted && <Unlisted />}
|
{tag.unlisted && <Unlisted />}
|
||||||
<header className="margin-bottom--xl">
|
<header className="margin-bottom--xl">
|
||||||
<h1>{title}</h1>
|
<Heading as="h1">{title}</Heading>
|
||||||
<Link href={tag.allTagsPath}>
|
<Link href={tag.allTagsPath}>
|
||||||
<Translate
|
<Translate
|
||||||
id="theme.tags.tagsPageLink"
|
id="theme.tags.tagsPageLink"
|
||||||
|
|
|
@ -16,6 +16,7 @@ import {
|
||||||
import TagsListByLetter from '@theme/TagsListByLetter';
|
import TagsListByLetter from '@theme/TagsListByLetter';
|
||||||
import SearchMetadata from '@theme/SearchMetadata';
|
import SearchMetadata from '@theme/SearchMetadata';
|
||||||
import type {Props} from '@theme/DocTagsListPage';
|
import type {Props} from '@theme/DocTagsListPage';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
function DocTagsListPageMetadata({
|
function DocTagsListPageMetadata({
|
||||||
title,
|
title,
|
||||||
|
@ -38,7 +39,7 @@ function DocTagsListPageContent({
|
||||||
<div className="container margin-vert--lg">
|
<div className="container margin-vert--lg">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<main className="col col--8 col--offset-2">
|
<main className="col col--8 col--offset-2">
|
||||||
<h1>{title}</h1>
|
<Heading as="h1">{title}</Heading>
|
||||||
<TagsListByLetter tags={tags} />
|
<TagsListByLetter tags={tags} />
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -9,6 +9,7 @@ import React from 'react';
|
||||||
import Translate from '@docusaurus/Translate';
|
import Translate from '@docusaurus/Translate';
|
||||||
import {ErrorBoundaryTryAgainButton} from '@docusaurus/theme-common';
|
import {ErrorBoundaryTryAgainButton} from '@docusaurus/theme-common';
|
||||||
import type {Props} from '@theme/Error';
|
import type {Props} from '@theme/Error';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
export default function ErrorPageContent({
|
export default function ErrorPageContent({
|
||||||
error,
|
error,
|
||||||
|
@ -18,13 +19,13 @@ export default function ErrorPageContent({
|
||||||
<main className="container margin-vert--xl">
|
<main className="container margin-vert--xl">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col col--6 col--offset-3">
|
<div className="col col--6 col--offset-3">
|
||||||
<h1 className="hero__title">
|
<Heading as="h1" className="hero__title">
|
||||||
<Translate
|
<Translate
|
||||||
id="theme.ErrorPageContent.title"
|
id="theme.ErrorPageContent.title"
|
||||||
description="The title of the fallback page when the page crashed">
|
description="The title of the fallback page when the page crashed">
|
||||||
This page crashed.
|
This page crashed.
|
||||||
</Translate>
|
</Translate>
|
||||||
</h1>
|
</Heading>
|
||||||
<p>{error.message}</p>
|
<p>{error.message}</p>
|
||||||
<div>
|
<div>
|
||||||
<ErrorBoundaryTryAgainButton onClick={tryAgain} />
|
<ErrorBoundaryTryAgainButton onClick={tryAgain} />
|
||||||
|
|
|
@ -9,19 +9,20 @@ import React from 'react';
|
||||||
import clsx from 'clsx';
|
import clsx from 'clsx';
|
||||||
import Translate from '@docusaurus/Translate';
|
import Translate from '@docusaurus/Translate';
|
||||||
import type {Props} from '@theme/NotFound/Content';
|
import type {Props} from '@theme/NotFound/Content';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
export default function NotFoundContent({className}: Props): JSX.Element {
|
export default function NotFoundContent({className}: Props): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<main className={clsx('container margin-vert--xl', className)}>
|
<main className={clsx('container margin-vert--xl', className)}>
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col col--6 col--offset-3">
|
<div className="col col--6 col--offset-3">
|
||||||
<h1 className="hero__title">
|
<Heading as="h1" className="hero__title">
|
||||||
<Translate
|
<Translate
|
||||||
id="theme.NotFound.title"
|
id="theme.NotFound.title"
|
||||||
description="The title of the 404 page">
|
description="The title of the 404 page">
|
||||||
Page Not Found
|
Page Not Found
|
||||||
</Translate>
|
</Translate>
|
||||||
</h1>
|
</Heading>
|
||||||
<p>
|
<p>
|
||||||
<Translate
|
<Translate
|
||||||
id="theme.NotFound.p1"
|
id="theme.NotFound.p1"
|
||||||
|
|
|
@ -9,13 +9,15 @@ import React from 'react';
|
||||||
import {listTagsByLetters, type TagLetterEntry} from '@docusaurus/theme-common';
|
import {listTagsByLetters, type TagLetterEntry} from '@docusaurus/theme-common';
|
||||||
import Tag from '@theme/Tag';
|
import Tag from '@theme/Tag';
|
||||||
import type {Props} from '@theme/TagsListByLetter';
|
import type {Props} from '@theme/TagsListByLetter';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
function TagLetterEntryItem({letterEntry}: {letterEntry: TagLetterEntry}) {
|
function TagLetterEntryItem({letterEntry}: {letterEntry: TagLetterEntry}) {
|
||||||
return (
|
return (
|
||||||
<article>
|
<article>
|
||||||
<h2>{letterEntry.letter}</h2>
|
<Heading as="h2" id={letterEntry.letter}>
|
||||||
|
{letterEntry.letter}
|
||||||
|
</Heading>
|
||||||
<ul className="padding--none">
|
<ul className="padding--none">
|
||||||
{letterEntry.tags.map((tag) => (
|
{letterEntry.tags.map((tag) => (
|
||||||
<li key={tag.permalink} className={styles.tag}>
|
<li key={tag.permalink} className={styles.tag}>
|
||||||
|
|
|
@ -33,7 +33,7 @@ import {
|
||||||
useSearchResultUrlProcessor,
|
useSearchResultUrlProcessor,
|
||||||
} from '@docusaurus/theme-search-algolia/client';
|
} from '@docusaurus/theme-search-algolia/client';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
// Very simple pluralization: probably good enough for now
|
// Very simple pluralization: probably good enough for now
|
||||||
|
@ -374,7 +374,7 @@ function SearchPageContent(): JSX.Element {
|
||||||
</Head>
|
</Head>
|
||||||
|
|
||||||
<div className="container margin-vert--lg">
|
<div className="container margin-vert--lg">
|
||||||
<h1>{getTitle()}</h1>
|
<Heading as="h1">{getTitle()}</Heading>
|
||||||
|
|
||||||
<form className="row" onSubmit={(e) => e.preventDefault()}>
|
<form className="row" onSubmit={(e) => e.preventDefault()}>
|
||||||
<div
|
<div
|
||||||
|
@ -455,9 +455,9 @@ function SearchPageContent(): JSX.Element {
|
||||||
{searchResultState.items.map(
|
{searchResultState.items.map(
|
||||||
({title, url, summary, breadcrumbs}, i) => (
|
({title, url, summary, breadcrumbs}, i) => (
|
||||||
<article key={i} className={styles.searchResultItem}>
|
<article key={i} className={styles.searchResultItem}>
|
||||||
<h2 className={styles.searchResultItemHeading}>
|
<Heading as="h2" className={styles.searchResultItemHeading}>
|
||||||
<Link to={url} dangerouslySetInnerHTML={{__html: title}} />
|
<Link to={url} dangerouslySetInnerHTML={{__html: title}} />
|
||||||
</h2>
|
</Heading>
|
||||||
|
|
||||||
{breadcrumbs.length > 0 && (
|
{breadcrumbs.length > 0 && (
|
||||||
<nav aria-label="breadcrumbs">
|
<nav aria-label="breadcrumbs">
|
||||||
|
|
|
@ -15,6 +15,7 @@ export = {
|
||||||
rules: {
|
rules: {
|
||||||
'@docusaurus/string-literal-i18n-messages': 'error',
|
'@docusaurus/string-literal-i18n-messages': 'error',
|
||||||
'@docusaurus/no-html-links': 'warn',
|
'@docusaurus/no-html-links': 'warn',
|
||||||
|
'@docusaurus/prefer-docusaurus-heading': 'warn',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
all: {
|
all: {
|
||||||
|
@ -23,6 +24,7 @@ export = {
|
||||||
'@docusaurus/string-literal-i18n-messages': 'error',
|
'@docusaurus/string-literal-i18n-messages': 'error',
|
||||||
'@docusaurus/no-untranslated-text': 'warn',
|
'@docusaurus/no-untranslated-text': 'warn',
|
||||||
'@docusaurus/no-html-links': 'warn',
|
'@docusaurus/no-html-links': 'warn',
|
||||||
|
'@docusaurus/prefer-docusaurus-heading': 'warn',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -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,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import noHtmlLinks from './no-html-links';
|
import noHtmlLinks from './no-html-links';
|
||||||
|
import preferDocusaurusHeading from './prefer-docusaurus-heading';
|
||||||
import noUntranslatedText from './no-untranslated-text';
|
import noUntranslatedText from './no-untranslated-text';
|
||||||
import stringLiteralI18nMessages from './string-literal-i18n-messages';
|
import stringLiteralI18nMessages from './string-literal-i18n-messages';
|
||||||
|
|
||||||
|
@ -13,4 +14,5 @@ export default {
|
||||||
'no-untranslated-text': noUntranslatedText,
|
'no-untranslated-text': noUntranslatedText,
|
||||||
'string-literal-i18n-messages': stringLiteralI18nMessages,
|
'string-literal-i18n-messages': stringLiteralI18nMessages,
|
||||||
'no-html-links': noHtmlLinks,
|
'no-html-links': noHtmlLinks,
|
||||||
|
'prefer-docusaurus-heading': preferDocusaurusHeading,
|
||||||
};
|
};
|
||||||
|
|
|
@ -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'});
|
||||||
|
},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
|
@ -7,12 +7,13 @@
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
// See https://github.com/facebook/docusaurus/issues/6337#issuecomment-1012913647
|
// See https://github.com/facebook/docusaurus/issues/6337#issuecomment-1012913647
|
||||||
export default function Analytics(): JSX.Element {
|
export default function Analytics(): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
<h1>Test Analytics</h1>
|
<Heading as="h1">Test Analytics</Heading>
|
||||||
<div>
|
<div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Interpolate from '@docusaurus/Interpolate';
|
import Interpolate from '@docusaurus/Interpolate';
|
||||||
import Layout from '@theme/Layout';
|
import Layout from '@theme/Layout';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
import ErrorBoundaryTestButton from '@site/src/components/ErrorBoundaryTestButton';
|
import ErrorBoundaryTestButton from '@site/src/components/ErrorBoundaryTestButton';
|
||||||
|
|
||||||
export default function ErrorBoundaryTests(): JSX.Element {
|
export default function ErrorBoundaryTests(): JSX.Element {
|
||||||
|
@ -17,7 +17,7 @@ export default function ErrorBoundaryTests(): JSX.Element {
|
||||||
<ErrorBoundaryTestButton>Crash outside layout</ErrorBoundaryTestButton>
|
<ErrorBoundaryTestButton>Crash outside layout</ErrorBoundaryTestButton>
|
||||||
<Layout>
|
<Layout>
|
||||||
<main className="container margin-vert--xl">
|
<main className="container margin-vert--xl">
|
||||||
<h1>Error boundary tests</h1>
|
<Heading as="h1">Error boundary tests</Heading>
|
||||||
<div>
|
<div>
|
||||||
<ErrorBoundaryTestButton>
|
<ErrorBoundaryTestButton>
|
||||||
Crash inside layout
|
Crash inside layout
|
||||||
|
|
|
@ -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/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/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/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
|
✅ = recommended
|
||||||
|
|
||||||
|
|
|
@ -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>
|
||||||
|
```
|
|
@ -12,6 +12,7 @@ import clsx from 'clsx';
|
||||||
import Translate from '@docusaurus/Translate';
|
import Translate from '@docusaurus/Translate';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
import Image from '@theme/IdealImage';
|
import Image from '@theme/IdealImage';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
const Playgrounds = [
|
const Playgrounds = [
|
||||||
{
|
{
|
||||||
|
@ -64,7 +65,7 @@ function PlaygroundCard({name, image, url, description}: Props) {
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
<div className="card__body">
|
<div className="card__body">
|
||||||
<h3>{name}</h3>
|
<Heading as="h3">{name}</Heading>
|
||||||
<p>{description}</p>
|
<p>{description}</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="card__footer">
|
<div className="card__footer">
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import React, {type ReactNode} from 'react';
|
import React, {type ReactNode} from 'react';
|
||||||
import Translate from '@docusaurus/Translate';
|
import Translate from '@docusaurus/Translate';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
function WebsiteLink({to, children}: {to: string; children?: ReactNode}) {
|
function WebsiteLink({to, children}: {to: string; children?: ReactNode}) {
|
||||||
return (
|
return (
|
||||||
|
@ -45,7 +46,9 @@ function TeamProfileCard({
|
||||||
alt={`${name}'s avatar`}
|
alt={`${name}'s avatar`}
|
||||||
/>
|
/>
|
||||||
<div className="avatar__intro">
|
<div className="avatar__intro">
|
||||||
<h3 className="avatar__name">{name}</h3>
|
<Heading as="h3" className="avatar__name">
|
||||||
|
{name}
|
||||||
|
</Heading>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -25,12 +25,13 @@ import ProductHuntCard from '@site/src/components/ProductHuntCard';
|
||||||
import HackerNewsIcon from '@site/src/components/HackerNewsIcon';
|
import HackerNewsIcon from '@site/src/components/HackerNewsIcon';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
import 'react-lite-youtube-embed/dist/LiteYouTubeEmbed.css';
|
import 'react-lite-youtube-embed/dist/LiteYouTubeEmbed.css';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
function HeroBanner() {
|
function HeroBanner() {
|
||||||
return (
|
return (
|
||||||
<div className={styles.hero} data-theme="dark">
|
<div className={styles.hero} data-theme="dark">
|
||||||
<div className={styles.heroInner}>
|
<div className={styles.heroInner}>
|
||||||
<h1 className={styles.heroProjectTagline}>
|
<Heading as="h1" className={styles.heroProjectTagline}>
|
||||||
<img
|
<img
|
||||||
alt={translate({message: 'Docusaurus with Keytar'})}
|
alt={translate({message: 'Docusaurus with Keytar'})}
|
||||||
className={styles.heroLogo}
|
className={styles.heroLogo}
|
||||||
|
@ -51,7 +52,7 @@ function HeroBanner() {
|
||||||
}),
|
}),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
</h1>
|
</Heading>
|
||||||
<div className={styles.indexCtas}>
|
<div className={styles.indexCtas}>
|
||||||
<Link className="button button--primary" to="/docs">
|
<Link className="button button--primary" to="/docs">
|
||||||
<Translate>Get Started</Translate>
|
<Translate>Get Started</Translate>
|
||||||
|
@ -109,9 +110,9 @@ function TweetsSection() {
|
||||||
return (
|
return (
|
||||||
<div className={clsx(styles.section, styles.sectionAlt)}>
|
<div className={clsx(styles.section, styles.sectionAlt)}>
|
||||||
<div className="container">
|
<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>
|
<Translate>Loved by many engineers</Translate>
|
||||||
</h2>
|
</Heading>
|
||||||
<div className={clsx('row', styles.tweetsSection)}>
|
<div className={clsx('row', styles.tweetsSection)}>
|
||||||
{tweetColumns.map((tweetItems, i) => (
|
{tweetColumns.map((tweetItems, i) => (
|
||||||
<div className="col col--4" key={i}>
|
<div className="col col--4" key={i}>
|
||||||
|
@ -161,9 +162,9 @@ function VideoContainer() {
|
||||||
<div className="container text--center margin-bottom--xl">
|
<div className="container text--center margin-bottom--xl">
|
||||||
<div className="row">
|
<div className="row">
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<h2>
|
<Heading as="h2">
|
||||||
<Translate>Check it out in the intro video</Translate>
|
<Translate>Check it out in the intro video</Translate>
|
||||||
</h2>
|
</Heading>
|
||||||
<div className="video-container">
|
<div className="video-container">
|
||||||
<LiteYouTubeEmbed
|
<LiteYouTubeEmbed
|
||||||
id="_An9EsKPhp0"
|
id="_An9EsKPhp0"
|
||||||
|
@ -198,7 +199,9 @@ function Feature({
|
||||||
src={withBaseUrl(feature.image.src)}
|
src={withBaseUrl(feature.image.src)}
|
||||||
loading="lazy"
|
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>
|
<p className="padding-horiz--md">{feature.text}</p>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -210,9 +213,9 @@ function FeaturesContainer() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="container text--center">
|
<div className="container text--center">
|
||||||
<h2>
|
<Heading as="h2">
|
||||||
<Translate>Main features</Translate>
|
<Translate>Main features</Translate>
|
||||||
</h2>
|
</Heading>
|
||||||
<div className="row margin-bottom--lg">
|
<div className="row margin-bottom--lg">
|
||||||
{firstRow.map((feature, idx) => (
|
{firstRow.map((feature, idx) => (
|
||||||
<Feature feature={feature} key={idx} />
|
<Feature feature={feature} key={idx} />
|
||||||
|
|
|
@ -19,6 +19,7 @@ import {
|
||||||
type Tag,
|
type Tag,
|
||||||
} from '@site/src/data/users';
|
} from '@site/src/data/users';
|
||||||
import {sortBy} from '@site/src/utils/jsUtils';
|
import {sortBy} from '@site/src/utils/jsUtils';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
import Tooltip from '../ShowcaseTooltip';
|
import Tooltip from '../ShowcaseTooltip';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
|
@ -76,11 +77,11 @@ function ShowcaseCard({user}: {user: User}) {
|
||||||
</div>
|
</div>
|
||||||
<div className="card__body">
|
<div className="card__body">
|
||||||
<div className={clsx(styles.showcaseCardHeader)}>
|
<div className={clsx(styles.showcaseCardHeader)}>
|
||||||
<h4 className={styles.showcaseCardTitle}>
|
<Heading as="h4" className={styles.showcaseCardTitle}>
|
||||||
<Link href={user.website} className={styles.showcaseCardLink}>
|
<Link href={user.website} className={styles.showcaseCardLink}>
|
||||||
{user.title}
|
{user.title}
|
||||||
</Link>
|
</Link>
|
||||||
</h4>
|
</Heading>
|
||||||
{user.tags.includes('favorite') && (
|
{user.tags.includes('favorite') && (
|
||||||
<FavoriteIcon svgClass={styles.svgIconFavorite} size="small" />
|
<FavoriteIcon svgClass={styles.svgIconFavorite} size="small" />
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -22,6 +22,7 @@ import {
|
||||||
type User,
|
type User,
|
||||||
type TagType,
|
type TagType,
|
||||||
} from '@site/src/data/users';
|
} from '@site/src/data/users';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
import ShowcaseTagSelect, {
|
import ShowcaseTagSelect, {
|
||||||
readSearchTags,
|
readSearchTags,
|
||||||
} from './_components/ShowcaseTagSelect';
|
} from './_components/ShowcaseTagSelect';
|
||||||
|
@ -122,7 +123,7 @@ function useFilteredUsers() {
|
||||||
function ShowcaseHeader() {
|
function ShowcaseHeader() {
|
||||||
return (
|
return (
|
||||||
<section className="margin-top--lg margin-bottom--lg text--center">
|
<section className="margin-top--lg margin-bottom--lg text--center">
|
||||||
<h1>{TITLE}</h1>
|
<Heading as="h1">{TITLE}</Heading>
|
||||||
<p>{DESCRIPTION}</p>
|
<p>{DESCRIPTION}</p>
|
||||||
<Link className="button button--primary" to={SUBMIT_URL}>
|
<Link className="button button--primary" to={SUBMIT_URL}>
|
||||||
<Translate id="showcase.header.button">
|
<Translate id="showcase.header.button">
|
||||||
|
@ -157,9 +158,9 @@ function ShowcaseFilters() {
|
||||||
<section className="container margin-top--l margin-bottom--lg">
|
<section className="container margin-top--l margin-bottom--lg">
|
||||||
<div className={clsx('margin-bottom--sm', styles.filterCheckbox)}>
|
<div className={clsx('margin-bottom--sm', styles.filterCheckbox)}>
|
||||||
<div>
|
<div>
|
||||||
<h2>
|
<Heading as="h2">
|
||||||
<Translate id="showcase.filters.title">Filters</Translate>
|
<Translate id="showcase.filters.title">Filters</Translate>
|
||||||
</h2>
|
</Heading>
|
||||||
<span>{siteCountPlural(filteredUsers.length)}</span>
|
<span>{siteCountPlural(filteredUsers.length)}</span>
|
||||||
</div>
|
</div>
|
||||||
<ShowcaseFilterToggle />
|
<ShowcaseFilterToggle />
|
||||||
|
@ -255,9 +256,9 @@ function ShowcaseCards() {
|
||||||
return (
|
return (
|
||||||
<section className="margin-top--lg margin-bottom--xl">
|
<section className="margin-top--lg margin-bottom--xl">
|
||||||
<div className="container padding-vert--md text--center">
|
<div className="container padding-vert--md text--center">
|
||||||
<h2>
|
<Heading as="h2">
|
||||||
<Translate id="showcase.usersList.noResult">No result</Translate>
|
<Translate id="showcase.usersList.noResult">No result</Translate>
|
||||||
</h2>
|
</Heading>
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -275,11 +276,11 @@ function ShowcaseCards() {
|
||||||
'margin-bottom--md',
|
'margin-bottom--md',
|
||||||
styles.showcaseFavoriteHeader,
|
styles.showcaseFavoriteHeader,
|
||||||
)}>
|
)}>
|
||||||
<h2>
|
<Heading as="h2">
|
||||||
<Translate id="showcase.favoritesList.title">
|
<Translate id="showcase.favoritesList.title">
|
||||||
Our favorites
|
Our favorites
|
||||||
</Translate>
|
</Translate>
|
||||||
</h2>
|
</Heading>
|
||||||
<FavoriteIcon svgClass={styles.svgIconFavorite} />
|
<FavoriteIcon svgClass={styles.svgIconFavorite} />
|
||||||
<SearchBar />
|
<SearchBar />
|
||||||
</div>
|
</div>
|
||||||
|
@ -296,9 +297,9 @@ function ShowcaseCards() {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="container margin-top--lg">
|
<div className="container margin-top--lg">
|
||||||
<h2 className={styles.showcaseHeader}>
|
<Heading as="h2" className={styles.showcaseHeader}>
|
||||||
<Translate id="showcase.usersList.allUsers">All sites</Translate>
|
<Translate id="showcase.usersList.allUsers">All sites</Translate>
|
||||||
</h2>
|
</Heading>
|
||||||
<ul className={clsx('clean-list', styles.showcaseList)}>
|
<ul className={clsx('clean-list', styles.showcaseList)}>
|
||||||
{otherUsers.map((user) => (
|
{otherUsers.map((user) => (
|
||||||
<ShowcaseCard key={user.title} user={user} />
|
<ShowcaseCard key={user.title} user={user} />
|
||||||
|
|
|
@ -168,11 +168,11 @@ export default function Version(): JSX.Element {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="margin-bottom--lg">
|
<div className="margin-bottom--lg">
|
||||||
<h3 id="legacy">
|
<Heading as="h3" id="legacy">
|
||||||
<Translate id="versionsPage.legacy.title">
|
<Translate id="versionsPage.legacy.title">
|
||||||
Docusaurus v1 (Legacy)
|
Docusaurus v1 (Legacy)
|
||||||
</Translate>
|
</Translate>
|
||||||
</h3>
|
</Heading>
|
||||||
<p>
|
<p>
|
||||||
<Translate id="versionsPage.legacy.description">
|
<Translate id="versionsPage.legacy.description">
|
||||||
Here you can find documentation for legacy version of Docusaurus.
|
Here you can find documentation for legacy version of Docusaurus.
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Translate from '@docusaurus/Translate';
|
import Translate from '@docusaurus/Translate';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
|
||||||
function TwitterLink() {
|
function TwitterLink() {
|
||||||
|
@ -63,7 +64,9 @@ export default function ChangelogListHeader({
|
||||||
}): JSX.Element {
|
}): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<header className="margin-bottom--lg">
|
<header className="margin-bottom--lg">
|
||||||
<h1 style={{fontSize: '3rem'}}>{blogTitle}</h1>
|
<Heading as="h1" style={{fontSize: '3rem'}}>
|
||||||
|
{blogTitle}
|
||||||
|
</Heading>
|
||||||
<p>
|
<p>
|
||||||
<Translate
|
<Translate
|
||||||
id="changelog.description"
|
id="changelog.description"
|
||||||
|
|
|
@ -8,11 +8,14 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import type {Props} from '@theme/Admonition';
|
import type {Props} from '@theme/Admonition';
|
||||||
import DefaultAdmonitionTypes from '@theme-original/Admonition/Types';
|
import DefaultAdmonitionTypes from '@theme-original/Admonition/Types';
|
||||||
|
import Heading from '@theme/Heading';
|
||||||
|
|
||||||
function MyCustomAdmonition(props: Props): JSX.Element {
|
function MyCustomAdmonition(props: Props): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<div style={{border: 'solid red', padding: 10}}>
|
<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>{props.children}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue