Textarea

TextAreas are multiline text inputs, useful for cases where users have a sizable amount of text to enter. They allow for all customizations that are available to text fields.

Quick Start

Installation
npm install @adaptavant/eds-core
Import
import { Textarea } from '@adaptavant/eds-core';

Size

Customise the size of the Textarea via the size prop on field.

{/* standard */}
<Field label="Standard textarea" size="standard">
   <Textarea placeholder="Placeholder" />
</Field>

{/* large */}
<Field label="Large textarea" size="large">
   <Textarea placeholder="Placeholder" />
</Field>

Appearance

The appearance of the Textarea can be changed by wrapping it with different types of field components.

To achieve a "standard" appearance, wrap the Textarea component with the Field component.

<Field label="Standard textarea" labelVisibility="hidden">
   <Textarea placeholder="Placeholder" />
</Field>

To achieve a "subtle" appearance, wrap the Textarea component with the InlineField component.

<InlineField label="Subtle textarea" labelVisibility="hidden">
  <Textarea placeholder="Placeholder" />
</InlineField>

Controlled

To control a Textarea provide a value, as well as an onChange function to set the new value whenever it is updated.

const [value, setValue] = React.useState(defaultValue);
const handleChange = (event) => setValue(event.target.value)

return (
  <Stack gap="8">
    <Field label="Controlled example">
      <Textarea value={value} onChange={handleChange} />
    </Field>
    <Text>The current value is: {value}</Text>
  </Stack>
);

Uncontrolled

When using formData from a request object to populate form data, you can use an uncontrolled Textarea component. In this case, you don't need to provide any state or update functions.

If you're using a form library like react-hook-form that uses an imperative API to retrieve the value of a form control, we forward the ref to the underlying <textarea> element. Here's an example:

const ref = useRef(null);

return (
  <Stack gap="8">
    <Field label="Uncontrolled example">
      <Textarea ref={ref} placeholder="Placeholder" />
    </Field>
  </Stack>
);

With characters limit counter

Utilize the "Counter" prop with numerical value, maxValue and isAlwaysVisible parameters within the <Field> component to enable the built-in Counter UI beneath the <Textarea>.

The Counter component shows the variance between the value and the maxValue, along with a circle indicating progress completion. When maxValue is greater than value counter will show negative number.

Note: By default, the counter is hidden. Use the isAlwaysVisible property in counter props to keep the counter visible.

40
const [inputValue, setInputValueValue] = React.useState('');
const maxLength = 40;

return (
  <Field
    className="w-[300px]"
    label="Characters counter demo"
    counter={{
      value: inputValue.length,
      maxValue: maxLength,
      isAlwaysVisible: true
    }}
    errorMessage={inputValue.length > maxLength ? 'Max length exceeded' : undefined}
  >
   <Textarea 
     placeholder="Enter more than 20 character to view counter"
     defaultValue={inputValue}
     onChange={(event) => setInputValueValue(event.target.value)}
   />
  </Field>
)

Disabled

Use the isDisabled prop for <Field/> to show that a TextArea isn't usable.

<Field label="Standard textarea" isDisabled>
   <Textarea placeholder="Placeholder" />
</Field>

Auto-Growing

This example demonstrates an auto-growing <Textarea/> that adjusts its height dynamically using onChange, ensuring a smooth expansion without vertical scrolling.

const textAreaRef = React.useRef(null);
const adjustHeight = () => {
  const textarea = textAreaRef.current;
  if (textarea) {
    textarea.style.height = "auto"; // Reset height
    textarea.style.height = `${textarea.scrollHeight}px`; // Set new height
  }
};

return (
  <Field
    className="w-full"
    label="Auto-growing textarea"
    labelVisibility="hidden"
  >
    <Textarea
      ref={textAreaRef}
      placeholder="Type something..."
      onChange={adjustHeight}
    />
  </Field>
);

Style API

Our design system components include style props that allow you to easily customize different parts of each component to match your design needs.

Please refer to the Style API documentation for more insights.

Textarea parts

<Field label="Textarea">
  <Textarea
    className="bg-positive text-primary placeholder:text-primary"
    classNames={{
      focusIndicator: 'border-2 border-input-critical'
    }}
    placeholder="Enter text here..."
  />
</Field>

Stylable Parts

Description

className

The main container that wraps the textarea element.

focusIndicator

The visual indicator that appears when the textarea is focused.