Select
Select는 사용자가 옵션 목록에서 하나의 값을 선택할 수 있는 드롭다운 컴포넌트입니다. Radix UI의 Select 컴포넌트를 기반으로 구현되었습니다.
- 접근성이 고려된 드롭다운 메뉴를 제공합니다
- 그룹화된 옵션을 지원합니다
- 키보드 탐색과 애니메이션 효과가 포함되어 있습니다
Installation
npx @jongh/cli add selectUsage
Select 컴포넌트는 Radix UI의 Select 컴포넌트를 기반으로 구현되었으며, 여러 하위 컴포넌트로 구성됩니다.
컴포넌트 구조
Select.Root: 셀렉트의 모든 파트를 감싸는 컨테이너입니다.Select.Trigger: 드롭다운을 열고 닫는 버튼입니다.Select.Value: 현재 선택된 값을 표시합니다.Select.Portal: 드롭다운 메뉴를 DOM의 최상위 레벨로 포탈링합니다.Select.Content: 드롭다운 메뉴의 콘텐츠를 담는 컨테이너입니다.Select.Viewport: 드롭다운 메뉴의 뷰포트를 정의합니다.Select.Item: 개별 선택 항목을 나타냅니다.Select.ItemText: 항목의 텍스트 부분을 나타냅니다.Select.ItemIndicator: 선택된 항목을 표시하는 인디케이터입니다.Select.Group: 관련 항목들을 그룹화합니다.Select.Label: 그룹의 레이블을 정의합니다.Select.Separator: 항목 그룹 간의 구분선을 제공합니다.Select.Arrow: 콘텐츠와 트리거를 연결하는 화살표를 나타냅니다.Select.ScrollUpButton: 뷰포트에서 위로 스크롤하는 버튼입니다.Select.ScrollDownButton: 뷰포트에서 아래로 스크롤하는 버튼입니다.
Props
Select.Root
defaultValue(string): 초기 선택된 값입니다 (비제어 모드).value(string): 현재 선택된 값입니다 (제어 모드).onValueChange((value: string) => void): 값이 변경될 때 호출되는 함수입니다 (제어 모드).open(boolean): 드롭다운의 열림 상태를 제어합니다 (제어 모드).onOpenChange((open: boolean) => void): 드롭다운의 열림 상태가 변경될 때 호출되는 함수입니다.disabled(boolean): 셀렉트의 비활성화 여부를 지정합니다.name(string): 셀렉트의 폼 이름을 지정합니다.required(boolean): 셀렉트의 필수 입력 여부를 지정합니다.
Select.Trigger
asChild(boolean): 트리거 요소를 자식 요소로 대체합니다. 기본값은false입니다.
Select.Value
placeholder(string): 아무것도 선택되지 않았을 때 표시되는 텍스트입니다.asChild(boolean): 값 요소를 자식 요소로 대체합니다. 기본값은false입니다.
Select.Portal
container(HTMLElement): 포탈링할 컨테이너 요소를 지정합니다.forceMount(boolean): 포탈 컴포넌트를 강제로 마운트합니다.
Select.Content
asChild(boolean): 콘텐츠 요소를 자식 요소로 대체합니다. 기본값은false입니다.position("popper" | "item-aligned"): 콘텐츠의 위치 전략을 지정합니다. 기본값은"popper"입니다.side("top" | "right" | "bottom" | "left"): 콘텐츠가 표시될 트리거 기준 위치입니다.sideOffset(number): 콘텐츠와 트리거 사이의 거리를 지정합니다.align("start" | "center" | "end"): 콘텐츠의 정렬 방향을 지정합니다.alignOffset(number): 정렬 오프셋을 지정합니다.avoidCollisions(boolean): 뷰포트와의 충돌을 방지할지 여부를 지정합니다.forceMount(boolean): 콘텐츠 컴포넌트를 강제로 마운트합니다.
Select.Item
value(string): 이 항목의 고유한 값입니다.disabled(boolean): 항목의 비활성화 여부를 지정합니다.textValue(string): 항목의 텍스트 표현을 지정합니다 (검색용).asChild(boolean): 항목 요소를 자식 요소로 대체합니다. 기본값은false입니다.
Accessibility
Select 컴포넌트는 WAI-ARIA Listbox 디자인 패턴을 따르고 있습니다.
Select.Trigger에는 자동으로aria-haspopup="listbox"가 설정됩니다.Select.Content에는 자동으로role="listbox"가 설정됩니다.Select.Item에는 자동으로role="option"이 설정됩니다.- 셀렉트가 열리면 포커스가 콘텐츠로 이동하고, 닫히면 트리거로 돌아갑니다.
- 화살표 키를 사용하여 항목 간 탐색이 가능합니다.
- Home 및 End 키로 처음과 마지막 항목으로 이동할 수 있습니다.
- 문자 입력으로 항목을 검색할 수 있습니다.
- 필요한 ARIA 속성이 자동으로 설정됩니다.
Example
기본 사용 예시
import * as Select from "@/components/select"
const SelectExample = () => (
<Select.Root>
<Select.Trigger>
<Select.Value placeholder="옵션을 선택하세요" />
</Select.Trigger>
<Select.Content>
<Select.Viewport>
<Select.Item value="option1">옵션 1</Select.Item>
<Select.Item value="option2">옵션 2</Select.Item>
<Select.Item value="option3">옵션 3</Select.Item>
</Select.Viewport>
</Select.Content>
</Select.Root>
)그룹화된 예시
import * as Select from "@/components/select"
const GroupedSelectExample = () => (
<Select.Root>
<Select.Trigger>
<Select.Value placeholder="과일을 선택하세요" />
</Select.Trigger>
<Select.Content>
<Select.Viewport>
<Select.Group>
<Select.Label>국내산</Select.Label>
<Select.Item value="apple">사과</Select.Item>
<Select.Item value="pear">배</Select.Item>
</Select.Group>
<Select.Separator />
<Select.Group>
<Select.Label>수입산</Select.Label>
<Select.Item value="banana">바나나</Select.Item>
<Select.Item value="orange">오렌지</Select.Item>
</Select.Group>
</Select.Viewport>
</Select.Content>
</Select.Root>
)비활성화된 항목 예시
import * as Select from "@/components/select"
const DisabledItemExample = () => (
<Select.Root>
<Select.Trigger>
<Select.Value placeholder="옵션을 선택하세요" />
</Select.Trigger>
<Select.Content>
<Select.Viewport>
<Select.Item value="option1">옵션 1</Select.Item>
<Select.Item value="option2" disabled>
옵션 2 (비활성화)
</Select.Item>
<Select.Item value="option3">옵션 3</Select.Item>
</Select.Viewport>
</Select.Content>
</Select.Root>
)제어 컴포넌트 예시
import * as Select from "@/components/select"
import { useState } from "react"
const ControlledSelectExample = () => {
const [value, setValue] = useState("")
return (
<div>
<p>선택된 값: {value || "없음"}</p>
<Select.Root value={value} onValueChange={setValue}>
<Select.Trigger>
<Select.Value placeholder="옵션을 선택하세요" />
</Select.Trigger>
<Select.Content>
<Select.Viewport>
<Select.Item value="option1">옵션 1</Select.Item>
<Select.Item value="option2">옵션 2</Select.Item>
<Select.Item value="option3">옵션 3</Select.Item>
</Select.Viewport>
</Select.Content>
</Select.Root>
</div>
)
}더 자세한 내용
더 자세한 내용은 Radix UI Select 공식 문서를 참조하세요.