Skip to main content

TextInputArea

Allows users to enter multi-line text into a UI.

github
View source code

Migration Information

For teams migrating from the V1 to V2 component, please refer to the migration guide for changes to the component.
Component Guide
import { TextInputArea } from '@uhg-abyss/web/ui/TextInputArea';
() => {
const [value, setValue] = useState('State Default Value');
return (
<TextInputArea
label="TextInputArea Sandbox"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
);
};

Using useForm and FormProvider simplifies form management by providing out-of-the-box validation, form state handling, and performance optimizations, leveraging the power of react-hook-form.

useState​

Using the useState hook gets values from the component state.

Label​

Use the label prop to display a label above the input. To hide the input label, set hideLabel to true.

Use isRequired and isOptional for further customization.

useState only

If using useForm, do not use isRequired. The same functionality can be achieved with required: true in validators.

Helper​

Use the helper prop to display a help icon next to the label. Simply passing a string value will render the default helper, a Tooltip containing that string. The helper can be customized by passing in a node. It is recommended to use either a Tooltip or a Popover. See When should I use a Tooltip vs. a Popover? for more information on best practices regarding the two.

Subtext​

Use the subText prop to display helpful information related to the input field. The prop accepts either a string or an object of the form:

{
text: string;
position: 'above' | 'below';
}

The position property determines where the subtext will be displayed in relation to the input field. The default value is 'below'.

Disabled​

Set the isDisabled prop to true to disable the input field so users cannot enter a value.

Validation​

Validators (useForm)​

Form Compatibility
useState
useForm

Use the validators prop to set validation rules for the field when using useForm. See the examples below for implementation on various types of validation.

Tip

The default error message when required is true is minimally acceptable for accessibility. It is highly recommended to customize it to be more specific to the use of the field and form.

Error message (useState)​

Form Compatibility
useState
useForm

Use the errorMessage prop to display a custom error message below the input field when using useState.

Success message​

Form Compatibility
useState
useForm

Use the successMessage prop to display a custom success message below the input field. To provide a single success message across all form input components using useForm/FormProvider, you can provide successMessage to FormProvider as shown here.

Highlighted​

Form Compatibility
useState
useForm

Use the highlighted prop to enable a distinct background color when fields are required. To supply this across all form input components using useForm/FormProvider, you can provide highlighted to FormProvider as shown here.

Max length​

Use the maxLength prop to limit the number of characters allowed in the input field. The default is 500. The remaining character count is formatted with a comma thousands separator for counts of 1,000 or more (for example, 5,000 characters remaining).

Max length threshold messages​

To minimize excessive and unwanted screen reader announcements about characters remaining, an alternate configurable approach is available using the alertThresholds prop (for more details see accessibility tab). Use alertThresholds to specify an array of percentage thresholds (as decimals) at which to announce the percentage of characters used to screen readers. For example, passing [0.25, 0.5, 0.75] will announce when 25%, 50%, and 75% of the max length has been used.

Note

If not defined, by default the only announcements are at:

  • "10 characters remaining"
  • "### characters maximum limit reached"

Preserve whitespace​

To preserve leading or trailing whitespace in your inputs, set prop preserveWhitespace to true.

TextInputArea Props​

Name
Type
DefaultRequiredA11yDescription
alertThresholds
number[] | undefined
List of decimal thresholds for character count alerts when maxLength is used (ex: [.75] for an alert of 75% of characters used). Triggers a screen-reader announcement of remaining characters when crossed.
className
string | undefined
CSS class name to apply to each element within the component
clearButtonRef
RefObject<HTMLButtonElement> | undefined
Use to pass a ref to the clear input button
css
CSSProperties | Partial<Record<"abyss-text-input-area" | "abyss-text-input-area-clear" | "abyss-text-input-area-label" | "abyss-text-input-area-root" | "abyss-text-input-area-sub-text" | "abyss-text-input-area-character-count" | "abyss-text-input-area-descriptors" | "abyss-text-input-area-container-wrapper", CSSProp...
Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation
See CSS Prop Styling for more information
data-testid
string | undefined
Suffix used to create a unique ID used for automated testing
See Component Testing for more information
disableDefaultProviderProps
boolean | undefined
false
If set to true, the component will not use the DefaultPropsProvider values.

