Skip to content

Commit e11232a

Browse files
committed
feat: make the color picker a form-associated custom element
Make the color picker a form-associated custom element via the ElementInternals API. This allows the color picker to participate in forms as a form control and contribute a form value on form submission. Additionally, on form reset, the color picker's form value is reset to the value of the `value` content attribute. The `value` content attribute, `defaultValue` IDL attribute, and `value` IDL attribute are implemented to match the behavior of native HTML form controls. Add the `value` IDL attribute. The getter returns a string formatted as a CSS RGB color (e.g. `'rgb(127.5 0 255 / 0.8)'`). This is also the value used in form submission. The setter accepts any valid CSS color string (including named colors) or any of the color picker's internal color object formats (e.g. `{ r: 127.5, g: 0, b: 255, a: 0.8 }`). Add the `defaultValue` IDL and `value` content attribute. Sets the default value used on form reset. Also sets the `value` IDL attribute as long as the user hasn't change the color. Add the `disabled` IDL and content attribute. Disabling the color picker will render it completely inert. All containing form controls and buttons will be disabled and the color picker thumb won't respond to interactions. An ancestor `fieldset` element which is disabled will also render the color picker disabled. Add the `readOnly` IDL and `readonly` content attribute. Setting the color picker to read-only will prevent the user from changing the color. Add the `required` IDL and content attribute. Add the `input` and `change` events. They are fired whenever the user changes the color. Note, that there is currently no scenario in which only the `input` but not the `change` event is fired. BREAKING CHANGE: Remove the content attribute `color`. **How to update**: Use the `value` content attribute or the `defaultValue` IDL attribute instead. BREAKING CHANGE: Remove the IDL attribute `color`. **How to update**: Use the `value` IDL attribute instead. BREAKING CHANGE: Remove the IDL attribute `colors`. **How to update**: Use the event data of the `color-change` event instead.
1 parent 1de875b commit e11232a

15 files changed

+957
-329
lines changed

README.md

Lines changed: 129 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
A color picker web component.
66

