mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 17:44:35 +08:00
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:
parent
f3869270ae
commit
c2519e776b
@ -61,3 +61,14 @@ exports[`renders ./components/message/demo/other.md correctly 1`] = `
|
|||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
exports[`renders ./components/message/demo/thenable.md correctly 1`] = `
|
||||||
|
<button
|
||||||
|
class="ant-btn"
|
||||||
|
type="button"
|
||||||
|
>
|
||||||
|
<span>
|
||||||
|
Display a sequence of message
|
||||||
|
</span>
|
||||||
|
</button>
|
||||||
|
`;
|
||||||
|
@ -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
|
// https://github.com/ant-design/ant-design/issues/8201
|
||||||
it('should hide message correctly', () => {
|
it('should hide message correctly', () => {
|
||||||
let hide;
|
let hide;
|
||||||
|
28
components/message/demo/thenable.md
Normal file
28
components/message/demo/thenable.md
Normal 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);
|
||||||
|
````
|
||||||
|
|
@ -34,6 +34,12 @@ Methods for global configuration and destruction are also provided:
|
|||||||
- `message.config(options)`
|
- `message.config(options)`
|
||||||
- `message.destroy()`
|
- `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
|
### message.config
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
/* global Promise */
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import Notification from 'rc-notification';
|
import Notification from 'rc-notification';
|
||||||
import Icon from '../icon';
|
import Icon from '../icon';
|
||||||
@ -34,12 +35,22 @@ function getMessageInstance(callback: (i: any) => void) {
|
|||||||
|
|
||||||
type NoticeType = 'info' | 'success' | 'error' | 'warning' | 'loading';
|
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(
|
function notice(
|
||||||
content: React.ReactNode,
|
content: React.ReactNode,
|
||||||
duration: (() => void) | number = defaultDuration,
|
duration: (() => void) | number = defaultDuration,
|
||||||
type: NoticeType,
|
type: NoticeType,
|
||||||
onClose?: () => void,
|
onClose?: () => void,
|
||||||
) {
|
): MessageType {
|
||||||
const iconType = ({
|
const iconType = ({
|
||||||
info: 'info-circle',
|
info: 'info-circle',
|
||||||
success: 'check-circle',
|
success: 'check-circle',
|
||||||
@ -54,25 +65,36 @@ function notice(
|
|||||||
}
|
}
|
||||||
|
|
||||||
const target = key++;
|
const target = key++;
|
||||||
getMessageInstance((instance) => {
|
const closePromise = new Promise((resolve) => {
|
||||||
instance.notice({
|
const callback = () => {
|
||||||
key: target,
|
if (typeof onClose === 'function') {
|
||||||
duration,
|
onClose();
|
||||||
style: {},
|
}
|
||||||
content: (
|
return resolve(true);
|
||||||
<div className={`${prefixCls}-custom-content ${prefixCls}-${type}`}>
|
};
|
||||||
<Icon type={iconType} />
|
getMessageInstance((instance) => {
|
||||||
<span>{content}</span>
|
instance.notice({
|
||||||
</div>
|
key: target,
|
||||||
),
|
duration,
|
||||||
onClose,
|
style: {},
|
||||||
|
content: (
|
||||||
|
<div className={`${prefixCls}-custom-content ${prefixCls}-${type}`}>
|
||||||
|
<Icon type={iconType} />
|
||||||
|
<span>{content}</span>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
onClose: callback,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
return () => {
|
const result: any = () => {
|
||||||
if (messageInstance) {
|
if (messageInstance) {
|
||||||
messageInstance.removeNotice(target);
|
messageInstance.removeNotice(target);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
result.then = (filled: ThenableArgument, rejected: ThenableArgument) => closePromise.then(filled, rejected);
|
||||||
|
result.promise = closePromise;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConfigContent = React.ReactNode | string;
|
type ConfigContent = React.ReactNode | string;
|
||||||
|
@ -35,6 +35,13 @@ title: Message
|
|||||||
- `message.config(options)`
|
- `message.config(options)`
|
||||||
- `message.destroy()`
|
- `message.destroy()`
|
||||||
|
|
||||||
|
组件同时提供 promise 接口
|
||||||
|
|
||||||
|
- `message[level](content, [duration]).then(afterClose)`
|
||||||
|
- `message[level](content, [duration], onClose).then(afterClose)`
|
||||||
|
|
||||||
|
其中`message[level]` 是组件已经提供的静态方法。`then` 接口返回值是 Promise 。
|
||||||
|
|
||||||
### message.config
|
### message.config
|
||||||
|
|
||||||
```js
|
```js
|
||||||
|
Loading…
Reference in New Issue
Block a user