Dialog 弹窗
如果项目中使用的是 0.x 版本的基础组件(@icedesign/base, @ali/ice, @alife/next),请在左侧导航顶部切换组件版本。
安装方法
- 在命令行中执行以下命令
npm install @alifd/next@latest -S
使用指南
对话框
何时使用
对话框是用于在不离开主路径的情况下,提供用户快速执行简单的操作、确认用户信息或反馈提示的辅助窗口。
API
Dialog
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
visible | 是否显示 | Boolean | false |
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() => void | Function | () => {} |
hasMask | 是否显示遮罩 | Boolean | true |
animation | 显示隐藏时动画的播放方式 | Object/Boolean | { in: 'fadeInDown', out: 'fadeOutUp', } |
autoFocus | 对话框弹出时是否自动获得焦点 | Boolean | false |
align | 对话框对齐方式, 具体见Overlay文档 | String/Boolean | 'cc cc' |
isFullScreen | 当对话框高度超过浏览器视口高度时,是否显示所有内容而不是出现滚动条以保证对话框完整显示在浏览器视口内,该属性仅在对话框垂直水平居中时生效,即 align 被设置为 'cc cc' 时 | Boolean | false |
shouldUpdatePosition | 是否在对话框重新渲染时及时更新对话框位置,一般用于对话框高度变化后依然能保证原来的对齐方式 | Boolean | false |
minMargin | 对话框距离浏览器顶部和底部的最小间距,align 被设置为 'cc cc' 并且 isFullScreen 被设置为 true 时不生效 | Number | 40 |
overlayProps | 透传到弹层组件的属性对象 | Object | {} |
height | 对话框的高度样式属性 | String | - |
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
title | 标题 | ReactNode | '' |
content | 内容 | ReactNode | '' |
onOk | 在点击确定按钮时触发的回调函数 | Function | () => {} |
onCancel | 在点击取消按钮时触发的回调函数 | Function | () => {} |
messageProps | 内嵌 Message 组件属性对象 | Object | {} |
Dialog.show
以下只列举 config 可以传入的常用属性,Dialog 组件其他属性也可以传入
属性 | 说明 | 类型 | 默认值 |
---|---|---|---|
title | 标题 | ReactNode | '' |
content | 内容 | ReactNode | '' |
onOk | 在点击确定按钮时触发的回调函数 | Function | () => {} |
onCancel | 在点击取消按钮时触发的回调函数 | Function | () => {} |
shouldUpdatePosition
,在内容更新后,会重新进行定位。-使用 isFullScreen
,启动 CSS 进行定位,无论对话框高度如何变化都能自适应居中,但是当内容过长时无法让操作按钮在可视区域内出现。## ARIA and Keyboard#键盘 | 说明 |
---|---|
esc | 按下ESC键将会关闭dialog而不触发任何的动作 |
tab | 正向聚焦到任何可以被聚焦的元素, 在Dialog显示的时候,焦点始终保持在框体内 |
shift+tab | 反向聚焦到任何可以被聚焦的元素,在Dialog显示的时候,焦点始终保持在框体内 |
代码示例
第一个对话框
查看源码在线预览
import { Button, Dialog } from '@alifd/next';
class Demo extends React.Component {
state = {
visible: false
};
onOpen = () => {
this.setState({
visible: true
});
};
onClose = reason => {
console.log(reason);
this.setState({
visible: false
});
};
render() {
return (
<div>
<Button onClick={this.onOpen} type="primary">
Open dialog
</Button>
<Dialog
title="Welcome to Alibaba.com"
visible={this.state.visible}
onOk={this.onClose.bind(this, 'okClick')}
onCancel={this.onClose.bind(this, 'cancelClick')}
onClose={this.onClose}>
Start your business here by searching a popular product
</Dialog>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
通过 footerActions 来调整确定按钮和取消按钮是否出现以及相互间的位置,通过 footerAlign 来调整底部按钮的对齐方式。
查看源码在线预览
import { Button, Radio, Dialog } from '@alifd/next';
class Demo extends React.Component {
state = {
visible: false,
footerActions: ['ok', 'cancel'],
footerAlign: 'right',
loading: false
};
onOpen = () => {
this.setState({
visible: true
});
}
onClose = () => {
this.setState({
visible: false
});
};
toggleFooterActions = footerActionsStr => {
this.setState({
footerActions: footerActionsStr.split(',')
});
};
toggleFooterAlign = footerAlign => {
this.setState({
footerAlign
});
};
toggleOkLoader = loading => {
this.setState({
loading
});
}
render() {
const { visible, footerActions, footerAlign, loading } = this.state;
const okProps = {
loading
};
return (
<div>
<Button onClick={this.onOpen} type="primary">
Open dialog
</Button>
<Dialog title="Customize buttons of footer"
visible={visible}
footerActions={footerActions}
footerAlign={footerAlign}
onOk={this.onClose}
onCancel={this.onClose}
onClose={this.onClose}
okProps={okProps}
>
<div className="demo-content">
<Radio.Group className="demo-radio-group" shape="button" value={footerActions.join(',')} onChange={this.toggleFooterActions}>
<Radio value="ok,cancel">ok is left</Radio>
<Radio value="cancel,ok">ok is right</Radio>
<Radio value="ok">only ok</Radio>
<Radio value="cancel">only cancel</Radio>
</Radio.Group>
<Radio.Group className="demo-radio-group" shape="button" value={footerAlign} onChange={this.toggleFooterAlign}>
<Radio value="left">left</Radio>
<Radio value="center">center</Radio>
<Radio value="right">right</Radio>
</Radio.Group>
<Radio.Group className="demo-radio-group" shape="button" value={loading} onChange={this.toggleOkLoader}>
<Radio value={false}>Loading Off</Radio>
<Radio value>Loading On</Radio>
</Radio.Group>
</div>
</Dialog>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
.demo-content {
padding: 10px;
border: 2px dashed #ddd;
background: #F8F8F8;
}
.demo-radio-group {
display: block;
}
.demo-radio-group + .demo-radio-group {
margin-top: 10px;
}
默认的 footer 为确定取消两个按钮,你可以自定义 footer 的内容。
查看源码在线预览
import { Button, Dialog } from '@alifd/next';
class Demo extends React.Component {
state = {
visible: false
};
onOpenFullyCustomized = () => {
this.setState({
fullyCustomizedVisible: true
});
};
onCloseFullyCustomized = () => {
this.setState({
fullyCustomizedVisible: false
});
};
onOpenTextCustomized = () => {
this.setState({
textCustomizedVisible: true
});
};
onCloseTextCustomized = () => {
this.setState({
textCustomizedVisible: false
});
};
render() {
return (
<div>
<Button onClick={this.onOpenFullyCustomized} type="primary">
Fully Customized Footer
</Button>
<Dialog
title="Welcome to Alibaba.com"
footer={<Button warning type="primary" onClick={this.onCloseFullyCustomized}>Customize footer</Button>}
visible={this.state.fullyCustomizedVisible}
onOk={this.onCloseFullyCustomized}
onCancel={this.onCloseFullyCustomized}
onClose={this.onCloseFullyCustomized}>
Start your business here by searching a popular product
</Dialog>
<Button onClick={this.onOpenTextCustomized} type="primary">
Text Only Customize
</Button>
<Dialog
title="Welcome to Alibaba.com"
visible={this.state.textCustomizedVisible}
onOk={this.onCloseTextCustomized}
onCancel={this.onCloseTextCustomized}
onClose={this.onCloseTextCustomized}
okProps={{children: 'Custom OK', className: 'asdf'}}
cancelProps={{children: 'Custom Cancel'}}
>
Start your business here by searching a popular product
</Dialog>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
通过设置 shouldUpdatePosition 为 true 来及时更新对话框的位置,一般用于对话框内容发生变化但是仍然要保证原来对齐方式的情况
查看源码在线预览
import { Switch, Button, Dialog } from '@alifd/next';
const shortContent = <p>Start your business here by searching a popular product</p>;
const longContent = [
<p key="0">Start your business here by searching a popular product</p>,
<p key="1">Start your business here by searching a popular product</p>,
<p key="2">Start your business here by searching a popular product</p>,
<p key="3">Start your business here by searching a popular product</p>
];
class App extends React.Component {
state = {
visible: false,
short: true,
shouldUpdatePosition: true
}
onOpen = () => {
this.setState({
visible: true,
short: true
});
};
onClose = () => {
this.setState({
visible: false
});
};
toggleShouldUpdatePosition = () => {
this.setState({
shouldUpdatePosition: !this.state.shouldUpdatePosition
});
};
modifyContent = () => {
this.setState({
short: !this.state.short
});
};
render() {
const { visible, short, shouldUpdatePosition } = this.state;
return (
<div>
<div style={{ display: 'block', marginBottom: '10px' }}>
Whether to update the dialog position when the dialog height changes:
</div>
<Switch style={{ display: 'block', marginBottom: '10px' }} checked={shouldUpdatePosition} onChange={this.toggleShouldUpdatePosition} />
<Button onClick={this.onOpen} type="primary">
Open dialog
</Button>
<Dialog title="Welcome to Alibaba.com"
visible={visible}
onOk={this.onClose.bind(this, 'okClick')}
onCancel={this.onClose.bind(this, 'cancelClick')}
onClose={this.onClose}
shouldUpdatePosition={shouldUpdatePosition}>
<Button type="primary" onClick={this.modifyContent}>
Change content
</Button>
{short ? shortContent : longContent}
</Dialog>
</div>
);
}
}
ReactDOM.render(<App/>, mountNode);
查看源码在线预览
import { Switch, Button, Dialog } from '@alifd/next';
const largeContent = new Array(30).fill(
<p>Start your business here by searching a popular product</p>
);
class Demo extends React.Component {
state = {
visible: false,
isFullScreen: false
};
onOpen = () => {
this.setState({
visible: true
});
};
onClose = () => {
this.setState({
visible: false
});
};
toggleIsFullScreen = () => {
this.setState({
isFullScreen: !this.state.isFullScreen
});
}
render() {
const { visible, isFullScreen } = this.state;
return (
<div>
<div style={{ display: 'block', marginBottom: '10px' }}>
When the height of the dialog exceeds the viewport height of the browser, whether to show the scroll bar:
</div>
<Switch style={{ display: 'block', marginBottom: '10px' }} checked={isFullScreen} onChange={this.toggleIsFullScreen} />
<Button onClick={this.onOpen} type="primary">
Open dialog
</Button>
<Dialog title="Welcome to Alibaba.com"
visible={visible}
isFullScreen={isFullScreen}
onOk={this.onClose}
onCancel={this.onClose}
onClose={this.onClose}>
{largeContent}
</Dialog>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
Dialog 提供 alert 和 confirm 的快掉调用方式,以及更底层的 show 方式。
查看源码在线预览
import { Button, Dialog, ConfigProvider } from '@alifd/next';
const popupAlert = () => {
Dialog.alert({
title: 'Alert',
content: 'alert content alert content...',
okProps: {children: 'Custom OK' },
onOk: () => console.log('ok')
});
};
const popupConfirm = () => {
Dialog.confirm({
title: 'Confirm',
content: 'confirm content confirm content...',
onOk: () => console.log('ok'),
onCancel: () => console.log('cancel')
});
};
const popupCustom = () => {
const dialog = Dialog.show({
title: 'Custom',
content: 'custom content custom content...',
footer: (
<Button warning type="primary" onClick={() => dialog.hide()}>
Custom button
</Button>
)
});
};
ReactDOM.render(
<ConfigProvider locale={{ Dialog: { ok: 'OK', cancel: 'Cancel' } }}>
<span>
<Button onClick={popupAlert}>Alert</Button>
<Button onClick={popupConfirm}>Confirm</Button>
<Button onClick={popupCustom}>Custom</Button>
</span>
</ConfigProvider>,
mountNode
);
在使用 Dialog.alert,Dialog.confirm 以及 Dialog.show 时,如果 onOk 返回 Promise,对话框会在 Promise resolve 时关闭,除非调用 resolve(false)
。
查看源码在线预览
import { Button, Message, Dialog } from '@alifd/next';
class Demo extends React.Component {
state = {
visible: false,
loading: false,
};
onOpen = () => {
this.setState({
visible: true
});
};
onOk = () => {
return new Promise(resolve => {
this.setState({
loading: true
});
setTimeout(resolve, 2000);
}).then(() => {
Message.success('Deleted successfully!');
this.setState({
loading: false,
visible: false
});
});
};
onClose = () => {
this.setState({
visible: false
});
};
render() {
const okProps = {
loading: this.state.loading
};
return (
<div>
<Button onClick={this.onOpen} type="primary">
Dialog Promise
</Button>
<Dialog
title="Welcome to Alibaba.com"
visible={this.state.visible}
okProps={okProps}
onOk={this.onOk}
onCancel={this.onClose}
onClose={this.onClose}>
Start your business here by searching a popular product
</Dialog>
</div>
);
}
}
const popupConfirm = () => {
Dialog.confirm({
title: 'Confirm',
content: 'Do you confirm deleting this content?',
onOk: () => {
return new Promise(resolve => {
setTimeout(resolve, 2000);
}).then(() => {
Message.success('Deleted successfully!');
});
}
});
};
ReactDOM.render(<div>
<Demo />
<Button type="primary" warning onClick={popupConfirm}>Quick Confirm Promise</Button>
</div>
, mountNode);
通过okProps
与cancelProps
设置aria-label
属性,屏幕阅读器读取确定和取消按钮。关于键盘操作请参考ARIA and KeyBoard
。
查看源码在线预览
import { Button, Dialog } from '@alifd/next';
class Demo extends React.Component {
state = {
visible: false
};
onOpen = () => {
this.setState({
visible: true
});
};
onClose = () => {
this.setState({
visible: false
});
};
render() {
return (
<div>
<Button onClick={this.onOpen} type="primary">
Open dialog
</Button>
<Dialog
title="Welcome to Alibaba.com"
visible={this.state.visible}
autoFocus
onOk={this.onClose.bind(this, 'okClick')}
onCancel={this.onClose.bind(this, 'cancelClick')}
onClose={this.onClose}
cancelProps={{'aria-label':'cancel'}}
okProps={{'aria-label':'ok'}}>
<p tabIndex="0"> Start your business here by searching a popular product</p>
</Dialog>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);
使用 'height' 道具设置 Dialog 高度风格。还将页尾底部的位置。
查看源码在线预览
import { Button, Dialog } from '@alifd/next';
class Demo extends React.Component {
state = {
visible: false,
};
onOpen = () => {
this.setState({
visible: true
});
}
onClose = () => {
this.setState({
visible: false
});
};
render() {
const { visible } = this.state;
return (
<div>
<Button onClick={this.onOpen} type="primary">
Open dialog
</Button>
<Dialog title="Fixed Height"
visible={visible}
height="400px"
onOk={this.onClose}
onCancel={this.onClose}
onClose={this.onClose}
>
Small Content in a fixed size Dialog
</Dialog>
</div>
);
}
}
ReactDOM.render(<Demo />, mountNode);