Dialog 弹窗

如果项目中使用的是 0.x 版本的基础组件(@icedesign/base, @ali/ice, @alife/next),请在左侧导航顶部切换组件版本。

安装方法

  1. 在命令行中执行以下命令npm install @alifd/next@latest -S

使用指南

对话框

何时使用

对话框是用于在不离开主路径的情况下,提供用户快速执行简单的操作、确认用户信息或反馈提示的辅助窗口。

API

Dialog

参数说明类型默认值
visible是否显示Booleanfalse
title标题ReactNode-
children内容ReactNode-
footer底部内容,设置为 false,则不进行显示Boolean/ReactNode<
footerAlign底部按钮的对齐方式可选值:'left', 'center', 'right'Enum'right'
footerActions指定确定按钮和取消按钮是否存在以及如何排列,可选值'ok', 'cancel'(确认取消按钮同时存在,确认按钮在左)'cancel', 'ok'(确认取消按钮同时存在,确认按钮在右)'ok'(只存在确认按钮)'cancel'(只存在取消按钮)Array'ok', 'cancel'
onOk在点击确定按钮时触发的回调函数签名:Function(event: Object) => void参数:event: {Object} 点击事件对象Function() => {}
onCancel在点击取消按钮时触发的回调函数签名:Function(event: Object) => void参数:event: {Object} 点击事件对象Function() => {}
okProps应用于确定按钮的属性对象Object{}
cancelProps应用于取消按钮的属性对象Object{}
closeable控制对话框关闭的方式,值可以为字符串或者布尔值,其中字符串是由以下值组成:close 表示点击关闭按钮可以关闭对话框mask 表示点击遮罩区域可以关闭对话框esc 表示按下 esc 键可以关闭对话框如 'close' 或 'close,esc,mask'如果设置为 true,则以上关闭方式全部生效如果设置为 false,则以上关闭方式全部失效String/Boolean'esc,close'
onClose对话框关闭时触发的回调函数签名:Function(trigger: String, event: Object) => void参数:trigger: {String} 关闭触发行为的描述字符串event: {Object} 关闭时事件对象Function() => {}
afterClose对话框关闭后触发的回调函数, 如果有动画,则在动画结束后触发签名:Function() => voidFunction() => {}
hasMask是否显示遮罩Booleantrue
animation显示隐藏时动画的播放方式Object/Boolean{ in: 'fadeInDown', out: 'fadeOutUp', }
autoFocus对话框弹出时是否自动获得焦点Booleanfalse
align对话框对齐方式, 具体见Overlay文档String/Boolean'cc cc'
isFullScreen当对话框高度超过浏览器视口高度时,是否显示所有内容而不是出现滚动条以保证对话框完整显示在浏览器视口内,该属性仅在对话框垂直水平居中时生效,即 align 被设置为 'cc cc' 时Booleanfalse
shouldUpdatePosition是否在对话框重新渲染时及时更新对话框位置,一般用于对话框高度变化后依然能保证原来的对齐方式Booleanfalse
minMargin对话框距离浏览器顶部和底部的最小间距,align 被设置为 'cc cc' 并且 isFullScreen 被设置为 true 时不生效Number40
overlayProps透传到弹层组件的属性对象Object{}
height对话框的高度样式属性String-
<!— api-extra-start —>### Dialog.alert(config)/Dialog.confirm(config)#以下只列举 config 可以传入的常用属性,Dialog 组件的其他属性也可以传入
属性说明类型默认值
title标题ReactNode''
content内容ReactNode''
onOk在点击确定按钮时触发的回调函数Function() => {}
onCancel在点击取消按钮时触发的回调函数Function() => {}
messageProps内嵌 Message 组件属性对象Object{}

Dialog.show

以下只列举 config 可以传入的常用属性,Dialog 组件其他属性也可以传入

