세그먼트

세그먼트 (Segmented)

여러 옵션을 나란히 보여주고 사용자가 단 하나의 옵션을 선택할 수 있게 해주는 컴포넌트입니다. 마치 토글이 여러 개 나란히 있는 형태라고 생각하면 쉬워요.

출처: 문서

본문

이 컴포넌트는 [email protected]부터 사용할 수 있습니다.

언제 사용하나요 (When To Use)

  • 여러 옵션을 보여주면서 사용자가 하나의 옵션만 선택해야 할 때
  • 선택한 옵션을 전환할 때, 관련된 영역의 내용이 함께 바뀌어야 할 때

예제 (Examples)

기본 (Basic)

가장 기본적인 사용법입니다.

import React from 'react';
import { Segmented } from 'antd';

const Demo: React.FC = () => (
  <Segmented<string>
    options={['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly']}
    onChange={(value) => {
      console.log(value); // string
    }}
  />
);

export default Demo;

세로 방향 (Vertical Direction)

세로로 배치할 수 있습니다.

import React from 'react';
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
import { Segmented } from 'antd';

const Demo: React.FC = () => (
  <Segmented
    orientation="vertical"
    options={[
      { value: 'List', icon: <BarsOutlined /> },
      { value: 'Kanban', icon: <AppstoreOutlined /> },
    ]}
  />
);

export default Demo;

블록 세그먼트 (Block Segmented)

block 속성을 주면 Segmented가 부모의 너비에 꽉 차게 늘어납니다.

import React from 'react';
import { Segmented } from 'antd';

const Demo: React.FC = () => (
  <Segmented<string | number> options={[123, 456, 'longtext-longtext-longtext-longtext']} block />
);

export default Demo;

둥근 모양 (Round shape)

Segmented의 둥근 모양입니다.

import React, { useState } from 'react';
import { MoonOutlined, SunOutlined } from '@ant-design/icons';
import { Flex, Segmented } from 'antd';
import type { SegmentedProps } from 'antd';

type SizeType = NonNullable<SegmentedProps['size']>;

const Demo: React.FC = () => {
  const [size, setSize] = useState<SizeType>('medium');
  return (
    <Flex gap="small" align="flex-start" vertical>
      <Segmented<SizeType> options={['small', 'medium', 'large']} value={size} onChange={setSize} />
      <Segmented
        size={size}
        shape="round"
        options={[
          { value: 'light', icon: <SunOutlined /> },
          { value: 'dark', icon: <MoonOutlined /> },
        ]}
      />
    </Flex>
  );
};

export default Demo;

비활성화 (Disabled)

비활성화된 Segmented입니다.

import React from 'react';
import { Flex, Segmented } from 'antd';

const App: React.FC = () => (
  <Flex gap="small" align="flex-start" vertical>
    <Segmented options={['Map', 'Transit', 'Satellite']} disabled />
    <Segmented
      options={[
        'Daily',
        { label: 'Weekly', value: 'Weekly', disabled: true },
        'Monthly',
        { label: 'Quarterly', value: 'Quarterly', disabled: true },
        'Yearly',
      ]}
    />
  </Flex>
);

export default App;

제어 모드 (Controlled mode)

값을 제어(controlled)하는 Segmented입니다.

import React, { useState } from 'react';
import { Segmented } from 'antd';

const Demo: React.FC = () => {
  const [value, setValue] = useState<string>('Map');
  return (
    <Segmented<string>
      options={['Map', 'Transit', 'Satellite']}
      value={value}
      onChange={setValue}
    />
  );
};

export default Demo;

커스텀 렌더링 (Custom Render)

각 Segmented 항목을 커스터마이즈합니다.

import React from 'react';
import { UserOutlined } from '@ant-design/icons';
import { Avatar, Flex, Segmented } from 'antd';

const App: React.FC = () => (
  <Flex gap="small" align="flex-start" vertical>
    <Segmented
      options={[
        {
          label: (
            <div style={{ padding: 4 }}>
              <Avatar src="https://api.dicebear.com/10.x/lorelei/svg?seed=8" alt="User 1" />
              <div>User 1</div>
            </div>
          ),
          value: 'user1',
          tooltip: { title: 'hello user1', color: 'gold' },
        },
        {
          label: (
            <div style={{ padding: 4 }}>
              <Avatar style={{ backgroundColor: '#f56a00' }} alt="User 2">
                K
              </Avatar>
              <div>User 2</div>
            </div>
          ),
          value: 'user2',
          tooltip: { title: 'hello user2', color: 'pink' },
        },
        {
          label: (
            <div style={{ padding: 4 }}>
              <Avatar style={{ backgroundColor: '#87d068' }} icon={<UserOutlined />} alt="User 3" />
              <div>User 3</div>
            </div>
          ),
          value: 'user3',
          tooltip: { title: 'hello user3', color: 'geekblue' },
        },
      ]}
    />
    <Segmented
      options={[
        {
          label: (
            <div style={{ padding: 4 }}>
              <div>Spring</div>
              <div>Jan-Mar</div>
            </div>
          ),
          value: 'spring',
        },
        {
          label: (
            <div style={{ padding: 4 }}>
              <div>Summer</div>
              <div>Apr-Jun</div>
            </div>
          ),
          value: 'summer',
        },
        {
          label: (
            <div style={{ padding: 4 }}>
              <div>Autumn</div>
              <div>Jul-Sept</div>
            </div>
          ),
          value: 'autumn',
        },
        {
          label: (
            <div style={{ padding: 4 }}>
              <div>Winter</div>
              <div>Oct-Dec</div>
            </div>
          ),
          value: 'winter',
        },
      ]}
    />
  </Flex>
);

