fix: refactor blog header with context

This commit is contained in:
jinhojang6
2023-06-22 17:56:10 +09:00
parent b30a2af923
commit d06094ee11
4 changed files with 85 additions and 39 deletions
@@ -1,15 +1,15 @@
import React, { useContext } from 'react'
import { createContext, useContext } from 'react'
import type { Props as BlogListPageProps } from '@theme/BlogListPage'
export type BlogPageContextType = {
type?: 'list' | 'page'
blogTitle?: string
blogDescription?: string
type: 'list' | null
props: BlogListPageProps
}
export const BlogPage = React.createContext<BlogPageContextType>({
type: 'list',
blogTitle: '',
blogDescription: '',
export const BlogPageContext = createContext<BlogPageContextType>({
type: null as any,
props: null as any,
})
export const useBlogPage = () => useContext(BlogPage)
export const useBlogPageData = () => useContext(BlogPageContext)
@@ -1,40 +1,20 @@
import clsx from 'clsx'
import React from 'react'
import { Props } from '@theme/BlogLayout'
import { ensureTrailingSlash } from '../../lib/string.utils'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
import { useBlogPluginData } from '@logos-theme/lib/useBlogPluginData'
import { Typography } from '@acid-info/lsd-react'
import styles from './styles.module.scss'
import Layout from '@theme/Layout'
import BlogSidebar from '@theme/BlogSidebar'
const useIsIndexPage = (props: Props) => {
if (typeof window === 'undefined') return false
const ctx = useDocusaurusContext()
const activePlugin = ctx.siteConfig.plugins.find(
(plugin) =>
plugin === '"@docusaurus/plugin-content-blog"' ||
plugin?.[0] === '@docusaurus/plugin-content-blog',
)
const routeBasePath = activePlugin?.[1]?.routeBasePath ?? '/blog'
return (
ensureTrailingSlash(routeBasePath) ===
ensureTrailingSlash(window.location.pathname)
)
}
import { useBlogPageData } from './BlogPage.context'
export default function BlogLayoutWrapper(props: Props): JSX.Element {
const { sidebar, toc, children, ...layoutProps } = props
const isIndexPage = useIsIndexPage(props)
const { type, props: blogPageProps } = useBlogPageData()
const isIndexPage = type === 'list'
const hasSidebar = sidebar && sidebar.items.length > 0
const plugin = useBlogPluginData()
const metadata = blogPageProps?.metadata // desstructing blogTitle & blogDescription raises an error
console.log('isIndexPage', isIndexPage)
return (
<Layout
{...layoutProps}
@@ -45,17 +25,17 @@ export default function BlogLayoutWrapper(props: Props): JSX.Element {
>
{isIndexPage && (
<div className={clsx(styles.blogHeader)}>
{plugin?.blogTitle && (
{metadata?.blogTitle && (
<Typography variant="h3" className={clsx(styles.blogTitle)}>
{plugin.blogTitle}
{metadata?.blogTitle}
</Typography>
)}
{plugin?.blogDescription && (
{metadata?.blogDescription && (
<Typography
variant="body2"
className={clsx(styles.blogDescription)}
>
{plugin.blogDescription}
{metadata?.blogDescription}
</Typography>
)}
</div>
@@ -5,7 +5,7 @@
display: flex;
flex-direction: column;
left: 0;
gap: 8px;
gap: 8px !important;
width: 100%;
max-width: var(--container-max-width);
@@ -23,3 +23,9 @@
.blogDescription {
grid-column: span 24;
}
@include utils.responsive('lg', 'down') {
.blogHeader {
padding-inline: var(--content-padding);
}
}
@@ -0,0 +1,60 @@
import React from 'react'
import clsx from 'clsx'
import useDocusaurusContext from '@docusaurus/useDocusaurusContext'
import {
PageMetadata,
HtmlClassNameProvider,
ThemeClassNames,
} from '@docusaurus/theme-common'
import BlogLayout from '@theme/BlogLayout'
import BlogListPaginator from '@theme/BlogListPaginator'
import SearchMetadata from '@theme/SearchMetadata'
import BlogPostItems from '@theme/BlogPostItems'
import { BlogPageContext } from '../BlogLayout/BlogPage.context'
function BlogListPageMetadata(props) {
const { metadata } = props
const {
siteConfig: { title: siteTitle },
} = useDocusaurusContext()
const { blogDescription, blogTitle, permalink } = metadata
const isBlogOnlyMode = permalink === '/'
const title = isBlogOnlyMode ? siteTitle : blogTitle
return (
<>
<PageMetadata title={title} description={blogDescription} />
<SearchMetadata tag="blog_posts_list" />
</>
)
}
function BlogListPageContent(props) {
const { metadata, items, sidebar } = props
return (
<BlogLayout sidebar={sidebar}>
<BlogPostItems items={items} />
<BlogListPaginator metadata={metadata} />
</BlogLayout>
)
}
export function BlogListPage(props) {
return (
<HtmlClassNameProvider
className={clsx(
ThemeClassNames.wrapper.blogPages,
ThemeClassNames.page.blogListPage,
)}
>
<BlogListPageMetadata {...props} />
<BlogListPageContent {...props} />
</HtmlClassNameProvider>
)
}
export default function BlogListPageWrapper(props): JSX.Element {
return (
<BlogPageContext.Provider value={{ type: 'list', props }}>
<BlogListPage {...props} />
</BlogPageContext.Provider>
)
}