mirror of
https://github.com/CherryHQ/cherry-studio.git
synced 2025-12-26 20:12:38 +08:00
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.
This commit is contained in:
parent
edeb9f84f9
commit
58f3edb352
@ -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 <FileUnknownFilled />
|
||||
}
|
||||
|
||||
const FileItem: React.FC<FileItemProps> = ({ fileInfo, style, gridTemplate = '' }) => {
|
||||
const FileItem: React.FC<FileItemProps> = ({ fileInfo, style, gridTemplate = '', isSelected = false }) => {
|
||||
const { name, ext, size, created_at, count, actions, icon, checkbox } = fileInfo
|
||||
|
||||
return (
|
||||
<FileItemCard style={style}>
|
||||
<FileItemCard style={style} className={isSelected ? 'selected' : ''}>
|
||||
<FileGrid style={{ gridTemplateColumns: gridTemplate }}>
|
||||
{checkbox && <FileCell>{checkbox}</FileCell>}
|
||||
{checkbox && (
|
||||
<FileCell>
|
||||
<CheckboxContainer className="file-checkbox">{checkbox}</CheckboxContainer>
|
||||
</FileCell>
|
||||
)}
|
||||
<FileCell>
|
||||
<FileIcon>{icon || getFileIcon(ext)}</FileIcon>
|
||||
</FileCell>
|
||||
@ -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)
|
||||
|
||||
@ -23,7 +23,7 @@ interface FileItemProps {
|
||||
columnWidths?: string
|
||||
}
|
||||
|
||||
const FileList: React.FC<FileItemProps> = ({ list, columnWidths }) => {
|
||||
const FileList: React.FC<FileItemProps> = ({ list, columnWidths, selectedFileIds = [] }) => {
|
||||
// if (id === FileTypes.IMAGE && files?.length && files?.length > 0) {
|
||||
// return (
|
||||
// <div style={{ padding: 16, overflowY: 'auto' }}>
|
||||
@ -90,6 +90,7 @@ const FileList: React.FC<FileItemProps> = ({ list, columnWidths }) => {
|
||||
actions: item.actions
|
||||
}}
|
||||
gridTemplate={columnWidths}
|
||||
isSelected={selectedFileIds.includes(item.key as string)}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -267,12 +267,14 @@ const FilesPage: FC = () => {
|
||||
<TableHeader>
|
||||
<TableGrid style={{ gridTemplateColumns: GRID_TEMPLATE }}>
|
||||
<TableCell>
|
||||
<Checkbox
|
||||
indeterminate={selectedFileIds.length > 0 && selectedFileIds.length < sortedFiles.length}
|
||||
checked={selectedFileIds.length === sortedFiles.length && sortedFiles.length > 0}
|
||||
onChange={(e) => handleSelectAll(e.target.checked)}
|
||||
disabled={sortedFiles.length === 0}
|
||||
/>
|
||||
<CheckboxContainer className={`header-checkbox ${selectedFileIds.length > 0 ? 'selected' : ''}`}>
|
||||
<Checkbox
|
||||
indeterminate={selectedFileIds.length > 0 && selectedFileIds.length < sortedFiles.length}
|
||||
checked={selectedFileIds.length === sortedFiles.length && sortedFiles.length > 0}
|
||||
onChange={(e) => handleSelectAll(e.target.checked)}
|
||||
disabled={sortedFiles.length === 0}
|
||||
/>
|
||||
</CheckboxContainer>
|
||||
</TableCell>
|
||||
<TableCell>{/* 图标列 */}</TableCell>
|
||||
<TableCell>
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user