属性说明类型默认值
title标题ReactNode''
content内容ReactNode''
onOk在点击确定按钮时触发的回调函数Function() => {}
onCancel在点击取消按钮时触发的回调函数Function() => {}
<!— api-extra-end —>## 常见问题#### 对话框高度变化,保持居中#Dialog 组件默认使用 JS 进行定位,当内容过长时使用 JS 自动调整对话框高度,以使得操作按钮在可视区域内出现,但是这会造成在对话框高度发生变化时无法感知重新使用 JS 定位,有下面两种解决方案:-设置 shouldUpdatePosition,在内容更新后,会重新进行定位。-使用 isFullScreen,启动 CSS 进行定位,无论对话框高度如何变化都能自适应居中,但是当内容过长时无法让操作按钮在可视区域内出现。## ARIA and Keyboard#
键盘说明
esc按下ESC键将会关闭dialog而不触发任何的动作
tab正向聚焦到任何可以被聚焦的元素, 在Dialog显示的时候,焦点始终保持在框体内
shift+tab反向聚焦到任何可以被聚焦的元素,在Dialog显示的时候,焦点始终保持在框体内

代码示例

基本

第一个对话框

Dialog 弹窗 - 图1

查看源码在线预览

  1. import { Button, Dialog } from '@alifd/next';
  2. class Demo extends React.Component {
  3. state = {
  4. visible: false
  5. };
  6. onOpen = () => {
  7. this.setState({
  8. visible: true
  9. });
  10. };
  11. onClose = reason => {
  12. console.log(reason);
  13. this.setState({
  14. visible: false
  15. });
  16. };
  17. render() {
  18. return (
  19. <div>
  20. <Button onClick={this.onOpen} type="primary">
  21. Open dialog
  22. </Button>
  23. <Dialog
  24. title="Welcome to Alibaba.com"
  25. visible={this.state.visible}
  26. onOk={this.onClose.bind(this, 'okClick')}
  27. onCancel={this.onClose.bind(this, 'cancelClick')}
  28. onClose={this.onClose}>
  29. Start your business here by searching a popular product
  30. </Dialog>
  31. </div>
  32. );
  33. }
  34. }
  35. ReactDOM.render(<Demo />, mountNode);

定制底部按钮

通过 footerActions 来调整确定按钮和取消按钮是否出现以及相互间的位置,通过 footerAlign 来调整底部按钮的对齐方式。

Dialog 弹窗 - 图2

查看源码在线预览

  1. import { Button, Radio, Dialog } from '@alifd/next';
  2. class Demo extends React.Component {
  3. state = {
  4. visible: false,
  5. footerActions: ['ok', 'cancel'],
  6. footerAlign: 'right',
  7. loading: false
  8. };
  9. onOpen = () => {
  10. this.setState({
  11. visible: true
  12. });
  13. }
  14. onClose = () => {
  15. this.setState({
  16. visible: false
  17. });
  18. };
  19. toggleFooterActions = footerActionsStr => {
  20. this.setState({
  21. footerActions: footerActionsStr.split(',')
  22. });
  23. };
  24. toggleFooterAlign = footerAlign => {
  25. this.setState({
  26. footerAlign
  27. });
  28. };
  29. toggleOkLoader = loading => {
  30. this.setState({
  31. loading
  32. });
  33. }
  34. render() {
  35. const { visible, footerActions, footerAlign, loading } = this.state;
  36. const okProps = {
  37. loading
  38. };
  39. return (
  40. <div>
  41. <Button onClick={this.onOpen} type="primary">
  42. Open dialog
  43. </Button>
  44. <Dialog title="Customize buttons of footer"
  45. visible={visible}
  46. footerActions={footerActions}
  47. footerAlign={footerAlign}
  48. onOk={this.onClose}
  49. onCancel={this.onClose}
  50. onClose={this.onClose}
  51. okProps={okProps}
  52. >
  53. <div className="demo-content">
  54. <Radio.Group className="demo-radio-group" shape="button" value={footerActions.join(',')} onChange={this.toggleFooterActions}>
  55. <Radio value="ok,cancel">ok is left</Radio>
  56. <Radio value="cancel,ok">ok is right</Radio>
  57. <Radio value="ok">only ok</Radio>
  58. <Radio value="cancel">only cancel</Radio>
  59. </Radio.Group>
  60. <Radio.Group className="demo-radio-group" shape="button" value={footerAlign} onChange={this.toggleFooterAlign}>
  61. <Radio value="left">left</Radio>
  62. <Radio value="center">center</Radio>
  63. <Radio value="right">right</Radio>
  64. </Radio.Group>
  65. <Radio.Group className="demo-radio-group" shape="button" value={loading} onChange={this.toggleOkLoader}>
  66. <Radio value={false}>Loading Off</Radio>
  67. <Radio value>Loading On</Radio>
  68. </Radio.Group>
  69. </div>
  70. </Dialog>
  71. </div>
  72. );
  73. }
  74. }
  75. ReactDOM.render(<Demo />, mountNode);
  1. .demo-content {
  2. padding: 10px;
  3. border: 2px dashed #ddd;
  4. background: #F8F8F8;
  5. }
  6. .demo-radio-group {
  7. display: block;
  8. }
  9. .demo-radio-group + .demo-radio-group {
  10. margin-top: 10px;
  11. }

