mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-13 23:16:47 +00:00
sideBar目录
This commit is contained in:
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
31
components/SideBarDrawer.js
Normal file
31
components/SideBarDrawer.js
Normal 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
|
||||
@@ -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 (
|
||||
|
||||
@@ -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
38
components/TocDrawer.js
Normal 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
|
||||
28
components/TocDrawerButton.js
Normal file
28
components/TocDrawerButton.js
Normal 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
|
||||
@@ -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>
|
||||
|
||||
@@ -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')
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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>
|
||||
}
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user