Skip to content
Devix Open Source

Customize

Styling and theming

import '@devix-labs/file-uploader/styles.css';        // plain
import '@devix-labs/file-uploader/styles.layer.css';  // the same, inside @layer devix

The layered stylesheet loses every specificity fight with your own CSS, which is what you want when the uploader is dropped into a design system that already has opinions.

Variables

.dxu {
  --dxu-radius: 12px;
  --dxu-font-size: 13px;
  --dxu-gap: 10px;
  --dxu-zone-padding: 22px;
  --dxu-thumb: 36px;
  --dxu-bar-height: 4px;

  --dxu-bg: #fff;
  --dxu-text: #18181b;
  --dxu-muted: #71717a;
  --dxu-border: #e4e4e7;
  --dxu-surface: #fafafa;      /* the drop zone, and hover */
  --dxu-accent: #ea4b71;       /* the progress bar, focus rings, the dragging state */
  --dxu-ok: #16a34a;
  --dxu-danger: #dc2626;
}

A compact list in a sidebar is two lines:

.dxu { --dxu-zone-padding: 14px; --dxu-thumb: 28px; --dxu-font-size: 12px; }

Dark

theme: 'auto' reads the page — Tailwind's .dark, data-theme, Bootstrap's data-bs-theme, or simply the background behind the widget — and re-reads it when a theme toggle flips. Override the dark palette by redefining the same variables under [data-theme='dark'].

Your classes

createFileUploader(input, {
  classNames: {
    zone: 'rounded-2xl border-2 border-dashed border-zinc-300',
    item: 'rounded-xl shadow-sm',
    name: 'font-medium truncate',
    bar: 'h-1',
  },
});

Parts: root, zone, icon, label, hint, browse, list, item, thumb, name, meta, bar, actions, action, error, footer, summary.

State

Selector When
.dxu--dragging Files are over the zone.
.dxu-item.is-waiting Queued.
.dxu-item.is-uploading On its way.
.dxu-item.is-done Arrived.
.dxu-item.is-failed Did not.
.dxu-item.is-cancelled Stopped.
.dxu-item.is-bad Refused, or failed — anything showing a reason.

Icons

createFileUploader(input, {
  icons: {
    upload: '<i class="fa-solid fa-cloud-arrow-up"></i>',
    file: '<i class="fa-regular fa-file"></i>',
    remove: '<i class="fa-solid fa-xmark"></i>',
    retry: '<i class="fa-solid fa-rotate-right"></i>',
    done: '<i class="fa-solid fa-check"></i>',
    failed: '<i class="fa-solid fa-triangle-exclamation"></i>',
  },
});

Replacing the icons to match a design system is an open request on Uppy with ten votes; here it is an option, and the markup is yours — an icon font, an inline SVG, or a sprite reference.

Three recipes

shadcn/ui

.dxu {
  --dxu-bg: hsl(var(--card));
  --dxu-surface: hsl(var(--muted));
  --dxu-text: hsl(var(--card-foreground));
  --dxu-muted: hsl(var(--muted-foreground));
  --dxu-border: hsl(var(--border));
  --dxu-accent: hsl(var(--primary));
  --dxu-radius: var(--radius);
}

Bootstrap 5

.dxu {
  --dxu-bg: var(--bs-body-bg);
  --dxu-surface: var(--bs-tertiary-bg);
  --dxu-text: var(--bs-body-color);
  --dxu-muted: var(--bs-secondary-color);
  --dxu-border: var(--bs-border-color);
  --dxu-accent: var(--bs-primary);
  --dxu-ok: var(--bs-success);
  --dxu-danger: var(--bs-danger);
  --dxu-radius: var(--bs-border-radius-lg);
}

Material 3

.dxu {
  --dxu-bg: var(--md-sys-color-surface);
  --dxu-surface: var(--md-sys-color-surface-container);
  --dxu-text: var(--md-sys-color-on-surface);
  --dxu-muted: var(--md-sys-color-on-surface-variant);
  --dxu-border: var(--md-sys-color-outline-variant);
  --dxu-accent: var(--md-sys-color-primary);
  --dxu-radius: 16px;
}

A whole page as the drop target

createFileUploader(input, { url: '/upload', dropOn: document.body });
.dxu--dragging::after {
  content: '';
  position: fixed;
  inset: 0;
  border: 3px dashed var(--dxu-accent);
  pointer-events: none;
}
Updated 15 Sep 2026