Textarea

Autosize or regular textarea

Usage

Textarea component supports Input and Input.Wrapper component features and all textarea element props. The Textarea documentation does not include all features supported by the component – see the Input documentation to learn about all available features.

Input description

Variant
Size
Radius
import { Textarea } from '@mantine/core';

function Demo() {
  return (
    <Textarea
      label="Input label"
      description="Input description"
      placeholder="Input placeholder"
    />
  );
}

Loading state

Set loading prop to display a loading indicator. By default, the loader is displayed on the right side of the input. You can change the position with the loadingPosition prop to 'left' or 'right'. This is useful for async operations like API calls, searches, or validations:

import { Textarea } from '@mantine/core';

function Demo() {
  return <Textarea placeholder="Your comment" loading />;
}

Controlled

import { useState } from 'react';
import { Textarea } from '@mantine/core';

function Demo() {
  const [value, setValue] = useState('');
  return (
    <Textarea
      value={value}
      onChange={(event) => setValue(event.currentTarget.value)}
    />
  );
}

Uncontrolled

Textarea can be used with uncontrolled forms the same way as a native textarea element. Set the name attribute to include textarea value in FormData object on form submission. To control the initial value in uncontrolled forms, use the defaultValue prop.

Example usage of uncontrolled Textarea with FormData:

import { Textarea } from '@mantine/core';

function Demo() {
  return (
    <form
      onSubmit={(event) => {
        event.preventDefault();
        const formData = new FormData(event.currentTarget);
        console.log('Textarea value:', formData.get('message'));
      }}
    >
      <Textarea label="Enter your message" name="message" />
      <button type="submit">Submit</button>
    </form>
  );
}

Autosize

Autosize textarea uses the react-textarea-autosize package. The textarea height will grow until maxRows are reached or indefinitely if maxRows is not set.

import { Textarea } from '@mantine/core';

function Demo() {
  return (
    <>
      <Textarea
        placeholder="Autosize with no rows limit"
        label="Autosize with no rows limit"
        autosize
        minRows={2}
      />

      <Textarea
        label="Autosize with 4 rows max"
        placeholder="Autosize with 4 rows max"
        autosize
        minRows={2}
        maxRows={4}
      />
    </>
  );
}

Enable resize

By default, resize is none; to enable it, set the resize prop to vertical or both:

import { Textarea } from '@mantine/core';

function Demo() {
  return <Textarea resize="vertical" label="Disabled" placeholder="Your comment" />;
}

Error state

Invalid name

import { Textarea } from '@mantine/core';

function Demo() {
  return (
    <>
      <Textarea label="Boolean error" placeholder="Boolean error" error />
      <Textarea
        mt="md"
        label="With error message"
        placeholder="With error message"
        error="Invalid name"
      />
    </>
  );
}

Disabled state

import { Textarea } from '@mantine/core';

function Demo() {
  return <Textarea label="Disabled" placeholder="Your comment" disabled />;
}

Styles API

Textarea supports the Styles API; you can add styles to any inner element of the component with the classNames prop. Follow the Styles API documentation to learn more.

Description

Error

Component Styles API

Hover over selectors to highlight corresponding elements

/*
 * Hover over selectors to apply outline styles
 *
 */

Get element ref

import { useRef } from 'react';
import { Textarea } from '@mantine/core';

function Demo() {
  const ref = useRef<HTMLTextAreaElement>(null);
  return <Textarea ref={ref} />;
}

Accessibility

If Textarea is used without the label prop, it will not be announced properly by screen readers:

import { Textarea } from '@mantine/core';

// Inaccessible input – screen reader will not announce it properly
function Demo() {
  return <Textarea />;
}

Set aria-label to make the input accessible. In this case the label will not be visible, but screen readers will announce it:

import { Textarea } from '@mantine/core';

// Accessible input – it has aria-label
function Demo() {
  return <Textarea aria-label="My input" />;
}

If the label prop is set, the input will be accessible and it is not required to set aria-label:

import { Textarea } from '@mantine/core';

// Accessible input – it has associated label element
function Demo() {
  return <Textarea label="My input" />;
}