logoMogu Design

⌘ K
  • 设计
  • 研发
  • 组件
  • 组件总览
  • 通用
    • Button按钮
    • Icon图标
    • Typography排版
  • 布局
    • Divider分割线
    • Grid栅格
    • Layout布局
    • Space间距
  • 导航
    • Anchor锚点
    • Breadcrumb面包屑
    • Dropdown下拉菜单
    • Menu导航菜单
    • Pagination分页
    • Steps步骤条
  • 数据录入
    • AutoComplete自动完成
    • Cascader级联选择
    • Checkbox多选框
    • ColorPicker颜色选择器New
    • DatePicker日期选择框
    • Form表单
    • Input输入框
    • InputNumber数字输入框
    • Mentions提及
    • Radio单选框
    • Rate评分
    • Select选择器
    • Slider滑动输入条
    • Switch开关
    • TimePicker时间选择框
    • Transfer穿梭框
    • TreeSelect树选择
    • Upload上传
  • 数据展示
    • Avatar头像
    • Badge徽标数
    • Calendar日历
    • Card卡片
    • Carousel走马灯
    • Collapse折叠面板
    • Descriptions描述列表
    • Empty空状态
    • Image图片
    • List列表
    • Popover气泡卡片
    • QRCode二维码
    • Segmented分段控制器
    • Statistic统计数值
    • Table表格
    • Tabs标签页
    • Tag标签
    • Timeline时间轴
    • Tooltip文字提示
    • Tour漫游式引导
    • Tree树形控件
  • 反馈
    • Alert警告提示
    • Drawer抽屉
    • Message全局提示
    • Modal对话框
    • Notification通知提醒框
    • Popconfirm气泡确认框
    • Progress进度条
    • Result结果
    • Skeleton骨架屏
    • Spin加载中
  • 其他
    • Affix固钉
    • App包裹组件
    • ConfigProvider全局化配置
    • FloatButton悬浮按钮
    • Watermark水印
何时使用
代码演示
基础抽屉
自定义位置
额外操作
渲染在当前 DOM
抽屉表单
信息预览抽屉
多层抽屉
预设宽度
API

Drawer抽屉

Alert警告提示Message全局提示

屏幕边缘滑出的浮层面板。

何时使用

抽屉从父窗体边缘滑入,覆盖住部分父窗体内容。用户在抽屉内操作时不必离开当前任务,操作完成后,可以平滑地回到原任务。

  • 当需要一个附加的面板来控制父窗体内容,这个面板在需要时呼出。比如,控制界面展示样式,往界面中添加内容。
  • 当需要在当前任务流中插入临时任务,创建或预览附加内容。比如展示协议条款,创建子对象。

代码演示

基础抽屉

基础抽屉,点击触发按钮抽屉从右滑出,点击遮罩区关闭。

expand codeexpand code
TypeScript
JavaScript
import React, { useState } from 'react';
import { Button, Drawer } from 'mogud';

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" placement="right" onClose={onClose} open={open}>
        <p>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
      </Drawer>
    </>
  );
};

export default App;
额外操作

在 Ant Design 规范中,操作按钮建议放在抽屉的右上角,可以使用 extra 属性来实现。

