Combobox
검색 가능한 드롭다운 선택 컴포넌트
개요
Combobox는 base-ui의 Combobox Primitive를 기반으로 구축된 검색형 선택 컴포넌트입니다. 텍스트 입력으로 항목을 필터링하고, 단일/다중 선택을 모두 지원합니다.
주요 특징
- ✅ 컴파운드 컴포넌트: Combobox, ComboboxInput, ComboboxContent, ComboboxList, ComboboxItem 등 유연한 구성
- ✅ 검색 필터링: 텍스트 입력으로 항목 실시간 검색
- ✅ 단일/다중 선택: 칩 기반 다중 선택 지원
- ✅ 그룹화: ComboboxGroup + ComboboxLabel로 옵션 그룹화
- ✅ Sizes: ComboboxInput에 xs, sm, md, lg, xl 5단계 크기
- ✅ 접근성: WAI-ARIA Combobox 패턴
- ✅ 디자인 토큰: 테마 커스터마이징 지원
구조 (Anatomy)
const items = ["옵션 1", "옵션 2", "옵션 3"]
<Combobox items={items}>
<ComboboxInput placeholder="검색..." />
<ComboboxContent>
<ComboboxEmpty>검색 결과 없음</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>{item}</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>참고:
itemsprop과ComboboxList의 render function 패턴을 사용해야 검색 필터링이 동작합니다. 객체 아이템을 사용하는 경우itemToStringValueprop으로 검색에 사용할 문자열을 지정합니다.
Sizes
ComboboxInput에 5가지 크기를 지원합니다. 기본값은 md입니다.
Preview
사용 예시
기본 사용
Preview
그룹화 옵션
ComboboxGroup과 ComboboxLabel로 옵션을 그룹화합니다.
그룹화는 static children 패턴을 사용합니다.
items+ render function 패턴과 함께 사용하려면 데이터 구조에 맞는 커스텀 로직이 필요합니다.
Preview
검색 결과 없음
ComboboxEmpty로 검색 결과가 없을 때 안내 문구를 표시합니다.
Preview
클리어 버튼
ComboboxInput의 showClear prop으로 선택 초기화 버튼을 표시합니다.
Preview
비활성 상태
Combobox의 disabled prop 또는 개별 ComboboxItem의 disabled로 비활성화합니다.
Preview
기본값 설정
defaultValue prop으로 초기 선택값을 지정합니다.
Preview
API Reference
Combobox
Combobox의 루트 컴포넌트입니다. base-ui Combobox를 래핑합니다.
| Prop | Type | Default | Description |
|---|---|---|---|
items | T[] | - | 아이템 배열 (필터링에 필수) |
value | T | T[] | null | - | 제어 모드 선택값 |
defaultValue | T | T[] | null | - | 초기 선택값 |
onValueChange | (value, eventDetails) => void | - | 값 변경 콜백 |
inputValue | string | - | 제어 모드 입력값 |
onInputValueChange | (value: string) => void | - | 입력값 변경 콜백 |
multiple | boolean | false | 다중 선택 모드 |
disabled | boolean | false | 비활성 상태 |
autoHighlight | boolean | false | 필터링 시 첫 번째 매칭 항목 자동 하이라이트 |
itemToStringValue | (item: T) => string | - | 아이템을 검색 문자열로 변환 (객체 아이템 필수) |
filter | (item: T, query: string) => boolean | - | 커스텀 필터 함수 |
ComboboxInput
검색 입력 + 트리거 컴포넌트입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
size | "xs" | "sm" | "md" | "lg" | "xl" | "md" | 입력 크기 |
placeholder | string | - | 플레이스홀더 |
showClear | boolean | false | 클리어 버튼 표시 |
disabled | boolean | - | 비활성 상태 |
className | string | - | 추가 CSS 클래스 |
ComboboxContent
드롭다운 팝업 컨테이너입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
anchor | React.RefObject | - | 앵커 요소 (다중용) |
className | string | - | 추가 CSS 클래스 |
ComboboxList
항목 리스트 컨테이너입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | 추가 CSS 클래스 |
ComboboxItem
개별 선택 옵션입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
value | string | - | 옵션 값 (필수) |
disabled | boolean | - | 비활성 상태 |
className | string | - | 추가 CSS 클래스 |
ComboboxGroup
옵션을 그룹화하는 컨테이너입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | 추가 CSS 클래스 |
ComboboxLabel
ComboboxGroup의 라벨입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | 추가 CSS 클래스 |
ComboboxEmpty
검색 결과가 없을 때 표시되는 컴포넌트입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | 추가 CSS 클래스 |
ComboboxSeparator
그룹 사이의 구분선입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | 추가 CSS 클래스 |
ComboboxChips
다중 선택 시 칩을 감싸는 컨테이너입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | 추가 CSS 클래스 |
ComboboxChip
다중 선택 시 개별 칩 컴포넌트입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | 추가 CSS 클래스 |
ComboboxChipsInput
다중 선택 모드에서 칩 컨테이너 안의 입력 필드입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
placeholder | string | - | 플레이스홀더 |
disabled | boolean | - | 비활성 상태 |
className | string | - | 추가 CSS 클래스 |
ComboboxClear
선택 값을 초기화하는 버튼입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
disabled | boolean | - | 비활성 상태 |
className | string | - | 추가 CSS 클래스 |
ComboboxValue
다중 선택 시 선택된 값을 렌더링하는 render-prop 컴포넌트입니다.
| Prop | Type | Default | Description |
|---|---|---|---|
children | (values: string[]) => ReactNode | - | 값 렌더링 함수 |
기본 사용법
import {
Combobox,
ComboboxInput,
ComboboxContent,
ComboboxList,
ComboboxItem,
ComboboxEmpty,
} from "@vortex/ui-foundation"
const frameworks = ["Next.js", "SvelteKit", "Nuxt.js", "Remix", "Astro"]
// 기본 (items + render function 패턴으로 필터링 활성화)
<Combobox items={frameworks}>
<ComboboxInput placeholder="검색..." style={{width: 200}} />
<ComboboxContent>
<ComboboxEmpty>결과 없음</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item} value={item}>{item}</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>
// 객체 아이템
const items = [
{ label: "Next.js", value: "next" },
{ label: "Remix", value: "remix" },
]
<Combobox items={items} itemToStringValue={(item) => item.label}>
<ComboboxInput placeholder="검색..." style={{width: 200}} />
<ComboboxContent>
<ComboboxEmpty>결과 없음</ComboboxEmpty>
<ComboboxList>
{(item) => (
<ComboboxItem key={item.value} value={item}>{item.label}</ComboboxItem>
)}
</ComboboxList>
</ComboboxContent>
</Combobox>접근성
ARIA 속성
- base-ui가
role="combobox",aria-expanded,aria-controls를 자동 설정 - 선택된 아이템에 체크 아이콘 자동 렌더링
키보드 네비게이션
- 입력: 텍스트 입력으로 항목 필터링
- Arrow Up / Down: 옵션 탐색
- Enter: 옵션 선택
- Esc: 드롭다운 닫기
권장 사항
- ✅ 명확한 placeholder 텍스트 제공
- ✅ 대량의 항목에서 검색이 필요한 경우 사용
- ✅ ComboboxEmpty로 빈 결과 안내 제공
- ❌ 항목이 적은 경우 Select 사용 권장