Text Area
Text Areas allow users to enter and edit multiple lines of text.
Anatomy

- Label: Title of the Text Area.
- Input Container: Rectangular container that houses the placeholder and body text.
- Placeholder/Body Text: Placeholder text is optional and shows an example of how the text is used.
Usage Guidance
- Use the Text Area component when you need to let users enter an amount of text that’s longer than a single line.
- To ensure we don’t overwhelm users, there shouldn’t be more than two Wide Text Areas on a page.
- For all Text Areas on Web, a user clicking into a field or label that’s not disabled will trigger the text cursor to appear, allowing users the ability to type. As the user types in the Text Area, the placeholder text is replaced with the user’s input.
When to Use
- Use the Text Area to fit longer text descriptions, usually around one paragraph.
When to Use Something Else
- Use a Rich Text Editor to give users the ability to format text.
- Use a Text Input for single line of text.
Examples
Basic Example
Text Area should be used in tandem with Form Field to ensure proper label association and screen reader support.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {TextArea} from '@workday/canvas-kit-react/text-area';
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setValue(event.target.value);
};
return (
<FormField>
<FormField.Label>Leave a Review</FormField.Label>
<FormField.Field>
<FormField.Input as={TextArea} onChange={handleChange} value={value} />
</FormField.Field>
</FormField>
);
};
Disabled
Set the disabled prop of the Text Area to prevent users from interacting with it.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {TextArea} from '@workday/canvas-kit-react/text-area';
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setValue(event.target.value);
};
return (
<FormField>
<FormField.Label>Leave a Review</FormField.Label>
<FormField.Field>
<FormField.Input as={TextArea} disabled onChange={handleChange} value={value} />
</FormField.Field>
</FormField>
);
};
Placeholder
Set the placeholder prop of the Text Area to display a sample of its expected format or value
before a value has been provided.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {TextArea} from '@workday/canvas-kit-react/text-area';
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setValue(event.target.value);
};
return (
<FormField>
<FormField.Label>Leave a Review</FormField.Label>
<FormField.Field>
<FormField.Input
as={TextArea}
onChange={handleChange}
placeholder="Let us know how we did!"
value={value}
/>
</FormField.Field>
</FormField>
);
};
Accessibility Note: Always provide a persistent
FormField.Labeland never rely on placeholder text as the only label for a text area. Placeholders can disappear or lack sufficient contrast. Use placeholders only for short format examples, and place detailed instructions or guidance inFormField.Hintinstead of the placeholder.
Ref Forwarding
Text Area supports ref forwarding. It will forward
ref to its underlying <textarea> element.
import React from 'react';
import {PrimaryButton} from '@workday/canvas-kit-react/button';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {TextArea} from '@workday/canvas-kit-react/text-area';
export default () => {
const [value, setValue] = React.useState('');
const ref = React.useRef(null);
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setValue(event.target.value);
};
const handleClick = () => {
ref.current.focus();
};
return (
<>
<FormField>
<FormField.Label>Leave a Review</FormField.Label>
<FormField.Field>
<FormField.Input as={TextArea} onChange={handleChange} ref={ref} value={value} />
</FormField.Field>
</FormField>
<PrimaryButton onClick={handleClick}>Focus Text Area</PrimaryButton>
</>
);
};
Resize Constraints
Set the resize prop of the Text Area to restrict resizing of it to certain dimensions. resize
accepts the following values:
TextArea.ResizeDirection.Both(Default)TextArea.ResizeDirection.HorizontalTextArea.ResizeDirection.NoneTextArea.ResizeDirection.Vertical
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {TextArea} from '@workday/canvas-kit-react/text-area';
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setValue(event.target.value);
};
return (
<FormField>
<FormField.Label>Leave a Review</FormField.Label>
<FormField.Field>
<FormField.Input
as={TextArea}
onChange={handleChange}
resize={TextArea.ResizeDirection.Vertical}
value={value}
/>
</FormField.Field>
</FormField>
);
};
Accessibility Note: Allowing users to resize the text area (default
resize: both) improves accessibility by letting them adjust it for comfort. Avoid disabling resizing (resize: none) unless necessary, and always ensure the initial size meets the needs of your content.
Grow
Set the grow prop of the Text Area to true to configure the Text Area to expand to the width of
its container.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {TextArea} from '@workday/canvas-kit-react/text-area';
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setValue(event.target.value);
};
return (
<FormField grow>
<FormField.Label>Leave a Review foo</FormField.Label>
<FormField.Field>
<FormField.Input as={TextArea} onChange={handleChange} value={value} />
</FormField.Field>
</FormField>
);
};
Label Position Horizontal
Set the orientation prop of the Form Field to designate the position of the label relative to the
input component. By default, the orientation will be set to vertical.
Message must be under 200 characters
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {TextArea} from '@workday/canvas-kit-react/text-area';
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setValue(event.target.value);
};
return (
<FormField orientation="horizontalStart">
<FormField.Label>Leave a Review</FormField.Label>
<FormField.Field>
<FormField.Input as={TextArea} onChange={handleChange} value={value} />
<FormField.Hint>Message must be under 200 characters</FormField.Hint>
</FormField.Field>
</FormField>
);
};
Required
Set the required prop of the wrapping Form Field to true to indicate that the field is required.
Labels for required fields are suffixed by a red asterisk.
import React from 'react';
import {FormField} from '@workday/canvas-kit-react/form-field';
import {TextArea} from '@workday/canvas-kit-react/text-area';
export default () => {
const [value, setValue] = React.useState('');
const handleChange = (event: React.ChangeEvent<HTMLTextAreaElement>) => {
setValue(event.target.value);
};
return (
<FormField isRequired={true}>
<FormField.Label>Leave a Review</FormField.Label>
<FormField.Field>
<FormField.Input as={TextArea} onChange={handleChange} value={value} />
</FormField.Field>
</FormField>
);
};
Error States
Form Field provides error and caution states for Text Area. Set the error prop on Form Field to
"error" or "caution" and use FormField.Hint to provide error messages. See
Form Field’s Error documentation for
examples and accessibility guidance.
Accessibility
TextArea should be used with Form Field to
ensure proper labeling, error handling, and help text association. See
FormField’s accessibility documentation
for comprehensive guidance on form accessibility best practices.
Character Limits
When limiting text area length:
- Use the
maxLengthattribute to enforce the limit programmatically. - For longer limits (100+ characters), consider adding character count information to
FormField.Hint. - Avoid announcing character counts after every keystroke, as this disrupts screen reader users. Check out Debouncing an AriaLiveRegion: TextArea with character limit for an example of how to wait for users to stop typing before announcing the character count to screen readers.
Screen Reader Experience
When properly implemented with FormField, screen readers will announce:
- The label text when the text area receives focus.
- Required, disabled, or read-only status.
- Help text and error messages (via
aria-describedby). - The current value or “blank” if empty.
- That it’s a multi-line text input field.
Component API
TextArea
Props
Props extend from textarea. Changing the as prop will change the element interface.
| Name | Type | Description | Default |
|---|---|---|---|
error | | The type of error associated with the TextArea (if applicable). | |
resize | | The resize constraints of the TextArea. | |
grow | boolean | True if the component should grow to its container's width. False otherwise. | |
children | React.ReactNode | ||
as | React.ElementType | Optional override of the default element used by the component. Any valid tag or Component. If you provided a Component, this component should forward the ref using Note: Not all elements make sense and some elements may cause accessibility issues. Change this value with care. | textarea |
ref | React.Ref<R = textarea> | Optional ref. If the component represents an element, this ref will be a reference to the real DOM element of the component. If |
TextArea.ErrorType
Basic type information:
ErrorTypeTextArea.ResizeDirection
| Name | Type | Description | Default |
|---|---|---|---|
None | 'none' | 'none' | |
Both | 'both' | 'both' | |
Horizontal | 'horizontal' | 'horizontal' | |
Vertical | 'vertical' | 'vertical' |
Specifications
Content Guidelines
- Refer to the guidelines on Placeholder Text in the Content Style Guide for more tips on how to write placeholder text.
Anatomy

