Collapse

Collapse (접이식 패널)

Collapse는 복잡한 영역을 그룹화하거나 숨겨 페이지를 깔끔하게 유지할 때 사용하는 컴포넌트예요.

출처: 문서

본문

언제 사용하나요

  • 복잡한 영역을 그룹화하거나 숨겨 페이지를 깔끔하게 유지할 수 있어요.
  • Accordion은 한 번에 하나의 패널만 펼칠 수 있게 하는 특별한 종류의 Collapse예요.

예제 (Examples)

Collapse

기본적으로 한 번에 여러 패널을 펼칠 수 있어요. 이 예에서는 첫 패널이 펼쳐져 있어요.

import React from 'react';
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';

const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

const items: CollapseProps['items'] = [
  {
    key: '1',
    label: 'This is panel header 1',
    children: <p>{text}</p>,
  },
  {
    key: '2',
    label: 'This is panel header 2',
    children: <p>{text}</p>,
  },
  {
    key: '3',
    label: 'This is panel header 3',
    children: <p>{text}</p>,
  },
];

const App: React.FC = () => {
  const onChange = (key: string | string[]) => {
    console.log(key);
  };

  return <Collapse items={items} defaultActiveKey={['1']} onChange={onChange} />;
};

export default App;

크기 (Size)

Ant Design은 기본 collapse 크기와 함께 large, small 크기를 지원해요.

large나 small collapse가 필요하면 size 속성을 각각 large 또는 small로 설정하세요. 기본 medium 크기는 size 속성을 생략하면 돼요.

import React from 'react';
import { Collapse, Divider } from 'antd';

const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

const App: React.FC = () => (
  <>
    <Divider titlePlacement="start">Medium Size</Divider>
    <Collapse
      items={[{ key: '1', label: 'This is medium size panel header', children: <p>{text}</p> }]}
    />
    <Divider titlePlacement="start">Small Size</Divider>
    <Collapse
      size="small"
      items={[{ key: '1', label: 'This is small size panel header', children: <p>{text}</p> }]}
    />
    <Divider titlePlacement="start">Large Size</Divider>
    <Collapse
      size="large"
      items={[{ key: '1', label: 'This is large size panel header', children: <p>{text}</p> }]}
    />
  </>
);

export default App;

Accordion

아코디언 모드에서는 한 번에 하나의 패널만 펼칠 수 있어요.

import React from 'react';
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';

const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

const items: CollapseProps['items'] = [
  {
    key: '1',
    label: 'This is panel header 1',
    children: <p>{text}</p>,
  },
  {
    key: '2',
    label: 'This is panel header 2',
    children: <p>{text}</p>,
  },
  {
    key: '3',
    label: 'This is panel header 3',
    children: <p>{text}</p>,
  },
];

const App: React.FC = () => <Collapse accordion items={items} />;

export default App;

중첩 패널 (Nested panel)

Collapse 안에 Collapse가 중첩돼요.

import React from 'react';
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';

const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

const itemsNest: CollapseProps['items'] = [
  {
    key: '1',
    label: 'This is panel nest panel',
    children: <p>{text}</p>,
  },
];

const items: CollapseProps['items'] = [
  {
    key: '1',
    label: 'This is panel header 1',
    children: <Collapse defaultActiveKey="1" items={itemsNest} />,
  },
  {
    key: '2',
    label: 'This is panel header 2',
    children: <p>{text}</p>,
  },
  {
    key: '3',
    label: 'This is panel header 3',
    children: <p>{text}</p>,
  },
];

const App: React.FC = () => {
  const onChange = (key: string | string[]) => {
    console.log(key);
  };

  return <Collapse onChange={onChange} items={items} />;
};

export default App;

테두리 없음 (Borderless)

테두리 없는 Collapse 스타일이에요.

import React from 'react';
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';

const text = (
  <p style={{ paddingInlineStart: 24 }}>
    A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found
    as a welcome guest in many households across the world.
  </p>
);

