useColorField
Provides the behavior and accessibility implementation for a color field component. Color fields allow users to enter and adjust a hex color value.
| install | yarn add @react-aria/color |
|---|---|
| version | 3.0.0-beta.4 |
| usage | import {useColorField} from '@react-aria/color' |
API#
useColorField(
props: AriaColorFieldProps,
state: ColorFieldState,
ref: RefObject<HTMLInputElement>
): ColorFieldAriaFeatures#
The <input type="color"> HTML element
can be used to build a color picker, however it is very inconsistent across browsers and operating systems and consists
of a complete color picker rather than a single field for editing a hex value. useColorField helps achieve accessible
color fields that can be styled as needed.
- Support for parsing and formatting a hex color value
- Validates keyboard entry as the user types so that only valid hex characters are accepted
- Supports using the arrow keys to increment and decrement the value
- Support for customizing the step value for incrementing and decrementing
- Exposed to assistive technology as a
textboxvia ARIA - Visual and ARIA labeling support
- Follows the spinbutton ARIA pattern
- Works around bugs in VoiceOver with the spinbutton role
- Uses an ARIA live region to ensure that value changes are announced
Anatomy#
A color field consists of an input element and a label. useColorField automatically manages
the relationship between the two elements using the for attribute on the <label> element
and the aria-labelledby attribute on the <input> element.
useColorField returns two sets of props that you should spread onto the appropriate element:
| Name | Type | Description |
labelProps | LabelHTMLAttributes<HTMLLabelElement> | Props for the label element. |
inputProps | HTMLAttributes<HTMLInputElement> | Props for the input element. |
State is managed by the useColorFieldState
hook from @react-stately/color. The state object should be passed as an option to useColorField
If there is no visual label, an aria-label or aria-labelledby prop must be passed instead
to identify the element to screen readers.
Example#
import {useColorFieldState} from '@react-stately/color';
function ColorField(props) {
let state = useColorFieldState(props);
let inputRef = ReactuseRef();
let {labelProps inputProps} = useColorField(props state inputRef);
return (
<div style={display: 'inline-flex' flexDirection: 'column'}>
<label ...labelProps>propslabel</label>
<input ...inputProps ref=inputRef />
</div>
);
}
<ColorField label="Color" />import {useColorFieldState} from '@react-stately/color';
function ColorField(props) {
let state = useColorFieldState(props);
let inputRef = ReactuseRef();
let {labelProps inputProps} = useColorField(
props
state
inputRef
);
return (
<div
style={
display: 'inline-flex'
flexDirection: 'column'
}>
<label ...labelProps>propslabel</label>
<input ...inputProps ref=inputRef />
</div>
);
}
<ColorField label="Color" />import {useColorFieldState} from '@react-stately/color';
function ColorField(
props
) {
let state = useColorFieldState(
props
);
let inputRef = ReactuseRef();
let {
labelProps
inputProps
} = useColorField(
props
state
inputRef
);
return (
<div
style={
display:
'inline-flex'
flexDirection:
'column'
}>
<label
...labelProps>
propslabel
</label>
<input
...inputProps
ref=inputRef
/>
</div>
);
}
<ColorField label="Color" />Usage#
The following examples show how to use the ColorField component created in the above example.
Uncontrolled#
By default, ColorField is uncontrolled. You can set a default value using the defaultValue prop.
<ColorField defaultValue="#7f007f" /><ColorField defaultValue="#7f007f" /><ColorField defaultValue="#7f007f" />Controlled#
A ColorField can be made controlled. The parseColor
function is used to parse the initial color from a hex string, stored in state. The value and onChange props
are used to update the value in state when the edits the value.
import {parseColor} from '@react-stately/color';
function Example() {
let [color setColor] = ReactuseState(parseColor('#7f007f'));
return (
<>
<ColorField value=color onChange=setColor />
<p>Current color value: colortoString('hex')</p>
</>
);
}
import {parseColor} from '@react-stately/color';
function Example() {
let [color setColor] = ReactuseState(
parseColor('#7f007f')
);
return (
<>
<ColorField value=color onChange=setColor />
<p>Current color value: colortoString('hex')</p>
</>
);
}
import {parseColor} from '@react-stately/color';
function Example() {
let [
color
setColor
] = ReactuseState(
parseColor('#7f007f')
);
return (
<>
<ColorField
value=color
onChange=
setColor
/>
<p>
Current color
value:' '
colortoString(
'hex'
)
</p>
</>
);
}
Step#
The step prop can be used to make a ColorField snap its value to specific increments.
<ColorField defaultValue="#7f007f" step=16 /><ColorField defaultValue="#7f007f" step=16 /><ColorField
defaultValue="#7f007f"
step=16
/>Disabled and read only#
A ColorField can be disabled using the isDisabled prop, and made read only using the isReadOnly prop.
The difference is that read only color fields are focusable but disabled color fields are not.
<ColorField defaultValue="#7f007f" isDisabled />
<ColorField defaultValue="#7f007f" isReadOnly /><ColorField defaultValue="#7f007f" isDisabled />
<ColorField defaultValue="#7f007f" isReadOnly /><ColorField
defaultValue="#7f007f"
isDisabled
/>
<ColorField
defaultValue="#7f007f"
isReadOnly
/>Internationalization#
RTL#
In right-to-left languages, color fields should be mirrored. The label should be right aligned, along with the text in the input. Ensure that your CSS accounts for this.
| Name | Type | Default | Description |
onChange | (
(color: Color
)) => void | — | Handler that is called when the value changes. |
step | number | 1 | The step value to increment and decrement the color by when using the arrow keys. |
value | string | Color | — | The current value (controlled). |
defaultValue | string | Color | — | The default value (uncontrolled). |
isDisabled | boolean | — | Whether the input is disabled. |
isReadOnly | boolean | — | Whether the input can be selected but not changed by the user. |
validationState | ValidationState | — | Whether the input should display its "valid" or "invalid" visual styling. |
isRequired | boolean | — | Whether user input is required on the input before form submission.
Often paired with the necessityIndicator prop to add a visual indicator to the input. |
autoFocus | boolean | — | Whether the element should receive focus on render. |
onFocus | (
(e: FocusEvent
)) => void | — | Handler that is called when the element receives focus. |
onBlur | (
(e: FocusEvent
)) => void | — | Handler that is called when the element loses focus. |
onFocusChange | (
(isFocused: boolean
)) => void | — | Handler that is called when the element's focus status changes. |
onKeyDown | (
(e: KeyboardEvent
)) => void | — | Handler that is called when a key is pressed. |
onKeyUp | (
(e: KeyboardEvent
)) => void | — | Handler that is called when a key is released. |
placeholder | string | — | Temporary text that occupies the text input when it is empty. |
label | ReactNode | — | The content to display as the label. |
aria-label | string | — | Defines a string value that labels the current element. |
aria-labelledby | string | — | Identifies the element (or elements) that labels the current element. |
aria-describedby | string | — | Identifies the element (or elements) that describes the object. |
aria-details | string | — | Identifies the element (or elements) that provide a detailed, extended description for the object. |
excludeFromTabOrder | boolean | — | Whether to exclude the element from the sequential tab order. If true, the element will not be focusable via the keyboard by tabbing. This should be avoided except in rare scenarios where an alternative means of accessing the element or its functionality via the keyboard is available. |
id | string | — | The element's unique identifier. See MDN. |
name | string | — | The name of the input element, used when submitting an HTML form. See MDN. |
onCopy | ClipboardEventHandler<HTMLInputElement> | — | Handler that is called when the user copies text. See MDN. |
onCut | ClipboardEventHandler<HTMLInputElement> | — | Handler that is called when the user cuts text. See MDN. |
onPaste | ClipboardEventHandler<HTMLInputElement> | — | Handler that is called when the user pastes text. See MDN. |
onCompositionStart | CompositionEventHandler<HTMLInputElement> | — | Handler that is called when a text composition system starts a new text composition session. See MDN. |
onCompositionEnd | CompositionEventHandler<HTMLInputElement> | — | Handler that is called when a text composition system completes or cancels the current text composition session. See MDN. |
onCompositionUpdate | CompositionEventHandler<HTMLInputElement> | — | Handler that is called when a new character is received in the current text composition session. See MDN. |
onSelect | ReactEventHandler<HTMLInputElement> | — | Handler that is called when text in the input is selected. See MDN. |
onBeforeInput | FormEventHandler<HTMLInputElement> | — | Handler that is called when the input value is about to be modified. See MDN. |
onInput | FormEventHandler<HTMLInputElement> | — | Handler that is called when the input value is modified. See MDN. |
aria-errormessage | string | — | Identifies the element that provides an error message for the object. |
Represents a color value.
| Method | Description |
toFormat(
(format: ColorFormat
)): Color | Converts the color to the given color format, and returns a new Color object. |
toHexInt(): number | Converts the color to hex, and returns an integer representation. |
getChannelValue(
(channel: ColorChannel
)): number | Returns the numeric value for a given channel. Throws an error if the channel is unsupported in the current color format. |
withChannelValue(
(channel: ColorChannel,
, value: number
)): Color | Sets the numeric value for a given channel, and returns a new Color object. Throws an error if the channel is unsupported in the current color format. |
getChannelRange(
(channel: ColorChannel
)): ColorChannelRange | Returns the minimum, maximum, and step values for a given channel. |
getChannelName(
(channel: ColorChannel,
, locale: string
)): string | Returns a localized color channel name for a given channel and locale, for use in visual or accessibility labels. |
formatChannelValue(
(channel: ColorChannel,
, locale: string
)): string | Formats the numeric value for a given channel for display according to the provided locale. |
A list of supported color formats.
'hex'
| 'hexa'
| 'rgb'
| 'rgba'
| 'hsl'
| 'hsla'
| 'hsb'
| 'hsba'A list of color channels.
'hue'
| 'saturation'
| 'brightness'
| 'lightness'
| 'red'
| 'green'
| 'blue'
| 'alpha'| Name | Type | Description |
minValue | number | The minimum value of the color channel. |
maxValue | number | The maximum value of the color channel. |
step | number | The step value of the color channel, used when incrementing and decrementing. |
Properties
| Name | Type | Description |
inputValue | string | The current text value of the input. Updated as the user types,
and formatted according to formatOptions on blur. |
colorValue | Color | The currently parsed color value, or null if the field is empty.
Updated based on the inputValue as the user types. |
Methods
| Method | Description |
setInputValue(
(value: string
)): void | Sets the current text value of the input. |
commit(): void | Updates the input value based on the currently parsed color value. Typically this is called when the field is blurred. |
increment(): void | Increments the current input value to the next step boundary, and fires onChange. |
decrement(): void | Decrements the current input value to the next step boundary, and fires onChange. |
incrementToMax(): void | Sets the current value to the maximum color value, and fires onChange. |
decrementToMin(): void | Sets the current value to the minimum color value, and fires onChange. |
validate(
(value: string
)): boolean | Validates a user input string. Values can be partially entered, and may be valid even if they cannot currently be parsed to a color. Can be used to implement validation as a user types. |
| Name | Type | Description |
labelProps | LabelHTMLAttributes<HTMLLabelElement> | Props for the label element. |
inputProps | HTMLAttributes<HTMLInputElement> | Props for the input element. |
Provides state management for a color field component. Color fields allow users to enter and adjust a hex color value.
useColorFieldState(
(props: ColorFieldProps
)): ColorFieldState| Name | Type | Default | Description |
onChange | (
(color: Color
)) => void | — | Handler that is called when the value changes. |
step | number | 1 | The step value to increment and decrement the color by when using the arrow keys. |
value | string | Color | — | The current value (controlled). |
defaultValue | string | Color | — | The default value (uncontrolled). |
isDisabled | boolean | — | Whether the input is disabled. |
isReadOnly | boolean | — | Whether the input can be selected but not changed by the user. |
validationState | ValidationState | — | Whether the input should display its "valid" or "invalid" visual styling. |
isRequired | boolean | — | Whether user input is required on the input before form submission.
Often paired with the necessityIndicator prop to add a visual indicator to the input. |
autoFocus | boolean | — | Whether the element should receive focus on render. |
onFocus | (
(e: FocusEvent
)) => void | — | Handler that is called when the element receives focus. |
onBlur | (
(e: FocusEvent
)) => void | — | Handler that is called when the element loses focus. |
onFocusChange | (
(isFocused: boolean
)) => void | — | Handler that is called when the element's focus status changes. |
onKeyDown | (
(e: KeyboardEvent
)) => void | — | Handler that is called when a key is pressed. |
onKeyUp | (
(e: KeyboardEvent
)) => void | — | Handler that is called when a key is released. |
placeholder | string | — | Temporary text that occupies the text input when it is empty. |
label | ReactNode | — | The content to display as the label. |
Parses a color from a string value. Throws an error if the string could not be parsed.
parseColor(
(value: string
)): Color