sideBar目录

This commit is contained in:
tangly1024
2021-11-05 16:25:39 +08:00
parent 299866d570
commit 5bcb50891c
13 changed files with 223 additions and 239 deletions

View File

@@ -1,92 +0,0 @@
import SearchInput from '@/components/SearchInput'
import MenuButtonGroup from '@/components/MenuButtonGroup'
import React, { useImperativeHandle, useState } from 'react'
import InfoCard from '@/components/InfoCard'
import TagList from '@/components/TagList'
import Logo from '@/components/Logo'
import LatestPosts from '@/components/LatestPosts'
import PostsCategories from '@/components/PostsCategories'
/**
* 抽屉面板,可以从侧面拉出
* @returns {JSX.Element}
* @constructor
*/
const Drawer = ({ post, currentTag, cRef, tags, posts, categories, currentCategory }) => {
// 暴露给父组件 通过cRef.current.handleMenuClick 调用
useImperativeHandle(cRef, () => {
return {
handleMenuClick: () => handleMenuClick()
}
})
const [isHidden, changeHiddenStatus] = useState(true)
// 点击按钮更改侧边抽屉状态
const handleMenuClick = () => {
changeHiddenStatus(!isHidden)
}
return <>
<div className='fixed top-0 left-0 z-50 h-screen shadow-2xl bg-white dark:bg-gray-800'>
{/* LOGO */}
<div
className={(isHidden ? '-ml-72' : '') + ' duration-200 w-72 border-r dark:border-gray-600'}>
<div className='w-72 flex space-x-4 px-5 py-1 dark:border-gray-500 '>
<div
className='z-10 py-2 duration-200 mr-2 text-gray-600 text-xl cursor-pointer dark:text-gray-300'>
<i className='fa hover:scale-125 transform duration-200 fa-bars ' onClick={handleMenuClick} />
</div>
<Logo/>
</div>
</div>
{/* 侧边菜单 */}
<div
className={(isHidden ? '-ml-72' : 'shadow-2xl') + ' overflow-y-scroll h-screen w-72 duration-200 overflow-y-auto'}>
<div className='pb-56'>
{/* 搜索框 */}
<div className='px-5 my-3 block md:hidden'>
<SearchInput currentTag={currentTag} />
</div>
{/* 信息卡 */}
<InfoCard />
<hr className='dark:border-gray-700' />
<MenuButtonGroup allowCollapse={true} />
<hr className='dark:border-gray-700 my-2' />
{/* 最新文章 */}
{posts && (
<div className='mt-2 sticky top-0'>
<LatestPosts posts={posts}/>
</div>
)}
{/* 分类 */}
{categories && (
<div className='mt-2'>
<PostsCategories currentCategory={currentCategory} categories={categories}/>
</div>
)}
{/* 标签云 */}
{tags && (
<div className='mt-2'>
<section
className='text-sm font-bold py-3 px-5 text-gray-600 dark:text-gray-400 dark:hover:bg-black duration-100 flex flex-nowrap align-middle'>
<div className='w-32'>标签</div>
</section>
<div className='px-5'>
<TagList tags={tags} currentTag={currentTag} />
</div>
</div>
)}
</div>
</div>
</div>
{/* 背景蒙版 */}
<div id='drawer-background' className={(isHidden ? 'hidden' : 'block') + ' fixed top-0 left-0 z-30 w-full h-full bg-black bg-opacity-30'}
onClick={handleMenuClick} />
</>
}
export default Drawer

View File

