import { Textarea } from "@vitality-ds/components";
Textarea
is used for multi-line text inputs, typically within a form. Examples of multi-line inputs include consult notes, invoice notes and comments. For a text input that only requires a single line, like a name, please see the Text Input component.
Unlike other input elements, the
textarea
uses thebody
font size in order to support longer blocks of text for clinical notes without using a lot of screen space.
Building a form? See Form Field for more information on how to use
Textarea
within a form.
If being used as a stand alone component, Textarea
must be passed a name, value and id. When used with FormField
, these props are passed down from FormField
and don't need to be passed again.
name
is a descriptive title for the data expected to be received from the textarea. ATextarea
for patient notes would have the namepatientNotes
for example.value
is what has been input to theTextarea
. Value can also represent default or existing data to prepopulate a textarea in the case of updating data. Name and value work together in the same way akey: value
pair work together in an object.id
is an identifier that enables a label to be associated with theTextarea
and aides in accessibility.
() => { const [value, setValue] = React.useState( "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin in est a tortor facilisis dapibus. Etiam et magna dolor. Ut varius finibus nulla." ); return ( <Textarea value={value} name="dailyReflection" id="dailyReflection" onChange={(event) => setValue(event.target.value)} /> ); };
The callback function passed to the component that triggers on every change event. A typical use case is to set a state with the new value. An event object can be retrieved from the Textarea
.
Read more about HTML change events.
() => { const text = "Lorem ipsum dolor sit amet."; const [value, setValue] = React.useState(text); function changeHandler(event) { setValue(event.target.value); } return ( <Textarea value={value} name="dailyReflection" id="dailyReflection" onChange={changeHandler} /> ); };
Placeholder text is a great way to communicate the structure of data you would expect to be input into Textarea
. Placeholder text should be used sparingly and never in place of a label as this affects both accessiblity and user experience. Placeholder text disappears once you enter a value, so be sure to consider if it's the best solution for the scenario - often helper text is an appropriate alternative.
- Using placeholder text as a label or helper message
() => { const [value, setValue] = React.useState(""); return ( <Stack> <label htmlFor="previousInjuries">Previous injuries</label> <Textarea placeholder="- Injury \n- Injury \n- Injury" value={value} name="previousInjuries" id="previousInjuries" onChange={(event) => setValue(event.target.value)} /> </Stack> ); };
A Textarea
can be disabled by passing a boolean value to the disabled prop. This will grey out the textarea and disable any interaction with the input.
() => { const [value, setValue] = React.useState( "This is a disabled textarea that can't be edited." ); return ( <Textarea disabled value={value} name="disabledTextarea" id="disabledTextarea" onChange={(event) => setValue(event.target.value)} /> ); };
Should the parent ref need to be passed to the Textarea
, create the ref locally and pass the prop.
() => { const parentRef = React.useRef(); const [value, setValue] = React.useState(""); return ( <Textarea ref={parentRef} value={value} name="refTextarea" id="refTextarea" onChange={(event) => { (parentRef.current.style.backgroundColor = "hsl(187, 46%, 78%)"), setValue(event.target.value); }} /> ); };
Use the resize prop to determine how (or if) the textarea will grow/shrink with changes in the amount of input text. Resize defaults to smart
which will dynamically grow and shrink as text is added or removed.
() => { const [smartResizeValue, setSmartResizeValue] = React.useState( "Smart resize (default) - will grow and shrink with the text" ); const [autoResizeValue, setAutoResizeValue] = React.useState( "Auto resize - manually resize textarea both horizontally and vertically" ); const [verticalResizeValue, setVerticalResizeValue] = React.useState( "Vertical resize - manually change the height of the textarea" ); const [horizontalResizeValue, setHorizontalResizeValue] = React.useState( "Horizontal resize - manually adjust the width of the textarea" ); const [noResizeValue, setNoResizeValue] = React.useState( "No resize - the textarea will maintain its size no matter how much text is input" ); const [noResizeShortValue, setNoResizeShortValue] = React.useState( "No resize - adjust the static size by using the minRows prop" ); return ( <Stack> <Stack direction="horizontal"> <Textarea resize="smart" // default, does not need to be passed value={smartResizeValue} name="resizeDemo" id="resizeDemo" onChange={(event) => setSmartResizeValue(event.target.value)} /> <Textarea resize="auto" value={autoResizeValue} name="resizeDemo" id="resizeDemo" onChange={(event) => setAutoResizeValue(event.target.value)} /> </Stack> <Stack direction="horizontal"> <Textarea resize="vertical" value={verticalResizeValue} name="resizeDemo" id="resizeDemo" onChange={(event) => setVerticalResizeValue(event.target.value)} /> <Textarea resize="horizontal" value={horizontalResizeValue} name="resizeDemo" id="resizeDemo" onChange={(event) => setHorizontalResizeValue(event.target.value)} /> </Stack> <Stack direction="horizontal"> <Textarea resize="none" value={noResizeValue} name="resizeDemo" id="resizeDemo" onChange={(event) => setNoResizeValue(event.target.value)} /> <Textarea resize="none" minRows={2} value={noResizeShortValue} name="resizeDemo" id="resizeDemo" onChange={(event) => setNoResizeShortValue(event.target.value)} /> </Stack> </Stack> ); };
There may be occasions where the default 4 rows of text is too tall or short for the space Textarea
is being used in. 4 rows may also inaccurately represents the amount of data you would expect to receive - for example when expecting an address, 2 rows is more suitable, or if expecting a diary entry, 4 rows may not seem like enough. In this case, pass a numeric value to minRows
to set the desired minimum.
Note that while it is possible to pass a value of 1, consider if there's a real use case for this. If only 1 line of text is expected to be input, use a Text Input
instead. The default maximum rows is set to 20, so keep this in mind if setting the minRows
to a high number.
() => { const [address, setAddress] = React.useState( "1/100 Road Name Rd\nBrisbane QLD 4000" ); return ( <Stack> <label htmlFor="address">Address</label> <Textarea minRows={2} value={address} name="address" id="address" onChange={(event) => setAddress(event.target.value)} /> </Stack> ); };
Similarly to minimum rows, there may be a time where it's important to ensure the Textarea
does not grow all the way to the default maximum of 20, or needs to grow beyond 20 lines. In this case, pass a numeric value to represent the maximum number of lines before the Textarea
stops growing and instead offers a scroll bar for any overflow. Applies to both auto and manual resizing.
() => { const notes = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin in est a tortor facilisis dapibus. Etiam et magna dolor. Ut varius finibus nulla et imperdiet. Lorem ipsum dolor sit amet. \n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Proin in est a tortor facilisis dapibus. Etiam et magna dolor. Ut varius finibus nulla et imperdiet. Lorem ipsum dolor sit amet."; return ( <Stack> <label htmlFor="patientNotes">Patient notes</label> <Textarea maxRows={8} value={notes} name="patientNotes" id="patientNotes" onChange={(event) => console.log(event.target.value)} /> </Stack> ); };
Textarea
has an error state hasError
which is a boolean value that changes the styling based on failed validation. Pass hasError
to enable the error state.
() => { const [value, setValue] = React.useState("This textarea failed validation"); const [error, setError] = React.useState(true); return ( <Textarea value={value} hasError={error} name="invalidTextarea" id="invalidTextarea" onChange={(event) => setValue(event.target.value)} /> ); };
Any other valid HTML <textarea>
attributes can be passed to the Textarea
component, and would be expected to perform the same as the native jsx element. See the MDN Docs for more information.
() => { const [value, setValue] = React.useState(""); return ( <Stack> <Textarea // max length is a HTML attribute that will limit the allowed characters maxLength={10} value={value} name="textareaName" id="textareaName" onChange={(event) => setValue(event.target.value)} /> </Stack> ); };
Description
Use this prop to disable the textarea. Disabled textarea's cannot be clicked on, changed, or have text interacted with at all.
Type
boolean
Default Value
false
Description
Optional prop that adds additional 'critical' styling to indicate if the input has failed validation.
Type
(boolean | "true"
Default Value
false
Description
The id of the textarea, used to pair the label with the input
Type
string
Description
Optional prop to set a maximum number of rows on the textarea. If more text is input than space allows, a scroll bar will appear.
Type
number
Default Value
20
Description
Optional prop to set a minimum number of rows on the textarea. Even if no text is input, the textarea will still appear this height. Useful to override the default height if smaller space is available.
Type
number
Default Value
4
Description
The name of the textarea, eg 'consultNotes' to describe what the textarea is for
Type
string
Description
Function triggered on change event
Type
ChangeEventHandler<HTMLTextAreaElement> & ((event: HTMLInputElement) => void)
Description
Handles how the textarea resizes depending on the amount of input text.
Type
("none" | "auto" | "vertical" | "horizontal" | "smart"
Default Value
smart
Description
The value of the textarea. I.e. entered text or retrieved data
Type
(string | number | readonly string[]) & string