File List Component
The FileList component displays files in a beautiful grid or list view with built-in sorting, search, pagination, and file actions.
Basic Usage
import { FileList } from '@dropper/react'
function App() {
return (
<FileList
onFileClick={(file) => console.log('Clicked:', file)}
/>
)
}
Props
interface FileListProps {
folderId?: string
view?: 'grid' | 'list'
selectable?: boolean
searchable?: boolean
sortBy?: 'name' | 'size' | 'createdAt' | 'updatedAt'
sortOrder?: 'asc' | 'desc'
actions?: Array<'download' | 'delete' | 'view'>
className?: string
onFileClick?: (file: FileResponseDto) => void
onFileSelect?: (files: FileResponseDto[]) => void
enablePagination?: boolean
pageSize?: number
}
folderId
Display files from a specific folder:
<FileList folderId="folder_abc123" />
view
Choose between grid or list view:
{/* Grid view (default) */}
<FileList view="grid" />
{/* List view */}
<FileList view="list" />
selectable
Enable file selection with checkboxes:
<FileList
selectable
onFileSelect={(files) => {
console.log('Selected files:', files)
}}
/>
searchable
Enable search functionality:
{/* With search (default) */}
<FileList searchable />
{/* Without search */}
<FileList searchable={false} />
sortBy
Default sort field:
{/* Sort by creation date (default) */}
<FileList sortBy="createdAt" />
{/* Sort by name */}
<FileList sortBy="name" />
{/* Sort by size */}
<FileList sortBy="size" />
{/* Sort by update date */}
<FileList sortBy="updatedAt" />
sortOrder
Default sort direction:
{/* Descending (default) */}
<FileList sortOrder="desc" />
{/* Ascending */}
<FileList sortOrder="asc" />
actions
Available file actions:
{/* All actions (default) */}
<FileList actions={['download', 'delete', 'view']} />
{/* View and download only */}
<FileList actions={['view', 'download']} />
{/* No actions */}
<FileList actions={[]} />
enablePagination
Enable "Show More" pagination:
{/* Disabled (default) */}
<FileList enablePagination={false} />
{/* Enabled with default page size (20) */}
<FileList enablePagination />
{/* Custom page size */}
<FileList enablePagination pageSize={50} />
Event Handlers
onFileClick
Called when a file is clicked:
<FileList
onFileClick={(file) => {
console.log('Clicked file:', file.originalFilename)
console.log('URL:', file.url)
openFilePreview(file)
}}
/>
onFileSelect
Called when file selection changes:
<FileList
selectable
onFileSelect={(files) => {
console.log(`Selected ${files.length} files`)
setSelectedFiles(files)
}}
/>
Complete Examples
Basic File Gallery
import { FileList } from '@dropper/react'
function FileGallery() {
return (
<FileList
view="grid"
sortBy="createdAt"
sortOrder="desc"
onFileClick={(file) => {
window.open(file.url, '_blank')
}}
/>
)
}
Image Gallery
import { FileList } from '@dropper/react'
import { useState } from 'react'
function ImageGallery() {
const [selectedImage, setSelectedImage] = useState(null)
return (
<div>
<FileList
view="grid"
searchable
onFileClick={(file) => {
setSelectedImage(file)
}}
/>
{selectedImage && (
<div className="modal">
<img src={selectedImage.url} alt={selectedImage.originalFilename} />
<button onClick={() => setSelectedImage(null)}>Close</button>
</div>
)}
</div>
)
}
Folder Files
import { FileList } from '@dropper/react'
import { useState } from 'react'
function FolderFiles() {
const [currentFolder, setCurrentFolder] = useState('folder_123')
return (
<div>
<h2>Files in Folder</h2>
<FileList
folderId={currentFolder}
view="list"
sortBy="name"
sortOrder="asc"
actions={['view', 'download', 'delete']}
/>
</div>
)
}
Selectable Files
import { FileList } from '@dropper/react'
import { useState } from 'react'
function SelectableFiles() {
const [selectedFiles, setSelectedFiles] = useState([])
const handleBulkDelete = async () => {
// Delete selected files
console.log('Deleting:', selectedFiles)
}
const handleBulkDownload = () => {
selectedFiles.forEach((file) => {
window.open(file.url, '_blank')
})
}
return (
<div>
{selectedFiles.length > 0 && (
<div className="actions">
<button onClick={handleBulkDownload}>
Download {selectedFiles.length} files
</button>
<button onClick={handleBulkDelete}>
Delete {selectedFiles.length} files
</button>
</div>
)}
<FileList
selectable
onFileSelect={setSelectedFiles}
/>
</div>
)
}
Paginated List
import { FileList } from '@dropper/react'
function PaginatedFileList() {
return (
<FileList
enablePagination
pageSize={20}
view="grid"
sortBy="createdAt"
sortOrder="desc"
/>
)
}
Document Library
import { FileList } from '@dropper/react'
import { useState } from 'react'
function DocumentLibrary() {
const [viewMode, setViewMode] = useState<'grid' | 'list'>('list')
return (
<div>
<div className="toolbar">
<button onClick={() => setViewMode('grid')}>Grid</button>
<button onClick={() => setViewMode('list')}>List</button>
</div>
<FileList
view={viewMode}
sortBy="name"
searchable
actions={['view', 'download']}
onFileClick={(file) => {
// Open document viewer
openDocumentViewer(file)
}}
/>
</div>
)
}
Media Manager
import { FileList } from '@dropper/react'
import { useState } from 'react'
function MediaManager() {
const [selectedFiles, setSelectedFiles] = useState([])
const [viewMode, setViewMode] = useState<'grid' | 'list'>('grid')
return (
<div className="media-manager">
<div className="toolbar">
<div className="view-toggle">
<button
onClick={() => setViewMode('grid')}
className={viewMode === 'grid' ? 'active' : ''}
>
Grid
</button>
<button
onClick={() => setViewMode('list')}
className={viewMode === 'list' ? 'active' : ''}
>
List
</button>
</div>
{selectedFiles.length > 0 && (
<div className="bulk-actions">
<span>{selectedFiles.length} selected</span>
<button>Download All</button>
<button>Delete All</button>
</div>
)}
</div>
<FileList
view={viewMode}
selectable
searchable
enablePagination
pageSize={30}
sortBy="createdAt"
sortOrder="desc"
actions={['view', 'download', 'delete']}
onFileSelect={setSelectedFiles}
onFileClick={(file) => {
console.log('Clicked:', file.originalFilename)
}}
/>
</div>
)
}
Features
Grid View
- Responsive grid layout
- Image thumbnails
- File type icons
- File name and size
- Action menu
List View
- Compact list layout
- Sortable columns
- File details
- Quick actions
- Efficient for large lists
Search
- Real-time search
- Search by filename
- Debounced input
- Clear search button
Sorting
- Sort by name, size, or date
- Ascending/descending order
- Visual sort indicators
- Persistent sort state
File Actions
- View: Preview file
- Download: Download file
- Delete: Delete file with confirmation
Selection
- Multi-select with checkboxes
- Select all/none
- Bulk actions
- Selection count
Pagination
- "Show More" button
- Infinite scroll support
- Configurable page size
- Loading states
Styling
Custom Class Name
<FileList
className="my-custom-file-list"
/>
Themed Component
Uses theme from DropperProvider:
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{ primary: '#3b82f6' }}
>
<FileList /> {/* Uses blue theme */}
</DropperProvider>
Architecture
The component follows a three-layer architecture:
1. API Layer (useFileListApi)
Handles data fetching and mutations:
const { files, isLoading, deleteFile } = useFileListApi({
folderId,
sortBy,
sortOrder,
})
2. Logic Layer (useFileListLogic)
Manages state and computed data:
const {
view,
searchQuery,
selectedFiles,
filteredFiles,
toggleSort,
} = useFileListLogic({
files,
initialView,
})
3. UI Layer (Component)
Renders the interface:
<FileList {...props} />
Accessibility
The component is fully accessible:
- Keyboard navigation
- Screen reader support
- ARIA labels
- Focus management
- Semantic HTML
Best Practices
1. Provide Event Handlers
<FileList
onFileClick={(file) => {
// Handle click
}}
onFileSelect={(files) => {
// Handle selection
}}
/>
2. Use Pagination for Large Lists
<FileList
enablePagination
pageSize={50}
/>
3. Enable Search
<FileList searchable />
4. Choose Appropriate View
{/* Grid for images */}
<FileList view="grid" />
{/* List for documents */}
<FileList view="list" />
5. Limit Actions
{/* Read-only */}
<FileList actions={['view']} />
{/* Full control */}
<FileList actions={['view', 'download', 'delete']} />
TypeScript Support
The component is fully typed:
import type { FileListProps, FileResponseDto } from '@dropper/react'
const props: FileListProps = {
view: 'grid',
sortBy: 'createdAt',
onFileClick: (file: FileResponseDto) => {
console.log(file.url)
},
}
<FileList {...props} />
Performance
The component is optimized for performance:
- React Query Caching: Files are cached automatically
- Debounced Search: Search input is debounced
- Virtual Scrolling: Efficient rendering for large lists
- Memoization: Computed values are memoized
- Lazy Loading: Images load on demand
Next Steps
- File Upload Component - Upload files
- Folder Browser - Navigate folders
- useDropper Hook - Access Dropper client