Theming
Customize the appearance of upload components
Overview
Clawdy's built-in <UploadButton /> and <UploadDropzone /> components are designed to work out of the box, but you can fully customize their appearance to match your application's design system.
Using the className Prop
The simplest way to style a component is with the className prop. This applies a CSS class to the outermost container of the component:
<UploadButton
endpoint="imageUploader"
className="my-custom-uploader"
/>
<UploadDropzone
endpoint="imageUploader"
className="my-custom-dropzone"
/>This is useful when you want to control layout properties like width, margin, or padding from the parent level.
Using the appearance Prop
For fine-grained control, use the appearance prop to target specific internal elements of the component. Each key accepts a string of CSS classes.
UploadButton
The UploadButton component exposes three style targets:
| Key | Description |
|---|---|
button | The clickable upload button element |
container | The outer wrapper around the button |
allowedContent | The text below the button showing allowed file types |
<UploadButton
endpoint="imageUploader"
appearance={{
button: "bg-blue-600 hover:bg-blue-700 text-white font-semibold px-6 py-3 rounded-lg",
container: "flex flex-col items-center gap-2",
allowedContent: "text-xs text-gray-400",
}}
/>UploadDropzone
The UploadDropzone component also supports the appearance prop with similar style targets:
<UploadDropzone
endpoint="imageUploader"
appearance={{
container: "border-2 border-dashed border-gray-300 rounded-xl p-8 hover:border-blue-400 transition-colors",
allowedContent: "text-xs text-gray-400 mt-2",
}}
/>Tailwind CSS Examples
Here are some common Tailwind CSS patterns for styling Clawdy components.
Minimal Button
<UploadButton
endpoint="imageUploader"
appearance={{
button: "bg-black text-white text-sm px-4 py-2 rounded-md hover:bg-gray-800 transition-colors",
container: "w-fit",
allowedContent: "hidden",
}}
/>Rounded Pill Button
<UploadButton
endpoint="imageUploader"
appearance={{
button: "bg-gradient-to-r from-purple-500 to-pink-500 text-white font-medium px-8 py-3 rounded-full shadow-lg hover:shadow-xl transition-shadow",
container: "flex justify-center",
allowedContent: "text-xs text-gray-500 mt-1",
}}
/>Large Dropzone
<UploadDropzone
endpoint="imageUploader"
appearance={{
container: "h-64 border-2 border-dashed border-blue-300 bg-blue-50 rounded-2xl flex items-center justify-center hover:bg-blue-100 transition-colors cursor-pointer",
allowedContent: "text-sm text-blue-400",
}}
/>Dark Theme Dropzone
<UploadDropzone
endpoint="imageUploader"
appearance={{
container: "h-48 border border-gray-700 bg-gray-900 rounded-lg hover:border-gray-500 transition-colors",
allowedContent: "text-xs text-gray-500",
}}
/>Building a Fully Custom-Styled Upload Experience
For complete control over every pixel, combine the appearance prop with wrapper elements and your own design tokens:
"use client";
import { UploadButton } from "@clawdyup/react";
export function BrandedUploader() {
return (
<div className="mx-auto max-w-md rounded-2xl border border-gray-200 bg-white p-8 shadow-sm">
<h3 className="mb-1 text-lg font-semibold text-gray-900">
Upload your avatar
</h3>
<p className="mb-6 text-sm text-gray-500">
JPG, PNG, or WebP. Max 4MB.
</p>
<UploadButton
endpoint="profileImage"
appearance={{
button:
"w-full bg-indigo-600 hover:bg-indigo-700 text-white font-medium py-3 rounded-lg transition-colors",
container: "w-full",
allowedContent: "text-xs text-gray-400 mt-3 text-center",
}}
/>
</div>
);
}If the appearance prop does not give you enough control, consider using the useClawdy hook to build a completely custom component from scratch. See the Custom Upload UI guide for details.