const items: CollapseProps['items'] = [
  {
    key: '1',
    label: 'This is panel header 1',
    children: text,
  },
  {
    key: '2',
    label: 'This is panel header 2',
    children: text,
  },
  {
    key: '3',
    label: 'This is panel header 3',
    children: text,
  },
];

const App: React.FC = () => <Collapse items={items} bordered={false} defaultActiveKey={['1']} />;

export default App;

커스텀 패널 (Custom Panel)

각 패널의 배경, 테두리, 여백 스타일과 아이콘을 커스터마이즈해요.

import type { CSSProperties } from 'react';
import React from 'react';
import { CaretRightOutlined } from '@ant-design/icons';
import type { CollapseProps } from 'antd';
import { Collapse, theme } from 'antd';

const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

const getItems: (panelStyle: CSSProperties) => CollapseProps['items'] = (panelStyle) => [
  {
    key: '1',
    label: 'This is panel header 1',
    children: <p>{text}</p>,
    style: panelStyle,
  },
  {
    key: '2',
    label: 'This is panel header 2',
    children: <p>{text}</p>,
    style: panelStyle,
  },
  {
    key: '3',
    label: 'This is panel header 3',
    children: <p>{text}</p>,
    style: panelStyle,
  },
];

const App: React.FC = () => {
  const { token } = theme.useToken();

  const panelStyle: React.CSSProperties = {
    marginBottom: 24,
    background: token.colorFillAlter,
    borderRadius: token.borderRadiusLG,
    border: 'none',
  };

  return (
    <Collapse
      bordered={false}
      defaultActiveKey={['1']}
      expandIcon={({ isActive }) => <CaretRightOutlined rotate={isActive ? 90 : 0} />}
      style={{ background: token.colorBgContainer }}
      items={getItems(panelStyle)}
    />
  );
};

export default App;

아이콘이 있는 패널 (Panel with icon)

패널 제목에 아이콘을 추가해요. 타사 아이콘 라이브러리(예: lucide, react-icons)의 순수 <svg>는 제목 텍스트와 세로 중앙에 정렬돼요.

import React from 'react';
import { SmileOutlined } from '@ant-design/icons';
import type { CollapseProps } from 'antd';
import { Collapse } 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 title text.
const ChartIcon: React.FC = () => (
  <svg
    viewBox="0 0 24 24"
    width="1em"
    height="1em"
    fill="none"
    stroke="currentColor"
    strokeWidth={2}
    aria-hidden="true"
  >
    <path d="M3 3v18h18" />
    <path d="M7 14l4-4 3 3 5-6" />
  </svg>
);

const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

const items: CollapseProps['items'] = [
  {
    key: '1',
    label: (
      <>
        <SmileOutlined /> Panel with an Ant Design icon
      </>
    ),
    children: <p>{text}</p>,
  },
  {
    key: '2',
    label: (
      <>
        <ChartIcon /> Panel with a third-party icon
      </>
    ),
    children: <p>{text}</p>,
  },
];

const App: React.FC = () => <Collapse defaultActiveKey={['1']} items={items} />;

export default App;

화살표 없음 (No arrow)

CollapsePanel 컴포넌트에 showArrow={false}를 전달해 화살표 아이콘을 숨길 수 있어요.

import React from 'react';
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';

const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

const items: CollapseProps['items'] = [
  {
    key: '1',
    label: 'This is panel header with arrow icon',
    children: <p>{text}</p>,
  },
  {
    key: '2',
    label: 'This is panel header with no arrow icon',
    children: <p>{text}</p>,
    showArrow: false,
  },
];

const App: React.FC = () => {
  const onChange = (key: string | string[]) => {
    console.log(key);
  };

  return <Collapse defaultActiveKey={['1']} onChange={onChange} items={items} />;
};

export default App;

추가 노드 (Extra node)

각 패널의 우측 상단에 추가 요소를 렌더링해요.

import React, { useState } from 'react';
import { SettingOutlined } from '@ant-design/icons';
import type { CollapseProps } from 'antd';
import { Collapse, Select } from 'antd';

const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

