Select
Select는 사용자가 옵션 목록에서 하나의 값을 선택할 수 있는 드롭다운 컴포넌트입니다. Radix UI의 Select 컴포넌트를 기반으로 구현되었습니다.
- 접근성이 고려된 드롭다운 메뉴를 제공합니다
- 그룹화된 옵션을 지원합니다
- 키보드 탐색과 애니메이션 효과가 포함되어 있습니다
Installation
npx @jongh/cli add select
Usage
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 공식 문서를 참조하세요.