# Dialog 弹层

- 来源：[E10 UI 组件库](https://www.e-cology.com.cn/ui/dialog/freepass)
- 平台：PC
- 维护者：蒋贝贝
- 设计稿：http://pd.e-cology.com.cn/pd/E10/interface/e10xiaoguotu/PC/zms/zujian-Dialog/
- Issue：http://gitlab.ecology10.cn/FRONTEND/weapp-ui/-/issues?state=all&search=[Dialog]

## 代码演示

### 基础用法

简单的对话框。

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, Select, Cascader, CityPicker } from '@weapp/ui';
import { cascaderOptions } from '../mock'

const { MultiCascader } = Cascader

const { uiPcClsPrefix } = constants;
const { customDialogEventName } = Dialog;
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;
class DialogBody extends Component<{}> {
  componentDidMount() {
  }
  render() {
    return <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
      <p>DialogBody</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>
        <CityPicker level={'city'} mode='union' />
      </p>
      <p>
        <MultiCascader
          options={cascaderOptions}
        />
      </p>
      <p>
        <CityPicker level={'country'} multiple />
      </p>
      <p>
        <CityPicker multiple />
      </p>
    </div>
  }
}

class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false
    }
  }
  componentDidMount() {
    document.addEventListener(customDialogEventName, this.onVisibleChange)
  }
  componentWillUnmount() {
    document.removeEventListener(customDialogEventName, this.onVisibleChange)
  }
  onVisibleChange = (customEventOptions: any) => {
    if (customEventOptions && customEventOptions.detail && customEventOptions.detail.visible) {
      console.log(customEventOptions.detail.visible)
    }
  }
  onClose = () => {
    this.setState({ visible: false });
  }
  showDialog = () => {
    this.setState({ visible: true });
  }
  onAfterClose = () => { }
  onAfterShow = () => {
    console.log('onAfterShow');
  }
  onScale = () => console.log('onScale')
  render() {
    const { visible } = this.state;

    return (
      <div className={prefixCls}>
        <Button onClick={this.showDialog}>打开弹框</Button>
        <Dialog
          visible={visible}
          onClose={this.onClose}
          title="基础对话框"
          width={600}
          closable
          destroyOnClose
          scale
          icon="Icon--Import-and-export"
          onScale={this.onScale}
          isStopPropagation={false}
        >
          <DialogBody />
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 自定义页头页脚

自定义页头页脚，设置页头常用的属性"最大化弹窗",当设置了windowOpenUrl属性时,title区域的放大按钮可选择“最大化”或者“新窗口打开”,新窗口打开的地址为windowOpenUrl中设置的地址。

```jsx
import { Component } from 'react';
import { Dialog, Button, constants } from '@weapp/ui';

const { uiPcClsPrefix } = constants;
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;

const dataItem = {
  id: 'tab1',
  content: '可选标签',
  icon: null,
  disabled: false,
  closeable: false,
  closeIcon: null,
  data: [],
};
const data = [
  { ...dataItem },
  { ...dataItem, id: 'tab2', content: '可选标签2很长很长很长很长很长' },
  // {...dataItem, key: 'tab3'},
]
class DialogBody extends Component<{}> {
  componentDidMount() {
  }
  render() {
    return <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
      <p>DialogBody</p>
      <p>show everything...</p>
      <p>show everything...</p>
    </div>
  }
}

class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false
    }
  }

  onClose = () => {
    this.setState({ visible: false });
  }
  showDialog = () => {
    this.setState({ visible: true });
  }

  handleOk = () => {
    this.setState({ visible: false });
  };

  handleCancel = () => {
    this.setState({ visible: false });
  };
  render() {
    const { visible } = this.state;

    return (
      <div className={prefixCls}>
        <Button type={'primary'} onClick={this.showDialog}>打开自定义弹框</Button>
        <Dialog
          visible={visible}
          onClose={this.onClose}
          title="自定义页头页脚"
          width={770}
          buttons={[<Button key='a'>页头1</Button>, <Button key='b'>页头2</Button>]}
          closable
          destroyOnClose
          scale
          footer={[<Button onClick={this.handleCancel} key='cancle'>自定义</Button>,<Button onClick={this.handleCancel} key='cancle'>取消</Button>, <Button onClick={this.handleOk} type={'primary'} key='ok'>确定</Button>]}
          maskClosable
          icon="Icon--Import-and-export"
          windowOpenUrl='https://www.baidu.com/'
          menus={data}
          menuValue='tab1'
        >
          <DialogBody />
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 自定义打开方式

自定义对话框打开方式，当path属性存在时，根据路由去控制对话框的显示与隐藏；否则可以通过visible属性，去控制对话框的显示与隐藏。

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, utils } from '@weapp/ui';
import { withRouter } from 'react-router-dom';

const { formatParentPath } = utils;
const { uiPcClsPrefix } = constants;
// const { customDialogEventName } = Dialog;
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;
class DialogBody extends Component<{}> {
  componentDidMount() {
  }
  render() {
    return <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
      <p>DialogBody</p>
      <p>可通过路由控制对话框显隐...</p>
      <p>可通过visible控制对话框显隐...</p>
    </div>
  }
}
// @ts-ignore
@withRouter
class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false  // 如果通过path控制，可省略
    }
  }

  onClose = () => {
    // visible 属性控制
    // this.setState({ visible: false });

    // 路由控制
    this.props.history.go(-1);
  }
  showDialog = () => {
    // visible 属性控制
    // this.setState({ visible: true });
    
    // 路由控制
    const parentPath = formatParentPath(this.props as any);
    this.props.history.push(`${parentPath}/route`)
  }

  handleOk = () => {
    // visible 属性控制
    // this.setState({ visible: false });

    // 路由控制
    this.props.history.go(-1);

  };

  handleCancel = () => {
    // visible 属性控制
    // this.setState({ visible: false });

    // 路由控制
    this.props.history.go(-1);
  };
  render() {
    const { visible } = this.state;
    const parentPath = formatParentPath(this.props as any);
    return (
      <div className={prefixCls}>
        <Button type={'primary'} onClick={this.showDialog}>打开路由弹框</Button>
        <Dialog
          // visible={visible} // visible属性控制
          onClose={this.onClose}
          title="自定义打开方式"
          width={400}
          closable
          destroyOnClose
          footer={[<Button onClick={this.handleCancel} key='cancle'>取消</Button>, <Button onClick={this.handleOk} type={'primary'} key='ok'>确定</Button>]}
          maskClosable
          icon="Icon--Import-and-export"
          path={`${parentPath}/route`} // 路由控制
        >
          <DialogBody />
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 消息层配置

可在弹框顶部，配置消息层

```jsx
import React, { Component, memo } from 'react';
import { Dialog, Button, constants } from '@weapp/ui';

const { uiPcClsPrefix } = constants;
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
}
const prefixCls = `${uiPcClsPrefix}-demo-dialog`;

class DialogBody extends Component<{}> {
  componentDidMount() {
  }
  render() {
    return <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>DialogBody</div>
  }
}

const MessageDemo = memo(React.forwardRef<{}, {}>(
  (props) => {
    return <div className={`${prefixCls}-messageDemo`}>顶部消息层</div>
  }
))
class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false,
    }
  }
  onClose = () => {
    this.setState({ visible: false });
  }
  showDialog = () => {
    this.setState({ visible: true });
  }
  render() {
    const { visible } = this.state;
    return (
      <div className={prefixCls}>
        <Button onClick={this.showDialog} >打开弹框</Button>
        <Dialog
          visible={visible}
          onClose={this.onClose}
          title="基本用法"
          buttons={[<Button key='a'>test</Button>, <Button key='b'>test</Button>]}
          closable
          destroyOnClose
          scale
          draggable
          mask
          height={500}
          maskClosable
          icon="Icon--Import-and-export"
          message={(<MessageDemo />)}
        >
          <DialogBody />
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 确认对话框

使用 confirm() 可以快捷地弹出确认框。一般用于删除前的询问提示。支持弹框销毁后的业务处理。

```jsx
import { Component, ReactText } from 'react';
import { Dialog, Button, constants, Input, utils } from '@weapp/ui';

const { uiPcClsPrefix } = constants;
const { message, confirm } = Dialog;
const { getHd } = utils;
interface DialogDemoProps {
  history?: any;
}

const prefixCls = `${uiPcClsPrefix}-demo-btn`;
class MyInput extends Component<any, any> {
  constructor(props: any) {
    super(props)
    this.state = {
      value : ''
    }
  }
  handleChange = (value: ReactText) => {
    this.setState({
      value
    })
  }
  render() {
    return (
      <>
        test: <Input value={this.state.value} onChange={this.handleChange}></Input>
      </>
    )
  }
}
class DialogDemo extends Component<DialogDemoProps> {
  instance: any;
  confirm = () => {
    confirm({
      content: '确认删除xxx吗？',
      onOk: () => {
        console.log('OK');
      },
      onCancel: () => {
        console.log('Cancel');
      },
      destroy: () => {
        console.log('组件销毁了')
      },
    });
  }

  confirmDraggable = () => {
    confirm({
      content: '确认删除xxx吗？',
      onOk: () => {
        console.log('OK');
      },
      onCancel: () => {
        console.log('Cancel');
      },
      destroy: () => {
        console.log('组件销毁了')
      },
      draggable: true,
    });
  }

  getInstance = (el: any) => {
    this.instance = el;
  }
  close = () => {
    this.instance && this.instance.onClose()
    console.log('close')
  }
  handleOk = () => {
    this.instance && this.instance.onOk()
    console.log('ok')
  }

  confirmFooter = () => {
    confirm({
      content: '不设置left/top/right/bottom 默认水平垂直居中显示',
      height: 220 * (getHd?.() || 1),
      // enableKeyboardEvent: false,
      customKeyboardEvent:()=> {
        console.log('触发自定义的事件')
        this.close()
        // this.instance && this.instance.onOk()
      },
      getInstance: this.getInstance,
      footer: <div>
                <Button onClick={this.handleOk}>确认（支持键盘事件）</Button>
                <Button onClick={this.close}>取消</Button>
              </div>,
      destroy: () => {
        console.log('组件销毁了')
      },
      onOk: () => {
        console.log('OK');
      },
    });
  }
  confirmInput = () => {
    confirm({
      content:(
        <div>
          <MyInput></MyInput>
        </div>
      ),
      onOk: () => {
        console.log('OK');
      },
      onCancel: () => {
        console.log('Cancel');
      },
      destroy: () => {
        console.log('组件销毁了')
      }
    });
  }

  render() {
    return (
      <div className={prefixCls}>
        <Button onClick={this.confirm}>确认框</Button>
        <Button onClick={this.confirmFooter}>确认框(自定义footer)</Button>
        <Button onClick={this.confirmInput}>确认框(插入input)</Button>
        <Button onClick={this.confirmDraggable}>确认框(可拖拽)</Button>
      </div>
    );
  }
}

export default DialogDemo
```

### 提示信息

提示信息反馈，顶部居中显示，是一种不打断用户操作的提示方式，包括普通、成功、失败。

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, Icon, utils } from '@weapp/ui';

const { uiPcClsPrefix } = constants;
const { message } = Dialog;
const { getHd } = utils;
interface DialogDemoProps {
  history?: any;
}

const prefixCls = `${uiPcClsPrefix}-demo-btn`;

class DialogDemo extends Component<DialogDemoProps> {
  
  info  = () => {
    message({
      type: 'info', // type: 'info', 'error', 'success', 'custom'
      content: '这是一条普通提示',
    });
  }

  success = () => {
    message({
      type: 'success', // type: 'info', 'error', 'success', 'custom'
      content: '这是一条询问信息, 会主动消失',
    });
  }

  infoCustomClose = () => {
    message({
      type: 'error', // type: 'info', 'error', 'success', 'custom'
      content: '这是一条询问信息, 不会主动消失',
      delay: 0, // 相当于禁止主动消失
    });
  }

  maxMessageCount = () => {
    message({
      type: 'success', // type: 'info', 'error', 'success', 'custom'
      content: '这是一条询问信息, 会主动消失,最大是三条',
      maxMessageCount: 3
    });
  }
  cunstomType  = () => {
    const fontSize = 14 * (getHd?.() || 1);
    const paddingTop = 3 * (getHd?.() || 1);
    message({
      type: 'custom', // type: 'info', 'error', 'success', 'custom'
      content: <div style={{ color: '#008c8c', fontSize: `${fontSize}px`, marginTop: `${paddingTop}px`}}>自定义类型与自定义的icon</div>,
      icon: <Icon name={"Icon-remind02"} size="lg"  style={{ color: '#008c8c'}}/>,
      delay: 0
    });
  }
  render() {
    return (
      <div className={prefixCls}>
        <Button type={'primary'} onClick={this.info}>信息提示(info)</Button>
        <Button type={'success'} onClick={this.success}>信息提示(success)</Button>
        <Button type={'danger'} onClick={this.infoCustomClose}>信息提示(error)</Button>
        <Button type={'success'} onClick={this.maxMessageCount}>可控制最大展示消息数</Button>
        <Button type={'primary'} onClick={this.cunstomType}>自定义类型</Button>
      </div>
    );
  }
}

export default DialogDemo
```

### 销毁方法

组件销毁方法

```jsx
import { Component } from 'react';
import { Dialog, Button, constants } from '@weapp/ui';

const { uiPcClsPrefix } = constants;
const { message, confirm } = Dialog;

interface DialogDemoProps {
  history?: any;
}

const prefixCls = `${uiPcClsPrefix}-demo-btn`;

class DialogDemo extends Component<DialogDemoProps> {
  destroy: any;
  
  infoCustomClose = () => {
    let obj = message({
      type: 'error', // type: 'info', 'error', 'success'
      content: '这是一条询问信息, 不会主动消失',
      delay: 0, // 相当于禁止主动消失
      destroy: () => {
        console.log('组件销毁了')
      }
    });
    this.destroy = obj.destroy;
  }
  
  ondestroy = () => {
    this.destroy && typeof this.destroy === 'function' && this.destroy();
  }

  render() {
    return (
      <div className={prefixCls}>
        <Button onClick={this.infoCustomClose}>信息提示(delay=0)</Button>
        <Button onClick={this.ondestroy} type='danger'>自定义销毁按钮</Button>
      </div>
    );
  }
}

export default DialogDemo
```

### 抽屉

相当于Drawer，是一种从屏幕边缘滑出的浮层面板。点击触发按钮抽屉从右滑出，点击遮罩区关闭。

```jsx
import { Component, CSSProperties } from 'react';
import { Dialog, Button, constants, Menu, Select, Trigger } from '@weapp/ui';

const { uiPcClsPrefix } = constants;
const dataItem = {
  id: 'tab1',
  content: '可选标签',
  icon: null,
  disabled: false,
  closeable: false,
  closeIcon: null,
  data: [],
};

interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  tabVisible?: boolean;
  menuValue?: string;
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;
class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  menuRef?: HTMLDivElement;
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      tabVisible: false,
    }
  }
  showTabDialog = () => {
    this.setState({ tabVisible: true });
  }
  closeTabDialog = () => {
    this.setState({ tabVisible: false });
    console.log('onClose')
  }

  render() {
    const { tabVisible } = this.state;

    return (
      <div className={prefixCls}>
        <Button type={'primary'} onClick={this.showTabDialog}>打开弹框</Button>
        <Dialog
          visible={tabVisible}
          onClose={this.closeTabDialog}
          title="基础抽屉Drawer"
          closable
          destroyOnClose
          placement="right"
          width={800}
          noMaskClose
          icon="Icon-Advanced-search"
        >
          <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
            <p>DialogBody</p>
            <p>something...</p>
          </div>
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 自定义抽屉位置

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

```jsx
import { Component, } from 'react';
import { Dialog, Button, constants,Radio,RadioValueType,RadioOptionType,RadioEvent, utils } from '@weapp/ui';

const { needRTL } = utils;
const { uiPcClsPrefix } = constants;

interface DialogDemoProps {
  history?: any;
}

type PositionTypes = 'top'|'right'|'bottom'|'left'

interface DialogDemoState {
  tabVisible?: boolean;
  positonVaule?: PositionTypes;
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;

const positionData = [
  {
    id: 'right',
    title: needRTL?.() ? 'left' : 'right',
    content: needRTL?.() ? 'left' : 'right',
  },
  {
    id: 'left',
    title: needRTL?.() ? 'right' : 'left',
    content: needRTL?.() ? 'right' : 'left',
  },
  {
    id: 'top',
    title: 'top',
    content: 'top',
  },
  {
    id: 'bottom',
    title: 'bottom',
    content: 'bottom',
  },
];

class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  menuRef?: HTMLDivElement;
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      tabVisible: false,
      positonVaule:'right'
    }
  }
  showTabDialog = () => {
    this.setState({ tabVisible: true });
  }
  closeTabDialog = () => {
    this.setState({ tabVisible: false });
    console.log('onClose')
  }
  onRadioChange=(v: RadioValueType, o: RadioOptionType, e: RadioEvent)=>{
    const value = v as PositionTypes
    this.setState({ positonVaule: value});
  }
  render() {
    const { tabVisible,positonVaule } = this.state;
    const dialogWidth = positonVaule==='bottom'||positonVaule==='top'?'100%':"50%"
    return (
      <div className={prefixCls}>
        <Radio data={positionData} defaultValue={'right'} onChange={this.onRadioChange}/>
        <Button type={'primary'} onClick={this.showTabDialog}>打开弹框</Button>
        <Dialog
          visible={tabVisible}
          onClose={this.closeTabDialog}
          title="基础抽屉Drawer"
          closable
          destroyOnClose
          placement={positonVaule}
          width={dialogWidth}
          noMaskClose
          icon="Icon-Advanced-search"
        >
          <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
            <p>DialogBody</p>
            <p>something...</p>
          </div>
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 多层抽屉

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

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, utils } from '@weapp/ui';
const { uiPcClsPrefix } = constants;
const { getRandom } = utils;
const dialogId = `weapp-ui-dialogDemo_dialogConfig`;
const prefixCls = `${uiPcClsPrefix}-demo-dialog-dialogConfig`;

Dialog.dialogConfig = { // 全局配置参数
  blacklist: [`button[id=${prefixCls}-dialog-open-btn]`],
}

interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visibleRight?: boolean;
  visibleRightSub?: boolean;
}

class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {

  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visibleRight: false,
      visibleRightSub: false,
    }
  }

  showRightDialog = () => this.setState({ visibleRight: true })
  closeRightDialog = () => this.setState({ visibleRight: false })
  closeRightSubDialog = () => this.setState({ visibleRightSub: false });
  showRightSubDialog = () => this.setState({ visibleRightSub: true });
  render() {
    const { visibleRight, visibleRightSub } = this.state;
    return (
      <div className={prefixCls}>
        <Button onClick={this.showRightDialog} id={`${prefixCls}-dialog-open-btn`}>打开弹框</Button>
        <Dialog
         
          visible={visibleRight}
          onClose={this.closeRightDialog}
          placement="right"
          title="一级弹框"
          closable
          destroyOnClose
          resize
          noMaskClose
          wrapClassName={`${prefixCls}-rightDialog`}
          width={'55%'}
          dialogId={dialogId}
        >
         一级弹框
          <Button onClick={this.showRightSubDialog}>打开二级弹框</Button>
        </Dialog>
        <Dialog
         
          visible={visibleRightSub}
          onClose={this.closeRightSubDialog}
          placement="right"
          title="二级弹框"
          closable
          destroyOnClose
          resize
          noMaskClose
          width={'30%'}
          wrapClassName={`${prefixCls}-rightDialogSub`}
          dialogConfig={{
            whitelist: [`div[id=${dialogId}]`],
          }}
        >
          这是二级弹框
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 本地化存储抽屉宽度

Dialog设置keepDialogAlive，可以将dialog页签的拖动状态存储到localStorage中，实现本地化存储Dialog宽度，且必须保证dialogId唯一不变，如果想实现用户维度的存储，请自行在dialogId中拼接TEAMS.currentUser.id

```jsx
import { Component, CSSProperties } from 'react';
import { Dialog, Button, constants } from '@weapp/ui';

const { uiPcClsPrefix } = constants;
const dataItem = {
  id: 'tab1',
  content: '可选标签',
  icon: null,
  disabled: false,
  closeable: false,
  closeIcon: null,
  data: [],
};
const data = [
  { ...dataItem },
  { ...dataItem, id: 'tab2', content: '可选标签2很长很长很长很长很长' },
  // {...dataItem, key: 'tab3'},
]
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  tabVisible?: boolean;
  menuValue?: string;
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;
class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  menuRef?: HTMLDivElement;
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      tabVisible: false,
      menuValue: 'tab1',
    }
  }
  showTabDialog = () => {
    this.setState({ tabVisible: true });
  }
  closeTabDialog = () => {
    this.setState({ tabVisible: false });
    console.log('onClose')
  }
  onMenuChange = (key: any) => {
    this.setState({ menuValue: key });
  }
  setMenuRef = (el: any) => this.menuRef = el;
  getPopupContainer = () => this.menuRef
  onResize = (style: CSSProperties, container?: HTMLDivElement | null) => {
    console.log('onResize', style, container?.clientWidth);
  }
  render() {
    const { tabVisible, menuValue } = this.state;
    return (
      <div className={prefixCls}>
        <Button onClick={this.showTabDialog}>打开弹框</Button>
        <Dialog
          visible={tabVisible}
          onClose={this.closeTabDialog}
          title="带页签"
          closable
          destroyOnClose
          scale
          placement="right"
          resize
          top={50}
          width={800}
          maxResizeWidth={1400}
          minResizeWidth={800}
          menus={data}
          onResize={this.onResize}
          menuValue={menuValue}
          onMenuChange={this.onMenuChange}
          noMaskClose
          icon="Icon-Advanced-search"
          dialogId={'qzw'}
          keepDialogAlive
        >
          <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
            DialogBody
          </div>
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 抽屉弹出层点击穿透解决方案

Dialog设置noMaskClose，涉及Trigger弹层的组件均会出现点击穿透，导致Dialog被关闭的情况，解决方案见此案例

```jsx
import { Component, MouseEventHandler } from 'react';
import {
  Dialog, Button, constants, Menu, Select, Trigger, Input,
  Popover, Icon, ColorPicker, DatePicker, Help, HrmCard, PhotoView, RichText, Cascader, PhotoViewData, CityPicker
} from '@weapp/ui';
import { cascaderOptions } from '../mock'
const { uiPcClsPrefix } = constants;

const { MultiCascader } = Cascader

interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
  visibleSub?: boolean;
  visiblePhotoView: boolean;
  indexPhotoView: number;
}
const prefixCls = `${uiPcClsPrefix}-demo-dialog`;
const Img = (props: any) => {
  const { index, onClick } = props
  function preview() {
    onClick(index)
  }
  return <img style={{ maxHeight: 100 }} alt={props.src} src={props.src} onClick={preview} />
}
const menuData = [
  { id: 'tab1', content: '全部' },
  {
    id: 'tab2',
    content: '可选标签2',
    children: [
      { id: 'childTab1', content: '子菜单1', parentId: 'tab2' },
      {
        id: 'childTab2', content: '子菜单2', parentId: 'tab2', children: [
          { id: 'secondchildTab1', content: '二级子菜单1', parentId: 'childTab2' },
          { id: 'secondchildTab2', content: '二级子菜单2', parentId: 'childTab2' },
          { id: 'secondchildTab3', content: '二级子菜单2', parentId: 'childTab2' },
        ]
      },
      { id: 'childTab3', content: '子菜单2', parentId: 'tab2' },
    ]
  },
  { id: 'tab3', content: '可选标签3' },
];
const selectOptions = [
  { id: '1', content: '选项一', other: true, color: '#5D9CEC' },
  { id: '2', content: '选项二', custom: 3, color: '#FF4D4F' },
  { id: '3', content: '超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本超长文本', color: '#52C41A' },
  { id: '4', content: '禁用项', disabled: true }
];

const extraPlugins = [
  // 撤销回退
  'undo',
  // 源码模式
  'sourcearea',
  // 页面属性
  'docprops', // fullPage我true方可使用
  // 全选
  'selectall',
  // 查找替换
  'find',
  // 格式刷
  'copyformatting',
  // 清楚格式
  'removeformat',
  // 格式
  'format',
  'stylescombo',
  // 字体 字号已默认加载
  // 缩进
  'indentlist',
  'indentblock',
  // 对齐方式
  'justify',
  // 序号
  'list',
  'liststyle',
  // 链接
  'link',
  // 特殊字符
  'specialchar',
  // 插入水平线
  'horizontalrule',
  // 插入水平分页符
  'pagebreak',
  // 插入iframe
  'iframe',
  // 图片
  'image2',
  'uploadimage',
  // 表格
  'table',
  'tableselection',
  'tabletools',
  'tableresizerowandcolumn', // 表格拖拽调整宽高
  // 最大化
  'maximize',
  // 复制word、excel
  'pastefromword',
  // 块引用
  'blockquote',
  // 特殊标签联想搜索和匹配 (例如输入框中的@)
  'mentions',
];
const toolbar = [[
  "Undo", // 撤销
  "Redo", // 回退
  "-",
  "Source", // 源码模式
  // "-",
  "DocProps", // 页面属性: fullPage我true方可使用
  "-",
  "SelectAll", // 全选
  "Cut", // 剪切
  "Copy", // 复制
  "Find", // 查找
  "Replace", // 替换
  "-",
  "CopyFormatting", // 格式刷
  "RemoveFormat", // 清楚格式
  "-",
  "Format", // 格式
  "Font", // 字体
  "FontSize", // 字号
  "TextColor", // 颜色
  "BGColor", // 背景色
  "Bold", // 加粗
  "Italic", // 斜体
  "Underline", // 下划线
  "Strike", // 删除线
  "Subscript", // 下标
  "Superscript", // 上标
  "-",
  "NumberedList", // 编号列表
  "BulletedList", // 项目列表
  "-",
  "Indent", // 增加缩进
  "Outdent", // 减少缩进
  "-",
  "JustifyLeft", // 居左
  "JustifyCenter", // 居中
  "JustifyRight", // 居右
  "JustifyBlock", // 两端对齐
  "-",
  "Link", // 链接
  "Unlink", // 删除链接
  "-",
  "Anchor", // 锚点
  "SpecialChar", // 特殊字符
  "HorizontalRule", // 插入水平线
  "PageBreak", // 插入入水分页符
  "-",
  "Iframe", // iframe
  "Table", // 表格
  "Blockquote",
  "Maximize" // 最大化
]];
const ckConfig = {
  extraPlugins: extraPlugins.join(','),
  toolbar,
  fullPage: true, // 编辑内容作为完成的html页面输出
  uploadUrl: '/api/file/upload', // 上传图片url
  uploadParams: {  // 上传图片params
    eteamsId: '35e32b15a4eea7a7f3e8749f9f63d523',
    module: "document",
  },
  mentions: [ // 联想功能配置 (例如输入框中的#)
    // 方式一：通过固定的数据匹配
    {
      feed: ['事项关联1', '事项关联2', 'John', '陈欣', '陈是', '王大力', '张尽可能'],
      minChars: 0,
      marker: '#',
      outputTemplate: '<a contenteditable="false" pluginname="at" data-id={id}>@{name}</a>&nbsp;', // 编辑器中最终输入的html （pluginname pluginid是为了组件统一管理数据）
    },
    // 方式二：通过走接口匹配
    // {
    //   feed: '/api/bs/hrm/user/userFast?keywords={encodedQuery}', // 接口 {encodedQuery} 为搜索的数据
    //   minChars: 0, // 标记字符后面的字符数
    //   marker: '@', // 标记,可自定义为#等
    //   itemTemplate: '<li data-id="{id}">{name}</li>', // 下拉框显示模板。必须有data-id="{id}"
    //   outputTemplate: '<a contenteditable="false" pluginname="at" data-id={id}>@{name}</a>&nbsp;', // 编辑器中最终输入的html （pluginname pluginid是为了组件统一管理数据）
    // }
  ]
};

const extendsConfig = [
  {
    name: 'emoticon', // 组件名称
    title: '插入表情', // 工具栏提示文字
    comProps: {} // 组件属性
  },
  {
    name: 'at',
    title: '@人员',
    comProps: {
      showTargetMember: true,
    }
  },
];
const images: PhotoViewData[] = [
  {
    id: '1',
    src: '/build/ui/demo/assets/photo-view/1.jpg',
    originSrc: '/build/ui/demo/assets/photo-view/1.jpg',
    imgSize: 1024,
    intro: '这是两只小肥羊',
    user: '屈正巍',
    time: '2021-10-22 18:00:00'
  },
  {
    id: '2',
    src: '/build/ui/demo/assets/photo-view/2.jpg',
    originSrc: '/build/ui/demo/assets/photo-view/2.jpg',
    imgSize: 10240,
    intro: '这是好多云',
    user: '屈正巍',
    time: '2021-10-22 18:00:00'
  },
  {
    id: '3',
    src: '/build/ui/demo/assets/photo-view/1.jpg',
    intro: '这是一片湖',
    user: '屈正巍',
    time: '2021-10-22 18:00:00'
  }
]
const { openHrmCard } = HrmCard;

class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  menuContainer?: HTMLDivElement;
  triggerContainer?: HTMLDivElement;
  popoverContainer?: HTMLSpanElement;
  colorContainer?: HTMLDivElement;
  datePickerContainer?: HTMLDivElement;
  hrmCardContainer?: HTMLAnchorElement;

  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false,
      visiblePhotoView: false,
      indexPhotoView: 0,
    }
  }
  closeDialog = () => this.setState({ visible: false });
  onClose = () => {
    Dialog.confirm({
      content: '确定关闭吗？',
      onOk: this.closeDialog,
    })
  }
  showDialog = () => {
    this.setState({ visible: true });
  }
  onAfterClose = () => { }
  onAfterShow = () => {
    console.log('onAfterShow');
  }
  setMenuContainer = (el: HTMLDivElement) => this.menuContainer = el;
  getPopupContainerMenu = () => this.menuContainer;

  setTriggerContainer = (el: HTMLDivElement) => this.triggerContainer = el;
  getPopupContainerTrigger = () => this.triggerContainer;

  setPopoverContainer = (el: HTMLSpanElement) => this.popoverContainer = el;
  getPopupContainerPopover = () => this.popoverContainer;

  setColorPickerContainer = (el: HTMLDivElement) => this.colorContainer = el;
  getPopupContainerColorPicker = () => this.colorContainer;

  setDatePickerPickerContainer = (el: HTMLDivElement) => this.datePickerContainer = el;
  getPopupContainerDatePicker = () => this.datePickerContainer;

  openHrmCard: MouseEventHandler<HTMLAnchorElement> = (e) => openHrmCard(e, '5138815178900248180', 'inside', 'bs/hrm', { bindTriggerContainer: true, inDialog: true })

  setHrmCardContainer = (el: HTMLAnchorElement) => this.hrmCardContainer = el;
  getPopupContainerHrmCard = () => this.hrmCardContainer;

  showDialogSub = () => this.setState({ visibleSub: true })
  onCloseSub = () => this.setState({ visibleSub: false })

  onClosePhotoView = () => { this.setState({ visiblePhotoView: false }) }
  previewPhotoView = () => this.setState({ visiblePhotoView: true })

  showImage0 = () => { PhotoView.showImage(images, 0) }
  showImage1 = () => { PhotoView.showImage(images, 1) }
  showImage2 = () => { PhotoView.showImage(images, 2) }

  render() {
    const { visible, visibleSub, visiblePhotoView, indexPhotoView } = this.state;
    return (
      <div className={prefixCls}>
        <Button onClick={this.showDialog}>打开弹框</Button>
        <Dialog
          visible={visible}
          onClose={this.onClose}
          title="基本用法"
          buttons={[<Button key='a'>test</Button>, <Button key='b'>test</Button>]}
          closable
          draggable
          destroyOnClose
          onAfterClose={this.onAfterClose}
          scale
          resize
          footer={[<Button key='a'>test</Button>, <Button key='b'>test</Button>]}
          noMaskClose
          onAfterShow={this.onAfterShow}
          className="test"
          placement="right"
          wrapClassName="wrappCls"
        >
          <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
            <div ref={this.setMenuContainer} className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>Menu</div>
              <Menu
                defaultValue={'tab1'}
                data={menuData}
                // type="select"
                triggerProps={{
                  popupClassName: 'menuDemo-select',
                  action: ['click']
                  // getPopupContainer: this.getPopupContainerMenu,
                }}
                childTriggerProps={{
                  popupClassName: 'menuDemo-select-child',
                  // getPopupContainer: this.getPopupContainerMenu,
                  action: ['click']
                }}
              // bindTriggerContainer
              />
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>Select</div>
              <Select
                style={{ width: 200 }}
                data={selectOptions}
                bindTriggerContainer
              />
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>Cascader</div>
              <Cascader
                options={cascaderOptions}
              />
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>MultiCascader</div>
              <MultiCascader
                options={cascaderOptions}
              />
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>MultiCascader（含defaultLabel）</div>
              <MultiCascader
                options={cascaderOptions}
                defaultLabel={[['测试1'], ['测试2']]}
              />
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>CityPIcker</div>
              <CityPicker
                level={'city'}
              />
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>Trigger</div>
              <Trigger
                action={['click']}
                popup={(
                  <div style={{ background: '#66B6F3', color: '#fff', padding: '10px 20px' }}>
                    TriggerContent
                  </div>
                )}
                popupClassName="popupClassName"
                getPopupContainer={this.getPopupContainerTrigger}
              >
                <div ref={this.setTriggerContainer}>
                  <Input />
                </div>
              </Trigger>
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>Popover</div>
              <Popover
                action={['click']}
                popup={(
                  <div style={{ background: '#66B6F3', color: '#fff', padding: '10px 20px' }}>
                    PopoverContent
                  </div>
                )}
                placement={"right"}
                triggerProps={{
                  getPopupContainer: this.getPopupContainerPopover
                }}
              >
                <span ref={this.setPopoverContainer} className={`${prefixCls}-single-container`}>
                  <Icon name="Icon-Message-center" />
                </span>
              </Popover>
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>ColorPicker</div>
              <div ref={this.setColorPickerContainer} className={`${prefixCls}-single-container`}>
                <ColorPicker
                  getPopupContainer={this.getPopupContainerColorPicker}
                  bindTriggerContainer
                  triggerProps={{
                    mask: false,
                    // getPopupContainer: this.getPopupContainerColorPicker,
                    popupPlacement: 'rightBottom',
                  }}
                />
              </div>
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>DatePicker及其他日期组件解决方案</div>
              <div ref={this.setDatePickerPickerContainer}>
                <DatePicker
                  bindTriggerContainer
                  triggerProps={{
                    // getPopupContainer: this.getPopupContainerDatePicker,
                    popupPlacement: 'bottomLeft',
                  }} />
              </div>
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>Help</div>
              <Help
                title={'在这里写入相应的提示信息在这里写入相应的提示信息在这里写入相应的提示信息在这里写入相应的提示信息'}
                placement="right"
                width={200}
              />
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>HrmCard(Trigger模式)</div>
              <HrmCard
               
                triggerProps={{
                  popupPlacement: 'topLeft',
                  getPopupContainer: this.getPopupContainerHrmCard,
                }}
                id={"5112105736079258211"}
                module="bs/hrm"
                type={"external"}
                inDialog={true}
              >
                <span className={`${prefixCls}-name`} ref={this.setHrmCardContainer}>外部联系人</span>
              </HrmCard>
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>HrmCard</div>
              <a className={`${prefixCls}-name`} onClick={this.openHrmCard}>王利琴</a>
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>Dialog</div>
              <Button onClick={this.showDialogSub}>打开弹框</Button>
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>RichText</div>
              <RichText
                defaultValue={'<p>Hello from CKEditor 4!</p>'}
                id="dialog_ckeditor_full" // 注意: id必填，并且唯一
                ckConfig={ckConfig}
                extendsConfig={extendsConfig}
              />
            </div>
            <div className={`${prefixCls}-single`}>
              <div className={`${prefixCls}-title`}>PhotoView</div>
              {images.map((item, index) =>
                <Img
                  key={item.id}
                  index={index}
                  src={item.src}
                  onClick={this.previewPhotoView} />
              )}
              <PhotoView
                visible={visiblePhotoView}
                photoIndex={indexPhotoView}
                data={images}
                onClose={this.onClosePhotoView}
              />
            </div>
          </div>
        </Dialog>
        <Dialog
          visible={visibleSub}
          onClose={this.onCloseSub}
          title="基本用法"
          closable
          destroyOnClose
          scale
          draggable
          mask
          maskClosable
        >
          基本用法
          <Button onClick={this.showImage0}>预览第1张</Button>
          <Button onClick={this.showImage1}>预览第2张</Button>
          <Button onClick={this.showImage2}>预览第3张</Button>
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 全屏状态设置

设置dialog全屏占比

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, Radio, RadioDataType, RadioValueType, RadioOptionType } from '@weapp/ui';

const { uiPcClsPrefix } = constants;
const { customDialogEventName } = Dialog;
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
  visible1?:boolean;
  arr: any;
  radioValue: '95%' | '100%';
  placement: string,
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;

const checkboxOptions: RadioDataType = [
  {
    id: '95%',
    title: '95%',
    content: '95%',
  },
  {
    id: '100%',
    title: '100%',
    content: '100%',
  }
];

const placementOptions: RadioDataType = [
  { id: 'middle', title: 'middle', content: 'middle' },
  { id: 'left', title: 'left', content: 'left' },
  { id: 'right', title: 'right', content: 'right' },
  { id: 'top', title: 'top', content: 'top' },
  { id: 'bottom', title: 'bottom', content: 'bottom' },
]
class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false,
      visible1:false,
      arr: [
        { name: "data1" },
        { name: "data2" },
        { name: "data3" },
        { name: "data4" },
        { name: "data5" },
        { name: "data6" },
        { name: "data7" },
      ],
      radioValue: '100%',
      placement: 'middle',
    }
  }
  componentDidMount() {
    document.addEventListener(customDialogEventName, this.onVisibleChange)
  }
  componentWillUnmount() {
    document.removeEventListener(customDialogEventName, this.onVisibleChange)
  }
  onVisibleChange = (customEventOptions: any) => {
    if (customEventOptions && customEventOptions.detail && customEventOptions.detail.visible) {
      console.log(customEventOptions.detail.visible)
    }
  }
  onClose = () => {
    this.setState({ visible: false });
  }
  onClose1 = () => {
    this.setState({ visible1: false });
  }
  showDialog = () => {
    this.setState({ visible: true });
  }
  showDialog1  = () => {
    this.setState({ visible1: true });
  }
  onAfterClose = () => { }
  onAfterShow = () => {
    console.log('onAfterShow');
  }
  onScale = () => console.log('onScale')
  handleAdd = () => {
    const { arr } = this.state
    let data = JSON.parse(JSON.stringify(arr))
    const obj = {
      name: `data${arr.length + 1}`
    }
    data.push(obj)
    this.setState({ arr: data })
  }
  handleDelete = () => {
    const { arr } = this.state
    let data = JSON.parse(JSON.stringify(arr))
    data.pop()
    this.setState({ arr: data })
  }

  onRadioChange = (v: RadioValueType, o: RadioOptionType) => {
    console.log('radioValue', v)
    this.setState({ radioValue: v as any })
  }
  onPlacementChange = (v: RadioValueType, o: RadioOptionType) => this.setState({ placement: v as any })
  render() {
    const { visible, radioValue, placement,visible1 } = this.state;
    return (
      <div className={prefixCls}>
        <h4>placement为middle，且必须设置top</h4>
        <Button onClick={this.showDialog} >打开弹框</Button>
        <Button onClick={this.showDialog1} >打开弹框(无footer)</Button>
        <div>
          <span>设置dialog全屏占比：</span>
          <Radio data={checkboxOptions} onChange={this.onRadioChange} value={radioValue} />
        </div>
        <div>
          <span>设置dialog打开方向：</span>
          <Radio data={placementOptions} onChange={this.onPlacementChange} value={placement} />
        </div>
        <Dialog
          visible={visible}
          onClose={this.onClose}
          title="placement为middle且设置了top"
          buttons={[<Button key='a'>test</Button>, <Button key='b'>test</Button>]}
          closable
          destroyOnClose
          onAfterClose={this.onAfterClose}
          scale
          footer={[<Button key='a'>test</Button>, <Button key='b'>test</Button>]}
          mask
          maskClosable
          onAfterShow={this.onAfterShow}
          className="test"
          wrapClassName="wrappCls"
          icon="Icon--Import-and-export"
          onScale={this.onScale}
          isStopPropagation={false}
          isEnlargeFullScreen={radioValue === '100%'}
          placement={placement as any}
        >
          <Button onClick={this.handleAdd}>add</Button>
          <Button onClick={this.handleDelete}>delete</Button>
          {
            this.state.arr.map((item: any, index: number) => <h1 key={index}>{item.name}</h1>)
          }
        </Dialog>
        <Dialog 
          visible={visible1}
          onClose={this.onClose1}
          title="placement为middle且设置了top"
          buttons={[<Button key='a'>test</Button>, <Button key='b'>test</Button>]}
          closable
          destroyOnClose
          onAfterClose={this.onAfterClose}
          scale
          mask
          top={30}
          maskClosable
          onAfterShow={this.onAfterShow}
          className="test"
          wrapClassName="wrappCls"
          icon="Icon--Import-and-export"
          onScale={this.onScale}
          isStopPropagation={false}
          isEnlargeFullScreen={radioValue === '100%'}
          placement={placement as any}
        >
          <Button onClick={this.handleAdd}>add</Button>
          <Button onClick={this.handleDelete}>delete</Button>
          {
            this.state.arr.map((item: any, index: number) => <h1 key={index}>{item.name}</h1>)
          }
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 弹框大小复写

当 ignoreCalculationContainer 为 true 时,忽略dialog内部宽高的最大最小值限定规则

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, utils } from '@weapp/ui';
//@ts-ignore
const { getHd } = utils; // 全局字体设置
const { uiPcClsPrefix } = constants;
interface DialogDemoProps {
  history?: any;
}
interface DialogDemoState {
  visible?: boolean;
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;
class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false
    }
  }
  onVisibleChange = (customEventOptions: any) => {
    if (customEventOptions && customEventOptions.detail && customEventOptions.detail.visible) {
      console.log(customEventOptions.detail.visible)
    }
  }
  onClose = () => {
    this.setState({ visible: false });
  }
  showDialog = () => {
    this.setState({ visible: true });
  }
  render() {
    const { visible } = this.state;
    return (
      <div className={prefixCls}>
        <h4>placement为middle，默认水平垂直方向居中</h4>
        <Button onClick={this.showDialog}>打开弹框</Button>
        <Dialog
          visible={visible}
          onClose={this.onClose}
          title="基本用法"
          buttons={[<Button key='a'>test</Button>, <Button key='b'>test</Button>]}
          closable
          destroyOnClose
          scale
          footer={[<Button key='a'>test</Button>, <Button key='b'>test</Button>]}
          mask
          maskClosable
          className="test"
          wrapClassName="wrappCls"
          icon="Icon--Import-and-export"
          isStopPropagation={false}
          ignoreCalculationContainer
          width={250 * (getHd?.() || 1)}
          height={180 * (getHd?.() || 1)}
        >
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 默认全屏对话框

当 defaultInnerScale 为 true 时，打开弹窗时默认全屏

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, Select, Cascader, CityPicker } from '@weapp/ui';
import { cascaderOptions } from '../mock'

const { MultiCascader } = Cascader

const { uiPcClsPrefix } = constants;
const { customDialogEventName } = Dialog;
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;
class DialogBody extends Component<{}> {
  componentDidMount() {
  }
  render() {
    return <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
      <p>默认全屏对话框</p>
    </div>
  }
}

class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false
    }
  }
  componentDidMount() {
    document.addEventListener(customDialogEventName, this.onVisibleChange)
  }
  componentWillUnmount() {
    document.removeEventListener(customDialogEventName, this.onVisibleChange)
  }
  onVisibleChange = (customEventOptions: any) => {
    if (customEventOptions && customEventOptions.detail && customEventOptions.detail.visible) {
      console.log(customEventOptions.detail.visible)
    }
  }
  onClose = () => {
    this.setState({ visible: false });
  }
  showDialog = () => {
    this.setState({ visible: true });
  }
  onAfterClose = () => { }
  onAfterShow = () => {
    console.log('onAfterShow');
  }
  onScale = () => console.log('onScale')
  render() {
    const { visible } = this.state;

    return (
      <div className={prefixCls}>
        <Button onClick={this.showDialog}>打开全屏弹框</Button>
        <Dialog
          visible={visible}
          onClose={this.onClose}
          title="默认全屏对话框"
          width={600}
          closable
          destroyOnClose
          scale
          icon="Icon--Import-and-export"
          onScale={this.onScale}
          isStopPropagation={false}
          defaultInnerScale
        >
          <DialogBody />
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 监听弹窗容器宽高变化，变化后重置拖拽位置

当 resetDragPosition 为 true 时，拖拽完弹窗后，弹窗宽高发生变化会重置弹窗位置

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, Cascader, CityPicker } from '@weapp/ui';
import { cascaderOptions } from '../mock'

const { MultiCascader } = Cascader

const { uiPcClsPrefix } = constants;
const { customDialogEventName } = Dialog;
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;
class DialogBody extends Component<any, any> {
  constructor(props: any) {
    super(props);
    this.state = {
      mockData: []
    }
  }
  componentDidMount() {
    let arr:any = []
    for(let i = 0; i < 20; i++) {
      arr[i] = {
        title: i
      }
    }
    setTimeout(() => {
      this.setState({
        mockData: arr
      })
    }, 3000);
  }
  render() {
    return <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
      <p>DialogBody</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>
        <CityPicker level={'city'} mode='union' />
      </p>
      <p>
        <MultiCascader
          options={cascaderOptions}
        />
      </p>
      <p>
        <CityPicker level={'country'} multiple />
      </p>
      <p>
        <CityPicker multiple />
      </p>
      {
        this.state.mockData.map((item: any) => (
          <div key={item.title}>{item.title}</div>
        ))
      }
    </div>
  }
}

class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false
    }
  }
  componentDidMount() {
    document.addEventListener(customDialogEventName, this.onVisibleChange)
  }
  componentWillUnmount() {
    document.removeEventListener(customDialogEventName, this.onVisibleChange)
  }
  onVisibleChange = (customEventOptions: any) => {
    if (customEventOptions && customEventOptions.detail && customEventOptions.detail.visible) {
      console.log(customEventOptions.detail.visible)
    }
  }
  onClose = () => {
    this.setState({ visible: false });
  }
  showDialog = () => {
    this.setState({ visible: true });
  }
  onAfterClose = () => { }
  onAfterShow = () => {
    console.log('onAfterShow');
  }
  onScale = () => console.log('onScale')
  render() {
    const { visible } = this.state;

    return (
      <div className={prefixCls}>
        <Button onClick={this.showDialog}>打开弹框</Button>
        <Dialog
          visible={visible}
          onClose={this.onClose}
          title="基础对话框"
          width={600}
          closable
          destroyOnClose
          scale
          icon="Icon--Import-and-export"
          onScale={this.onScale}
          isStopPropagation={false}
          resetDragPosition
        >
          <DialogBody />
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### Dialog上、下、左、右侧内容自定义

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, Select, Cascader, CityPicker, utils } from '@weapp/ui';
import { cascaderOptions } from '../mock'

const { MultiCascader } = Cascader

const { uiPcClsPrefix } = constants;
const { customDialogEventName } = Dialog;
const { needRTL } = utils;
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
}
const prefixCls = `${uiPcClsPrefix}-demo-dialog`;
class DialogBody extends Component<{}> {
  componentDidMount() {
  }
  render() {
    return <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
      <p>DialogBody</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>
        <CityPicker level={'city'} mode='union' />
      </p>
      <p>
        <MultiCascader
          options={cascaderOptions}
        />
      </p>
      <p>
        <CityPicker level={'country'} multiple />
      </p>
      <p>
        <CityPicker multiple />
      </p>
    </div>
  }
}

class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false
    }
  }
  onClose = () => {
    this.setState({ visible: false });
  }
  showDialog = () => {
    this.setState({ visible: true });
  }
  onAfterClose = () => { }
  onAfterShow = () => {
    console.log('onAfterShow');
  }
  onScale = () => console.log('onScale')
  getLeftExtraContent = () => {
    if (needRTL?.()) {
      return (<div className={`${prefixCls}-rightExtraContent`}>right</div>)
    }
    return (<div className={`${prefixCls}-leftExtraContent`}>left</div>)
  }
  getRightExtraContent = () => {
    if (needRTL?.()) {
      return (<div className={`${prefixCls}-leftExtraContent`}>left</div>)
    }
    return (<div className={`${prefixCls}-rightExtraContent`}>right</div>)
  }
  getBottomExtraContent = () => {
    return (<div className={`${prefixCls}-bottomExtraContent`}>bottom</div>)
  }
  leftExtraContentProps = {
    className: `${prefixCls}-leftExtraContent-container`,
    allowHidden: true,
  }
  rightExtraContentProps = {
    className: `${prefixCls}-rightExtraContent-container`
  }
  render() {
    const { visible } = this.state;

    return (
      <div className={prefixCls}>
        <Button onClick={this.showDialog}>打开弹框</Button>
        <Dialog
          visible={visible}
          onClose={this.onClose}
          title="基础对话框"
          width={1000}
          closable
          destroyOnClose
          scale
          icon="Icon--Import-and-export"
          onScale={this.onScale}
          isStopPropagation={false}
          topExtraContent={<div className={`${prefixCls}-topExtraContent`}>top</div>}
          leftExtraContent={this.getLeftExtraContent}
          leftExtraContentProps={this.leftExtraContentProps}
          rightExtraContentProps={this.rightExtraContentProps}
          rightExtraContent={this.getRightExtraContent}
          bottomExtraContent={this.getBottomExtraContent}
        >
          <DialogBody />
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

### 页脚改变

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, utils } from '@weapp/ui';
import { classUseMemo } from '@weapp/utils';
//@ts-ignore
const { getHd } = utils;
const { uiPcClsPrefix } = constants;
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
  showFooter: boolean;
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;

class DialogBody extends Component<{ onClick?: () => void }> {
  componentDidMount() {
  }
  render() {
    const { onClick } = this.props;
    const hd = getHd?.() || 1;
    const customStyle = classUseMemo('customStyle', this, () => {
      return {
        maxHeight: 700 / hd,
      }
    }, [hd]);
    return <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`} style={customStyle}>
      <p>DialogBody</p>
      <Button
       
        onClick={onClick}
      >
        展示页脚
      </Button>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
      <p>show everything...</p>
    </div>
  }
}