const App: React.FC = () => {
  const [expandIconPlacement, setExpandIconPlacement] =
    useState<CollapseProps['expandIconPlacement']>('start');

  const onPlacementChange = (newExpandIconPlacement: CollapseProps['expandIconPlacement']) => {
    setExpandIconPlacement(newExpandIconPlacement);
  };

  const onChange = (key: string | string[]) => {
    console.log(key);
  };

  const genExtra = () => (
    <SettingOutlined
      onClick={(event) => {
        // If you don't want click extra trigger collapse, you can prevent this:
        event.stopPropagation();
      }}
    />
  );

  const items: CollapseProps['items'] = [
    {
      key: '1',
      label: 'This is panel header 1',
      children: <div>{text}</div>,
      extra: genExtra(),
    },
    {
      key: '2',
      label: 'This is panel header 2',
      children: <div>{text}</div>,
      extra: genExtra(),
    },
    {
      key: '3',
      label: 'This is panel header 3',
      children: <div>{text}</div>,
      extra: genExtra(),
    },
  ];

  return (
    <>
      <Collapse
        defaultActiveKey={['1']}
        onChange={onChange}
        expandIconPlacement={expandIconPlacement}
        items={items}
      />
      <br />
      <span>Expand Icon Placement: </span>
      <Select
        value={expandIconPlacement}
        style={{ margin: '0 8px' }}
        onChange={onPlacementChange}
        options={[
          { label: 'start', value: 'start' },
          { label: 'end', value: 'end' },
        ]}
      />
    </>
  );
};

export default App;

고스트 Collapse (Ghost Collapse)

Collapse의 배경을 투명하게 만들어요.

import React from 'react';
import type { CollapseProps } from 'antd';
import { Collapse } from 'antd';

const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

const items: CollapseProps['items'] = [
  {
    key: '1',
    label: 'This is panel header 1',
    children: <p>{text}</p>,
  },
  {
    key: '2',
    label: 'This is panel header 2',
    children: <p>{text}</p>,
  },
  {
    key: '3',
    label: 'This is panel header 3',
    children: <p>{text}</p>,
  },
];

const App: React.FC = () => <Collapse defaultActiveKey={['1']} ghost items={items} />;

export default App;

접이기 트리거 (Collapsible)

collapsible로 접힐 수 있는 트리거 영역을 지정해요.

import React from 'react';
import { Collapse, Space } from 'antd';
import { createStyles } from 'antd-style';

const text = `
  A dog is a type of domesticated animal.
  Known for its loyalty and faithfulness,
  it can be found as a welcome guest in many households across the world.
`;

const useStyles = createStyles((props) => {
  const { css } = props;
  return {
    content: css`
      width: 100%;
    `,
  };
});

const App: React.FC = () => {
  const { styles } = useStyles();
  return (
    <Space className={styles.content} vertical>
      <Collapse
        collapsible="header"
        defaultActiveKey={['1']}
        items={[
          {
            key: '1',
            label: 'This panel can be collapsed by clicking text or icon',
            children: <p>{text}</p>,
          },
        ]}
      />
      <Collapse
        collapsible="icon"
        defaultActiveKey={['1']}
        items={[
          {
            key: '1',
            label: 'This panel can only be collapsed by clicking icon',
            children: <p>{text}</p>,
          },
        ]}
      />
      <Collapse
        collapsible="disabled"
        items={[
          {
            key: '1',
            label: "This panel can't be collapsed",
            children: <p>{text}</p>,
          },
        ]}
      />
    </Space>
  );
};

export default App;

커스텀 시맨틱 DOM 스타일링

classNames와 styles에 객체/함수를 전달해 Collapse의 시맨틱 DOM 스타일을 커스터마이즈할 수 있어요.

import React from 'react';
import type { CollapseProps, GetProp } from 'antd';
import { Collapse, Flex } from 'antd';
import { createStaticStyles } from 'antd-style';

const classNames = createStaticStyles(({ css }) => ({
  root: css`
    background-color: #fafafa;
    border: 1px solid #e0e0e0;
    border-radius: 8px;
  `,
}));

const element = (
  <p>
    A dog is a type of domesticated animal. Known for its loyalty and faithfulness, it can be found
    as a welcome guest in many households across the world.
  </p>
);