expand codeexpand code
TypeScript
JavaScript
import React, { useState } from 'react';
import { Button, Drawer, Radio, Space } from 'mogud';
import type { DrawerProps } from 'mogud/es/drawer';
import type { RadioChangeEvent } from 'mogud/es/radio';

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}
        width={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;
抽屉表单

在抽屉中使用表单。

expand codeexpand code
TypeScript
JavaScript
import React, { useState } from 'react';
import { PlusOutlined } from '@ant-design/icons';
import { Button, Col, DatePicker, Drawer, Form, Input, Row, Select, Space } from 'mogud';

const { Option } = Select;

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"
        width={720}
        onClose={onClose}
        open={open}
        bodyStyle={{ paddingBottom: 80 }}
        extra={
          <Space>
            <Button onClick={onClose}>Cancel</Button>
            <Button onClick={onClose} type="primary">
              Submit
            </Button>
          </Space>
        }
      >
        <Form layout="vertical" hideRequiredMark>
          <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' }]}
              >
                <Input
                  style={{ width: '100%' }}
                  addonBefore="http://"
                  addonAfter=".com"
                  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">
                  <Option value="xiao">Xiaoxiao Fu</Option>
                  <Option value="mao">Maomao Zhou</Option>
                </Select>
              </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">
                  <Option value="private">Private</Option>
                  <Option value="public">Public</Option>
                </Select>
              </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">
                  <Option value="jack">Jack Ma</Option>
                  <Option value="tom">Tom Liu</Option>
                </Select>
              </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;
.site-form-in-drawer-wrapper {
  position: absolute;
  right: 0px;
  bottom: 0px;
  width: 100%;
  padding: 10px 16px;
  text-align: right;
  background: #fff;
  border-top: 1px solid #e9e9e9;
}
多层抽屉

在抽屉内打开新的抽屉,用以解决多分支任务的复杂状况。

expand codeexpand code
TypeScript
JavaScript
import React, { useState } from 'react';
import { Button, Drawer } from 'mogud';

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" width={520} closable={false} onClose={onClose} open={open}>
        <Button type="primary" onClick={showChildrenDrawer}>
          Two-level drawer
        </Button>
        <Drawer
          title="Two-level Drawer"
          width={320}
          closable={false}
          onClose={onChildrenDrawerClose}
          open={childrenDrawer}
        >
          This is two-level drawer
        </Drawer>
      </Drawer>
    </>
  );
};

export default App;
自定义位置

自定义位置,点击触发按钮抽屉从相应的位置滑出,点击遮罩区关闭。

expand codeexpand code
TypeScript
JavaScript
import React, { useState } from 'react';
import type { DrawerProps, RadioChangeEvent } from 'mogud';
import { Button, Drawer, Radio, Space } from 'mogud';

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;
Render in this
渲染在当前 DOM

渲染在当前 dom 里。自定义容器,查看 getContainer。

注意:在 v5 中 style 与 className 迁移至 Drawer 面板上与 Modal 保持一致,原 style 与 className 替换为 rootStyle 与 rootClassName。

