zentrixui
Version:
ZentrixUI - A modern, highly customizable and accessible React file upload component library with multiple variants, JSON-based configuration, and excellent developer experience.
415 lines (337 loc) โข 9.06 kB
Markdown
<div align="center">
<h1>๐ ZentrixUI</h1>
<p>Modern, highly customizable and accessible React file upload components</p>
[](https://badge.fury.io/js/zentrixui)
[](https://opensource.org/licenses/MIT)
[](http://www.typescriptlang.org/)
[](https://reactjs.org/)
</div>
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 zentrixui
pnpm add zentrixui
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 (
<FileUpload
variant="dropzone"
onUpload={handleUpload}
accept="image/*"
maxSize={5 * 1024 * 1024} // 5MB
multiple
/>
)
}
```
Traditional file input styled as a button.
```tsx
<FileUpload
variant="button"
onUpload={handleUpload}
size="lg"
radius="md"
/>
```
Drag-and-drop area with visual feedback.
```tsx
<FileUpload
variant="dropzone"
onUpload={handleUpload}
accept="image/*,video/*"
multiple
maxFiles={10}
/>
```
Shows file previews after selection with upload progress.
```tsx
<FileUpload
variant="preview"
onUpload={handleUpload}
multiple
maxSize={10 * 1024 * 1024}
/>
```
Specialized for image files with thumbnail preview.
```tsx
<FileUpload
variant="image-only"
onUpload={handleUpload}
accept="image/*"
maxSize={2 * 1024 * 1024}
/>
```
Handles multiple files with individual progress tracking.
```tsx
<FileUpload
variant="multi-file"
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<void>
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'
<FileUpload config={config} onUpload={handleUpload} />
```
Wrap your app with the ThemeProvider for consistent theming:
```tsx
import { ThemeProvider } from 'zentrixui'
function App() {
return (
<ThemeProvider theme="auto">
<YourApp />
</ThemeProvider>
)
}
```
```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'
}
}
<FileUpload
config={{ styling: customTheme }}
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
<FileUpload
ariaLabel="Upload your documents"
ariaDescribedBy="upload-help-text"
onUpload={handleUpload}
/>
<div id="upload-help-text">
Supported formats: PDF, DOC, DOCX. Maximum size: 10MB.
</div>
```
```tsx
const handleUpload = async (files: File[]) => {
// Custom validation
const validFiles = files.filter(file => {
if (file.size > 5 * 1024 * 1024) {
console.error(`File ${file.name} is too large`)
return false
}
return true
})
// Upload valid files
for (const file of validFiles) {
await uploadFile(file)
}
}
<FileUpload
onUpload={handleUpload}
onError={(error) => console.error('Upload error:', error)}
maxSize={5 * 1024 * 1024}
accept="image/*,.pdf"
/>
```
```tsx
const [uploadProgress, setUploadProgress] = useState<Record<string, number>>({})
const handleProgress = (progress: number, file?: UploadFile) => {
if (file) {
setUploadProgress(prev => ({
...prev,
[]: progress
}))
}
}
<FileUpload
variant="multi-file"
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](CONTRIBUTING.md) for details.
MIT License - see [LICENSE](LICENSE) file for details.
- [API Reference](docs/API.md) - Complete API documentation
- [Configuration Guide](docs/CONFIGURATION.md) - JSON configuration reference
- [Usage Examples](docs/EXAMPLES.md) - Code examples for all variants
See [CHANGELOG.md](CHANGELOG.md) for version history and updates.