Featuring Design System
Legacy

CoreSelectPrim

레거시 compound Select 컴포넌트. 단일 값 선택을 지원하며 신규 프로젝트에서는 Select로 전환을 권장합니다.

개요

마이그레이션 안내 — 이 컴포넌트는 레거시입니다. 신규 프로젝트에서는 Select를 사용하세요.

SelectPrim은 Radix UI Select 위에 Featuring 디자인 토큰과 상태(status/size/readonly) 전파를 얹은 compound 컴포넌트입니다.

  • Compound 구조Root · Label · Trigger · Value · Portal · Content · Item · HelperText · Group · GroupLabel · Separator 서브 컴포넌트로 구성
  • Context 전파Root에 지정한 status / size / width / disabled / readonly / required가 하위 서브 컴포넌트에 자동 전달
  • 함수형 childrenItemchildren(selected: boolean) => ReactNode로 작성하면 선택 여부에 따라 렌더를 분기할 수 있음
  • Controlled / Uncontrolled 모두 지원

Usage

기본 사용법

<CoreSelectPrim.Root required width="240px">
<CoreSelectPrim.Label tooltip="도움말">Label</CoreSelectPrim.Label>
<CoreSelectPrim.Trigger>
  <CoreSelectPrim.Value placeholder="옵션을 선택하세요" />
</CoreSelectPrim.Trigger>
<CoreSelectPrim.HelperText>Helper Text</CoreSelectPrim.HelperText>
<CoreSelectPrim.Portal>
  <CoreSelectPrim.Content>
    <CoreSelectPrim.Item value="option1">Option 1</CoreSelectPrim.Item>
    <CoreSelectPrim.Item value="option2">Option 2</CoreSelectPrim.Item>
    <CoreSelectPrim.Item value="option3" disabled>Option 3 (disabled)</CoreSelectPrim.Item>
  </CoreSelectPrim.Content>
</CoreSelectPrim.Portal>
</CoreSelectPrim.Root>

Controlled

() => {
const [selected, setSelected] = React.useState('option1');
return (
  <CoreSelectPrim.Root value={selected} onValueChange={setSelected} required width="240px">
    <CoreSelectPrim.Label>Label</CoreSelectPrim.Label>
    <CoreSelectPrim.Trigger>
      <CoreSelectPrim.Value />
    </CoreSelectPrim.Trigger>
    <CoreSelectPrim.Portal>
      <CoreSelectPrim.Content>
        <CoreSelectPrim.Item value="option1">Option 1</CoreSelectPrim.Item>
        <CoreSelectPrim.Item value="option2">Option 2</CoreSelectPrim.Item>
      </CoreSelectPrim.Content>
    </CoreSelectPrim.Portal>
  </CoreSelectPrim.Root>
);
}

그룹과 구분선

<CoreSelectPrim.Root required width="240px">
<CoreSelectPrim.Label>Label</CoreSelectPrim.Label>
<CoreSelectPrim.Trigger>
  <CoreSelectPrim.Value />
</CoreSelectPrim.Trigger>
<CoreSelectPrim.Portal>
  <CoreSelectPrim.Content>
    <CoreSelectPrim.Group>
      <CoreSelectPrim.GroupLabel>그룹 1</CoreSelectPrim.GroupLabel>
      <CoreSelectPrim.Item value="option1">Option 1</CoreSelectPrim.Item>
      <CoreSelectPrim.Item value="option2">Option 2</CoreSelectPrim.Item>
    </CoreSelectPrim.Group>
    <CoreSelectPrim.Separator />
    <CoreSelectPrim.Group>
      <CoreSelectPrim.GroupLabel>그룹 2</CoreSelectPrim.GroupLabel>
      <CoreSelectPrim.Item value="option3">Option 3</CoreSelectPrim.Item>
      <CoreSelectPrim.Item value="option4">Option 4</CoreSelectPrim.Item>
    </CoreSelectPrim.Group>
  </CoreSelectPrim.Content>
</CoreSelectPrim.Portal>
</CoreSelectPrim.Root>

함수형 children으로 선택 상태 분기

Itemchildren을 함수로 작성하면 selected 파라미터로 선택 여부를 받을 수 있습니다.

<CoreSelectPrim.Root required width="240px">
<CoreSelectPrim.Label>Label</CoreSelectPrim.Label>
<CoreSelectPrim.Trigger>
  <CoreSelectPrim.Value />
</CoreSelectPrim.Trigger>
<CoreSelectPrim.Portal>
  <CoreSelectPrim.Content>
    <CoreSelectPrim.Item value="option1">
      {(selected) => (
        <CoreRadio label="Option 1" checked={selected} onChange={() => {}} />
      )}
    </CoreSelectPrim.Item>
    <CoreSelectPrim.Item value="option2">
      {(selected) => (
        <CoreRadio label="Option 2" checked={selected} onChange={() => {}} />
      )}
    </CoreSelectPrim.Item>
  </CoreSelectPrim.Content>
</CoreSelectPrim.Portal>
</CoreSelectPrim.Root>

상태(status)와 크기(size)

<CoreSelectPrim.Root status="error" size="lg" width="300px" required>
<CoreSelectPrim.Label>Label</CoreSelectPrim.Label>
<CoreSelectPrim.Trigger>
  <CoreSelectPrim.Value />
