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 |
---|---|
version | 3.36.0 |
usage | import {useColorField} from 'react-aria' |
API#
useColorField(
props: AriaColorFieldProps,
state: ColorFieldState,
ref: RefObject<HTMLInputElement
| | null>
): ColorFieldAria
Features#
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
- Exposed to assistive technology as a
textbox
via 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 | InputHTMLAttributes<HTMLInputElement> | Props for the input element. |
descriptionProps | DOMAttributes | Props for the text field's description element, if any. |
errorMessageProps | DOMAttributes | Props for the text field's error message element, if any. |
isInvalid | boolean | Whether the input value is invalid. |
validationErrors | string[] | The current error messages for the input if it is invalid, otherwise an empty array. |
validationDetails | ValidityState | The native validation details for the input. |
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';
import {useColorField} from 'react-aria';
function ColorField(props) {
let state = useColorFieldState(props);
let inputRef = React.useRef(null);
let {
labelProps,
inputProps
} = useColorField(props, state, inputRef);
return (
<div style={{ display: 'inline-flex', flexDirection: 'column' }}>
<label {...labelProps}>{props.label}</label>
<input {...inputProps} ref={inputRef} />
</div>
);
}
<ColorField label="Color" />
import {useColorFieldState} from 'react-stately';
import {useColorField} from 'react-aria';
function ColorField(props) {
let state = useColorFieldState(props);
let inputRef = React.useRef(null);
let {
labelProps,
inputProps
} = useColorField(props, state, inputRef);
return (
<div
style={{
display: 'inline-flex',
flexDirection: 'column'
}}
>
<label {...labelProps}>{props.label}</label>
<input {...inputProps} ref={inputRef} />
</div>
);
}
<ColorField label="Color" />
import {useColorFieldState} from 'react-stately';
import {useColorField} from 'react-aria';
function ColorField(
props
) {
let state =
useColorFieldState(
props
);
let inputRef = React
.useRef(null);
let {
labelProps,
inputProps
} = useColorField(
props,
state,
inputRef
);
return (
<div
style={{
display:
'inline-flex',
flexDirection:
'column'
}}
>
<label
{...labelProps}
>
{props.label}
</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 aria-label="Color" defaultValue="#7f007f" />
<ColorField aria-label="Color" defaultValue="#7f007f" />
<ColorField
aria-label="Color"
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';
function Example() {
let [color, setColor] = React.useState(parseColor('#7f007f'));
return (
<>
<ColorField aria-label="Color" value={color} onChange={setColor} />
<p>Current color value: {color.toString('hex')}</p>
</>
);
}
import {parseColor} from 'react-stately';
function Example() {
let [color, setColor] = React.useState(
parseColor('#7f007f')
);
return (
<>
<ColorField
aria-label="Color"
value={color}
onChange={setColor}
/>
<p>Current color value: {color.toString('hex')}</p>
</>
);
}
import {parseColor} from 'react-stately';
function Example() {
let [color, setColor] =
React.useState(
parseColor(
'#7f007f'
)
);
return (
<>
<ColorField
aria-label="Color"
value={color}
onChange={setColor}
/>
<p>
Current color
value:{' '}
{color.toString(
'hex'
)}
</p>
</>
);
}
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 aria-label="Color" defaultValue="#7f007f" isDisabled />
<ColorField aria-label="Color" defaultValue="#7f007f" isReadOnly />
<ColorField
aria-label="Color"
defaultValue="#7f007f"
isDisabled
/>
<ColorField
aria-label="Color"
defaultValue="#7f007f"
isReadOnly
/>
<ColorField
aria-label="Color"
defaultValue="#7f007f"
isDisabled
/>
<ColorField
aria-label="Color"
defaultValue="#7f007f"
isReadOnly
/>
HTML forms#
ColorField supports the name
prop for integration with HTML forms. The value will be submitted to the server as a hex color string.
<ColorField label="Color" name="color" />
<ColorField label="Color" name="color" />
<ColorField
label="Color"
name="color"
/>
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.