Dice UI
Components

Color Swatch

A color swatch component for displaying color values with support for transparency and various sizes.

Primary Blue
Different Sizes
Semi-transparent Blue
Color Palette
Disabled
import { ColorSwatch } from "@/components/ui/color-swatch";
 
export function ColorSwatchDemo() {
  return (
    <div className="flex flex-col gap-6">
      <div className="flex items-center gap-3">
        <ColorSwatch color="#3b82f6" />
        <span className="font-medium text-sm">Primary Blue</span>
      </div>
      <div className="flex items-center gap-3">
        <ColorSwatch color="#ef4444" size="sm" />
        <ColorSwatch color="#ef4444" size="default" />
        <ColorSwatch color="#ef4444" size="lg" />
        <span className="font-medium text-sm">Different Sizes</span>
      </div>
      <div className="flex items-center gap-3">
        <ColorSwatch color="rgba(59, 130, 246, 0.5)" />
        <span className="font-medium text-sm">Semi-transparent Blue</span>
      </div>
      <div className="flex items-center gap-3">
        <span className="font-medium text-sm">Color Palette</span>
        <div className="flex gap-2">
          <ColorSwatch color="#ef4444" />
          <ColorSwatch color="#f97316" />
          <ColorSwatch color="#eab308" />
          <ColorSwatch color="#22c55e" />
          <ColorSwatch color="#3b82f6" />
          <ColorSwatch color="#8b5cf6" />
          <ColorSwatch color="#ec4899" />
        </div>
      </div>
      <div className="flex items-center gap-3">
        <ColorSwatch color="#ef4444" disabled />
        <span className="font-medium text-sm">Disabled</span>
      </div>
    </div>
  );
}

Installation

CLI

npx shadcn@latest add "https://diceui.com/r/color-swatch"
pnpm dlx shadcn@latest add "https://diceui.com/r/color-swatch"
yarn dlx shadcn@latest add "https://diceui.com/r/color-swatch"
bun x shadcn@latest add "https://diceui.com/r/color-swatch"

Manual

Install the following dependencies:

npm install @radix-ui/react-slot class-variance-authority
pnpm add @radix-ui/react-slot class-variance-authority
yarn add @radix-ui/react-slot class-variance-authority
bun add @radix-ui/react-slot class-variance-authority

Copy and paste the following code into your project.

"use client";
 
import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
import { cn } from "@/lib/utils";
 
const colorSwatchVariants = cva(
  "box-border rounded-sm border shadow-sm [background-clip:padding-box] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
  {
    variants: {
      size: {
        default: "size-8",
        sm: "size-6",
        lg: "size-12",
      },
    },
    defaultVariants: {
      size: "default",
    },
  },
);
 
function getIsCssColor(v: string): boolean {
  try {
    return typeof CSS !== "undefined" && typeof CSS.supports === "function"
      ? CSS.supports("color", v)
      : true;
  } catch {
    return false;
  }
}
 
