Color Picker

The trigger opens a popover with a color area, hue strip, hex field, and channel sliders. Edits come back as a lowercase hex string.

<script lang="ts">
    import * as ColorPicker from '@sivir-ui/svelte/components/color-picker';

    let color = $state('#5e6ad2');
</script>

<ColorPicker.Root value={color} onValueChange={(v) => (color = v)}>
    <ColorPicker.Trigger />
    <ColorPicker.Content />
</ColorPicker.Root>

Installation

Copy the command below and run it in your terminal.

bunx @sivir-ui/svelte add color-picker

Usage

Bind value on Root, or pass value with onValueChange. format picks the slider set: hsl (default), rgb, or hsv.

import * as ColorPicker from '@sivir-ui/svelte/components/color-picker';

let value = $state('#5e6ad2');

<ColorPicker.Root bind:value format="hsl">
	<ColorPicker.Trigger />
	<ColorPicker.Content />
</ColorPicker.Root>

Opening the picker focuses the color area, not the hex field. Arrow keys move the color area and hue strip, and Shift moves them in steps of 10. In browsers that support the EyeDropper API, the pipette button in the hex field picks a color from anywhere on screen.

Examples

Default

Accent color

<script lang="ts">
    import * as ColorPicker from '@sivir-ui/svelte/components/color-picker';

    let value = $state('#5e6ad2');
</script>

<div class="w-full max-w-sm">
    <ColorPicker.Root {value} onValueChange={(v) => (value = v)} label="Accent color">
        <ColorPicker.Trigger />
        <ColorPicker.Content />
    </ColorPicker.Root>
</div>

Channel formats

HSL

RGB

HSV

<script lang="ts">
    import * as ColorPicker from '@sivir-ui/svelte/components/color-picker';

    let hslValue = $state('#5e6ad2');
    let rgbValue = $state('#5e6ad2');
    let hsvValue = $state('#5e6ad2');
</script>

<div class="flex flex-wrap items-center justify-center gap-4">
    <ColorPicker.Root
        value={hslValue}
        onValueChange={(v) => (hslValue = v)}
        format="hsl"
        label="HSL"
    >
        <ColorPicker.Trigger />
        <ColorPicker.Content />
    </ColorPicker.Root>
    <ColorPicker.Root
        value={rgbValue}
        onValueChange={(v) => (rgbValue = v)}
        format="rgb"
        label="RGB"
    >
        <ColorPicker.Trigger />
        <ColorPicker.Content />
    </ColorPicker.Root>
    <ColorPicker.Root
        value={hsvValue}
        onValueChange={(v) => (hsvValue = v)}
        format="hsv"
        label="HSV"
    >
        <ColorPicker.Trigger />
        <ColorPicker.Content />
    </ColorPicker.Root>
</div>

With preset swatches

Label color

<script lang="ts">
    import type { ColorOption } from '@sivir-ui/svelte/components/color-picker';
    import * as ColorPicker from '@sivir-ui/svelte/components/color-picker';

    let valueWithOptions = $state('#0284c7');

    const presetSwatches: ColorOption[] = [
        { label: 'Blue', value: '#2563eb' },
        { label: 'Indigo', value: '#4f46e5' },
        { label: 'Violet', value: '#7c3aed' },
        { label: 'Pink', value: '#db2777' },
        { label: 'Rose', value: '#e11d48' }
    ];
</script>

<div class="flex items-center justify-center">
    <ColorPicker.Root
        value={valueWithOptions}
        onValueChange={(v) => (valueWithOptions = v)}
        options={presetSwatches}
        label="Label color"
    >
        <ColorPicker.Trigger />
        <ColorPicker.Content />
    </ColorPicker.Root>
</div>

Anatomy

ColorPicker.Root - Controls color picker state.

ColorPicker.Trigger - Opens the color picker.

ColorPicker.Content - Renders color selection controls.