Featuring Design System
Legacy

CoreSegmentedControl

레거시 세그먼트 컨트롤 컴포넌트. SegmentedControl로 마이그레이션을 권장합니다.

개요

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

CoreSegmentedControlCoreSegmentedControlGroup과 함께 사용하는 탭형 선택 컴포넌트입니다.

  • CoreSegmentedControlGroup — 방향(orientation), 크기(size) 등 컨텍스트를 자식에 전달
  • CoreSegmentedControl — 개별 항목. selected prop으로 선택 상태를 직접 제어
  • 단일·다중 선택 — 외부 state 로직으로 두 모드 모두 구현 가능
  • 아이콘 지원leadingElement / trailingElement로 아이콘 단독 또는 텍스트와 조합

Usage

기본 사용법 (단일 선택)

() => {
const [selected, setSelected] = React.useState('0');
return (
  <CoreSegmentedControlGroup size="md">
    <CoreSegmentedControl selected={selected === '0'} onClick={() => setSelected('0')}>Tab 1</CoreSegmentedControl>
    <CoreSegmentedControl selected={selected === '1'} onClick={() => setSelected('1')}>Tab 2</CoreSegmentedControl>
    <CoreSegmentedControl selected={selected === '2'} onClick={() => setSelected('2')}>Tab 3</CoreSegmentedControl>
    <CoreSegmentedControl selected={selected === '3'} onClick={() => setSelected('3')} disabled>Disabled</CoreSegmentedControl>
  </CoreSegmentedControlGroup>
);
}

다중 선택

() => {
const [selected, setSelected] = React.useState([]);
const toggle = (v) => setSelected((prev) =>
  prev.includes(v) ? prev.filter((x) => x !== v) : [...prev, v]
);
return (
  <CoreSegmentedControlGroup size="md">
    <CoreSegmentedControl selected={selected.includes('0')} onClick={() => toggle('0')}>Tab 1</CoreSegmentedControl>
    <CoreSegmentedControl selected={selected.includes('1')} onClick={() => toggle('1')}>Tab 2</CoreSegmentedControl>
    <CoreSegmentedControl selected={selected.includes('2')} onClick={() => toggle('2')}>Tab 3</CoreSegmentedControl>
  </CoreSegmentedControlGroup>
);
}

아이콘 전용

() => {
const [selected, setSelected] = React.useState('0');
return (
  <CoreSegmentedControlGroup size="md">
    <CoreSegmentedControl selected={selected === '0'} onClick={() => setSelected('0')} leadingElement={<IconSearchOutline />} />
    <CoreSegmentedControl selected={selected === '1'} onClick={() => setSelected('1')} leadingElement={<IconAddOutline />} />
    <CoreSegmentedControl selected={selected === '2'} onClick={() => setSelected('2')} leadingElement={<IconCloseOutline />} disabled />
  </CoreSegmentedControlGroup>
);
}

아이콘 + 텍스트

() => {
const [selected, setSelected] = React.useState('0');
return (
  <CoreSegmentedControlGroup size="md">
    <CoreSegmentedControl selected={selected === '0'} onClick={() => setSelected('0')} leadingElement={<IconSearchOutline />}>검색</CoreSegmentedControl>
    <CoreSegmentedControl selected={selected === '1'} onClick={() => setSelected('1')} leadingElement={<IconAddOutline />} trailingElement={<IconCaretDownFilled />}>추가</CoreSegmentedControl>
  </CoreSegmentedControlGroup>
);
}

크기 비교

() => {
const [s, setS] = React.useState('0');
return (
  <VStack $css={{ gap: '12px' }}>
    {['sm','md','lg'].map((size) => (
      <CoreSegmentedControlGroup key={size} size={size}>
        <CoreSegmentedControl selected={s === '0'} onClick={() => setS('0')}>Tab 1</CoreSegmentedControl>
        <CoreSegmentedControl selected={s === '1'} onClick={() => setS('1')}>Tab 2</CoreSegmentedControl>
        <CoreSegmentedControl selected={s === '2'} onClick={() => setS('2')}>Tab 3</CoreSegmentedControl>
      </CoreSegmentedControlGroup>
    ))}
  </VStack>
);
}

세로 방향

() => {
const [selected, setSelected] = React.useState('0');
return (
  <CoreSegmentedControlGroup size="md" orientation="vertical">
    <CoreSegmentedControl selected={selected === '0'} onClick={() => setSelected('0')}>Tab 1</CoreSegmentedControl>
    <CoreSegmentedControl selected={selected === '1'} onClick={() => setSelected('1')}>Tab 2</CoreSegmentedControl>
    <CoreSegmentedControl selected={selected === '2'} onClick={() => setSelected('2')}>Tab 3</CoreSegmentedControl>
  </CoreSegmentedControlGroup>
);
}

Props

CoreSegmentedControlGroup

ComponentPropsWithoutRef<'div'>를 확장한 컴포넌트입니다.

Prop

Type

CoreSegmentedControl

ComponentPropsWithoutRef<'button'>를 확장한 컴포넌트입니다.

Prop

Type

CoreSegmentedControlSize

Prop

Type

스타일

CoreSegmentedControlGroup:

  • display: flex, gap: 4px, padding: 4px
  • border-radius: radius-100
  • background-color: background-1
  • box-shadow: inset 0 0 0 1px border[1]
  • transition: 0.2s

CoreSegmentedControl:

  • display: flex, justify-content: center
  • border-radius: radius-50
  • transition: 0.2s

Group Size Variants

size높이
sm26px
md32px
lg40px

Item Size Variants

size항목 높이TypographyGapPadding X (텍스트)Padding X (아이콘 전용)
sm18pxheading[1]4px8px2px
md24pxheading[2]4px10px6px
lg32pxheading[2]6px12px8px

상태 토큰

상태colorbackground
기본
hovertoggle-primary-1toggle-hover-bg
activetoggle-primary-2
selectedgray-15
disabledtoggle-disabled-text

마이그레이션 가이드

신규 SegmentedControl 컴포넌트는 Base UI 기반으로 키보드 접근성이 개선됐습니다.

Before / After

// Before — CoreSegmentedControl
const [selected, setSelected] = useState('tab1');

<CoreSegmentedControlGroup size="md">
  <CoreSegmentedControl selected={selected === 'tab1'} onClick={() => setSelected('tab1')}>
    Tab 1
  </CoreSegmentedControl>
  <CoreSegmentedControl selected={selected === 'tab2'} onClick={() => setSelected('tab2')}>
    Tab 2
  </CoreSegmentedControl>
</CoreSegmentedControlGroup>
// After — SegmentedControl
<SegmentedControl.Group size="md" defaultValue="tab1">
  <SegmentedControl.Item value="tab1">Tab 1</SegmentedControl.Item>
  <SegmentedControl.Item value="tab2">Tab 2</SegmentedControl.Item>
</SegmentedControl.Group>

변경 사항

CoreSegmentedControlSegmentedControl
selected + onClick으로 외부 state 직접 제어value / defaultValue로 선언적 제어
CoreSegmentedControlGroup wrapper 필요SegmentedControl.Group으로 통합
orientation propSegmentedControl.Grouporientation
키보드 탐색 직접 구현 필요방향키 탐색 기본 제공