Skip to content

Commit

Permalink
fix: toc active logic
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <i@innei.in>
  • Loading branch information
Innei committed Aug 28, 2024
1 parent a7828d4 commit 13ba679
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 45 deletions.
80 changes: 39 additions & 41 deletions src/renderer/src/components/ui/markdown/components/Toc.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
import { springScrollToElement } from "@renderer/lib/scroller"
import { cn } from "@renderer/lib/utils"
import {
useGetWrappedElementPosition,
} from "@renderer/providers/wrapped-element-provider"
import { atom, useAtom } from "jotai"
import { useGetWrappedElementPosition } from "@renderer/providers/wrapped-element-provider"
import { throttle } from "lodash-es"
import {
memo,
startTransition,
useContext,
useEffect,
useMemo,
Expand Down Expand Up @@ -72,17 +68,18 @@ export const Toc: Component = ({ className }) => {
)

const [_, setTreeRef] = useState<HTMLUListElement | null>()
const [activeId, setActiveId] = useActiveId($headings)
// const [activeId, setActiveId] = useActiveId($headings)

const scrollContainerElement = useScrollViewElement()

const handleScrollTo = useEventCallback(
(i: number, $el: HTMLElement | null, anchorId: string) => {
(i: number, $el: HTMLElement | null, _anchorId: string) => {
if ($el) {
const handle = () => {
springScrollToElement($el, -100, scrollContainerElement!).then(() => {
setActiveId?.(anchorId)
})
springScrollToElement($el, -100, scrollContainerElement!)
// .then(() => {
// setActiveId?.(anchorId)
// })
}
handle()
}
Expand Down Expand Up @@ -151,7 +148,7 @@ export const Toc: Component = ({ className }) => {
{toc.map((heading, index) => (
<MemoedItem
heading={heading}
active={heading.anchorId === activeId}
// active={heading.anchorId === activeId}
key={heading.title}
rootDepth={rootDepth}
onClick={handleScrollTo}
Expand All @@ -163,40 +160,41 @@ export const Toc: Component = ({ className }) => {
</div>
)
}
const tocActiveIdAtom = atom<string | null>(null)
function useActiveId($headings: HTMLHeadingElement[]) {
const [activeId, setActiveId] = useAtom(tocActiveIdAtom)
const scrollContainerElement = useScrollViewElement()
useEffect(() => {
const observer = new IntersectionObserver(
(entries) => {
entries.forEach((entry) => {
if (entry.isIntersecting) {
startTransition(() => {
setActiveId((entry.target as HTMLElement).dataset.rid || "")
})
}
})
},
{ rootMargin: `-100px 0px -100px 0px`, root: scrollContainerElement },
)
$headings.forEach(($heading) => {
observer.observe($heading)
})
return () => {
observer.disconnect()
}
}, [$headings, scrollContainerElement, setActiveId])

return [activeId, setActiveId] as const
}
// const tocActiveIdAtom = atom<string | null>(null)
// function useActiveId($headings: HTMLHeadingElement[]) {
// const [activeId, setActiveId] = useAtom(tocActiveIdAtom)
// const scrollContainerElement = useScrollViewElement()
// useEffect(() => {
// const observer = new IntersectionObserver(
// (entries) => {
// entries.forEach((entry) => {
// if (entry.isIntersecting) {
// startTransition(() => {
// setActiveId((entry.target as HTMLElement).dataset.rid || "")
// })
// }
// })
// },
// { rootMargin: `-100px 0px -100px 0px`, root: scrollContainerElement },
// )
// $headings.forEach(($heading) => {
// observer.observe($heading)
// })
// return () => {
// observer.disconnect()
// }
// }, [$headings, scrollContainerElement, setActiveId])

// return [activeId, setActiveId] as const
// }

const MemoedItem = memo<TocItemProps>((props) => {
const {
active,

// active,
range,
...rest
} = props
const active = range > 0

const itemRef = useRef<HTMLElement>(null)

Expand All @@ -221,6 +219,6 @@ const MemoedItem = memo<TocItemProps>((props) => {
}
}, [active])

return <TocItem active={active} {...rest} />
return <TocItem range={range} {...rest} />
})
MemoedItem.displayName = "MemoedItem"
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface ITocItem {

export interface TocItemProps {
heading: ITocItem
active: boolean
// active: boolean
rootDepth: number
onClick?: (i: number, $el: HTMLElement | null, anchorId: string) => void

Expand All @@ -22,7 +22,7 @@ export interface TocItemProps {
}

export const TocItem: FC<TocItemProps> = memo((props) => {
const { active, onClick, heading, isScrollOut, range } = props
const { onClick, heading, isScrollOut, range } = props
const { $heading, anchorId, depth, index, title } = heading

const $ref = useRef<HTMLButtonElement>(null)
Expand All @@ -48,15 +48,15 @@ export const TocItem: FC<TocItemProps> = memo((props) => {
style={{
width: widthMap[depth],
}}
data-active={active}
data-active={!!range}
className={cn(
"relative inline-block h-1.5 rounded-full",
"bg-zinc-100 duration-200 hover:!bg-zinc-400 group-hover:bg-zinc-400/50",
isScrollOut && "bg-zinc-400/80",

"dark:bg-zinc-800/80 dark:hover:!bg-zinc-600 dark:group-hover:bg-zinc-600/50",
isScrollOut && "dark:bg-zinc-700",
active &&
!!range &&
"!bg-zinc-400/50 data-[active=true]:group-hover:!bg-zinc-500 dark:!bg-zinc-600",
)}
>
Expand Down

0 comments on commit 13ba679

Please sign in to comment.