TextArea | CoUI

TextArea

여러 줄 텍스트 입력 영역 컴포넌트

TextArea#

여러 줄의 텍스트를 입력받는 텍스트 영역 컴포넌트입니다. Flutter/Web 양쪽에서 동일한 API(CoTextArea)를 제공합니다.

Live Preview#

Web
Flutter
Loading Flutter...
class TextAreaDefaultExample extends StatefulComponent {
  const TextAreaDefaultExample({super.key});

  @override
  State<TextAreaDefaultExample> createState() =>
      _TextAreaDefaultExampleState();
}

class _TextAreaDefaultExampleState extends State<TextAreaDefaultExample> {
  @override
  Component build(BuildContext context) {
    return CoTextArea(
      placeholder: 'Enter your message...',
      rows: 4,
    );
  }
}
class TextAreaDefaultExample extends StatefulWidget {
  const TextAreaDefaultExample({super.key});

  @override
  State<TextAreaDefaultExample> createState() =>
      _TextAreaDefaultExampleState();
}

class _TextAreaDefaultExampleState extends State<TextAreaDefaultExample> {
  @override
  Widget build(BuildContext context) {
    return CoTextArea(
      placeholder: 'Enter your message...',
      rows: 4,
    );
  }
}

사용 시기 (When to Use)#

이 컴포넌트를 사용하세요:

  • 댓글, 메모, 설명 등 여러 줄 텍스트 입력이 필요할 때
  • 사용자 피드백이나 문의 내용을 받을 때
  • 긴 텍스트 편집이 필요할 때

대신 다른 컴포넌트를 사용하세요:

  • TextField/Input: 한 줄 텍스트 입력
  • Form: 여러 필드 묶어 검증
  • Select: 미리 정의된 옵션 선택

기본 사용법 (Basic Usage)#

// 기본 텍스트 영역
CoTextArea(
  placeholder: 'Enter your message...',
  rows: 4,
  onChanged: (value) => print(value),
)

// 라벨 + 설명 + 에러
CoTextArea(
  label: 'Message',
  description: 'Type your feedback here',
  errorText: hasError ? 'This field is required' : null,
  placeholder: 'Enter your message...',
  onChanged: handleChange,
)

// 크기 조절 가능 (드래그 핸들)
CoTextArea(
  expandableHeight: true,
  expandableWidth: true,
  initialHeight: 150,
  placeholder: 'Drag to resize...',
  onChanged: handleChange,
)
// 기본 텍스트 영역
CoTextArea(
  placeholder: 'Enter your message...',
  rows: 4,
  onChanged: (value) => print(value),
)

// 라벨 + 설명 + 에러
CoTextArea(
  label: 'Message',
  description: 'Type your feedback here',
  errorText: hasError ? 'This field is required' : null,
  placeholder: 'Enter your message...',
  onChanged: handleChange,
)

// rows + maxLength 제어
CoTextArea(
  rows: 6,
  maxLength: 500,
  placeholder: 'Max 500 chars',
  onChanged: handleChange,
)