- Label: Title of the Text Area.
- Input Container: Rectangular container that houses the placeholder and body text.
- Placeholder/Body Text: Placeholder text is optional and shows an example text entry or instructional text.
Interaction States
Text Areas support inactive, active, and disabled interaction states.
Inactive states are the default state if the text area is not active, disabled, or displaying an alert.

Active states are displayed with a blue border, a cursor, and a keyboard.

Disabled states are grayed out to prevent users from interacting with the text area.

When pressing on the text area, the container fill changes to gray to provide touch feedback to the user.

Notification States
Notification states on mobile include additional visual affordances. They include an icon and a notification label.

Variations
Dynamic Height
This is the default behavior. Dynamic height text areas have a fixed base height that grows as the height of the content exceeds the initial height.

Fixed Height
Fixed height text areas should be used for data dense pages. Their fixed size helps reduce the overall density and visual load on the page.
If content exceeds the height of the Text Area, users can scroll within the input field to view the rest of the text. When inactive, content is shown to overflow at the bottom. When active, the content is scrollable, indicated by a scrollbar that appears within the text area. When typing, the content pushes up, leaving the cursor at the bottom of the input.

Usage Guidance
- To ensure we don’t overwhelm users, a max of two Text Areas per page is recommended.
- On iOS and Android devices, tapping into a field that is not disabled will cause a cursor to appear as well as a keyboard. As the user types within the Text Area, placeholder text is replaced with the user’s input. Tapping outside of the Text Area should trigger the inactive state.
When to Use
- Use when you need to enter an amount of text that’s longer than a single line.
When to Use Something Else
- Use a Text Input for a single line of text.
- Use a Time Picker if the user is inputting a time.
- Use a Date Picker if the user is inputting a date.
- Use a Rich Text Editor if input styling is needed.
- Use a Select dropdown, Radio Button, or Checkbox if inputted data is predetermined.
Mobile Guidance
Mobile Text Areas have larger typography for increased readability on smaller screens.
API Guidelines
Component Definition
LabelledTextArea
public struct LabelledTextArea: ViewCanvasKit design TextArea
Properties
body
public var body: some ViewMethods
init(text:placeholderText:label:accessibilityLabel:helperText:context:isExpandable:)
public init(
text: Binding<String>,
placeholderText: String?,
label: String,
accessibilityLabel: String,
helperText: String?,
context: Binding<SemanticContext>,
isExpandable: Bool = true
)Create an instance of LabelledTextArea.
Parameters
| Name | Description |
|---|---|
| text | Text binding in field, already localized |
| placeholderText | Label for possible content of field, already localized |
| label | Label to be positioned above field, already localized |
| accessibilityLabel | Accessibility label of field, already localized |
| helperText | Helper text below field, already localized |
| context | SemanticContext of the field |
| isExpandable | Whether height of the field is dynamic |
init(text:placeholderText:label:helperText:context:isExpandable:localizer:)
public init(
text: Binding<String>,
placeholderText: String? = "",
label: String,
helperText: String?,
context: Binding<SemanticContext>,
isExpandable: Bool = true,
localizer: LocalizationAdapting
)Content Guidelines
Refer to the guidelines on Placeholder Text in the Content Style Guide for more tips on how to write placeholder text.
Anatomy

