Filter | CoUI

Filter

상호 배타적인 옵션을 토글 버튼 그룹으로 묶는 분절형 필터 컨트롤

Filter#

여러 옵션을 라디오 그룹처럼 상호 배타적으로 선택하는 분절형 필터 컨트롤입니다. Flutter/Web 양쪽에서 동일한 API(Filter)를 제공합니다.

Filtercontrolled 컴포넌트입니다 — 선택값은 부모가 groupValue로 소유하고, onValueChanged 콜백으로 상태를 갱신합니다. 선택적으로 reset 버튼을 통해 선택을 해제할 수 있습니다.

Live Preview#

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

  @override
  State<FilterDefaultExample> createState() => _FilterDefaultExampleState();
}

class _FilterDefaultExampleState extends State<FilterDefaultExample> {
  String? _selected = 'svelte';

  void handleValueChanged(String value) {
    setState(() => _selected = value);
  }

  void handleReset() {
    setState(() => _selected = null);
  }

  @override
  Component build(BuildContext context) {
    return Filter<String>(
      groupValue: _selected,
      onValueChanged: handleValueChanged,
      onReset: handleReset,
      showResetButton: true,
      items: const [
        CoreFilterItem(value: 'svelte', label: 'Svelte'),
        CoreFilterItem(value: 'vue', label: 'Vue'),
        CoreFilterItem(value: 'react', label: 'React'),
      ],
    );
  }
}
class FilterDefaultExample extends StatefulWidget {
  const FilterDefaultExample({super.key});

  @override
  State<FilterDefaultExample> createState() => _FilterDefaultExampleState();
}

class _FilterDefaultExampleState extends State<FilterDefaultExample> {
  String? _selected = 'svelte';

  void handleValueChanged(String value) {
    setState(() => _selected = value);
  }

  void handleReset() {
    setState(() => _selected = null);
  }

  @override
  Widget build(BuildContext context) {
    return Filter<String>(
      groupValue: _selected,
      onValueChanged: handleValueChanged,
      onReset: handleReset,
      showResetButton: true,
      items: const [
        CoreFilterItem(value: 'svelte', label: 'Svelte'),
        CoreFilterItem(value: 'vue', label: 'Vue'),
        CoreFilterItem(value: 'react', label: 'React'),
      ],
    );
  }
}

사용 시기 (When to Use)#

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

  • 한정된 옵션 중 하나를 빠르게 전환해야 할 때 (프레임워크, 정렬 기준, 카테고리 등)
  • 옵션이 항상 화면에 모두 노출되어야 할 때
  • 선택 해제(reset) 기능이 필요할 때

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

  • RadioGroup: 폼 안에서 세로 정렬된 라디오 선택
  • Tabs: 콘텐츠 패널 전환이 함께 필요할 때
  • ChipGroup: 다중 선택이 필요할 때

기본 사용법 (Basic Usage)#

Filter<String>(
  groupValue: _selected,
  onValueChanged: (value) => setState(() => _selected = value),
  onReset: () => setState(() => _selected = null),
  showResetButton: true,
  items: const [
    CoreFilterItem(value: 'svelte', label: 'Svelte'),
    CoreFilterItem(value: 'vue', label: 'Vue'),
    CoreFilterItem(value: 'react', label: 'React'),
  ],
)
Filter<String>(
  groupValue: _selected,
  onValueChanged: (value) => setState(() => _selected = value),
  onReset: () => setState(() => _selected = null),
  showResetButton: true,
  items: const [
    CoreFilterItem(value: 'svelte', label: 'Svelte'),
    CoreFilterItem(value: 'vue', label: 'Vue'),
    CoreFilterItem(value: 'react', label: 'React'),
  ],
)

Props / Parameters#

Filter는 Flutter/Web에서 동일한 파라미터 이름을 사용합니다. 타입만 플랫폼별로 다릅니다.

속성Flutter 타입Web 타입기본값설명
variant CoreFilterVariant CoreFilterVariant .segmented 시각 변형
groupValue T? T? 현재 선택된 값
items List<CoreFilterItem<T>> List<CoreFilterItem<T>> 필터 옵션 목록
onValueChanged void Function(T) void Function(T) 항목 선택 콜백
onReset VoidCallback? CoreVoidCallback? null reset 버튼 콜백
showResetButton bool bool false reset 버튼 표시 여부
filterStyle CoreFilterStyle? CoreFilterStyle? null 인스턴스별 스타일 오버라이드

CoreFilterItem<T>value(T)와 label(String) 두 필드를 가집니다.

스타일 커스터마이징 (Style)#

모든 시각 chrome은 단일 filterStyle: CoreFilterStyle? 슬롯으로 들어갑니다.

Filter<String>(
  groupValue: _selected,
  onValueChanged: handleValueChanged,
  items: items,
  filterStyle: const CoreFilterStyle(
    backgroundColor: CoreColor.token(CoreColors.surfaceContainer),
    selectedColor: CoreColor.token(CoreColors.surface),
    itemSpacing: CoreSpace.space4,
  ),
)

CoreFilterStyle 필드: backgroundColor, selectedColor, borderRadius, itemBorderRadius, padding, itemPadding, itemSpacing, resetButtonStyle (리셋 버튼 chrome 단일 진입점 — CoreButtonStyle nested 슬롯: square width/height, padding, borderRadius, animationDuration, rest/hover foreground, leadingIconStyle 글리프), selectedFontWeight, transitionDuration, labelTextStyle, selectedLabelTextStyle.

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

CoreFilterTheme으로 프로젝트 레벨 스타일 오버라이드가 가능합니다.

CoreComponentTheme(
  filter: CoreFilterTheme(
    style: CoreFilterStyle(
      backgroundColor: CoreColor.token(CoreColors.surfaceContainerHigh),
    ),
  ),
)

Resolve 우선순위: 디자인 시스템 기본값 → CoreFilterTheme.styleCoreFilterTheme.variantStyles[variant] → 위젯 filterStyle.

동작 스펙 (Behavior)#

시각#

  • 배경색이 있는 컨테이너 + 토글 버튼 형태의 항목
  • 선택된 항목은 배경색 + 굵은(semibold) 텍스트로 강조
  • 선택 전환 시 150ms 색상 transition

레이아웃#

  • 항목들은 가로로 배치되며 itemSpacing 간격 유지
  • showResetButton: true이고 onReset != null이면 항목들 앞에 X 아이콘 버튼 표시

접근성 (Accessibility)#

  • 컨테이너는 role="radiogroup"
  • 각 항목은 role="radio" + aria-checked + aria-label (Web), Semantics(selected:) (Flutter)
  • reset 버튼은 role="button" + aria-label="Reset filter"