@dropper/react

Beautiful React components and hooks for building file upload and management interfaces with Dropper.

Features

  • React 18+ - Built for modern React with hooks
  • TypeScript - Full type safety out of the box
  • React Query - Automatic caching and data synchronization
  • Drag & Drop - Beautiful drag-and-drop file upload
  • Progress Tracking - Real-time upload progress
  • File Management - Browse, search, sort, and manage files
  • Folder Navigation - Hierarchical folder structure
  • Media Library - Complete media management solution
  • Theming - Customizable to match your brand
  • Accessible - WCAG compliant with keyboard navigation
  • Responsive - Works on all screen sizes

Installation

npm install @dropper/react

Or with your preferred package manager:

# pnpm
pnpm add @dropper/react

# yarn
yarn add @dropper/react

Quick Start

1. Install the package

npm install @dropper/react

2. Import styles

import '@dropper/react/dist/index.css'

3. Wrap your app with DropperProvider

import { DropperProvider } from '@dropper/react'
import '@dropper/react/dist/index.css'

function App() {
  return (
    <DropperProvider publishableKey="pk_dropper_test_xxx">
      <YourApp />
    </DropperProvider>
  )
}

4. Use components

import { FileUpload, FileList, MediaLibrary } from '@dropper/react'

function MyApp() {
  return (
    <div>
      {/* Simple file upload */}
      <FileUpload
        onSuccess={(file) => console.log('Uploaded:', file.url)}
      />
      
      {/* Or use the complete media library */}
      <MediaLibrary />
    </div>
  )
}

Core Components

DropperProvider

Context provider that configures Dropper for your app.

<DropperProvider
  publishableKey="pk_dropper_test_xxx"
  theme={{ primary: '#3b82f6' }}
>
  {children}
</DropperProvider>

Learn more →

FileUpload

Drag-and-drop file upload with validation and progress tracking.

<FileUpload
  accept="image/*"
  maxSize={5 * 1024 * 1024}
  maxFiles={10}
  onSuccess={(file) => console.log('Uploaded:', file)}
/>

Learn more →

FileList

Display files in grid or list view with search, sort, and actions.

<FileList
  view="grid"
  searchable
  sortBy="createdAt"
  onFileClick={(file) => console.log('Clicked:', file)}
/>

Learn more →

FilePreview

Preview files in a modal with navigation and actions.

<FilePreview
  file={selectedFile}
  open={isOpen}
  onClose={() => setIsOpen(false)}
  onDelete={(file) => console.log('Deleted:', file)}
/>

FolderBrowser

Navigate and manage folder hierarchies with tree view.

<FolderBrowser
  showFiles
  allowCreate
  allowRename
  allowDelete
  onFolderChange={(folderId) => console.log('Folder:', folderId)}
/>

Learn more →

UploadProgress

Display upload progress for multiple files.

<UploadProgress
  items={uploadItems}
  onCancel={(id) => console.log('Cancelled:', id)}
  onRetry={(id) => console.log('Retry:', id)}
/>

MediaLibrary Components

MediaLibrary

Complete media management solution with upload, browse, and organize.

<MediaLibrary
  enablePagination
  pageSize={30}
/>

Learn more →

MediaAssetCard

Display individual file/asset cards.

<MediaAssetCard
  asset={file}
  viewMode="grid"
  isSelected={false}
  onSelect={(selected) => console.log('Selected:', selected)}
  actions={['preview', 'download', 'delete']}
/>

FolderCard

Display folder cards.

<FolderCard
  folder={folder}
  viewMode="grid"
  isSelected={false}
  onSelect={(selected) => console.log('Selected:', selected)}
  onClick={() => console.log('Open folder')}
/>

BreadcrumbNavigation

Display navigation breadcrumbs.

<BreadcrumbNavigation
  path={[
    { id: 'root', name: 'Home' },
    { id: 'folder1', name: 'Documents' },
  ]}
  onNavigate={(folderId) => console.log('Navigate to:', folderId)}
/>

MediaAssetGrid

Display grid of files and folders.

<MediaAssetGrid
  folders={folders}
  files={files}
  viewMode="grid"
  selectedAssets={new Set()}
  onAssetSelect={(id, selected) => console.log('Select:', id)}
  onFolderClick={(id) => console.log('Open:', id)}
/>

Modal Components

CreateFolderModal

Modal for creating new folders.

<CreateFolderModal
  open={isOpen}
  onClose={() => setIsOpen(false)}
  currentFolderId={currentFolder}
  onSuccess={(folder) => console.log('Created:', folder)}
/>

FileUploadModal

Modal wrapper for file upload.

<FileUploadModal
  open={isOpen}
  onClose={() => setIsOpen(false)}
  title="Upload Files"
  onSuccess={(file) => console.log('Uploaded:', file)}
/>

MediaPreviewModal

Modal for previewing media files.

<MediaPreviewModal
  file={selectedFile}
  isOpen={isOpen}
  onClose={() => setIsOpen(false)}
