Textarea

Textarea

자동 크기 조절(autosize) 또는 일반 텍스트 영역(textarea) 컴포넌트예요. Input과 Input.Wrapper 컴포넌트의 기능과 모든 textarea 요소 props를 지원해요.

출처: 문서

본문

사용법 (Usage)

Textarea 컴포넌트는 Input과 Input.Wrapper 컴포넌트의 기능과 모든 textarea 요소 props를 지원해요. Textarea 문서에는 컴포넌트가 지원하는 모든 기능이 포함되어 있지 않아요. 사용 가능한 모든 기능은 Input 문서에서 확인할 수 있어요.

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

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

로딩 상태 (Loading state)

loading prop을 설정하면 로딩 인디케이터를 표시해요. 기본적으로 로더는 입력 오른쪽에 표시돼요. loadingPosition prop을 'left' 또는 'right'로 설정해 위치를 바꿀 수 있어요. 이는 API 호출, 검색, 검증 같은 비동기 작업에 유용해요.

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

function Demo() {
  return <Textarea loading loadingPosition="right" />;
}

제어 컴포넌트 (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는 네이티브 textarea 요소와 같은 방식으로 비제어 폼과 함께 사용할 수 있어요. 폼 제출 시 FormData 객체에 textarea 값을 포함하려면 name 속성을 설정해요. 비제어 폼에서 초기 값을 제어하려면 defaultValue prop을 사용해요.

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 name="message" placeholder="Your message" />
      <button type="submit">Submit</button>
    </form>
  );
}

하단 섹션 (Bottom section)

bottomSection prop으로 입력 테두리 안쪽 하단에 콘텐츠를 렌더링할 수 있어요. 문자 카운터, 힌트, 기타 보조 정보를 표시하는 데 유용해요.

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

function Demo() {
  const maxLength = 500;
  const [value, setValue] = useState('');

  return (
    <Textarea
      label="Your message"
      value={value}
      onChange={(event) => setValue(event.currentTarget.value.slice(0, maxLength))}
      bottomSection={
        <Text size="xs" c="dimmed" ta="right">
          {value.length}/{maxLength} characters
        </Text>
      }
    />
  );
}

자동 크기 조절 (Autosize)

자동 크기 조절 textarea의 높이는 maxRows에 도달할 때까지 커지고, maxRows를 설정하지 않으면 무한정 커질 수 있어요.

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

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

크기 조절 활성화 (Enable resize)

기본적으로 resize는 none이에요. 활성화하려면 resize prop을 vertical 또는 both로 설정해요.

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

function Demo() {
  return <Textarea resize="vertical" />;
}

오류 상태 (Error state)

불리언 오류 또는 오류 메시지와 함께 Textarea를 표시할 수 있어요.

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

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

성공 상태 (Success state)

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

function Demo() {
  return <Textarea label="Textarea" description="Looks good!" />;
}

비활성 상태 (Disabled state)

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

function Demo() {
  return <Textarea disabled />;
}

Styles API

Textarea는 Styles API를 지원해요. classNames prop으로 컴포넌트의 내부 요소에 스타일을 추가할 수 있어요. 자세한 내용은 Styles API 문서를 참고해요.

selector 설명
wrapper Input의 루트 요소
input Input 요소
section 왼쪽 및 오른쪽 섹션
bottomSection 하단 섹션 요소, 입력 테두리 안쪽 하단에 렌더링돼요
root 루트 요소
label 라벨 요소
required 필수 별표 요소, 라벨 안에 렌더링돼요
description 설명 요소
error 오류 요소
success 성공 요소

요소 ref 가져오기 (Get element ref)

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

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

접근성 (Accessibility)

Textarea를 label prop 없이 사용하면 화면 판독기(screen readers)가 제대로 알려주지 못해요. aria-label을 설정하면 라벨이 보이지 않아도 화면 판독기가 알려줘요. label prop을 설정하면 별도로 aria-label을 지정할 필요 없이 접근성이 확보돼요.

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

// 접근 불가 입력 – 화면 판독기가 제대로 알려주지 않아요
// function Demo() { return <Textarea />; }

// 접근 가능 입력 – aria-label이 있어요
function Demo() {
  return <Textarea aria-label="Your message" />;
}

더 알아보기 (Learn more)