From 4e0f38523557788f01ee0f2accfc39dfdc96812a Mon Sep 17 00:00:00 2001 From: lkzwc Date: Sat, 7 Oct 2023 21:22:20 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90add=E3=80=91=E6=B7=BB=E5=8A=A0?= =?UTF-8?q?=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/theme/BlogLayout.tsx | 5 +- src/theme/BlogListPage.tsx | 5 +- src/theme/BlogPostItem.tsx | 40 +++++------ src/theme/BlogPostItem/Container/index.tsx | 32 +++++++++ src/theme/BlogPostItem/Content/index.tsx | 30 ++++++++ .../Footer/ReadMoreLink/index.tsx | 44 ++++++++++++ src/theme/BlogPostItem/Footer/index.tsx | 60 ++++++++++++++++ .../BlogPostItem/Footer/styles.module.css | 10 +++ .../BlogPostItem/Header/Author/index.tsx | 55 ++++++++++++++ .../BlogPostItem/Header/Authors/index.tsx | 53 ++++++++++++++ .../Header/Authors/styles.module.css | 21 ++++++ src/theme/BlogPostItem/Header/Info/index.tsx | 71 +++++++++++++++++++ .../Header/Info/styles.module.css | 10 +++ src/theme/BlogPostItem/Header/Title/index.tsx | 33 +++++++++ .../Header/Title/styles.module.css | 19 +++++ src/theme/BlogPostItem/Header/index.tsx | 21 ++++++ 16 files changed, 480 insertions(+), 29 deletions(-) create mode 100644 src/theme/BlogPostItem/Container/index.tsx create mode 100644 src/theme/BlogPostItem/Content/index.tsx create mode 100644 src/theme/BlogPostItem/Footer/ReadMoreLink/index.tsx create mode 100644 src/theme/BlogPostItem/Footer/index.tsx create mode 100644 src/theme/BlogPostItem/Footer/styles.module.css create mode 100644 src/theme/BlogPostItem/Header/Author/index.tsx create mode 100644 src/theme/BlogPostItem/Header/Authors/index.tsx create mode 100644 src/theme/BlogPostItem/Header/Authors/styles.module.css create mode 100644 src/theme/BlogPostItem/Header/Info/index.tsx create mode 100644 src/theme/BlogPostItem/Header/Info/styles.module.css create mode 100644 src/theme/BlogPostItem/Header/Title/index.tsx create mode 100644 src/theme/BlogPostItem/Header/Title/styles.module.css create mode 100644 src/theme/BlogPostItem/Header/index.tsx diff --git a/src/theme/BlogLayout.tsx b/src/theme/BlogLayout.tsx index 06aaad2..235c378 100644 --- a/src/theme/BlogLayout.tsx +++ b/src/theme/BlogLayout.tsx @@ -18,10 +18,7 @@ export default function BlogLayout(props) { > {children} -
- - {toc && toc} -
+
{toc && toc}
diff --git a/src/theme/BlogListPage.tsx b/src/theme/BlogListPage.tsx index e26a176..aa9eb83 100644 --- a/src/theme/BlogListPage.tsx +++ b/src/theme/BlogListPage.tsx @@ -59,10 +59,7 @@ export default function BlogListPage(props) { height: "70%", }} /> -
- -
- + {content?.metadata?.description} ))} diff --git a/src/theme/BlogPostItem.tsx b/src/theme/BlogPostItem.tsx index 21bdd58..505abbd 100644 --- a/src/theme/BlogPostItem.tsx +++ b/src/theme/BlogPostItem.tsx @@ -1,30 +1,28 @@ - // import BlogPostItem from "@theme-original/BlogPostItem"; -import React from 'react'; -import clsx from 'clsx'; +import React from "react"; +import clsx from "clsx"; // import {useBlogPost} from '@docusaurus/theme-common/internal'; -import BlogPostItemContainer from '@theme/BlogPostItem/Container'; -import BlogPostItemHeader from '@theme/BlogPostItem/Header'; -import BlogPostItemContent from '@theme/BlogPostItem/Content'; -import BlogPostItemFooter from '@theme/BlogPostItem/Footer'; -import type {Props} from '@theme/BlogPostItem'; +import BlogPostItemContainer from "@theme/BlogPostItem/Container"; +import BlogPostItemHeader from "@theme/BlogPostItem/Header"; +import BlogPostItemContent from "@theme/BlogPostItem/Content"; +import BlogPostItemFooter from "@theme/BlogPostItem/Footer"; +import type { Props } from "@theme/BlogPostItem"; -// apply a bottom margin in list view -function useContainerClassName() { - // const {isBlogPostPage} = useBlogPost(); - // return !isBlogPostPage ? 'margin-bottom--xl' : undefined; -} +export default function BlogPostItem(props): JSX.Element { + // const { + // children: { + // type: { metadata }, + // }, + // } = props; + // console.log("propos", props); + + const { children } = props; -export default function BlogPostItem({ - children, - className, -}: Props): JSX.Element { - const containerClassName = useContainerClassName(); return ( - + <> {children} - + ); -} \ No newline at end of file +} diff --git a/src/theme/BlogPostItem/Container/index.tsx b/src/theme/BlogPostItem/Container/index.tsx new file mode 100644 index 0000000..ab9d2a9 --- /dev/null +++ b/src/theme/BlogPostItem/Container/index.tsx @@ -0,0 +1,32 @@ +/** + * 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 React from 'react'; +import {useBaseUrlUtils} from '@docusaurus/useBaseUrl'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import type {Props} from '@theme/BlogPostItem/Container'; + +export default function BlogPostItemContainer({ + children, + className, +}: Props): JSX.Element { + const {frontMatter, assets} = useBlogPost(); + const {withBaseUrl} = useBaseUrlUtils(); + const image = assets.image ?? frontMatter.image; + return ( +
+ {image && ( + + )} + {children} +
+ ); +} diff --git a/src/theme/BlogPostItem/Content/index.tsx b/src/theme/BlogPostItem/Content/index.tsx new file mode 100644 index 0000000..4d586a1 --- /dev/null +++ b/src/theme/BlogPostItem/Content/index.tsx @@ -0,0 +1,30 @@ +/** + * 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 React from "react"; +import clsx from "clsx"; +import { blogPostContainerID } from "@docusaurus/utils-common"; +import { useBlogPost } from "@docusaurus/theme-common/internal"; +import MDXContent from "@theme/MDXContent"; +import type { Props } from "@theme/BlogPostItem/Content"; + +export default function BlogPostItemContent({ + children, + className, +}: Props): JSX.Element { + // const {isBlogPostPage} = useBlogPost(); + return ( +
+ {children} +
+ ); +} diff --git a/src/theme/BlogPostItem/Footer/ReadMoreLink/index.tsx b/src/theme/BlogPostItem/Footer/ReadMoreLink/index.tsx new file mode 100644 index 0000000..75f725c --- /dev/null +++ b/src/theme/BlogPostItem/Footer/ReadMoreLink/index.tsx @@ -0,0 +1,44 @@ +/** + * 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 React from 'react'; +import Translate, {translate} from '@docusaurus/Translate'; +import Link from '@docusaurus/Link'; +import type {Props} from '@theme/BlogPostItem/Footer/ReadMoreLink'; + +function ReadMoreLabel() { + return ( + + + Read More + + + ); +} + +export default function BlogPostItemFooterReadMoreLink( + props: Props, +): JSX.Element { + const {blogPostTitle, ...linkProps} = props; + return ( + + + + ); +} diff --git a/src/theme/BlogPostItem/Footer/index.tsx b/src/theme/BlogPostItem/Footer/index.tsx new file mode 100644 index 0000000..314faac --- /dev/null +++ b/src/theme/BlogPostItem/Footer/index.tsx @@ -0,0 +1,60 @@ +/** + * 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 React from 'react'; +import clsx from 'clsx'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import EditThisPage from '@theme/EditThisPage'; +import TagsListInline from '@theme/TagsListInline'; +import ReadMoreLink from '@theme/BlogPostItem/Footer/ReadMoreLink'; + +import styles from './styles.module.css'; + +export default function BlogPostItemFooter(): JSX.Element | null { + const {metadata, isBlogPostPage} = useBlogPost(); + const {tags, title, editUrl, hasTruncateMarker} = metadata; + + // A post is truncated if it's in the "list view" and it has a truncate marker + const truncatedPost = !isBlogPostPage && hasTruncateMarker; + + const tagsExists = tags.length > 0; + + const renderFooter = tagsExists || truncatedPost || editUrl; + + if (!renderFooter) { + return null; + } + + return ( +
+ {tagsExists && ( +
+ +
+ )} + + {isBlogPostPage && editUrl && ( +
+ +
+ )} + + {truncatedPost && ( +
+ +
+ )} +
+ ); +} diff --git a/src/theme/BlogPostItem/Footer/styles.module.css b/src/theme/BlogPostItem/Footer/styles.module.css new file mode 100644 index 0000000..f9272fb --- /dev/null +++ b/src/theme/BlogPostItem/Footer/styles.module.css @@ -0,0 +1,10 @@ +/** + * 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. + */ + +.blogPostFooterDetailsFull { + flex-direction: column; +} diff --git a/src/theme/BlogPostItem/Header/Author/index.tsx b/src/theme/BlogPostItem/Header/Author/index.tsx new file mode 100644 index 0000000..92ace43 --- /dev/null +++ b/src/theme/BlogPostItem/Header/Author/index.tsx @@ -0,0 +1,55 @@ +/** + * 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 React from 'react'; +import clsx from 'clsx'; +import Link, {type Props as LinkProps} from '@docusaurus/Link'; + +import type {Props} from '@theme/BlogPostItem/Header/Author'; + +function MaybeLink(props: LinkProps): JSX.Element { + if (props.href) { + return ; + } + return <>{props.children}; +} + +export default function BlogPostItemHeaderAuthor({ + author, + className, +}: Props): JSX.Element { + const {name, title, url, imageURL, email} = author; + const link = url || (email && `mailto:${email}`) || undefined; + return ( +
+ {imageURL && ( + + {name} + + )} + + {name && ( + + )} +
+ ); +} diff --git a/src/theme/BlogPostItem/Header/Authors/index.tsx b/src/theme/BlogPostItem/Header/Authors/index.tsx new file mode 100644 index 0000000..d1ed5bb --- /dev/null +++ b/src/theme/BlogPostItem/Header/Authors/index.tsx @@ -0,0 +1,53 @@ +/** + * 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 React from 'react'; +import clsx from 'clsx'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import BlogPostItemHeaderAuthor from '@theme/BlogPostItem/Header/Author'; +import type {Props} from '@theme/BlogPostItem/Header/Authors'; +import styles from './styles.module.css'; + +// Component responsible for the authors layout +export default function BlogPostItemHeaderAuthors({ + className, +}: Props): JSX.Element | null { + const { + metadata: {authors}, + assets, + } = useBlogPost(); + const authorsCount = authors.length; + if (authorsCount === 0) { + return null; + } + const imageOnly = authors.every(({name}) => !name); + return ( +
+ {authors.map((author, idx) => ( +
+ +
+ ))} +
+ ); +} diff --git a/src/theme/BlogPostItem/Header/Authors/styles.module.css b/src/theme/BlogPostItem/Header/Authors/styles.module.css new file mode 100644 index 0000000..b1bd110 --- /dev/null +++ b/src/theme/BlogPostItem/Header/Authors/styles.module.css @@ -0,0 +1,21 @@ +/** + * 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. + */ + +.authorCol { + max-width: inherit !important; + flex-grow: 1 !important; +} + +.imageOnlyAuthorRow { + display: flex; + flex-flow: row wrap; +} + +.imageOnlyAuthorCol { + margin-left: 0.3rem; + margin-right: 0.3rem; +} diff --git a/src/theme/BlogPostItem/Header/Info/index.tsx b/src/theme/BlogPostItem/Header/Info/index.tsx new file mode 100644 index 0000000..0775884 --- /dev/null +++ b/src/theme/BlogPostItem/Header/Info/index.tsx @@ -0,0 +1,71 @@ +/** + * 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 React from 'react'; +import clsx from 'clsx'; +import {translate} from '@docusaurus/Translate'; +import {usePluralForm} from '@docusaurus/theme-common'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import type {Props} from '@theme/BlogPostItem/Header/Info'; + +import styles from './styles.module.css'; + +// Very simple pluralization: probably good enough for now +function useReadingTimePlural() { + const {selectMessage} = usePluralForm(); + return (readingTimeFloat: number) => { + const readingTime = Math.ceil(readingTimeFloat); + return selectMessage( + readingTime, + translate( + { + id: 'theme.blog.post.readingTime.plurals', + description: + 'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)', + message: 'One min read|{readingTime} min read', + }, + {readingTime}, + ), + ); + }; +} + +function ReadingTime({readingTime}: {readingTime: number}) { + const readingTimePlural = useReadingTimePlural(); + return <>{readingTimePlural(readingTime)}; +} + +function Date({date, formattedDate}: {date: string; formattedDate: string}) { + return ( + + ); +} + +function Spacer() { + return <>{' ยท '}; +} + +export default function BlogPostItemHeaderInfo({ + className, +}: Props): JSX.Element { + const {metadata} = useBlogPost(); + const {date, formattedDate, readingTime} = metadata; + + return ( +
+ + {typeof readingTime !== 'undefined' && ( + <> + + + + )} +
+ ); +} diff --git a/src/theme/BlogPostItem/Header/Info/styles.module.css b/src/theme/BlogPostItem/Header/Info/styles.module.css new file mode 100644 index 0000000..796b0f1 --- /dev/null +++ b/src/theme/BlogPostItem/Header/Info/styles.module.css @@ -0,0 +1,10 @@ +/** + * 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. + */ + +.container { + font-size: 0.9rem; +} diff --git a/src/theme/BlogPostItem/Header/Title/index.tsx b/src/theme/BlogPostItem/Header/Title/index.tsx new file mode 100644 index 0000000..ea40c2e --- /dev/null +++ b/src/theme/BlogPostItem/Header/Title/index.tsx @@ -0,0 +1,33 @@ +/** + * 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 React from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import {useBlogPost} from '@docusaurus/theme-common/internal'; +import type {Props} from '@theme/BlogPostItem/Header/Title'; + +import styles from './styles.module.css'; + +export default function BlogPostItemHeaderTitle({ + className, +}: Props): JSX.Element { + const {metadata, isBlogPostPage} = useBlogPost(); + const {permalink, title} = metadata; + const TitleHeading = isBlogPostPage ? 'h1' : 'h2'; + return ( + + {isBlogPostPage ? ( + title + ) : ( + + {title} + + )} + + ); +} diff --git a/src/theme/BlogPostItem/Header/Title/styles.module.css b/src/theme/BlogPostItem/Header/Title/styles.module.css new file mode 100644 index 0000000..5ffc89f --- /dev/null +++ b/src/theme/BlogPostItem/Header/Title/styles.module.css @@ -0,0 +1,19 @@ +/** + * 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. + */ + +.title { + font-size: 3rem; +} + +/** + Blog post title should be smaller on smaller devices +**/ +@media (max-width: 576px) { + .title { + font-size: 2rem; + } +} diff --git a/src/theme/BlogPostItem/Header/index.tsx b/src/theme/BlogPostItem/Header/index.tsx new file mode 100644 index 0000000..77acbaf --- /dev/null +++ b/src/theme/BlogPostItem/Header/index.tsx @@ -0,0 +1,21 @@ +/** + * 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 React from 'react'; +import BlogPostItemHeaderTitle from '@theme/BlogPostItem/Header/Title'; +import BlogPostItemHeaderInfo from '@theme/BlogPostItem/Header/Info'; +import BlogPostItemHeaderAuthors from '@theme/BlogPostItem/Header/Authors'; + +export default function BlogPostItemHeader(): JSX.Element { + return ( +
+ + + +
+ ); +}