nex_design/src/pages/DocsPage.jsx

191 lines
4.7 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import { useState, useEffect } from 'react'
import { Layout, Menu, Spin } from 'antd'
import { FileTextOutlined } from '@ant-design/icons'
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
import rehypeRaw from 'rehype-raw'
import rehypeHighlight from 'rehype-highlight'
import 'highlight.js/styles/github.css'
import './DocsPage.css'
const { Sider, Content } = Layout
// 文档目录数据
const docsMenuData = [
{
key: 'design',
label: '设计规范',
children: [
{
key: 'design-cookbook',
label: '设计手册',
path: '/docs/DESIGN_COOKBOOK.md',
},
],
},
{
key: 'components',
label: '组件文档',
children: [
{
key: 'components-overview',
label: '组件概览',
path: '/docs/components/README.md',
},
{
key: 'page-title-bar',
label: 'PageTitleBar',
path: '/docs/components/PageTitleBar.md',
},
{
key: 'list-action-bar',
label: 'ListActionBar',
path: '/docs/components/ListActionBar.md',
},
{
key: 'tree-filter-panel',
label: 'TreeFilterPanel',
path: '/docs/components/TreeFilterPanel.md',
},
{
key: 'list-table',
label: 'ListTable',
path: '/docs/components/ListTable.md',
},
{
key: 'detail-drawer',
label: 'DetailDrawer',
path: '/docs/components/DetailDrawer.md',
},
{
key: 'info-panel',
label: 'InfoPanel',
path: '/docs/components/InfoPanel.md',
},
{
key: 'confirm-dialog',
label: 'ConfirmDialog',
path: '/docs/components/ConfirmDialog.md',
},
{
key: 'toast',
label: 'Toast',
path: '/docs/components/Toast.md',
},
],
},
{
key: 'pages',
label: '页面文档',
children: [
{
key: 'main-layout',
label: '主布局',
path: '/docs/pages/main-layout.md',
},
],
},
]
function DocsPage() {
const [selectedKey, setSelectedKey] = useState('design-cookbook')
const [markdownContent, setMarkdownContent] = useState('')
const [loading, setLoading] = useState(false)
// 构建菜单项
const menuItems = docsMenuData.map((group) => ({
key: group.key,
label: group.label,
icon: <FileTextOutlined />,
children: group.children.map((item) => ({
key: item.key,
label: item.label,
})),
}))
// 根据 key 查找文档路径
const findDocPath = (key) => {
for (const group of docsMenuData) {
const found = group.children.find((item) => item.key === key)
if (found) return found.path
}
return null
}
// 加载 markdown 文件
const loadMarkdown = async (key) => {
const path = findDocPath(key)
if (!path) return
setLoading(true)
try {
const response = await fetch(path)
if (response.ok) {
const text = await response.text()
setMarkdownContent(text)
} else {
setMarkdownContent('# 文档加载失败\n\n无法加载该文档请稍后重试。')
}
} catch (error) {
console.error('Error loading markdown:', error)
setMarkdownContent('# 文档加载失败\n\n' + error.message)
} finally {
setLoading(false)
}
}
// 处理菜单点击
const handleMenuClick = ({ key }) => {
setSelectedKey(key)
loadMarkdown(key)
}
// 初始加载默认文档
useEffect(() => {
loadMarkdown(selectedKey)
}, [])
return (
<div className="docs-page">
<Layout className="docs-layout">
{/* 左侧目录 */}
<Sider width={280} className="docs-sider" theme="light">
<div className="docs-sider-header">
<h2>文档中心</h2>
</div>
<Menu
mode="inline"
selectedKeys={[selectedKey]}
defaultOpenKeys={['design', 'components', 'pages']}
items={menuItems}
onClick={handleMenuClick}
className="docs-menu"
/>
</Sider>
{/* 右侧内容 */}
<Content className="docs-content">
<div className="docs-content-wrapper">
{loading ? (
<div className="docs-loading">
<Spin size="large" tip="加载中..." />
</div>
) : (
<div className="markdown-body">
<ReactMarkdown
remarkPlugins={[remarkGfm]}
rehypePlugins={[rehypeRaw, rehypeHighlight]}
>
{markdownContent}
</ReactMarkdown>
</div>
)}
</div>
</Content>
</Layout>
</div>
)
}
export default DocsPage