export default App;

동적 로딩 (Dynamic)

options를 동적으로 불러옵니다.

import React, { useState } from 'react';
import { Button, Flex, Segmented } from 'antd';

const Demo: React.FC = () => {
  const [options, setOptions] = useState(['Daily', 'Weekly', 'Monthly']);
  const [moreLoaded, setMoreLoaded] = useState(false);

  const handleLoadOptions = () => {
    setOptions((prev) => [...prev, 'Quarterly', 'Yearly']);
    setMoreLoaded(true);
  };

  return (
    <Flex gap="small" align="flex-start" vertical>
      <Segmented options={options} />
      <Button type="primary" disabled={moreLoaded} onClick={handleLoadOptions}>
        Load more options
      </Button>
    </Flex>
  );
};

export default Demo;

Segmented의 세 가지 크기 (Three sizes of Segmented)

Segmented 컴포넌트에는 large (40px), medium (32px), small (24px) 세 가지 크기가 있습니다.

import React from 'react';
import { Flex, Segmented } from 'antd';

const App: React.FC = () => (
  <Flex gap="small" align="flex-start" vertical>
    <Segmented size="large" options={['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly']} />
    <Segmented options={['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly']} />
    <Segmented size="small" options={['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly']} />
  </Flex>
);

export default App;

아이콘과 함께 (With Icon)

Segmented 항목에 icon을 설정할 수 있습니다. icon은 서드파티 아이콘 라이브러리의 단순한 <svg> 요소도 받아들이며, 이 경우 라벨과 세로 방향으로 중앙 정렬됩니다.

import React from 'react';
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
import { Segmented } from 'antd';

// Icons from third-party libraries (e.g. lucide, react-icons) render as a bare `<svg>`
// rather than an `.anticon` wrapper. It stays vertically centred with the label.
const CalendarIcon: React.FC = () => (
  <svg
    viewBox="0 0 24 24"
    width="1em"
    height="1em"
    fill="none"
    stroke="currentColor"
    strokeWidth={2}
    aria-hidden="true"
  >
    <rect x="3" y="4" width="18" height="18" rx="2" />
    <path d="M16 2v4M8 2v4M3 10h18" />
  </svg>
);

const Demo: React.FC = () => (
  <Segmented
    options={[
      { label: 'List', value: 'List', icon: <BarsOutlined /> },
      { label: 'Kanban', value: 'Kanban', icon: <AppstoreOutlined /> },
      { label: 'Calendar', value: 'Calendar', icon: <CalendarIcon /> },
    ]}
  />
);

export default Demo;

아이콘만 사용하기 (With Icon only)

label 없이 icon만 설정할 수 있습니다.

import React from 'react';
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
import { Segmented } from 'antd';

const Demo: React.FC = () => (
  <Segmented
    options={[
      { value: 'List', icon: <BarsOutlined /> },
      { value: 'Kanban', icon: <AppstoreOutlined /> },
    ]}
  />
);

export default Demo;

name 속성과 함께 (With name)

같은 Segmented 안에 있는 모든 input[type="radio"]에 name 속성을 전달할 수 있습니다. 브라우저가 이 Segmented를 실제 하나의 "그룹"으로 인식해 기본 동작을 유지하게 하는 데 주로 사용됩니다. 예를 들어 같은 Segmented 안에서 좌우 방향키를 이용해 선택을 변경하도록 할 수 있습니다.

import React from 'react';
import { Segmented } from 'antd';

const Demo: React.FC = () => (
  <Segmented<string> options={['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly']} name="group" />
);

export default Demo;

커스텀 시맨틱 DOM 스타일링 (Custom semantic dom styling)

classNames와 styles에 객체 또는 함수를 넘겨서 Segmented의 시맨틱 DOM 스타일을 커스터마이즈할 수 있습니다.

import React from 'react';
import { CloudOutlined, RocketOutlined, ThunderboltOutlined } from '@ant-design/icons';
import { Flex, Segmented } from 'antd';
import type { GetProp, SegmentedProps } from 'antd';
import { createStaticStyles } from 'antd-style';

const classNames = createStaticStyles(({ css }) => ({
  root: css`
    padding: 2px;
  `,
}));

const styleFn: SegmentedProps['styles'] = (info): GetProp<SegmentedProps, 'styles', 'Return'> => {
  if (info.props.vertical) {
    return {
      root: {
        border: '1px solid #77BEF0',
        padding: 4,
        width: 100,
      },
      icon: {
        color: '#77BEF0',
      },
      item: {
        textAlign: 'start',
      },
    };
  }
  return {};
};

