From cebce088c6f0a8e0fd2125db808ab51dd8f8f4f6 Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Tue, 6 Feb 2018 15:21:13 +0800 Subject: [PATCH] add notification --- components/_util/vnode.js | 21 +- components/dropdown/index.en-US.md | 12 +- components/dropdown/index.zh-CN.md | 12 +- components/index.js | 7 + components/notification/demo/basic.md | 29 +++ components/notification/demo/custom-icon.md | 30 +++ components/notification/demo/custom-style.md | 33 +++ components/notification/demo/duration.md | 32 +++ components/notification/demo/index.vue | 50 +++++ components/notification/demo/placement.md | 48 +++++ components/notification/demo/with-btn.md | 46 +++++ components/notification/demo/with-icon.md | 34 ++++ components/notification/index.en-US.md | 37 +--- components/notification/index.js | 204 +++++++++++++++++++ components/notification/index.vue | 201 ------------------ components/notification/index.zh-CN.md | 28 +-- components/notification/src/Notice.vue | 10 +- components/notification/src/Notification.vue | 40 ++-- components/style.js | 1 + contributors.md | 6 +- examples/components/demo.vue | 2 +- examples/demo.js | 1 + examples/index.js | 10 +- examples/routes.js | 8 +- 24 files changed, 607 insertions(+), 295 deletions(-) create mode 100644 components/notification/demo/custom-icon.md create mode 100644 components/notification/demo/custom-style.md create mode 100644 components/notification/demo/duration.md create mode 100644 components/notification/demo/index.vue create mode 100644 components/notification/demo/placement.md create mode 100644 components/notification/demo/with-btn.md create mode 100644 components/notification/demo/with-icon.md create mode 100644 components/notification/index.js delete mode 100644 components/notification/index.vue diff --git a/components/_util/vnode.js b/components/_util/vnode.js index e36d6e822..ba85697ee 100644 --- a/components/_util/vnode.js +++ b/components/_util/vnode.js @@ -1,16 +1,15 @@ -import cloneDeep from 'lodash.clonedeep' export function cloneVNode (vnode, deep) { const componentOptions = vnode.componentOptions const data = vnode.data let listeners = {} if (componentOptions && componentOptions.listeners) { - listeners = cloneDeep(componentOptions.listeners) + listeners = { ...componentOptions.listeners } } let on = {} if (data && data.on) { - on = cloneDeep(data.on) + on = { ...data.on } } const cloned = new vnode.constructor( @@ -98,11 +97,23 @@ export function isEmptyElement (ele) { } export function getClass (ele) { - return ele.data && (ele.data.class || ele.data.staticClass) + let data = {} + if (ele.data) { + data = ele.data + } else if (ele.$vnode && ele.$vnode.data) { + data = ele.$vnode.data + } + return data.class || data.staticClass } export function getStyle (ele) { - return ele.data && (ele.data.style || ele.data.staticStyle) + let data = {} + if (ele.data) { + data = ele.data + } else if (ele.$vnode && ele.$vnode.data) { + data = ele.$vnode.data + } + return data.style || data.staticStyle } export function filterEmpty (children = []) { diff --git a/components/dropdown/index.en-US.md b/components/dropdown/index.en-US.md index a0b0dba82..4c872bd8c 100644 --- a/components/dropdown/index.en-US.md +++ b/components/dropdown/index.en-US.md @@ -6,7 +6,7 @@ | -------- | ----------- | ---- | ------- | | disabled | whether the dropdown menu is disabled | boolean | - | | getPopupContainer | to set the container of the dropdown menu. The default is to create a `div` element in `body`, you can reset it to the scrolling area and make a relative reposition. [example](https://codepen.io/afc163/pen/zEjNOy?editors=0010) | Function(triggerNode) | `() => document.body` | -| overlay(slot) | the dropdown menu | [Menu](#/components/us/menu) | - | +| overlay(slot) | the dropdown menu | [Menu](#/us/components/menu) | - | | placement | placement of pop menu: `bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | String | `bottomLeft` | | trigger | the trigger mode which executes the drop-down action | Array<`click`\|`hover`\|`contextMenu`> | `['hover']` | | visible(v-model) | whether the dropdown menu is visible | boolean | - | @@ -16,7 +16,7 @@ | --- | --- | --- | | visibleChange | a callback function takes an argument: `visible`, is executed when the visible state is changed | function(visible) | -You should use [Menu](#/components/us/menu/) as `overlay`. The menu items and dividers are also available by using `Menu.Item` and `Menu.Divider`. +You should use [Menu](#/us/components/menu/) as `overlay`. The menu items and dividers are also available by using `Menu.Item` and `Menu.Divider`. > Warning: You must set a unique `key` for `Menu.Item`. > @@ -27,11 +27,11 @@ You should use [Menu](#/components/us/menu/) as `overlay`. The menu items and di | Property | Description | Type | Default | | -------- | ----------- | ---- | ------- | | disabled | whether the dropdown menu is disabled | boolean | - | -| overlay(slot) | the dropdown menu | [Menu](#/components/us/menu) | - | +| overlay(slot) | the dropdown menu | [Menu](#/us/components/menu) | - | | placement | placement of pop menu: `bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | String | `bottomLeft` | -| size | size of the button, the same as [Button](#/components/us/button) | string | `default` | +| size | size of the button, the same as [Button](#/us/components/button) | string | `default` | | trigger | the trigger mode which executes the drop-down action | Array<`click`\|`hover`\|`contextMenu`> | `['hover']` | -| type | type of the button, the same as [Button](#/components/us/button) | string | `default` | +| type | type of the button, the same as [Button](#/us/components/button) | string | `default` | | visible | whether the dropdown menu is visible | boolean | - | @@ -39,5 +39,5 @@ You should use [Menu](#/components/us/menu/) as `overlay`. The menu items and di ### Dropdown.Button events | Events Name | Description | Arguments | | --- | --- | --- | -| click | a callback function, the same as [Button](#/components/us/button), which will be executed when you click the button on the left | Function | +| click | a callback function, the same as [Button](#/us/components/button), which will be executed when you click the button on the left | Function | | visibleChange | a callback function takes an argument: `visible`, is executed when the visible state is changed | Function | diff --git a/components/dropdown/index.zh-CN.md b/components/dropdown/index.zh-CN.md index 8f4d3d753..8c4f839ff 100644 --- a/components/dropdown/index.zh-CN.md +++ b/components/dropdown/index.zh-CN.md @@ -6,12 +6,12 @@ | --- | --- | --- | --- | | disabled | 菜单是否禁用 | boolean | - | | getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。 | Function(triggerNode) | `() => document.body` | -| overlay(slot) | 菜单 | [Menu](#/components/cn/menu) | - | +| overlay(slot) | 菜单 | [Menu](#/cn/components/menu) | - | | placement | 菜单弹出位置:`bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | String | `bottomLeft` | | trigger | 触发下拉的行为 | Array<`click`\|`hover`\|`contextMenu`> | `['hover']` | | visible(v-model) | 菜单是否显示 | boolean | - | -`overlay` 菜单使用 [Menu](#/components/cn/menu/),还包括菜单项 `Menu.Item`,分割线 `Menu.Divider`。 +`overlay` 菜单使用 [Menu](#/cn/components/menu/),还包括菜单项 `Menu.Item`,分割线 `Menu.Divider`。 > 注意: Menu.Item 必须设置唯一的 key 属性。 > @@ -28,15 +28,15 @@ | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | | disabled | 菜单是否禁用 | boolean | - | -| overlay(slot) | 菜单 | [Menu](#/components/cn/menu/) | - | +| overlay(slot) | 菜单 | [Menu](#/cn/components/menu/) | - | | placement | 菜单弹出位置:`bottomLeft` `bottomCenter` `bottomRight` `topLeft` `topCenter` `topRight` | String | `bottomLeft` | -| size | 按钮大小,和 [Button](#/components/cn/button/) 一致 | string | 'default' | +| size | 按钮大小,和 [Button](#/cn/components/button/) 一致 | string | 'default' | | trigger | 触发下拉的行为 | Array<`click`\|`hover`\|`contextMenu`> | `['hover']` | -| type | 按钮类型,和 [Button](#/components/cn/button/) 一致 | string | 'default' | +| type | 按钮类型,和 [Button](#/cn/components/button/) 一致 | string | 'default' | | visible(v-model) | 菜单是否显示 | boolean | - | ### Dropdown.Button事件 | 事件名称 | 说明 | 回调参数 | | --- | --- | --- | -| click | 点击左侧按钮的回调,和 [Button](#/components/cn/button/) 一致 | Function | +| click | 点击左侧按钮的回调,和 [Button](#/cn/components/button/) 一致 | Function | | visibleChange | 菜单显示状态改变时调用,参数为 visible | function(visible) | diff --git a/components/index.js b/components/index.js index dbc9732f0..f5cb081d8 100644 --- a/components/index.js +++ b/components/index.js @@ -59,3 +59,10 @@ export { default as Divider } from './divider' import Collapse from './collapse' const CollapsePanel = Collapse.Panel export { Collapse, CollapsePanel } + +import notification from './notification' + +const api = { + notification, +} +export { api } diff --git a/components/notification/demo/basic.md b/components/notification/demo/basic.md index e69de29bb..d34fffc6c 100644 --- a/components/notification/demo/basic.md +++ b/components/notification/demo/basic.md @@ -0,0 +1,29 @@ + + +#### 基本 +最简单的用法,4.5 秒后自动关闭。 + + + +#### Basic +The simplest usage that close the notification box after 4.5s. + + +```html + + +``` + diff --git a/components/notification/demo/custom-icon.md b/components/notification/demo/custom-icon.md new file mode 100644 index 000000000..72f59be1c --- /dev/null +++ b/components/notification/demo/custom-icon.md @@ -0,0 +1,30 @@ + + +#### 自定义图标 +图标可以被自定义。 + + + +#### Customized Icon +The icon can be customized to any vue node or (h) => vue node. + + +```html + + +``` + diff --git a/components/notification/demo/custom-style.md b/components/notification/demo/custom-style.md new file mode 100644 index 000000000..7df909377 --- /dev/null +++ b/components/notification/demo/custom-style.md @@ -0,0 +1,33 @@ + + +#### 自定义样式 +使用 style 和 className 来定义样式。 + + + +#### Customized style +The style and className are available to customize Notification. + + +```html + + +``` + diff --git a/components/notification/demo/duration.md b/components/notification/demo/duration.md new file mode 100644 index 000000000..26d01aab3 --- /dev/null +++ b/components/notification/demo/duration.md @@ -0,0 +1,32 @@ + + +#### 自动关闭的延时 +自定义通知框自动关闭的延时,默认`4.5s`,取消自动关闭只要将该值设为 `0` 即可。 + + + +#### Duration after which the notification box is closed +`Duration` can be used to specify how long the notification stays open. After the duration time elapses, +the notification closes automatically. If not specified, default value is 4.5 seconds. If you set the value to 0, +the notification box will never close automatically. + + +```html + + +``` + diff --git a/components/notification/demo/index.vue b/components/notification/demo/index.vue new file mode 100644 index 000000000..c67499a4a --- /dev/null +++ b/components/notification/demo/index.vue @@ -0,0 +1,50 @@ + diff --git a/components/notification/demo/placement.md b/components/notification/demo/placement.md new file mode 100644 index 000000000..5779b0388 --- /dev/null +++ b/components/notification/demo/placement.md @@ -0,0 +1,48 @@ + + +#### 位置 +可以设置通知从右上角、右下角、左下角、左上角弹出。 + + + +#### Placement +A notification box can pop up from `topRight` or `bottomRight` or `bottomLeft` or `topLeft`. + + +```html + + +``` + diff --git a/components/notification/demo/with-btn.md b/components/notification/demo/with-btn.md new file mode 100644 index 000000000..ab9b25c68 --- /dev/null +++ b/components/notification/demo/with-btn.md @@ -0,0 +1,46 @@ + + +#### 基本 +最简单的用法,4.5 秒后自动关闭。 + + + +#### Basic +The simplest usage that close the notification box after 4.5s. + + +```html + + +``` + diff --git a/components/notification/demo/with-icon.md b/components/notification/demo/with-icon.md new file mode 100644 index 000000000..74fce01b9 --- /dev/null +++ b/components/notification/demo/with-icon.md @@ -0,0 +1,34 @@ + + +#### 带有图标的通知提醒框 +通知提醒框左侧有图标。 + + + +#### Notification with icon +A notification box with a icon at the left side. + + +```html + + +``` + diff --git a/components/notification/index.en-US.md b/components/notification/index.en-US.md index 3b9af9239..b0d5e306c 100644 --- a/components/notification/index.en-US.md +++ b/components/notification/index.en-US.md @@ -1,22 +1,3 @@ ---- -category: Components -type: Feedback -noinstant: true -title: Notification ---- - -Display a notification message globally. - -## When To Use - -To display a notification message at any of the four corners of the viewport. Typically it can be -used in the following cases: - -- A notification with complex content. -- A notification providing a feedback based on the user interaction. Or it may show some details - about upcoming steps the user may have to follow. -- A notification that is pushed by the application. - ## API - `notification.success(config)` @@ -31,15 +12,15 @@ The properties of config are as follows: | Property | Description | Type | Default | | -------- | ----------- | ---- | ------- | -| btn | Customized close button | ReactNode | - | -| className | Customized CSS class | string | - | -| description | The content of notification box (required) | string\|ReactNode | - | +| btn | Customized close button | vueNode \|function(h) | - | +| class | Customized CSS class | string | - | +| description | The content of notification box (required) | string\| vueNode \|function(h) | - | | duration | Time in seconds before Notification is closed. When set to 0 or null, it will never be closed automatically | number | 4.5 | -| icon | Customized icon | ReactNode | - | +| icon | Customized icon | vueNode \|function(h) | - | | key | The unique identifier of the Notification | string | - | -| message | The title of notification box (required) | string\|ReactNode | - | +| message | The title of notification box (required) | string\|vueNode \|function(h) | - | | placement | Position of Notification, can be one of `topLeft` `topRight` `bottomLeft` `bottomRight` | string | `topRight` | -| style | Customized inline style | [React.CSSProperties](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e434515761b36830c3e58a970abf5186f005adac/types/react/index.d.ts#L794) | - | +| style | Customized inline style | Object \| string | - | | onClose | Specify a function that will be called when the close button is clicked | Function | - | `notification` also provides a global `config()` method that can be used for specifying the default options. Once this method is used, all the notification boxes will take into account these globally defined options when displaying. @@ -49,15 +30,15 @@ The properties of config are as follows: ```js notification.config({ placement: 'bottomRight', - bottom: 50, + bottom: '50px', duration: 3, }); ``` | Property | Description | Type | Default | | -------- | ----------- | ---- | ------- | -| bottom | Distance from the bottom of the viewport, when `placement` is `bottomRight` or `bottomLeft` (unit: pixels). | number | 24 | +| bottom | Distance from the bottom of the viewport, when `placement` is `bottomRight` or `bottomLeft` (unit: pixels). | string | `24px` | | duration | Time in seconds before Notification is closed. When set to 0 or null, it will never be closed automatically | number | 4.5 | | getContainer | Return the mount node for Notification | () => HTMLNode | () => document.body | | placement | Position of Notification, can be one of `topLeft` `topRight` `bottomLeft` `bottomRight` | string | `topRight` | -| top | Distance from the top of the viewport, when `placement` is `topRight` or `topLeft` (unit: pixels). | number | 24 | +| top | Distance from the top of the viewport, when `placement` is `topRight` or `topLeft` (unit: pixels). | string | `24px` | diff --git a/components/notification/index.js b/components/notification/index.js new file mode 100644 index 000000000..1c7b1fd3d --- /dev/null +++ b/components/notification/index.js @@ -0,0 +1,204 @@ +import Notification from './src/notification' +import Icon from '../icon' + +// export type NotificationPlacement = 'topLeft' | 'topRight' | 'bottomLeft' | 'bottomRight'; + +// export type IconType = 'success' | 'info' | 'error' | 'warning'; + +const notificationInstance = {} +let defaultDuration = 4.5 +let defaultTop = '24px' +let defaultBottom = '24px' +let defaultPlacement = 'topRight' +let defaultGetContainer = () => document.body + +// export interface ConfigProps { +// top?: number; +// bottom?: number; +// duration?: number; +// placement?: NotificationPlacement; +// getContainer?: () => HTMLElement; +// } +function setNotificationConfig (options) { + const { duration, placement, bottom, top, getContainer } = options + if (duration !== undefined) { + defaultDuration = duration + } + if (placement !== undefined) { + defaultPlacement = placement + } + if (bottom !== undefined) { + defaultBottom = bottom + } + if (top !== undefined) { + defaultTop = top + } + if (getContainer !== undefined) { + defaultGetContainer = getContainer + } +} + +function getPlacementStyle (placement) { + let style + switch (placement) { + case 'topLeft': + style = { + left: 0, + top: defaultTop, + bottom: 'auto', + } + break + case 'topRight': + style = { + right: 0, + top: defaultTop, + bottom: 'auto', + } + break + case 'bottomLeft': + style = { + left: 0, + top: 'auto', + bottom: defaultBottom, + } + break + default: + style = { + right: 0, + top: 'auto', + bottom: defaultBottom, + } + break + } + return style +} + +function getNotificationInstance (prefixCls, placement, callback) { + const cacheKey = `${prefixCls}-${placement}` + if (notificationInstance[cacheKey]) { + callback(notificationInstance[cacheKey]) + return + } + Notification.newInstance({ + prefixCls, + class: `${prefixCls}-${placement}`, + style: getPlacementStyle(placement), + getContainer: defaultGetContainer, + }, (notification) => { + notificationInstance[cacheKey] = notification + callback(notification) + }) +} + +const typeToIcon = { + success: 'check-circle-o', + info: 'info-circle-o', + error: 'cross-circle-o', + warning: 'exclamation-circle-o', +} + +// export interface ArgsProps { +// message: React.ReactNode; +// description: React.ReactNode; +// btn?: React.ReactNode; +// key?: string; +// onClose?: () => void; +// duration?: number | null; +// icon?: React.ReactNode; +// placement?: NotificationPlacement; +// style?: React.CSSProperties; +// prefixCls?: string; +// className?: string; +// readonly type?: IconType; +// } +function notice (args) { + const { icon, type, description, placement, message, btn } = args + const outerPrefixCls = args.prefixCls || 'ant-notification' + const prefixCls = `${outerPrefixCls}-notice` + const duration = args.duration === undefined ? defaultDuration : args.duration + + let iconNode = null + if (icon) { + iconNode = (h) => ( + + {typeof icon === 'function' ? icon(h) : icon} + + ) + } else if (type) { + const iconType = typeToIcon[type] + iconNode = (h) => ( + + ) + } + + const autoMarginTag = (!description && iconNode) + ? + : null + + getNotificationInstance(outerPrefixCls, placement || defaultPlacement, (notification) => { + notification.notice({ + content: (h) => ( +
+ {iconNode && iconNode(h)} +
+ {autoMarginTag} + {typeof message === 'function' ? message(h) : message} +
+
+ {typeof description === 'function' ? description(h) : description} +
+ {btn ? + {typeof btn === 'function' ? btn(h) : btn} + : null} +
+ ), + duration, + closable: true, + onClose: args.onClose, + key: args.key, + style: args.style || {}, + class: args.class, + }) + }) +} + +const api = { + open: notice, + close (key) { + Object.keys(notificationInstance) + .forEach(cacheKey => notificationInstance[cacheKey].removeNotice(key)) + }, + config: setNotificationConfig, + destroy () { + Object.keys(notificationInstance).forEach(cacheKey => { + notificationInstance[cacheKey].destroy() + delete notificationInstance[cacheKey] + }) + }, +}; + +['success', 'info', 'warning', 'error'].forEach((type) => { + api[type] = (args) => api.open({ + ...args, + type, + }) +}) + +api.warn = api.warning + +// export interface NotificationApi { +// success(args: ArgsProps): void; +// error(args: ArgsProps): void; +// info(args: ArgsProps): void; +// warn(args: ArgsProps): void; +// warning(args: ArgsProps): void; +// open(args: ArgsProps): void; +// close(key: string): void; +// config(options: ConfigProps): void; +// destroy(): void; +// } +export default api + diff --git a/components/notification/index.vue b/components/notification/index.vue deleted file mode 100644 index fabfea257..000000000 --- a/components/notification/index.vue +++ /dev/null @@ -1,201 +0,0 @@ - \ No newline at end of file diff --git a/components/notification/index.zh-CN.md b/components/notification/index.zh-CN.md index 1b79dd3c4..c03533e72 100644 --- a/components/notification/index.zh-CN.md +++ b/components/notification/index.zh-CN.md @@ -1,13 +1,3 @@ ---- -category: Components -type: Feedback -noinstant: true -title: Notification -subtitle: 通知提醒框 ---- - -全局展示通知提醒信息。 - ## 何时使用 在系统四个角显示通知提醒信息。经常用于以下情况: @@ -30,15 +20,15 @@ config 参数如下: | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | -| btn | 自定义关闭按钮 | ReactNode | - | -| className | 自定义 CSS class | string | - | -| description | 通知提醒内容,必选 | string\|ReactNode | - | +| btn | 自定义关闭按钮 | vueNode \|function(h) | - | +| class | 自定义 CSS class | string | - | +| description | 通知提醒内容,必选 | string \|vueNode \|function(h) | - | | duration | 默认 4.5 秒后自动关闭,配置为 null 则不自动关闭 | number | 4.5 | -| icon | 自定义图标 | ReactNode | - | +| icon | 自定义图标 | vueNode \|function(h) | - | | key | 当前通知唯一标志 | string | - | -| message | 通知提醒标题,必选 | string\|ReactNode | - | +| message | 通知提醒标题,必选 | string \|vueNode \|function(h) | - | | placement | 弹出位置,可选 `topLeft` `topRight` `bottomLeft` `bottomRight` | string | topRight | -| style | 自定义内联样式 | [React.CSSProperties](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/e434515761b36830c3e58a970abf5186f005adac/types/react/index.d.ts#L794) | - | +| style | 自定义内联样式 | Object \| string | - | | onClose | 点击默认关闭按钮时触发的回调函数 | Function | - | 还提供了一个全局配置方法,在调用前提前配置,全局一次生效。 @@ -48,15 +38,15 @@ config 参数如下: ```js notification.config({ placement: 'bottomRight', - bottom: 50, + bottom: '50px', duration: 3, }); ``` | 参数 | 说明 | 类型 | 默认值 | | --- | --- | --- | --- | -| bottom | 消息从底部弹出时,距离底部的位置,单位像素。 | number | 24 | +| bottom | 消息从底部弹出时,距离底部的位置,单位像素。 | string | `24px` | | duration | 默认自动关闭延时,单位秒 | number | 4.5 | | getContainer | 配置渲染节点的输出位置 | () => HTMLNode | () => document.body | | placement | 弹出位置,可选 `topLeft` `topRight` `bottomLeft` `bottomRight` | string | topRight | -| top | 消息从顶部弹出时,距离顶部的位置,单位像素。 | number | 24 | +| top | 消息从顶部弹出时,距离顶部的位置,单位像素。 | string | `24px` | diff --git a/components/notification/src/Notice.vue b/components/notification/src/Notice.vue index 18129498d..7acc902f7 100644 --- a/components/notification/src/Notice.vue +++ b/components/notification/src/Notice.vue @@ -7,23 +7,27 @@ export default { mixins: [BaseMixin], props: { duration: PropTypes.number.def(1.5), + closable: PropTypes.bool, + prefixCls: PropTypes.string, }, mounted () { this.startCloseTimer() }, - beforeDestory () { + beforeDestroy () { this.clearCloseTimer() + this.willDestroy = true // beforeDestroy调用后依然会触发onMouseleave事件 }, methods: { close () { this.clearCloseTimer() - this._emit('close') + this.__emit('close') }, startCloseTimer () { - if (this.duration) { + this.clearCloseTimer() + if (!this.willDestroy && this.duration) { this.closeTimer = setTimeout(() => { this.close() }, this.duration * 1000) diff --git a/components/notification/src/Notification.vue b/components/notification/src/Notification.vue index 848f302d1..8df9f8674 100644 --- a/components/notification/src/Notification.vue +++ b/components/notification/src/Notification.vue @@ -57,26 +57,32 @@ const Notification = { }, }, - render () { + render (h) { const { prefixCls, notices, remove, getTransitionName } = this + const transitionProps = getTransitionProps(getTransitionName()) const noticeNodes = notices.map((notice) => { - const onClose = createChainedFunction(remove.bind(this, notice.key), notice.on.close) + const { content, duration, closable, onClose, key, style, class: className } = notice + const close = createChainedFunction(remove.bind(this, key), onClose) const noticeProps = { - ...notice, props: { prefixCls, - ...notice.props, + duration, + closable, }, on: { - ...notice.on, - close: onClose, + close, }, + style, + class: className, + key, } - return ( - {notice.content} - ) + return ( + + {content(h)} + + ) }) const className = { [prefixCls]: 1, @@ -87,14 +93,14 @@ const Notification = { top: '65px', left: '50%', }}> - {noticeNodes} + {noticeNodes} ) }, } Notification.newInstance = function newNotificationInstance (properties, callback) { - const { getContainer, style, class: className, on = {}, ...props } = properties || {} + const { getContainer, style, class: className, ...props } = properties || {} const div = document.createElement('div') if (getContainer) { const root = getContainer() @@ -102,7 +108,7 @@ Notification.newInstance = function newNotificationInstance (properties, callbac } else { document.body.appendChild(div) } - const notificationInstance = new Vue({ + new Vue({ el: div, mounted () { const self = this @@ -116,9 +122,8 @@ Notification.newInstance = function newNotificationInstance (properties, callbac }, component: self, destroy () { - // self.$destroy() - notificationInstance.$destroy() - div.parentNode.removeChild(div) + self.$destroy() + self.$el.parentNode.removeChild(self.$el) }, }) }) @@ -126,7 +131,6 @@ Notification.newInstance = function newNotificationInstance (properties, callbac render () { const p = { props, - on, ref: 'notification', style, class: className, diff --git a/components/style.js b/components/style.js index ab2b465ea..275b52db9 100644 --- a/components/style.js +++ b/components/style.js @@ -18,3 +18,4 @@ import './dropdown/style' import './divider/style' import './card/style' import './collapse/style' +import './notification/style' diff --git a/contributors.md b/contributors.md index 6666ac201..a928183a6 100644 --- a/contributors.md +++ b/contributors.md @@ -13,6 +13,8 @@ Popover | done Menu | done Dropdown | done Divider | done +notification | done +message Carousel Mention Input | done |select完成后补全demo @@ -32,9 +34,7 @@ Affix Alert BackTop Layout -message Modal -notification Anchor Tree TreeSelect @@ -46,7 +46,7 @@ Avatar | done Badge | done Breadcrumb | done Card | done -Collapse +Collapse | done LocaleProvider Progress Slider diff --git a/examples/components/demo.vue b/examples/components/demo.vue index ceef9ce93..f52f79b67 100644 --- a/examples/components/demo.vue +++ b/examples/components/demo.vue @@ -15,7 +15,7 @@ export default {
{Object.keys(AllDemo).map(d => - {d} + {d} )}
diff --git a/examples/demo.js b/examples/demo.js index 874cade54..70349ef1d 100644 --- a/examples/demo.js +++ b/examples/demo.js @@ -19,4 +19,5 @@ export { default as tooltip } from 'antd/tooltip/demo/index.vue' 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' diff --git a/examples/index.js b/examples/index.js index 905f09e51..79c4cf8c1 100644 --- a/examples/index.js +++ b/examples/index.js @@ -16,8 +16,14 @@ Vue.component(Md.name, Md) Vue.component(Api.name, Api) Vue.component('demo-box', demoBox) Object.keys(Components).forEach(k => { - const name = `a${k.replace(/([A-Z])/g, '-$1').toLowerCase()}` - Vue.component(name, Components[k]) + if (k === 'api') { + Object.keys(Components[k]).forEach(api => { + Vue.prototype[`$${api}`] = Components[k][api] + }) + } else { + const name = `a${k.replace(/([A-Z])/g, '-$1').toLowerCase()}` + Vue.component(name, Components[k]) + } }) const router = new VueRouter({ diff --git a/examples/routes.js b/examples/routes.js index ee71d394d..0878c06c2 100644 --- a/examples/routes.js +++ b/examples/routes.js @@ -1,11 +1,13 @@ import Demo from './components/demo.vue' const AsyncComp = () => { + const hashs = window.location.hash.split('/') + const d = hashs[hashs.length - 1] return { - component: import(`../components/collapse/demo/index.vue`), + component: import(`../components/notification/demo/${d}.md`), } } export default [ - { path: '/components/:lang/:name/:demo?', component: Demo }, + { path: '/:lang/components/:name/:demo?', component: Demo }, { path: '/:lang?/test/:name/:demo?', component: AsyncComp }, - { path: '/*', redirect: '/components/cn/menu' }, + { path: '/*', redirect: '/cn/components/menu' }, ]