Media Library
The MediaLibrary component is a complete, all-in-one media management solution that combines file upload, browsing, folder navigation, and file actions into a single powerful component.
Basic Usage
import { MediaLibrary } from '@dropper/react'
function App() {
return <MediaLibrary />
}
Props
interface MediaLibraryProps {
isSelectionMode?: boolean
onFileSelect?: (file: FileResponseDto) => void
allowedTypes?: string[]
hideUpload?: boolean
initialFolderId?: string | null
emptyMessage?: string
debug?: boolean
className?: string
uploadProgressPosition?: 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right'
enablePagination?: boolean
pageSize?: number
}
isSelectionMode
Enable selection mode for file picking:
<MediaLibrary
isSelectionMode
onFileSelect={(file) => {
console.log('Selected:', file)
}}
/>
onFileSelect
Callback when a file is selected (in selection mode):
<MediaLibrary
isSelectionMode
onFileSelect={(file) => {
setSelectedFile(file)
closeModal()
}}
/>
allowedTypes
Filter files by MIME type in selection mode:
{/* Images only */}
<MediaLibrary
isSelectionMode
allowedTypes={['image/*']}
onFileSelect={(file) => console.log('Selected image:', file)}
/>
{/* Specific types */}
<MediaLibrary
isSelectionMode
allowedTypes={['image/jpeg', 'image/png', 'video/mp4']}
/>
hideUpload
Hide upload functionality:
{/* Show upload (default) */}
<MediaLibrary />
{/* Hide upload */}
<MediaLibrary hideUpload />
initialFolderId
Start at a specific folder:
<MediaLibrary initialFolderId="folder_abc123" />
emptyMessage
Custom message when no files exist:
<MediaLibrary
emptyMessage="No media files yet. Upload your first file to get started!"
/>
uploadProgressPosition
Position of the upload progress panel:
{/* Bottom right (default) */}
<MediaLibrary uploadProgressPosition="bottom-right" />
{/* Other positions */}
<MediaLibrary uploadProgressPosition="top-left" />
<MediaLibrary uploadProgressPosition="top-right" />
<MediaLibrary uploadProgressPosition="bottom-left" />
enablePagination
Enable "Show More" pagination:
{/* Enabled (default) */}
<MediaLibrary enablePagination />
{/* Disabled */}
<MediaLibrary enablePagination={false} />
{/* Custom page size */}
<MediaLibrary enablePagination pageSize={50} />
Complete Examples
Full Media Manager
import { MediaLibrary } from '@dropper/react'
function MediaManager() {
return (
<div className="h-screen">
<MediaLibrary />
</div>
)
}
File Picker Modal
import { MediaLibrary } from '@dropper/react'
import { useState } from 'react'
function FilePickerModal({ open, onClose }) {
const [selectedFile, setSelectedFile] = useState(null)
return (
<Modal open={open} onClose={onClose}>
<div className="h-[600px]">
<MediaLibrary
isSelectionMode
onFileSelect={(file) => {
setSelectedFile(file)
onClose(file)
}}
/>
</div>
</Modal>
)
}
Image Picker
import { MediaLibrary } from '@dropper/react'
function ImagePicker({ onSelect }) {
return (
<MediaLibrary
isSelectionMode
allowedTypes={['image/*']}
onFileSelect={(file) => {
onSelect(file.url)
}}
/>
)
}
Document Library
import { MediaLibrary } from '@dropper/react'
function DocumentLibrary() {
return (
<div className="container mx-auto p-4">
<h1 className="text-2xl font-bold mb-4">Document Library</h1>
<MediaLibrary
allowedTypes={['.pdf', '.doc', '.docx', '.txt']}
emptyMessage="No documents yet. Upload your first document!"
enablePagination
pageSize={30}
/>
</div>
)
}
Read-Only Gallery
import { MediaLibrary } from '@dropper/react'
function ReadOnlyGallery() {
return (
<MediaLibrary
hideUpload
allowedTypes={['image/*', 'video/*']}
/>
)
}
CMS Media Selector
import { MediaLibrary } from '@dropper/react'
import { useState } from 'react'
function CMSMediaSelector({ fieldName, onSelect }) {
const [isOpen, setIsOpen] = useState(false)
const [selectedMedia, setSelectedMedia] = useState(null)
return (
<div>
<label>{fieldName}</label>
{selectedMedia && (
<div className="preview">
<img src={selectedMedia.url} alt={selectedMedia.originalFilename} />
<button onClick={() => setSelectedMedia(null)}>Remove</button>
</div>
)}
<button onClick={() => setIsOpen(true)}>
Select Media
</button>
{isOpen && (
<Modal open={isOpen} onClose={() => setIsOpen(false)}>
<MediaLibrary
isSelectionMode
allowedTypes={['image/*']}
onFileSelect={(file) => {
setSelectedMedia(file)
onSelect(file)
setIsOpen(false)
}}
/>
</Modal>
)}
</div>
)
}
Features
File Management
- Upload: Drag-and-drop or click to upload
- Browse: Grid and list views
- Search: Real-time file search
- Sort: Sort by name, size, or date
- Filter: Filter by file type
- Preview: Preview images and videos
- Download: Download files
- Delete: Delete files with confirmation
Folder Management
- Navigate: Browse folder hierarchy
- Create: Create new folders
- Rename: Rename folders
- Delete: Delete folders
- Breadcrumbs: Navigate with breadcrumbs
Upload Features
- Drag & Drop: Drag files to upload
- Multiple Files: Upload multiple files at once
- Progress Tracking: Real-time upload progress
- Queue Management: Manage upload queue
- Retry: Retry failed uploads
- Cancel: Cancel in-progress uploads
View Options
- Grid View: Visual grid layout
- List View: Compact list layout
- Toggle: Switch between views
- Responsive: Adapts to screen size
Selection Mode
- File Picker: Use as a file picker
- Type Filtering: Filter by MIME type
- Single Selection: Select one file
- Quick Select: Click to select
Architecture
The MediaLibrary orchestrates multiple components:
Components Used
- BreadcrumbNavigation: Folder path navigation
- MediaAssetGrid: File and folder display
- CreateFolderModal: Folder creation
- FileUploadModal: File upload
- MediaPreviewModal: File preview
- UploadProgress: Upload progress tracking
- LoadMorePagination: Pagination
Hooks Used
- useFileListApi: File data fetching
- useInfiniteFileListApi: Paginated file fetching
- useFolderBrowserApi: Folder data fetching
- useMediaLibraryLogic: State management
- useUploadQueue: Upload queue management
Styling
Custom Class Name
<MediaLibrary className="my-custom-library" />
Themed Component
Uses theme from DropperProvider:
<DropperProvider
publishableKey="pk_dropper_test_xxx"
theme={{
primary: '#3b82f6',
radius: 'lg',
}}
>
<MediaLibrary />
</DropperProvider>
Keyboard Shortcuts
- Arrow Keys: Navigate files
- Enter: Open/select file
- Delete: Delete selected file
- Escape: Close modals
- Ctrl/Cmd + A: Select all (when selectable)
Accessibility
The component is fully accessible:
- Keyboard navigation
- Screen reader support
- ARIA labels
- Focus management
- Semantic HTML
Best Practices
1. Use in Full-Screen Context
<div className="h-screen">
<MediaLibrary />
</div>
2. Provide Selection Callback
<MediaLibrary
isSelectionMode
onFileSelect={(file) => {
// Handle selection
}}
/>
3. Filter by Type
<MediaLibrary
allowedTypes={['image/*']}
/>
4. Enable Pagination
<MediaLibrary
enablePagination
pageSize={30}
/>
5. Customize Empty State
<MediaLibrary
emptyMessage="Upload your first file to get started!"
/>
Common Patterns
Modal File Picker
function useFilePicker() {
const [isOpen, setIsOpen] = useState(false)
const [selectedFile, setSelectedFile] = useState(null)
const openPicker = () => setIsOpen(true)
const closePicker = () => setIsOpen(false)
const picker = (
<Modal open={isOpen} onClose={closePicker}>
<MediaLibrary
isSelectionMode
onFileSelect={(file) => {
setSelectedFile(file)
closePicker()
}}
/>
</Modal>
)
return { openPicker, selectedFile, picker }
}
Embedded in CMS
function CMSMediaField({ value, onChange }) {
const [showPicker, setShowPicker] = useState(false)
return (
<div>
{value && (
<img src={value.url} alt={value.originalFilename} />
)}
<button onClick={() => setShowPicker(true)}>
{value ? 'Change' : 'Select'} Media
</button>
{showPicker && (
<Modal open onClose={() => setShowPicker(false)}>
<MediaLibrary
isSelectionMode
allowedTypes={['image/*']}
onFileSelect={(file) => {
onChange(file)
setShowPicker(false)
}}
/>
</Modal>
)}
</div>
)
}
TypeScript Support
The component is fully typed:
import type { MediaLibraryProps, FileResponseDto } from '@dropper/react'
const props: MediaLibraryProps = {
isSelectionMode: true,
allowedTypes: ['image/*'],
onFileSelect: (file: FileResponseDto) => {
console.log(file.url)
},
}
<MediaLibrary {...props} />
Performance
The component is optimized for performance:
- React Query Caching: Data is cached automatically
- Infinite Scrolling: Efficient pagination
- Lazy Loading: Images load on demand
- Debounced Search: Search is debounced
- Memoization: Computed values are memoized
Comparison with Individual Components
Use MediaLibrary When:
- You need a complete media management solution
- You want upload, browse, and organize in one component
- You're building a file picker or media selector
- You need a ready-to-use solution
Use Individual Components When:
- You need fine-grained control
- You're building a custom interface
- You only need specific functionality
- You want maximum flexibility
Next Steps
- File Upload Component - Upload files
- File List Component - Display files
- Folder Browser - Navigate folders
- Theming - Customize appearance