From 3fdee5cab445bcf7c103619bb2d5aad14c5f7f08 Mon Sep 17 00:00:00 2001 From: ddshi <8811906+ddshi@user.noreply.gitee.com> Date: Tue, 3 Feb 2026 16:29:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E4=BC=98=E5=8C=96=E6=8F=90=E9=86=92?= =?UTF-8?q?=E5=8D=A1=E7=89=87=E6=A0=B7=E5=BC=8F=E5=92=8C=E5=88=97=E8=A1=A8?= =?UTF-8?q?=E6=BB=9A=E5=8A=A8=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 调整正常提醒卡片布局:左侧 checkbox+标题+内容,右侧日期时间 - 移除正常卡片悬停时的编辑按钮 - 纪念日/提醒/便签列表支持独立滚动 - 页面整体禁用滚动,支持 Ctrl+滚轮缩放 - 滚动条样式优化:默认隐藏,悬停时显示淡雅样式 Co-Authored-By: Claude (MiniMax-M2.1) --- .../anniversary/AnniversaryList.tsx | 65 ++++- src/components/note/NoteEditor.tsx | 56 +++- src/components/reminder/ReminderCard.tsx | 244 ++++++++++++------ src/components/reminder/ReminderList.tsx | 61 ++++- src/pages/HomePage.tsx | 64 ++--- 5 files changed, 348 insertions(+), 142 deletions(-) diff --git a/src/components/anniversary/AnniversaryList.tsx b/src/components/anniversary/AnniversaryList.tsx index 6b59323..f042f6e 100644 --- a/src/components/anniversary/AnniversaryList.tsx +++ b/src/components/anniversary/AnniversaryList.tsx @@ -1,5 +1,5 @@ -import { useMemo } from 'react'; -import { Stack, Text, Paper, Group, Button } from '@mantine/core'; +import { useMemo, useRef } from 'react'; +import { Stack, Text, Paper, Group, Button, Box } from '@mantine/core'; import { IconPlus } from '@tabler/icons-react'; import { AnniversaryCard } from './AnniversaryCard'; import { getHolidaysForYear } from '../../constants/holidays'; @@ -28,6 +28,42 @@ interface BuiltInHolidayEvent { export function AnniversaryList({ events, onEventClick, onAddClick }: AnniversaryListProps) { const anniversaries = events.filter((e) => e.type === 'anniversary'); const showHolidays = useAppStore((state) => state.settings?.showHolidays ?? true); + const scrollContainerRef = useRef(null); + + // 滚动条样式 - 仅在悬停时显示 + const scrollbarStyle = ` + .anniversary-scroll::-webkit-scrollbar { + width: 4px; + height: 4px; + } + .anniversary-scroll::-webkit-scrollbar-track { + background: transparent; + } + .anniversary-scroll::-webkit-scrollbar-thumb { + background: transparent; + border-radius: 2px; + } + .anniversary-scroll:hover::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.15); + } + `; + + // 处理滚轮事件,实现列表独立滚动 + const handleWheel = (e: React.WheelEvent) => { + const container = scrollContainerRef.current; + if (!container) return; + + const { scrollTop, scrollHeight, clientHeight } = container; + // 使用 1px 缓冲避免浮点数精度问题 + const isAtTop = scrollTop <= 0; + const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1; + + // 如果已经滚动到顶部且向下滚动,或者已经滚动到底部且向上滚动,则阻止事件冒泡 + if ((isAtTop && e.deltaY > 0) || (isAtBottom && e.deltaY < 0)) { + e.stopPropagation(); + } + // 如果在滚动范围内,允许事件继续传递以实现正常滚动 + }; // 获取内置节假日 const builtInHolidays = useMemo(() => { @@ -88,8 +124,9 @@ export function AnniversaryList({ events, onEventClick, onAddClick }: Anniversar // 空状态 if (allAnniversaries.total === 0) { return ( - - + + + 暂无纪念日 @@ -112,8 +149,10 @@ export function AnniversaryList({ events, onEventClick, onAddClick }: Anniversar } return ( - - + <> + + + 纪念日 @@ -136,7 +175,13 @@ export function AnniversaryList({ events, onEventClick, onAddClick }: Anniversar - + + {/* 内置节假日 */} {allAnniversaries.builtIn.length > 0 && ( <> @@ -193,7 +238,9 @@ export function AnniversaryList({ events, onEventClick, onAddClick }: Anniversar ))} )} - - + + + + ); } diff --git a/src/components/note/NoteEditor.tsx b/src/components/note/NoteEditor.tsx index f093c39..1f02e59 100644 --- a/src/components/note/NoteEditor.tsx +++ b/src/components/note/NoteEditor.tsx @@ -1,4 +1,4 @@ -import { useState, useEffect, useCallback } from 'react'; +import { useState, useEffect, useCallback, useRef } from 'react'; import { Paper, Textarea, @@ -47,6 +47,24 @@ export function NoteEditor({ onSave }: NoteEditorProps) { // Auto-save with 3 second debounce const [debouncedContent] = useDebouncedValue(content, 3000); + // 滚动条样式 - 仅在悬停时显示 + const scrollbarStyle = ` + .note-scroll::-webkit-scrollbar { + width: 4px; + height: 4px; + } + .note-scroll::-webkit-scrollbar-track { + background: transparent; + } + .note-scroll::-webkit-scrollbar-thumb { + background: transparent; + border-radius: 2px; + } + .note-scroll:hover::-webkit-scrollbar-thumb { + background: rgba(0, 0, 0, 0.15); + } + `; + useEffect(() => { if (debouncedContent !== undefined && notes && debouncedContent !== content) { handleSave(debouncedContent); @@ -87,8 +105,28 @@ export function NoteEditor({ onSave }: NoteEditorProps) { } }; + const scrollContainerRef = useRef(null); + + // 处理滚轮事件,实现列表独立滚动 + const handleWheel = (e: React.WheelEvent) => { + const container = scrollContainerRef.current; + if (!container) return; + + const { scrollTop, scrollHeight, clientHeight } = container; + // 使用 1px 缓冲避免浮点数精度问题 + const isAtTop = scrollTop <= 0; + const isAtBottom = scrollTop + clientHeight >= scrollHeight - 1; + + // 如果已经滚动到顶部且向下滚动,或者已经滚动到底部且向上滚动,则阻止事件冒泡 + if ((isAtTop && e.deltaY > 0) || (isAtBottom && e.deltaY < 0)) { + e.stopPropagation(); + } + // 如果在滚动范围内,允许事件继续传递以实现正常滚动 + }; + return ( - + + {/* Header */} @@ -119,7 +157,13 @@ export function NoteEditor({ onSave }: NoteEditorProps) { {/* Editor/Preview Area */} - + {viewMode === 'edit' && (