UploadKit
SDK@uploadkitdev/react

Theming

Customize @uploadkitdev/react components with CSS custom properties.

Components use CSS custom properties (not Tailwind classes) so they work in any React project, not just Tailwind projects.

CSS custom properties

All visual properties are controlled by CSS variables. Override them on :root or any ancestor element to theme the components.

Core tokens

VariableLight defaultDark defaultControls
--uk-primary#0070f3#0070f3Button background, dropzone border on hover, progress bar
--uk-primary-hover#005bb5#005bb5Button background on hover
--uk-accent#6366f1#6366f1Focus rings, subtle accent highlights
--uk-bg#ffffff#0a0a0bComponent background
--uk-bg-secondary#fafafa#141416File item backgrounds, icon container backgrounds
--uk-border#eaeaeargba(255,255,255,0.08)Borders and dividers
--uk-text#171717#fafafaPrimary text color
--uk-text-secondary#666666#a1a1aaSecondary text, labels, hints
--uk-success#00c853#00c853Success state (checkmark, button after upload)
--uk-error#dc2626#dc2626Error state (X icon, button on failure, toast text)
--uk-beam-success#22c55e#22c55eAnimated border-beam success color
--uk-beam-error#ef4444#ef4444Animated border-beam error color
--uk-radius12px12pxBorder radius on buttons, dropzone, modal, file items
--uk-fontSystem UI stackSystem UI stackFont family for all component text
--uk-transition200ms ease-out200ms ease-outTransition duration and easing

Many components expose additional CSS variables specific to their visual language (e.g. --uk-aurora-from, --uk-brutal-shadow, --uk-terminal-fg). See the individual component reference pages for the full list.

Overriding tokens

Set variables on :root to change them globally, or on a specific ancestor to scope them:

/* Global override */
:root {
  --uk-primary: #7c3aed;        /* Purple instead of blue */
  --uk-primary-hover: #6d28d9;
  --uk-radius: 8px;             /* Less rounded */
}

/* Scoped override — only affects components inside .upload-area */
.upload-area {
  --uk-primary: #059669;        /* Green for this section only */
}

Dark mode

Dark mode works in two ways:

Automatic (prefers-color-scheme): The background, border, and text tokens switch automatically based on the system preference. No code required.

Explicit (data-theme attribute): Set data-theme="dark" on <html> (or any ancestor) to force dark mode regardless of system preference:

app/layout.tsx
<html lang="en" data-theme="dark">

Or toggle dynamically:

document.documentElement.setAttribute('data-theme', isDark ? 'dark' : 'light');

The --uk-primary, --uk-success, and --uk-error tokens are the same in light and dark mode by default. Only the background, border, and text tokens change.

Full brand color override

:root {
  /* Primary — your brand color */
  --uk-primary: #7c3aed;
  --uk-primary-hover: #6d28d9;

  /* Softer radius for a more conservative look */
  --uk-radius: 6px;

  /* Custom font stack */
  --uk-font: 'Inter', -apple-system, sans-serif;
}

@media (prefers-color-scheme: dark) {
  :root {
    /* Lighten primary slightly for better contrast on dark bg */
    --uk-primary: #a78bfa;
    --uk-primary-hover: #8b5cf6;
  }
}

Tailwind integration

Use the className prop to add Tailwind utility classes to the outer wrapper, and the appearance prop to target inner elements:

<UploadButton
  route="imageUploader"
  className="w-full"
  appearance={{
    button: 'rounded-full font-semibold tracking-tight',
    progressBar: 'h-0.5',
    progressText: 'text-xs tabular-nums',
  }}
/>

<UploadDropzone
  route="imageUploader"
  className="border-dashed"
  appearance={{
    container: 'min-h-48 rounded-2xl',
    label: 'text-sm',
    icon: 'opacity-60',
    fileItem: 'bg-neutral-50 dark:bg-neutral-900/50',
  }}
/>

For deeper customization, override CSS variables in your Tailwind theme:

/* globals.css or your Tailwind CSS file */
@layer base {
  :root {
    --uk-primary: theme(colors.violet.600);
    --uk-primary-hover: theme(colors.violet.700);
    --uk-radius: theme(borderRadius.lg);
  }
}

