From 0c3a6ebf2fd911e61c89ec8341c2d1db99cfe857 Mon Sep 17 00:00:00 2001
From: Innei
Date: Sun, 9 Jul 2023 23:01:26 +0800
Subject: [PATCH] fix: toc
Signed-off-by: Innei
---
global.d.ts | 11 +-
.../widgets/shared/ArticleRightAside.tsx | 72 +++++++++--
src/components/widgets/toc/TocAside.tsx | 112 ++++++++++--------
src/components/widgets/toc/TocItem.tsx | 9 --
src/styles/theme.css | 26 +++-
5 files changed, 157 insertions(+), 73 deletions(-)
diff --git a/global.d.ts b/global.d.ts
index 5ac91e7b6a..19bb826ae7 100644
--- a/global.d.ts
+++ b/global.d.ts
@@ -11,12 +11,11 @@ declare global {
} & Props
>
- export type Component
= FC<
- {
- className?: string
- } & P &
- PropsWithChildren
- >
+ export type Component
= FC
+
+ export type ComponentType = {
+ className?: string
+ } & PropsWithChildren
// TODO should remove in next TypeScript version
interface Document {
diff --git a/src/components/widgets/shared/ArticleRightAside.tsx b/src/components/widgets/shared/ArticleRightAside.tsx
index a56ae3efd0..c4d3df3bee 100644
--- a/src/components/widgets/shared/ArticleRightAside.tsx
+++ b/src/components/widgets/shared/ArticleRightAside.tsx
@@ -1,19 +1,73 @@
-import React from 'react'
+'use client'
+
+import React, { useEffect, useRef, useState } from 'react'
+import clsx from 'clsx'
+import type { TocAsideRef } from '../toc'
+
+import { useViewport } from '~/atoms'
import { TocAside } from '../toc'
import { ReadIndicator } from './ReadIndicator'
export const ArticleRightAside: Component = ({ children }) => {
+ const asideRef = useRef(null)
+ const [isScrollToBottom, setIsScrollToBottom] = useState(false)
+ const [isScrollToTop, setIsScrollToTop] = useState(false)
+ const [canScroll, setCanScroll] = useState(false)
+ const h = useViewport((v) => v.h)
+ useEffect(() => {
+ const $ = asideRef.current?.getContainer()
+ if (!$) return
+
+ // if $ can not scroll, return null
+ if ($.scrollHeight <= $.clientHeight + 2) return
+
+ setCanScroll(true)
+
+ const handler = () => {
+ // to bottom
+ if ($.scrollTop + $.clientHeight + 20 > $.scrollHeight) {
+ setIsScrollToBottom(true)
+ setIsScrollToTop(false)
+ }
+
+ // if scroll to top,
+ // set isScrollToTop to true
+ else if ($.scrollTop === 0) {
+ setIsScrollToTop(true)
+ setIsScrollToBottom(false)
+ } else {
+ setIsScrollToBottom(false)
+ setIsScrollToTop(false)
+ }
+ }
+ $.addEventListener('scroll', handler)
+
+ handler()
+
+ return () => {
+ $.removeEventListener('scroll', handler)
+ }
+ }, [h])
+
return (
-