Skip to content

Commit

Permalink
feat(toc): redesign toc item in wide mode
Browse files Browse the repository at this point in the history
Signed-off-by: Innei <[email protected]>
  • Loading branch information
Innei committed Oct 5, 2024
1 parent 6697ff5 commit 535afe2
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 16 deletions.
7 changes: 5 additions & 2 deletions apps/renderer/src/atoms/sidebar.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ viewAtom.onMount = () => {
setSidebarActiveView(view)
}
}
export const [, , useFeedColumnShow, , , setFeedColumnShow] = createAtomHooks(atom(true))
export const [, , useFeedColumnShow, , getFeedColumnShow, setFeedColumnShow] = createAtomHooks(
atom(true),
)

export const [, , useFeedColumnTempShow, , , setFeedColumnTempShow] = createAtomHooks(atom(false))
export const [, , useFeedColumnTempShow, , getFeedColumnTempShow, setFeedColumnTempShow] =
createAtomHooks(atom(false))
39 changes: 36 additions & 3 deletions apps/renderer/src/components/ui/markdown/components/Toc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import { springScrollToElement } from "~/lib/scroller"
import { cn } from "~/lib/utils"
import {
useGetWrappedElementPosition,
useWrappedElementPosition,
useWrappedElementSize,
} from "~/providers/wrapped-element-provider"

Expand Down Expand Up @@ -81,7 +82,7 @@ export const Toc: Component = ({ className }) => {
[toc],
)

const [_, setTreeRef] = useState<HTMLUListElement | null>()
const [_, setTreeRef] = useState<HTMLDivElement | null>()

const scrollContainerElement = useScrollViewElement()

Expand Down Expand Up @@ -195,12 +196,44 @@ export const Toc: Component = ({ className }) => {

const [hoverShow, setHoverShow] = useState(false)

const renderContentElementPosition = useWrappedElementPosition()
const renderContentElementSize = useWrappedElementSize()

const xAxis = renderContentElementPosition.x + renderContentElementSize.w
const w = window.innerWidth

const shouldShowTitle = w - xAxis > 300

if (toc.length === 0) return null

if (shouldShowTitle)
return (
<div
ref={setTreeRef}
className={cn(
"group relative overflow-auto opacity-60 duration-200 scrollbar-none group-hover:opacity-100",
"flex w-[300px] flex-col",
className,
)}
>
{toc.map((heading, index) => (
<MemoedItem
variant="title-line"
heading={heading}
key={heading.anchorId}
rootDepth={rootDepth}
onClick={handleScrollTo}
isScrollOut={index < currentScrollRange[0]}
range={index === currentScrollRange[0] ? currentScrollRange[1] : 0}
/>
))}
</div>
)
return (
<div className="flex grow flex-col scroll-smooth px-2 scrollbar-none">
<HoverCard.Root openDelay={100} open={hoverShow} onOpenChange={setHoverShow}>
<HoverCard.Trigger asChild>
<ul
<div
ref={setTreeRef}
className={cn(
"group overflow-auto opacity-60 duration-200 scrollbar-none group-hover:opacity-100",
Expand All @@ -217,7 +250,7 @@ export const Toc: Component = ({ className }) => {
range={index === currentScrollRange[0] ? currentScrollRange[1] : 0}
/>
))}
</ul>
</div>
</HoverCard.Trigger>
<HoverCard.Portal forceMount>
<div>
Expand Down
30 changes: 25 additions & 5 deletions apps/renderer/src/components/ui/markdown/components/TocItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ import { memo, useCallback, useRef } from "react"

import { cn } from "~/lib/utils"

import { EllipsisHorizontalTextWithTooltip } from "../../typography"

export interface ITocItem {
depth: number
title: string
Expand All @@ -20,20 +22,29 @@ export interface TocItemProps {

isScrollOut: boolean
range: number
variant?: "line" | "title-line"
}

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

const $ref = useRef<HTMLButtonElement>(null)

const isTitleLine = variant === "title-line"
return (
<button
type="button"
ref={$ref}
data-index={index}
className="block cursor-pointer"
className={cn("cursor-pointer", isTitleLine && "relative flex min-w-0 flex-col")}
style={
isTitleLine
? {
paddingLeft: `${(depth - rootDepth) * 12}px`,
}
: undefined
}
data-depth={depth}
onClick={useCallback(
(e: MouseEvent) => {
Expand All @@ -45,20 +56,29 @@ export const TocItem: FC<TocItemProps> = memo((props) => {
)}
title={title}
>
{isTitleLine && (
<EllipsisHorizontalTextWithTooltip className="w-full min-w-0 truncate text-left text-xs text-zinc-500 hover:!text-zinc-500 dark:text-zinc-400 dark:hover:!text-zinc-300">
{title}
</EllipsisHorizontalTextWithTooltip>
)}
<span
style={{
width: widthMap[depth],
}}
data-active={!!range}
className={cn(
"relative inline-block h-1.5 rounded-full",
"bg-zinc-100 duration-200 hover:!bg-zinc-400",
"relative inline-block rounded-full",
"bg-zinc-100 duration-200",
isScrollOut && "bg-zinc-400/80",

"dark:bg-zinc-800/80 dark:hover:!bg-zinc-600",
"dark:bg-zinc-800/80",
isScrollOut && "dark:bg-zinc-700",
!!range && "!bg-zinc-400/50 dark:!bg-zinc-600",
"overflow-hidden",

isTitleLine
? `my-1 h-1 duration-200 ${range ? "mb-3" : "mb-0.5"} bg-transparent dark:bg-transparent`
: "h-1.5 hover:!bg-zinc-400 dark:hover:!bg-zinc-600",
)}
>
<span
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,13 +38,13 @@ export const Component = () => {
transition={{ duration: 0.2, type: "spring" }}
className={cn(
"flex min-w-0 flex-1 flex-col",
wideMode && "absolute inset-0 z-10 bg-theme-background pl-12",
wideMode && "absolute inset-0 z-10 bg-theme-background",
)}
>
{wideMode && (
<ActionButton
className={cn(
"absolute left-3 top-3 z-10",
"absolute left-3 top-3 z-10 duration-200",
shouldHeaderPaddingLeft
? "left-[calc(theme(width.3)+theme(width.feed-col))]"
: "left-3",
Expand All @@ -57,7 +57,9 @@ export const Component = () => {
<EntryContent
entryId={realEntryId}
classNames={{
header: shouldHeaderPaddingLeft ? "ml-[theme(width.feed-col)]" : "",
header: shouldHeaderPaddingLeft
? "ml-[calc(theme(width.feed-col)+theme(width.12))]"
: "ml-12",
}}
/>
</m.div>
Expand Down
13 changes: 10 additions & 3 deletions apps/renderer/src/pages/(main)/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { setMainContainerElement } from "~/atoms/dom"
import { useViewport } from "~/atoms/hooks/viewport"
import { getUISettings, setUISetting, useUISettingKey } from "~/atoms/settings/ui"
import {
getFeedColumnTempShow,
setFeedColumnShow,
setFeedColumnTempShow,
useFeedColumnShow,
Expand Down Expand Up @@ -212,14 +213,20 @@ const FeedResponsiveResizerContainer = ({
const feedColumnShow = useFeedColumnShow()
const feedColumnTempShow = useFeedColumnTempShow()

const isInEntryContentWideMode = useUISettingKey("wideMode")
useEffect(() => {
if (feedColumnShow) {
setFeedColumnTempShow(false)
return
}
const handler = throttle((e: MouseEvent) => {
const mouseX = e.clientX
const mouseY = e.clientY

const uiSettings = getUISettings()
const feedColumnTempShow = getFeedColumnTempShow()
const isInEntryContentWideMode = uiSettings.wideMode
if (mouseY < 100 && isInEntryContentWideMode) return
const threshold = feedColumnTempShow ? getUISettings().feedColWidth : 100
const threshold = feedColumnTempShow ? uiSettings.feedColWidth : 100

if (mouseX < threshold) {
setFeedColumnTempShow(true)
Expand All @@ -232,7 +239,7 @@ const FeedResponsiveResizerContainer = ({
return () => {
document.removeEventListener("mousemove", handler)
}
}, [feedColumnTempShow, isInEntryContentWideMode])
}, [feedColumnShow])

useHotkeys(
shortcuts.layout.toggleSidebar.key,
Expand Down

0 comments on commit 535afe2

Please sign in to comment.