드로어
드로어 (Drawer)
페이지 위에 덮여 옆에서 슬라이드되는 패널 컴포넌트예요. 정보나 작업 묶음을 담으며, 현재 페이지를 떠나지 않고도 같은 맥락 안에서 작업을 효율적으로 처리할 수 있게 해 줘요.
출처: 문서
본문
언제 사용하나요 (When To Use)
Drawer는 보통 페이지 위에 겹쳐 놓고 옆에서 슬라이드되는 패널이에요. 정보나 작업 묶음을 담아요. 사용자가 현재 페이지를 떠나지 않고도 Drawer와 상호작용할 수 있어서, 같은 맥락 안에서 작업을 더 효율적으로 끝낼 수 있어요.
- Form을 사용해 정보 묶음을 만들거나 수정할 때
- 하위 작업(subtask)을 처리할 때. 하위 작업이 Popover로는 너무 무겁고, 하위 작업을 메인 작업의 맥락 안에 유지하고 싶을 때 Drawer가 매우 유용해요.
- 같은 Form을 여러 곳에서 사용해야 할 때
개발자를 위한 참고사항
5.17.0부터는 Spin을 통해loadingprop을 제공했어요. 하지만5.18.0버전부터 이 디자인 오류를 수정해 Spin을 Skeleton으로 교체했고,loadingprop의 타입도boolean타입만 받도록 변경했어요.
예시 (Examples)
기본 (Basic)
기본 드로어예요.
import React, { useState } from 'react';
import { Button, Drawer } from 'antd';
const App: React.FC = () => {
const [open, setOpen] = useState(false);
const showDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
return (
<>
<Button type="primary" onClick={showDrawer}>
Open
</Button>
<Drawer
title="Basic Drawer"
closable={{ 'aria-label': 'Close Button' }}
onClose={onClose}
open={open}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</>
);
};
export default App;
위치 커스터마이즈 (Custom Placement)
Drawer는 화면의 어느 가장자리에서도 나타날 수 있어요.
import React, { useState } from 'react';
import type { DrawerProps, RadioChangeEvent } from 'antd';
import { Button, Drawer, Radio, Space } from 'antd';
const App: React.FC = () => {
const [open, setOpen] = useState(false);
const [placement, setPlacement] = useState<DrawerProps['placement']>('left');
const showDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
const onChange = (e: RadioChangeEvent) => {
setPlacement(e.target.value);
};
return (
<>
<Space>
<Radio.Group value={placement} onChange={onChange}>
<Radio value="top">top</Radio>
<Radio value="right">right</Radio>
<Radio value="bottom">bottom</Radio>
<Radio value="left">left</Radio>
</Radio.Group>
<Button type="primary" onClick={showDrawer}>
Open
</Button>
</Space>
<Drawer
title="Basic Drawer"
placement={placement}
closable={false}
onClose={onClose}
open={open}
key={placement}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</>
);
};
export default App;
크기 조절 (Resizable)
사용자가 가장자리를 드래그해 Drawer의 너비나 높이를 조절할 수 있는 리사이즈 가능한 드로어예요.
import React, { useState } from 'react';
import type { DrawerProps, RadioChangeEvent } from 'antd';
import { Button, Drawer, Radio, Space } from 'antd';
const App: React.FC = () => {
const [open, setOpen] = useState(false);
const [placement, setPlacement] = useState<DrawerProps['placement']>('right');
const [size, setSize] = useState(256);
const onChange = (e: RadioChangeEvent) => {
setSize(256);
setPlacement(e.target.value);
};
return (
<>
<Space style={{ marginBottom: 16 }}>
<Radio.Group
value={placement}
onChange={onChange}
options={['top', 'right', 'bottom', 'left'].map((pos) => ({
label: pos,
value: pos,
}))}
/>
<Button type="primary" onClick={() => setOpen(true)}>
Open Drawer
</Button>
</Space>
<div>Current size: {size}px</div>
<Drawer
title="Resizable Drawer"
placement={placement}
onClose={() => setOpen(false)}
open={open}
key={placement}
size={size}
resizable={{
onResize: (newSize) => setSize(newSize),
}}
>
<p>Drag the edge to resize the drawer</p>
<p>Current size: {size}px</p>
</Drawer>
</>
);
};
export default App;
로딩 (Loading)
Drawer의 로딩 상태를 설정해요.
import React from 'react';
import { Button, Drawer } from 'antd';
const App: React.FC = () => {
const [open, setOpen] = React.useState<boolean>(false);
const [loading, setLoading] = React.useState<boolean>(true);
const showLoading = () => {
setOpen(true);
setLoading(true);
// Simple loading mock. You should add cleanup logic in real world.
setTimeout(() => {
setLoading(false);
}, 2000);
};
return (
<>
<Button type="primary" onClick={showLoading}>
Open Drawer
</Button>
<Drawer
closable
destroyOnHidden
title={<p>Loading Drawer</p>}
placement="right"
open={open}
loading={loading}
onClose={() => setOpen(false)}
>
<Button type="primary" style={{ marginBottom: 16 }} onClick={showLoading}>
Reload
</Button>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</>
);
};
export default App;
추가 동작 (Extra Actions)
Ant Design에서는 추가 동작을 드로어의 모서리에 배치해요. extra prop으로 설정할 수 있어요.
import React, { useState } from 'react';
import { Button, Drawer, Radio, Space } from 'antd';
import type { DrawerProps, RadioChangeEvent } from 'antd';
const App: React.FC = () => {
const [open, setOpen] = useState(false);
const [placement, setPlacement] = useState<DrawerProps['placement']>('right');
const showDrawer = () => {
setOpen(true);
};
const onChange = (e: RadioChangeEvent) => {
setPlacement(e.target.value);
};
const onClose = () => {
setOpen(false);
};
return (
<>
<Space>
<Radio.Group value={placement} onChange={onChange}>
<Radio value="top">top</Radio>
<Radio value="right">right</Radio>
<Radio value="bottom">bottom</Radio>
<Radio value="left">left</Radio>
</Radio.Group>
<Button type="primary" onClick={showDrawer}>
Open
</Button>
</Space>
<Drawer
title="Drawer with extra actions"
placement={placement}
size={500}
onClose={onClose}
open={open}
extra={
<Space>
<Button onClick={onClose}>Cancel</Button>
<Button type="primary" onClick={onClose}>
OK
</Button>
</Space>
}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</>
);
};
export default App;
현재 DOM에 렌더링
현재 DOM에 렌더링하기. 커스텀 컨테이너는 getContainer를 확인하세요.
참고: v5에서는
style과classNameprops가 Modal 컴포넌트와 맞춰 Drawer 패널로 이동했어요. 원래style,classNameprops는rootStyle,rootClassName으로 대체됐어요.
getContainer가 DOM 노드를 반환할 때는rootStyle을{ position: 'absolute' }로 수동 설정해야 해요. #41951 참고.
import React, { useState } from 'react';
import { Button, Drawer, theme } from 'antd';
const App: React.FC = () => {
const { token } = theme.useToken();
const [open, setOpen] = useState(false);
const showDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
const containerStyle: React.CSSProperties = {
position: 'relative',
height: 200,
padding: 48,
overflow: 'hidden',
background: token.colorFillAlter,
border: `${token.lineWidth}px ${token.lineType} ${token.colorBorderSecondary}`,
borderRadius: token.borderRadiusLG,
};
return (
<div style={containerStyle}>
Render in this
<div style={{ marginTop: 16 }}>
<Button type="primary" onClick={showDrawer}>
Open
</Button>
</div>
<Drawer
title="Basic Drawer"
placement="right"
closable={false}
onClose={onClose}
open={open}
getContainer={false}
>
<p>Some contents...</p>
</Drawer>
</div>
);
};
export default App;
드로어 안에서 폼 제출
Drawer 안에서 제출 버튼과 함께 Form을 사용해요.
import React, { useState } from 'react';
import { PlusOutlined } from '@ant-design/icons';
import { Button, Col, DatePicker, Drawer, Form, Input, Row, Select, Space } from 'antd';
import type { InputProps } from 'antd';
const UrlInput: React.FC<InputProps> = (props) => {
return (
<Space.Compact>
<Space.Addon>http://</Space.Addon>
<Input style={{ width: '100%' }} {...props} />
<Space.Addon>.com</Space.Addon>
</Space.Compact>
);
};
const App: React.FC = () => {
const [open, setOpen] = useState(false);
const showDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
return (
<>
<Button type="primary" onClick={showDrawer} icon={<PlusOutlined />}>
New account
</Button>
<Drawer
title="Create a new account"
size={720}
onClose={onClose}
open={open}
styles={{
body: {
paddingBottom: 80,
},
}}
extra={
<Space>
<Button onClick={onClose}>Cancel</Button>
<Button onClick={onClose} type="primary">
Submit
</Button>
</Space>
}
>
<Form layout="vertical" requiredMark={false}>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="name"
label="Name"
rules={[{ required: true, message: 'Please enter user name' }]}
>
<Input placeholder="Please enter user name" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="url"
label="Url"
rules={[{ required: true, message: 'Please enter url' }]}
>
<UrlInput placeholder="Please enter url" />
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="owner"
label="Owner"
rules={[{ required: true, message: 'Please select an owner' }]}
>
<Select
placeholder="Please select an owner"
options={[
{ label: 'Xiaoxiao Fu', value: 'xiao' },
{ label: 'Maomao Zhou', value: 'mao' },
]}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="type"
label="Type"
rules={[{ required: true, message: 'Please choose the type' }]}
>
<Select
placeholder="Please choose the type"
options={[
{ label: 'private', value: 'private' },
{ label: 'public', value: 'public' },
]}
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="approver"
label="Approver"
rules={[{ required: true, message: 'Please choose the approver' }]}
>
<Select
placeholder="Please choose the approver"
options={[
{ label: 'Jack Ma', value: 'jack' },
{ label: 'Tom Liu', value: 'tom' },
]}
/>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="dateTime"
label="DateTime"
rules={[{ required: true, message: 'Please choose the dateTime' }]}
>
<DatePicker.RangePicker
style={{ width: '100%' }}
getPopupContainer={(trigger) => trigger.parentElement!}
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={24}>
<Form.Item
name="description"
label="Description"
rules={[
{
required: true,
message: 'please enter url description',
},
]}
>
<Input.TextArea rows={4} placeholder="please enter url description" />
</Form.Item>
</Col>
</Row>
</Form>
</Drawer>
</>
);
};
export default App;
프리뷰 드로어 (Preview drawer)
목록의 항목처럼 객체의 상세 정보를 Drawer로 빠르게 미리 볼 때 사용해요.
import React, { useState } from 'react';
import { Avatar, Col, Divider, Drawer, List, Row } from 'antd';
import { createStyles } from 'antd-style';
const useStyles = createStyles((props) => {
const { css, cssVar } = props;
return {
descriptionItem: css`
margin-bottom: ${cssVar.marginXS};
color: ${cssVar.colorTextLabel};
font-size: ${cssVar.fontSize};
line-height: ${cssVar.lineHeight};
`,
profileTitle: css`
display: block;
margin-bottom: ${cssVar.margin};
color: ${cssVar.colorTextHeading};
font-size: ${cssVar.fontSizeLG};
line-height: ${cssVar.lineHeight};
`,
label: css`
display: inline-block;
margin-inline-end: ${cssVar.marginXS};
color: ${cssVar.colorTextHeading};
`,
};
});
interface DescriptionItemProps {
title: string;
content: React.ReactNode;
}
const DescriptionItem: React.FC<DescriptionItemProps> = (props) => {
const { title, content } = props;
const { styles } = useStyles();
return (
<div className={styles.descriptionItem}>
<p className={styles.label}>{title}:</p>
{content}
</div>
);
};
const App: React.FC = () => {
const { styles } = useStyles();
const [open, setOpen] = useState(false);
const showDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
return (
<>
<List
bordered
dataSource={[
{ id: 1, name: 'Lily' },
{ id: 2, name: 'Lily' },
]}
renderItem={(item) => (
<List.Item
key={item.id}
actions={[
<a onClick={showDrawer} key={`a-${item.id}`}>
View Profile
</a>,
]}
>
<List.Item.Meta
avatar={
<Avatar src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png" />
}
title={<a href="https://ant.design/index-cn">{item.name}</a>}
description="Progresser XTech"
/>
</List.Item>
)}
/>
<Drawer size={640} placement="right" closable={false} onClose={onClose} open={open}>
<p className={styles.profileTitle} style={{ marginBottom: 24 }}>
User Profile
</p>
<p className={styles.profileTitle}>Personal</p>
<Row>
<Col span={12}>
<DescriptionItem title="Full Name" content="Lily" />
</Col>
<Col span={12}>
<DescriptionItem title="Account" content="[email protected]" />
</Col>
</Row>
<Row>
<Col span={12}>
<DescriptionItem title="City" content="HangZhou" />
</Col>
<Col span={12}>
<DescriptionItem title="Country" content="China🇨🇳" />
</Col>
</Row>
<Row>
<Col span={12}>
<DescriptionItem title="Birthday" content="February 2,1900" />
</Col>
<Col span={12}>
<DescriptionItem title="Website" content="-" />
</Col>
</Row>
<Row>
<Col span={24}>
<DescriptionItem
title="Message"
content="Make things as simple as possible but no simpler."
/>
</Col>
</Row>
<Divider />
<p className={styles.profileTitle}>Company</p>
<Row>
<Col span={12}>
<DescriptionItem title="Position" content="Programmer" />
</Col>
<Col span={12}>
<DescriptionItem title="Responsibilities" content="Coding" />
</Col>
</Row>
<Row>
<Col span={12}>
<DescriptionItem title="Department" content="XTech" />
</Col>
<Col span={12}>
<DescriptionItem title="Supervisor" content={<a>Lin</a>} />
</Col>
</Row>
<Row>
<Col span={24}>
<DescriptionItem
title="Skills"
content="C / C + +, data structures, software engineering, operating systems, computer networks, databases, compiler theory, computer architecture, Microcomputer Principle and Interface Technology, Computer English, Java, ASP, etc."
/>
</Col>
</Row>
<Divider />
<p className={styles.profileTitle}>Contacts</p>
<Row>
<Col span={12}>
<DescriptionItem title="Email" content="[email protected]" />
</Col>
<Col span={12}>
<DescriptionItem title="Phone Number" content="+86 181 0000 0000" />
</Col>
</Row>
<Row>
<Col span={24}>
<DescriptionItem
title="GitHub"
content={
<a
href="https://github.com/ant-design/ant-design"
target="_blank"
rel="noopener noreferrer"
>
github.com/ant-design/ant-design
</a>
}
/>
</Col>
</Row>
</Drawer>
</>
);
};
export default App;
다단계 드로어 (Multi-level drawer)
기존 드로어 위에 새 드로어를 열어 여러 분기 작업을 처리해요.
import React, { useState } from 'react';
import { Button, Drawer } from 'antd';
const App: React.FC = () => {
const [open, setOpen] = useState(false);
const [childrenDrawer, setChildrenDrawer] = useState(false);
const showDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
const showChildrenDrawer = () => {
setChildrenDrawer(true);
};
const onChildrenDrawerClose = () => {
setChildrenDrawer(false);
};
return (
<>
<Button type="primary" onClick={showDrawer}>
Open drawer
</Button>
<Drawer title="Multi-level drawer" size={520} closable={false} onClose={onClose} open={open}>
<Button type="primary" onClick={showChildrenDrawer}>
Two-level drawer
</Button>
<Drawer
title="Two-level Drawer"
size={320}
closable={false}
onClose={onChildrenDrawerClose}
open={childrenDrawer}
>
This is two-level drawer
</Drawer>
</Drawer>
</>
);
};
export default App;
사전 설정 크기 (Preset size)
Drawer의 기본 너비(또는 높이)는 378px이고, 사전 설정된 큰 크기 736px가 있어요.
import React, { useState } from 'react';
import { Button, Drawer, Radio, Space } from 'antd';
import type { DrawerProps } from 'antd';
const App: React.FC = () => {
const [open, setOpen] = useState(false);
const [size, setSize] = useState<DrawerProps['size']>();
const onClose = () => {
setOpen(false);
};
return (
<>
<Space style={{ marginBottom: 16 }}>
<Radio.Group
value={size}
onChange={(e) => setSize(e.target.value)}
options={[
{ label: 'Large Size (736px)', value: 'large' },
{ label: 'Default Size (378px)', value: 'default' },
{ label: 256, value: 256 },
{ label: '500px', value: '500px' },
{ label: '50%', value: '50%' },
{ label: '20vw', value: '20vw' },
]}
/>
</Space>
<Button type="primary" onClick={() => setOpen(true)}>
Open Drawer
</Button>
<Drawer
title={`${size} Drawer`}
placement="right"
size={size}
onClose={onClose}
open={open}
extra={
<Space>
<Button onClick={onClose}>Cancel</Button>
<Button type="primary" onClick={onClose}>
OK
</Button>
</Space>
}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</>
);
};
export default App;
마스크 (mask)
마스크 효과예요.
import React, { useState } from 'react';
import { Button, Drawer, Space } from 'antd';
type MaskType = 'blur' | 'dimmed' | 'none';
type DrawerConfig = {
type: MaskType;
mask: boolean | { blur: boolean };
title: string;
};
const drawerList: DrawerConfig[] = [
{ type: 'blur', mask: { blur: true }, title: 'blur' },
{ type: 'dimmed', mask: true, title: 'Dimmed mask' },
{ type: 'none', mask: false, title: 'No mask' },
];
const App: React.FC = () => {
const [open, setOpen] = useState<false | MaskType>(false);
const showDrawer = (type: MaskType) => {
setOpen(type);
};
const onClose = () => {
setOpen(false);
};
return (
<Space wrap>
{drawerList.map((item) => (
<React.Fragment key={item.type}>
<Button
onClick={() => {
showDrawer(item.type);
}}
>
{item.title}
</Button>
<Drawer
title={item.title}
placement="right"
mask={item.mask}
onClose={onClose}
open={open === item.type}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</React.Fragment>
))}
</Space>
);
};
export default App;
닫기 버튼 위치 (Closable placement)
닫기 버튼 위치를 end로 커스터마이즈할 수 있는 드로어예요. 기본값은 start예요.
import React, { useState } from 'react';
import { Button, Drawer } from 'antd';
const App: React.FC = () => {
const [open, setOpen] = useState(false);
const showDrawer = () => {
setOpen(true);
};
const onClose = () => {
setOpen(false);
};
return (
<>
<Button type="primary" onClick={showDrawer}>
Open
</Button>
<Drawer
title="Drawer Closable Placement"
closable={{ placement: 'end' }}
onClose={onClose}
open={open}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Take a look at the top-right corner...</p>
</Drawer>
</>
);
};
export default App;
커스텀 시맨틱 DOM 스타일 (Custom semantic dom styling)
classNames와 styles로 객체나 함수를 넘겨 Drawer의 시맨틱 DOM 스타일을 커스터마이즈할 수 있어요.
import React, { useState } from 'react';
import { Button, Drawer, Flex } from 'antd';
import type { DrawerProps, GetProp } from 'antd';
import { createStaticStyles } from 'antd-style';
const lineStyle: React.CSSProperties = {
lineHeight: '28px',
};
const sharedContent = (
<>
<div style={lineStyle}>
Following the Ant Design specification, we developed a React UI library antd that contains a
set of high quality components and demos for building rich, interactive user interfaces.
</div>
<div style={lineStyle}>🌈 Enterprise-class UI designed for web applications.</div>
<div style={lineStyle}>📦 A set of high-quality React components out of the box.</div>
<div style={lineStyle}>🛡 Written in TypeScript with predictable static types.</div>
<div style={lineStyle}>⚙️ Whole package of design resources and development tools.</div>
<div style={lineStyle}>🌍 Internationalization support for dozens of languages.</div>
<div style={lineStyle}>🎨 Powerful theme customization in every detail.</div>
</>
);
const classNames = createStaticStyles(
({ css }): NonNullable<GetProp<DrawerProps, 'classNames', 'Return'>> => ({
root: css`
border-radius: 10px;
padding: 10px;
`,
}),
);
const styles: DrawerProps['styles'] = {
mask: {
backgroundImage: `linear-gradient(to top, #18181b 0, rgba(21, 21, 22, 0.2) 100%)`,
},
};
const stylesFn: DrawerProps['styles'] = (info): GetProp<DrawerProps, 'styles', 'Return'> => {
if (info.props.footer) {
return {
header: {
padding: 16,
},
body: {
padding: 16,
},
footer: {
padding: '16px 10px',
backgroundColor: '#fafafa',
},
};
}
};
const App: React.FC = () => {
const [drawerOpen, setDrawerOpen] = useState(false);
const [drawerFnOpen, setDrawerFnOpen] = useState(false);
const sharedProps: DrawerProps = {
classNames,
size: 500,
};
const footer: React.ReactNode = (
<Flex gap="medium" justify="flex-end">
<Button
onClick={() => setDrawerFnOpen(false)}
styles={{ root: { borderColor: '#ccc', color: '#171717', backgroundColor: '#fff' } }}
>
Cancel
</Button>
<Button
type="primary"
styles={{ root: { backgroundColor: '#171717' } }}
onClick={() => setDrawerOpen(true)}
>
Submit
</Button>
</Flex>
);
return (
<Flex gap="medium">
<Button onClick={() => setDrawerOpen(true)}>Open Style Drawer</Button>
<Button type="primary" onClick={() => setDrawerFnOpen(true)}>
Open Function Drawer
</Button>
<Drawer
{...sharedProps}
footer={null}
title="Custom Style Drawer"
styles={styles}
open={drawerOpen}
onClose={() => setDrawerOpen(false)}
>
{sharedContent}
</Drawer>
<Drawer
{...sharedProps}
footer={footer}
title="Custom Function drawer"
styles={stylesFn}
mask={{ enabled: true, blur: true }}
open={drawerFnOpen}
onClose={() => setDrawerFnOpen(false)}
>
{sharedContent}
</Drawer>
</Flex>
);
};
export default App;
API
공통 props 참조: Common props
| 속성 | 설명 | 타입 | 기본값 | 버전 | 전역 설정 |
|---|---|---|---|---|---|
| afterOpenChange | Drawer 전환 시 애니메이션이 끝난 뒤의 콜백 | function(open) | - | × | |
Drawer 본문의 스타일, styles.body를 대신 사용하세요 |
CSSProperties | - | - | × | |
| className | Drawer 패널의 className 설정. 최상위 DOM 스타일은 rootClassName을 사용 |
string | - | 5.7.0 | |
| classNames | Drawer 컴포넌트 내 각 시맨틱 구조에 대한 클래스를 커스터마이즈. 객체 또는 함수를 지원 | Record<SemanticDOM, string> | (info: { props })=> Record<SemanticDOM, string> | - | 5.10.0 | |
| closable | 닫기 버튼 표시 여부. 위치는 placement로 설정 |
boolean | { closeIcon?: React.ReactNode; disabled?: boolean; placement?: 'start' | 'end' } | true | placement: 5.28.0 | 5.15.0, placement: 6.1.1 |
Drawer 래퍼의 스타일, styles.wrapper를 대신 사용하세요 |
CSSProperties | - | - | × | |
Drawer를 닫을 때 하위 컴포넌트를 마운트 해제할지 여부, destroyOnHidden을 대신 사용하세요 |
boolean | false | × | ||
| destroyOnHidden | Drawer를 닫을 때 하위 컴포넌트를 마운트 해제할지 여부 | boolean | false | 5.25.0 | × |
Drawer 패널의 스타일, styles.section을 대신 사용하세요 |
CSSProperties | - | - | × | |
| extra | 모서리의 추가 동작 영역 | ReactNode | - | 4.17.0 | × |
| footer | Drawer의 푸터 | ReactNode | - | × | |
Drawer 푸터의 스타일, styles.footer를 대신 사용하세요 |
CSSProperties | - | - | × | |
| forceRender | Drawer 컴포넌트를 강제로 사전 렌더링 | boolean | false | × | |
| focusable | Drawer에서 포커스 관리를 위한 설정 | { trap?: boolean, focusTriggerAfterClose?: boolean } |
- | 6.2.0 | 6.4.0 |
| getContainer | Drawer를 마운트할 노드와 표시 창 | HTMLElement | () => HTMLElement | Selectors | false | body | × | |
Drawer 헤더 부분의 스타일, styles.header를 대신 사용하세요 |
CSSProperties | - | × | ||
placement가 top 또는 bottom일 때 Drawer 대화상자의 높이, size를 대신 사용하세요 |
string | number | 378 | × | ||
| keyboard | esc 키로 닫기를 지원할지 여부 | boolean | true | × | |
| loading | Skeleton 표시 | boolean | false | 5.17.0 | × |
| mask | 마스크 효과 | boolean | { enabled?: boolean, blur?: boolean, closable?: boolean } |
true | mask.closable: 6.3.0 | 6.0.0, mask.closable: 6.3.0 |
| 마스크(Drawer 바깥 영역)를 클릭해 Drawer를 닫을지 여부 | boolean | true | × | ||
Drawer 마스크의 스타일, styles.mask를 대신 사용하세요 |
CSSProperties | - | - | × | |
| maxSize | 리사이즈 가능할 때 최대 크기(placement에 따라 너비 또는 높이) |
number | - | 6.0.0 | × |
| open | Drawer 대화상자의 표시 여부 | boolean | false | × | |
| placement | Drawer의 위치 | top | right | bottom | left |
right |
× | |
| push | 중첩 드로어의 밀기(push) 동작 | boolean | { distance: string | number } | { distance: 180 } | 4.5.0+ | × |
| resizable | 드래그로 리사이즈 가능하게 하기 | boolean | ResizableConfig | - | boolean: 6.1.0 | × |
| rootStyle | style과 달리 마스크를 포함하는 래퍼 요소의 스타일 |
CSSProperties | - | × | |
| size | 드로어 사전 설정 크기, 기본 378px, large는 736px, 또는 커스텀 숫자 |
'default' | 'large' | number | string | 'default' | 4.17.0, string: 6.2.0 | × |
| style | Drawer 패널의 스타일. 본문만 설정하려면 styles.body 사용 |
CSSProperties | - | 5.7.0 | |
| styles | Drawer 컴포넌트 내 각 시맨틱 구조에 대한 인라인 스타일을 커스터마이즈. 객체 또는 함수를 지원 | Record<SemanticDOM, CSSProperties> | (info: { props })=> Record<SemanticDOM, CSSProperties> | - | 5.10.0 | |
| title | Drawer의 제목 | ReactNode | - | × | |
Drawer 대화상자의 너비, size를 대신 사용하세요 |
string | number | 378 | × | ||
| zIndex | Drawer의 z-index |
number | 1000 | × | |
| onClose | 사용자가 마스크, 닫기 버튼 또는 취소 버튼을 클릭했을 때 호출되는 콜백 지정 | function(e) | - | × | |
| drawerRender | 커스텀 drawer 콘텐츠 렌더링 | (node: ReactNode) => ReactNode | - | 5.18.0 | × |
ResizableConfig
| 속성 | 설명 | 타입 | 기본값 | 버전 |
|---|---|---|---|---|
| onResizeStart | 리사이즈 시작 시 콜백 | () => void | - | 6.0.0 |
| onResize | 리사이즈 중 콜백 | (size: number) => void | - | 6.0.0 |
| onResizeEnd | 리사이즈 종료 시 콜백 | () => void | - | 6.0.0 |
Semantic DOM
https://ant.design/components/drawer/semantic.md
Design Token
Component Token (Drawer)
| 토큰 이름 | 설명 | 타입 | 기본값 |
|---|---|---|---|
| draggerSize | 리사이즈 핸들의 크기 | number | 4 |
| footerPaddingBlock | 푸터의 세로 패딩 | number | 8 |
| footerPaddingInline | 푸터의 가로 패딩 | number | 16 |
| zIndexPopup | drawer의 z-index | number | 1000 |
Global Token
| 토큰 이름 | 설명 | 타입 | 기본값 |
|---|---|---|---|
| borderRadiusSM | SM 크기의 테두리 반경. 작은 크기 컴포넌트(Button, Input, Select 등 작은 입력 컴포넌트)에서 사용 | number | |
| colorBgElevated | 팝업 레이어의 컨테이너 배경색. 다크 모드에서는 colorBgContainer보다 밝음. 예: modal, pop-up, menu 등 |
string | |
| colorBgMask | 마스크의 배경색. 마스크 아래 콘텐츠를 덮는 데 사용하며, Modal, Drawer, Image 등 컴포넌트가 이 토큰 사용 | string | |
| colorBgTextActive | 활성 상태 텍스트의 배경색 제어 | string | |
| colorBgTextHover | 호버 상태 텍스트의 배경색 제어 | string | |
| colorIcon | 약한 동작. allowClear나 Alert 닫기 버튼 등 |
string | |
| colorIconHover | 약한 동작의 호버 색상. allowClear나 Alert 닫기 버튼 등 |
string | |
| colorPrimary | 브랜드 색상은 제품의 특성과 커뮤니케이션을 반영하는 가장 직접적인 시각 요소 중 하나 | string | |
| colorPrimaryBorder | 메인 색 그라데이션의 획 색상. Slider 등 컴포넌트의 획에 사용 | string | |
| colorSplit | 구분선의 색상으로 사용. colorBorderSecondary와 같지만 투명도를 가짐 | string | |
| colorText | W3C 표준을 따르는 기본 텍스트 색상. 가장 어두운 중립 색 | string | |
| fontSizeLG | 큰 글꼴 크기 | number | |
| fontWeightStrong | 제목 컴포넌트(h1, h2, h3)나 선택된 항목의 글꼴 두께 제어 | number | |
| lineHeightLG | 큰 텍스트의 줄 높이 | number | |
| lineType | 기본 컴포넌트의 테두리 스타일 | string | |
| lineWidth | 기본 컴포넌트의 테두리 너비 | number | |
| lineWidthFocus | 컴포넌트가 포커스 상태일 때 라인의 너비 제어 | number | |
| marginXS | 요소의 여백을 작은 크기로 제어 | number | |
| motionDurationMid | 중간 속도 모션. 중간 요소 애니메이션 상호작용에 사용 | string | |
| motionDurationSlow | 느린 속도 모션. 큰 요소 애니메이션 상호작용에 사용 | string | |
| padding | 요소의 패딩 제어 | number | |
| paddingLG | 요소의 큰 패딩 제어 | number | |
| paddingXS | 요소의 매우 작은 패딩 제어 | number |