ColorPicker

ColorPicker is a form field for one color. The user moves a thumb in the square, moves a slider, writes a hex text, or takes a color from the screen. The color is held as hue, saturation and brightness, and the value that goes out is text.

Brand color

Anatomy

ColorPicker.Root holds the color. ColorPicker.Area is the square of two channels, with ColorPicker.AreaThumb in it. ColorPicker.Slider is the track of one channel, with ColorPicker.SliderThumb in it.

ColorPicker.HexField is the color as text. ColorPicker.ChannelField is one channel as a number. ColorPicker.SwatchList holds the ColorPicker.Swatch elements. ColorPicker.Preview shows the color, and ColorPicker.EyeDropper takes one from the screen.

<script>
	import { ColorPicker } from '@human-kit/ui';
</script>

<ColorPicker.Root name="brand" defaultValue="#3366cc">
	<ColorPicker.Label>Brand color</ColorPicker.Label>
	<ColorPicker.Area>
		<ColorPicker.AreaThumb />
	</ColorPicker.Area>
	<ColorPicker.Slider channel="hue">
		<ColorPicker.SliderThumb />
	</ColorPicker.Slider>
	<ColorPicker.HexField />
	<ColorPicker.Preview />
</ColorPicker.Root>

Value

Use bind:value to give the root your state. Use value with onChange and controlledValue to hold the state yourself. The root then reports each change, and it does not write value back.

The value is text. A hex color, rgb(), hsl() and hsb() all come in, and format decides what goes out: hex, rgb, hsl or hsb. A text that names no color leaves the color that is there.

onChange runs on each change, also on each move of a drag. onChangeEnd runs when a sequence of changes ends: at the release of a key, and at the end of a drag.

The model of the color

The color is held as hue, saturation and brightness. The square keeps its shape at each hue in that model, and it does not in red-green-blue.

A black and a gray say nothing about the hue. The picker keeps the hue that was there. The thumb in the square stays where the user left it, and the hue slider does not jump back to red.

The square and the sliders

ColorPicker.Area is the saturation against the brightness. The vertical axis counts from the bottom: white is at the top left corner, and black is at the bottom. Give xChannel and yChannel for two other channels.

ColorPicker.Slider moves one channel: hue, saturation, brightness, lightness, alpha, red, green or blue. Give orientation="vertical" for a track that goes up.

The arrows step, Shift with an arrow moves a large step, and Home and End go to the ends. The horizontal arrows follow the text direction. The hue is a circle: one step past red comes back to red.

Alpha

Give alpha for a color with an alpha, and a ColorPicker.Slider with channel="alpha". The value then holds the fourth number: #3366cc80 in hex, and rgba(51, 102, 204, 0.5) in rgb.

Without alpha the text holds only the three color channels. A picker with no alpha slider must not answer a number nobody can change.

Overlay

rgba(51, 102, 204, 0.75)

The fields

ColorPicker.HexField reads its text at Enter and when the focus leaves. What the user writes stays in the field until then, thus a half written color is not read on each key. A text that names no color goes back to the color of the picker.

ColorPicker.ChannelField is a native number field with the limits and the step of its channel. Red goes from 0 to 255, the hue from 0 to 360, and the alpha from 0 to 1.

Exact color

Swatches and the eye dropper

ColorPicker.SwatchList is a listbox, and each ColorPicker.Swatch in it is an option. One swatch is in the tab order, the arrows move between them, and Enter or the space bar takes the color. A swatch outside a list shows a color and answers nothing.

ColorPicker.EyeDropper opens the eye dropper of the browser, and the color of the press becomes the color of the picker. A browser without it gets data-unsupported, which your CSS can hide. Test for it before you make it the one way to choose a color.

The browser takes up to two seconds to paint its eye dropper, because it must first read the screen. Give data-open a style of its own: the button carries it, and aria-busy, from the press until the color arrives. Without that style the button does not move, and the reader presses it again.

Label color

Style

The picker paints nothing of its own. These custom properties give your CSS what it needs:

  • --color-picker-value on the root: the color, with its alpha.
  • --color-picker-hue and --color-picker-hue-color: the hue as a number, and as the color at full saturation and brightness. The square is two gradients over that color.
  • --color-picker-area-x and --color-picker-area-y on the area: the position of the thumb, in percent.
  • --color-picker-slider-start, --color-picker-slider-end and --color-picker-slider-percent on a slider: the two ends of its channel in the color of now, and the position of its thumb.
  • --color-picker-swatch-color on a swatch and on the preview.

Forms

