Combobox
먼저 보고, 그다음 계약을 읽습니다
타이핑으로 필터링하는 인라인 자동완성 (input + listbox).
Component intent의도와 경계 읽기
input(role=combobox) 아래에 필터된 listbox 가 떠 있는 WAI-ARIA combobox 패턴. CommandPalette 와 같은 필터·키보드 내비·한국어 IME 가드 로직을 쓰되, modal dialog 대신 Popover anchor 로 인라인 렌더한다. 포커스는 항상 input 에 머물고 aria-activedescendant 로 가상 포커스만 이동하며, 팝업은 portal 로 떠 overflow:hidden 부모에 갇히지 않는다. 옵션이 적고 고정이면 Select 를 검토.
예제
SSOT에 등록된 실제 API 기준 snippet입니다. standalone 배지만 독립 실행 단위이며, fragment는 주변 state·handler 문맥을 생략합니다.
import { Combobox } from "@axe/ui";<Combobox items={[ { value: "kr", label: "한국", keywords: "korea south" }, { value: "us", label: "미국", keywords: "usa united states" }, { value: "jp", label: "일본", keywords: "japan" }, ]} value={value} onValueChange={setValue} placeholder="국가 검색…" emptyText="일치하는 국가 없음"/>Props
TSX 소스가 진실입니다. 주요 export 컴포넌트의 public API만 노출합니다.
| 이름 | 타입 | 필수 | 기본값 | 설명 |
|---|---|---|---|---|
items | ComboboxItem[] | 필수 | — | 옵션 목록. 각 항목 = { value, label, keywords? } (keywords 는 label 외 추가 검색 대상). |
value | string | — | — | 선택된 value (controlled). |
onValueChange | (value: string) => void | — | — | 항목 선택 시 콜백. |
placeholder | string | — | "검색…" | input placeholder. |
emptyText | string | — | "결과 없음" | 필터 결과가 0건일 때 표시할 텍스트. |
disabled | boolean | — | false | 입력·열림 비활성. |
className | string | — | — | 루트 .axe-combobox 에 병합. |
.axe-* 클래스 계약
React 밖에서도 같은 표면을 그리는 공개 계약입니다. stable은 minor 버전 안에서 이름을 바꾸지 않습니다.
| 클래스 | 안정성 | 용도 |
|---|---|---|
.axe-combobox | stable | 루트 래퍼(Popover anchor). |
.axe-combobox__input | stable | 필터 input(role=combobox) — Select 트리거와 동일 sizing/border/ring 토큰. |
.axe-combobox__content | stable | 포털로 뜨는 팝업 패널. |
.axe-combobox__list | stable | 옵션 스크롤 리스트(role=listbox). |
.axe-combobox__item | stable | 옵션 row(role=option) — aria-selected/hover 시 강조. |
.axe-combobox__empty | stable | 결과 없음 안내 영역. |
접근성
키보드, ARIA, 구현 노트를 함께 검토합니다.
- ↓ 로 열기 / 다음 항목, ↑ 로 이전 항목
- Enter 로 활성 항목 선택 (단, 한글 IME 조합 중 Enter 는 글자 확정으로 처리해 선택되지 않음)
- Esc 로 닫고 입력 쿼리 초기화
input 에 role=combobox·aria-autocomplete=list·aria-expanded·aria-controls(listbox), 열림 시 aria-activedescendant 로 활성 옵션을 가리킴. 리스트=role=listbox, 각 옵션=role=option + aria-selected. 실제 DOM 포커스는 input 에 고정된다.
Popover open/close auto-focus 를 막아 포커스가 input 밖으로 나가지 않는다. 옵션 클릭은 mousedown 으로 확정(input blur 로 닫히기 전). 활성 옵션은 scrollIntoView 로 항상 시야에 유지. portal 렌더라 overflow:hidden 부모에 갇히지 않음.