Skip to content

ColorSwatch

A color preview element that displays a color with a checkerboard background for visualizing alpha transparency.

Preview

Source code
vue
<script setup lang="ts">
import { shallowRef } from "vue";
import { Color } from "@urcolor/core";
import { ColorSwatchRoot } from "@urcolor/vue";
import { Check } from "lucide-vue-next";

const colors = [
  Color.parse("hsl(210, 80%, 50%)")!,
  Color.parse("hsl(350, 90%, 60%)")!,
  Color.parse("hsl(120, 60%, 45%)")!,
  Color.parse("hsla(45, 100%, 55%, 0.5)")!,
];

const selected = shallowRef(colors[0]);
</script>

<template>
  <div class="flex items-center gap-3">
    <ColorSwatchRoot
      v-for="(color, i) in colors"
      :key="i"
      :model-value="color"
      alpha
      class="flex size-10 cursor-pointer items-center justify-center rounded-lg"
      @click="selected = color"
    >
      <Check
        class="
          size-5 text-white drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]
          transition-opacity duration-150
        "
        :class="selected === color ? 'opacity-100' : 'opacity-0'"
      />
    </ColorSwatchRoot>
  </div>
</template>

Anatomy

ColorSwatchRoot is the whole family, a single component with no sub-parts.

vue
<script setup lang="ts">
import { ColorSwatchRoot } from "@urcolor/vue";
</script>

<template>
  <ColorSwatchRoot model-value="hsl(210, 80%, 50%)" />
</template>

Examples

Basic

A set of color swatches, including one with alpha transparency.

Source code
vue
<script setup lang="ts">
import { shallowRef } from "vue";
import { Color } from "@urcolor/core";
import { ColorSwatchRoot } from "@urcolor/vue";
import { Check } from "lucide-vue-next";

const colors = [
  Color.parse("hsl(210, 80%, 50%)")!,
  Color.parse("hsl(350, 90%, 60%)")!,
  Color.parse("hsl(120, 60%, 45%)")!,
  Color.parse("hsla(45, 100%, 55%, 0.5)")!,
];

const selected = shallowRef(colors[0]);
</script>

<template>
  <div class="flex items-center gap-3">
    <ColorSwatchRoot
      v-for="(color, i) in colors"
      :key="i"
      :model-value="color"
      alpha
      class="flex size-10 cursor-pointer items-center justify-center rounded-lg"
      @click="selected = color"
    >
      <Check
        class="
          size-5 text-white drop-shadow-[0_1px_2px_rgba(0,0,0,0.5)]
          transition-opacity duration-150
        "
        :class="selected === color ? 'opacity-100' : 'opacity-0'"
      />
    </ColorSwatchRoot>
  </div>
</template>

API Reference

ColorSwatchRoot

Renders a color preview with an automatic checkerboard background. Extends reka-ui's PrimitiveProps.

The Vue swatch is presentational only. It has no pressed state and no toggle behaviour. Selection lives in ColorSwatchPicker, whose ColorSwatchPickerItemSwatch wraps this component and feeds it the item's color.

PropTypeDefaultDescription
modelValueColor | string | nullThe color value to display.
checkerSizenumber16The checkerboard tile size in pixels.
alphabooleanfalseWhen true, reflects the color's alpha channel. When false, displays the color as fully opaque.
labelstringAutoAccessible name for the swatch. Falls back to the resolved color string, then "transparent".
asstring'div'The element or component to render as.
asChildbooleanfalseMerge props onto the single child instead of rendering an element.

TIP

modelValue is a plain prop, not a two-way binding. The swatch never writes back, so :model-value="color" is the idiomatic form and v-model would have nothing to update.

Slots

SlotPayloadDescription
default{ color: string; alpha: number }Rendered inside the swatch, e.g. a selection checkmark. color is the same string as --urcolor-swatch-color; alpha is the color's alpha, or 1 when there is no color.

Data Attributes

AttributePresent when
data-no-colorThere is no color, or the color is fully transparent. Either way nothing is visible.

CSS Variables

The component exposes CSS custom properties on the root element for advanced styling:

VariableDescription
--urcolor-swatch-colorThe painted color, honouring alpha. transparent when there is no color.
--urcolor-swatch-color-opaqueThe same color forced to alpha 1.
--urcolor-swatch-alphaThe color's alpha channel, 1 when there is no color.
--urcolor-swatch-checkerboardThe transparency grid painted under the color.
--urcolor-swatch-backgroundThe composited background, built from the four above.

All five are always emitted, including when the value is absent or unparseable, so your styling never has to guard for a missing variable. The unprefixed --swatch-color, --swatch-color-opaque, --swatch-alpha and --swatch-checkerboard are still emitted as aliases of their replacements and are deprecated.

The grid itself reads three further properties, and no component writes them, so a rule anywhere above the element wins:

VariableDefaultDescription
--urcolor-checkerboard-darkrgb(230, 230, 230)The darker of the two checks.
--urcolor-checkerboard-lightwhiteThe lighter of the two checks.
--urcolor-checkerboard-size16pxThe tile size. checkerSize writes it inline, which beats a stylesheet.

Accessibility

ColorSwatch is a purely visual element that displays a color preview. It is not focusable and handles no keyboard input.

ARIA Labels

AttributeDescription
role="img"Identifies the swatch as a presentational image for screen readers.
aria-roledescriptionAlways "color swatch", so the role is announced in the component's own terms.
aria-labelThe label prop when given, otherwise the resolved color string, otherwise "transparent".

Keyboard Navigation

The swatch has no keyboard behaviour of its own. It is not a tab stop and handles no keys. For a keyboard-navigable set of selectable swatches, use ColorSwatchPicker, which owns roving focus and selection.

KeyAction
None. The swatch is not focusable.