自定义底部

默认的 footer 为确定取消两个按钮,你可以自定义 footer 的内容。

Dialog 弹窗 - 图3

查看源码在线预览

  1. import { Button, Dialog } from '@alifd/next';
  2. class Demo extends React.Component {
  3. state = {
  4. visible: false
  5. };
  6. onOpenFullyCustomized = () => {
  7. this.setState({
  8. fullyCustomizedVisible: true
  9. });
  10. };
  11. onCloseFullyCustomized = () => {
  12. this.setState({
  13. fullyCustomizedVisible: false
  14. });
  15. };
  16. onOpenTextCustomized = () => {
  17. this.setState({
  18. textCustomizedVisible: true
  19. });
  20. };
  21. onCloseTextCustomized = () => {
  22. this.setState({
  23. textCustomizedVisible: false
  24. });
  25. };
  26. render() {
  27. return (
  28. <div>
  29. <Button onClick={this.onOpenFullyCustomized} type="primary">
  30. Fully Customized Footer
  31. </Button> &nbsp;
  32. <Dialog
  33. title="Welcome to Alibaba.com"
  34. footer={<Button warning type="primary" onClick={this.onCloseFullyCustomized}>Customize footer</Button>}
  35. visible={this.state.fullyCustomizedVisible}
  36. onOk={this.onCloseFullyCustomized}
  37. onCancel={this.onCloseFullyCustomized}
  38. onClose={this.onCloseFullyCustomized}>
  39. Start your business here by searching a popular product
  40. </Dialog>
  41. <Button onClick={this.onOpenTextCustomized} type="primary">
  42. Text Only Customize
  43. </Button>
  44. <Dialog
  45. title="Welcome to Alibaba.com"
  46. visible={this.state.textCustomizedVisible}
  47. onOk={this.onCloseTextCustomized}
  48. onCancel={this.onCloseTextCustomized}
  49. onClose={this.onCloseTextCustomized}
  50. okProps={{children: 'Custom OK', className: 'asdf'}}
  51. cancelProps={{children: 'Custom Cancel'}}
  52. >
  53. Start your business here by searching a popular product
  54. </Dialog>
  55. </div>
  56. );
  57. }
  58. }
  59. ReactDOM.render(<Demo />, mountNode);

更新位置

通过设置 shouldUpdatePosition 为 true 来及时更新对话框的位置,一般用于对话框内容发生变化但是仍然要保证原来对齐方式的情况

Dialog 弹窗 - 图4

查看源码在线预览

  1. import { Switch, Button, Dialog } from '@alifd/next';
  2. const shortContent = <p>Start your business here by searching a popular product</p>;
  3. const longContent = [
  4. <p key="0">Start your business here by searching a popular product</p>,
  5. <p key="1">Start your business here by searching a popular product</p>,
  6. <p key="2">Start your business here by searching a popular product</p>,
  7. <p key="3">Start your business here by searching a popular product</p>
  8. ];
  9. class App extends React.Component {
  10. state = {
  11. visible: false,
  12. short: true,
  13. shouldUpdatePosition: true
  14. }
  15. onOpen = () => {
  16. this.setState({
  17. visible: true,
  18. short: true
  19. });
  20. };
  21. onClose = () => {
  22. this.setState({
  23. visible: false
  24. });
  25. };
  26. toggleShouldUpdatePosition = () => {
  27. this.setState({
  28. shouldUpdatePosition: !this.state.shouldUpdatePosition
  29. });
  30. };
  31. modifyContent = () => {
  32. this.setState({
  33. short: !this.state.short
  34. });
  35. };
  36. render() {
  37. const { visible, short, shouldUpdatePosition } = this.state;
  38. return (
  39. <div>
  40. <div style={{ display: 'block', marginBottom: '10px' }}>
  41. Whether to update the dialog position when the dialog height changes:
  42. </div>
  43. <Switch style={{ display: 'block', marginBottom: '10px' }} checked={shouldUpdatePosition} onChange={this.toggleShouldUpdatePosition} />
  44. <Button onClick={this.onOpen} type="primary">
  45. Open dialog
  46. </Button>
  47. <Dialog title="Welcome to Alibaba.com"
  48. visible={visible}
  49. onOk={this.onClose.bind(this, 'okClick')}
  50. onCancel={this.onClose.bind(this, 'cancelClick')}
  51. onClose={this.onClose}
  52. shouldUpdatePosition={shouldUpdatePosition}>
  53. <Button type="primary" onClick={this.modifyContent}>
  54. Change content
  55. </Button>
  56. {short ? shortContent : longContent}
  57. </Dialog>
  58. </div>
  59. );
  60. }
  61. }
  62. ReactDOM.render(<App/>, mountNode);