const items: CollapseProps['items'] = [
  {
    key: '1',
    label: 'This is panel header 1',
    children: element,
  },
  {
    key: '2',
    label: 'This is panel header 2',
    children: element,
  },
  {
    key: '3',
    label: 'This is panel header 3',
    children: element,
  },
];

const styles: CollapseProps['styles'] = {
  root: {
    backgroundColor: '#fafafa',
    border: '1px solid #e0e0e0',
    borderRadius: 8,
  },
  header: {
    backgroundColor: '#f0f0f0',
    padding: '12px 16px',
    color: '#141414',
  },
};

const stylesFn: CollapseProps['styles'] = ({
  props,
}): GetProp<CollapseProps, 'styles', 'Return'> => {
  if (props.size === 'large') {
    return {
      root: {
        backgroundColor: '#fff',
        border: '1px solid #696FC7',
        borderRadius: 8,
      },
      header: {
        backgroundColor: '#F5EFFF',
        padding: '12px 16px',
        color: '#141414',
      },
    };
  }
};

const App: React.FC = () => {
  const sharedProps: CollapseProps = { classNames, items };

  return (
    <Flex vertical gap="medium">
      <Collapse {...sharedProps} defaultActiveKey={['1']} styles={styles} />
      <Collapse {...sharedProps} defaultActiveKey={['2']} styles={stylesFn} size="large" />
    </Flex>
  );
};

export default App;

API

공통 props 참고: Common props

Collapse

속성 설명 타입 기본값 버전 전역 설정
accordion true면 Collapse가 Accordion으로 렌더링 boolean false ×
activeKey 활성 패널의 key string[] | string
number[] | number
기본값 없음. accordion 모드에서는 첫 패널의 key ×
bordered collapse 블록 주변 테두리 렌더링 토글 boolean true ×
classNames 컴포넌트 내부 각 시맨틱 구조의 클래스 커스터마이즈. 객체 또는 함수 지원 Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> - 6.0.0
collapsible Collapse를 어떻게 트리거할지 지정. 아이콘 클릭, 헤더의 아무 영역 클릭, 또는 접기 기능 자체 비활성화 header | icon | disabled - 4.9.0 ×
defaultActiveKey 초기 활성 패널의 key string[] | string
number[] | number
- ×
destroyInactivePanel 비활성 패널 파괴 boolean false ×
destroyOnHidden 비활성 패널 파괴 boolean false 5.25.0 ×
expandIcon 접기 확장 아이콘 커스터마이즈 (panelProps) => ReactNode - 5.15.0
expandIconPlacement 확장 아이콘 위치 설정 start | end start - ×
expandIconPosition 확장 아이콘 위치 설정, expandIconPlacement를 사용하세요 start | end - 4.21.0 ×
ghost collapse를 테두리 없이 만들고 배경을 투명하게 boolean false 4.4.0 ×
size collapse의 크기 설정 large | medium | small medium 5.2.0 ×
styles 컴포넌트 내부 각 시맨틱 구조의 인라인 스타일 커스터마이즈. 객체 또는 함수 지원 Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties> - 6.0.0
onChange 활성 패널이 바뀔 때 실행되는 콜백 함수 function - ×
items collapse 항목 콘텐츠 ItemType - 5.6.0 ×

ItemType

속성 설명 타입 기본값 버전
classNames 시맨틱 구조 className Record<header | body, string> - 5.21.0
collapsible 패널이 접힐 수 있는지 또는 접기 트리거 영역 지정 header | icon | disabled -
children 본문 영역 콘텐츠 ReactNode -
extra 모서리의 추가 요소 ReactNode -
forceRender 헤더 클릭 후의 lazy 렌더링 대신 패널 콘텐츠를 강제 렌더링 boolean false
key 형제들 사이에서 패널을 식별하는 고유 key string | number -
label 패널의 제목 ReactNode - -
showArrow false면 패널에 화살표 아이콘을 표시하지 않음. false면 collapsible을 icon으로 설정할 수 없음 boolean true
styles 시맨틱 DOM 스타일 Record<header | body, CSSProperties> - 5.21.0

