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