class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false,
      showFooter: false,
    }
  }

  onClose = () => {
    this.setState({ visible: false });
  }
  showDialog = () => {
    this.setState({ visible: true });
  }
  handleClick = () => {
    this.setState({ showFooter: true });
  }

  handleOk = () => {
    this.setState({ visible: false });
  };

  handleCancel = () => {
    this.setState({ visible: false });
  };
  render() {
    const { visible, showFooter } = this.state;

    const footer = showFooter ? [
      <Button
       
        onClick={this.handleCancel}
        key='cancle'
      >
        自定义
      </Button>,
      <Button
       
        onClick={this.handleCancel}
        key='cancle'
      >
        取消
      </Button>,
      <Button
       
        onClick={this.handleOk}
        type={'primary'}
        key='ok'
      >
        确定
      </Button>
    ] : "";

    const dialog = visible ? (
      <Dialog
        visible={visible}
        onClose={this.onClose}
        title="自定义页头页脚"
        width={750}
        buttons={[<Button key='a'>页头1</Button>, <Button key='b'>页头2</Button>]}
        closable
        destroyOnClose
        scale
        footer={footer}
        maskClosable
        icon="Icon--Import-and-export"
        windowOpenUrl='https://www.baidu.com/'
      >
        <DialogBody
         
          onClick={this.handleClick}
        />
      </Dialog>
    ) : null;

    return (
      <div className={prefixCls}>
        <Button
         
          type={'primary'}
          onClick={this.showDialog}
        >
          打开自定义弹框
        </Button>
        {dialog}
      </div>
    );
  }
}

