Skip to content

Commit 95ab9f8

Browse files
OzakIOneslorber
andauthored
feat(theme): show unlisted/draft banners in dev mode (#10376)
Co-authored-by: OzakIOne <[email protected]> Co-authored-by: sebastien <[email protected]>
1 parent c58fcbd commit 95ab9f8

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+411
-140
lines changed

packages/docusaurus-theme-classic/src/theme-classic.d.ts

+21-1
Original file line numberDiff line numberDiff line change
@@ -1602,14 +1602,34 @@ declare module '@theme/Tag' {
16021602
export default function Tag(props: Props): JSX.Element;
16031603
}
16041604

1605-
declare module '@theme/Unlisted' {
1605+
declare module '@theme/ContentVisibility' {
1606+
export interface Props {
1607+
readonly metadata: {
1608+
// the visibility metadata our 3 content plugins share in common
1609+
readonly unlisted: boolean;
1610+
readonly frontMatter: {draft?: boolean; unlisted?: boolean};
1611+
};
1612+
}
1613+
1614+
export default function ContentVisibility(props: Props): JSX.Element;
1615+
}
1616+
1617+
declare module '@theme/ContentVisibility/Unlisted' {
16061618
export interface Props {
16071619
className?: string;
16081620
}
16091621

16101622
export default function Unlisted(props: Props): JSX.Element;
16111623
}
16121624

1625+
declare module '@theme/ContentVisibility/Draft' {
1626+
export interface Props {
1627+
className?: string;
1628+
}
1629+
1630+
export default function Draft(props: Props): JSX.Element;
1631+
}
1632+
16131633
declare module '@theme/prism-include-languages' {
16141634
import type * as PrismNamespace from 'prismjs';
16151635

packages/docusaurus-theme-classic/src/theme/BlogPostPage/index.tsx

+3-3
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ import BlogPostPaginator from '@theme/BlogPostPaginator';
1818
import BlogPostPageMetadata from '@theme/BlogPostPage/Metadata';
1919
import BlogPostPageStructuredData from '@theme/BlogPostPage/StructuredData';
2020
import TOC from '@theme/TOC';
21+
import ContentVisibility from '@theme/ContentVisibility';
2122
import type {Props} from '@theme/BlogPostPage';
22-
import Unlisted from '@theme/Unlisted';
2323
import type {BlogSidebar} from '@docusaurus/plugin-content-blog';
2424

2525
function BlogPostPageContent({
@@ -30,7 +30,7 @@ function BlogPostPageContent({
3030
children: ReactNode;
3131
}): JSX.Element {
3232
const {metadata, toc} = useBlogPost();
33-
const {nextItem, prevItem, frontMatter, unlisted} = metadata;
33+
const {nextItem, prevItem, frontMatter} = metadata;
3434
const {
3535
hide_table_of_contents: hideTableOfContents,
3636
toc_min_heading_level: tocMinHeadingLevel,
@@ -48,7 +48,7 @@ function BlogPostPageContent({
4848
/>
4949
) : undefined
5050
}>
51-
{unlisted && <Unlisted />}
51+
<ContentVisibility metadata={metadata} />
5252

5353
<BlogPostItem>{children}</BlogPostItem>
5454

packages/docusaurus-theme-classic/src/theme/BlogTagsPostsPage/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import BlogListPaginator from '@theme/BlogListPaginator';
2020
import SearchMetadata from '@theme/SearchMetadata';
2121
import type {Props} from '@theme/BlogTagsPostsPage';
2222
import BlogPostItems from '@theme/BlogPostItems';
23-
import Unlisted from '@theme/Unlisted';
23+
import Unlisted from '@theme/ContentVisibility/Unlisted';
2424
import Heading from '@theme/Heading';
2525

2626
function BlogTagsPostsPageMetadata({tag}: Props): JSX.Element {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import React from 'react';
9+
import clsx from 'clsx';
10+
import {
11+
ThemeClassNames,
12+
DraftBannerTitle,
13+
DraftBannerMessage,
14+
} from '@docusaurus/theme-common';
15+
import Admonition from '@theme/Admonition';
16+
import type {Props} from '@theme/ContentVisibility/Draft';
17+
18+
export default function Draft({className}: Props): JSX.Element | null {
19+
return (
20+
<Admonition
21+
type="caution"
22+
title={<DraftBannerTitle />}
23+
className={clsx(className, ThemeClassNames.common.draftBanner)}>
24+
<DraftBannerMessage />
25+
</Admonition>
26+
);
27+
}

packages/docusaurus-theme-classic/src/theme/Unlisted/index.tsx packages/docusaurus-theme-classic/src/theme/ContentVisibility/Unlisted/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import {
1414
UnlistedMetadata,
1515
} from '@docusaurus/theme-common';
1616
import Admonition from '@theme/Admonition';
17-
import type {Props} from '@theme/Unlisted';
17+
import type {Props} from '@theme/ContentVisibility/Unlisted';
1818

1919
function UnlistedBanner({className}: Props) {
2020
return (
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
/**
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* This source code is licensed under the MIT license found in the
5+
* LICENSE file in the root directory of this source tree.
6+
*/
7+
8+
import React from 'react';
9+
10+
import type {Props} from '@theme/ContentVisibility';
11+
import Draft from '@theme/ContentVisibility/Draft';
12+
import Unlisted from '@theme/ContentVisibility/Unlisted';
13+
14+
export default function ContentVisibility({
15+
metadata,
16+
}: Props): JSX.Element | null {
17+
const {unlisted, frontMatter} = metadata;
18+
// Reading draft/unlisted status from frontMatter is useful to display
19+
// the banners in dev mode (in dev, metadata.unlisted is always false)
20+
// See https://github.com/facebook/docusaurus/issues/8285
21+
return (
22+
<>
23+
{(unlisted || frontMatter.unlisted) && <Unlisted />}
24+
{frontMatter.draft && <Draft />}
25+
</>
26+
);
27+
}

packages/docusaurus-theme-classic/src/theme/DocItem/Layout/index.tsx

+3-5
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import DocItemTOCMobile from '@theme/DocItem/TOC/Mobile';
1717
import DocItemTOCDesktop from '@theme/DocItem/TOC/Desktop';
1818
import DocItemContent from '@theme/DocItem/Content';
1919
import DocBreadcrumbs from '@theme/DocBreadcrumbs';
20-
import Unlisted from '@theme/Unlisted';
20+
import ContentVisibility from '@theme/ContentVisibility';
2121
import type {Props} from '@theme/DocItem/Layout';
2222

2323
import styles from './styles.module.css';
@@ -48,13 +48,11 @@ function useDocTOC() {
4848

4949
export default function DocItemLayout({children}: Props): JSX.Element {
5050
const docTOC = useDocTOC();
51-
const {
52-
metadata: {unlisted},
53-
} = useDoc();
51+
const {metadata} = useDoc();
5452
return (
5553
<div className="row">
5654
<div className={clsx('col', !docTOC.hidden && styles.docItemCol)}>
57-
{unlisted && <Unlisted />}
55+
<ContentVisibility metadata={metadata} />
5856
<DocVersionBanner />
5957
<div className={styles.docItemContainer}>
6058
<article>

packages/docusaurus-theme-classic/src/theme/DocTagDocListPage/index.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import {
1717
import Translate, {translate} from '@docusaurus/Translate';
1818
import SearchMetadata from '@theme/SearchMetadata';
1919
import type {Props} from '@theme/DocTagDocListPage';
20-
import Unlisted from '@theme/Unlisted';
20+
import Unlisted from '@theme/ContentVisibility/Unlisted';
2121
import Heading from '@theme/Heading';
2222

2323
// Very simple pluralization: probably good enough for now

packages/docusaurus-theme-classic/src/theme/MDXPage/index.tsx

+10-13
Original file line numberDiff line numberDiff line change
@@ -15,26 +15,23 @@ import {
1515
import Layout from '@theme/Layout';
1616
import MDXContent from '@theme/MDXContent';
1717
import TOC from '@theme/TOC';
18-
import Unlisted from '@theme/Unlisted';
18+
import ContentVisibility from '@theme/ContentVisibility';
1919
import type {Props} from '@theme/MDXPage';
2020

2121
import EditMetaRow from '@theme/EditMetaRow';
2222
import styles from './styles.module.css';
2323

2424
export default function MDXPage(props: Props): JSX.Element {
2525
const {content: MDXPageContent} = props;
26+
const {metadata, assets} = MDXPageContent;
2627
const {
27-
metadata: {
28-
title,
29-
editUrl,
30-
description,
31-
frontMatter,
32-
unlisted,
33-
lastUpdatedBy,
34-
lastUpdatedAt,
35-
},
36-
assets,
37-
} = MDXPageContent;
28+
title,
29+
editUrl,
30+
description,
31+
frontMatter,
32+
lastUpdatedBy,
33+
lastUpdatedAt,
34+
} = metadata;
3835
const {
3936
keywords,
4037
wrapperClassName,
@@ -60,7 +57,7 @@ export default function MDXPage(props: Props): JSX.Element {
6057
<main className="container container--fluid margin-vert--lg">
6158
<div className={clsx('row', styles.mdxPageWrapper)}>
6259
<div className={clsx('col', !hideTableOfContents && 'col--8')}>
63-
{unlisted && <Unlisted />}
60+
<ContentVisibility metadata={metadata} />
6461
<article>
6562
<MDXContent>
6663
<MDXPageContent />

packages/docusaurus-theme-common/src/index.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,9 @@ export {
123123
UnlistedBannerTitle,
124124
UnlistedBannerMessage,
125125
UnlistedMetadata,
126-
} from './utils/unlistedUtils';
126+
DraftBannerTitle,
127+
DraftBannerMessage,
128+
} from './translations/contentVisibilityTranslations';
127129

128130
export {
129131
ErrorBoundaryTryAgainButton,

packages/docusaurus-theme-common/src/utils/unlistedUtils.tsx packages/docusaurus-theme-common/src/translations/contentVisibilityTranslations.tsx

+25-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import Head from '@docusaurus/Head';
1212
export function UnlistedBannerTitle(): JSX.Element {
1313
return (
1414
<Translate
15-
id="theme.unlistedContent.title"
15+
id="theme.contentVisibility.unlistedBanner.title"
1616
description="The unlisted content banner title">
1717
Unlisted page
1818
</Translate>
@@ -22,18 +22,41 @@ export function UnlistedBannerTitle(): JSX.Element {
2222
export function UnlistedBannerMessage(): JSX.Element {
2323
return (
2424
<Translate
25-
id="theme.unlistedContent.message"
25+
id="theme.contentVisibility.unlistedBanner.message"
2626
description="The unlisted content banner message">
2727
This page is unlisted. Search engines will not index it, and only users
2828
having a direct link can access it.
2929
</Translate>
3030
);
3131
}
3232

33+
// TODO Docusaurus v4 breaking change (since it's v3 public theme-common API :/)
34+
// Move this to theme/ContentVisibility/Unlisted
3335
export function UnlistedMetadata(): JSX.Element {
3436
return (
3537
<Head>
3638
<meta name="robots" content="noindex, nofollow" />
3739
</Head>
3840
);
3941
}
42+
43+
export function DraftBannerTitle(): JSX.Element {
44+
return (
45+
<Translate
46+
id="theme.contentVisibility.draftBanner.title"
47+
description="The draft content banner title">
48+
Draft page
49+
</Translate>
50+
);
51+
}
52+
53+
export function DraftBannerMessage(): JSX.Element {
54+
return (
55+
<Translate
56+
id="theme.contentVisibility.draftBanner.message"
57+
description="The draft content banner message">
58+
This page is a draft. It will only be visible in dev and be excluded from
59+
the production build.
60+
</Translate>
61+
);
62+
}

packages/docusaurus-theme-common/src/utils/ThemeClassNames.ts

+1
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ export const ThemeClassNames = {
4343
codeBlock: 'theme-code-block',
4444
admonition: 'theme-admonition',
4545
unlistedBanner: 'theme-unlisted-banner',
46+
draftBanner: 'theme-draft-banner',
4647

4748
admonitionType: (type: string) => `theme-admonition-${type}`,
4849
},

packages/docusaurus-theme-translations/locales/ar/theme-common.json

+8-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
"theme.admonition.warning": "warning",
2323
"theme.blog.archive.description": "أرشيف",
2424
"theme.blog.archive.title": "أرشيف",
25+
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
26+
"theme.blog.authorsList.pageTitle": "Authors",
27+
"theme.blog.authorsList.viewAll": "View All Authors",
2528
"theme.blog.paginator.navAriaLabel": "التنقل في صفحة قائمة المدونة",
2629
"theme.blog.paginator.newerEntries": "إدخالات أحدث",
2730
"theme.blog.paginator.olderEntries": "إدخالات أقدم",
@@ -40,6 +43,10 @@
4043
"theme.common.editThisPage": "تعديل هذه الصفحة",
4144
"theme.common.headingLinkTitle": "ارتباط مباشر بالعنوان {heading}",
4245
"theme.common.skipToMainContent": "انتقل إلى المحتوى الرئيسي",
46+
"theme.contentVisibility.draftBanner.message": "This page is a draft. It will only be visible in dev and be excluded from the production build.",
47+
"theme.contentVisibility.draftBanner.title": "Draft page",
48+
"theme.contentVisibility.unlistedBanner.message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
49+
"theme.contentVisibility.unlistedBanner.title": "Unlisted page",
4350
"theme.docs.DocCard.categoryDescription.plurals": "{count} مواد",
4451
"theme.docs.breadcrumbs.home": "الرئيسية",
4552
"theme.docs.breadcrumbs.navAriaLabel": "التنقل التفصيلي",
@@ -68,7 +75,5 @@
6875
"theme.navbar.mobileVersionsDropdown.label": "إصدارات",
6976
"theme.tags.tagsListLabel": "الوسوم:",
7077
"theme.tags.tagsPageLink": "عرض كل الوسوم",
71-
"theme.tags.tagsPageTitle": "الوسوم",
72-
"theme.unlistedContent.message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
73-
"theme.unlistedContent.title": "Unlisted page"
78+
"theme.tags.tagsPageTitle": "الوسوم"
7479
}

packages/docusaurus-theme-translations/locales/base/theme-common.json

+15-8
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,16 @@
4141
"theme.admonition.tip___DESCRIPTION": "The default label used for the Tip admonition (:::tip)",
4242
"theme.admonition.warning": "warning",
4343
"theme.admonition.warning___DESCRIPTION": "The default label used for the Warning admonition (:::warning)",
44-
"theme.blog.authorsList.pageTitle": "Authors",
45-
"theme.blog.authorsList.viewAll": "View All Authors",
46-
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
4744
"theme.blog.archive.description": "Archive",
4845
"theme.blog.archive.description___DESCRIPTION": "The page & hero description of the blog archive page",
4946
"theme.blog.archive.title": "Archive",
5047
"theme.blog.archive.title___DESCRIPTION": "The page & hero title of the blog archive page",
48+
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
49+
"theme.blog.author.pageTitle___DESCRIPTION": "The title of the page for a blog author",
50+
"theme.blog.authorsList.pageTitle": "Authors",
51+
"theme.blog.authorsList.pageTitle___DESCRIPTION": "The title of the authors page",
52+
"theme.blog.authorsList.viewAll": "View All Authors",
53+
"theme.blog.authorsList.viewAll___DESCRIPTION": "The label of the link targeting the blog authors page",
5154
"theme.blog.paginator.navAriaLabel": "Blog list page navigation",
5255
"theme.blog.paginator.navAriaLabel___DESCRIPTION": "The ARIA label for the blog pagination",
5356
"theme.blog.paginator.newerEntries": "Newer Entries",
@@ -84,6 +87,14 @@
8487
"theme.common.headingLinkTitle___DESCRIPTION": "Title for link to heading",
8588
"theme.common.skipToMainContent": "Skip to main content",
8689
"theme.common.skipToMainContent___DESCRIPTION": "The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation",
90+
"theme.contentVisibility.draftBanner.message": "This page is a draft. It will only be visible in dev and be excluded from the production build.",
91+
"theme.contentVisibility.draftBanner.message___DESCRIPTION": "The draft content banner message",
92+
"theme.contentVisibility.draftBanner.title": "Draft page",
93+
"theme.contentVisibility.draftBanner.title___DESCRIPTION": "The draft content banner title",
94+
"theme.contentVisibility.unlistedBanner.message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
95+
"theme.contentVisibility.unlistedBanner.message___DESCRIPTION": "The unlisted content banner message",
96+
"theme.contentVisibility.unlistedBanner.title": "Unlisted page",
97+
"theme.contentVisibility.unlistedBanner.title___DESCRIPTION": "The unlisted content banner title",
8798
"theme.docs.DocCard.categoryDescription.plurals": "1 item|{count} items",
8899
"theme.docs.DocCard.categoryDescription.plurals___DESCRIPTION": "The default description for a category card in the generated index about how many items this category includes",
89100
"theme.docs.breadcrumbs.home": "Home page",
@@ -140,9 +151,5 @@
140151
"theme.tags.tagsPageLink": "View All Tags",
141152
"theme.tags.tagsPageLink___DESCRIPTION": "The label of the link targeting the tag list page",
142153
"theme.tags.tagsPageTitle": "Tags",
143-
"theme.tags.tagsPageTitle___DESCRIPTION": "The title of the tag list page",
144-
"theme.unlistedContent.message": "This page is unlisted. Search engines will not index it, and only users having a direct link can access it.",
145-
"theme.unlistedContent.message___DESCRIPTION": "The unlisted content banner message",
146-
"theme.unlistedContent.title": "Unlisted page",
147-
"theme.unlistedContent.title___DESCRIPTION": "The unlisted content banner title"
154+
"theme.tags.tagsPageTitle___DESCRIPTION": "The title of the tag list page"
148155
}

packages/docusaurus-theme-translations/locales/bg/theme-common.json

+8-3
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
"theme.admonition.warning": "Внимание",
2323
"theme.blog.archive.description": "Архив",
2424
"theme.blog.archive.title": "Архив",
25+
"theme.blog.author.pageTitle": "{authorName} - {nPosts}",
26+
"theme.blog.authorsList.pageTitle": "Authors",
27+
"theme.blog.authorsList.viewAll": "View All Authors",
2528
"theme.blog.paginator.navAriaLabel": "Навигация в страницата със списък на блогове",
2629
"theme.blog.paginator.newerEntries": "По-нови записи",
2730
"theme.blog.paginator.olderEntries": "По-стари записи",
@@ -40,6 +43,10 @@
4043
"theme.common.editThisPage": "Редактирай тази страница",
4144
"theme.common.headingLinkTitle": "Директна връзка към {heading}",
4245
"theme.common.skipToMainContent": "Преминете към основното съдържание",
46+
"theme.contentVisibility.draftBanner.message": "This page is a draft. It will only be visible in dev and be excluded from the production build.",
47+
"theme.contentVisibility.draftBanner.title": "Draft page",
48+
"theme.contentVisibility.unlistedBanner.message": "Тази страница е скрита. Търсачките няма да я индексират и само потребители с директна връзка имат достъп до него.",
49+
"theme.contentVisibility.unlistedBanner.title": "Скрита страница",
4350
"theme.docs.DocCard.categoryDescription.plurals": "един предмет|{count} предмета",
4451
"theme.docs.breadcrumbs.home": "Начална страница",
4552
"theme.docs.breadcrumbs.navAriaLabel": "Галета",
@@ -68,7 +75,5 @@
6875
"theme.navbar.mobileVersionsDropdown.label": "Версии",
6976
"theme.tags.tagsListLabel": "Етикети:",
7077
"theme.tags.tagsPageLink": "Вижте всички етикети",
71-
"theme.tags.tagsPageTitle": "Етикети",
72-
"theme.unlistedContent.message": "Тази страница е скрита. Търсачките няма да я индексират и само потребители с директна връзка имат достъп до него.",
73-
"theme.unlistedContent.title": "Скрита страница"
78+
"theme.tags.tagsPageTitle": "Етикети"
7479
}

0 commit comments

Comments
 (0)