/// Inputs
ColorInput
A sunken hex/rgb field with a leading swatch that opens a ColorPicker in a popover — clearable and controllable.
import { ColorInput } from "@protocore/pds";Basics
The field shows the hex value with a leading ColorSwatch. Click the swatch to open the picker; type a valid hex to update it live. Value is controllable via value / defaultValue / onValueChange, and onValueChange fires undefined when cleared.
Click the swatch to open the picker
Alpha & rgb
Set format="rgb" to display an rgb()/rgba() string, and alpha to include an alpha channel in both the picker and the emitted value.
rgb() format with an alpha channel
Sizes
Matches the control-height contract: sm (32), md (36, default), lg (40) — the leading swatch scales with the field.
When to use it
Use ColorInput for an on-demand color field in a form — a compact sunken control that reads like an Input and opens the full ColorPicker only when needed. When the picker should always be visible (a theme editor, a settings panel), embed ColorPicker directly instead. The field accepts typed hex or rgb() and commits any valid color immediately; invalid partial text is kept without committing. Wrap it in a Field for a label, hint, and error wiring.
Usage
Do
- Wrap it in a `Field` for a visible label, or pass `aria-label`.
- Use `clearable` when an empty (no color) value is valid.
- Match `format` and `alpha` to what the consuming system stores.
- Allow direct hex entry alongside the picker.
Don't
- Don't use it where the picker should stay open — use ColorPicker.
- Don't leave it unlabelled; the swatch and field need an accessible name.
- Don't expect a committed value from invalid partial text — only valid colors commit.
- Don't enable `alpha` if the target can't store or render transparency.
Accessibility
| Keys | Action |
|---|---|
| Tab | Focus the swatch trigger, then the text field. |
| Enter / Space | On the swatch trigger: open the picker popover. |
| Escape | Close the picker popover, returning focus to the trigger. |
| Type | Enter a hex or rgb() value directly; valid input commits immediately. |
- The leading swatch is a `<button>` (`aria-haspopup="dialog"`) that opens the picker; the picker is a Radix Popover with full focus management and dismissal.
- The text field carries `aria-invalid` when `invalid` is set, matching the Input contract.
- Clearing (the × button or emptying the field) emits `undefined` and shows the checkered empty swatch.
ColorInput props
| Prop | Type | Default | Description |
|---|---|---|---|
alpha | boolean | false | Include an alpha channel in the picker and the emitted value. |
aria-label | string | — | Accessible label for the text field. |
className | string | — | Merged after the pds class on the root. |
clearable | boolean | false | Show a clear (×) button once a value is set. |
defaultValue | string | — | Initial color in uncontrolled mode. |
disabled | boolean | false | Disable the control. |
format | enum | hex | Text-field format: `hex` (default) or `rgb`. |
id | string | — | Root id — also labels the text field. |
invalid | boolean | false | Mark the field invalid — danger border plus `aria-invalid`. |
onValueChange | ((value: string) => void) | — | Fires with the next hex string, or `undefined` when cleared. |
placeholder | string | #000000 | Placeholder for the empty field. |
size | enum | md | Control height: `sm` (32) · `md` (36, default) · `lg` (40). |
swatches | string[] | — | Preset swatches passed through to the picker. |
value | string | — | Controlled color as a hex string. |