add message

pull/165/head
tangjinzhou 2018-02-06 16:43:59 +08:00
parent 13882af397
commit df29c56d71
15 changed files with 439 additions and 4 deletions

View File

@ -61,8 +61,10 @@ const CollapsePanel = Collapse.Panel
export { Collapse, CollapsePanel }
import notification from './notification'
import message from './message'
const api = {
notification,
message,
}
export { api }

View File

@ -0,0 +1,26 @@
<cn>
#### 修改延时
自定义时长 `10s`,默认时长为 `3s`
</cn>
<us>
#### Customize duration
Customize message display duration from default `3s` to `10s`.
</us>
```html
<template>
<a-button @click="success">Customized display duration</a-button>
</template>
<script>
export default {
methods: {
success () {
this.$message.success('This is a prompt message for success, and it will disappear in 10 seconds', 10);
},
}
}
</script>
```

View File

@ -0,0 +1,38 @@
<script>
import Duration from './duration'
import Info from './info'
import Loading from './loading'
import Other from './other'
import CN from '../index.zh-CN.md'
import US from '../index.en-US.md'
const md = {
cn: `# 全局提示
全局展示操作反馈信息
## 何时使用
- 可提供成功警告和错误等反馈信息
- 顶部居中显示并自动消失是一种不打断用户操作的轻量级提示方式
## 代码演示`,
us: `# Message
Display global messages as feedback in response to user operations.
## When To Use
- To provide feedback such as success, warning, error etc.
- A message is displayed at top and center and will be dismissed automatically, as a non-interrupting light-weighted prompt.`,
}
export default {
render () {
return (
<div>
<md cn={md.cn} us={md.us}/>
<Info />
<Duration />
<Loading />
<Other />
<api>
<CN slot='cn' />
<US/>
</api>
</div>
)
},
}
</script>

View File

@ -0,0 +1,26 @@
<cn>
#### 普通提示
信息提醒反馈。
</cn>
<us>
#### Normal prompt
Normal messages as feedbacks.
</us>
```html
<template>
<a-button type="primary" @click="info">Display normal message</a-button>
</template>
<script>
export default {
methods: {
info () {
this.$message.info('This is a normal message');
},
}
}
</script>
```

View File

@ -0,0 +1,27 @@
<cn>
#### 加载中
进行全局 loading异步自行移除。
</cn>
<us>
#### Message of loading
Display a global loading indicator, which is dismissed by itself asynchronously.
</us>
```html
<template>
<a-button @click="success">Display a loading indicator</a-button>
</template>
<script>
export default {
methods: {
success () {
const hide = this.$message.loading('Action in progress..', 0);
setTimeout(hide, 2500);
},
}
}
</script>
```

View File

@ -0,0 +1,36 @@
<cn>
#### 其他提示类型
包括成功、失败、警告。
</cn>
<us>
#### Other types of message
Messages of success, error and warning types.
</us>
```html
<template>
<div>
<a-button @click="success">Success</a-button>
<a-button @click="error">Error</a-button>
<a-button @click="warning">Warning</a-button>
</div>
</template>
<script>
export default {
methods: {
success () {
this.$message.success('This is a message of success');
},
error () {
this.$message.error('This is a message of error');
},
warning () {
this.$message.warning('This is message of warning');
},
}
}
</script>
```

View File

@ -0,0 +1,36 @@
## API
This components provides some static methods, with usage and arguments as following:
- `message.success(content, [duration], onClose)`
- `message.error(content, [duration], onClose)`
- `message.info(content, [duration], onClose)`
- `message.warning(content, [duration], onClose)`
- `message.warn(content, [duration], onClose)` // alias of warning
- `message.loading(content, [duration], onClose)`
| Argument | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| content | content of the message | string\|vueNode \|function(h) | - |
| duration | time before auto-dismiss, in seconds | number | 1.5 |
| onClose | Specify a function that will be called when the message is closed | Function | - |
Methods for global configuration and destruction are also provided:
- `message.config(options)`
- `message.destroy()`
### message.config
```js
message.config({
top: '100px',
duration: 2,
});
```
| Argument | Description | Type | Default |
| -------- | ----------- | ---- | ------- |
| duration | time before auto-dismiss, in seconds | number | 1.5 |
| getContainer | Return the mount node for Message | () => HTMLElement | () => document.body |
| top | distance from top | string | `24px` |

126
components/message/index.js Normal file
View File

