# Color picker

> Choose any color with a saturation and brightness area, a hue slider and a hex field, over a native color input.

## Anatomy

Write a `.color-picker` with `role="group"` and a name around an `<input type="color">`. Without JavaScript it is the native swatch.

AutoInit starts `ColorPicker`, which adds a saturation and brightness area, a hue slider and a hex field. The native input stays the form value and the preview. The browser's own picker still opens from it. The browser's color input only holds `#rrggbb`, so there is no alpha.

```
<div class="color-picker" role="group" aria-label="Accent color">
  <input type="color" name="accent" value="#6750a4" aria-label="Accent color">
</div>
```

## Keyboard

The area is one slider. Its value is read out as, for example, "Saturation 60%, brightness 80%". It does not mirror in right-to-left pages, because it is the color itself.

Safari leaves the native color swatch out of the Tab order, as it does for every `<input type="color">`. In Safari the area, the hue slider and the hex field still set any color from the keyboard. Only the system color dialog is out of reach.

| Key | Effect |
| --- | --- |
| Left, Right | Saturation down or up by 1%; with Shift, 10% |
| Up, Down | Brightness up or down by 1%; with Shift, 10% |
| Page Up, Page Down | Brightness up or down by 10% |
| Home, End | No saturation or full saturation |

The hue slider is the framework's range input, with its usual keys. In the hex field, Enter applies the value instead of submitting the form, and an invalid value goes back to the current color.

## Events

Every change writes the native input and fires its `input` event. A committed change, such as a released drag, a key press, a released hue or an applied hex value, also fires `change`. Listeners written for the native input keep working.

```
el.querySelector('input[type="color"]').addEventListener('input', (e) => {
  preview.style.background = e.target.value; // live, during a drag
});
```

## Tokens

Override these on the `.color-picker`.

| Token | Default |
| --- | --- |
| `--md-comp-color-picker-width` | 280px |
| `--md-comp-color-picker-area-height` | 160px |
| `--md-comp-color-picker-area-shape` | `--md-sys-shape-corner-medium` |
| `--md-comp-color-picker-thumb-size` | 24px |
| `--md-comp-color-picker-field-shape` | `--md-sys-shape-corner-extra-small` |

## Options

| Name | Type | Default | Description |
| --- | --- | --- | --- |
| `onChange` | Function | `null` | Called with the new `#rrggbb` value when a change is committed. For live updates, listen for `input` on the native input. |

## Methods

> All methods are called on the plugin instance. You can get the instance like this:

```
const instance = Expressive.ColorPicker.getInstance(elem);
```

```
instance.destroy(); // removes the area, hue slider and hex field; the native input stays
```

## Properties

| Name | Type | Description |
| --- | --- | --- |
| `el` | Element | The `.color-picker` element. |
| `options` | Object | The options the instance was initialized with. |
| `input` | Element | The native color input. |
| `value` | String | The current `#rrggbb` color. Setting it updates the picker and the input without firing events. |
