feat: Add docs-related stable classnames (#5445)

This commit is contained in:
Sébastien Lorber 2021-08-31 11:00:46 +02:00 committed by GitHub
parent 280a8abac9
commit 3a312d964d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 96 additions and 22 deletions

View file

@ -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>

View file

@ -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

View file

@ -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,

View file

@ -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}

View file

@ -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,

View file

@ -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!

View file

@ -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!

View file

@ -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>

View file

@ -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"

View file

@ -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>
); );
} }

View file

@ -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 = {

View file

@ -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
},
}; };