@@ -1,51 +0,0 @@
import TocBar from '@/components/TocBar'
import React, { useImperativeHandle, useState } from 'react'
/**
* 右侧边栏
* @param toc
* @param post
* @returns {JSX.Element}
* @constructor
*/
const DrawerRight = ({ post, cRef }) => {
// 暴露给父组件 通过cRef.current.handleMenuClick 调用
useImperativeHandle(cRef, () => {
return {
handleMenuClick: () => handleMenuClick()
}
})
const [showDrawer, switchShowDrawer] = useState(false)
const handleMenuClick = () => {
switchShowDrawer(!showDrawer)
}
return <div>
<div className='fixed top-0 right-0 z-40 h-full'>
<div
className={(showDrawer ? 'shadow-2xl' : '-mr-72') + ' overflow-y-auto duration-200 w-72 h-full bg-white dark:bg-gray-700 border-r dark:border-gray-600'}>
{/* LOGO */}
<div className='sticky top-0 z-20 bg-white w-72 flex space-x-4 px-5 py-3.5 dark:border-gray-500 border-b dark:bg-gray-900 '>
<div className='text-lg font-bold font-semibold px-2 py-1 duration-200 dark:text-gray-300'>文章目录
</div>
<div
className='z-10 p-1 duration-200 mr-2 absolute right-6 text-gray-600 text-xl cursor-pointer dark:text-gray-300'>
<i className='fa hover:scale-125 transform duration-200 fa-bookmark ' onClick={handleMenuClick} />
</div>
</div>
</div>
{/* 侧边菜单 */}
<div
className={(showDrawer ? 'shadow-2xl ' : ' -mr-72 ') + ' w-72 duration-200 h-full fixed right-0 top-16 overflow-y-auto'}>
<div className='z-20'>
{post && <TocBar toc={post.toc}/>}
</div>
</div>
</div>
{/* 背景蒙版 */}
<div id='right-drawer-background' className={(showDrawer ? 'block' : 'hidden') + ' fixed top-0 left-0 z-30 w-full h-full bg-black bg-opacity-50'}
onClick={handleMenuClick} />
</div>
}
export default DrawerRight

View File

@@ -10,7 +10,7 @@ import { useGlobal } from '@/lib/global'
* @returns {JSX.Element}
* @constructor
*/
const JumpToTop = ({ targetRef, showPercent = true }) => {
const JumpToTopButton = ({ targetRef, showPercent = true }) => {
const { locale } = useGlobal()
const [show, switchShow] = useState(false)
const [percent, changePercent] = useState(0)
@@ -33,7 +33,7 @@ const JumpToTop = ({ targetRef, showPercent = true }) => {
}, [show])
return (
<div id='jump-to-top' className='right-0 fixed flex bottom-24 mr-2.5 py-1 duration-500 z-20'>
<div id='jump-to-top' className='right-0 fixed flex bottom-24 mr-2.5 py-1 duration-500 z-20 opacity-75'>
<div className='transform hover:scale-105 duration-200 '>
<div
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
@@ -50,4 +50,4 @@ const JumpToTop = ({ targetRef, showPercent = true }) => {
)
}
export default JumpToTop
export default JumpToTopButton

View File

@@ -4,7 +4,20 @@ import InfoCard from '@/components/InfoCard'
import TagList from '@/components/TagList'
import LatestPosts from '@/components/LatestPosts'
import PostsCategories from '@/components/PostsCategories'
import Toc from '@/components/Toc'
import SearchInput from '@/components/SearchInput'
/**
* 侧边栏
* @param tags
* @param currentTag
* @param post
* @param posts
* @param categories
* @param currentCategory
* @returns {JSX.Element}
* @constructor
*/
const SideBar = ({ tags, currentTag, post, posts, categories, currentCategory }) => {
// 按时间排序
if (posts) {
@@ -15,47 +28,60 @@ const SideBar = ({ tags, currentTag, post, posts, categories, currentCategory })
}).slice(0, 5)
}
return <aside className='z-10 dark:border-gray-500 border-gray-200 bg-white hidden xl:block'>
<div
className='w-72 dark:bg-gray-800 h-full scroll-hidden left-0 duration-500 ease-in-out min-h-screen'>
<div id='sidebar' className='hidden md:block sticky top-20 pb-56 duration-500'>
<>
<InfoCard />
<hr className='dark:border-gray-700' />
<MenuButtonGroup allowCollapse={true} />
</>
return <aside id='sidebar' className='bg-white dark:bg-gray-800 w-72 z-10 dark:border-gray-500 border-gray-200 scroll-hidden h-full'>
<section>
<InfoCard />
</section>
<div className={(!post ? 'sticky top-0' : '') + ' bg-white dark:bg-gray-800'}>
{/* 搜索框 */}
<section className='p-5'>
<SearchInput currentTag={currentTag} />
</section>
<section>
<hr className='dark:border-gray-700' />
<MenuButtonGroup allowCollapse={true} />
<hr className='dark:border-gray-700 my-2' />
</section>
{/* 分类 */}
{categories && (
<div className='mt-2'>
<PostsCategories currentCategory={currentCategory} categories={categories}/>
{/* 分类 */}
{categories && (
<section className='mt-2'>
<PostsCategories currentCategory={currentCategory} categories={categories} />
</section>
)}
{/* 最新文章 */}
{posts && (
<section className='mt-2'>
<LatestPosts posts={posts} />
</section>
)}
{/* 标签云 */}
{tags && (
<section className='mt-2'>
<section
className='text-sm font-bold py-3 px-5 text-gray-600 dark:text-gray-400 duration-100 flex flex-nowrap align-middle'>
<div className='w-32'>标签</div>
</section>
<div className='px-5'>
<TagList tags={tags} currentTag={currentTag} />
</div>
)}
{/* 最新文章 */}
{posts && (
<div className='mt-2'>
<LatestPosts posts={posts}/>
</div>
)}
{/* 标签云 */}
{tags && (
<div className='mt-2'>
<section
className='text-sm font-bold py-3 px-5 text-gray-600 dark:text-gray-400 duration-100 flex flex-nowrap align-middle'>
<div className='w-32'>标签</div>
</section>
<div className='px-5'>
<TagList tags={tags} currentTag={currentTag} />
</div>
</div>
)}
</div>
</section>
)}
</div>
{post && (
<section id='left-toc' className='sticky top-0 bg-white dark:bg-gray-800'>
<Toc toc={post.toc} />
</section>
)}
<section id='blank' className='bg-white dark:bg-gray-800 py-20'/>
</aside>
}
export default SideBar

