diff --git a/src/components/Comment/index.js b/src/components/Comment/index.js
new file mode 100644
index 0000000..0442a95
--- /dev/null
+++ b/src/components/Comment/index.js
@@ -0,0 +1,93 @@
+import React, { useState, useEffect } from 'react';
+import styles from './styles.module.css';
+
+export default function Comment({ docId }) {
+ const [comments, setComments] = useState([]);
+ const [newComment, setNewComment] = useState('');
+ const [isOpen, setIsOpen] = useState(false);
+
+ useEffect(() => {
+ // 从localStorage中读取评论
+ const savedComments = JSON.parse(localStorage.getItem(`docComments_${docId}`) || '[]');
+ setComments(savedComments);
+ }, [docId]);
+
+ const handleAddComment = () => {
+ if (!newComment.trim()) return;
+
+ const comment = {
+ id: Date.now(),
+ text: newComment,
+ timestamp: new Date().toLocaleString(),
+ author: '用户' // 这里可以替换为实际的用户名
+ };
+
+ const updatedComments = [...comments, comment];
+ setComments(updatedComments);
+ localStorage.setItem(`docComments_${docId}`, JSON.stringify(updatedComments));
+ setNewComment('');
+ };
+
+ const handleDeleteComment = (commentId) => {
+ const updatedComments = comments.filter(comment => comment.id !== commentId);
+ setComments(updatedComments);
+ localStorage.setItem(`docComments_${docId}`, JSON.stringify(updatedComments));
+ };
+
+ return (
+
+
+
+ {isOpen && (
+
+
+ {comments.map(comment => (
+
+
+ {comment.author}
+ {comment.timestamp}
+
+
+
{comment.text}
+
+ ))}
+
+
+
+
+ )}
+
+ );
+}
\ No newline at end of file
diff --git a/src/components/Comment/styles.module.css b/src/components/Comment/styles.module.css
new file mode 100644
index 0000000..054a149
--- /dev/null
+++ b/src/components/Comment/styles.module.css
@@ -0,0 +1,132 @@
+.commentContainer {
+ position: relative;
+ display: inline-block;
+}
+
+.commentButton {
+ background: none;
+ border: none;
+ cursor: pointer;
+ padding: 4px;
+ color: var(--ifm-color-emphasis-600);
+ transition: all 0.2s ease;
+ opacity: 0;
+ z-index: 100;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ width: 20px;
+ height: 20px;
+}
+
+.commentButton:hover {
+ color: var(--ifm-color-primary);
+ transform: scale(1.1);
+}
+
+.commentPanel {
+ position: absolute;
+ top: 100%;
+ right: 0;
+ width: 300px;
+ background: var(--ifm-background-color);
+ border: 1px solid var(--ifm-color-emphasis-200);
+ border-radius: 8px;
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
+ z-index: 1000;
+ margin-top: 8px;
+ padding: 16px;
+}
+
+.commentList {
+ max-height: 300px;
+ overflow-y: auto;
+ margin-bottom: 16px;
+}
+
+.commentItem {
+ padding: 8px;
+ border-bottom: 1px solid var(--ifm-color-emphasis-200);
+}
+
+.commentItem:last-child {
+ border-bottom: none;
+}
+
+.commentHeader {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 4px;
+}
+
+.commentAuthor {
+ font-weight: 500;
+ color: var(--ifm-color-primary);
+}
+
+.commentTime {
+ font-size: 12px;
+ color: var(--ifm-color-emphasis-600);
+}
+
+.deleteButton {
+ background: none;
+ border: none;
+ color: var(--ifm-color-emphasis-600);
+ cursor: pointer;
+ padding: 0 4px;
+ font-size: 16px;
+}
+
+.deleteButton:hover {
+ color: var(--ifm-color-danger);
+}
+
+.commentText {
+ font-size: 14px;
+ line-height: 1.4;
+ color: var(--ifm-color-emphasis-800);
+}
+
+.commentInput {
+ display: flex;
+ flex-direction: column;
+ gap: 8px;
+}
+
+.commentInput textarea {
+ width: 100%;
+ padding: 8px;
+ border: 1px solid var(--ifm-color-emphasis-200);
+ border-radius: 4px;
+ resize: vertical;
+ font-family: inherit;
+ font-size: 14px;
+}
+
+.commentInput textarea:focus {
+ outline: none;
+ border-color: var(--ifm-color-primary);
+}
+
+.submitButton {
+ align-self: flex-end;
+ padding: 6px 12px;
+ background-color: var(--ifm-color-primary);
+ color: white;
+ border: none;
+ border-radius: 4px;
+ cursor: pointer;
+ font-size: 14px;
+ transition: background-color 0.2s ease;
+}
+
+.submitButton:hover {
+ background-color: var(--ifm-color-primary-darker);
+}
+
+/* 当鼠标悬停在侧边栏项目上时显示评论按钮 */
+:global(.menu__link-wrapper:hover) .commentButton {
+ opacity: 1;
+}
\ No newline at end of file
diff --git a/src/theme/DocSidebarItem/index.js b/src/theme/DocSidebarItem/index.js
index 43fd1c6..d75aba0 100644
--- a/src/theme/DocSidebarItem/index.js
+++ b/src/theme/DocSidebarItem/index.js
@@ -1,6 +1,7 @@
import React, { useEffect, useState } from 'react';
import DocSidebarItem from '@theme-original/DocSidebarItem';
import styles from './styles.module.css';
+import Comment from '@site/src/components/Comment';
export default function DocSidebarItemWrapper(props) {
const { item } = props;
@@ -31,6 +32,9 @@ export default function DocSidebarItemWrapper(props) {
);
diff --git a/src/theme/DocSidebarItem/styles.module.css b/src/theme/DocSidebarItem/styles.module.css
index ea09cda..0381f52 100644
--- a/src/theme/DocSidebarItem/styles.module.css
+++ b/src/theme/DocSidebarItem/styles.module.css
@@ -1,13 +1,35 @@
.menuLinkWrapper {
position: relative;
+ display: flex;
+ align-items: center;
+ width: 100%;
+}
+
+.actionButtons {
+ display: flex;
+ align-items: center;
+ margin-left: auto;
+ padding-right: 8px;
+}
+
+.bookmarkedItem {
+ background-color: var(--ifm-color-emphasis-100);
}
.bookmarkedItem :global(.menu__link) {
- color: var(--ifm-color-primary) !important;
- font-weight: 500 !important;
- background-color: var(--ifm-color-emphasis-100) !important;
- border-left: 3px solid var(--ifm-color-primary) !important;
- padding-left: calc(1rem - 3px) !important;
+ font-weight: 500;
+ color: var(--ifm-color-primary);
+}
+
+/* 确保侧边栏项目有足够的空间显示按钮 */
+:global(.menu__link-wrapper) {
+ padding-right: 60px !important;
+ position: relative !important;
+}
+
+/* 调整列表项样式 */
+:global(.menu__list-item) {
+ position: relative !important;
}
.bookmarkedItem :global(.menu__link:hover) {