@exmg/exm-color-picker
v2.0.19
Published
Material 3 styled color picker components built with [Lit](https://lit.dev) and [@material/web](https://material-web.dev/). The package contains a standalone color picker panel, two form associated input variants and the internal building blocks they are
Readme
<exm-color-picker> 
@exmg/exm-color-picker
Material 3 styled color picker components built with Lit and @material/web. The package contains a standalone color picker panel, two form associated input variants and the internal building blocks they are composed of.
Installation
bun add @exmg/exm-color-pickerPeer dependencies: lit, @exmg/lit-base.
Example Usage
Color picker panel
<exm-color-picker
value="#123456"
label="Text color"
trailing-icon="border_color"
></exm-color-picker>With swatches (the swatches property is an array and must be set from JavaScript):
<script type="module">
import '@exmg/exm-color-picker/exm-color-picker.js';
const picker = document.querySelector('exm-color-picker');
picker.swatches = ['#00ff00', '#0000ff'];
</script>Form associated input variants
The outlined and filled variants render a text field that opens the color picker in a menu. They are
form associated: name and value participate in FormData and support constraint validation.
<form>
<exm-outlined-color-picker
name="text-color"
label="Text Color"
required
supporting-text="Choose a color."
value="#123456"
></exm-outlined-color-picker>
<exm-filled-color-picker
name="background-color"
label="Background Color"
value="#123456"
></exm-filled-color-picker>
<button type="submit">Submit</button>
</form>Saturation / lightness surface and hue slider
These are the building blocks of the picker panel and can be used standalone:
<exm-saturation-lightness-picker hue="180" saturation="100" lightness="50"> </exm-saturation-lightness-picker>
<exm-hui-slider value="180"></exm-hui-slider>API
<exm-color-picker>
The full color picker panel: a saturation/lightness surface, a hue slider, a hex input field and an optional swatch bar with confirm/cancel actions.
Properties/Attributes
| Name | Type | Default | Description |
| ----------------------- | ---------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| value | string | None | The selected color as a hex string, for example #123456. Parsed into hue/saturation/lightness state when the attribute changes. |
| label | string | None | Label of the hex input field. |
| trailingIcon | string | None | Material icon name shown as trailing icon of the hex input field. Attribute: trailing-icon. |
| swatches | string[] | [] | Hex colors rendered as clickable swatches below the hex input field. Property only (array), no corresponding attribute. |
Note: after selecting a color through the picker surface, the hue slider or a swatch, the value is
stored without the # prefix (for example 00ff00); the hex input field stores the value exactly
as typed. Both formats are accepted as input.
Methods
| Name | Description |
| ------------------ | ----------------------------------------------------------------------------------------------- |
| triggerRerender() | Recalculates the saturation/lightness handle position. Call when the picker becomes visible, for example when rendered inside a menu that was closed while hidden. |
Events
| Name | Detail | Description |
| -------------- | ----------------- | ---------------------------------------------------------------------- |
| color-change | string (value) | Fired when the OK button is clicked. Bubbles. |
| color-cancel | string (value) | Fired when the Close button is clicked. Bubbles. |
<exm-outlined-color-picker> / <exm-filled-color-picker>
Text field variants that open the color picker in a menu. Both share the same API and differ only in the Material text field style. The value and validity are synced with the surrounding form.
Properties/Attributes
| Name | Type | Default | Description |
| ----------------- | --------- | ------------- | ------------------------------------------------------------------------------ |
| value | string | '#aaffcc' | The color value as a hex string. |
| name | string | None | Form control name used when submitting the surrounding form. |
| label | string | 'Select Color' | Label of the text field. |
| pickerLabel | string | 'HEX' | Label passed to the hex input field inside the picker. Attribute: picker-label. |
| supportingText | string | '' | Supporting text below the text field. Attribute: supporting-text. |
| trailingIcon | string | 'colors' | Material icon name of the button that toggles the picker menu. Attribute: trailing-icon. |
| showSwatch | boolean | true | Shows a color swatch as leading icon of the text field. Attribute: show-swatch. |
| disabled | boolean | false | Disables the input and the picker toggle. Reflected to the disabled attribute. |
| required | boolean | false | Marks the form control as required. Attribute: required. |
Methods
| Name | Description |
| ----------------- | ------------------------------------------------------------------------------------------------------- |
| checkValidity() | Returns whether the current value satisfies the constraints (required, hex pattern). |
| reportValidity() | Reports validity and clears the error state on the text field when valid. |
| validate() | Recomputes the validity state and syncs it with the text field. |
Events
| Name | Detail | Description |
| -------- | ---------------- | ------------------------------------------------------------------------- |
| change | string (value) | Fired when a color is confirmed in the picker or entered in the field. |
Validation: the value must consist of 3 to 6 hexadecimal characters, otherwise the control is
invalid with the message Please enter a valid color code like: ff452a.
<exm-saturation-lightness-picker>
A saturation/lightness surface. The handle can be dragged and repositions when clicking anywhere in
the container; the position is kept in sync with the saturation and lightness attributes.
Properties/Attributes
| Name | Type | Default | Description |
| ------------ | -------- | ------- | ----------------------------------------------- |
| hue | number | 0 | Hue angle in degrees, 0-360. |
| saturation | number | 100 | Saturation percentage, 0-100 (HSL). |
| lightness | number | 100 | Lightness percentage, 0-100 (HSL). |
Events
| Name | Detail | Description |
| ------------------ | ------------------------------------------------- | ----------------------------------------------------------------------- |
| sat-light-change | { hue, saturation, lightness } (number values) | Fired when the handle position or the hue changes. |
CSS Custom Properties
The component keeps the following custom properties on itself in sync with its state; they can be used to theme the surface and handle:
| Name | Example | Description |
| ---------------------- | ---------- | ------------------------------------ |
| --picker-hue | 180deg | Current hue angle. |
| --picker-saturation | 50% | Current HSL saturation. |
| --picker-lightness | 50 | Current HSL lightness (0-100). |
<exm-hui-slider>
A hue slider based on the Material 3 Slider, preset to a 0-360 degree range with step 1. The slider
nub color follows the selected hue through the --nub-color custom property (for example 180deg).
Testing
The package is tested with Vitest and jsdom. From the repository root:
bun run testor scoped to this package:
cd packages/exm-color-picker
bun run testRequires Node >= 22. The test setup (src/test-setup.ts) stubs the jsdom gaps (pointer capture,
ElementInternals and ResizeObserver); component geometry is mocked in the tests themselves since
jsdom performs no layout.
