ZentrixUI - A modern, highly customizable and accessible React file upload component library with multiple variants, JSON-based configuration, and excellent developer experience.
npm install zentrixuiModern, highly customizable and accessible React file upload components
A modern, highly customizable and accessible React file upload component library with multiple variants, JSON-based configuration, and excellent developer experience. Built with TypeScript, TailwindCSS, and Radix UI primitives.
- ๐จ Multiple Variants: Button, Dropzone, Preview, Image-only, and Multi-file upload variants
- โ๏ธ JSON Configuration: Declarative configuration system for easy customization
- โฟ Accessibility First: Full keyboard navigation, screen reader support, and ARIA compliance
- ๐ฏ TypeScript: Complete type safety with comprehensive TypeScript definitions
- ๐จ Themeable: Light/dark themes with customizable colors, spacing, and styling
- ๐ฑ Responsive: Mobile-friendly with touch interactions and responsive layouts
- ๐ง Developer Experience: Excellent DX with clear APIs and comprehensive documentation
- ๐งช Mock Upload: Built-in mock upload service for development and testing
- ๐ณ Tree Shakeable: Import only what you need for optimal bundle size
``bash`
npm install zentrixuior
pnpm add zentrixuior
yarn add zentrixui
`tsx
import { FileUpload } from 'zentrixui'
import 'zentrixui/styles'
function App() {
const handleUpload = async (files: File[]) => {
// Handle file upload
console.log('Uploading files:', files)
}
return (
onUpload={handleUpload}
accept="image/*"
maxSize={5 1024 1024} // 5MB
multiple
/>
)
}
`
`tsx`
onUpload={handleUpload}
size="lg"
radius="md"
/>
`tsx`
onUpload={handleUpload}
accept="image/,video/"
multiple
maxFiles={10}
/>
`tsx`
onUpload={handleUpload}
multiple
maxSize={10 1024 1024}
/>
`tsx`
onUpload={handleUpload}
accept="image/*"
maxSize={2 1024 1024}
/>
`tsx`
onUpload={handleUpload}
multiple
maxFiles={20}
accept=".pdf,.doc,.docx"
/>
`tsx
interface FileUploadProps {
// Core behavior
variant?: 'button' | 'dropzone' | 'preview' | 'image-only' | 'multi-file'
size?: 'sm' | 'md' | 'lg'
radius?: 'none' | 'sm' | 'md' | 'lg' | 'full'
disabled?: boolean
multiple?: boolean
accept?: string
maxSize?: number
maxFiles?: number
// Styling
theme?: 'light' | 'dark' | 'auto'
className?: string
style?: React.CSSProperties
// Customization
icon?: ReactNode
iconPlacement?: 'left' | 'right' | 'top' | 'bottom'
placeholder?: string
borderStyle?: 'solid' | 'dashed' | 'dotted' | 'none'
borderWidth?: 'thin' | 'medium' | 'thick'
// Event handlers
onUpload?: (files: File[]) => Promise
onError?: (error: string) => void
onProgress?: (progress: number, file?: UploadFile) => void
onFileSelect?: (files: File[]) => void
onFileRemove?: (fileId: string) => void
// Configuration
config?: FileUploadConfig | string // Config object or path to JSON file
// Accessibility
ariaLabel?: string
ariaDescribedBy?: string
children?: ReactNode
}
`
Create a file-upload.config.json file for declarative configuration:
`json`
{
"defaults": {
"variant": "dropzone",
"size": "md",
"radius": "md",
"theme": "auto",
"multiple": true,
"maxSize": 10485760,
"maxFiles": 5
},
"validation": {
"allowedTypes": ["image/*", "application/pdf"],
"allowedExtensions": [".jpg", ".png", ".pdf"],
"maxSize": 10485760,
"maxFiles": 5
},
"styling": {
"theme": "auto",
"colors": {
"primary": "#3b82f6",
"success": "#10b981",
"error": "#ef4444"
}
},
"labels": {
"uploadText": "Choose files to upload",
"dragText": "Drag and drop files here",
"successText": "Upload successful"
},
"features": {
"dragAndDrop": true,
"preview": true,
"progress": true,
"removeFiles": true
}
}
Then use it in your component:
`tsx
import config from './file-upload.config.json'
`
Wrap your app with the ThemeProvider for consistent theming:
`tsx
import { ThemeProvider } from 'zentrixui'
function App() {
return (
)
}
`
`tsx
const customTheme = {
colors: {
primary: '#8b5cf6',
secondary: '#64748b',
success: '#059669',
error: '#dc2626',
background: '#ffffff',
foreground: '#1f2937'
},
spacing: {
padding: '1.5rem',
margin: '0.75rem',
gap: '0.75rem'
}
}
onUpload={handleUpload}
/>
`
The component is built with accessibility in mind:
- Keyboard Navigation: Full keyboard support with Tab, Enter, Space, and Escape keys
- Screen Reader Support: Comprehensive ARIA labels and live regions
- Focus Management: Proper focus indicators and focus trapping
- High Contrast: Support for high contrast mode and custom focus indicators
- Announcements: Status updates announced to screen readers
`tsx`
ariaDescribedBy="upload-help-text"
onUpload={handleUpload}
/>
Supported formats: PDF, DOC, DOCX. Maximum size: 10MB.
`tsxFile ${file.name} is too large
const handleUpload = async (files: File[]) => {
// Custom validation
const validFiles = files.filter(file => {
if (file.size > 5 1024 1024) {
console.error()
return false
}
return true
})
// Upload valid files
for (const file of validFiles) {
await uploadFile(file)
}
}
onError={(error) => console.error('Upload error:', error)}
maxSize={5 1024 1024}
accept="image/*,.pdf"
/>
`
`tsx
const [uploadProgress, setUploadProgress] = useState
const handleProgress = (progress: number, file?: UploadFile) => {
if (file) {
setUploadProgress(prev => ({
...prev,
[file.id]: progress
}))
}
}
onUpload={handleUpload}
onProgress={handleProgress}
multiple
/>
`
`tsx
import { mockUploadService } from 'zentrixui'
// Configure mock service for development
mockUploadService.configure({
delay: 2000,
successRate: 0.8,
chunkSize: 1024 * 1024
})
const handleUpload = async (files: File[]) => {
for (const file of files) {
try {
const result = await mockUploadService.upload(file, {
onProgress: (progress) => console.log(${file.name}: ${progress}%)`
})
console.log('Upload successful:', result)
} catch (error) {
console.error('Upload failed:', error)
}
}
}
The library is built with TypeScript and provides comprehensive type definitions:
`tsx
import type {
FileUploadProps,
FileUploadConfig,
UploadFile,
FileUploadState,
FileValidationResult
} from 'zentrixui'
const config: FileUploadConfig = {
defaults: {
variant: 'dropzone',
size: 'lg',
multiple: true
},
// ... rest of config with full type safety
}
const handleFileSelect = (files: File[]) => {
// Type-safe file handling
}
``
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
We welcome contributions! Please see our Contributing Guide for details.
MIT License - see LICENSE file for details.
- API Reference - Complete API documentation
- Configuration Guide - JSON configuration reference
- Usage Examples - Code examples for all variants
See CHANGELOG.md for version history and updates.