Blocks

Color Picker

A hex color picker with HSL, RGB or HSV channel controls and optional preset swatches.

Installation

pnpm dlx @mielui/svelte add color-picker

Usage

Compose Root, Trigger and Content. Bind value to a six-digit hex string with its leading hash, such as #5e6ad2. Shorthand hex, named colors and other color formats are not parsed.

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

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

<ColorPicker.Root bind:value label="Accent color">
    <ColorPicker.Trigger />
    <ColorPicker.Content />
</ColorPicker.Root>

label prints a visible label above the trigger and names the trigger and panel. Give each picker a distinct label when several appear together. The hex field and every channel have accessible names, and the channel sliders are a keyboard alternative to the plane. Hue changes keep zero saturation, so raise saturation to see the hue.

Examples

Custom composition

Content defaults to Plane, Preview, Hue, HexInput, Channels, and Presets. Supply children to omit, reorder, or style those same parts. Every part reads one shared color state from Root. Here, presets come first and the plane and hue strip are omitted. Channels uses the Root format; Presets uses its options.

Default

Channel formats

format picks the channel sliders: HSL, RGB or HSV. The value stays a hex string.

With preset swatches

Glass surface

Set surface="glass" on Content for a translucent panel with blur, or surface="solid" for an opaque one. Without surface, the panel follows the theme. Glass falls back to an opaque panel when backdrop filtering is unavailable or reduced transparency is on.

Panel behavior

In browsers with the EyeDropper API, currently Chrome and Edge on desktop, the hex field shows a pipette button that picks a color from anywhere on screen. Other browsers do not show the button. Content shares its panel with Popover. A press outside closes the picker unless you set allowClickOutside={false}. dismissLayer={false} removes the invisible layer that catches the first outside press. focusTrap and lockScroll decide whether Tab and page scrolling are held while it is open.

portal={false} renders the panel in place, which you need when the picker sits inside a dialog that traps focus. refElement anchors it to another element. role and tabindex set the panel's ARIA role and tab index, and surfaceClass styles the inner surface while class styles the frame.

Labels

Built-in text is English. Pass a ColorPickerLabels object to labels on Root to translate the trigger text shown before a color is chosen, and the names of the panel, the hex input, the screen color button, and each slider and channel. trigger is a function of Root's label and the color, so a translation can reorder them. Every key is optional, and an omitted key keeps its English default.

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

    const labels: ColorPickerLabels = {
        choose: 'Choisir une couleur',
        picker: 'Sélecteur de couleur',
        hex: 'Couleur hexadécimale',
        eyedropper: 'Prélever une couleur',
        trigger: (label, color) => `${label} : ${color}`,
        hue: 'Teinte',
        saturation: 'Saturation',
        lightness: 'Luminosité',
        brightness: 'Valeur',
        red: 'Rouge',
        green: 'Vert',
        blue: 'Bleu'
    };

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

<ColorPicker.Root bind:value {labels}>
    <ColorPicker.Trigger />
    <ColorPicker.Content />
</ColorPicker.Root>

API reference

ColorPicker.Root

Controls color picker state.

  • labels
    ColorPickerLabels

    Overrides the built-in text and accessible names. Every key is optional and English is the fallback.

  • label
    string

    Accessible name of the trigger.

  • value Bindable
    string

    Selected color as a hex string. Bindable.

    Default ''

  • onValueChange
    ((value: string) => void)

    Called with the new value when it changes.

  • options
    ColorOption[]

    Preset swatches offered at the bottom of the panel.

    Default []

  • format
    ColorFormat

    Channel controls to show: HSL, RGB, or HSV.

    Default 'hsl'

  • children
    Snippet<[]>

    Content rendered inside.

  • class
    string

    Classes added to the element.

ColorPicker.Content

Renders color selection controls.

  • class
    (string & (ClassValue | null))

    Classes added to the element.

  • tabindex
    number

    Tab index of the panel.

  • role
    "dialog" | "alertdialog" | "menu" | "listbox" | "none"

    ARIA role of the panel.

  • surface
    "solid" | "glass"

    Surface treatment. Omit it to inherit --mielui-surface from the theme.

  • surfaceClass
    string

    Classes for the inset surface (where children live) — padding, layout, background overrides. The class prop styles the outer Panel frame.

  • allowClickOutside
    boolean

    Closes when the pointer is pressed outside it. Set false to keep it open until it is dismissed another way.

  • dismissLayer
    boolean

    Render the full-viewport dismiss layer under the panel while open. Defaults to true. Set to false for triggers that must stay clickable while open (e.g. an input-style combobox trigger); outside pointer dismissal still applies via allowClickOutside.

  • portal
    boolean

    Moves the panel to the end of the document so ancestors cannot clip it. Set false to render it in place.

  • refElement
    VirtualElement

    Positions the panel against this element or virtual element instead of the trigger. The panel then opens to the right of it, as a submenu does.

  • focusTrap
    boolean

    Trap Tab focus inside the panel while open. Defaults to true.

  • lockScroll
    boolean

    Lock document scrolling while the panel is open. Defaults to true.

  • children
    Snippet<[]>

    Content rendered inside.

ColorPicker.Trigger

Opens the color picker.

  • variant
    "outline" | "secondary" | "ghost"

    Trigger style -- matches Button variants. Defaults to outlined.

    Default 'outline'

  • class
    string

    Classes added to the element.

Other parts

These parts have no props of their own. They pass HTML attributes and events to their element.

  • ColorPicker.Channels
  • ColorPicker.HexInput
  • ColorPicker.Hue
  • ColorPicker.Plane
  • ColorPicker.Presets
  • ColorPicker.Preview