feat: Added color picker component - #1973
Conversation
…I/igniteui-webcomponents into rkaraivanov/color-picker
Introduce an explicit "missing color" sentinel and surface it through the color picker. ColorModel: - Add `ColorModel.empty()` factory and an `isEmpty` getter representing a missing/undefined color. `default()` keeps returning black. - Clear the empty state when any channel (r/g/b/h/s/l/v/alpha) is modified. - `asString()` returns an empty string while empty; `clone()` preserves the empty state and `equals()` accounts for it. - `parse()` returns the empty sentinel for null/undefined/empty/whitespace input. Component: - Initialize the internal color as empty so an unset picker has an empty value. - Render the trigger anchor with a checkered background while the value is empty, via an `empty` shadow part token. - Validate the color value input on commit using the new `isValidColor` helper; empty or invalid input reverts the field to the current color. Styles: - Add a checkered pattern on `[part~='empty']::part(base)`, mirroring the alpha slider track. Add `isValidColor()` and update model, common and component unit tests to cover the empty sentinel, validation and revert behavior.
Some code reorganization and refactoring was done to support the new input mode. The color picker component now has an input mode that allows users to enter color values directly. The component will handle changes from the input field and update the color value accordingly.
There was a problem hiding this comment.
Pull request overview
Adds a new igc-color-picker web component to the Ignite UI Web Components library, including its internal color model/converters, styles, Storybook story, and unit tests.
Changes:
- Introduces the
IgcColorPickerComponent(and supportingigc-picker-canvas) with theming and interactions (hue/SV selection, alpha, swatches, copy, eyedropper). - Adds a color parsing/model layer (
ColorModel, converters, validation helpers) plus unit tests. - Wires the component into the public exports and the “define all components” registration list, and adds a Storybook story.
Reviewed changes
Copilot reviewed 13 out of 14 changed files in this pull request and generated 7 comments.
Show a summary per file
| File | Description |
|---|---|
| tsconfig.json | Extends lit plugin global attributes (adds inert). |
| stories/color-picker.stories.ts | Adds Storybook coverage for the new color picker. |
| src/index.ts | Exports IgcColorPickerComponent from the package entry. |
| src/components/common/definitions/defineAllComponents.ts | Registers IgcColorPickerComponent in the “define all” list. |
| src/components/color-picker/themes/picker-canvas.base.scss | Styles for the SV picker canvas and marker. |
| src/components/color-picker/themes/color-picker.base.scss | Styles for the overall color picker UI (sliders, buttons, swatches). |
| src/components/color-picker/picker-canvas.ts | New SV picker surface with pointer + keyboard interactions and events. |
| src/components/color-picker/model.ts | ColorModel implementation and context helper for parsing. |
| src/components/color-picker/model.spec.ts | Unit tests for ColorModel. |
| src/components/color-picker/converters.ts | RGB/HSL/HSV conversion utilities. |
| src/components/color-picker/common.ts | Color parsing + validation helpers. |
| src/components/color-picker/common.spec.ts | Unit tests for parsing/validation helpers. |
| src/components/color-picker/color-picker.ts | Main igc-color-picker component implementation. |
| src/components/color-picker/color-picker.spec.ts | Component-level tests incl. a11y and form association. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 35 out of 36 changed files in this pull request and generated no new comments.
Suppressed comments (5)
src/components/color-picker/color-picker.ts:697
- The internal
<igc-select>in the picker popup is a form-associated control and currently hasname="format". This can cause the nested select to submit an extraformatfield when the color picker is placed in a form. Other composite components avoid giving internal controls aname(seesrc/components/select/select.ts:783-799). Remove thenameattribute here.
<igc-select
id="format-select"
part="format-select"
placeholder="Color format"
name="format"
outlined
src/components/color-picker/color-picker.ts:718
- The popup color value
<igc-input>is form-associated and currently hasname="color-input", which can introduce an extra field in form submission when the color picker is used inside a form. Since the host component already handles form association and submission under its ownname, the internal input should not have aname.
<igc-input
id="color-input"
name="color-input"
placeholder=${formatPlaceholders[this.format]}
src/components/color-picker/color-picker.ts:423
_handleColorInputChange()updates the component value but never emitsigcInput, unlike the other interaction paths (canvas/slider/swatches/EyeDropper). This means typing/committing a color via the text field won’t notify consumers listening forigcInput. EmitigcInputafter updating the color so all user-driven value changes behave consistently.
this._color = cleared ? ColorModel.empty() : ColorModel.parse(value);
this._updateColor();
// The model was replaced directly rather than through `value`, so no
// `value` change is recorded and the sync in `updated()` will not run.
this._syncCanvasPosition();
src/components/color-picker/color-picker.ts:667
- The internal alpha
<igc-input>is form-associated and has anameattribute. When the color picker is used inside a form, this nested control can end up contributing an extraalphafield to form submission, which is inconsistent with other composite controls (e.g.combo/selectrender internal<igc-input>withoutname). Remove thenameattribute from the internal input.
This issue also appears in the following locations of the same file:
- line 692
- line 715
id="alpha"
name="alpha"
placeholder="Alpha value"
src/components/icon/internal-icons-lib.ts:40
- The new internal
colorizeSVG hardcodesfill="#e3e3e3", unlike the other internal icons which rely on CSS/currentColor for theming. Hardcoding the fill can make the icon ignore theme/consumer styling. Drop the explicit fill attribute so it inherits like the rest of the icon set.
@sbayreva In the design, the % symbol is part of the input value. The design does not provide what happens if the % is in the suffix. If the % is a suffix, we have to either change the design or override the input per theme to make it look like the design, which in Bootstrap is nearly impossible without hacky overrides. @rkaraivanov can we append the % to the input value, so we don't have to use the suffix? |
|
@desig9stein @sbayreva |
…loated-notch` for better encapsulation and maintainability
…elper text and refined spacing
|
@sbayreva @sdimchevski, regarding the comments on overriding the colors for the icon button and input group—I strongly advise against altering the default color tokens for these components. Keeping the default color models ensures consistent theming and avoids maintenance friction across themes. If you'd still like to proceed, please provide the complete color specs for both components in the context of the popover:
Keep in mind that hardcoding these overrides will prevent users from customizing these components via theming variables—unless they write specific CSS overrides within that exact scope. @sbayreva, spacing and sizing should match the design now; you can test it. |
|
@desig9stein agreed with all of this. Let's use the defaults and not override the color tokens |
@sbayreva To achieve this, we will need to use an SVG. Pure CSS cannot control an inner border arch independently; adjusting the outer radius to compensate would mismatch the parent container's radius, which isn't an ideal trade-off. |
|
@rkaraivanov @sbayreva Just a heads-up, there's a new PR in the theming repo for the color changes. It includes a few variable name updates, so to avoid local errors, you'll need to use a package built directly from this PR until it gets merged. |
…ehn we have hideFormats set to tue the color input takes the full grid

No description provided.