export default DialogDemo
```

### 全屏受控

当 innerScale 为 true 时，弹窗全屏,为 false 时,弹窗非全屏

```jsx
import { Component } from 'react';
import { Dialog, Button, constants, Select } from '@weapp/ui';

const selectOptions = [
  { id: 'middle', content: '居中' },
  { id: 'right', content: '右侧' },
];

const { uiPcClsPrefix } = constants;
const { customDialogEventName } = Dialog;
interface DialogDemoProps {
  history?: any;
}

interface DialogDemoState {
  visible?: boolean;
  innerScale?: boolean
  placement?: any
  isEnlargeFullScreen?: boolean
}
const prefixCls = `${uiPcClsPrefix}-demo-btn`;
class DialogBody extends Component<any, any> {
  componentDidMount() {
  }
  render() {
    return <div className={`${uiPcClsPrefix}-demo-dialog-dialogBody`}>
      {this.props.btns}
      <p>默认全屏对话框</p>
    </div>
  }
}

class DialogDemo extends Component<DialogDemoProps, DialogDemoState> {
  constructor(props: DialogDemoProps) {
    super(props);
    this.state = {
      visible: false,
      innerScale: true,
      placement: 'right',
      isEnlargeFullScreen: true,
    }
  }
  componentDidMount() {
    document.addEventListener(customDialogEventName, this.onVisibleChange)
  }
  componentWillUnmount() {
    document.removeEventListener(customDialogEventName, this.onVisibleChange)
  }
  onVisibleChange = (customEventOptions: any) => {
    if (customEventOptions && customEventOptions.detail && customEventOptions.detail.visible) {
      console.log(customEventOptions.detail.visible)
    }
  }
  onClose = () => {
    this.setState({ visible: false });
  }
  showDialog = () => {
    this.setState({ visible: true });
  }
  changeInnerScale = () => {
    this.setState({ innerScale: !this.state.innerScale });
  }
  changeIsEnlargeFullScreen = () => {
    this.setState({ isEnlargeFullScreen: !this.state.isEnlargeFullScreen });
  }
  changePlacement = (v: any) => {
    this.setState({ placement: v });
  }
  onAfterClose = () => { }
  onAfterShow = () => {
    console.log('onAfterShow');
  }
  onScale = (scale?: boolean) => {
    this.setState({ innerScale: scale })
  }
  render() {
    const { visible, innerScale, placement, isEnlargeFullScreen } = this.state;
    console.log('placement', placement)
    console.log('innerScale', innerScale)
    return (
      <div className={prefixCls}>
        点击切换全屏模式：
        {
          <Button onClick={this.changeInnerScale}>{innerScale ? '全屏' : '非全屏'}</Button>
        }
        <br />
        点击切换全屏是否铺满：
        {
          <Button onClick={this.changeIsEnlargeFullScreen}>{isEnlargeFullScreen ? '铺满' : '不铺满'}</Button>
        }
        <br />
        点击切换弹出模式：
        {
          <Select
            style={{ width: 200 }}
            data={selectOptions}
            value={placement}
            onChange={this.changePlacement}
            bindTriggerContainer
          />
        }
        <br />
        <Button onClick={this.showDialog}>打开全屏弹框</Button>
        <Dialog
          visible={visible}
          onClose={this.onClose}
          title="默认全屏对话框"
          width={600}
          closable
          destroyOnClose
          scale
          icon="Icon--Import-and-export"
          onScale={this.onScale}
          isStopPropagation={false}
          defaultInnerScale
          innerScale={innerScale}
          placement={placement}
          isEnlargeFullScreen={isEnlargeFullScreen}
        >
          <DialogBody />
        </Dialog>
      </div>
    );
  }
}