</CoreSelectPrim.Trigger>
<CoreSelectPrim.HelperText status="error">에러 메시지가 표시됩니다</CoreSelectPrim.HelperText>
<CoreSelectPrim.Portal>
  <CoreSelectPrim.Content height={200}>
    <CoreSelectPrim.Item value="option1">Option 1</CoreSelectPrim.Item>
    <CoreSelectPrim.Item value="option2">Option 2</CoreSelectPrim.Item>
  </CoreSelectPrim.Content>
</CoreSelectPrim.Portal>
</CoreSelectPrim.Root>

커스텀 Value 표시

선택된 값을 Trigger에서 다른 방식으로 표시해야 할 때 Valuechildren을 직접 넣습니다.

() => {
const options = {
  option1: { label: 'Option 1' },
  option2: { label: 'Option 2' },
  option3: { label: 'Option 3' },
};
const [selected, setSelected] = React.useState('option1');
return (
  <CoreSelectPrim.Root value={selected} onValueChange={setSelected} required width="240px">
    <CoreSelectPrim.Label>Label</CoreSelectPrim.Label>
    <CoreSelectPrim.Trigger>
      <CoreSelectPrim.Value>
        <CoreTag text={options[selected]?.label ?? ''} />
      </CoreSelectPrim.Value>
    </CoreSelectPrim.Trigger>
    <CoreSelectPrim.Portal>
      <CoreSelectPrim.Content>
        {Object.entries(options).map(([value, { label }]) => (
          <CoreSelectPrim.Item key={value} value={value}>{label}</CoreSelectPrim.Item>
        ))}
      </CoreSelectPrim.Content>
    </CoreSelectPrim.Portal>
  </CoreSelectPrim.Root>
);
}

Props

CoreSelectPrim.Root

Root는 전체 Select를 감싸는 최상위 컴포넌트입니다. 여기에 설정한 status / size / width / disabled / readonly / required는 모든 하위 서브 컴포넌트에 자동 전달됩니다.

Prop

Type

CoreSelectPrim.Label

Prop

Type

CoreSelectPrim.Trigger

선택된 값을 보여주는 <button> 요소입니다.

Prop

Type

CoreSelectPrim.Value

Trigger 내부에서 선택된 값을 표시합니다.

Prop

Type

CoreSelectPrim.HelperText

Prop

Type

CoreSelectPrim.Portal

옵션 목록을 body에 포털로 렌더합니다. Select.SelectPortalProps를 그대로 수용합니다.

CoreSelectPrim.Content

Prop

Type

CoreSelectPrim.Item

Prop

Type

CoreSelectPrim.Group

옵션을 논리적으로 묶는 컨테이너입니다. Select.SelectGroupProps를 수용합니다.

CoreSelectPrim.GroupLabel

그룹 제목을 표시합니다. Select.SelectLabelProps를 수용합니다.

CoreSelectPrim.Separator

옵션 사이 구분선입니다. Select.SelectSeparatorProps를 수용합니다.

CoreTooltipProps

CoreTooltip 컴포넌트의 props를 참조하세요.

스타일

Label

  • typography: heading[1], color: text-2 (기본) / text-4 (disabled)
  • margin-bottom: spacing-150 (6px)
  • 필수 마크: margin-left: spacing-50 (2px)
  • 툴팁 아이콘: margin-left: spacing-100 (4px)

Trigger

상태border-color
noneborder[1]
warningsupport-warning[3]
errorsupport-error[3]
  • Default: background-color: background-1, color: text-1
  • Hover: background-color: background-2, border-color: border-2
  • Focus / open: border-color: primary[50]
  • Readonly: background-color: background[4], cursor: auto
  • Disabled: background-color: background[4], color: text[4], cursor: not-allowed

Size Variants (Trigger / Item)

sizetypographyTrigger min-heightItem padding-y
smbody[1]28pxspacing-50 (2px)
mdbody[2]32pxspacing-100 (4px)
lgbody[2]40pxspacing-200 (8px)

Content

  • background-color: background-1, padding: spacing-200 (8px), border-radius: radius-100, elevation: elevation-8

Item 상태

  • Highlighted: background-color: primary[10], color: primary[100]
  • Disabled: background-color: toggle-disabled-bg, color: toggle-disabled-text, cursor: not-allowed

HelperText

statuscolor
nonetext-3
warningsupport-warning-3
errorsupport-error-3

마이그레이션 가이드

신규 Select 컴포넌트는 동일한 compound 구조를 유지하면서 Base UI 기반으로 재작성되었습니다. 주요 차이점은 아래와 같습니다.

CoreSelectPrimSelect (신규)
CoreSelectPrim.RootSelect.Root
CoreSelectPrim.Trigger + CoreSelectPrim.ValueSelect.Trigger + Select.Value
CoreSelectPrim.Portal + CoreSelectPrim.ContentSelect.Popup
CoreSelectPrim.ItemSelect.Item
CoreSelectPrim.Group + CoreSelectPrim.GroupLabelSelect.Group + Select.GroupLabel
CoreSelectPrim.SeparatorSelect.Separator
CoreSelectPrim.HelperTextSelect.HelperText