expand codeexpand code
TypeScript
JavaScript
import React, { useState } from 'react';
import { Button, Drawer, theme } from 'mogud';

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',
    textAlign: 'center',
    background: token.colorFillAlter,
    border: `1px solid ${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;
  • Lily

    Progresser XTech
    • View Profile
  • Lily

    Progresser XTech
    • View Profile
信息预览抽屉

需要快速预览对象概要时使用,点击遮罩区关闭。

expand codeexpand code
TypeScript
JavaScript
import React, { useState } from 'react';
import { Avatar, Col, Divider, Drawer, List, Row } from 'mogud';

interface DescriptionItemProps {
  title: string;
  content: React.ReactNode;
}

const DescriptionItem = ({ title, content }: DescriptionItemProps) => (
  <div className="site-description-item-profile-wrapper">
    <p className="site-description-item-profile-p-label">{title}:</p>
    {content}
  </div>
);

const App: React.FC = () => {
  const [open, setOpen] = useState(false);

  const showDrawer = () => {
    setOpen(true);
  };

  const onClose = () => {
    setOpen(false);
  };

  return (
    <>
      <List
        dataSource={[
          {
            id: 1,
            name: 'Lily',
          },
          {
            id: 2,
            name: 'Lily',
          },
        ]}
        bordered
        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 width={640} placement="right" closable={false} onClose={onClose} open={open}>
        <p className="site-description-item-profile-p" style={{ marginBottom: 24 }}>
          User Profile
        </p>
        <p className="site-description-item-profile-p">Personal</p>
        <Row>
          <Col span={12}>
            <DescriptionItem title="Full Name" content="Lily" />
          </Col>
          <Col span={12}>
            <DescriptionItem title="Account" content="AntDesign@example.com" />
          </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="site-description-item-profile-p">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="site-description-item-profile-p">Contacts</p>
        <Row>
          <Col span={12}>
            <DescriptionItem title="Email" content="AntDesign@example.com" />
          </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="http://github.com/ant-design/ant-design/">
                  github.com/ant-design/ant-design/
                </a>
              }
            />
          </Col>
        </Row>
      </Drawer>
    </>
  );
};

export default App;
.site-description-item-profile-wrapper {
  margin-bottom: 7px;
  color: rgba(0, 0, 0, 0.65);
  font-size: 14px;
  line-height: 1.5715;
}

.ant-drawer-body p.site-description-item-profile-p {
  display: block;
  margin-bottom: 16px;
  color: rgba(0, 0, 0, 0.85);
  font-size: 16px;
  line-height: 1.5715;
}

.site-description-item-profile-p-label {
  display: inline-block;
  margin-right: 8px;
  color: rgba(0, 0, 0, 0.85);
}
预设宽度

抽屉的默认宽度为 378px,另外还提供一个大号抽屉 736px,可以用 size 属性来设置。

expand codeexpand code
TypeScript
JavaScript
import React, { useState } from 'react';
import { Button, Drawer, Space } from 'mogud';
import type { DrawerProps } from 'mogud/es/drawer';

const App: React.FC = () => {
  const [open, setOpen] = useState(false);
  const [size, setSize] = useState<DrawerProps['size']>();

  const showDefaultDrawer = () => {
    setSize('default');
    setOpen(true);
  };

  const showLargeDrawer = () => {
    setSize('large');
    setOpen(true);
  };

  const onClose = () => {
    setOpen(false);
  };

  return (
    <>
      <Space>
        <Button type="primary" onClick={showDefaultDrawer}>
          Open Default Size (378px)
        </Button>
        <Button type="primary" onClick={showLargeDrawer}>
          Open Large Size (736px)
        </Button>
      </Space>
      <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;

API

🚨 注意: v5 使用 rootClassName 与 rootStyle 来配置最外层元素样式。原 v4 className 与 style 改至配置 Drawer 窗体样式以和 Modal 对齐。

参数说明类型默认值版本
autoFocus抽屉展开后是否将焦点切换至其 Dom 节点booleantrue4.17.0
afterOpenChange切换抽屉时动画结束后的回调function(open)-
bodyStyle可用于设置 Drawer 内容部分的样式CSSProperties-
classNameDrawer 容器外层 className 设置,如果需要设置最外层,请使用 rootClassNamestring-
closable是否显示左上角的关闭按钮booleantrue
closeIcon自定义关闭图标ReactNode<CloseOutlined />
contentWrapperStyle可用于设置 Drawer 包裹内容部分的样式CSSProperties-
destroyOnClose关闭时销毁 Drawer 里的子元素booleanfalse
extra抽屉右上角的操作区域ReactNode-4.17.0
footer抽屉的页脚ReactNode-
footerStyle抽屉页脚部件的样式CSSProperties-
forceRender预渲染 Drawer 内元素booleanfalse
getContainer指定 Drawer 挂载的节点,并在容器内展现,false 为挂载在当前位置HTMLElement | () => HTMLElement | Selectors | falsebody
headerStyle用于设置 Drawer 头部的样式CSSProperties-
height高度, 在 placement 为 top 或 bottom 时使用string | number378
keyboard是否支持键盘 esc 关闭booleantrue
mask是否展示遮罩booleantrue
maskClosable点击蒙层是否允许关闭booleantrue
maskStyle遮罩样式CSSProperties{}
placement抽屉的方向top | right | bottom | leftright
push用于设置多层 Drawer 的推动行为boolean | { distance: string | number }{ distance: 180 }4.5.0+
rootClassName对话框外层容器的类名string-
rootStyle可用于设置 Drawer 最外层容器的样式,和 style 的区别是作用节点包括 maskCSSProperties-
size预设抽屉宽度(或高度),default 378px 和 large 736px'default' | 'large''default'4.17.0
style设计 Drawer 容器样式,如果你只需要设置内容部分请使用 bodyStyleCSSProperties-
title标题ReactNode-
openDrawer 是否可见boolean-
width宽度string | number378
zIndex设置 Drawer 的 z-indexnumber1000
onClose点击遮罩层或左上角叉或取消按钮的回调function(e)-