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 🙏

© 2025 – Pkg Stats / Ryan Hefner

@aadarshg214/file-upload-ui

v1.0.0

Published

A config-driven, accessible file upload component library

Readme

@file-upload/ui

A config-driven, accessible file upload component library built with React, TypeScript, and Tailwind CSS. Features multiple variants, themes, and real-time configuration editing.

✨ Features

  • 🎨 Config-Driven: Fully customizable via JSON configuration
  • Accessible: Keyboard navigation, screen reader support, ARIA labels
  • 📦 NPM Ready: Proper package structure with TypeScript support
  • 🎯 Multiple Variants: Button, dropzone, preview, and compact layouts
  • 🌈 Theme Support: Default, minimal, modern, and classic themes
  • 📱 Responsive: Works perfectly on all devices
  • 🔧 TypeScript: Full type safety throughout
  • Fast: Built with Vite for lightning-fast development
  • 💾 LocalStorage: Files persist across page refreshes
  • 🖼️ Image Previews: Beautiful image previews with status overlays

🚀 Quick Start

Installation

npm install @file-upload/ui

Basic Usage

import { FileUpload } from '@file-upload/ui'

function App() {
  const handleFilesSelected = (files: File[]) => {
    console.log('Files selected:', files)
  }

  return (
    <FileUpload
      onFilesSelected={handleFilesSelected}
      config={{
        variant: 'dropzone',
        theme: 'modern',
        maxSize: 10 * 1024 * 1024, // 10MB
        acceptedTypes: ['image/*', '.pdf']
      }}
    />
  )
}

📋 Component Variants

1. Button Variant

Simple button-style upload with icon placement options.

<FileUpload
  config={{
    variant: 'button',
    size: 'md',
    theme: 'default',
    iconPlacement: 'left'
  }}
/>

2. Dropzone Variant

Drag-and-drop interface with visual feedback.

<FileUpload
  config={{
    variant: 'dropzone',
    size: 'lg',
    theme: 'modern',
    borderStyle: 'dashed'
  }}
/>

3. Preview Variant

Upload with file previews and progress tracking.

<FileUpload
  config={{
    variant: 'preview',
    showPreview: true,
    showProgress: true,
    acceptedTypes: ['image/*']
  }}
  onFileUpload={async (file) => {
    // Handle file upload
    await uploadToServer(file)
  }}
/>

4. Compact Variant

Minimal design for space-constrained layouts.

<FileUpload
  config={{
    variant: 'compact',
    size: 'sm',
    theme: 'minimal'
  }}
/>

🎨 Configuration System

The component is fully configurable via a JSON schema that's LLM-friendly with a simple, declarative structure:

interface FileUploadConfig {
  // Variant configuration
  variant: 'button' | 'dropzone' | 'preview' | 'compact'
  size: 'sm' | 'md' | 'lg'
  theme: 'default' | 'minimal' | 'modern' | 'classic'
  
  // File restrictions
  maxSize: number // in bytes
  acceptedTypes: string[]
  multiple: boolean
  maxFiles?: number
  
  // Styling
  radius: 'none' | 'sm' | 'md' | 'lg' | 'full'
  borderStyle: 'solid' | 'dashed' | 'dotted' | 'none'
  iconPlacement: 'left' | 'right' | 'top' | 'bottom' | 'center'
  
  // Labels and text
  labels: {
    title: string
    subtitle: string
    buttonText: string
    dragText: string
    dropText: string
    errorText: string
    successText: string
  }
  
  // Behavior
  autoUpload: boolean
  showProgress: boolean
  showPreview: boolean
  allowRemove: boolean
  
  // Accessibility
  ariaLabel: string
  ariaDescribedBy?: string
}

📝 JSON Configuration Examples

Basic Dropzone

{
  "variant": "dropzone",
  "size": "md",
  "theme": "default",
  "maxSize": 10485760,
  "acceptedTypes": ["image/*", ".pdf", ".doc"],
  "multiple": true,
  "labels": {
    "title": "Upload Files",
    "subtitle": "Drag and drop files here or click to browse",
    "buttonText": "Choose Files",
    "dragText": "Drag files here",
    "dropText": "Drop files here",
    "errorText": "Error uploading file",
    "successText": "File uploaded successfully"
  }
}

Image-Only Preview

{
  "variant": "preview",
  "size": "lg",
  "theme": "modern",
  "maxSize": 5242880,
  "acceptedTypes": ["image/*"],
  "multiple": true,
  "showPreview": true,
  "showProgress": true,
  "autoUpload": true,
  "labels": {
    "title": "Upload Images",
    "subtitle": "Drag and drop images here or click to browse",
    "buttonText": "Select Images",
    "dragText": "Drag images here",
    "dropText": "Drop images here",
    "errorText": "Error uploading image",
    "successText": "Image uploaded successfully"
  }
}

Compact Button