View File

@@ -0,0 +1,31 @@
import React, { useImperativeHandle, useState } from 'react'
import SideBar from '@/components/SideBar'
/**
* 侧边栏抽屉面板,可以从侧面拉出
* @returns {JSX.Element}
* @constructor
*/
const SideBarDrawer = ({ post, currentTag, cRef, tags, posts, categories, currentCategory }) => {
// 暴露给父组件 通过cRef.current.handleMenuClick 调用
useImperativeHandle(cRef, () => {
return {
handleSwitchSideDrawerVisible: () => switchSideDrawerVisible()
}
})
const [isHidden, changeHiddenStatus] = useState(true)
// 点击按钮更改侧边抽屉状态
const switchSideDrawerVisible = () => {
changeHiddenStatus(!isHidden)
}
return <div>
<div className={(isHidden ? '-ml-72' : 'shadow-2xl') + ' flex flex-col duration-300 fixed h-full left-0 overflow-y-scroll scroll-hidden top-0 z-50'}>
<SideBar tags={tags} post={post} posts={posts} categories={categories} currentCategory={currentCategory} />
</div>
{/* 背景蒙版 */}
<div id='drawer-background'
className={(isHidden ? 'hidden' : 'block') + ' fixed top-0 left-0 z-30 w-full h-full bg-black bg-opacity-30'}
onClick={switchSideDrawerVisible} />
</div>
}
export default SideBarDrawer

View File