内容较多的对话框

Dialog 弹窗 - 图5

查看源码在线预览

  1. import { Switch, Button, Dialog } from '@alifd/next';
  2. const largeContent = new Array(30).fill(
  3. <p>Start your business here by searching a popular product</p>
  4. );
  5. class Demo extends React.Component {
  6. state = {
  7. visible: false,
  8. isFullScreen: false
  9. };
  10. onOpen = () => {
  11. this.setState({
  12. visible: true
  13. });
  14. };
  15. onClose = () => {
  16. this.setState({
  17. visible: false
  18. });
  19. };
  20. toggleIsFullScreen = () => {
  21. this.setState({
  22. isFullScreen: !this.state.isFullScreen
  23. });
  24. }
  25. render() {
  26. const { visible, isFullScreen } = this.state;
  27. return (
  28. <div>
  29. <div style={{ display: 'block', marginBottom: '10px' }}>
  30. When the height of the dialog exceeds the viewport height of the browser, whether to show the scroll bar:
  31. </div>
  32. <Switch style={{ display: 'block', marginBottom: '10px' }} checked={isFullScreen} onChange={this.toggleIsFullScreen} />
  33. <Button onClick={this.onOpen} type="primary">
  34. Open dialog
  35. </Button>
  36. <Dialog title="Welcome to Alibaba.com"
  37. visible={visible}
  38. isFullScreen={isFullScreen}
  39. onOk={this.onClose}
  40. onCancel={this.onClose}
  41. onClose={this.onClose}>
  42. {largeContent}
  43. </Dialog>
  44. </div>
  45. );
  46. }
  47. }
  48. ReactDOM.render(<Demo />, mountNode);

快捷调用

Dialog 提供 alert 和 confirm 的快掉调用方式,以及更底层的 show 方式。

Dialog 弹窗 - 图6

查看源码在线预览

  1. import { Button, Dialog, ConfigProvider } from '@alifd/next';
  2. const popupAlert = () => {
  3. Dialog.alert({
  4. title: 'Alert',
  5. content: 'alert content alert content...',
  6. okProps: {children: 'Custom OK' },
  7. onOk: () => console.log('ok')
  8. });
  9. };
  10. const popupConfirm = () => {
  11. Dialog.confirm({
  12. title: 'Confirm',
  13. content: 'confirm content confirm content...',
  14. onOk: () => console.log('ok'),
  15. onCancel: () => console.log('cancel')
  16. });
  17. };
  18. const popupCustom = () => {
  19. const dialog = Dialog.show({
  20. title: 'Custom',
  21. content: 'custom content custom content...',
  22. footer: (
  23. <Button warning type="primary" onClick={() => dialog.hide()}>
  24. Custom button
  25. </Button>
  26. )
  27. });
  28. };
  29. ReactDOM.render(
  30. <ConfigProvider locale={{ Dialog: { ok: 'OK', cancel: 'Cancel' } }}>
  31. <span>
  32. <Button onClick={popupAlert}>Alert</Button> &nbsp;
  33. <Button onClick={popupConfirm}>Confirm</Button> &nbsp;
  34. <Button onClick={popupCustom}>Custom</Button>
  35. </span>
  36. </ConfigProvider>,
  37. mountNode
  38. );

延迟关闭

在使用 Dialog.alert,Dialog.confirm 以及 Dialog.show 时,如果 onOk 返回 Promise,对话框会在 Promise resolve 时关闭,除非调用 resolve(false)

Dialog 弹窗 - 图7