Give name for the color of the field. The root renders a hidden input with the text of the color, and a <form> reset takes the first color back. invalid marks the color as wrong.

API reference

Root

The color, and the context of each control. It renders a div with role="group", named by ColorPicker.Label, and it carries the color in --color-picker-value.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-alpha Present while the picker holds an alpha.
data-color-picker-root
data-color-picker-value
data-disabled Present while the picker is disabled.
data-format The text format of the value: "hex", "rgb", "hsl" or "hsb".
data-invalid Present while the color is invalid.
data-readonly Present while the picker is read-only.

Label

The accessible name of the picker. It renders a span, and the root points at it with aria-labelledby.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-color-picker-label
data-disabled Present while the picker is disabled.

Area

The square of two channels. A press in it moves the thumb there and starts a drag. It is position: relative, and it carries the position of the thumb in --color-picker-area-x and --color-picker-area-y.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-color-picker-area
data-disabled Present while the picker is disabled.
data-dragging Present while a pointer moves the thumb.
data-readonly Present while the picker is read-only.
data-x-channel The channel of the horizontal axis.
data-y-channel The channel of the vertical axis.

AreaThumb

The handle of the square. It renders a div at a position in percent, with two native sliders in it: one for each axis. The inputs have the focus and the ARIA state.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-axis The axis of one native input: "x" or "y".
data-color-picker-area-input
data-color-picker-area-thumb
data-disabled Present while the picker is disabled.
data-dragging Present while a pointer moves the thumb.
data-focus-visible Present while the focus on the thumb must be visible (keyboard modality).
data-focused Present while one of the two inputs has the focus.
data-readonly Present while the picker is read-only.

Slider

The track of one channel. A press on it moves the thumb there and starts a drag. It carries the two ends of the channel in --color-picker-slider-start and --color-picker-slider-end.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-channel The channel of the slider.
data-color-picker-slider
data-disabled Present while the picker is disabled.
data-dragging Present while a pointer moves the thumb.
data-orientation The orientation: "horizontal" or "vertical".
data-readonly Present while the picker is read-only.

SliderThumb

The handle of one channel. It renders a div at a position in percent, with a native slider in it. The input has the focus and the ARIA state.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-channel The channel of the slider.
data-color-picker-slider-input
data-color-picker-slider-thumb
data-disabled Present while the picker is disabled.
data-dragging Present while a pointer moves the thumb.
data-focus-visible Present while the focus on the thumb must be visible (keyboard modality).
data-focused Present while the native input has the focus.
data-orientation The orientation: "horizontal" or "vertical".
data-readonly Present while the picker is read-only.

HexField

The color as a hex text. It renders a native text input, and it reads the text at Enter and when the focus leaves.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-color-picker-hex-field
data-disabled Present while the picker is disabled.
data-focused Present while the field has the focus.
data-invalid Present while the color is invalid.
data-readonly Present while the picker is read-only.

ChannelField

One channel as a number. It renders a native number input with the limits and the step of that channel.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-channel The channel of the field.
data-color-picker-channel-field
data-disabled Present while the picker is disabled.
data-focused Present while the field has the focus.
data-invalid Present while the color is invalid.
data-readonly Present while the picker is read-only.

SwatchList

A set of colors to choose from. It renders a div with role="listbox", and each ColorPicker.Swatch in it is an option.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-color-picker-swatch-list
data-disabled Present while the picker is disabled.
data-readonly Present while the picker is read-only.

Swatch

One color to choose. In a list it is an option with role="option". Outside a list it shows a color and answers nothing. The color is in --color-picker-swatch-color.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-color The color of the swatch, as the consumer wrote it.
data-color-picker-swatch
data-disabled Present while the picker is disabled.
data-focus-visible Present while the focus on the swatch must be visible (keyboard modality).
data-focused Present while the swatch has the focus.
data-selected Present while the color of the swatch is the color of the picker.

Preview

The color of now. It renders a div with the color in --color-picker-swatch-color, and it has no name and no role.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-color The text of the color, in the format of the root.
data-color-picker-preview
data-disabled Present while the picker is disabled.

EyeDropper

Takes a color from the screen. It renders a button that opens the eye dropper of the browser.

Prop Type Default

* required. Native HTML attributes of the underlying element are also accepted.

Data attribute Description
data-color-picker-eye-dropper
data-disabled Present while the picker is disabled.
data-open Present while the eye dropper of the browser is open. The browser takes up to two seconds to paint it, thus this attribute is what tells the reader that the press did something.
data-unsupported Present while the browser has no eye dropper.