function getHasAlpha(v: string): boolean {
  const s = v.trim().toLowerCase();
 
  if (s === "transparent") return true;
 
  if (/^#(?:[0-9a-f]{4}|[0-9a-f]{8})$/i.test(s)) return true;
 
  if (/\b(?:rgba|hsla)\s*\(/i.test(s)) return true;
 
  if (
    /\b(?:rgb|hsl|lab|lch|oklab|oklch|color)\s*\([^)]*\/\s*[\d.]+%?\s*\)/i.test(
      s,
    )
  ) {
    return true;
  }
 
  return false;
}
 
interface ColorSwatchProps
  extends Omit<React.ComponentProps<"div">, "children">,
    VariantProps<typeof colorSwatchVariants> {
  color?: string;
  asChild?: boolean;
  disabled?: boolean;
  withoutTransparency?: boolean;
}
 
function ColorSwatch({
  color,
  size = "default",
  asChild = false,
  disabled = false,
  withoutTransparency = false,
  className,
  style,
  ...props
}: ColorSwatchProps) {
  const colorValue = color?.trim();
 
  const backgroundStyle = React.useMemo<React.CSSProperties>(() => {
    if (!colorValue) {
      return {
        background:
          "linear-gradient(to bottom right, transparent calc(50% - 1px), hsl(var(--destructive)) calc(50% - 1px) calc(50% + 1px), transparent calc(50% + 1px)) no-repeat",
      };
    }
 
    if (!getIsCssColor(colorValue)) {
      return { backgroundColor: "transparent" };
    }
 
    if (!withoutTransparency && getHasAlpha(colorValue)) {
      return {
        background: `linear-gradient(${colorValue}, ${colorValue}), repeating-conic-gradient(#ccc 0% 25%, #fff 0% 50%) 0% 50% / 10px 10px`,
      };
    }
 
    return { backgroundColor: colorValue };
  }, [colorValue, withoutTransparency]);
 
  const ariaLabel = !colorValue
    ? "No color selected"
    : `Color swatch: ${colorValue}`;
 
  const Primitive = asChild ? Slot : "div";
 
  return (
    <Primitive
      role="img"
      aria-label={ariaLabel}
      aria-disabled={disabled || undefined}
      data-slot="color-swatch"
      data-disabled={disabled ? "" : undefined}
      {...props}
      className={cn(colorSwatchVariants({ size }), className)}
      style={{
        ...backgroundStyle,
        forcedColorAdjust: "none",
        ...style,
      }}
    />
  );
}
 
export { ColorSwatch };

Usage

Import the component and use it to display color values.

import { ColorSwatch } from "@/components/ui/color-swatch";

<ColorSwatch value="#3b82f6" />

Examples

Different Sizes

The color swatch component supports three different sizes: sm, default, and lg.

Small (sm)
Default
Large (lg)
import { ColorSwatch } from "@/components/ui/color-swatch";
 
const colors = [
  "#ef4444", // red
  "#f97316", // orange
  "#eab308", // yellow
  "#22c55e", // green
  "#3b82f6", // blue
];
 
export function ColorSwatchSizesDemo() {
  return (
    <div className="flex flex-col gap-6">
      <div className="flex flex-col gap-2">
        <span className="font-medium text-sm">Small (sm)</span>
        <div className="flex gap-2">
          {colors.map((color, index) => (
            <ColorSwatch key={index} color={color} size="sm" />
          ))}
        </div>
      </div>
      <div className="flex flex-col gap-2">
        <span className="font-medium text-sm">Default</span>
        <div className="flex gap-2">
          {colors.map((color, index) => (
            <ColorSwatch key={index} color={color} size="default" />
          ))}
        </div>
      </div>
 
      <div className="flex flex-col gap-2">
        <span className="font-medium text-sm">Large (lg)</span>
        <div className="flex gap-2">
          {colors.map((color, index) => (
            <ColorSwatch key={index} color={color} size="lg" />
          ))}
        </div>
      </div>
    </div>
  );
}

Transparency Support

The color swatch automatically detects transparent colors and displays them with a checkerboard background pattern.

Alpha Transparency
HSLA Colors
Without Transparency Pattern
With Transparency Pattern (Default)
import { ColorSwatch } from "@/components/ui/color-swatch";
 
export function ColorSwatchTransparencyDemo() {
  return (
    <div className="flex flex-col gap-6">
      <div className="flex flex-col gap-2">
        <span className="font-medium text-sm">Alpha Transparency</span>
        <div className="flex gap-2">
          <ColorSwatch color="rgba(59, 130, 246, 1)" />
          <ColorSwatch color="rgba(59, 130, 246, 0.8)" />
          <ColorSwatch color="rgba(59, 130, 246, 0.6)" />
          <ColorSwatch color="rgba(59, 130, 246, 0.4)" />
          <ColorSwatch color="rgba(59, 130, 246, 0.2)" />
        </div>
      </div>
      <div className="flex flex-col gap-2">
        <span className="font-medium text-sm">HSLA Colors</span>
        <div className="flex gap-2">
          <ColorSwatch color="hsla(220, 91%, 60%, 1)" />
          <ColorSwatch color="hsla(220, 91%, 60%, 0.75)" />
          <ColorSwatch color="hsla(220, 91%, 60%, 0.5)" />
          <ColorSwatch color="hsla(220, 91%, 60%, 0.25)" />
          <ColorSwatch color="hsla(220, 91%, 60%, 0.1)" />
        </div>
      </div>
      <div className="flex flex-col gap-2">
        <span className="font-medium text-sm">
          Without Transparency Pattern
        </span>
        <div className="flex gap-2">
          <ColorSwatch color="rgba(239, 68, 68, 0.8)" withoutTransparency />
          <ColorSwatch color="rgba(34, 197, 94, 0.6)" withoutTransparency />
          <ColorSwatch color="rgba(139, 92, 246, 0.4)" withoutTransparency />
        </div>
      </div>
      <div className="flex flex-col gap-2">
        <span className="font-medium text-sm">
          With Transparency Pattern (Default)
        </span>
        <div className="flex gap-2">
          <ColorSwatch color="rgba(239, 68, 68, 0.8)" />
          <ColorSwatch color="rgba(34, 197, 94, 0.6)" />
          <ColorSwatch color="rgba(139, 92, 246, 0.4)" />
        </div>
      </div>
    </div>
  );
}

API Reference

ColorSwatch

A color swatch component that displays a color value with optional transparency support.

PropTypeDefault
asChild?
boolean
false
disabled?
boolean
false
withoutTransparency?
boolean
false
size?
"default" | "sm" | "lg"
"default"
color?
string
undefined
Data AttributeValue
[data-disabled]Present when the component is disabled.
[data-slot]Always set to 'color-swatch' for identification.

Accessibility

The color swatch component includes proper accessibility features:

  • ARIA Label: Automatically generates descriptive aria-label text based on the color value
  • Role: Uses role="img" to indicate it's an image representation of a color
  • Disabled State: Properly handles disabled state with appropriate visual and interaction changes

Screen Reader Support

  • When a color value is provided, the aria-label reads "Color swatch: [color-value]"
  • When no color is selected, the aria-label reads "No color selected"

Color Format Support

The color swatch component supports various color formats:

  • HEX: #3b82f6
  • RGB: rgb(59, 130, 246)
  • RGBA: rgba(59, 130, 246, 0.5)
  • HSL: hsl(217, 91%, 60%)
  • HSLA: hsla(217, 91%, 60%, 0.5)
  • Named Colors: blue, red, etc.

Transparency Detection

The component automatically detects transparent colors by checking for:

  • rgba() or hsla() function notation
  • RGB/HSL with 4 values (including alpha)
  • Any color format that includes transparency information

When transparency is detected, a checkerboard pattern is displayed behind the color to show the transparency effect. Use the withoutTransparency prop to disable this behavior.

Usage with Forms

The color swatch component can be used as a form control by utilizing the asChild prop:

<ColorSwatch asChild>
  <button type="button" onClick={handleColorSelect}>
    <span className="sr-only">Select color</span>
  </button>
</ColorSwatch>

Styling

The component uses CSS custom properties for styling:

  • Uses forcedColorAdjust: none to maintain color accuracy in high contrast mode
  • Supports all standard HTML div attributes and styling
  • Can be customized with additional CSS classes via the className prop