UploadKit
SDK@uploadkitdev/react

UploadSourceTabs

A Cloudinary/Uppy-style compact card with tabbed upload sources — Device, URL, and Clipboard.

A compact card component with pill tabs to switch between upload sources. The Device tab offers drag-drop and file picker, URL lets users paste a remote file URL, and Clipboard supports Ctrl+V paste uploads.

Design inspiration: Cloudinary Upload Widget, Uppy Dashboard.

motion is an optional peerDependency. Without it, the tab indicator snaps. pnpm add motion for a sliding layoutId tab indicator.

Choose file or drag here

Cloudinary · Uppy — multi-source tabs

Basic usage

import { UploadSourceTabs } from '@uploadkitdev/react';

export default function Page() {
  return (
    <UploadSourceTabs
      route="imageUploader"
      accept={['image/*']}
      tabs={['device', 'url', 'clipboard']}
      onUploadComplete={(result) => {
        console.log('Uploaded from any source:', result.url);
      }}
    />
  );
}

Props

PropTypeDefaultDescription
routestringRequired. Route name from your file router.
acceptstring[]Accepted MIME types.
maxSizenumberMaximum file size in bytes.
metadataRecord<string, unknown>Metadata forwarded to the server.
tabs('device' | 'url' | 'clipboard')[]All threeWhich source tabs to show.
onUploadComplete(result: UploadResult) => voidCalled after successful upload.
onUploadError(error: Error) => voidCalled on failure.
classNamestringAdditional CSS class(es).

Tab panels

TabInteraction
DeviceDrag-drop zone + click to browse
URLPaste field + Upload button (fetches URL as blob)
ClipboardFocus area, Ctrl+V/Cmd+V to paste files/images

Accessibility

  • role="tablist" / role="tab" / role="tabpanel" ARIA pattern
  • aria-selected, aria-controls, aria-labelledby
  • aria-live region for upload status
  • Respects prefers-reduced-motion

On this page