스타일 시스템 — textAreaStyle (Epic #1302)#

CoTextArea 는 CoTextFieldCoreTextFieldStyle 공유 — chrome 99% 동일하므로 별도 클래스를 만들지 않습니다. multi-line 전용 동작 (rows / expandableHeight / expandableWidth) 은 위젯 파라미터.

CoTextArea(
  variant: CoreTextFieldVariant.outline,                  // ← 시맨틱 enum 위젯 파라미터
  size: CoreComponentSize.md,                              // ← 시맨틱 enum 위젯 파라미터
  rows: 4,                                                 // ← multi-line 동작
  expandableHeight: true,                                  // ← multi-line 동작
  onChanged: handleBio,
  textAreaStyle: CoreTextFieldStyle(                       // ← chrome / 슬롯 (TextField 공유)
    borderRadius: 8,
    paddingH: 16,
    paddingV: 12,
    minHeight: 96,
    maxHeight: 240,
    focusBorderColor: cs.primary,
    valueStyle: CoreTextStyle(fontSize: 14, lineHeight: 1.6),
  ),
)

CoreTextFieldStyle 의 22 필드 — TextField 와 동일. minHeight / maxHeight 는 TextArea 의 auto-grow 제약에 특히 의미가 있습니다.

Resolve chain#

design system default for variant
  → CoreTextAreaTheme.style
  → CoreTextAreaTheme.variantStyles[widget.variant]
  → 부모 컴포넌트 슬롯 오버라이드
  → widget.textAreaStyle

Props / Parameters#

CoTextArea은 Flutter/Web에서 동일한 파라미터 이름을 사용합니다.

속성Flutter 타입Web 타입기본값설명
placeholder String? String? null 빈 상태 안내
initialValue String? String? null 초기 값
onChanged CoreValueChanged<String>? CoreValueChanged<String>? null 값 변경 콜백
onSubmitted CoreValueChanged<String>? CoreValueChanged<String>? null 제출 콜백 (Web은 change 이벤트)
enabled bool bool true 활성화 여부
readOnly bool bool false 읽기 전용
autofocus bool bool false 자동 포커스
variant CoreTextFieldVariant CoreTextFieldVariant defaultVariant 시맨틱 변형 (위젯 파라미터)
size CoreComponentSize CoreComponentSize md 크기 토큰 (위젯 파라미터)
label String? String? null 상단 라벨
description String? String? null 하단 설명 (에러 없을 때)
errorText String? String? null 에러 메시지
required bool bool false 필수 입력 표시
name String? String? null 폼 제출용 필드 이름
maxLength int? int? null 최대 글자 수
rows int? int? null 보이는 행 수
textAlign TextAlign String start 수평 정렬
prefix Widget? Component? null 좌측 아이콘/텍스트
suffix Widget? Component? null 우측 아이콘/텍스트
expandableHeight bool bool false 세로 리사이즈 가능
expandableWidth bool bool false 가로 리사이즈 가능
textAreaStyle CoreTextFieldStyle? CoreTextFieldStyle? null chrome / dimensional / cursor / nested slot 묶음 (TextField Style 공유)
controller TextEditingController? null null Flutter 전용
focusNode FocusNode? null null Flutter 전용

Flutter 전용 확장#

  • obscureText, obscuringCharacter: 텍스트 마스킹
  • textAlignVertical, textDirection: 정렬/방향
  • showCursor, cursorOpacityAnimates: 커서 동작 (시각 chrome 인 cursor color/width/radius 는 textAreaStyle 안)
  • keyboardType, textInputAction, textCapitalization, keyboardAppearance: 키보드
  • maxLengthEnforcement, inputFormatters: 입력 제약
  • onEditingComplete, onTap, onTapOutside: 추가 콜백
  • scrollController, scrollPadding, scrollPhysics: 스크롤
  • selectionControls, selectionHeightStyle, selectionWidthStyle, dragStartBehavior: 선택
  • autocorrect, enableSuggestions, enableInteractiveSelection, enableIMEPersonalizedLearning, stylusHandwritingEnabled: IME
  • autofillHints, clipBehavior, restorationId, contextMenuBuilder, undoController: 고급

Web 전용 확장#

  • cols: HTML cols 속성 (행 너비 추정치)

테마 커스터마이징 (Theme)#

CoreComponentTheme(
  textArea: CoreTextAreaTheme(
    style: CoreTextFieldStyle(            // ← TextField Style 공유
      borderRadius: 8,
      paddingH: 16,
      paddingV: 12,
    ),
    variantStyles: {
      CoreTextFieldVariant.outline: CoreTextFieldStyle(
        focusBorderColor: cs.primary,
      ),
    },
    autocorrect: true,
    enableSuggestions: true,
  ),
)

Resolve 우선순위: widget.textAreaStyle > CoreTextAreaTheme.variantStyles[variant]

CoreTextAreaTheme.style > 디자인 시스템 기본값.

동작 스펙 (Behavior)#

인터랙션#

  • 타이핑: 입력 시 onChanged 호출
  • 포커스 이탈/Enter: onSubmitted 호출 (Web은 change 이벤트)
  • 크기 조절:
    • Flutter: expandableHeight/expandableWidth로 드래그 핸들 표시
    • Web: 네이티브 <textarea> 리사이즈 핸들(resize: vertical) 제공

유효성#

  • maxLength: 초과 입력 차단
  • errorText 존재 시 description 숨김, varianterror로 자동 변경
  • required: true → 라벨 옆 * 표시

시각적 토큰 통일#

  • 기본 변형(defaultVariant): surface 배경 + outlineVariant 보더 + primary 포커스 링
  • 에러 변형(error): error 보더 + error 포커스 링
  • filled: false (기본값) → 투명 배경. filled: true → 변형에 맞는 배경색 적용
  • Flutter/Web 모두 CoreTextFieldVariantStyle을 참조하여 토큰 일관성 유지

접근성 (Accessibility)#

동작
TabTextArea로 포커스
Shift+Tab이전 요소로 포커스
Enter새 줄 삽입
  • Web: <textarea> 네이티브 시맨틱 사용. aria-required, aria-invalid 등 자동.
  • Flutter: Semantics 통해 스크린 리더 지원.