/>

Hooks

useDropper

Access Dropper client, configuration, and theme.

import { useDropper } from '@dropper/react'

function MyComponent() {
  const { client, config, theme } = useDropper()
  
  const uploadFile = async (file: File) => {
    const result = await client.uploadFile(file)
    console.log('Uploaded:', result.url)
  }
  
  return <div style={{ color: theme.primary }}>...</div>
}

Learn more →

useTheme

Access theme configuration only.

import { useTheme } from '@dropper/react'

function ThemedButton() {
  const theme = useTheme()
  
  return (
    <button style={{ backgroundColor: theme.primary }}>
      Click me
    </button>
  )
}

Internal Hooks

The package includes internal hooks following a three-layer architecture:

  • API Layer: useFileListApi, useFolderBrowserApi, useFileUploadApi
  • Logic Layer: useFileListLogic, useFolderBrowserLogic, useMediaLibraryLogic
  • UI Layer: Components use these hooks internally

These hooks are used internally by components and are not exported for direct use.

Utilities

Core Utilities (Re-exported from @dropper/core)

import {
  // Validation
  validateFiles,
  validateFileType,
  validateFileSize,
  validateFileCount,
  validatePublishableKey,
  
  // Type checkers
  isImage,
  isVideo,
  isPDF,
  
  // Formatting
  formatFileSize,
  formatDate,
  getFileExtension,
  getMimeTypeCategory,
  
  // Helpers
  generateId,
  debounce,
  throttle,
  sleep,
  retry,
  
  // Client & Queue
  DropperClient,
  UploadQueue,
  
  // Errors
  DropperError,
  ValidationError,
  AuthenticationError,
  AuthorizationError,
  NotFoundError,
  NetworkError,
  UploadError,
} from '@dropper/react'

Browser-Specific Utilities (React-only)

import {
  cn,                  // Tailwind class name merger
  getPreviewUrl,       // Get preview URL for file
  getDownloadUrl,      // Get download URL for file
  isImageFile,         // Check if file is image
  isVideoFile,         // Check if file is video
  isPDFFile,           // Check if file is PDF
  downloadFromUrl,     // Download file from URL
  downloadBlob,        // Download blob as file
} from '@dropper/react'

Usage Examples

// Validate files before upload
const errors = validateFiles(files, {
  accept: 'image/*',
  maxSize: 10 * 1024 * 1024, // 10MB
  maxFiles: 5,
})

// Format file size
formatFileSize(1024) // "1 KB"
formatFileSize(1048576) // "1 MB"

// Check file types
isImage(file) // true/false
isVideo(file) // true/false
isPDF(file) // true/false

// Browser utilities
const previewUrl = getPreviewUrl(file)
const downloadUrl = getDownloadUrl(file)
downloadFromUrl(file.url, file.originalFilename)

// Merge Tailwind classes
const className = cn('base-class', isActive && 'active-class')

Theming

Customize component appearance to match your brand:

<DropperProvider
  publishableKey="pk_dropper_test_xxx"
  theme={{
    primary: '#10b981',  // Green theme
  }}
>
  <App />
</DropperProvider>

Learn more →

TypeScript Support

Full TypeScript support with exported types:

import type {
  DropperProviderProps,
  FileUploadProps,
  FileListProps,
  FolderBrowserProps,
  MediaLibraryProps,
  FileResponseDto,
  FolderResponseDto,
  DropperTheme,
} from '@dropper/react'

Complete Example

import { DropperProvider, MediaLibrary } from '@dropper/react'
import '@dropper/react/dist/index.css'

function App() {
  return (
    <DropperProvider
      publishableKey={process.env.NEXT_PUBLIC_DROPPER_KEY!}
      theme={{ primary: '#3b82f6' }}
    >
      <div className="container mx-auto p-4">
        <h1 className="text-2xl font-bold mb-4">Media Library</h1>
        <MediaLibrary
          enablePagination
          pageSize={30}
        />
      </div>
    </DropperProvider>
  )
}

export default App

Architecture

The React package follows a clean three-layer architecture:

1. API Layer

Handles data fetching and mutations using React Query:

  • useFileListApi - File data operations
  • useFolderBrowserApi - Folder data operations
  • useFileUploadApi - Upload operations

2. Logic Layer

Manages state and computed data:

  • useFileListLogic - View state, search, filtering
  • useFolderBrowserLogic - Navigation, selection
  • useMediaLibraryLogic - Orchestration logic

3. UI Layer

Components focus purely on rendering:

  • FileUpload, FileList, FolderBrowser, MediaLibrary
  • Minimal logic, maximum reusability

This separation ensures:

  • Testability: Each layer can be tested independently
  • Reusability: Logic hooks can be used across components
  • Maintainability: Clear separation of concerns
  • Performance: Optimized re-renders

Framework Support

Works with all React frameworks:

  • Next.js (App Router & Pages Router)
  • Vite
  • Create React App
  • Remix
  • Gatsby

Next Steps