Select

Stable

미리 정의한 옵션 중 하나를 선택하는 필드입니다.

DESIGN & DEVELOPMENTUpdated Sep 2026

Overview

Select는 미리 정의된 목록에서 한 가지 값을 선택할 때 사용합니다. 현재 선택과 변경 가능 여부를 명확하게 전달합니다.

LIVE PREVIEW키보드로도 조작할 수 있어요

여행할 도시 한 곳을 선택해 주세요.

현재 값: 없음

TSX / CSS
<label htmlFor="destination">여행지</label>
<Select id="destination" size="md"
  options={[{ value: 'seoul', label: '서울' }, { value: 'busan', label: '부산' }]}
  placeholder="여행지를 선택하세요"
  aria-describedby="destination-help"
/>
<p id="destination-help">한 곳을 선택해 주세요.</p>

이 가이드의 Select는 네이티브 select로 독립 구현했습니다. 트리거는 원본 site 토큰을 사용하고, 열린 목록의 외형과 키보드 동작은 브라우저·운영체제를 따릅니다.

Anatomy

5. 도움말 또는 오류 메시지

번호구성 요소역할
1Label필드 이름. htmlFor와 id로 연결
2Container크기·경계·배경·포커스 영역
3Selected value / Placeholder현재 선택 값 또는 선택 안내
4Indicator / Options열림 가능성을 알리는 표시와 선택 목록
5Description / Erroraria-describedby로 연결한 도움말·오류 메시지

번호는 구성 요소를 식별하며 배치 순서를 고정하지 않습니다. 레이블은 위나 옆에 배치할 수 있습니다. 옵션의 순서는 선택 맥락에 맞게 정합니다.

Variants

원본 Select는 하나의 기본 스타일을 사용합니다. 필수 선택 여부, 초기 선택과 비활성 옵션을 조합합니다. 이 구현은 단일 선택 전용입니다.

필수 항목입니다. “준비 중” 옵션은 선택할 수 없습니다.

Sizes

원본 공통 Component size 9개를 사용합니다. 기본 md는 40px입니다. 터치 영역이 필요한 화면에서는 lg(44px) 이상을 선택합니다.

SizeHeightPadding XFont size
xxxs
xxs
xs
sm
md
lg
xl
xxl
xxxl

States

Default, Focus, Error, Readonly, Disabled 상태를 지원합니다. 위 Live Preview에서 상태를 바꾸고 Tab으로 실제 포커스를 확인하세요.

Tab으로 포커스를 이동해 보세요.

입력한 값을 확인해 주세요.

값을 확인할 수 있지만 변경할 수 없습니다.

현재 사용할 수 없습니다.

네이티브 select에는 readonly 속성이 없습니다. readOnly에서는 선택된 레이블을 읽기 전용 텍스트 필드로 표시하고, name이 있으면 hidden input으로 실제 값을 전송합니다. 이때 목록은 열리지 않습니다. disabled 상태는 폼 전송에서 제외됩니다.

Select 상태 토큰 전체 · 원본 이름과 매핑
Token정의 / 매핑현재 값
--site-select-default-bgvar(--site-bg-base)
--site-select-default-bordervar(--site-line-default)
--site-select-default-textvar(--site-text-primary)
--site-select-default-iconvar(--site-icon-default-color)
--site-select-focus-bordervar(--site-line-focus)
--site-select-focus-textvar(--site-text-primary)
--site-select-focus-iconvar(--site-icon-strong-color)
--site-select-error-bordervar(--site-line-error)
--site-select-error-textvar(--site-text-error)
--site-select-readonly-bgvar(--site-bg-surface-light)
--site-select-readonly-bordervar(--site-line-default)
--site-select-readonly-textvar(--site-text-primary)
--site-select-readonly-iconvar(--site-icon-muted-color)
--site-select-disabled-bgvar(--site-bg-disabled)
--site-select-disabled-bordervar(--site-line-default)
--site-select-disabled-textvar(--site-text-on-disabled)
--site-select-disabled-iconvar(--site-icon-muted-color)

Guidelines

권장해요

항상 보이는 레이블과 구체적인 도움말을 제공합니다.

오류에는 aria-invalid와 수정 방법을 설명하는 메시지를 함께 제공합니다.

사용자가 이해하는 이름으로 옵션을 표시하고, 실제 값은 고유한 문자열로 관리합니다.

피해주세요

placeholder만으로 레이블을 대신하지 않습니다.

값을 읽기만 해야 할 때 disabled로 정보를 숨기지 않습니다.

검색·다중 선택·비동기 옵션 로딩을 이 단일 Select에 포함하지 않습니다.

원본 색상 값을 보존합니다. 오류·placeholder 등의 대비는 사용하는 배경과 글자 크기에 맞게 확인합니다.

API

이 레포의 API입니다. 원본 Radix의 SelectTrigger/SelectItem 합성 API 대신 options 배열과 네이티브 onChange 이벤트를 사용합니다. className은 컨테이너에 적용됩니다.

PropTypeDefault / 설명
sizexxxs | xxs | xs | sm | md | lg | xl | xxl | xxxlmd
optionsreadonly SelectOption[]필수 · value / label / disabled?
placeholderstring선택 안내 · 값은 빈 문자열
value / defaultValuestring제어 / 초기 값 · 둘 중 하나 사용
disabledbooleanfalse · 조작 및 폼 전송 제외
readOnlybooleanfalse · 값 확인만 허용
aria-invalidboolean | "true" | "false"오류 표시
aria-describedbystring도움말·오류 요소의 id
id / namestring레이블 연결 / 폼 필드 이름
onChangeChangeEventHandler<HTMLSelectElement>변경 이벤트
…native props네이티브 단일 select 속성 (ref 제외)required, autoComplete 등

Code Example

TSX / CSS
'use client';
import { useState } from 'react';
import { Select } from '@/components/select';

export default function DestinationField() {
  const [destination, setDestination] = useState('');
  return (
    <div>
      <label htmlFor="destination">여행지</label>
      <Select id="destination" name="destination"
        value={destination}
        onChange={e => setDestination(e.target.value)}
        placeholder="여행지를 선택하세요"
        options={[
          { value: 'seoul', label: '서울' },
          { value: 'busan', label: '부산' },
        ]}
        aria-describedby="destination-help" />
      <p id="destination-help">여행할 도시 한 곳을 선택하세요.</p>
    </div>
  );
}
작은 원칙이 좋은 경험을 만듭니다.맨 위로