- Label: Title of the Text Area.
- Input Container: Rectangular container that houses the placeholder and body text.
- Placeholder/Body Text: Placeholder text is optional and shows an example text entry or instructional text.
Interaction States
Text Areas support inactive, active, and disabled interaction states.
Inactive states are the default state if the text area is not active, disabled, or displaying an alert.

Active states are displayed with a blue border, a cursor, and a keyboard.

Disabled states are grayed out to prevent users from interacting with the text area.

When pressing on the text area, the container fill changes to gray to provide touch feedback to the user.

Notification States
Notification states on mobile include additional visual affordances. They include an icon and a notification label.

Variations
Dynamic Height
This is the default behavior. Dynamic height text areas have a fixed base height that grows as the height of the content exceeds the initial height.

Fixed Height
Fixed height text areas should be used for data dense pages. Their fixed size helps reduce the density and visual load on the page.
If content exceeds the height of the text area, users can scroll within the input field to view the rest of the text. When inactive, content overflows at the bottom of the input. When active, the content is scrollable, indicated by a scrollbar that appears within the text area. When typing, content pushes up, leaving the cursor at the bottom of the input.

Usage Guidance
- To ensure we don’t overwhelm users, a max of two Text Areas per page is recommended.
- On iOS and Android devices, tapping into a field or label that is not disabled will cause a text cursor to appear as well as a corresponding keyboard. As the user types within the Text Area, any placeholder text is replaced with the user’s input. Tapping outside of the Text Area should trigger the inactive state.
When to Use
- Use when you need to enter an amount of text that’s longer than a single line.
When to Use Something Else
- Use a Text Input for a single line of text.
- Use a Time Picker if the user is inputting a time.
- Use a Date Picker if the user is inputting a date.
- Use a Rich Text Editor if input styling is needed.
- Use a Select dropdown, Radio, or Checkbox if inputted data is predetermined.
Mobile Guidance
Mobile Text Areas have larger typography for increased readability on smaller screens.
API Guidelines
Component Definition
@Composable
fun NonInteractivePillUiComponent(
modifier: Modifier = Modifier,
label: String? = null,
value: String,
onValueChange: String -> Unit,
readOnly: Boolean = false,
textStyle: TextStyle = LocalTextStyle.current,
placeholder: String? = null,
placeholderTextStyle: TextStyle = WorkdayTheme.canvasTypography.bodyMedium,
heightConfig: TextInputHeightConfig = TextInputHeightConfig.SingleLineConfig,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
leadingIcon: @Composable() -> Unit? = null,
trailingIcon: @Composable() -> Unit? = null,
visualTransformation: VisualTransformation = VisualTransformation.None,
helperText: String? = null,
onClickInputText: () -> Unit = {},
onClickClearTextIcon: () -> Unit = {},
keyboardOptions: KeyboardOptions = defaultKeyboardOptions(
isSingleLine = heightConfig.isSingleLine
),
keyboardActions: KeyboardActions = defaultKeyboardActions(),
semanticState: SemanticState = SemanticState())
) {Parameters
| Name | Description |
|---|---|
| modifier | Modifier to be applied to the TextInputUiComponent |
| label | The text above the input that typically designates the name of the component. |
| value | The text to be displayed inside of the text input. |
| onValueChange | Callback lambda that is executed whenever the text of the input changes. |
| readOnly | Removes the ability for user input into the text input. The entire Input surface provides a ripple click animation when readOnly is set to true. |
| textStyle | The style to be applied to the input text. The default textStyle uses the LocalTextStyle defined by the theme. |
| placeholder | This text is shown inside of the input when the value is empty to provide a hint to the user. |
| placeholderTextStyle | Configures the placeholder typography style. |
| heightConfig | Toggles between a TextInput and TextArea UI Component. Provides min height and max lines configurations for multi-line inputs. |
| interactionSource | The MutableInteractionSource representing the stream of Interactions for this TextInputUiComponent. You can create and pass in your own remembered MutableInteractionSource if you want to observe Interactions and customize the appearance / behavior of this TextInputUiComponent in different Interactions. |
| leadingIcon | The optional leading icon rendered at the start of the input area. |
| trailingIcon | The optional trailing icon rendered at the end of the input area. |
| visualTransformation | Transforms the visual representation of the input value For example, you can use PasswordVisualTransformation to create a password text field. By default no visual transformation is applied. |
| helperText | Helper text is displayed underneath the input area that to give additional context to the user. Error and Alert helper text prefixes are localized and automatically displayed when the component’s semanticState is changed |
| onClickInputText | Callback lambda that is executed when the user clicks on the Input area. |
| onClickClearTextIcon | Callback lambda that is executed when the user clicks on the “clear text” trailingIcon that is displayed while the component is focused. |
| keyboardOptions | Software keyboard options that contains configuration such as KeyboardType and ImeAction. For TextInputHeightConfig.SingleLineConfig, by default ImeAction.Done is provided as keyboard option. For TextInputHeightConfig.DynamicMultiLineConfig and TextInputHeightConfig.FixedMultiLineConfig) by default KeyboardOptions.Default is provided. |
| keyboardActions | when the input service emits an IME action, the corresponding callback is called. Note that this IME action may be different from what you specified in KeyboardOptions.imeAction. By default for KeyboardActions.onDone keyboard is hidden and focus is cleared of the input area. |
| semanticState | Adjusts the state of the Component. This allows for enabling, disabling, warning, error, and required states. |
Content Guidelines
Refer to the guidelines on Placeholder Text in the Content Style Guide for more tips on how to write placeholder text.
Can't Find What You Need?
Check out our FAQ section which may help you find the information you're looking for. For further information, contact the #ask-canvas-design or #ask-canvas-kitchannels on Slack.