Collapse.Panel

:::warning{title=Deprecated} 버전 >= 5.6.0을 사용할 때는 items로 패널을 구성하는 것을 권장합니다. :::

속성 설명 타입 기본값 버전
collapsible 패널이 접힐 수 있는지 또는 접기 트리거 영역 지정 header | icon | disabled - 4.9.0 (icon: 4.24.0)
extra 모서리의 추가 요소 ReactNode -
forceRender 헤더 클릭 후의 lazy 렌더링 대신 패널 콘텐츠를 강제 렌더링 boolean false
header 패널의 제목 ReactNode -
key 형제들 사이에서 패널을 식별하는 고유 key string | number -
showArrow false면 패널에 화살표 아이콘을 표시하지 않음. false면 collapsible을 icon으로 설정할 수 없음 boolean true

시맨틱 DOM (Semantic DOM)

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

디자인 토큰 (Design Token)

컴포넌트 토큰 (Collapse)

토큰 이름 설명 타입 기본값
borderlessContentBg borderless 스타일에서 콘텐츠의 배경 string transparent
borderlessContentPadding borderless 스타일에서 콘텐츠의 패딩 Padding<string | number> | undefined 4px 16px 16px
contentBg 콘텐츠의 배경 string #ffffff
contentPadding 콘텐츠의 패딩 Padding<string | number> | undefined 16px 16px
contentPaddingLG 큰 콘텐츠의 패딩 Padding<string | number> | undefined 24
contentPaddingSM 작은 콘텐츠의 패딩 Padding<string | number> | undefined 12
headerBg 헤더의 배경 string rgba(0,0,0,0.02)
headerPadding 헤더의 패딩 Padding<string | number> | undefined 12px 16px
headerPaddingLG 큰 헤더의 패딩 Padding<string | number> | undefined 16px 24px 16px 16px
headerPaddingSM 작은 헤더의 패딩 Padding<string | number> | undefined 8px 12px 8px 8px

전역 토큰 (Global Token)

토큰 이름 설명 타입 기본값
borderRadiusLG LG 크기 테두리 반지름, Card, Modal 등 큰 반지름 컴포넌트에 사용 number
colorBorder 기본 테두리색, 요소를 구분하는 데 사용. 예: 폼 구분선, 카드 구분선 등 string
colorPrimaryBorder 기본 색 그라데이션 아래의 스트로크 색. Slider 같은 컴포넌트의 스트로크에 사용 string
colorText W3C 표준을 준수하는 기본 텍스트 색. 가장 어두운 중성색이기도 함. string
colorTextDisabled 비활성 상태 텍스트의 색 제어. string
colorTextHeading 제목의 폰트 색 제어. string
fontFamily 시스템 기본 인터페이스 폰트와 화면 표시에 적합한 대체 폰트 라이브러리 세트 제공 string
fontSize 디자인 시스템에서 가장 널리 사용되는 폰트 크기. number
fontSizeIcon Select, Cascader 등의 동작 아이콘 폰트 크기 제어. 보통 fontSizeSM과 같음. number
fontSizeLG 큰 폰트 크기 number
lineHeight 텍스트의 줄 높이. number
lineHeightLG 큰 텍스트의 줄 높이. number
lineType 기본 컴포넌트의 테두리 스타일 string
lineWidth 기본 컴포넌트의 테두리 너비 number
lineWidthFocus 컴포넌트가 포커스 상태일 때 선 너비 제어. number
marginSM 요소의 여백 제어, 중간-작은 크기. number
motionDurationMid 모션 속도, 중간 속도. 중간 요소 애니메이션 상호작용에 사용. string
motionDurationSlow 모션 속도, 느린 속도. 대형 요소 애니메이션 상호작용에 사용. string
motionEaseInOut 프리셋 모션 곡선. string
padding 요소의 패딩 제어. number
paddingLG 요소의 큰 패딩 제어. number
paddingSM 요소의 작은 패딩 제어. number
paddingXS 요소의 매우 작은 패딩 제어. number

더 알아보기 (Learn more)