{
  "variant": "compact",
  "size": "sm",
  "theme": "minimal",
  "maxSize": 2097152,
  "acceptedTypes": [".pdf", ".doc", ".txt"],
  "multiple": false,
  "labels": {
    "title": "Quick Upload",
    "subtitle": "Select a document to upload",
    "buttonText": "Choose File",
    "dragText": "Drag file here",
    "dropText": "Drop file here",
    "errorText": "Error uploading file",
    "successText": "File uploaded successfully"
  }
}

🛠️ API Reference

FileUpload Props

| Prop | Type | Default | Description | |------|------|---------|-------------| | config | Partial<FileUploadConfig> | defaultConfig | Configuration object | | onFilesSelected | (files: File[]) => void | - | Callback when files are selected | | onFileUpload | (file: FileWithPreview) => Promise<void> | - | Callback for file upload | | onFileRemove | (fileId: string) => void | - | Callback when file is removed | | className | string | - | Additional CSS classes | | disabled | boolean | false | Disable the component | | storageKey | string | 'fileUpload' | localStorage key for persistence |

Utility Functions

import { 
  createFileUploadConfig,
  getConfigFromJSON,
  exportConfigToJSON,
  validateConfig,
  saveFilesToStorage,
  loadFilesFromStorage,
  clearFilesFromStorage
} from '@file-upload/ui'

// Create config with overrides
const config = createFileUploadConfig({
  variant: 'button',
  theme: 'modern'
})

// Parse JSON string to config
const config = getConfigFromJSON(jsonString)

// Export config to JSON
const jsonString = exportConfigToJSON(config)

// Validate config
const { isValid, errors } = validateConfig(config)

// Storage utilities
saveFilesToStorage(files, 'myUploadKey')
const files = loadFilesFromStorage('myUploadKey')
clearFilesFromStorage('myUploadKey')

Preset Configurations

import { configPresets } from '@file-upload/ui'

// Use preset configurations
<FileUpload config={configPresets.imageOnly} />
<FileUpload config={configPresets.documentOnly} />
<FileUpload config={configPresets.compact} />
<FileUpload config={configPresets.modern} />

🎯 Accessibility Features

  • Keyboard Navigation: Full keyboard support with Enter/Space activation
  • Screen Reader Support: Proper ARIA labels and descriptions
  • Focus Management: Clear focus indicators and logical tab order
  • Error Handling: Accessible error messages and validation feedback
  • Drag & Drop: Keyboard fallback for drag-and-drop functionality

🎨 Theming

The component supports four built-in themes:

Default Theme

Clean, professional design with neutral colors.

Minimal Theme

Subtle borders and transparent backgrounds.

Modern Theme

Gradient buttons and blue accent colors.

Classic Theme

Traditional gray color scheme.

🧪 Demo

Run the development server to see the interactive demo:

npm run dev

Visit http://localhost:5173 to see:

  • Live Demo: Interactive file upload with real-time configuration
  • All Variants: Showcase of all component variants and themes
  • Config Editor: Live JSON configuration editor with real-time preview
  • Preset Configurations: Pre-built configurations for common use cases

Demo Features

  1. Live Demo Tab

    • Real-time component preview
    • Current configuration display
    • Upload summary with statistics
  2. All Variants Tab

    • Button variants (Default, Modern, Minimal)
    • Dropzone variants (Modern, Classic)
    • Preview variants (Image, Document)
    • Compact variants (Small, Medium, Large)
  3. Config Editor Tab

    • Live JSON editor with syntax highlighting
    • Real-time component preview
    • Preset configuration buttons
    • Copy/Reset functionality

📦 Building for Production

Build the Library

npm run build:lib

Create NPM Package

npm run pack

Development

npm run dev

🔧 Development

Project Structure

src/
├── components/
│   ├── file-upload.tsx          # Main component
│   ├── file-upload-button.tsx   # Button variant
│   ├── file-upload-dropzone.tsx # Dropzone variant
│   └── file-upload-preview.tsx  # Preview variant
├── types/
│   ├── config.ts                # Configuration types
│   └── variants.ts              # Variant types
├── config/
│   └── default-config.ts        # Default configuration
├── utils/
│   ├── config.ts                # Configuration utilities
│   └── storage.ts               # Storage utilities
├── lib/
│   └── utils.ts                 # General utilities
└── demo/
    └── App.tsx                  # Demo application

Adding New Variants

  1. Add variant type to types/variants.ts
  2. Add styles to variantStyles and themeStyles
  3. Implement variant logic in file-upload.tsx
  4. Create variant-specific component (optional)
  5. Update documentation

🛠 Tech Stack

  • React 19 - Latest React with concurrent features
  • TypeScript - Type safety and better developer experience
  • Tailwind CSS - Utility-first CSS framework
  • Vite - Fast build tool and dev server
  • Radix UI - Accessible UI primitives
  • clsx & tailwind-merge - Conditional styling utilities

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature-name
  3. Commit your changes: git commit -am 'Add feature'
  4. Push to the branch: git push origin feature-name
  5. Submit a pull request

📄 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments