color-controller
NPM 1.9.0
Overview
The ColorController is a comprehensive
Features
- Color management: Manage color values in multiple formats, including RGB, HSL, HSV, and Hex
- Validation: Validate color strings and ensure they conform to expected formats
- Conversion: Convert colors between different color spaces for versatile applications
- State management: Maintain current color state and save/restore previous color values
- Format preservation: Automatically preserve the format of the original color input when returning values
Properties
color: Gets or sets the current color value. The color can be provided in various formats, including strings, objects, or instances of theColorclass.colorValue: Gets the color value in various formats based on the original color input.hue: Gets or sets the hue value of the current color.
Methods
-
validateColorString(color: string): ColorValidationResult:
Validates a color string and returns the validation result, including the color space, coordinates, alpha value, and validity.Returns:
ColorValidationResultobject with:spaceId(string | null): The color space identifier ('srgb', 'hsl', or 'hsv')coords(number[]): Array of numeric values representing the color coordinatesalpha(number): The alpha value of the color (0 to 1)isValid(boolean): Whether the color string is valid
-
getColor(format: string | ColorSpace): ColorObject:
Converts the current color to the specified format. Throws an error if the format is not valid.Returns:
ColorObject- The color object in the specified format -
getHslString(): string:
Returns the current color in HSL string format.Returns: string - HSL representation of the current color
-
savePreviousColor(): void:
Saves the current color as the previous color. -
restorePreviousColor(): void:
Restores the previous color.
Usage
yarn add @spectrum-web-components/reactive-controllers
Import the ColorController via:
import { ColorController } from '@spectrum-web-components/reactive-controllers/src/ColorController.js';
Examples
Basic usage
import { LitElement, html } from 'lit'; import { property } from 'lit/decorators.js'; import { ColorController } from '@spectrum-web-components/reactive-controllers/src/ColorController.js'; class ColorPickerElement extends LitElement { /** * Gets the current color value from the color controller. */ @property({ type: String }) public get color(): ColorTypes { return this.colorController.colorValue; } /** * Sets the color for the color controller. */ public set color(color: ColorTypes) { this.colorController.color = color; } // Initialize the controller to manage colors in HSV color space private colorController = new ColorController(this, { manageAs: 'hsv' }); render() { return html` <div style="background-color: ${this.color}" role="img" aria-label="Color preview: ${this.color}" > Current color: ${this.color} </div> `; } } customElements.define('color-picker-element', ColorPickerElement);
Constructor initialization
The color controller can also be initialized in the constructor:
import { LitElement } from 'lit'; import { ColorController } from '@spectrum-web-components/reactive-controllers/src/ColorController.js'; class ColorPickerElement extends LitElement { @property({ type: String }) public get color(): ColorTypes { return this.colorController.colorValue; } public set color(color: ColorTypes) { this.colorController.color = color; } private colorController: ColorController; constructor() { super(); this.colorController = new ColorController(this, { manageAs: 'hsv' }); } }
Color validation
Validate color strings before using them:
import { ColorController } from '@spectrum-web-components/reactive-controllers/src/ColorController.js'; class ColorInputElement extends LitElement { private colorController = new ColorController(this); handleColorInput(event: InputEvent) { const input = event.target as HTMLInputElement; const validation = this.colorController.validateColorString( input.value ); if (validation.isValid) { this.colorController.color = input.value; // Announce successful color change for screen readers this.setAttribute('aria-live', 'polite'); this.setAttribute('aria-label', `Color changed to ${input.value}`); } else { // Provide error feedback input.setAttribute('aria-invalid', 'true'); input.setAttribute('aria-describedby', 'color-error'); } } render() { return html` <label for="color-input">Choose a color</label> <input id="color-input" type="text" @input=${this.handleColorInput} aria-describedby="color-help" /> <span id="color-help"> Enter a color in hex, RGB, HSL, or HSV format </span> <span id="color-error" role="alert"></span> `; } }
Usage with color components
Example of using ColorController within a color picker that works with other Spectrum Web Components:
import { LitElement, html } from 'lit'; import { ColorController } from '@spectrum-web-components/reactive-controllers/src/ColorController.js'; import '@spectrum-web-components/field-label/sp-field-label.js'; import '@spectrum-web-components/help-text/sp-help-text.js'; import '@spectrum-web-components/color-area/sp-color-area.js'; import '@spectrum-web-components/color-slider/sp-color-slider.js'; class CompleteColorPicker extends LitElement { private colorController = new ColorController(this, { manageAs: 'hsv' }); @property({ type: String }) public get color(): ColorTypes { return this.colorController.colorValue; } public set color(color: ColorTypes) { const oldColor = this.color; this.colorController.color = color; this.requestUpdate('color', oldColor); } handleColorChange(event: Event) { const target = event.target as any; this.color = target.color; } render() { return html` <div role="group" aria-labelledby="picker-label"> <sp-field-label id="picker-label" for="color-area"> Color picker </sp-field-label> <sp-help-text> Choose a color from the picker or enter a value manually </sp-help-text> <sp-color-area id="color-area" .color=${this.color} @change=${this.handleColorChange} ></sp-color-area> <sp-color-slider .color=${this.color} @change=${this.handleColorChange} aria-label="Hue slider" ></sp-color-slider> </div> `; } }
Saving and restoring colors
Implement undo functionality using savePreviousColor and restorePreviousColor:
import { LitElement, html } from 'lit'; import { ColorController } from '@spectrum-web-components/reactive-controllers/src/ColorController.js'; import '@spectrum-web-components/button/sp-button.js'; class ColorPickerWithUndo extends LitElement { private colorController = new ColorController(this, { manageAs: 'hsv' }); @property({ type: String }) public get color(): ColorTypes { return this.colorController.colorValue; } public set color(color: ColorTypes) { // Save the current color before changing this.colorController.savePreviousColor(); this.colorController.color = color; } handleUndo() { this.colorController.restorePreviousColor(); this.requestUpdate(); // Announce undo action for screen readers this.dispatchEvent( new CustomEvent('color-restored', { detail: { color: this.color }, bubbles: true, composed: true, }) ); } render() { return html` <div> <input type="color" .value=${this.color} @change=${(e: Event) => (this.color = (e.target as HTMLInputElement).value)} aria-label="Color picker" /> <sp-button @click=${this.handleUndo} aria-label="Undo color change" > Undo </sp-button> </div> `; } }
Supported color formats
The ColorController supports a wide range of color formats for input and output:
#f00, #0a5#f00f, #0a58#ff0000, #00aa55#ff0000ff, #00aa5580rgb(255, 0, 0), rgb(0, 170, 85)rgba(255, 0, 0, 1), rgba(0, 170, 85, 0.5)hsl(0, 100%, 50%), hsl(150, 100%, 33%)hsla(0, 100%, 50%, 1), hsla(150, 100%, 33%, 0.5)hsv(0, 100%, 100%), hsv(150, 100%, 67%)hsva(0, 100%, 100%, 1), hsva(150, 100%, 67%, 0.5)red, rebeccapurple, darkseagreenAccessibility
When implementing color pickers or other color-related UI with the ColorController, consider these accessibility best practices:
Color perception
- Never rely on color alone to convey information. Always provide alternative text descriptions or patterns.
- Provide text alternatives for color values (e.g., "red", "dark blue", "#FF0000") that are announced by screen readers.
- Use ARIA labels (
aria-labeloraria-labelledby) to describe the purpose of color controls.
Screen reader support
- Announce color changes with
aria-liveregions when colors update dynamically. - Provide meaningful labels for all interactive color controls.
- Include instructions in
aria-describedbyfor how to use color inputs.
Keyboard accessibility
When building color pickers with this controller:
- Ensure all color selection methods are keyboard accessible.
- Provide visible focus indicators for all interactive elements.
- Consider implementing keyboard shortcuts for common actions (e.g., arrow keys for fine-tuning).
Error handling
- Use
aria-invalidandaria-describedbyto communicate validation errors. - Provide clear error messages when color values are invalid.
Color contrast
When using colors selected via this controller for text or UI elements, ensure they meet
- Normal text: 4.5:1 contrast ratio
- Large text (18pt+ or 14pt+ bold): 3:1 contrast ratio
- UI components and graphics: 3:1 contrast ratio
Related components
The ColorController is used by these Spectrum Web Components:
- Two-dimensional color picker<sp-color-area> - Text input for color values<sp-color-field> - Slider for selecting color channel values<sp-color-slider> - Circular hue selector<sp-color-wheel> - Color preview display<sp-swatch>