export default DialogDemo
```

## API

### 参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| placement | middle \| top \| right \| bottom \| left | string | 否 | middle |
| buttons | 按钮组(顶部) | ReactNode | 否 |  |
| bodyStyle | Dialog 内容部分样式 | CSSProperties | 否 |  |
| maskStyle | Dialog 遮罩层部分样式 | CSSProperties | 否 |  |
| visible | 显示受控 | boolean | 否 |  |
| onClose | 击遮罩层或右上角叉或取消按钮的回调 | () => void | 否 |  |
| onAfterClose | Dialog 关闭后回调(带动画效果) | ( () => void; | 否 |  |
| height | Dialog 高度（注意：1. left/right 模式不可改。 2. placement 为 middle 时，高度设置小于 200 不生效） | number \| string | 否 |  |
| width | Dialog 宽度 （注意：placement 为 middle 时，宽度设置小于 380 不生效） | number \| string | 否 |  |
| closable | 是否显示右上角的关闭按钮 | boolean | 否 |  |
| closeIcon | 自定义关闭按钮 | ReactNode | 否 |  |
| destroyOnClose | 关闭时销毁 Drawer 里的子元素 | boolean | 否 |  |
| forceRender | 预渲染弹框内部内容 | boolean | 否 |  |
| top | 距离顶部高度 | number \| string | 否 |  |
| left | 距离左侧高度 | number \| string | 否 |  |
| right | 距离右侧高度 | number \| string | 否 |  |
| bottom | 距离底部高度 | number \| string | 否 |  |
| mask | 是否展示遮罩 | boolean | 否 |  |
| maskClosable | 点击蒙层是否允许关闭 | boolean | 否 |  |
| scale | 是否支持最大化 | boolean | 否 |  |
| onScale | 放大/缩小弹框回调 | () => void | 否 |  |
| footer | 按钮组(底部) | ReactNode | 否 |  |
| headerStyle | Dialog 标题区样式 | CSSProperties | 否 |  |
| zIndex | Dialog 层级 | number | 否 |  |
| getContainer | 弹层容器定位 | (element?: HTMLElement) => HTMLElement | 否 |  |
| draggable | Dialog 是否开启拖拽 | boolean | 否 | true |
| path | 通过路由打开 | string | 否 |  |
| wrapClassName | 外层容器 class | string | 否 |  |
| wrapStyle | 外层容器自定义样式 | CSSProperties | 否 |  |
| noMaskClose | 无蒙层，Dialog 外部触发弹窗关闭，非 middle 模式支持 | boolean | 否 |  |
| resize | 是否支持拖拽调整宽度 | boolean | 否 |  |
| keepDialogAlive | 业签模式是否开启本地化存储(dialogId 必须唯一不变) | boolean | 否 | true |
| maxResizeWidth | 可调整的最大宽度 | string \| number | 否 |  |
| minResizeWidth | 可调整的最小宽度 | string \| number | 否 |  |
| maxResizeHeight | 可调整的最大高度 | string \| number | 否 |  |
| minResizeHeight | 可调整的最小高度 | string \| number | 否 |  |
| onResize | 拖拽事件回调 | (style: CSSProperties, container?: HTMLDivElement \| null) => void | 否 |  |
| customRenderDialogBody | 自定义弹框内容(用于复写基于 Dialog 开发的组件弹层内容) | (_: any, ele: ReactNode) => ReactNode | 否 |  |
| customRenderDialogTitle | 自定义标题内容(用于复写基于 Dialog 标题内容) | (_: any, ele: ReactNode) => ReactNode | 否 |  |
| customRenderInDialogContainer | 在 container 层级下复写弹框内容 | ReactNode | 否 |  |
| noTitle | 隐藏弹框顶部内容 | boolean | 否 |  |
| dialogId | 弹框唯一标记 | string | 否 |  |
| isStopPropagation | 禁止阻止冒泡 | boolean | 否 | true |
| message | 消息层内容 | string \| ReactNode | 否 |  |
| windowOpenUrl | 从新的窗口打开该 dialog 的地址 | string | 否 |  |
| ignoreCalculationContainer | 忽略 dialog 内部宽高的最大最小值限定规则 | boolean | 否 | false |
| enableEventEmitter | 启用事件监听方案 | boolean | 否 | true |
| isEnlargeFullScreen | 全屏模式下弹框宽高占可视区域比例 | boolean | 否 | false |
| closeAnimation | 关闭动画 | boolean | 否 | false |
| ref | 组件实例 | any | 否 |  |
| defaultInnerScale | 默认全屏 | boolean | 否 |  |
| innerScale | 是否全屏，优先级高于defaultInnerScale | boolean | 否 |  |
| resetDragPosition | 监听弹窗容器宽高变化，变化后重置拖拽位置 | boolean | 否 |  |
| topExtraContent | 自定义顶部内容 | ReactNode | 否 |  |
| topExtraContentProps | 自定义弹层顶部Layout区参数配置 | LayoutBoxProps | 否 |  |
| leftExtraContent | 自定义左侧内容 | ReactNode | 否 |  |
| leftExtraContentProps | 自定义弹层左侧Layout区参数配置 | LayoutBoxProps | 否 |  |
| rightExtraContent | 自定义右侧内容 | ReactNode | 否 |  |
| rightExtraContentProps | 自定义弹层右侧Layout区参数配置 | LayoutBoxProps | 否 |  |
| bottomExtraContent | 自定义底部内容 | ReactNode | 否 |  |
| bottomExtraContentProps | 自定义弹层底部Layout区参数配置 | LayoutBoxProps | 否 |  |
| dialogConfig | 功能同Dialog.dialogConfig,优先级高于Dialog.dialogConfig | AnyObj | 否 |  |
### Dialog 支持 Title 组件的所有参数

[详情查看 Title 组件文档](/ui/title)

### Dialog.dialogConfig 说明

**1. 一般用于全局Dialog参数配置 **

**2. 组件props上支持dialogConfig参数，支持覆盖全局dialogConfig配置 **

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| top | 距离顶部高度 | number\|string | 否 |  |
| left | 距离左侧高度 | number\|string | 否 |  |
| right | 距离右侧高度 | number\|string | 否 |  |
| bottom | 距离底部高度 | number\|string | 否 |  |
| placement | 弹框打开方向(middle \| top \| right \| bottom \| left) | string | 否 |  |
| cloestContainers | 禁止关闭弹框的触发器区域容器标记，如'div[id="PhotoView_Slider"]' | Array<string> | 否 |  |
| blacklist | 禁止关闭弹框的触发器区域容器标记，如'div[id="PhotoView_Slider"]' | Array<string> | 否 |  |
| whitelist | 允许关闭弹框的触发器区域容器标记，如'div[id="PhotoView_Slider"]' | Array<string> | 否 |  |
| whitelist | 允许在blacklist的基础上添加不被传入的props中的dialogConfig覆盖的默认黑名单，如'div[id="PhotoView_Slider"]' | Array<string> | 否 |  |
### Dialog.message 参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| type | 消息类型 | `info` \| `error` \| `success` \| `custom` | 否 | 'info' |
| content | 消息内容 | ReactNode | 否 |  |
| delay | 自定义消息消失时间, 以毫秒为单位（0: 代表不会自动消失） | number | 否 |  |
| destroy | 销毁方法 | () => void; | 否 |  |
| maxMessageCount | 最大可同时展示的消息数 | number | 否 | 3 |
| icon | type = 'custom' 时自定义icon | ReactNode | 否 |  |
### Dialog.confirm 参数说明如下：

| 参数 | 说明 | 类型 | 是否必填 | 默认值 |
| --- | --- | --- | --- | --- |
| okText | 确定按钮文字 | string \| ReactNode | 否 |  |
| okType | 确定按钮类型 | BtnType | 否 |  |
| hideOkBtn | 隐藏确定按钮 | boolean | 否 |  |
| cancelText | 取消按钮文字 | string \|ReactNode | 否 |  |
| cancelType | 取消按钮类型 | BtnType | 否 |  |
| hideCancelBtn | 隐藏确定按钮 | boolean | 否 |  |
| onCancel | 取消回调方法 | () => void | 否 |  |
| onOk | 确定回调方法 | () => void | 否 |  |
| title | 标题信息 | string | 否 |  |
| content | 内容 | ReactNode | 否 |  |
| getTitle | 自定义标题 | () => ReactNode | 否 |  |
| icon | 标题图标 | string | 否 |  |
| iconBgcolor | 标题图标颜色 | string | 否 |  |
| closeIcon | 自定义关闭按钮 | ReactNode | 否 |  |
| footer | 按钮组(底部) | ReactNode | 否 |  |
| getInstance | 获取弹框实例 | (instance: any) => void |  |  |
| top | 距离顶部高度 | number \| string |  |  |
| left | 距离左边高度 | number \| string |  |  |
| right | 距离右边高度 | number \| string |  |  |
| bottom | 距离底部高度 | number \| string |  |  |
| height | 设置弹窗高度 | number \| string |  |  |
| width | 设置弹窗宽度 | number \| string |  |  |
| wrapStyle | 外层容器自定义样式 | CSSProperties | 否 |  |
| zIndex |  | number | 否 |  |
| confirmWrapId | 确认框蒙包裹层id(主要用于处理全局点击白名单) | string | 否 |  |
| confirmMaskClassName | 确认框蒙层样式名 | string | 否 |  |
| enableHistoryListen | 启用路由监听关闭弹框方案 | boolean | 否 |  |
| enableKeyboardEvent | 是否开启键盘事件（键盘事件默认触发onOK回调） | boolean | 否 | true |
| customKeyboardEvent | 自定义键盘事件触发的回调 | () => void | 否 |  |
| draggable | 拖拽 | boolean | 否 |  |
### Dialog.createDialog 参数说明如下：

```
1.示例：(用于纯文本内容说明，不包含html格式)
Dialog.createDialog({
  title: 'Create Dialog'
})

