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 |
- | × | |
| 비활성 패널 파괴 | boolean | false | × | ||
| destroyOnHidden | 비활성 패널 파괴 | boolean | false | 5.25.0 | × |
| expandIcon | 접기 확장 아이콘 커스터마이즈 | (panelProps) => ReactNode | - | 5.15.0 | |
| expandIconPlacement | 확장 아이콘 위치 설정 | start | end |
start |
- | × |
확장 아이콘 위치 설정, 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)
- Tabs 컴포넌트 — 탭 전환
- Steps 컴포넌트 — 단계 표시
- Ant Design 시작하기 — 프로젝트 설정