본문으로 건너뛰기
입력 / select

Select

옵션 목록에서 하나를 고르는 커스텀 셀렉트 (Radix Select 기반).
입력selectStatic specimenselect셀렉트드롭다운dropdown
01 · Specimen

먼저 보고, 그다음 계약을 읽습니다

옵션 목록에서 하나를 고르는 커스텀 셀렉트 (Radix Select 기반).

Workbench 불러오는 중…
Component intent의도와 경계 읽기

네이티브 <select> 와 달리 옵션 row 의 typography·spacing·아이콘을 디자인 토큰으로 통제한다. 키보드 내비게이션·type-ahead·포털 위치 계산은 Radix Select 가 처리하고, @axe/ui 는 트리거·팝업·focus ring 스타일만 입힌다. Select(Root)·SelectTrigger·SelectValue·SelectContent·SelectItem·SelectGroup·SelectLabel·SelectSeparator 를 조합해 쓴다.

02 · Use

예제

SSOT에 등록된 실제 API 기준 snippet입니다. standalone 배지만 독립 실행 단위이며, fragment는 주변 state·handler 문맥을 생략합니다.

01기본tsxfragment
기본
import {  Select,  SelectTrigger,  SelectValue,  SelectContent,  SelectItem,} from "@axe/ui";<Select value={v} onValueChange={setV}>  <SelectTrigger>    <SelectValue placeholder="국가 선택…" />  </SelectTrigger>  <SelectContent>    <SelectItem value="kr">한국</SelectItem>    <SelectItem value="us">미국</SelectItem>    <SelectItem value="jp">일본</SelectItem>  </SelectContent></Select>
02그룹 · 라벨 · 구분선 · lg 사이즈tsxfragment
그룹 · 라벨 · 구분선 · lg 사이즈
import {  Select,  SelectTrigger,  SelectValue,  SelectContent,  SelectGroup,  SelectLabel,  SelectItem,  SelectSeparator,} from "@axe/ui";<Select value={v} onValueChange={setV}>  <SelectTrigger size="lg">    <SelectValue placeholder="담당자…" />  </SelectTrigger>  <SelectContent>    <SelectGroup>      <SelectLabel>운영</SelectLabel>      <SelectItem value="a">강수훈</SelectItem>      <SelectItem value="b">한진우</SelectItem>    </SelectGroup>    <SelectSeparator />    <SelectGroup>      <SelectLabel>외부</SelectLabel>      <SelectItem value="c">외부 감사인</SelectItem>    </SelectGroup>  </SelectContent></Select>
03 · React

Props

TSX 소스가 진실입니다. 주요 export 컴포넌트의 public API만 노출합니다.

이름타입필수기본값설명
valuestring선택된 값 (controlled). Radix Select.Root prop.
onValueChange(value: string) => void값이 바뀔 때 콜백 (Root).
defaultValuestringuncontrolled 초기 선택값 (Root).
disabledbooleanfalse전체 비활성 (Root).
size"md" | "lg""md"SelectTrigger 높이 토큰. md=36px / lg=44px (Input 과 동일).
position"item-aligned" | "popper""popper"SelectContent 배치 전략. popper=트리거 아래 앵커.
sideOffsetnumber6SelectContent 와 트리거 사이 간격(px).
placeholderstringSelectValue 의 미선택 표시 텍스트 (선택 전 muted 색).
value (SelectItem)string필수각 SelectItem 의 옵션 값 — 선택 시 Root onValueChange 로 전달.
...rest각 Radix Select.* props트리거/콘텐츠/아이템 등 각 파트는 대응 Radix 컴포넌트 props(asChild 포함)를 그대로 전파.
04 · Any stack

.axe-* 클래스 계약

React 밖에서도 같은 표면을 그리는 공개 계약입니다. stable은 minor 버전 안에서 이름을 바꾸지 않습니다.

클래스안정성용도
.axe-select__triggerstable트리거 버튼 루트(닫힌 상태 표시).
.axe-select__trigger--lgstablelg 사이즈 변형(44px).
.axe-select__contentstable포털로 뜨는 팝업 패널.
.axe-select__viewportinternal팝업 내부 스크롤 뷰포트(패딩 래퍼) — Radix Viewport.
.axe-select__labelstableSelectLabel — 그룹 제목(대문자 트래킹).
.axe-select__itemstable옵션 row.
.axe-select__indicatorinternal선택된 항목의 체크 표시 슬롯 — Radix ItemIndicator.
.axe-select__separatorstable그룹 구분선.
비-React 소비 노트
포털 위치 계산·open/close·항목 하이라이트가 Radix 런타임(data-state)에 의존해 CSS-only 로는 동작하는 위젯을 재현할 수 없다. .axe-select__* 토큰은 노출되나 실제 소비는 React 컴포넌트를 통해서 한다.
05 · Inclusive

접근성

키보드, ARIA, 구현 노트를 함께 검토합니다.

Keyboard
  • Space/Enter/↓ 로 열기
  • ↑/↓ 로 항목 이동, Home/End 로 처음/끝
  • 글자 입력 시 type-ahead 로 해당 항목 점프
  • Enter 로 선택, Esc 로 닫기(트리거로 포커스 복원)
ARIA

Radix 가 트리거에 aria-haspopup=listbox·aria-expanded 를, 콘텐츠에 role=listbox, 각 아이템에 role=option(선택은 data-state=checked)을 부여. 현재 값은 SelectValue 가 표시.

Notes

focus-visible·열림 시 --ring 적용, 미선택 트리거는 data-placeholder 로 muted 색. 부모 .axe-form-field--error 안에서 자동으로 danger 보더/링. prefers-reduced-motion 시 open/close 애니메이션 제거.

06 · Judgment

권장 · 지양

권장
  • SelectValue 에 placeholder 를 주어 미선택 상태를 명확히.
  • 라벨은 <FormField label=… htmlFor=…> 로 연결하거나 트리거에 aria-label 부여.
  • 옵션이 많고 자유 검색이 필요하면 Combobox 를 대신 검토.
지양
  • 네이티브 <option> 마크업을 섞지 말 것 — 파트는 SelectItem 등으로만.
  • SelectContent 를 overflow:hidden 부모 안에서 position 을 임의 변경하지 말 것(포털이 기본).
검색창을 열면 컴포넌트 인덱스를 불러옵니다.