@ -0,0 +1,126 @@
import Notification from '../vc-notification'
import Icon from '../icon'
let defaultDuration = 3
let defaultTop = null
let messageInstance = null
let key = 1
let prefixCls = 'ant-message'
let getContainer = () => document.body
function getMessageInstance (callback) {
if (messageInstance) {
callback(messageInstance)
return
}
Notification.newInstance({
prefixCls,
transitionName: 'move-up',
style: { top: defaultTop }, // 覆盖原来的样式
getContainer,
}, (instance) => {
if (messageInstance) {
callback(messageInstance)
return
}
messageInstance = instance
callback(instance)
})
}
// type NoticeType = 'info' | 'success' | 'error' | 'warning' | 'loading';
function notice (
content,
duration,
type,
onClose,
) {
const iconType = ({
info: 'info-circle',
success: 'check-circle',
error: 'cross-circle',
warning: 'exclamation-circle',
loading: 'loading',
})[type]
if (typeof duration === 'function') {
onClose = duration
duration = defaultDuration
}
const target = key++
getMessageInstance((instance) => {
instance.notice({
key: target,
duration,
style: {},
content: (h) => (
<div class={`${prefixCls}-custom-content ${prefixCls}-${type}`}>
<Icon type={iconType} />
<span>{typeof content === 'function' ? content(h) : content}</span>
</div>
),
onClose,
})
})
return () => {
if (messageInstance) {
messageInstance.removeNotice(target)
}
}
}
// type ConfigContent = React.ReactNode | string;
// type ConfigDuration = number | (() => void);
// export type ConfigOnClose = () => void;
// export interface ConfigOptions {
// top?: number;
// duration?: number;
// prefixCls?: string;
// getContainer?: () => HTMLElement;
// }
export default {
info (content, duration, onClose) {
return notice(content, duration, 'info', onClose)
},
success (content, duration, onClose) {
return notice(content, duration, 'success', onClose)
},
error (content, duration, onClose) {
return notice(content, duration, 'error', onClose)
},
// Departed usage, please use warning()
warn (content, duration, onClose) {
return notice(content, duration, 'warning', onClose)
},
warning (content, duration, onClose) {
return notice(content, duration, 'warning', onClose)
},
loading (content, duration, onClose) {
return notice(content, duration, 'loading', onClose)
},
config (options) {
if (options.top !== undefined) {
defaultTop = options.top
messageInstance = null // delete messageInstance for new defaultTop
}
if (options.duration !== undefined) {
defaultDuration = options.duration
}
if (options.prefixCls !== undefined) {
prefixCls = options.prefixCls
}
if (options.getContainer !== undefined) {
getContainer = options.getContainer
}
},
destroy () {
if (messageInstance) {
messageInstance.destroy()
messageInstance = null
}
},
}

View File

@ -0,0 +1,36 @@
## API
组件提供了一些静态方法,使用方式和参数如下:
- `message.success(content, [duration], onClose)`
- `message.error(content, [duration], onClose)`
- `message.info(content, [duration], onClose)`
- `message.warning(content, [duration], onClose)`
- `message.warn(content, [duration], onClose)` // alias of warning
- `message.loading(content, [duration], onClose)`
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| content | 提示内容 | string\|vueNode \|function(h) | - |
| duration | 自动关闭的延时,单位秒 | number | 3 |
| onClose | 关闭时触发的回调函数 | Function | - |
还提供了全局配置和全局销毁方法:
- `message.config(options)`
- `message.destroy()`
### message.config
```js
message.config({
top: `100px`,
duration: 2,
});
```
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| duration | 默认自动关闭延时,单位秒 | number | 3 |
| getContainer | 配置渲染节点的输出位置 | () => HTMLElement | () => document.body |
| top | 消息距离顶部的位置 | string | `24px` |

View File

@ -0,0 +1,2 @@
import '../../style/index.less'
import './index.less'

View File

@ -0,0 +1,74 @@
@import "../../style/themes/default";
@import "../../style/mixins/index";
@message-prefix-cls: ~"@{ant-prefix}-message";
.@{message-prefix-cls} {
.reset-component;
position: fixed;
z-index: @zindex-message;
width: 100%;
top: 16px;
left: 0;
pointer-events: none;
&-notice {
padding: 8px;
text-align: center;
&:first-child {
margin-top: -8px;
}
}
&-notice-content {
padding: 10px 16px;
border-radius: @border-radius-base;
box-shadow: @shadow-2;
background: @component-background;
display: inline-block;
pointer-events: all;
}
&-success .@{iconfont-css-prefix} {
color: @success-color;
}
&-error .@{iconfont-css-prefix} {
color: @error-color;
}
&-warning .@{iconfont-css-prefix} {
color: @warning-color;
}
&-info .@{iconfont-css-prefix},
&-loading .@{iconfont-css-prefix} {
color: @info-color;
}
.@{iconfont-css-prefix} {
margin-right: 8px;
font-size: @font-size-lg;
top: 1px;
position: relative;
}
&-notice.move-up-leave.move-up-leave-active {
animation-name: MessageMoveOut;
overflow: hidden;
animation-duration: .3s;
}
}
@keyframes MessageMoveOut {
0% {
opacity: 1;
max-height: 150px;
padding: 8px;
}
100% {
opacity: 0;
max-height: 0;
padding: 0;
}
}

View File

@ -19,3 +19,4 @@ import './divider/style'
import './card/style'
import './collapse/style'
import './notification/style'
import './message/style'

View File

@ -20,4 +20,5 @@ export { default as dropdown } from 'antd/dropdown/demo/index.vue'
export { default as divider } from 'antd/divider/demo/index.vue'
export { default as collapse } from 'antd/collapse/demo/index.vue'
export { default as notification } from 'antd/notification/demo/index.vue'
export { default as message } from 'antd/message/demo/index.vue'

View File

@ -3,7 +3,7 @@ const AsyncComp = () => {
const hashs = window.location.hash.split('/')
const d = hashs[hashs.length - 1]
return {
component: import(`../components/notification/demo/${d}.md`),
component: import(`../components/message/demo/${d}.md`),
}
}
export default [

View File

@ -79,7 +79,7 @@ md.core.ruler.push('update_template', function replace ({ tokens }) {
jsfiddle = md.utils.escapeHtml(JSON.stringify(jsfiddle))
const codeHtml = code ? md.render(code) : ''
const cnHtml = cn ? md.render(cn) : ''
const newContent = `
let newContent = `
<template>
<demo-box :jsfiddle="${jsfiddle}">
<template slot="component">${template}</template>
@ -87,13 +87,17 @@ md.core.ruler.push('update_template', function replace ({ tokens }) {
<template slot="us-description">${us ? md.render(us) : ''}</template>
<template slot="code">${codeHtml}</template>
</demo-box>
</template>
</template>`
newContent += script ? `
<script>
${script || ''}
</script>
` : ''
newContent += style ? `
<style>
${style || ''}
</style>`
</style>
` : ''
const t = new Token('html_block', '', 0)
t.content = newContent
tokens.push(t)