forked from Gitlink/gitlink_help_center
Merge pull request '测试' (#17) from master into wangjing22e
This commit is contained in:
commit
862c49c38d
|
|
@ -15,6 +15,16 @@ module.exports = {
|
|||
projectName: 'docusaurus-luffyzh-website', // Usually your repo name.
|
||||
scripts: [],
|
||||
// stylesheets: ['styles/dark-mode.css'],
|
||||
plugins: [
|
||||
function (context, options) {
|
||||
return {
|
||||
name: 'custom-docusaurus-plugin',
|
||||
injectHtmlTags() {
|
||||
return {};
|
||||
},
|
||||
};
|
||||
},
|
||||
],
|
||||
themeConfig: {
|
||||
|
||||
docs:{
|
||||
|
|
@ -75,6 +85,10 @@ module.exports = {
|
|||
// position: 'right',
|
||||
// className: 'header-github-link',
|
||||
// },
|
||||
{
|
||||
type: 'custom-table-of-contents',
|
||||
position: 'right'
|
||||
},
|
||||
{
|
||||
type: 'custom-pdf-export',
|
||||
position: 'right'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,464 @@
|
|||
import React, { useState, useRef, useEffect } from 'react';
|
||||
import BrowserOnly from '@docusaurus/BrowserOnly';
|
||||
import styles from './TableOfContentsButton.module.css';
|
||||
|
||||
export default function TableOfContentsButton() {
|
||||
return (
|
||||
<BrowserOnly>
|
||||
{() => {
|
||||
const [isOpen, setIsOpen] = useState(false);
|
||||
const [searchQuery, setSearchQuery] = useState('');
|
||||
const dropdownRef = useRef(null);
|
||||
const searchInputRef = useRef(null);
|
||||
const useHistory = require('@docusaurus/router').useHistory;
|
||||
const history = useHistory();
|
||||
|
||||
// 路径前缀
|
||||
const pathPrefix = '/next';
|
||||
|
||||
// 硬编码的目录结构,基于实际docs文件夹结构
|
||||
// 带有子目录支持
|
||||
const directories = [
|
||||
{
|
||||
name: '首页',
|
||||
path: `${pathPrefix}/`,
|
||||
column: 1,
|
||||
isMainCategory: true
|
||||
},
|
||||
{
|
||||
name: '视频教程',
|
||||
path: `${pathPrefix}/视频教程`,
|
||||
column: 1,
|
||||
isMainCategory: true
|
||||
},
|
||||
{
|
||||
name: '快速开始',
|
||||
path: `${pathPrefix}/快速开始`,
|
||||
column: 1,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '注册GitLink账号', path: `${pathPrefix}/快速开始/注册GitLink账号` },
|
||||
{ name: '创建第一个开源项目', path: `${pathPrefix}/快速开始/创建第一个开源项目` },
|
||||
{ name: '提交第一行代码', path: `${pathPrefix}/快速开始/提交第一行代码` },
|
||||
{ name: '导入GitHub等第三方Git项目', path: `${pathPrefix}/快速开始/导入GitHub等第三方Git项目` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '代码库管理',
|
||||
path: `${pathPrefix}/代码库管理`,
|
||||
column: 1,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '仓库创建', path: `${pathPrefix}/代码库管理/仓库创建` },
|
||||
{ name: '仓库设置', path: `${pathPrefix}/代码库管理/仓库设置` },
|
||||
{ name: '代码提交', path: `${pathPrefix}/代码库管理/代码提交` },
|
||||
{ name: '分支管理', path: `${pathPrefix}/代码库管理/分支管理` },
|
||||
{ name: '文件管理', path: `${pathPrefix}/代码库管理/文件管理` },
|
||||
{ name: '成员管理', path: `${pathPrefix}/代码库管理/成员管理` },
|
||||
{ name: 'Webhook', path: `${pathPrefix}/代码库管理/Webhook` },
|
||||
{ name: 'WebIDE', path: `${pathPrefix}/代码库管理/WebIDE` },
|
||||
{ name: '标签和发行版管理', path: `${pathPrefix}/代码库管理/标签和发行版管理` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '合并请求(PR)',
|
||||
path: `${pathPrefix}/合并请求`,
|
||||
column: 2,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '合并请求简介', path: `${pathPrefix}/合并请求/合并请求简介` },
|
||||
{ name: '创建合并请求', path: `${pathPrefix}/合并请求/创建合并请求` },
|
||||
{ name: '代码评审', path: `${pathPrefix}/合并请求/代码评审` },
|
||||
{ name: '合并模式简介', path: `${pathPrefix}/合并请求/合并模式简介` },
|
||||
{ name: '合并请求关联疑修', path: `${pathPrefix}/合并请求/合并请求关联疑修` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '疑修(Issue)',
|
||||
path: `${pathPrefix}/疑修`,
|
||||
column: 3,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '疑修简介', path: `${pathPrefix}/疑修/疑修简介` },
|
||||
{ name: '疑修创建', path: `${pathPrefix}/疑修/疑修创建` },
|
||||
{ name: '疑修状态变更', path: `${pathPrefix}/疑修/疑修状态变更` },
|
||||
{ name: '疑修列表', path: `${pathPrefix}/疑修/疑修列表` },
|
||||
{ name: '评论及操作记录', path: `${pathPrefix}/疑修/评论及操作记录` },
|
||||
{ name: '标记管理', path: `${pathPrefix}/疑修/标记管理` },
|
||||
{ name: '里程碑管理', path: `${pathPrefix}/疑修/里程碑管理` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '机器人(Bot)',
|
||||
path: `${pathPrefix}/Bot市场/Bot简介`,
|
||||
column: 2,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: 'bot安装', path: `${pathPrefix}/Bot市场/bot安装` },
|
||||
{ name: 'bot配置', path: `${pathPrefix}/Bot市场/bot配置` },
|
||||
{ name: 'bot开发', path: `${pathPrefix}/Bot市场/bot开发` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '第三方服务',
|
||||
path: `${pathPrefix}/第三方服务`,
|
||||
column: 2,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: 'WebIDE', path: `${pathPrefix}/第三方服务/WebIDE` },
|
||||
{ name: '重睛鸟代码溯源', path: `${pathPrefix}/第三方服务/重睛鸟代码溯源` },
|
||||
{ name: '跨平台代码同步服务', path: `${pathPrefix}/第三方服务/跨平台代码同步` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '组织管理',
|
||||
path: `${pathPrefix}/组织管理`,
|
||||
column: 2,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '组织简介', path: `${pathPrefix}/组织管理/组织简介` },
|
||||
{ name: '组织创建及设置', path: `${pathPrefix}/组织管理/组织创建及设置` },
|
||||
{ name: '组织团队管理', path: `${pathPrefix}/组织管理/组织团队管理` },
|
||||
{ name: '组织成员管理', path: `${pathPrefix}/组织管理/组织成员管理` },
|
||||
{ name: '组织项目管理', path: `${pathPrefix}/组织管理/组织项目管理` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '维基',
|
||||
path: `${pathPrefix}/维基`,
|
||||
column: 2,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '维基页面管理', path: `${pathPrefix}/维基/维基页面管理` },
|
||||
{ name: '模板导入及导出', path: `${pathPrefix}/维基/模板导入及导出` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: 'DevOps引擎',
|
||||
path: `${pathPrefix}/DevOps引擎`,
|
||||
column: 3,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '引擎简介', path: `${pathPrefix}/DevOps引擎/引擎简介` },
|
||||
{ name: '代码流水线', path: `${pathPrefix}/DevOps引擎/代码流水线` },
|
||||
{ name: '图形流水线', path: `${pathPrefix}/DevOps引擎/图形流水线` },
|
||||
{ name: '参数配置', path: `${pathPrefix}/DevOps引擎/参数配置` },
|
||||
{ name: '密钥设置', path: `${pathPrefix}/DevOps引擎/密钥设置` },
|
||||
{ name: '执行记录查询', path: `${pathPrefix}/DevOps引擎/执行记录查询` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '通知',
|
||||
path: `${pathPrefix}/通知`,
|
||||
column: 3,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '通知简介', path: `${pathPrefix}/通知/通知简介` },
|
||||
{ name: '通知设置', path: `${pathPrefix}/通知/通知设置` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '个人主页建站',
|
||||
path: `${pathPrefix}/个人主页建站`,
|
||||
column: 3,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: '建站流程', path: `${pathPrefix}/个人主页建站/站点创建流程` },
|
||||
{ name: '建站工具', path: `${pathPrefix}/个人主页建站/建站工具` }
|
||||
]
|
||||
},
|
||||
{
|
||||
name: '平台公告',
|
||||
path: `${pathPrefix}/平台公告`,
|
||||
column: 3,
|
||||
isMainCategory: true
|
||||
},
|
||||
{
|
||||
name: '服务协议',
|
||||
path: `${pathPrefix}/服务协议`,
|
||||
column: 3,
|
||||
isMainCategory: true,
|
||||
subItems: [
|
||||
{ name: 'GitLink服务协议', path: `${pathPrefix}/服务协议/GitLink服务协议` }
|
||||
]
|
||||
}
|
||||
];
|
||||
|
||||
// 按列分组目录
|
||||
// 重新分配各目录到三列,确保各列内容均衡
|
||||
const column1 = directories.filter(dir =>
|
||||
dir.name === '首页' ||
|
||||
dir.name === '视频教程' ||
|
||||
dir.name === '快速开始' ||
|
||||
dir.name === '代码库管理' ||
|
||||
dir.name === '合并请求(PR)'
|
||||
);
|
||||
|
||||
const column2 = directories.filter(dir =>
|
||||
dir.name === '疑修(Issue)' ||
|
||||
dir.name === '机器人(Bot)' ||
|
||||
dir.name === '维基' ||
|
||||
dir.name === '第三方服务' ||
|
||||
dir.name === '组织管理'
|
||||
);
|
||||
|
||||
const column3 = directories.filter(dir =>
|
||||
dir.name === 'DevOps引擎' ||
|
||||
dir.name === '通知' ||
|
||||
dir.name === '个人主页建站' ||
|
||||
dir.name === '平台公告' ||
|
||||
dir.name === '服务协议'
|
||||
);
|
||||
|
||||
// 移除列4,改为三列布局
|
||||
const column4 = [];
|
||||
|
||||
// 搜索功能
|
||||
// 过滤目录项
|
||||
const filterDirectories = (query) => {
|
||||
if (!query) return directories;
|
||||
|
||||
const normalizedQuery = query.toLowerCase().trim();
|
||||
|
||||
return directories.filter(dir => {
|
||||
// 检查主目录名称是否匹配
|
||||
const dirNameMatch = dir.name.toLowerCase().includes(normalizedQuery);
|
||||
|
||||
// 如果主目录匹配,直接返回
|
||||
if (dirNameMatch) return true;
|
||||
|
||||
// 检查子目录是否有匹配
|
||||
if (dir.subItems && dir.subItems.length > 0) {
|
||||
const hasMatchingSubItem = dir.subItems.some(
|
||||
subItem => subItem.name.toLowerCase().includes(normalizedQuery)
|
||||
);
|
||||
return hasMatchingSubItem;
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
};
|
||||
|
||||
// 获取经过搜索过滤的目录列表
|
||||
const filteredDirectories = filterDirectories(searchQuery);
|
||||
|
||||
// 过滤后的目录分组
|
||||
const filteredColumn1 = filteredDirectories.filter(dir => column1.some(c => c.name === dir.name));
|
||||
const filteredColumn2 = filteredDirectories.filter(dir => column2.some(c => c.name === dir.name));
|
||||
const filteredColumn3 = filteredDirectories.filter(dir => column3.some(c => c.name === dir.name));
|
||||
|
||||
// 将搜索结果重新分配到各列,实现更均衡的布局
|
||||
const distributeSearchResults = (results) => {
|
||||
if (!searchQuery) {
|
||||
// 不搜索时使用原始布局
|
||||
return {
|
||||
col1: filteredColumn1,
|
||||
col2: filteredColumn2,
|
||||
col3: filteredColumn3,
|
||||
col4: []
|
||||
};
|
||||
}
|
||||
|
||||
// 搜索时根据数量动态分配
|
||||
const totalCount = results.length;
|
||||
|
||||
if (totalCount <= 3) {
|
||||
// 结果很少时,全部放在第一列
|
||||
return {
|
||||
col1: results,
|
||||
col2: [],
|
||||
col3: [],
|
||||
col4: []
|
||||
};
|
||||
} else if (totalCount <= 6) {
|
||||
// 结果较少时,放在两列
|
||||
const midPoint = Math.ceil(totalCount / 2);
|
||||
return {
|
||||
col1: results.slice(0, midPoint),
|
||||
col2: results.slice(midPoint),
|
||||
col3: [],
|
||||
col4: []
|
||||
};
|
||||
} else {
|
||||
// 结果较多时,放在三列
|
||||
const colSize = Math.ceil(totalCount / 3);
|
||||
return {
|
||||
col1: results.slice(0, colSize),
|
||||
col2: results.slice(colSize, colSize * 2),
|
||||
col3: results.slice(colSize * 2),
|
||||
col4: []
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
// 获取重新分配后的各列内容
|
||||
const {
|
||||
col1: displayColumn1,
|
||||
col2: displayColumn2,
|
||||
col3: displayColumn3,
|
||||
col4: displayColumn4
|
||||
} = distributeSearchResults(filteredDirectories);
|
||||
|
||||
// 处理搜索框变化
|
||||
const handleSearchChange = (e) => {
|
||||
setSearchQuery(e.target.value);
|
||||
};
|
||||
|
||||
// 清除搜索
|
||||
const clearSearch = () => {
|
||||
setSearchQuery('');
|
||||
if (searchInputRef.current) {
|
||||
searchInputRef.current.focus();
|
||||
}
|
||||
};
|
||||
|
||||
// 处理点击目录链接
|
||||
const handleDirectoryClick = (dir) => {
|
||||
// 如果有子目录,则跳转到第一个子目录
|
||||
if (dir.subItems && dir.subItems.length > 0) {
|
||||
history.push(dir.subItems[0].path);
|
||||
} else {
|
||||
history.push(dir.path);
|
||||
}
|
||||
setIsOpen(false);
|
||||
};
|
||||
|
||||
// 点击外部关闭下拉菜单
|
||||
useEffect(() => {
|
||||
function handleClickOutside(event) {
|
||||
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
||||
setIsOpen(false);
|
||||
}
|
||||
}
|
||||
|
||||
document.addEventListener('mousedown', handleClickOutside);
|
||||
return () => {
|
||||
document.removeEventListener('mousedown', handleClickOutside);
|
||||
};
|
||||
}, []);
|
||||
|
||||
// 当目录打开时聚焦到搜索框
|
||||
useEffect(() => {
|
||||
if (isOpen && searchInputRef.current) {
|
||||
setTimeout(() => {
|
||||
searchInputRef.current.focus();
|
||||
}, 100);
|
||||
} else {
|
||||
setSearchQuery(''); // 关闭目录时清空搜索
|
||||
}
|
||||
}, [isOpen]);
|
||||
|
||||
// 渲染目录项
|
||||
const renderDirectoryItem = (dir) => {
|
||||
// 当有搜索词时,只显示匹配的子项
|
||||
let subItems = dir.subItems;
|
||||
if (searchQuery && dir.subItems) {
|
||||
const normalizedQuery = searchQuery.toLowerCase().trim();
|
||||
subItems = dir.subItems.filter(item =>
|
||||
item.name.toLowerCase().includes(normalizedQuery)
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div key={dir.name} className={styles.directoryItem}>
|
||||
<a
|
||||
onClick={() => handleDirectoryClick(dir)}
|
||||
className={`${styles.docLink} ${styles.mainCategory}`}
|
||||
>
|
||||
{dir.name}
|
||||
</a>
|
||||
|
||||
{subItems && subItems.length > 0 && (
|
||||
<div className={styles.subItemsContainer}>
|
||||
{subItems.map(subItem => (
|
||||
<a
|
||||
key={subItem.name}
|
||||
onClick={() => {
|
||||
history.push(subItem.path);
|
||||
setIsOpen(false);
|
||||
}}
|
||||
className={`${styles.docLink} ${styles.subCategory}`}
|
||||
>
|
||||
{subItem.name}
|
||||
</a>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className={styles.tocButtonContainer} ref={dropdownRef}>
|
||||
<button
|
||||
className={styles.tocButton}
|
||||
onClick={() => setIsOpen(!isOpen)}
|
||||
aria-label="文档目录"
|
||||
title="浏览文档目录"
|
||||
>
|
||||
<span className={styles.tocIcon}>
|
||||
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M3 5H21" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
|
||||
<path d="M3 12H21" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
|
||||
<path d="M3 19H21" stroke="currentColor" strokeWidth="2" strokeLinecap="round"/>
|
||||
</svg>
|
||||
</span>
|
||||
</button>
|
||||
|
||||
{isOpen && (
|
||||
<div className={styles.tocDropdown}>
|
||||
<h2 className={styles.tocTitle}>文档目录</h2>
|
||||
|
||||
<div className={styles.searchContainer}>
|
||||
<input
|
||||
ref={searchInputRef}
|
||||
type="text"
|
||||
value={searchQuery}
|
||||
onChange={handleSearchChange}
|
||||
placeholder="搜索文档..."
|
||||
className={styles.searchInput}
|
||||
aria-label="搜索文档"
|
||||
/>
|
||||
{searchQuery && (
|
||||
<button
|
||||
className={styles.clearSearchButton}
|
||||
onClick={clearSearch}
|
||||
aria-label="清除搜索"
|
||||
>
|
||||
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M18 6L6 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
<path d="M6 6L18 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
|
||||
</svg>
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={styles.tocContent}>
|
||||
{filteredDirectories.length === 0 ? (
|
||||
<div className={styles.emptyMessage}>未找到匹配的文档</div>
|
||||
) : (
|
||||
<div className={styles.multiColumnLayout}>
|
||||
<div className={styles.column}>
|
||||
{displayColumn1.map(renderDirectoryItem)}
|
||||
</div>
|
||||
{displayColumn2.length > 0 && (
|
||||
<div className={styles.column}>
|
||||
{displayColumn2.map(renderDirectoryItem)}
|
||||
</div>
|
||||
)}
|
||||
{displayColumn3.length > 0 && (
|
||||
<div className={styles.column}>
|
||||
{displayColumn3.map(renderDirectoryItem)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}}
|
||||
</BrowserOnly>
|
||||
);
|
||||
}
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
.tocButtonContainer {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
/* 搜索框样式 */
|
||||
.searchContainer {
|
||||
position: relative;
|
||||
margin-bottom: 1rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.searchInput {
|
||||
width: 100%;
|
||||
padding: 0.75rem 2.5rem 0.75rem 1rem;
|
||||
border-radius: 6px;
|
||||
border: 1px solid var(--ifm-color-emphasis-300);
|
||||
background-color: var(--ifm-background-color);
|
||||
color: var(--ifm-font-color-base);
|
||||
font-size: 0.95rem;
|
||||
outline: none;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.searchInput:focus {
|
||||
border-color: var(--ifm-color-primary);
|
||||
box-shadow: 0 0 0 2px rgba(var(--ifm-color-primary-rgb), 0.25);
|
||||
}
|
||||
|
||||
.clearSearchButton {
|
||||
position: absolute;
|
||||
right: 10px;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
background: none;
|
||||
border: none;
|
||||
padding: 4px;
|
||||
cursor: pointer;
|
||||
color: var(--ifm-color-emphasis-500);
|
||||
border-radius: 50%;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.clearSearchButton:hover {
|
||||
background-color: var(--ifm-color-emphasis-200);
|
||||
color: var(--ifm-color-emphasis-700);
|
||||
}
|
||||
|
||||
/* 暗色模式搜索框适配 */
|
||||
html[data-theme='dark'] .searchInput {
|
||||
background-color: var(--ifm-background-surface-color);
|
||||
border-color: var(--ifm-color-emphasis-300);
|
||||
}
|
||||
|
||||
html[data-theme='dark'] .searchInput:focus {
|
||||
border-color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
.tocButton {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background-color: transparent;
|
||||
border: none;
|
||||
color: var(--ifm-navbar-link-color);
|
||||
cursor: pointer;
|
||||
padding: 0.5rem;
|
||||
border-radius: 50%;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.tocButton:hover {
|
||||
background-color: var(--ifm-color-emphasis-200);
|
||||
color: var(--ifm-navbar-link-hover-color);
|
||||
}
|
||||
|
||||
.tocIcon {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.tocDropdown {
|
||||
position: absolute;
|
||||
top: calc(100% + 5px);
|
||||
right: 0;
|
||||
width: 800px;
|
||||
max-width: 98vw;
|
||||
max-height: 90vh;
|
||||
overflow-y: auto;
|
||||
background-color: var(--ifm-background-surface-color);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.16);
|
||||
z-index: 1000;
|
||||
padding: 1.5rem;
|
||||
border: 1px solid var(--ifm-color-emphasis-200);
|
||||
}
|
||||
|
||||
.tocTitle {
|
||||
font-size: 1.25rem;
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
padding-bottom: 0.5rem;
|
||||
border-bottom: 1px solid var(--ifm-color-emphasis-200);
|
||||
}
|
||||
|
||||
.tocContent {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.multiColumnLayout {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
gap: 1.5rem;
|
||||
width: 100%;
|
||||
align-items: flex-start;
|
||||
}
|
||||
|
||||
.column {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 0.85rem;
|
||||
flex: 1;
|
||||
min-width: 160px;
|
||||
}
|
||||
|
||||
.column:nth-child(1),
|
||||
.column:nth-child(2),
|
||||
.column:nth-child(3) {
|
||||
align-self: stretch;
|
||||
height: 100%;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.column:nth-child(4) {
|
||||
align-self: flex-start;
|
||||
}
|
||||
|
||||
.directoryItem {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
margin-bottom: 0.2rem;
|
||||
}
|
||||
|
||||
.mainCategory {
|
||||
font-weight: 600;
|
||||
color: var(--ifm-color-primary);
|
||||
padding: 0.5rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.subItemsContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding-left: 1.25rem;
|
||||
margin-top: 0.15rem;
|
||||
margin-bottom: 0.25rem;
|
||||
gap: 0.25rem;
|
||||
}
|
||||
|
||||
.subCategory {
|
||||
font-weight: normal;
|
||||
color: var(--ifm-font-color-base);
|
||||
padding: 0.3rem 0.5rem;
|
||||
font-size: 0.92rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.subCategory:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -8px;
|
||||
top: 50%;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
border-radius: 50%;
|
||||
background-color: var(--ifm-color-emphasis-400);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
.docLink {
|
||||
display: block;
|
||||
text-decoration: none;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
}
|
||||
|
||||
.docLink:hover {
|
||||
background-color: var(--ifm-color-emphasis-100);
|
||||
color: var(--ifm-color-primary);
|
||||
}
|
||||
|
||||
.activeDoc .docLink {
|
||||
background-color: var(--ifm-color-emphasis-100);
|
||||
color: var(--ifm-color-primary);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
/* 响应式样式 */
|
||||
@media (max-width: 768px) {
|
||||
.tocDropdown {
|
||||
width: 640px;
|
||||
right: -8px;
|
||||
}
|
||||
}
|
||||
|
||||
/* 暗色模式适配 */
|
||||
html[data-theme='dark'] .tocDropdown {
|
||||
background-color: var(--ifm-background-surface-color);
|
||||
border-color: var(--ifm-color-emphasis-300);
|
||||
}
|
||||
|
||||
/* 滚动条样式 */
|
||||
.tocDropdown::-webkit-scrollbar {
|
||||
width: 6px;
|
||||
}
|
||||
|
||||
.tocDropdown::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.tocDropdown::-webkit-scrollbar-thumb {
|
||||
background-color: var(--ifm-color-emphasis-300);
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.tocDropdown::-webkit-scrollbar-thumb:hover {
|
||||
background-color: var(--ifm-color-emphasis-400);
|
||||
}
|
||||
|
||||
.loadingMessage,
|
||||
.errorMessage,
|
||||
.emptyMessage {
|
||||
padding: 1rem;
|
||||
text-align: center;
|
||||
color: var(--ifm-color-emphasis-600);
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.errorMessage {
|
||||
color: #ff4d4f;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import React from 'react';
|
||||
import TableOfContentsButton from './TableOfContentsButton';
|
||||
|
||||
export default function TableOfContentsNavbarItem() {
|
||||
return <TableOfContentsButton />;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
import DefaultNavbarItem from '@theme/NavbarItem/DefaultNavbarItem';
|
||||
import DocNavbarItem from '@theme/NavbarItem/DocNavbarItem';
|
||||
import DocSidebarNavbarItem from '@theme/NavbarItem/DocSidebarNavbarItem';
|
||||
import DocsVersionNavbarItem from '@theme/NavbarItem/DocsVersionNavbarItem';
|
||||
import DocsVersionDropdownNavbarItem from '@theme/NavbarItem/DocsVersionDropdownNavbarItem';
|
||||
import DropdownNavbarItem from '@theme/NavbarItem/DropdownNavbarItem';
|
||||
import LocaleDropdownNavbarItem from '@theme/NavbarItem/LocaleDropdownNavbarItem';
|
||||
import SearchNavbarItem from '@theme/NavbarItem/SearchNavbarItem';
|
||||
|
||||
import PdfExportNavbarItem from '../../components/PdfExportNavbarItem';
|
||||
import PdfBackToTopNavbarItem from '../../components/PdfBackToTopNavbarItem';
|
||||
import QAButtonNavbarItem from '../../components/QAButtonNavbarItem';
|
||||
import TableOfContentsNavbarItem from '../../components/TableOfContentsNavbarItem';
|
||||
|
||||
const ComponentTypes = {
|
||||
default: DefaultNavbarItem,
|
||||
localeDropdown: LocaleDropdownNavbarItem,
|
||||
search: SearchNavbarItem,
|
||||
dropdown: DropdownNavbarItem,
|
||||
docsVersionDropdown: DocsVersionDropdownNavbarItem,
|
||||
docsVersion: DocsVersionNavbarItem,
|
||||
doc: DocNavbarItem,
|
||||
docSidebar: DocSidebarNavbarItem,
|
||||
'custom-pdf-export': PdfExportNavbarItem,
|
||||
'custom-back-to-top': PdfBackToTopNavbarItem,
|
||||
'custom-qa-button': QAButtonNavbarItem,
|
||||
'custom-table-of-contents': TableOfContentsNavbarItem,
|
||||
};
|
||||
|
||||
export default ComponentTypes;
|
||||
Loading…
Reference in New Issue