ColorRing
A circular ring component for adjusting a single color channel along a circular arc.
Preview
Source code
tsx
import "internationalized-color/css";
import { ColorRing, useColor } from "@urcolor/react";
export default function ColorRingHue() {
const { color, setColor, hex } = useColor("hsl(210, 80%, 50%)");
return (
<>
<code>{hex}</code>
<ColorRing.Root
value={color}
onValueChange={setColor}
colorSpace="hsl"
channel="h"
innerRadius={0.85}
className="relative block size-64"
style={{ containerType: "inline-size" }}
>
<ColorRing.Track className="relative block size-full">
<ColorRing.Gradient className="absolute inset-0 block" />
<ColorRing.Thumb
className="
size-4 rounded-full border-2 border-white
shadow-[0_0_0_1px_rgba(0,0,0,0.3),0_2px_4px_rgba(0,0,0,0.3)]
focus-visible:shadow-[0_0_0_1px_rgba(0,0,0,0.3),0_0_0_3px_rgba(66,153,225,0.6)]
"
/>
</ColorRing.Track>
</ColorRing.Root>
</>
);
}Anatomy
tsx
<ColorRing.Root>
<ColorRing.Track>
<ColorRing.Checkerboard />
<ColorRing.Gradient />
<ColorRing.Thumb />
</ColorRing.Track>
</ColorRing.Root>Examples
Hue
Hue ring slider for cycling through the color spectrum.
Source code
tsx
import "internationalized-color/css";
import { ColorRing, useColor } from "@urcolor/react";
export default function ColorRingHue() {
const { color, setColor, hex } = useColor("hsl(210, 80%, 50%)");
return (
<>
<code>{hex}</code>
<ColorRing.Root
value={color}
onValueChange={setColor}
colorSpace="hsl"
channel="h"
innerRadius={0.85}
className="relative block size-64"
style={{ containerType: "inline-size" }}
>
<ColorRing.Track className="relative block size-full">
<ColorRing.Gradient className="absolute inset-0 block" />
<ColorRing.Thumb
className="
size-4 rounded-full border-2 border-white
shadow-[0_0_0_1px_rgba(0,0,0,0.3),0_2px_4px_rgba(0,0,0,0.3)]
focus-visible:shadow-[0_0_0_1px_rgba(0,0,0,0.3),0_0_0_3px_rgba(66,153,225,0.6)]
"
/>
</ColorRing.Track>
</ColorRing.Root>
</>
);
}Saturation
Saturation ring slider for adjusting color intensity.
Source code
tsx
import "internationalized-color/css";
import { ColorRing, useColor } from "@urcolor/react";
export default function ColorRingSaturation() {
const { color, setColor, hex } = useColor("hsl(210, 80%, 50%)");
return (
<>
<code>{hex}</code>
<ColorRing.Root
value={color}
onValueChange={setColor}
colorSpace="hsl"
channel="s"
innerRadius={0.85}
className="relative block size-64"
style={{ containerType: "inline-size" }}
>
<ColorRing.Track className="relative block size-full">
<ColorRing.Gradient className="absolute inset-0 block" />
<ColorRing.Thumb
className="
size-4 rounded-full border-2 border-white
shadow-[0_0_0_1px_rgba(0,0,0,0.3),0_2px_4px_rgba(0,0,0,0.3)]
focus-visible:shadow-[0_0_0_1px_rgba(0,0,0,0.3),0_0_0_3px_rgba(66,153,225,0.6)]
"
/>
</ColorRing.Track>
</ColorRing.Root>
</>
);
}API Reference
ColorRing.Root
The root container that manages ring state and color channel binding.
| Prop | Type | Default | Description |
|---|---|---|---|
value | Color | string | null | — | Controlled color value. |
defaultValue | Color | string | 'hsl(0, 100%, 50%)' | Initial color when uncontrolled. |
colorSpace | string | 'hsl' | Color space mode (e.g. 'hsl', 'oklch'). |
channel | string | Auto | Channel to control. Auto-derived from color space. |
startAngle | number | 0 | Starting angle offset in degrees. |
innerRadius | number | 0.7 | Inner radius ratio (0–1) controlling ring thickness. |
disabled | boolean | false | Disables interaction. |
onValueChange | (color: Color) => void | — | Called when color changes. |
onValueCommit | (color: Color) => void | — | Called when interaction ends. |
ColorRing.Track
The track container that holds the gradient, checkerboard, and thumb.
ColorRing.Gradient
Renders a ring gradient canvas for the track.
| Prop | Type | Default | Description |
|---|---|---|---|
channelOverrides | Record<string, number> | false | { alpha: 1 } | Lock specific channels to fixed values in the gradient. |
ColorRing.Checkerboard
Renders a checkerboard pattern behind the gradient to visualize alpha transparency.
ColorRing.Thumb
The draggable thumb element positioned along the ring arc.
Accessibility
ColorRing provides a circular slider interface for adjusting a single color channel with full keyboard support.
Keyboard Navigation
| Key | Action |
|---|---|
| Arrow Right / Arrow Up | Increase by one step |
| Arrow Left / Arrow Down | Decrease by one step |
| Shift + Arrow | Move by 10 steps |
| Page Up | Increase by 10 steps |
| Page Down | Decrease by 10 steps |
| Home | Move to minimum |
| End | Move to maximum |