2.ts说明：DialogProps代表Dialog组件的所有props配置，具体见上方参数说明
createDialog: (e: DialogProps) => { destroy: () => void };
```

### window.weaJs.showDialog 方法说明：用于带格式的内容或iframe方式展示内容的场景

window.weaJs.showDialog = (url: string, options: CreateIframeDialogProps) => { destroy: () => void }

```
1.示例一：带格式的内容，如处理文本换行
window.weaJs.showDialog('', { isIframe: false, content: '<div>文本一<br/>文本二</div>', style: { width: 500, height: 500 }})
2.示例二：iframe方式
window.weaJs.showDialog('http://www.baidu.com', {})
3.CreateIframeDialogProps说明
（1）CreateIframeDialogProps包含style、isIrame、content等其他Dialog组件支持的参数配置。
（2）style：仅支持配置width、height。
（3）content：支持纯文本以及带html标签的文本内容
（4）isIframe：弹框内容在content字段配置的场景，isIframe需配置成false
（5）其余Dialog组件支持的参数配置，如icon等，请参考上方参数说明。
```

### 一、noMaskClose 与 maskClosable 参数不可共同使用

### 二、getPopupContainer 与 maskClosable 参数不可共同使用

### 三、弹框显隐事件监听

```
使用方式：document.addEventListener(customDialogEventName, () => {})
使用方式：
  1. 添加监听事件：eventEmitter.addListener(uiAppName, Dialog.EVENT_VISIBLE_CHANGE, this.onVisibleChange)
  2. 卸载监听事件：eventEmitter.removeListener(uiAppName, Dialog.EVENT_VISIBLE_CHANGE, this.onVisibleChange)
  3. onVisibleChange示例方法：onVisibleChange = (customEventOptions: any) => {
    if (customEventOptions && customEventOptions.detail) {
      console.log(customEventOptions.detail.visible)
    }
  }
  4. 组件设置 enableEventEmitter=true