@@ -10,7 +10,7 @@ import TagItemMini from '@/components/TagItemMini'
const TagList = ({ tags, currentTag }) => {
if (!tags) return <></>
return (
<div id='tags-list' className='duration-500 dark:border-gray-600 dark:bg-gray-800 w-66'>
<div id='tags-list' className='duration-500 dark:border-gray-600 dark:bg-gray-800 w-66'>
{Object.keys(tags).map(tag => {
const selected = tag === currentTag
return (

View File

@@ -9,7 +9,7 @@ import { cs } from 'react-notion-x'
* @returns {JSX.Element}
* @constructor
*/
const TocBar = ({ toc }) => {
const Toc = ({ toc }) => {
// 无目录就直接返回空
if (!toc || toc.length < 1) return <></>
@@ -50,8 +50,12 @@ const TocBar = ({ toc }) => {
setActiveSection(currentSectionId)
}, throttleMs))
return <div>
<nav className='text-gray-500 dark:text-gray-400 underline overflow-auto scroll-hidden py-2'>
return <>
<div
className=' dark:border-gray-600 border-b text-2xl bg-white font-bold text-black dark:bg-gray-900 dark:text-white py-6 px-6'>
文章目录
</div>
<nav className='text-gray-500 dark:text-gray-400 underline overflow-y-auto scroll-hidden p-2'>
{toc.map((tocItem) => {
const id = uuidToId(tocItem.id)
return (
@@ -78,7 +82,7 @@ const TocBar = ({ toc }) => {
)
})}
</nav>
</div>
</>
}
export default TocBar
export default Toc

38
components/TocDrawer.js Normal file
View File

@@ -0,0 +1,38 @@
import Toc from '@/components/Toc'
import React, { useImperativeHandle, useState } from 'react'
/**
* 目录抽屉栏
* @param toc
* @param post
* @returns {JSX.Element}
* @constructor
*/
const TocDrawer = ({ post, cRef }) => {
// 暴露给父组件 通过cRef.current.handleMenuClick 调用
useImperativeHandle(cRef, () => {
return {
handleSwitchVisible: () => switchVisible()
}
})
const [showDrawer, switchShowDrawer] = useState(false)
const switchVisible = () => {
switchShowDrawer(!showDrawer)
}
return <div>
<div className='fixed top-0 right-0 z-40 '>
{/* 侧边菜单 */}
<div
className={(showDrawer ? 'shadow-2xl ' : ' -mr-72 ') + ' w-72 duration-200 h-full bg-white fixed right-0 top-0 overflow-y-auto'}>
<div className='z-20'>
{post && <Toc toc={post.toc}/>}
</div>
</div>
</div>
{/* 背景蒙版 */}
<div id='right-drawer-background' className={(showDrawer ? 'block' : 'hidden') + ' fixed top-0 left-0 z-30 w-full h-full bg-black bg-opacity-50'}
onClick={switchVisible} />
</div>
}
export default TocDrawer

View File

@@ -0,0 +1,28 @@
import React from 'react'
/**
* 点击召唤目录抽屉
* 当屏幕下滑500像素后会出现该控件
* @param targetRef 关联高度的目标html标签
* @param showPercent 是否显示百分比
* @returns {JSX.Element}
* @constructor
*/
const TocDrawerButton = (props) => {
return (
<div id='jump-to-top' className='right-0 fixed flex bottom-40 mr-2.5 py-1 duration-500 z-20 opacity-70' onClick={props.onClick}>
<div className='transform hover:scale-105 duration-200 '>
<div style={{ boxShadow: 'rgba(41, 50, 60, 0.5) 0px 2px 16px', borderRadius: '28px' }}
className={'animate__fadeInUp bg-gray-700 px-2.5 py-2 cursor-pointer animate__animated animate__faster shadow-2xl'}>
<div className='text-center text-gray-100'>
<div className='w-10 text-xl ' title='目录' ><i className='fa fa-book'/> </div>
<div className='text-sm'>目录</div>
</div>
</div>
</div>
</div>
)
}
export default TocDrawerButton

View File

@@ -1,45 +1,35 @@
import { useRef } from 'react'
import DarkModeButton from '@/components/DarkModeButton'
import SearchInput from '@/components/SearchInput'
import Drawer from '@/components/Drawer'
import DrawerRight from '@/components/DrawerRight'
import Logo from '@/components/Logo'
import SideBarDrawer from '@/components/SideBarDrawer'
const TopNav = ({ tags, currentTag, post, posts, currentSearch, categories, currentCategory }) => {
const drawer = useRef()
const drawerRight = useRef()
return (<>
{/* 侧面抽屉 */}
<Drawer post={post} currentTag={currentTag} cRef={drawer} tags={tags} posts={posts} categories={categories} currentCategory={currentCategory}/>
<DrawerRight post={post} cRef={drawerRight}/>
<SideBarDrawer post={post} currentTag={currentTag} cRef={drawer} tags={tags} posts={posts} categories={categories} currentCategory={currentCategory}/>
{/* 导航栏 */}
<div id='sticky-nav' className='fixed w-full top-0 z-20 transform duration-500 bg-white dark:bg-gray-800 border-b dark:border-gray-700'>
<div id='sticky-nav' className='fixed w-full top-0 z-20 transform duration-500 bg-white dark:bg-gray-900 border-b dark:border-gray-700'>
<div className='text-sm m-auto w-full flex flex-row justify-between items-center px-4 py-2 shadow-md'>
{/* 左侧LOGO */}
<div className='flex ml-12'>
<div onClick={() => { drawer.current.handleMenuClick() }}
<div onClick={() => { drawer.current.handleSwitchSideDrawerVisible() }}
className='fixed top-3 left-0 z-30 py-1 px-5 text-gray-600 text-2xl cursor-pointer dark:text-gray-300'>
<i className='fa hover:scale-125 transform duration-200 fa-bars '
/>
</div>
<Logo/>
</div>
{/* 中间搜索框 */}
<div className='hidden sm:block w-96'>
<div className='w-96'>
<SearchInput currentTag={currentTag} currentSearch={currentSearch}/>
</div>
{/* 右侧功能 */}
<div className='flex flex-nowrap space-x-1'>
<DarkModeButton />
{post && (
<div className='block xl:hidden z-10 p-1 duration-200 mr-2 h-12 text-xl cursor-pointer dark:text-gray-300 '>
<i className='fa p-2.5 hover:scale-125 transform duration-200 fa-bookmark-o' onClick={() => { drawerRight.current.handleMenuClick() }}/>
</div>
)}
</div>
</div>
</div>

View File

@@ -6,10 +6,22 @@ import BLOG from '@/blog.config'
import TopNav from '@/components/TopNav'
import Footer from '@/components/Footer'
import SideBar from '@/components/SideBar'
import JumpToTop from '@/components/JumpToTop'
import JumpToTopButton from '@/components/JumpToTopButton'
import { useGlobal } from '@/lib/global'
const BaseLayout = ({ children, layout, fullWidth, tags, meta, post, totalPosts, currentSearch, currentCategory, categories, ...customMeta }) => {
const BaseLayout = ({
children,
layout,
fullWidth,
tags,
meta,
post,
totalPosts,
currentSearch,
currentCategory,
categories,
...customMeta
}) => {
let windowTop = 0
const scrollTrigger = useCallback(throttle(() => {
const scrollS = window.scrollY
@@ -37,14 +49,20 @@ const BaseLayout = ({ children, layout, fullWidth, tags, meta, post, totalPosts,
<div id='wrapper' className={[BLOG.font, theme].join(' ')}>
<CommonHead meta={meta} />
<TopNav tags={tags} post={post} posts={totalPosts} currentSearch={currentSearch} categories={categories} currentCategory={currentCategory}/>
<div className='block lg:hidden'>
<TopNav tags={tags} post={post} posts={totalPosts} currentSearch={currentSearch} categories={categories}
currentCategory={currentCategory} />
</div>
{/* Middle Wrapper */}
<main className='flex dark:bg-black'>
<SideBar tags={tags} post={post} posts={totalPosts} categories={categories} currentCategory={currentCategory} />
<div className='hidden lg:block z-10 pt-10'>
<SideBar tags={tags} post={post} posts={totalPosts} categories={categories} currentCategory={currentCategory} />
</div>
<div className='flex flex-grow' ref={targetRef}>
{children}
{children}
</div>
<JumpToTop targetRef={targetRef} showPercent={true} />
<JumpToTopButton targetRef={targetRef} showPercent={true} />
</main>
<Footer />
@@ -58,13 +76,13 @@ const BaseLayout = ({ children, layout, fullWidth, tags, meta, post, totalPosts,
const hiddenNav = () => {
if (document) {
const nav = document.querySelector('#sticky-nav')
const sidebar = document.querySelector('#sidebar')
const tagsBar = document.querySelector('#tags-bar')
const rightToc = document.querySelector('#right-toc')
// const sidebar = document.querySelector('#sidebar')
// const tagsBar = document.querySelector('#tags-bar')
// const rightToc = document.querySelector('#right-toc')
nav && nav.classList.replace('top-0', '-top-16')
tagsBar && tagsBar.classList.replace('top-16', 'top-0')
sidebar && sidebar.classList.replace('top-20', 'top-2')
rightToc && rightToc.classList.replace('top-16', 'top-0')
// tagsBar && tagsBar.classList.replace('top-16', 'top-0')
// sidebar && sidebar.classList.replace('top-20', 'top-2')
// rightToc && rightToc.classList.replace('top-16', 'top-0')
}
}
@@ -74,13 +92,13 @@ const hiddenNav = () => {
const showNav = () => {
if (document) {
const nav = document.querySelector('#sticky-nav')
const sidebar = document.querySelector('#sidebar')
const tagsBar = document.querySelector('#tags-bar')
const rightToc = document.querySelector('#right-toc')
// const sidebar = document.querySelector('#sidebar')
// const tagsBar = document.querySelector('#tags-bar')
// const rightToc = document.querySelector('#right-toc')
nav && nav.classList.replace('-top-16', 'top-0')
tagsBar && tagsBar.classList.replace('top-0', 'top-16')
sidebar && sidebar.classList.replace('top-2', 'top-20')
rightToc && rightToc.classList.replace('top-0', 'top-16')
// tagsBar && tagsBar.classList.replace('top-0', 'top-16')
// sidebar && sidebar.classList.replace('top-2', 'top-20')
// rightToc && rightToc.classList.replace('top-0', 'top-16')
}
}

View File

@@ -9,7 +9,6 @@ import { Code, Collection, CollectionRow, Equation, NotionRenderer } from 'react
import RewardButton from '@/components/RewardButton'
import ShareBar from '@/components/ShareBar'
import Comment from '@/components/Comment'
import TocBar from '@/components/TocBar'
import BaseLayout from '@/layouts/BaseLayout'
import React, { useRef } from 'react'
import Custom404 from '@/pages/404'
@@ -23,6 +22,8 @@ import 'prismjs/components/prism-python'
import 'prismjs/components/prism-javascript'
import 'prismjs/components/prism-typescript'
import RecommendPosts from '@/components/RecommendPosts'
import TocDrawer from '@/components/TocDrawer'
import TocDrawerButton from '@/components/TocDrawerButton'
const mapPageUrl = id => {
return 'https://www.notion.so/' + id.replace(/-/g, '')
@@ -37,6 +38,7 @@ const ArticleDetail = ({ post, blockMap, tags, prev, next, posts, categories })
type: 'article'
}
const targetRef = useRef(null)
const drawerRight = useRef(null)
const url = BLOG.link + useRouter().asPath
return <BaseLayout meta={meta} tags={tags} post={post} totalPosts={posts} categories={categories} >
@@ -53,7 +55,7 @@ const ArticleDetail = ({ post, blockMap, tags, prev, next, posts, categories })
)}
</header>
<article className='shadow mb-20 w-screen md:w-full overflow-x-auto md:px-10 px-5 pt-10 max-w-5xl mx-auto dark:border-gray-700 bg-white dark:bg-gray-700'>
<article className='shadow mb-20 w-screen md:w-full overflow-x-auto md:px-10 px-5 pt-10 max-w-5xl mx-auto dark:border-gray-700 bg-white dark:bg-gray-800'>
{/* 文章标题 */}
<h1 className='font-bold text-4xl text-black my-5 dark:text-white animate__animated animate__fadeIn'>
{post.title}
@@ -163,19 +165,11 @@ const ArticleDetail = ({ post, blockMap, tags, prev, next, posts, categories })
</div>
{/* 右侧目录 */}
<aside className='dark:bg-gray-800 bg-white z-10'>
<section
className='h-full 2xl:static 2xl:block hidden top-0 right-0 fixed h-full w-52 duration-500'>
<div id='right-toc' className='sticky top-16 duration-500'>
<div
className='border-t dark:border-gray-600 border-b text-2xl bg-white font-bold text-black dark:bg-gray-900 dark:text-white py-6 px-6'>
文章目录
</div>
<TocBar toc={post.toc} />
</div>
</section>
</aside>
<div className='block lg:hidden'>
<TocDrawerButton onClick={() => { drawerRight.current.handleSwitchVisible() }} />
{/* 目录侧边栏 */}
<TocDrawer post={post} cRef={ drawerRight }/>
</div>
</BaseLayout>
}

View File

@@ -1,7 +1,6 @@
import { getAllPosts, getAllTags, getAllCategories } from '@/lib/notion'
import { getAllCategories, getAllPosts, getAllTags } from '@/lib/notion'
import BLOG from '@/blog.config'
import BaseLayout from '@/layouts/BaseLayout'
import TagsBar from '@/components/TagsBar'
import BlogPostListScroll from '@/components/BlogPostListScroll'
export async function getStaticProps () {
@@ -31,7 +30,6 @@ const Index = ({ posts, tags, meta, categories }) => {
return (
<BaseLayout meta={meta} tags={tags} totalPosts={posts} categories={categories}>
<div className='flex-grow bg-gray-200 dark:bg-black shadow-inner'>
<TagsBar tags={tags} />
<BlogPostListScroll posts={posts} tags={tags} />
</div>
</BaseLayout>