Modal 模态框
模态框。
何时使用
需要用户处理事务,又不希望跳转页面以致打断工作流程时,可以使用 Modal
在当前页面正中打开一个浮层,承载相应的操作。
另外当需要一个简洁的确认框询问用户时,可以使用 Modal.confirm()
等语法糖方法。
请预先在项目页面根节点外包裹 ModalProvider,demo 中 APP 节点外包裹即可省略。
代码演示
基本使用
基本使用。
import React from 'react';
import ReactDOM from 'react-dom';
import { useModal, Button, ModalProvider } from 'choerodon-ui/pro';
const ModalContent = ({ modal }) => {
modal.handleOk(() => {
console.log('do OK');
return false;
});
modal.handleCancel(() => {
console.log('do Cancel');
modal.close();
});
const toggleOkDisabled = React.useCallback(() => {
modal.update({
okProps: { disabled: !modal.props.okProps.disabled },
okText: '保存',
});
}, []);
console.log('modal', modal);
return (
<div>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
<Button color="primary" onClick={modal.close}>
custom button for close modal
异步关闭
异步关闭。
import React from 'react';
import ReactDOM from 'react-dom';
import { useModal, Button, ModalProvider } from 'choerodon-ui/pro';
const App = () => {
const Modal = useModal();
const openModal = React.useCallback(() => {
Modal.open({
title: 'Synchronize',
children: (
<div>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</div>
),
onOk: () =>
new Promise((resolve) => {
setTimeout(() => {
resolve();
}, 1000);
}),
onCancel: () =>
new Promise((resolve, reject) => {
setTimeout(() => {
reject(new Error('error'));
}, 1000);
自定义页脚
自定义页脚。
import React from 'react';
import ReactDOM from 'react-dom';
import { useModal, Button, ModalProvider } from 'choerodon-ui/pro';
const App = () => {
const Modal = useModal();
const openModal = React.useCallback(() => {
const modal = Modal.open({
title: 'Custom Footer',
children: (
<div>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</div>
),
footer: <Button onClick={closeModal}>关闭</Button>,
});
function closeModal() {
modal.close();
}
}, [Modal]);
const openNoFooter = React.useCallback(() => {
Modal.open({
title: 'No Footer',
多层
多层。
import React from 'react';
import ReactDOM from 'react-dom';
import { useModal, Button, Modal, ModalProvider } from 'choerodon-ui/pro';
const { confirm } = Modal;
const App = () => {
const UseModal = useModal();
const openSubModal = React.useCallback(async () => {
return (await confirm('确认关闭?')) === 'ok';
}, [UseModal]);
const openModal = React.useCallback(() => {
UseModal.open({
title: 'Multilayer',
children: (
<div>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</div>
),
onClose: openSubModal,
});
}, [UseModal, openSubModal]);
return <Button onClick={openModal}>Open</Button>;
自定义坐标
自定义坐标。
import React from 'react';
import ReactDOM from 'react-dom';
import { useModal, Button, ModalProvider } from 'choerodon-ui/pro';
const App = () => {
const Modal = useModal();
const openModal = React.useCallback(() => {
Modal.open({
title: 'No Footer',
children: (
<div>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</div>
),
style: {
left: 100,
top: 200,
},
});
}, [Modal]);
return <Button onClick={openModal}>Open</Button>;
};
ReactDOM.render(
关闭按钮
关闭按钮。
import React from 'react';
import ReactDOM from 'react-dom';
import { useModal, Button, ModalProvider } from 'choerodon-ui/pro';
const App = () => {
const Modal = useModal();
const openModal = React.useCallback(() => {
Modal.open({
title: 'Close button',
children: (
<div>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</div>
),
closable: true,
});
}, [Modal]);
return <Button onClick={openModal}>Open</Button>;
};
ReactDOM.render(
<ModalProvider>
<App />
</ModalProvider>,
确认框
确认框。
import React from 'react';
import ReactDOM from 'react-dom';
import { Modal, Button, ModalProvider } from 'choerodon-ui/pro';
function doConfirm() {
Modal.confirm({
title: 'Confirm',
children: (
<div>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</div>
),
}).then((button) => {
Modal.info(`Click ${button}`);
});
}
function info() {
Modal.info({
title: 'This is title',
children: '您的订单已经提交!',
});
}
function success() {
Modal.success('订单提交成功!');
全屏显示
全屏显示。
import React from 'react';
import ReactDOM from 'react-dom';
import { useModal, Button, ModalProvider } from 'choerodon-ui/pro';
const App = () => {
const Modal = useModal();
const openModal = React.useCallback(() => {
Modal.open({
title: 'Full screen',
children: (
<div>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</div>
),
fullScreen: true,
});
}, [Modal]);
return <Button onClick={openModal}>Open</Button>;
};
ReactDOM.render(
<ModalProvider>
<App />
</ModalProvider>,
多层抽屉
通过设定多个 drawer 类型的弹出框形成多层抽屉,可指定弹出层宽度,弹出动画。
import React from 'react';
import ReactDOM from 'react-dom';
import { useModal, Button, ModalProvider } from 'choerodon-ui/pro';
const App = () => {
const Modal = useModal();
const openSubModal2 = React.useCallback(() => {
return new Promise((resolve) => {
Modal.open({
title: 'Sub Mode 2',
size: 'large',
drawer: true,
drawerTransitionName: 'slide-left',
children: (
<div>
<p>Open Sub Modal2...</p>
<p>Open Sub Modal2...</p>
</div>
),
onOk: resolve,
});
});
}, [Modal]);
const openSubModal1 = React.useCallback(() => {
return new Promise((resolve) => {
Modal.open({
更新渲染
更新渲染。
import React from 'react';
import ReactDOM from 'react-dom';
import { useModal, Button, ModalProvider } from 'choerodon-ui/pro';
const ModalContent = ({ modal }) => {
modal.handleOk(() => {
console.log('do OK');
return false;
});
modal.handleCancel(() => {
console.log('do Cancel');
modal.close();
});
const handleUpdate = React.useCallback(() => {
modal.update({
title: 'update',
children: (
<div>
<p>update contents...</p>
</div>
),
okText: '保存',
cancelText: '退出',
onOk: () => modal.close(),
});
}, [modal]);
return (
destroyAll
destroyAll 销毁所有弹出的Modal框。
import React from 'react';
import ReactDOM from 'react-dom';
import { Modal, Button, ModalProvider } from 'choerodon-ui/pro';
function destroyAll() {
Modal.destroyAll();
}
function destroyConfirm() {
for (let i = 0; i < 4; i++) {
setTimeout(() => {
Modal.confirm({
title: 'Confirm',
children: <Button onClick={destroyAll}>Click to destroy all</Button>,
});
}, i * 600);
}
}
ReactDOM.render(
<Button onClick={destroyConfirm}>Open</Button>,
document.getElementById('container'),
);
自定义遮罩样式
自定义遮罩样式
import React from 'react';
import ReactDOM from 'react-dom';
import { useModal, Button, ModalProvider } from 'choerodon-ui/pro';
const maskStyle = {
backgroundColor: 'rgb(0, 193, 255,.3)',
};
const App = () => {
const Modal = useModal();
const openModal = React.useCallback(
(mask = true) => {
Modal.open({
title: 'Customized mask',
children: (
<div>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</div>
),
okText: '确定',
maskStyle,
mask,
maskClassName: 'mask-class-name',
});
},
API
Modal
参数 | 说明 | 类型 | 默认值 |
---|---|---|---|
key | 唯一键, 当 destroyOnClose 为 false 时,必须指定 key。为了避免与其他 modal 的 key 重复,可通过 Modal.key()来获取唯一 key。 | string | |
title | 标题 | ReactNode | |
closable | 显示右上角关闭按钮 | boolean | false |
movable | 可移动, drawer 无法移动 | boolean | true |
fullScreen | 全屏显示 | boolean | false |
maskClosable | 点击蒙层是否允许关闭 | boolean | false |
mask | 是否显示蒙层 | boolean | true |
maskStyle | 蒙层样式 | CSSProperties | |
maskClassName | 蒙层自定义样式名 | string | |
keyboardClosable | 按 esc 键是否允许关闭 | boolean | true |
destroyOnClose | 关闭时是否销毁 | boolean | true |
footer | 底部内容 | ReactNode 或 (okBtn, cancelBtn) => ReactNode | |
okText | 确认按钮文字 | ReactNode | 确定 |
cancelText | 取消按钮文字 | ReactNode | 取消 |
onClose | 关闭时回调,返回false Promise.resolve(false) 或Promise.reject() 不会关闭, 其他自动关闭 | () => Promise<boolean> | |
onOk | 点击确定回调,返回false Promise.resolve(false) 或Promise.reject() 不会关闭, 其他自动关闭 | () => Promise<boolean> | |
onCancel | 点击取消回调,返回false Promise.resolve(false) 或Promise.reject() 不会关闭, 其他自动关闭 | () => Promise<boolean> | |
afterClose | 关闭后回调 | () => void | |
drawer | 抽屉模式 | boolean | false |
drawerTransitionName | 抽屉模式使用的动画 | string | ‘slide-right’ |
okCancel | 同时显示 ok 和 cancel 按钮,false 的时候只显示 ok 按钮 | boolean | true |
okFirst | ok 按钮是否排在第一个 | boolean | true |
okProps | ok 按钮属性 | object | |
cancelProps | cancel 按钮属性 | object |
ModalProvider > v0.8.50
- 使用 Modal 前,需要在页面根节点外包裹 ModalProvider。如果路由切换时要清空所有 Modal,需要在 ModalProvider 传入 location,如下所示。
- 如果 Modal 要获取 React Context,请在对应的 Context.Provider 子节点外包裹 ModalProvider,并使用 ModalProvider 提供的 injectModal 或 useModal 来代替 Modal.open。
import { ModalProvider } from 'choerodon-ui/pro';
import { withRouter } from 'react-router';
@withRouter
class App extends React.Component {
render() {
const { location } = this.props;
return (
<ModalProvider location={location}>
<Main />
</ModalProvider>
);
}
}
render(<App />, mountNode);
ModalContent <= v0.8.50
- 使用 Modal 前,需要在页面 Root 内插入 ModalContainer。如果路由切换时要清空所有 Modal,需要在 ModalContiner 传入 location,如下所示。
- 如果 Modal 要获取 React Context,请将 ModalContainer 至于 Context.Provider 之下。
- 为了避免多个 ModalContainer 之间 Context 错乱, ModalContainer 务必作为第一个子元素使用。
import { ModalContainer } from 'choerodon-ui/pro';
import { withRouter } from 'react-router';
@withRouter
class App extends React.Component {
render() {
const { location } = this.props;
return (
<div>
<ModalContainer location={location} />
<Main />
</div>
);
}
}
render(<App />, mountNode);
Modal.open
Modal.open()返回一个对象,该对象具有如下方法:
名称 | 说明 | 参数 |
---|---|---|
close(destroy) | 关闭 | destroy - 是否销毁 |
open() | 打开 | |
update(props) | 更新 |
props.modal
Modal 会向内部组件注入 modal 对象,该对象具有如下属性与方法:
名称 | 说明 | 参数 |
---|---|---|
handleOk(callback) | 注册响应 ok 按钮的钩子,返回值为 false 将阻止关闭 | callback - 钩子 |
handleCancel(callback) | 注册响应 cancel 按钮的钩子,返回值为 false 将阻止关闭 | callback - 钩子 |
close(destroy) | 关闭 | destroy - 是否销毁 |
update(props) | 更新 | |
props | modal 的 props |
当前内容版权归 Choerodon UI 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 Choerodon UI .