npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

zentrixui

v1.0.1

Published

ZentrixUI - A modern, highly customizable and accessible React file upload component library with multiple variants, JSON-based configuration, and excellent developer experience.

Downloads

26

Readme

ZentrixUI

npm version License: MIT TypeScript React

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.

Features

  • 🎨 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

Installation

npm install zentrixui
# or
pnpm add zentrixui
# or
yarn add zentrixui

Quick Start

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
    />
  )
}

Variants

Button Upload

Traditional file input styled as a button.

<FileUpload
  variant="button"
  onUpload={handleUpload}
  size="lg"
  radius="md"
/>

Dropzone Upload

Drag-and-drop area with visual feedback.

<FileUpload
  variant="dropzone"
  onUpload={handleUpload}
  accept="image/*,video/*"
  multiple
  maxFiles={10}
/>

Preview Upload

Shows file previews after selection with upload progress.

<FileUpload
  variant="preview"
  onUpload={handleUpload}
  multiple
  maxSize={10 * 1024 * 1024}
/>

Image Upload

Specialized for image files with thumbnail preview.

<FileUpload
  variant="image-only"
  onUpload={handleUpload}
  accept="image/*"
  maxSize={2 * 1024 * 1024}
/>

Multi-file Upload

Handles multiple files with individual progress tracking.

<FileUpload
  variant="multi-file"
  onUpload={handleUpload}
  multiple
  maxFiles={20}
  accept=".pdf,.doc,.docx"
/>

Configuration

Props Configuration

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
}

JSON Configuration

Create a file-upload.config.json file for declarative configuration:

{
  "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:

import config from './file-upload.config.json'

<FileUpload config={config} onUpload={handleUpload} />

Theming

Theme Provider

Wrap your app with the ThemeProvider for consistent theming:

import { ThemeProvider } from 'zentrixui'

function App() {
  return (
    <ThemeProvider theme="auto">
      <YourApp />
    </ThemeProvider>
  )
}

Custom Themes

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}
/>

Accessibility

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

Accessibility Props

<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>

Advanced Usage

File Validation

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"
/>

Progress Tracking

const [uploadProgress, setUploadProgress] = useState<Record<string, number>>({})

const handleProgress = (progress: number, file?: UploadFile) => {
  if (file) {
    setUploadProgress(prev => ({
      ...prev,
      [file.id]: progress
    }))
  }
}

<FileUpload
  variant="multi-file"
  onUpload={handleUpload}
  onProgress={handleProgress}
  multiple
/>

Custom Upload Service

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)
    }
  }
}

TypeScript Support

The library is built with TypeScript and provides comprehensive type definitions:

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
}

Browser Support

  • Chrome 90+
  • Firefox 88+
  • Safari 14+
  • Edge 90+

Contributing

We welcome contributions! Please see our Contributing Guide for details.

License

MIT License - see LICENSE file for details.

Documentation

Changelog

See CHANGELOG.md for version history and updates.