查看源码在线预览

  1. import { Button, Message, Dialog } from '@alifd/next';
  2. class Demo extends React.Component {
  3. state = {
  4. visible: false,
  5. loading: false,
  6. };
  7. onOpen = () => {
  8. this.setState({
  9. visible: true
  10. });
  11. };
  12. onOk = () => {
  13. return new Promise(resolve => {
  14. this.setState({
  15. loading: true
  16. });
  17. setTimeout(resolve, 2000);
  18. }).then(() => {
  19. Message.success('Deleted successfully!');
  20. this.setState({
  21. loading: false,
  22. visible: false
  23. });
  24. });
  25. };
  26. onClose = () => {
  27. this.setState({
  28. visible: false
  29. });
  30. };
  31. render() {
  32. const okProps = {
  33. loading: this.state.loading
  34. };
  35. return (
  36. <div>
  37. <Button onClick={this.onOpen} type="primary">
  38. Dialog Promise
  39. </Button>
  40. <Dialog
  41. title="Welcome to Alibaba.com"
  42. visible={this.state.visible}
  43. okProps={okProps}
  44. onOk={this.onOk}
  45. onCancel={this.onClose}
  46. onClose={this.onClose}>
  47. Start your business here by searching a popular product
  48. </Dialog>
  49. </div>
  50. );
  51. }
  52. }
  53. const popupConfirm = () => {
  54. Dialog.confirm({
  55. title: 'Confirm',
  56. content: 'Do you confirm deleting this content?',
  57. onOk: () => {
  58. return new Promise(resolve => {
  59. setTimeout(resolve, 2000);
  60. }).then(() => {
  61. Message.success('Deleted successfully!');
  62. });
  63. }
  64. });
  65. };
  66. ReactDOM.render(<div>
  67. <Demo />
  68. <Button type="primary" warning onClick={popupConfirm}>Quick Confirm Promise</Button>
  69. </div>
  70. , mountNode);

无障碍

通过okPropscancelProps设置aria-label属性,屏幕阅读器读取确定和取消按钮。关于键盘操作请参考ARIA and KeyBoard

Dialog 弹窗 - 图8

查看源码在线预览

  1. import { Button, Dialog } from '@alifd/next';
  2. class Demo extends React.Component {
  3. state = {
  4. visible: false
  5. };
  6. onOpen = () => {
  7. this.setState({
  8. visible: true
  9. });
  10. };
  11. onClose = () => {
  12. this.setState({
  13. visible: false
  14. });
  15. };
  16. render() {
  17. return (
  18. <div>
  19. <Button onClick={this.onOpen} type="primary">
  20. Open dialog
  21. </Button>
  22. <Dialog
  23. title="Welcome to Alibaba.com"
  24. visible={this.state.visible}
  25. autoFocus
  26. onOk={this.onClose.bind(this, 'okClick')}
  27. onCancel={this.onClose.bind(this, 'cancelClick')}
  28. onClose={this.onClose}
  29. cancelProps={{'aria-label':'cancel'}}
  30. okProps={{'aria-label':'ok'}}>
  31. <p tabIndex="0"> Start your business here by searching a popular product</p>
  32. </Dialog>
  33. </div>
  34. );
  35. }
  36. }
  37. ReactDOM.render(<Demo />, mountNode);

定制底部按钮

使用 'height' 道具设置 Dialog 高度风格。还将页尾底部的位置。

Dialog 弹窗 - 图9

查看源码在线预览

  1. import { Button, Dialog } from '@alifd/next';
  2. class Demo extends React.Component {
  3. state = {
  4. visible: false,
  5. };
  6. onOpen = () => {
  7. this.setState({
  8. visible: true
  9. });
  10. }
  11. onClose = () => {
  12. this.setState({
  13. visible: false
  14. });
  15. };
  16. render() {
  17. const { visible } = this.state;
  18. return (
  19. <div>
  20. <Button onClick={this.onOpen} type="primary">
  21. Open dialog
  22. </Button>
  23. <Dialog title="Fixed Height"
  24. visible={visible}
  25. height="400px"
  26. onOk={this.onClose}
  27. onCancel={this.onClose}
  28. onClose={this.onClose}
  29. >
  30. Small Content in a fixed size Dialog
  31. </Dialog>
  32. </div>
  33. );
  34. }
  35. }
  36. ReactDOM.render(<Demo />, mountNode);

相关区块

Dialog 弹窗 - 图10

暂无相关区块