Clawdy
Guides

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:

KeyDescription
buttonThe clickable upload button element
containerThe outer wrapper around the button
allowedContentThe 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.

On this page