useColorField

Provides the behavior and accessibility implementation for a color field component. Color fields allow users to enter and adjust a hex color value.

installyarn add react-aria
version3.35.0
usageimport {useColorField} from 'react-aria'

API#


useColorField( props: AriaColorFieldProps, state: ColorFieldState, ref: RefObject<HTMLInputElementnull> ): 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#


#ABCDEFBackground colorInputLabel

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:

NameTypeDescription
labelPropsLabelHTMLAttributes<HTMLLabelElement>Props for the label element.
inputPropsInputHTMLAttributes<HTMLInputElement>Props for the input element.
descriptionPropsDOMAttributesProps for the text field's description element, if any.
errorMessagePropsDOMAttributesProps for the text field's error message element, if any.
isInvalidbooleanWhether the input value is invalid.
validationErrorsstring[]The current error messages for the input if it is invalid, otherwise an empty array.
validationDetailsValidityStateThe 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.