data-uk-element targeting

Every rendered element in @uploadkitdev/react components has a data-uk-element attribute (no uk- prefix — just the element name). Use CSS attribute selectors to target and restyle specific elements without overriding CSS custom properties.

Element names

Attribute valueElement
buttonThe upload button
containerThe dropzone container
labelThe dropzone label
upload-iconThe cloud/upload icon in the dropzone
allowed-contentThe "Images up to 4 MB" hint under the dropzone
file-itemA single file row in the list
previewA file preview thumbnail
progress-barThe progress bar wrapper
progress-textThe progress percentage text
modalThe modal dialog
submit-buttonThe modal's primary submit button

data-state values

Elements also carry a data-state attribute reflecting the current lifecycle:

ValueMeaning
idleNo upload in progress (dropzone default)
readyButton is idle and ready to receive a click
draggingDropzone is receiving a drag-over
uploadingUpload in progress
successUpload finished successfully
errorUpload failed

Direct CSS targeting

/* Style the button */
[data-uk-element="button"] {
  background: linear-gradient(135deg, #6366f1, #8b5cf6);
  border-radius: 999px;
}

/* Style the dropzone during upload */
[data-uk-element="container"][data-state="uploading"] {
  opacity: 0.6;
  pointer-events: none;
}

/* Style file items */
[data-uk-element="file-item"] {
  background: #f8f9fa;
  border-radius: 8px;
}

Tailwind withUk wrapper

@uploadkitdev/react ships a withUk Tailwind plugin that generates variants matching the data-uk-element and data-state attributes.

Setup

For Tailwind CSS v4:

/* globals.css */
@import "tailwindcss";
@plugin "@uploadkitdev/react/tailwind";

For Tailwind CSS v3:

// tailwind.config.js
const { withUk } = require('@uploadkitdev/react/tailwind');

module.exports = withUk({
  content: ['./src/**/*.{ts,tsx}'],
  theme: { extend: {} },
  plugins: [],
});

Available variants

Element variants (target elements by data-uk-element):

VariantTargets
uk-button:[data-uk-element="button"]
uk-container:[data-uk-element="container"]
uk-label:[data-uk-element="label"]
uk-upload-icon:[data-uk-element="upload-icon"]
uk-allowed-content:[data-uk-element="allowed-content"]
uk-file-item:[data-uk-element="file-item"]
uk-progress-bar:[data-uk-element="progress-bar"]
uk-preview:[data-uk-element="preview"]
uk-modal:[data-uk-element="modal"]
uk-submit:[data-uk-element="submit-button"]

State variants (target elements by data-state):

VariantTargets
uk-ready:[data-state="ready"]
uk-idle:[data-state="idle"]
uk-dragging:[data-state="dragging"]
uk-uploading:[data-state="uploading"]
uk-success:[data-state="success"]
uk-error:[data-state="error"]

Usage examples

<UploadButton
  route="imageUploader"
  className="uk-button:rounded-full uk-button:bg-violet-600 uk-uploading:opacity-50"
/>

<UploadDropzone
  route="imageUploader"
  className="uk-error:border-red-500 uk-error:bg-red-50"
/>

CSS custom properties (--uk-primary, --uk-radius, etc.) remain the recommended approach for color and spacing overrides. data-uk-element targeting is best suited for structural or layout changes that can't be expressed as token values.

CSS keyframes

The package defines these animations (used internally):

KeyframeUsed by
uk-spinSpinning loader in UploadButton during upload
uk-modal-enterModal scale-in on open
uk-modal-exitModal scale-out on close
uk-fade-inFile item appearance, error toast appearance
uk-progress-indeterminateProgress bar indeterminate state

Reduced motion

All component transitions and animations are gated on prefers-reduced-motion. When the user has enabled reduced motion in their OS, durations drop to 0.01ms — effectively instant with no flicker.

@media (prefers-reduced-motion: reduce) {
  .uk-button,
  .uk-dropzone,
  .uk-modal,
  /* ... all component elements */
  {
    transition-duration: 0.01ms !important;
    animation-duration: 0.01ms !important;
  }
}

On this page