demo参考基础用法案例
```

#### ⚠️ Dialog.customDialogEventName 弹框显隐事件监听

已废弃，新用法请参考‘弹框显隐事件监听’

```
使用方式：  document.addEventListener('ui-confirm-visible-change', () => {})
demo参考提示信息案例
使用方式：document.addEventListener(customDialogEventName, () => {})
demo参考基础用法案例
```

### 四、特别注意（使用前须知）

#### 当 placement 为 middle 且没有设置 top 值的时候，弹窗水平垂直方向居中显示。默认宽度为当前屏幕宽度的 70%，最大宽度为当前屏幕宽度的 90%，最小宽度为 380。高度由内容撑起，最大高度为当前屏幕高度的 90%，最小高度为 200。

```
1、弹窗内部内容高度过高（需要垂直滚动），需要自行设置高度。
2、如果弹窗内部内容是异步获取，可以等待数据返回后再调用弹框，或者是设置弹窗固定高度避免造成抖动。
3、弹窗内部如果有多个tab，且每个tab的高度不一定时，建议设置弹窗固定高度避免造成抖动。
```

#### 当 placement 为 middle 且设置了 top 值的时候，弹窗垂直方向会距离顶部 top 高度，此时屏幕的最大高度为当前屏幕高度 - 2 * top，最小高度为 200。宽度规则和上述一致。

```
1、当dialog内容不确定（高度不确定），需要通过用户操作使弹窗向下撑开展示内容时，适用此场景。
```

#### confirm 在不设置 top、right、bottom 和 left 的时候，默认水平垂直居中
