目录组件百分比进度
This commit is contained in:
tangly1024
2021-12-22 16:22:17 +08:00
parent 0ef9da886f
commit 565b3ac194
9 changed files with 33 additions and 23 deletions

View File

@@ -165,10 +165,13 @@ export default function ArticleDetail ({ post, blockMap, recommendPosts, prev, n
{/* 悬浮目录按钮 */}
<div className="block lg:hidden">
<TocDrawerButton onClick={() => { drawerRight.current.handleSwitchVisible() }} />
<TocDrawer post={post} cRef={drawerRight} />
<TocDrawer post={post} cRef={drawerRight} targetRef={targetRef} />
</div>
<Progress targetRef={targetRef} />
{/* 移动端顶部进度条 */}
{/* <div className='fixed left-0 top-0 w-full z-40 block md:hidden'>
<Progress targetRef={targetRef} />
</div> */}
</>)
}

View File

@@ -12,7 +12,7 @@ import smoothscroll from 'smoothscroll-polyfill'
* @returns {JSX.Element}
* @constructor
*/
const JumpToBottomButton = ({ targetRef, showPercent = true }) => {
const JumpToBottomButton = ({ targetRef, showPercent = false }) => {
const { locale } = useGlobal()
const [show, switchShow] = useState(false)
const [percent, changePercent] = useState(0)

View File

@@ -12,7 +12,7 @@ import smoothscroll from 'smoothscroll-polyfill'
* @returns {JSX.Element}
* @constructor
*/
const JumpToTopButton = ({ targetRef, showPercent = true }) => {
const JumpToTopButton = ({ targetRef, showPercent = false }) => {
const { locale } = useGlobal()
const [show, switchShow] = useState(false)
const [percent, changePercent] = useState(0)
@@ -39,7 +39,7 @@ const JumpToTopButton = ({ targetRef, showPercent = true }) => {
return (<div id='jump-to-top' className='right-3 fixed flex bottom-48 duration-500 z-20'>
<div onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
className={(show ? '' : 'hidden') + ' animate__fadeInRight animate__animated animate__faster shadow-card rounded-xl glassmorphism py-1 cursor-pointer '}>
className={(show ? '' : 'hidden') + ' animate__fadeInRight animate__animated animate__faster shadow-card rounded-xl glassmorphism py-3 cursor-pointer '}>
<div className='text-center'>
<div className='w-10 dark:text-gray-200 transform hover:scale-150 duration-200 text-xs' title={locale.POST.TOP} >
<FontAwesomeIcon icon={faArrowUp} />

View File

@@ -8,7 +8,7 @@ import React, { useEffect, useState } from 'react'
const Progress = ({ targetRef }) => {
const [percent, changePercent] = useState(0)
const scrollListener = () => {
if (targetRef.current) {
if (targetRef?.current) {
const clientHeight = targetRef ? (targetRef.current.clientHeight) : 0
const scrollY = window.pageYOffset
const fullHeight = clientHeight - window.outerHeight
@@ -23,8 +23,9 @@ const Progress = ({ targetRef }) => {
return () => document.removeEventListener('scroll', scrollListener)
}, [percent])
return (<div className='h-1 fixed left-0 top-0 w-full shadow-2xl z-40 bg-blue-200'>
<div className='h-1 bg-blue-600 fixed left-0 top-0 duration-200 rounded' style={{ width: `${percent}%` }}/>
return (<div className='h-4 w-full shadow-2xl bg-purple-400'>
<div className='text-center w-full absolute text-white text-xs'>{percent}%</div>
<div className='h-4 bg-purple-700 duration-200 rounded-r' style={{ width: `${percent}%` }}/>
</div>)
}

View File

@@ -8,6 +8,7 @@ import { faAngleDoubleRight, faChartBar, faThList } from '@fortawesome/free-soli
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import Link from 'next/link'
import React from 'react'
import Progress from './Progress'
/**
* 侧边平铺
@@ -21,7 +22,7 @@ import React from 'react'
* @returns {JSX.Element}
* @constructor
*/
const SideAreaLeft = ({ title, tags, currentTag, post, posts, categories, currentCategory, currentSearch }) => {
const SideAreaLeft = ({ title, tags, currentTag, post, posts, categories, currentCategory, currentSearch, targetRef }) => {
const { locale } = useGlobal()
const showToc = post && post.toc && post.toc.length > 1
const postCount = posts?.length || 0
@@ -71,10 +72,10 @@ const SideAreaLeft = ({ title, tags, currentTag, post, posts, categories, curren
{showToc && (
<section className='sticky top-8 pb-20 rounded-xl shadow-md bg-white dark:bg-gray-800 hover:shadow-2xl duration-200'>
<div className='border-b text-2xl bg-white text-black rounded-t-xl dark:border-gray-700 dark:bg-gray-700 dark:text-white py-6 px-6'>
<div className='border-b text-center text-2xl bg-white text-black rounded-t-xl dark:border-gray-700 dark:bg-gray-700 dark:text-white py-6 px-6'>
{locale.COMMON.TABLE_OF_CONTENTS}
</div>
<Toc toc={post.toc} />
<Toc toc={post.toc} targetRef={targetRef} />
</section>
)}
</>

View File

@@ -1,6 +1,7 @@
import React, { useCallback } from 'react'
import throttle from 'lodash.throttle'
import { uuidToId } from 'notion-utils'
import Progress from './Progress'
// import { cs } from 'react-notion-x'
/**
@@ -9,7 +10,7 @@ import { uuidToId } from 'notion-utils'
* @returns {JSX.Element}
* @constructor
*/
const Toc = ({ toc }) => {
const Toc = ({ toc, targetRef }) => {
// 无目录就直接返回空
if (!toc || toc.length < 1) return <></>
@@ -51,6 +52,9 @@ const Toc = ({ toc }) => {
}, throttleMs))
return <>
<div className='w-full'>
<Progress targetRef={targetRef}/>
</div>
<nav className=' dark:text-gray-100 bg-white dark:bg-gray-800 overflow-y-auto scroll-hidden p-6'>
{toc.map((tocItem) => {
const id = uuidToId(tocItem.id)
@@ -58,9 +62,9 @@ const Toc = ({ toc }) => {
<a
key={id}
href={`#${id}`}
className={`notion-table-of-contents-item duration-300 transform font-light
className={`notion-table-of-contents-item duration-300 transform font-mono
notion-table-of-contents-item-indent-level-${tocItem.indentLevel}
${activeSection === id && ' font-bold text-blue-400 dark:text-white'}`}
${activeSection === id && ' font-bold text-purple-500 dark:text-purple-400'}`}
>
<span
style={{

View File

@@ -9,7 +9,7 @@ import { useGlobal } from '@/lib/global'
* @returns {JSX.Element}
* @constructor
*/
const TocDrawer = ({ post, cRef }) => {
const TocDrawer = ({ post, cRef, targetRef }) => {
// 暴露给父组件 通过cRef.current.handleMenuClick 调用
useImperativeHandle(cRef, () => {
return {
@@ -26,13 +26,13 @@ const TocDrawer = ({ post, cRef }) => {
{/* 侧边菜单 */}
<div
className={(showDrawer ? 'animate__slideInRight ' : ' -mr-72 animate__slideOutRight') +
' shadow-xl animate__animated animate__faster max-h-96 ' +
' shadow-card animate__animated animate__faster max-h-96 ' +
' w-60 duration-200 fixed right-4 top-16 rounded overflow-y-auto'}>
{post && <>
<div className='text-xl font-bold text-black dark:text-white bg-gray-200 dark:bg-gray-600 py-2 px-6'>
<div className='text-xl font-bold text-center text-black dark:text-white bg-white dark:bg-gray-600 py-2 px-6'>
{locale.COMMON.TABLE_OF_CONTENTS}
</div>
<Toc toc={post.toc}/>
<Toc toc={post.toc} targetRef={targetRef}/>
</>
}
</div>