From 58f3edb352d9f9bf92376faba8890ae82566862c Mon Sep 17 00:00:00 2001 From: suyao Date: Fri, 13 Jun 2025 19:20:16 +0800 Subject: [PATCH] refactor(FileItem, FileList, FilesPage): enhance file selection UI and improve checkbox handling - Added isSelected prop to FileItem for visual indication of selection. - Updated FileList to manage selected file IDs and pass selection state to FileItem. - Enhanced FilesPage checkbox handling with improved visibility on hover and selection state. - Introduced CheckboxContainer for consistent styling of checkboxes across components. --- src/renderer/src/pages/files/FileItem.tsx | 32 +++++++++++++++++++-- src/renderer/src/pages/files/FileList.tsx | 3 +- src/renderer/src/pages/files/FilesPage.tsx | 33 ++++++++++++++++++---- 3 files changed, 58 insertions(+), 10 deletions(-) diff --git a/src/renderer/src/pages/files/FileItem.tsx b/src/renderer/src/pages/files/FileItem.tsx index 08724033e8..31dc175e58 100644 --- a/src/renderer/src/pages/files/FileItem.tsx +++ b/src/renderer/src/pages/files/FileItem.tsx @@ -29,6 +29,7 @@ interface FileItemProps { } style?: React.CSSProperties gridTemplate?: string + isSelected?: boolean } const getFileIcon = (type?: string) => { @@ -79,13 +80,17 @@ const getFileIcon = (type?: string) => { return } -const FileItem: React.FC = ({ fileInfo, style, gridTemplate = '' }) => { +const FileItem: React.FC = ({ fileInfo, style, gridTemplate = '', isSelected = false }) => { const { name, ext, size, created_at, count, actions, icon, checkbox } = fileInfo return ( - + - {checkbox && {checkbox}} + {checkbox && ( + + {checkbox} + + )} {icon || getFileIcon(ext)} @@ -116,11 +121,26 @@ const FileItemCard = styled.div` box-shadow 0.2s ease, background-color 0.2s ease; --shadow-color: rgba(0, 0, 0, 0.05); + &:hover { box-shadow: 0 10px 15px -3px var(--shadow-color), 0 4px 6px -4px var(--shadow-color); } + + .file-checkbox { + opacity: 0; + transition: opacity 0.2s ease; + } + + &:hover .file-checkbox { + opacity: 1; + } + + &.selected .file-checkbox { + opacity: 1; + } + body[theme-mode='dark'] & { --shadow-color: rgba(255, 255, 255, 0.02); } @@ -178,4 +198,10 @@ const FileCount = styled.div` color: var(--color-text-2); ` +const CheckboxContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; +` + export default memo(FileItem) diff --git a/src/renderer/src/pages/files/FileList.tsx b/src/renderer/src/pages/files/FileList.tsx index 39fb61dfa9..aed570fb6f 100644 --- a/src/renderer/src/pages/files/FileList.tsx +++ b/src/renderer/src/pages/files/FileList.tsx @@ -23,7 +23,7 @@ interface FileItemProps { columnWidths?: string } -const FileList: React.FC = ({ list, columnWidths }) => { +const FileList: React.FC = ({ list, columnWidths, selectedFileIds = [] }) => { // if (id === FileTypes.IMAGE && files?.length && files?.length > 0) { // return ( //
@@ -90,6 +90,7 @@ const FileList: React.FC = ({ list, columnWidths }) => { actions: item.actions }} gridTemplate={columnWidths} + isSelected={selectedFileIds.includes(item.key as string)} />
)} diff --git a/src/renderer/src/pages/files/FilesPage.tsx b/src/renderer/src/pages/files/FilesPage.tsx index 64b21839cf..c805903538 100644 --- a/src/renderer/src/pages/files/FilesPage.tsx +++ b/src/renderer/src/pages/files/FilesPage.tsx @@ -267,12 +267,14 @@ const FilesPage: FC = () => { - 0 && selectedFileIds.length < sortedFiles.length} - checked={selectedFileIds.length === sortedFiles.length && sortedFiles.length > 0} - onChange={(e) => handleSelectAll(e.target.checked)} - disabled={sortedFiles.length === 0} - /> + 0 ? 'selected' : ''}`}> + 0 && selectedFileIds.length < sortedFiles.length} + checked={selectedFileIds.length === sortedFiles.length && sortedFiles.length > 0} + onChange={(e) => handleSelectAll(e.target.checked)} + disabled={sortedFiles.length === 0} + /> + {/* 图标列 */} @@ -471,6 +473,25 @@ const TableCell = styled.div` const TableHeader = styled.div` margin: 0 16px; + + .header-checkbox { + opacity: 0; + transition: opacity 0.2s ease; + } + + &:hover .header-checkbox { + opacity: 1; + } + + .header-checkbox.selected { + opacity: 1; + } +` + +const CheckboxContainer = styled.div` + display: flex; + align-items: center; + justify-content: center; ` export default FilesPage