46 lines
1.9 KiB
TypeScript
46 lines
1.9 KiB
TypeScript
'use client'
|
||
|
||
import Image from 'next/image'
|
||
import { Plus } from 'lucide-react'
|
||
import { uploadAreaAddTileClass, uploadAreaEmptyButtonClass, uploadAreaTileClass } from './upload-field-styles'
|
||
|
||
interface CompactImageFileGridProps {
|
||
files: Array<{ file: File; preview: string }>
|
||
label: string
|
||
disabled?: boolean
|
||
onAdd: () => void
|
||
onRemove: (index: number) => void
|
||
}
|
||
|
||
export default function CompactImageFileGrid({ files, label, disabled = false, onAdd, onRemove }: CompactImageFileGridProps) {
|
||
return (
|
||
<div className={files.length > 0 ? 'flex flex-wrap gap-2' : ''}>
|
||
{files.map((item, index) => (
|
||
<div key={`${item.file.name}-${index}`} className="group relative" title={item.file.name}>
|
||
<div className={uploadAreaTileClass}>
|
||
<Image src={item.preview} alt={`${label} ${index + 1}`} fill unoptimized sizes="80px" className="object-cover" />
|
||
<span className="absolute bottom-0 right-0 rounded-tl-[6px] bg-[#1a1c1d]/80 px-1.5 py-0.5 text-xs text-white">{index + 1}</span>
|
||
</div>
|
||
<button
|
||
type="button"
|
||
onClick={() => onRemove(index)}
|
||
disabled={disabled}
|
||
aria-label={`移除${label} ${index + 1}`}
|
||
className="absolute right-1 top-1 flex h-7 w-7 items-center justify-center rounded-[6px] bg-[#1a1c1d]/80 text-white opacity-100 transition-opacity sm:opacity-0 sm:group-hover:opacity-100 focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[#1677ff] disabled:cursor-not-allowed disabled:opacity-50"
|
||
>×</button>
|
||
</div>
|
||
))}
|
||
<button
|
||
type="button"
|
||
onClick={onAdd}
|
||
disabled={disabled}
|
||
aria-label={`添加${label}`}
|
||
className={files.length > 0 ? uploadAreaAddTileClass : uploadAreaEmptyButtonClass}
|
||
>
|
||
<Plus className="h-5 w-5" aria-hidden="true" />
|
||
{files.length === 0 && `添加${label}`}
|
||
</button>
|
||
</div>
|
||
)
|
||
}
|