mirror of
https://github.com/facebook/docusaurus.git
synced 2025-06-10 14:52:29 +02:00
feat: Add docs-related stable classnames (#5445)
This commit is contained in:
parent
280a8abac9
commit
3a312d964d
12 changed files with 96 additions and 22 deletions
|
@ -20,6 +20,7 @@ import TOCCollapsible from '@theme/TOCCollapsible';
|
||||||
import {MainHeading} from '@theme/Heading';
|
import {MainHeading} from '@theme/Heading';
|
||||||
|
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
import {ThemeClassNames} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
export default function DocItem(props: Props): JSX.Element {
|
export default function DocItem(props: Props): JSX.Element {
|
||||||
const {content: DocContent, versionMetadata} = props;
|
const {content: DocContent, versionMetadata} = props;
|
||||||
|
@ -67,7 +68,11 @@ export default function DocItem(props: Props): JSX.Element {
|
||||||
<div className={styles.docItemContainer}>
|
<div className={styles.docItemContainer}>
|
||||||
<article>
|
<article>
|
||||||
{showVersionBadge && (
|
{showVersionBadge && (
|
||||||
<span className="badge badge--secondary">
|
<span
|
||||||
|
className={clsx(
|
||||||
|
ThemeClassNames.docs.docVersionBadge,
|
||||||
|
'badge badge--secondary',
|
||||||
|
)}>
|
||||||
Version: {versionMetadata.label}
|
Version: {versionMetadata.label}
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
|
@ -75,11 +80,15 @@ export default function DocItem(props: Props): JSX.Element {
|
||||||
{canRenderTOC && (
|
{canRenderTOC && (
|
||||||
<TOCCollapsible
|
<TOCCollapsible
|
||||||
toc={DocContent.toc}
|
toc={DocContent.toc}
|
||||||
className={styles.tocMobile}
|
className={clsx(
|
||||||
|
ThemeClassNames.docs.docTocMobile,
|
||||||
|
styles.tocMobile,
|
||||||
|
)}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="markdown">
|
<div
|
||||||
|
className={clsx(ThemeClassNames.docs.docMarkdown, 'markdown')}>
|
||||||
{/*
|
{/*
|
||||||
Title can be declared inside md content or declared through frontmatter and added manually
|
Title can be declared inside md content or declared through frontmatter and added manually
|
||||||
To make both cases consistent, the added title is added under the same div.markdown block
|
To make both cases consistent, the added title is added under the same div.markdown block
|
||||||
|
@ -98,7 +107,10 @@ export default function DocItem(props: Props): JSX.Element {
|
||||||
</div>
|
</div>
|
||||||
{renderTocDesktop && (
|
{renderTocDesktop && (
|
||||||
<div className="col col--3">
|
<div className="col col--3">
|
||||||
<TOC toc={DocContent.toc} />
|
<TOC
|
||||||
|
toc={DocContent.toc}
|
||||||
|
className={ThemeClassNames.docs.docTocDesktop}
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -16,10 +16,15 @@ import TagsListInline, {
|
||||||
} from '@theme/TagsListInline';
|
} from '@theme/TagsListInline';
|
||||||
|
|
||||||
import styles from './styles.module.css';
|
import styles from './styles.module.css';
|
||||||
|
import {ThemeClassNames} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
function TagsRow(props: TagsListInlineProps) {
|
function TagsRow(props: TagsListInlineProps) {
|
||||||
return (
|
return (
|
||||||
<div className="row margin-bottom--sm">
|
<div
|
||||||
|
className={clsx(
|
||||||
|
ThemeClassNames.docs.docFooterTagsRow,
|
||||||
|
'row margin-bottom--sm',
|
||||||
|
)}>
|
||||||
<div className="col">
|
<div className="col">
|
||||||
<TagsListInline {...props} />
|
<TagsListInline {...props} />
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,7 +43,7 @@ function EditMetaRow({
|
||||||
formattedLastUpdatedAt,
|
formattedLastUpdatedAt,
|
||||||
}: EditMetaRowProps) {
|
}: EditMetaRowProps) {
|
||||||
return (
|
return (
|
||||||
<div className="row">
|
<div className={clsx(ThemeClassNames.docs.docFooterEditMetaRow, 'row')}>
|
||||||
<div className="col">{editUrl && <EditThisPage editUrl={editUrl} />}</div>
|
<div className="col">{editUrl && <EditThisPage editUrl={editUrl} />}</div>
|
||||||
|
|
||||||
<div className={clsx('col', styles.lastUpdated)}>
|
<div className={clsx('col', styles.lastUpdated)}>
|
||||||
|
@ -75,7 +80,8 @@ export default function DocItemFooter(props: Props): JSX.Element {
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<footer className="docusaurus-mt-lg">
|
<footer
|
||||||
|
className={clsx(ThemeClassNames.docs.docFooter, 'docusaurus-mt-lg')}>
|
||||||
{canDisplayTagsRow && <TagsRow tags={tags} />}
|
{canDisplayTagsRow && <TagsRow tags={tags} />}
|
||||||
{canDisplayEditMetaRow && (
|
{canDisplayEditMetaRow && (
|
||||||
<EditMetaRow
|
<EditMetaRow
|
||||||
|
|
|
@ -55,7 +55,7 @@ function DocPageContent({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout
|
<Layout
|
||||||
wrapperClassName={ThemeClassNames.wrapper.docPages}
|
wrapperClassName={ThemeClassNames.wrapper.docsPages}
|
||||||
pageClassName={ThemeClassNames.page.docsDocPage}
|
pageClassName={ThemeClassNames.page.docsDocPage}
|
||||||
searchMetadatas={{
|
searchMetadatas={{
|
||||||
version,
|
version,
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {
|
||||||
useAnnouncementBar,
|
useAnnouncementBar,
|
||||||
MobileSecondaryMenuFiller,
|
MobileSecondaryMenuFiller,
|
||||||
MobileSecondaryMenuComponent,
|
MobileSecondaryMenuComponent,
|
||||||
|
ThemeClassNames,
|
||||||
} from '@docusaurus/theme-common';
|
} from '@docusaurus/theme-common';
|
||||||
import useWindowSize from '@theme/hooks/useWindowSize';
|
import useWindowSize from '@theme/hooks/useWindowSize';
|
||||||
import useScrollPosition from '@theme/hooks/useScrollPosition';
|
import useScrollPosition from '@theme/hooks/useScrollPosition';
|
||||||
|
@ -78,7 +79,7 @@ function DocSidebarDesktop({path, sidebar, onCollapse, isHidden}: Props) {
|
||||||
[styles.menuWithAnnouncementBar]:
|
[styles.menuWithAnnouncementBar]:
|
||||||
!isAnnouncementBarClosed && showAnnouncementBar,
|
!isAnnouncementBarClosed && showAnnouncementBar,
|
||||||
})}>
|
})}>
|
||||||
<ul className="menu__list">
|
<ul className={clsx(ThemeClassNames.docs.docSidebarMenu, 'menu__list')}>
|
||||||
<DocSidebarItems items={sidebar} activePath={path} />
|
<DocSidebarItems items={sidebar} activePath={path} />
|
||||||
</ul>
|
</ul>
|
||||||
</nav>
|
</nav>
|
||||||
|
@ -93,7 +94,7 @@ const DocSidebarMobileSecondaryMenu: MobileSecondaryMenuComponent<Props> = ({
|
||||||
path,
|
path,
|
||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<ul className="menu__list">
|
<ul className={clsx(ThemeClassNames.docs.docSidebarMenu, 'menu__list')}>
|
||||||
<DocSidebarItems
|
<DocSidebarItems
|
||||||
items={sidebar}
|
items={sidebar}
|
||||||
activePath={path}
|
activePath={path}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import {
|
||||||
usePrevious,
|
usePrevious,
|
||||||
Collapsible,
|
Collapsible,
|
||||||
useCollapsible,
|
useCollapsible,
|
||||||
|
ThemeClassNames,
|
||||||
} from '@docusaurus/theme-common';
|
} from '@docusaurus/theme-common';
|
||||||
import Link from '@docusaurus/Link';
|
import Link from '@docusaurus/Link';
|
||||||
import isInternalUrl from '@docusaurus/isInternalUrl';
|
import isInternalUrl from '@docusaurus/isInternalUrl';
|
||||||
|
@ -117,9 +118,13 @@ function DocSidebarItemCategory({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<li
|
<li
|
||||||
className={clsx('menu__list-item', {
|
className={clsx(
|
||||||
'menu__list-item--collapsed': collapsed,
|
ThemeClassNames.docs.docSidebarItemCategory,
|
||||||
})}>
|
'menu__list-item',
|
||||||
|
{
|
||||||
|
'menu__list-item--collapsed': collapsed,
|
||||||
|
},
|
||||||
|
)}>
|
||||||
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
|
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
|
||||||
<a
|
<a
|
||||||
className={clsx('menu__link', {
|
className={clsx('menu__link', {
|
||||||
|
@ -161,7 +166,12 @@ function DocSidebarItemLink({
|
||||||
const {href, label} = item;
|
const {href, label} = item;
|
||||||
const isActive = isActiveSidebarItem(item, activePath);
|
const isActive = isActiveSidebarItem(item, activePath);
|
||||||
return (
|
return (
|
||||||
<li className="menu__list-item" key={label}>
|
<li
|
||||||
|
className={clsx(
|
||||||
|
ThemeClassNames.docs.docSidebarItemLink,
|
||||||
|
'menu__list-item',
|
||||||
|
)}
|
||||||
|
key={label}>
|
||||||
<Link
|
<Link
|
||||||
className={clsx('menu__link', {
|
className={clsx('menu__link', {
|
||||||
'menu__link--active': isActive,
|
'menu__link--active': isActive,
|
||||||
|
|
|
@ -63,7 +63,7 @@ export default function DocTagDocListPage({tag}: Props): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<Layout
|
<Layout
|
||||||
title={title}
|
title={title}
|
||||||
wrapperClassName={ThemeClassNames.wrapper.docPages}
|
wrapperClassName={ThemeClassNames.wrapper.docsPages}
|
||||||
pageClassName={ThemeClassNames.page.docsTagDocListPage}
|
pageClassName={ThemeClassNames.page.docsTagDocListPage}
|
||||||
searchMetadatas={{
|
searchMetadatas={{
|
||||||
// assign unique search tag to exclude this page from search results!
|
// assign unique search tag to exclude this page from search results!
|
||||||
|
|
|
@ -20,7 +20,7 @@ function DocTagsListPage({tags}: Props): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<Layout
|
<Layout
|
||||||
title={title}
|
title={title}
|
||||||
wrapperClassName={ThemeClassNames.wrapper.docPages}
|
wrapperClassName={ThemeClassNames.wrapper.docsPages}
|
||||||
pageClassName={ThemeClassNames.page.docsTagsListPage}
|
pageClassName={ThemeClassNames.page.docsTagsListPage}
|
||||||
searchMetadatas={{
|
searchMetadatas={{
|
||||||
// assign unique search tag to exclude this page from search results!
|
// assign unique search tag to exclude this page from search results!
|
||||||
|
|
|
@ -14,9 +14,13 @@ import {
|
||||||
useDocVersionSuggestions,
|
useDocVersionSuggestions,
|
||||||
GlobalVersion,
|
GlobalVersion,
|
||||||
} from '@theme/hooks/useDocs';
|
} from '@theme/hooks/useDocs';
|
||||||
import {useDocsPreferredVersion} from '@docusaurus/theme-common';
|
import {
|
||||||
|
ThemeClassNames,
|
||||||
|
useDocsPreferredVersion,
|
||||||
|
} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
import type {Props} from '@theme/DocVersionBanner';
|
import type {Props} from '@theme/DocVersionBanner';
|
||||||
|
import clsx from 'clsx';
|
||||||
|
|
||||||
type BannerLabelComponentProps = {
|
type BannerLabelComponentProps = {
|
||||||
siteTitle: string;
|
siteTitle: string;
|
||||||
|
@ -131,7 +135,12 @@ function DocVersionBannerEnabled({versionMetadata}: Props): JSX.Element {
|
||||||
latestDocSuggestion ?? getVersionMainDoc(latestVersionSuggestion);
|
latestDocSuggestion ?? getVersionMainDoc(latestVersionSuggestion);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="alert alert--warning margin-bottom--md" role="alert">
|
<div
|
||||||
|
className={clsx(
|
||||||
|
ThemeClassNames.docs.docVersionBanner,
|
||||||
|
'alert alert--warning margin-bottom--md',
|
||||||
|
)}
|
||||||
|
role="alert">
|
||||||
<div>
|
<div>
|
||||||
<BannerLabel siteTitle={siteTitle} versionMetadata={versionMetadata} />
|
<BannerLabel siteTitle={siteTitle} versionMetadata={versionMetadata} />
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,10 +10,15 @@ import Translate from '@docusaurus/Translate';
|
||||||
|
|
||||||
import type {Props} from '@theme/EditThisPage';
|
import type {Props} from '@theme/EditThisPage';
|
||||||
import IconEdit from '@theme/IconEdit';
|
import IconEdit from '@theme/IconEdit';
|
||||||
|
import {ThemeClassNames} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
export default function EditThisPage({editUrl}: Props): JSX.Element {
|
export default function EditThisPage({editUrl}: Props): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<a href={editUrl} target="_blank" rel="noreferrer noopener">
|
<a
|
||||||
|
href={editUrl}
|
||||||
|
target="_blank"
|
||||||
|
rel="noreferrer noopener"
|
||||||
|
className={ThemeClassNames.common.editThisPage}>
|
||||||
<IconEdit />
|
<IconEdit />
|
||||||
<Translate
|
<Translate
|
||||||
id="theme.common.editThisPage"
|
id="theme.common.editThisPage"
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Translate from '@docusaurus/Translate';
|
import Translate from '@docusaurus/Translate';
|
||||||
import type {Props} from '@theme/LastUpdated';
|
import type {Props} from '@theme/LastUpdated';
|
||||||
|
import {ThemeClassNames} from '@docusaurus/theme-common';
|
||||||
|
|
||||||
function LastUpdatedAtDate({
|
function LastUpdatedAtDate({
|
||||||
lastUpdatedAt,
|
lastUpdatedAt,
|
||||||
|
@ -57,7 +58,7 @@ export default function LastUpdated({
|
||||||
lastUpdatedBy,
|
lastUpdatedBy,
|
||||||
}: Props): JSX.Element {
|
}: Props): JSX.Element {
|
||||||
return (
|
return (
|
||||||
<>
|
<span className={ThemeClassNames.common.lastUpdated}>
|
||||||
<Translate
|
<Translate
|
||||||
id="theme.lastUpdated.lastUpdatedAtBy"
|
id="theme.lastUpdated.lastUpdatedAtBy"
|
||||||
description="The sentence used to display when a page has been last updated, and by who"
|
description="The sentence used to display when a page has been last updated, and by who"
|
||||||
|
@ -84,6 +85,6 @@ export default function LastUpdated({
|
||||||
<small> (Simulated during dev for better perf)</small>
|
<small> (Simulated during dev for better perf)</small>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -579,6 +579,7 @@ declare module '@theme/TOC' {
|
||||||
|
|
||||||
export type TOCProps = {
|
export type TOCProps = {
|
||||||
readonly toc: readonly TOCItem[];
|
readonly toc: readonly TOCItem[];
|
||||||
|
readonly className?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TOCHeadingsProps = {
|
export type TOCHeadingsProps = {
|
||||||
|
|
|
@ -6,6 +6,8 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// These class names are used to style page layouts in Docusaurus
|
// These class names are used to style page layouts in Docusaurus
|
||||||
|
// Those are meant to be targeted by user-provided custom CSS selectors
|
||||||
|
// /!\ Please do not modify the classnames! This is a breaking change, and annoying for users!
|
||||||
export const ThemeClassNames = {
|
export const ThemeClassNames = {
|
||||||
page: {
|
page: {
|
||||||
blogListPage: 'blog-list-page',
|
blogListPage: 'blog-list-page',
|
||||||
|
@ -22,7 +24,34 @@ export const ThemeClassNames = {
|
||||||
wrapper: {
|
wrapper: {
|
||||||
main: 'main-wrapper',
|
main: 'main-wrapper',
|
||||||
blogPages: 'blog-wrapper',
|
blogPages: 'blog-wrapper',
|
||||||
docPages: 'docs-wrapper',
|
docsPages: 'docs-wrapper',
|
||||||
mdxPages: 'mdx-wrapper',
|
mdxPages: 'mdx-wrapper',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// /!\ Please keep the naming convention consistent!
|
||||||
|
// Something like: "theme-{blog,doc,version,page}?-<suffix>"
|
||||||
|
common: {
|
||||||
|
editThisPage: 'theme-edit-this-page',
|
||||||
|
lastUpdated: 'theme-last-updated',
|
||||||
|
},
|
||||||
|
layout: {
|
||||||
|
// TODO add other stable classNames here
|
||||||
|
},
|
||||||
|
docs: {
|
||||||
|
docVersionBanner: 'theme-doc-version-banner',
|
||||||
|
docVersionBadge: 'theme-doc-version-badge',
|
||||||
|
docMarkdown: 'theme-doc-markdown',
|
||||||
|
docTocMobile: 'theme-doc-toc-mobile',
|
||||||
|
docTocDesktop: 'theme-doc-toc-desktop',
|
||||||
|
docFooter: 'theme-doc-footer',
|
||||||
|
docFooterTagsRow: 'theme-doc-footer-tags-row',
|
||||||
|
docFooterEditMetaRow: 'theme-doc-footer-edit-meta-row',
|
||||||
|
docSidebarMenu: 'theme-doc-sidebar-menu',
|
||||||
|
docSidebarItemCategory: 'theme-doc-sidebar-item-category',
|
||||||
|
docSidebarItemLink: 'theme-doc-sidebar-item-link',
|
||||||
|
// TODO add other stable classNames here
|
||||||
|
},
|
||||||
|
blog: {
|
||||||
|
// TODO add other stable classNames here
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue