Files
XCDesktop/src/components/editor/TOC/TOC.tsx
2026-03-08 01:34:54 +08:00

72 lines
2.4 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import React from 'react'
import type { TOCItem } from '@/lib/utils'
import { useWallpaper } from '@/stores'
export interface TOCProps {
isOpen: boolean
onClose: () => void
tocItems: TOCItem[]
width: number
onResizeStart: (e: React.MouseEvent) => void
onTOCItemClick: (id: string) => void
}
const renderTOCItem = (item: TOCItem, onTOCItemClick: (id: string) => void) => {
const indent = (item.level - 1) * 16
return (
<div key={item.id} className="mb-1">
<div
className="text-gray-600 dark:text-gray-200 hover:text-gray-900 dark:hover:text-white cursor-pointer px-2 py-1 rounded hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors"
style={{ marginLeft: `${indent}px` }}
onClick={() => onTOCItemClick(item.id)}
>
{item.text}
</div>
{item.children.length > 0 && (
<div className="mt-1">
{item.children.map(child => renderTOCItem(child, onTOCItemClick))}
</div>
)}
</div>
)
}
export const TOC: React.FC<TOCProps> = ({ isOpen, onClose, tocItems, width, onResizeStart, onTOCItemClick }) => {
const { opacity } = useWallpaper()
return (
<div
className={`absolute left-0 top-0 bottom-0 border-r border-gray-200 dark:border-gray-700/60 flex flex-col z-30 transition-transform duration-300 ease-in-out transform backdrop-blur-sm ${isOpen ? 'translate-x-0' : '-translate-x-full'}`}
style={{
width,
backgroundColor: `rgba(var(--app-toc-bg-rgb), ${opacity})`,
}}
>
<div className="h-12 flex items-center px-4 border-b border-gray-200 dark:border-gray-700/60 font-semibold text-gray-700 dark:text-gray-200 flex justify-between">
<span className="text-base"></span>
<button
onClick={onClose}
className="w-8 h-8 hover:bg-gray-100 dark:hover:bg-gray-700 rounded flex items-center justify-center text-2xl"
>
×
</button>
</div>
<div className="flex-1 overflow-y-auto p-4 no-scrollbar">
{tocItems.length > 0 ? (
<div>
{tocItems.map(item => renderTOCItem(item, onTOCItemClick))}
</div>
) : (
<div className="text-gray-600 dark:text-gray-200"></div>
)}
</div>
<div
className="absolute right-0 top-0 bottom-0 w-1 cursor-col-resize z-10"
onMouseDown={onResizeStart}
/>
</div>
)
}