fix: toc overflow (#968)

This commit is contained in:
Innei 2023-09-05 13:17:10 +08:00 committed by GitHub
parent a299442069
commit e5a68d7c78
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 60 additions and 36 deletions

View File

@ -1,7 +1,7 @@
"use client"
import type { Result as TocResult } from "mdast-util-toc"
import { createElement, useEffect, useState } from "react"
import { createElement, useEffect, useRef, useState } from "react"
import { scrollTo } from "~/lib/utils"
@ -63,45 +63,69 @@ function useActiveId(itemIds: string[]) {
function Items(props: ItemsProps) {
const { items, activeId, prefix = "" } = props
const [maxWidth, setMaxWidth] = useState(0)
const anchorRef = useRef<HTMLLIElement>(null)
useEffect(() => {
const handler = () => {
if (!anchorRef.current) return
const $anchor = anchorRef.current
const pos = $anchor.getBoundingClientRect()
const maxWidth = window.innerWidth - pos.x - 20
setMaxWidth(maxWidth)
}
handler()
window.addEventListener("resize", handler)
return () => {
window.removeEventListener("resize", handler)
}
}, [])
return (
<ol className={prefix ? "pl-5" : ""}>
{items?.children?.map((item, index) => (
<li key={index}>
{item.children.map((child: any, i) => {
const content = `${prefix}${index + 1}. ${child.content}`
<li ref={anchorRef} />
{maxWidth > 0 &&
items?.children?.map((item, index) => (
<li
key={index}
style={{
maxWidth: maxWidth + "px",
}}
>
{item.children.map((child: any, i) => {
const content = `${prefix}${index + 1}. ${child.content}`
return (
<span key={index + "-" + i}>
{child.type === "paragraph" && child.children?.[0]?.url && (
<span
data-url={child.children[0].url}
onClick={() => scrollTo(child.children[0].url)}
title={content}
className={
(`#${activeId}` === child.children[0].url
? "text-accent font-bold"
: "text-zinc-400 font-medium") +
" truncate inline-block max-w-full align-bottom hover:text-accent cursor-pointer"
}
>
return (
<span key={index + "-" + i}>
{child.type === "paragraph" && child.children?.[0]?.url && (
<span
dangerouslySetInnerHTML={{
__html: content,
}}
/>
</span>
)}
{child.type === "list" &&
createElement(Items, {
items: child,
activeId,
prefix: `${prefix}${index + 1}.`,
})}
</span>
)
})}
</li>
))}
data-url={child.children[0].url}
onClick={() => scrollTo(child.children[0].url)}
title={content}
className={
(`#${activeId}` === child.children[0].url
? "text-accent font-bold"
: "text-zinc-400 font-medium") +
" truncate inline-block max-w-full align-bottom hover:text-accent cursor-pointer"
}
>
<span
dangerouslySetInnerHTML={{
__html: content,
}}
/>
</span>
)}
{child.type === "list" &&
createElement(Items, {
items: child,
activeId,
prefix: `${prefix}${index + 1}.`,
})}
</span>
)
})}
</li>
))}
</ol>
)
}