Text Area

A text area takes text that runs over several lines, such as a message, a description or feedback.

A text area takes text that runs over several lines: a comment, a bio, a bug report. For a single line, such as a name or an email address, use a Text Field. For a chat composer that grows as people type and takes attachments, use a Chatbar.

Playground

Drag the bottom-right corner to resize the textarea.

Usage

import { Flex, Text, TextArea } from '@kushagradhawan/kookie-ui';
 
export function FeedbackField() {
  return (
    <Flex direction="column" gap="1">
      <Text as="label" htmlFor="feedback" size="2" weight="medium">
        What could we do better?
      </Text>
      <TextArea
        id="feedback"
        rows={5}
        maxLength={1000}
      />
    </Flex>
  );
}

Best practices

Give it a visible label. Put the label above the text area and connect it with htmlFor or aria-labelledby. A placeholder disappears once someone starts typing.

Set the height to the answer you expect. Use rows so a short note gets two or three lines and a report gets more. People write less when the box looks small.

Let people make it taller. A text area resizes vertically by default, so people can drag the bottom edge when they write more than you planned for. Set resize="none" for a fixed layout, such as a dialog.

Say what is wrong and how to fix it. Set error and pass an errorMessage such as "Describe the problem in at least 20 characters". Show it after someone leaves the field or submits, not while they type.

Use a Text Field for one line. A text area tells people to write a lot. A name, a title or a search term belongs in a Text Field.

Variant

variant sets the look. The values match Text Field, so both can sit in one form.

VariantUse it for
raisedMost forms. This is the default
surfaceFields on a plain background that need a clear edge
softFields inside a card or a panel that already has a border
outlineDense forms where a fill would feel heavy
ghostInline editing, such as a note that looks like text until focused

Size

size sets the text size and padding, and a minimum height of 28, 32, 40 or 48 pixels. Size 2 is the default. Use the same size as the text fields in the same form. rows sets how tall it actually is. size accepts a responsive object, such as { initial: '3', md: '2' }.

Resize

resize sets which way people can drag to resize. It is vertical unless you set it.

ResizeEffect
noneFixed size
verticalTaller or shorter. The best choice for most forms
horizontalWider or narrower
bothAny direction

resize accepts a responsive object, such as { initial: 'none', md: 'vertical' }.

Examples

Character limit

maxLength stops typing at the limit. Show the count below so people know how much room is left.

const [bio, setBio] = React.useState('');
 
<Flex direction="column" gap="1">
  <TextArea
    aria-label="Bio"
    value={bio}
    onChange={(event) => setBio(event.target.value)}
    maxLength={160}
  />
  <Text size="1" emphasis="medium">{bio.length} / 160</Text>
</Flex>

Validation

error marks the text area as invalid and errorMessage shows below it, linked so a screen reader reads it with the field.

<TextArea
  aria-label="Steps to reproduce"
  error
  errorMessage="Describe what you did before the error appeared"
/>

Read-only text

readOnly keeps the text selectable and focusable but stops edits. Use it for something people copy, such as a generated key or a log. Use disabled only when the field doesn't apply right now.

Props

PropTypeDefaultDescription
variant'raised' | 'surface' | 'soft' | 'outline' | 'ghost''raised'The look
size'1' | '2' | '3' | '4', responsive'2'Text size, padding and minimum height
resize'none' | 'vertical' | 'horizontal' | 'both', responsive'vertical'Which way people can resize it
colorAccentColorTheme accentThe colour of the focus ring
radius'none' | 'small' | 'medium' | 'large' | 'full'Theme radiusThe corner
valuestringThe value, when you control it
defaultValuestringThe starting value, when the field controls it
errorbooleanfalseMarks the field as invalid
errorMessagestringText shown below the field and linked to it
requiredbooleanfalseMust be filled before the form submits

TextArea also accepts every attribute of the HTML textarea element, such as rows, placeholder, maxLength, disabled, readOnly and onChange.

Accessibility

KeyAction
TabMoves focus into the text area
EnterStarts a new line
  • Label: The text area renders no label of its own. Connect a visible label with htmlFor and id, or pass aria-label.
  • Errors: error sets aria-invalid. The errorMessage element is linked with aria-describedby and has role="alert", so a screen reader reads it when it appears.
  • Focus: The focus ring wraps the whole box and uses the field's colour.
  • High contrast: In forced colors mode the box draws a real border, since the browser drops its shadows.