ChipInput | CoUI

ChipInput

칩(태그) 형태로 여러 항목을 입력하고 관리하는 컴포넌트

ChipInput#

텍스트를 입력하고 Enter로 확인하면 칩(태그) 형태로 추가되는 다중 항목 입력 컴포넌트입니다. 각 칩에는 제거 버튼이 있고, 칩 목록은 List<String>이라 Flutter / Web API가 동일합니다.

Live Preview#

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

  @override
  State<ChipInputDefaultExample> createState() =>
      _ChipInputDefaultExampleState();
}

class _ChipInputDefaultExampleState extends State<ChipInputDefaultExample> {
  List<String> _chips = const <String>['Flutter', 'Dart'];

  void handleChanged(List<String> chips) {
    setState(() {
      _chips = chips;
    });
  }

  void handleSubmitted(String text) {
    setState(() {
      _chips = [..._chips, text];
    });
  }

  @override
  Component build(BuildContext context) {
    return ChipInput(
      chips: _chips,
      placeholder: 'Add a tag...',
      onChanged: handleChanged,
      onSubmitted: handleSubmitted,
    );
  }
}
class ChipInputDefaultExample extends StatefulWidget {
  const ChipInputDefaultExample({super.key});

  @override
  State<ChipInputDefaultExample> createState() =>
      _ChipInputDefaultExampleState();
}

class _ChipInputDefaultExampleState extends State<ChipInputDefaultExample> {
  List<String> _chips = const <String>['Flutter', 'Dart'];

  void handleChanged(List<String> chips) {
    setState(() {
      _chips = chips;
    });
  }

  void handleSubmitted(String text) {
    setState(() {
      _chips = [..._chips, text];
    });
  }

  @override
  Widget build(BuildContext context) {
    return ChipInput(
      chips: _chips,
      placeholder: 'Add a tag...',
      onChanged: handleChanged,
      onSubmitted: handleSubmitted,
    );
  }
}

사용 시기 (When to Use)#

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

  • 태그 / 키워드처럼 자유 입력 다중 값을 받는 경우
  • 입력한 항목을 칩으로 시각화하고 개별 제거가 필요한 경우

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

  • Select: 미리 정의된 옵션 중에서 다중 선택할 때
  • Autocomplete: 단일 값 + 추천 목록이 필요할 때

기본 사용법 (Basic Usage)#

// 기본 칩 입력
ChipInput(
  chips: tags,
  placeholder: 'Add a tag...',
  onChanged: (chips) => setState(() => tags = chips),
  onSubmitted: (text) => setState(() => tags = [...tags, text]),
)

// 최대 개수 제한
ChipInput(
  chips: tags,
  maxChips: 5,
  onChanged: handleChanged,
  onSubmitted: handleSubmitted,
)
// 기본 칩 입력
ChipInput(
  chips: tags,
  placeholder: 'Add a tag...',
  onChanged: (chips) => setState(() => tags = chips),
  onSubmitted: (text) => setState(() => tags = [...tags, text]),
)

// 최대 개수 제한
ChipInput(
  chips: tags,
  maxChips: 5,
  onChanged: handleChanged,
  onSubmitted: handleSubmitted,
)

Props / Parameters#

속성타입기본값설명
chips List<String> [] 현재 칩 목록
placeholder String? null 입력 필드 안내 문구
enabledbooltrue입력 가능 여부
maxChips int? null 최대 칩 개수 (null = 무제한)
onChanged ValueChanged<List<String>>? null 칩 목록 변경 콜백 (추가/제거)
onSubmitted ValueChanged<String>? null Enter로 텍스트 확정 시 콜백
chipInputStyle CoreChipInputStyle? null 컨테이너 / 칩 chrome 오버라이드

동작 스펙 (Behavior)#

  • 칩 추가: 텍스트 입력 후 Enter → onSubmitted(text) 호출, 입력 필드 비움
  • 칩 제거: 칩의 X 버튼 클릭 → 해당 칩 제거된 목록으로 onChanged 호출
  • maxChips: 칩 개수가 한도에 도달하면 입력 필드를 숨김

접근성 (Accessibility)#

  • 컨테이너: role="group" + aria-label="Chip input"
  • 제거 버튼: aria-label="Remove {chip}"

크로스 플랫폼 차이점 (Platform Differences)#

항목FlutterWeb
클래스명ChipInputChipInput
입력 필드EditableText네이티브 <input>
포커스 링FocusOutline:focus-within ring