InputsReact
A choice of preset colors.
Rendered by React 19.3.1
Loading React…Installation
npm i @hamur/reactNot on npm yet. The package goes out under the chosen name.
Anatomy
Import the component and assemble its parts:
<ColorSwatchPicker.Root>
<ColorSwatchPicker.Item />
</ColorSwatchPicker.Root>Examples
The demo at the top is the one example this component has so far.
API reference
16 props across 2 parts, in React syntax. className, style, render are listed once, under Shared props.
ItemColorSwatchPicker.Item
A preset color: a radio named by the color's description (or its aria-label), checked when its color equals the value. Renders a <span>.
| Prop | Type | Default |
|---|---|---|
valuerequiredThe item's color, any CSS color string. | string | — |
disabledWhether the item cannot be checked. | boolean | false |
nativeButtonWhether the component renders a native <button> element when replacing it | boolean | false |
| Data attribute | Description |
|---|---|
data-checked | Present when the item's color is the value. |
data-unchecked | Present when the item's color is not the value. |
data-disabled | Present when the item or the swatch picker is disabled. |
| CSS variable | Description |
|---|---|
--color | The item's color. |
RootColorSwatchPicker.Root
A radio group of preset colors, checked by parsed equality. Inside ColorPicker.Root it reads and sets the picker's color and renders no hidden input of its own. (and a hidden <input> beside it outside a picker). Renders a <div>.
| Prop | Type | Default |
|---|---|---|
valueThe checked color, or null for none. | string | null | — |
defaultValueThe checked color when the component is initially rendered. | string | null | null |
onValueChangeEvent handler called when an item is checked, with the item's value. | ((value: string | null, eventDetails: ColorSwatchPickerRootChangeEventDetails) => void) | — |
disabledWhether the component should ignore user interaction. | boolean | false |
readOnlyWhether the user should be unable to change the color. | boolean | false |
requiredWhether the user must choose a color before submitting a form. | boolean | false |
loopFocusWhether the arrow keys wrap from the last item to the first and back. | boolean | true |
labelsThe color name words of the items' names, in English by default. | Partial<ColorNameLabels> | — |
getColorNameNames an item's color in place of the generated name. | ((color: Color) => string) | — |
localeThe locale of the transparency percentage in the names. | Intl.LocalesArgument | — |
nameIdentifies the field when a form is submitted. | string | — |
formIdentifies the form that owns the hidden input. | string | — |
inputRefA ref to access the hidden input element. | React.Ref<HTMLInputElement> | — |
| Data attribute | Description |
|---|---|
data-disabled | Present when the swatch picker is disabled. |
data-readonly | Present when the swatch picker is read-only. |
Shared props
Every part that renders an element takes these.
| Prop | Type |
|---|---|
classNameCSS class applied to the element, or a function that
returns a class based on the component's state. | string | ((state: State) => string | undefined) |
styleStyle applied to the element, or a function that
returns a style object based on the component's state. | React.CSSProperties | ((state: State) => React.CSSProperties | undefined) |
renderAllows you to replace the component's HTML element
with a different tag, or compose it with another component. | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | ComponentRenderFn<HTMLProps, State> |
Keyboard and accessibility
Keyboard
| Keys | Does | Part |
|---|---|---|
| Tab | Moves into the group on the checked item, or the first one when none is checked | Root |
| ArrowRightArrowDown | Moves to the next item and checks it; from the last it wraps to the first | Item |
| ArrowLeftArrowUp | Moves to the previous item and checks it; in RTL ArrowLeft moves forward | Item |
Stop at the first and last item with loopFocus={false} | Root | |
| Space | Checks the focused item | Item |
| Enter | Nothing: a swatch is a radio, not a button | Item |
Accessibility
| Part | Sets | So that |
|---|---|---|
| Root | role="radiogroup", aria-readonly, aria-required, aria-disabled; its name from Field.Label, aria-label or aria-labelledby | the swatches are read as one choice with its name and state |
| Item | role="radio", aria-checked, aria-label with the color's name ("vibrant blue", "red, 50% transparent") | each swatch says its color, not only shows it |
| Item | an aria-label of your own wins over the color name | a token name ("Info", "Danger") is read where the color stands for one |
| Item | aria-disabled and tabindex="-1" on a disabled item | a disabled swatch stays in the group and the arrows skip it |
Focus order
- The group is one Tab stop: the checked item, or the first item that is not disabled when nothing is checked. Nothing takes focus on mount, and Tab into the group checks nothing.
- The arrows move focus to the item they check.
- A read-only group keeps its Tab stop and checks nothing; a disabled one has none.