Initial commit
This commit is contained in:
71
src/components/editor/TOC/TOC.tsx
Normal file
71
src/components/editor/TOC/TOC.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user