const styles: SegmentedProps['styles'] = {
  root: {
    padding: 4,
    width: 260,
  },
};

const options: SegmentedProps['options'] = [
  {
    label: 'Boost',
    value: 'boost',
    icon: <RocketOutlined />,
  },
  {
    label: 'Stream',
    value: 'stream',
    icon: <ThunderboltOutlined />,
  },
  {
    label: 'Cloud',
    value: 'cloud',
    icon: <CloudOutlined />,
  },
];

const App: React.FC = () => {
  const segmentedSharedProps: SegmentedProps = {
    options,
    classNames,
  };

  return (
    <Flex vertical gap="medium">
      <Segmented {...segmentedSharedProps} styles={styles} />
      <Segmented {...segmentedSharedProps} styles={styleFn} vertical />
    </Flex>
  );
};

export default App;

API

Common props ref:Common props

이 컴포넌트는 [email protected]부터 사용할 수 있습니다.

Segmented

Property Description Type Default Version Global Config
block Option to fit width to its parent's width boolean false ×
classNames Customize class for each semantic structure inside the Segmented component. Supports object or function. Record<SemanticDOM, string> | (info: { props }) => Record<SemanticDOM, string> - 6.0.0
defaultValue Default selected value string | number Value of first item in options ×
disabled Disable all segments boolean false ×
onChange The callback function that is triggered when the state changes function(value: string | number) ×
options Set children optional string[] | number[] | SegmentedItemType[] [] ×
orientation Orientation horizontal | vertical horizontal ×
size The size of the Segmented. large | medium | small medium ×
styles Customize inline style for each semantic structure inside the Segmented component. Supports object or function. Record<SemanticDOM, CSSProperties> | (info: { props }) => Record<SemanticDOM, CSSProperties> - 6.0.0
vertical Orientation. Simultaneously existing with orientation, orientation takes priority boolean false 5.21.0 ×
value Currently selected value string | number ×
shape shape of Segmented default | round default 5.24.0 ×
name The name property of all input[type="radio"] children. if not set, it will fallback to a randomly generated name string 5.23.0 ×

SegmentedItemType

Property Description Type Default Version
disabled Disabled state of segmented item boolean false
className The additional css class string -
icon Display icon for Segmented item ReactNode -
label Display text for Segmented item ReactNode -
tooltip tooltip for Segmented item string | TooltipProps -
value Value for Segmented item string | number -

시맨틱 DOM (Semantic DOM)

https://ant.design/components/segmented/semantic.md

디자인 토큰 (Design Token)

컴포넌트 토큰 (Component Token - Segmented)

Token Name Description Type Default Value
itemActiveBg Background color of item when active string rgba(0,0,0,0.15)
itemColor Text color of item string rgba(0,0,0,0.65)
itemHoverBg Background color of item when hover string rgba(0,0,0,0.06)
itemHoverColor Text color of item when hover string rgba(0,0,0,0.88)
itemSelectedBg Background color of item when selected string #ffffff
itemSelectedColor Text color of item when selected string rgba(0,0,0,0.88)
trackBg Background of Segmented container string #f5f5f5
trackPadding Padding of Segmented container string | number 2

글로벌 토큰 (Global Token)

Token Name Description Type Default Value
borderRadius Border radius of base components number
borderRadiusLG LG size border radius, used in some large border radius components, such as Card, Modal and other components. number
borderRadiusSM SM size border radius, used in small size components, such as Button, Input, Select and other input components in small size number
borderRadiusXS XS size border radius, used in some small border radius components, such as Segmented, Arrow and other components with small border radius. number
boxShadowTertiary Control the tertiary box shadow style of an element. string
colorPrimaryBorder The stroke color under the main color gradient, used on the stroke of components such as Slider. string
colorText Default text color which comply with W3C standards, and this color is also the darkest neutral color. string
colorTextDisabled Control the color of text in disabled state. string
controlHeight The height of the basic controls such as buttons and input boxes in Ant Design number
controlHeightLG LG component height number
controlHeightSM SM component height number
controlPaddingHorizontal Control the horizontal padding of an element. number
controlPaddingHorizontalSM Control the horizontal padding of an element with a small-medium size. number
fontFamily The font family of Ant Design prioritizes the default interface font of the system, and provides a set of alternative font libraries that are suitable for screen display to maintain the readability and readability of the font under different platforms and browsers, reflecting the friendly, stable and professional characteristics. string
fontSize The most widely used font size in the design system, from which the text gradient will be derived. number
fontSizeLG Large font size number
lineHeight Line height of text. number
lineWidth Border width of base components number
lineWidthFocus Control the width of the line when the component is in focus state. number
marginSM Control the margin of an element, with a medium-small size. number
motionDurationMid Motion speed, medium speed. Used for medium element animation interaction. string
motionDurationSlow Motion speed, slow speed. Used for large element animation interaction. string
motionEaseInOut Preset motion curve. string
paddingXXS Control the extra extra small padding of the element. number

더 알아보기 (Learn more)