If you aren’t using the DefaultPropsProvider, this prop can be ignored.
errorMessage
string | undefined
Error message to display for the input. Only used when not in a FormProvider.
errorMessage should not exist in useForm mode.
helper
string | number | bigint | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<...> | null | undefined
Helper element next to label
hiddenFrom
Breakpoint | undefined
When defined, the component is hidden once the screen width reaches the specified breakpoint.
hideLabel
boolean | undefined
false
If true, hides the label visually while keeping it accessible to screen readers.
highlighted
boolean | undefined
false
If true, the input field will be highlighted
isClearable
boolean | undefined
If true, the input will display a clear button
isDisabled
boolean | undefined
false
If true, the input will be disabled
isOptional
boolean | undefined
false
If true, the label will be appended with "(Optional)"
isReadOnly
boolean | undefined
false
If true, the input will be read-only
isRequired
boolean | undefined
Whether the input is required. Only used when not in a FormProvider.
isRequired should not exist in useForm mode.
label
string
The label for the input; associated with it so screen readers announce it as the input's accessible name.
maxLength
number | undefined
500
The maximum number of characters allowed in the input.
model
string | undefined
model should not exist in useState mode.
Model name for form validation. Only used when in a FormProvider.
onBlur
FocusEventHandler<HTMLInputElement> | undefined
Callback function executed when the input is blurred
onChange
ChangeEventHandler<HTMLInputElement> | undefined
Callback function executed when the input value changes
onClear
(() => void) | undefined
Callback function executed when the input is cleared
onFocus
FocusEventHandler<HTMLInputElement> | undefined
Callback function executed when the input is focused
preserveWhitespace
boolean | undefined
false
Whether to preserve leading and trailing whitespace
slotProps
Partial<Record<ToSlotKey<{ root: LeafSlotDef<"div", undefined>; containerWrapper: LeafSlotDef<"div", undefined>; label: LeafSlotDef<"div", undefined>; ... 4 more ...; descriptors: LeafSlotDef<...>; }, "text-input-area">, SlotPropsLeafValue>> | undefined
Props to pass to individual internal slots of the component.
See slotProps for more information
subText
string | { text: string; position: SubTextPosition; } | undefined
Additional descriptive text for the input
successMessage
string | undefined
Success message to display for the input
validators
RegisterOptions | undefined
validators should not exist in useState mode.
Validators for the input. Only used when in a FormProvider.
value
string | (readonly string[] & string) | undefined
The value of the input. Only used when not in a FormProvider.
value should not exist in useForm mode.
visibleFrom
Breakpoint | undefined
When defined, the component is hidden until the screen width reaches the specified breakpoint.

TextInputArea Classes​

Class NameDescription
.abyss-text-input-areaTextInputArea input field
.abyss-text-input-area-character-countTextInputArea character count
.abyss-text-input-area-clearTextInputArea clear button
.abyss-text-input-area-container-wrapperTextInputArea container wrapper
.abyss-text-input-area-descriptorsTextInputArea descriptors
.abyss-text-input-area-labelTextInputArea label
.abyss-text-input-area-rootTextInputArea root container
.abyss-text-input-area-sub-textTextInputArea subtext

"Characters remaining not announced" - screen reader implementation details​

Unlike most fields in Abyss, the visible "character remaining" is not automatically announced as part of TextInputArea receiving focus. If it was, (using aria-describedby) it would be triggered on every keystroke entering data in many BrATs (such as JAWS & Chrome, NVDA & Firefox).

To provide a more appropriate and configurable screen reader experiences use the max length threshold messages feature covered on the overview tab.

Known BrAT issues​

  • JAWS (prior to 2024)
    • ARIA settings, including aria-describedby, aria-required, and aria-invalid, are not announced on textarea

Component Tokens​

Tip

Click on the token row to copy the token to your clipboard.

TextInputArea Tokens​

Token NameValue
text-input-area.color.text.character-count
#4B4D4F
text-input-area.spacing.padding.vertical.clear-button
4px
text-input-area.spacing.padding.vertical.field
12px
text-input-area.spacing.gap.horizontal.character-count
16px

Header Tokens​

Token NameValue
input-header.color.text.label
#4B4D4F
input-header.color.text.hint
#4B4D4F
input-header.color.icon.info.rest
#196ECF
input-header.color.icon.info.hover
#004BA0
input-header.color.icon.info.active
#002677
input-header.sizing.all.icon
24px
input-header.spacing.gap.horizontal.container
4px
input-header.spacing.gap.horizontal.label
4px
input-header.spacing.gap.vertical.content
4px
input-header.spacing.padding.top.content
2px

Validation Tokens​

Token NameValue
input-validation.color.surface.container
#FFFFFF
input-validation.color.text.error
#990000
input-validation.color.text.success
#007000
input-validation.color.icon.error
#990000
input-validation.color.icon.success
#007000
input-validation.sizing.all.icon
20px
input-validation.spacing.gap.horizontal.container
4px

Input Tokens​

Token NameValue
input.color.surface.field.default
#FFFFFF
input.color.surface.field.highlighted
#E5F8FB
input.color.surface.field.disabled
#F3F3F3
input.color.border.field.rest
#4B4D4F
input.color.border.field.hover.default
#196ECF
input.color.border.field.hover.error
#990000
input.color.border.field.hover.success
#007000
input.color.border.field.active.default
#004BA0
input.color.border.field.active.error
#990000
input.color.border.field.active.success
#007000
input.color.text.input
#4B4D4F
input.color.text.hint
#4B4D4F
input.color.text.required
#990000
input.color.icon.utility.rest
#4B4D4F
input.color.icon.utility.hover
#323334
input.color.icon.utility.active
#000000
input.color.icon.content
#323334
input.color.cursor
#196ECF
input.border-radius.all.field
4px
input.border-width.all.field.default
1px
input.border-width.all.field.active
3px
input.sizing.all.icon
20px
input.spacing.gap.vertical.container
8px
input.spacing.gap.horizontal.field
12px
input.spacing.gap.horizontal.input-indicator
2px
input.spacing.gap.horizontal.prefix-input
2px
input.spacing.gap.horizontal.suffix-clear
2px
input.spacing.padding.all.focus-container
2px
input.spacing.padding.horizontal.field
12px
input.spacing.padding.left.field
12px
input.spacing.padding.right.focus-field
44px
Table of Contents