7-
This package’s files are distributed in the ES module format and have not been transpiled. It uses [lit-html](https://www.npmjs.com/package/lit-html).
7+
- Form-associated custom element (i.e. it works in forms via the [ElementInternals API](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals))
8+
- Distributed is ES module format
9+
- Not transpiled
10+
- Uses [lit-html](https://www.npmjs.com/package/lit-html) (as a peer dependency)
811

912
Links:
1013

@@ -21,17 +24,23 @@ Links:
2124
- [As npm package](#as-npm-package)
2225
- [As plain files directly in the browser (no build step)](#as-plain-files-directly-in-the-browser-no-build-step)
2326
- [Documentation](#documentation)
24-
- [Properties](#properties)
27+
- [Attributes](#attributes)
2528
- [`alphaChannel`](#alphachannel)
26-
- [`color`](#color)
29+
- [`defaultValue`](#defaultvalue)
30+
- [`disabled`](#disabled)
2731
- [`format`](#format)
2832
- [`id`](#id)
33+
- [`name`](#name)
34+
- [`readOnly`](#readonly)
35+
- [`value`](#value)
2936
- [`visibleFormats`](#visibleformats)
3037
- [Methods](#methods)
3138
- [`copyColor()`](#copycolor)
3239
- [`switchFormat()`](#switchformat)
3340
- [Events](#events)
41+
- [`change`](#change)
3442
- [`color-change`](#color-change)
43+
- [`input`](#input)
3544
- [Theming](#theming)
3645
- [Versioning](#versioning)
3746
- [Contributing](#contributing)
@@ -107,7 +116,7 @@ Links:
107116
1. Download the files.
108117

109118
```sh
110-
curl --remote-name-all 'https://cdn.jsdelivr.net/npm/yet-another-color-picker@latest/dist/ColorPicker.{js,css}'
119+
curl --remote-name-all 'https://cdn.jsdelivr.net/npm/yet-another-color-picker@latest/dist/ColorPicker.{js,css,d.ts}'
111120
```
112121

113122
1. Define an [import map](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script/type/importmap) for lit-html.
@@ -190,19 +199,19 @@ Links:
190199

191200
## Documentation
192201

193-
### Properties
202+
### Attributes
194203

195-
Most of the following properties can also be set via its corresponding attribute.
204+
In the following sections, the web component's [IDL and content attibutes](https://developer.mozilla.org/en-US/docs/Glossary/IDL#content_versus_idl_attributes), are documented.
196205

197-
**Note**: Changing an attribute will be synced to its corresponding property; however, changing a property will *not* be synced to its corresponding attribute.
206+
**Note**: Setting a content attribute will be reflected by its corresponding IDL attribute; however, setting an IDL attribute will *not* be reflected by its corresponding content attribute.
198207

199208
#### `alphaChannel`
200209

201-
- **Description**: Whether to show input controls for a color’s alpha channel. If set to `'hide'`, the alpha range input and the alpha channel input are hidden, the “Copy color” button will copy a CSS color value without alpha channel, and the object emitted in a `color-change` event will have a `cssColor` property value without alpha channel.
210+
- **Description**: Whether to show controls for a color’s alpha channel. If set to `'hide'`, the alpha range input and the alpha channel input are hidden, the “Copy color” button will copy a CSS color value without alpha channel, and the object emitted in a `color-change` event will have a `cssColor` property value without alpha channel.
202211
- **Type**: `'show' | 'hide'`
203212
- **Required**: `false`
204213
- **Default**: `'show'`
205-
- **Attribute**: `alpha-channel`
214+
- **Content attribute**: `alpha-channel`
206215
- **Usage**:
207216

208217
JavaScript:
@@ -215,33 +224,47 @@ Most of the following properties can also be set via its corresponding attribute
215224
<color-picker alpha-channel="hide"></color-picker>
216225
```
217226

218-
#### `color`
227+
#### `defaultValue`
219228

220-
- **Description**: Sets the color of the color picker. You can pass any valid CSS color string.
221-
- **Type**: `string | ColorHsl | ColorHwb | ColorRgb` (for `string`, any valid CSS color string will work)
229+
- **Description**: Set the color picker's current color as long as the color wasn't changed by the user already.
230+
- **Type**: `string`
222231
- **Required**: `false`
223-
- **Default**: `'#ffffffff'`
224-
- **Attribute**: `color`
232+
- **Default**: `''`
233+
- **Content attribute**: `value`
225234
- **Usage**:
226235

227236
JavaScript:
228237
```js
229-
colorPicker.color = 'hsl(270 100% 50% / 0.8)'
238+
colorPicker.defaultValue = 'hsl(270 100% 50% / 0.8)'
230239
```
231240

232-
JavaScript:
233-
```js
234-
colorPicker.color = { h: 270, s: 100, l: 50, a: 0.8 }
241+
HTML:
242+
```html
243+
<color-picker value="hsl(270 100% 50% / 0.8)"></color-picker>
235244
```
236245

237246
HTML:
238247
```html
239-
<color-picker color="hsl(270 100% 50% / 0.8)"></color-picker>
248+
<color-picker value="#f80b"></color-picker>
249+
```
250+
251+
#### `disabled`
252+
253+
- **Description**: Disables the color picker.
254+
- **Type**: `boolean`
255+
- **Required**: `false`
256+
- **Default**: `false`
257+
- **Content attribute**: `disabled`
258+
- **Usage**:
259+
260+
JavaScript:
261+
```js
262+
colorPicker.disabled = true
240263
```
241264

242265
HTML:
243266
```html
244-
<color-picker color="#f80b"></color-picker>
267+
<color-picker disabled></color-picker>
245268
```
246269

247270
#### `format`
@@ -250,7 +273,7 @@ Most of the following properties can also be set via its corresponding attribute
250273
- **Type**: `VisibleColorFormat`
251274
- **Required**: `false`
252275
- **Default**: `'hsl'`
253-
- **Attribute**: `format`
276+
- **Content attribute**: `format`
254277
- **Usage**:
255278

256279
JavaScript:
@@ -265,11 +288,14 @@ Most of the following properties can also be set via its corresponding attribute
265288

266289
#### `id`
267290

268-
- **Description**: The ID value will be used to prefix all `input` elements’ `id` and `label` elements’ `for` attribute values. Make sure to set this if you use multiple instances of the component on a page.
291+
- **Description**: This value will be used to prefix any of the color picker’s form-associated elements’ `id` and `for` attribute values. Make sure to set this if you use multiple instances of the component on a page.
292+
293+
**Note**: The IDL attribute `id` of form-associated elements _is_ reflected by its content attribute.
294+
269295
- **Type**: `string`
270296
- **Required**: `false`
271297
- **Default**: `'color-picker'`
272-
- **Attribute**: `id`
298+
- **Content attribute**: `id`
273299
- **Usage**:
274300

275301
JavaScript:
@@ -282,13 +308,80 @@ Most of the following properties can also be set via its corresponding attribute
282308
<color-picker id="color-picker-1"></color-picker>
283309
```
284310

311+
#### `name`
312+
313+
- **Description**: Name of the color picker (used when the color picker is part of a form).
314+
315+
**Note**: The IDL attribute `name` of form-associated elements _is_ reflected by its content attribute.
316+
317+
- **Type**: `string`
318+
- **Required**: `false`
319+
- **Default**: `''`
320+
- **Content attribute**: `name`
321+
- **Usage**:
322+
323+
JavaScript:
324+
```js
325+
colorPicker.name = 'color-picker'
326+
```
327+
328+
HTML:
329+
```html
330+
<color-picker name="color-picker"></color-picker>
331+
```
332+
333+
#### `readOnly`
334+
335+
- **Description**: Makes the color picker read-only.
336+
- **Type**: `boolean`
337+
- **Required**: `false`
338+
- **Default**: `false`
339+
- **Content attribute**: `readonly`
340+
- **Usage**:
341+
342+
JavaScript:
343+
```js
344+
colorPicker.readonly = true
345+
```
346+
347+
HTML:
348+
```html
349+
<color-picker readonly></color-picker>
350+
```
351+
352+
#### `value`
353+
354+
- **Description**: The current color of the color picker.
355+
356+
The `value` getter will return the current color as a string (formatted as a CSS RGB color, e.g. `'rgb(127.5 0 255 / 0.8)'`). This is also the form value used in form submission.
357+
358+
The `value` setter accepts a `string` (any CSS color works, e.g. `'hsl(270 100% 50% / 0.8)'`) or an `object` (e.g. `{ h: 270, s: 100, l: 50, a: 0.8 }`).
359+
360+
- **Type**: `string | ColorHsl | ColorHwb | ColorRgb` (for `string`, any valid CSS color string will work)
361+
- **Required**: `false`
362+
- **Default**: `'rgb(255 255 255 / 1)'`
363+
- **Content attribute**: None. The `value` IDL attribute doesn't directly reflect a content attribute. However, the `value` IDL attribute does reflect the `defaultValue` IDL attribute as long as the dirty flag isn't set.
364+
- **Usage**:
365+
366+
JavaScript:
367+
```js
368+
colorPicker.value = 'hsl(270 100% 50% / 0.8)'
369+
colorPicker.value
370+
//> 'rgb(127.5 0 255 / 0.8)'
371+
```
372+
373+
JavaScript:
374+
```js
375+
colorPicker.value = { h: 270, s: 100, l: 50, a: 0.8 }
376+
```
377+
285378
#### `visibleFormats`
286379

287380
- **Description**: A list of visible color formats. Controls for which formats the color `input` elements are shown and in which order the formats will be cycled through when activating the format switch button.
288381
- **Type**: `VisibleColorFormat` (an array of `VisibleColorFormat`s)
289382
- **Required**: `false`
290383
- **Default**: `['hex', 'hsl', 'hwb', 'rgb']`
291-
- **Attribute**: `visible-formats`
384+
- **Content attribute**: `visible-formats`
292385
- **Usage**:
293386

294387
JavaScript:
@@ -331,18 +424,22 @@ Most of the following properties can also be set via its corresponding attribute
331424

332425
### Events
333426

427+
#### `change`
428+
429+
- **Description**: The `change` event is fired when the color is changed.
430+
- **Type**: `Event`
431+
334432
#### `color-change`
335433

336-
- **Description**: The custom event that is emitted each time the internal colors object is updated.
434+
- **Description**: The `color-change` event is fired when the color is changed.
337435
- **Type**: `CustomEvent<ColorChangeDetail>`
338-
- **Data**: The custom event emits an object whose `detail` property contains both the internal colors object and a CSS color value as a string based on the currently active format. The `cssColor` property will respect `alpha-channel`.
436+
- **Data**: Emits an object whose `detail` property contains both the internal `colors` object and a CSS color value as a string based on the currently active format. The `cssColor` property respects the `alphaChannel` IDL attribute.
339437

340438
```ts
341439
{
342440
colors: {
343441
hex: string
344442
hsl: ColorHsl
345-
hsv: ColorHsv
346443
hwb: ColorHwb
347444
rgb: ColorRgb
348445
}
@@ -367,6 +464,11 @@ Most of the following properties can also be set via its corresponding attribute
367464
})
368465
```
369466

467+
#### `input`
468+
469+
- **Description**: The `input` event is fired when the color is changed.
470+
- **Type**: `Event`
471+
370472
## Theming
371473

372474
You can customize the GUI of the color picker using CSS custom properties:

0 commit comments

Comments
 (0)