Add promise-like interface (#10470)

* Add promise-like interface

* Keep hide interface

* Shorten

* Test Promise

* Update document

* Update demo: 2.5 second is insignificant with the default 3s hiding

* Update demo: then  interface

* Fix line break

* Chainable

* Thenable demo

* Thenable test

* Fix tsc error

* Fix tsc error

* Better document

* Revert change in loading.md

* Change snapshot
This commit is contained in:
Jinxuan Zhu 2018-05-25 08:41:07 -04:00 committed by 偏右
parent f3869270ae
commit c2519e776b
6 changed files with 99 additions and 14 deletions

View File

@ -61,3 +61,14 @@ exports[`renders ./components/message/demo/other.md correctly 1`] = `
</button>
</div>
`;
exports[`renders ./components/message/demo/thenable.md correctly 1`] = `
<button
class="ant-btn"
type="button"
>
<span>
Display a sequence of message
</span>
</button>
`;

View File

@ -85,6 +85,17 @@ describe('message', () => {
});
});
it('should be called like promise', () => {
jest.useRealTimers();
const defaultDuration = 3;
const now = Date.now();
message.info('whatever').then(() => {
// calculate the approximately duration value
const aboutDuration = parseInt((Date.now() - now) / 1000, 10);
expect(aboutDuration).toBe(defaultDuration);
});
});
// https://github.com/ant-design/ant-design/issues/8201
it('should hide message correctly', () => {
let hide;

View File

@ -0,0 +1,28 @@
---
order: 5
title:
zh-CN: Promise 接口
en-US: Promise interface
---
## zh-CN
可以通过 then 接口在关闭后运行 callback 。以上用例将在每个 message 将要结束时通过 then 显示新的 message 。
## en-US
`message` provides promise interface for `onClose`. The above example will display a new message when old message is about to finish.
````jsx
import { message, Button } from 'antd';
const success = () => {
message.loading('Action in progress..', 2.5)
.then(() => message.success('Loading finished', 2.5))
.then(() => message.info('Loading finished is finished', 2.5));
};
ReactDOM.render(
<Button onClick={success}>Display a sequence of message</Button>
, mountNode);
````

View File

@ -34,6 +34,12 @@ Methods for global configuration and destruction are also provided:
- `message.config(options)`
- `message.destroy()`
`afterClose` can be called in then-able interface:
- `message[level](content, [duration]).then(afterClose)`
- `message[level](content, [duration], onClose).then(afterClose)`
where `level` refers one static methods of `message`. The result of `then` method will be a Promise.
### message.config
```js

View File

@ -1,3 +1,4 @@
/* global Promise */
import * as React from 'react';
import Notification from 'rc-notification';
import Icon from '../icon';
@ -34,12 +35,22 @@ function getMessageInstance(callback: (i: any) => void) {
type NoticeType = 'info' | 'success' | 'error' | 'warning' | 'loading';
export interface ThenableArgument {
(_: any): any;
}
export interface MessageType {
(): void;
then: (fill: ThenableArgument, reject: ThenableArgument) => Promise<any>;
promise: Promise<any>;
}
function notice(
content: React.ReactNode,
duration: (() => void) | number = defaultDuration,
type: NoticeType,
onClose?: () => void,
) {
): MessageType {
const iconType = ({
info: 'info-circle',
success: 'check-circle',
@ -54,25 +65,36 @@ function notice(
}
const target = key++;
getMessageInstance((instance) => {
instance.notice({
key: target,
duration,
style: {},
content: (
<div className={`${prefixCls}-custom-content ${prefixCls}-${type}`}>
<Icon type={iconType} />
<span>{content}</span>
</div>
),
onClose,
const closePromise = new Promise((resolve) => {
const callback = () => {
if (typeof onClose === 'function') {
onClose();
}
return resolve(true);
};
getMessageInstance((instance) => {
instance.notice({
key: target,
duration,
style: {},
content: (
<div className={`${prefixCls}-custom-content ${prefixCls}-${type}`}>
<Icon type={iconType} />
<span>{content}</span>
</div>
),
onClose: callback,
});
});
});
return () => {
const result: any = () => {
if (messageInstance) {
messageInstance.removeNotice(target);
}
};
result.then = (filled: ThenableArgument, rejected: ThenableArgument) => closePromise.then(filled, rejected);
result.promise = closePromise;
return result;
}
type ConfigContent = React.ReactNode | string;

View File

@ -35,6 +35,13 @@ title: Message
- `message.config(options)`
- `message.destroy()`
组件同时提供 promise 接口
- `message[level](content, [duration]).then(afterClose)`
- `message[level](content, [duration], onClose).then(afterClose)`
其中`message[level]` 是组件已经提供的静态方法。`then` 接口返回值是 Promise 。
### message.config
```js