From eb44209a5acd7755a6ff0031c1b6ea6e5fbab2e7 Mon Sep 17 00:00:00 2001 From: neverland Date: Sun, 25 Nov 2018 10:36:07 +0800 Subject: [PATCH] [new feature] add Notify component (#2135) --- docs/src/demo-entry.js | 1 + docs/src/doc.config.js | 8 ++ docs/src/docs-entry.js | 2 + packages/circle/index.vue | 4 +- packages/index.js | 3 + packages/index.less | 1 + packages/notify/Notify.vue | 52 +++++++++++++ packages/notify/demo/index.vue | 58 +++++++++++++++ packages/notify/en-US.md | 57 ++++++++++++++ packages/notify/index.js | 74 +++++++++++++++++++ packages/notify/index.less | 12 +++ .../test/__snapshots__/demo.spec.js.snap | 12 +++ .../test/__snapshots__/index.spec.js.snap | 31 ++++++++ packages/notify/test/demo.spec.js | 4 + packages/notify/test/index.spec.js | 49 ++++++++++++ packages/notify/zh-CN.md | 56 ++++++++++++++ packages/progress/index.vue | 4 +- packages/style/var.less | 5 ++ packages/toast/en-US.md | 2 +- packages/utils/color.js | 1 + types/index.d.ts | 2 + types/notify.d.ts | 32 ++++++++ 22 files changed, 465 insertions(+), 5 deletions(-) create mode 100644 packages/notify/Notify.vue create mode 100644 packages/notify/demo/index.vue create mode 100644 packages/notify/en-US.md create mode 100644 packages/notify/index.js create mode 100644 packages/notify/index.less create mode 100644 packages/notify/test/__snapshots__/demo.spec.js.snap create mode 100644 packages/notify/test/__snapshots__/index.spec.js.snap create mode 100644 packages/notify/test/demo.spec.js create mode 100644 packages/notify/test/index.spec.js create mode 100644 packages/notify/zh-CN.md create mode 100644 types/notify.d.ts diff --git a/docs/src/demo-entry.js b/docs/src/demo-entry.js index 15fc1e21e..fbdac6068 100644 --- a/docs/src/demo-entry.js +++ b/docs/src/demo-entry.js @@ -27,6 +27,7 @@ export default { 'loading': () => wrapper(import('../../packages/loading/demo'), 'loading'), 'nav-bar': () => wrapper(import('../../packages/nav-bar/demo'), 'nav-bar'), 'notice-bar': () => wrapper(import('../../packages/notice-bar/demo'), 'notice-bar'), + 'notify': () => wrapper(import('../../packages/notify/demo'), 'notify'), 'number-keyboard': () => wrapper(import('../../packages/number-keyboard/demo'), 'number-keyboard'), 'pagination': () => wrapper(import('../../packages/pagination/demo'), 'pagination'), 'panel': () => wrapper(import('../../packages/panel/demo'), 'panel'), diff --git a/docs/src/doc.config.js b/docs/src/doc.config.js index 565bb1246..ca4ef296c 100644 --- a/docs/src/doc.config.js +++ b/docs/src/doc.config.js @@ -172,6 +172,10 @@ module.exports = { path: '/loading', title: 'Loading 加载' }, + { + path: '/notify', + title: 'Notify 消息通知' + }, { path: '/pull-refresh', title: 'PullRefresh 下拉刷新' @@ -469,6 +473,10 @@ module.exports = { path: '/loading', title: 'Loading' }, + { + path: '/notify', + title: 'Notify' + }, { path: '/pull-refresh', title: 'PullRefresh' diff --git a/docs/src/docs-entry.js b/docs/src/docs-entry.js index a13c0f2ba..70b5caf4e 100644 --- a/docs/src/docs-entry.js +++ b/docs/src/docs-entry.js @@ -62,6 +62,8 @@ export default { 'nav-bar.zh-CN': () => import('../../packages/nav-bar/zh-CN.md'), 'notice-bar.en-US': () => import('../../packages/notice-bar/en-US.md'), 'notice-bar.zh-CN': () => import('../../packages/notice-bar/zh-CN.md'), + 'notify.en-US': () => import('../../packages/notify/en-US.md'), + 'notify.zh-CN': () => import('../../packages/notify/zh-CN.md'), 'number-keyboard.en-US': () => import('../../packages/number-keyboard/en-US.md'), 'number-keyboard.zh-CN': () => import('../../packages/number-keyboard/zh-CN.md'), 'pagination.en-US': () => import('../../packages/pagination/en-US.md'), diff --git a/packages/circle/index.vue b/packages/circle/index.vue index d6a338f8d..9b8c2de58 100644 --- a/packages/circle/index.vue +++ b/packages/circle/index.vue @@ -24,7 +24,7 @@ diff --git a/packages/notify/demo/index.vue b/packages/notify/demo/index.vue new file mode 100644 index 000000000..bd8fad6b9 --- /dev/null +++ b/packages/notify/demo/index.vue @@ -0,0 +1,58 @@ + + + + + diff --git a/packages/notify/en-US.md b/packages/notify/en-US.md new file mode 100644 index 000000000..949a28358 --- /dev/null +++ b/packages/notify/en-US.md @@ -0,0 +1,57 @@ +## Notify + +### Install + +``` javascript +import { Notify } from 'vant'; + +Vue.use(Notify); +``` + +### Usage + +#### Basic Usage + +```js +Notify('Notify Message'); +``` + +#### Custom Config + +```js +Notify({ + message: 'Notify Message', + duration: 1000, + background: '#1989fa' +}); +``` + +#### $notify Method + +After import the Notify component, the $notify method is automatically mounted on Vue.prototype, making it easy to call within a vue component. + +```js +export default { + mounted() { + this.$notify('Notify Message'); + } +} +``` + +### Methods + +| Methods | Attribute | Return value | Description | +|------|------|------|------| +| Notify | `options | message` | notify instance | Show notify | +| Notify.clear | - | `void` | Close notify | +| Notify.setDefaultOptions | `options` | `void` | Set default options of all notifies | +| Notify.resetDefaultOptions | - | `void` | Reset default options of all notifies | + +### API + +| Attribute | Description | Type | Default | +|------|------|------|------| +| message | Message | `String` | - | +| duration | Duration(ms), won't disappear if value is 0 | `Number` | `3000` | +| color | Message color | `String` | `#fff` | | +| background | Background color | `String` | `#f44` | diff --git a/packages/notify/index.js b/packages/notify/index.js new file mode 100644 index 000000000..428f5c411 --- /dev/null +++ b/packages/notify/index.js @@ -0,0 +1,74 @@ +import Vue from 'vue'; +import VanNotify from './Notify'; +import { RED, WHITE } from '../utils/color'; +import { isObj, isServer } from '../utils'; + +let timer; +let instance; + +const initInstance = () => { + instance = new (Vue.extend(VanNotify))({ + el: document.createElement('div') + }); + + document.body.appendChild(instance.$el); +}; + +const parseOptions = message => (isObj(message) ? message : { message }); + +const Notify = options => { + /* istanbul ignore if */ + if (isServer) { + return; + } + + if (!instance) { + initInstance(); + } + + options = { + ...Notify.currentOptions, + ...parseOptions(options) + }; + + Object.assign(instance, options); + clearTimeout(timer); + + if (options.duration > 0) { + timer = setTimeout(Notify.clear, options.duration); + } + + return instance; +}; + +Notify.clear = () => { + if (instance) { + instance.value = false; + } +}; + +Notify.defaultOptions = { + value: true, + text: '', + color: WHITE, + background: RED, + duration: 3000 +}; + +Notify.setDefaultOptions = options => { + Object.assign(Notify.currentOptions, options); +}; + +Notify.resetDefaultOptions = () => { + Notify.currentOptions = { ...Notify.defaultOptions }; +}; + +Notify.install = () => { + Vue.use(VanNotify); +}; + +Notify.resetDefaultOptions(); + +Vue.prototype.$notify = Notify; + +export default Notify; diff --git a/packages/notify/index.less b/packages/notify/index.less new file mode 100644 index 000000000..aee0ee00b --- /dev/null +++ b/packages/notify/index.less @@ -0,0 +1,12 @@ +@import '../style/var'; + +.van-notify { + position: fixed; + top: 0; + width: 100%; + text-align: center; + box-sizing: border-box; + padding: @notify-padding; + font-size: @notify-font-size; + line-height: @notify-line-height; +} diff --git a/packages/notify/test/__snapshots__/demo.spec.js.snap b/packages/notify/test/__snapshots__/demo.spec.js.snap new file mode 100644 index 000000000..7aac71288 --- /dev/null +++ b/packages/notify/test/__snapshots__/demo.spec.js.snap @@ -0,0 +1,12 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`renders demo correctly 1`] = ` +
+
+ +
+
+ +
+
+`; diff --git a/packages/notify/test/__snapshots__/index.spec.js.snap b/packages/notify/test/__snapshots__/index.spec.js.snap new file mode 100644 index 000000000..0637b69c0 --- /dev/null +++ b/packages/notify/test/__snapshots__/index.spec.js.snap @@ -0,0 +1,31 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`create a notify 1`] = ` +
+ test +
+`; + +exports[`notify disappear 1`] = ` +
+ test +
+`; + +exports[`notify disappear 2`] = ` + +`; + +exports[`notify disappear 3`] = ` +
+ text2 +
+`; + +exports[`notify disappear 4`] = ` + +`; diff --git a/packages/notify/test/demo.spec.js b/packages/notify/test/demo.spec.js new file mode 100644 index 000000000..d647cfabc --- /dev/null +++ b/packages/notify/test/demo.spec.js @@ -0,0 +1,4 @@ +import Demo from '../demo'; +import demoTest from '../../../test/demo-test'; + +demoTest(Demo); diff --git a/packages/notify/test/index.spec.js b/packages/notify/test/index.spec.js new file mode 100644 index 000000000..6191a7311 --- /dev/null +++ b/packages/notify/test/index.spec.js @@ -0,0 +1,49 @@ +import Notify from '../'; +import { transitionStub, later } from '../../../test/utils'; + +transitionStub(); + +test('create a notify', async() => { + // should not cause error when call clear before show notify + Notify.clear(); + + const notify = Notify('test'); + + await later(); + expect(notify.$el.outerHTML).toMatchSnapshot(); +}); + +test('notify disappear', async() => { + const notify = Notify({ + message: 'test', + color: 'red', + background: 'blue', + duration: 10 + }); + + await later(); + expect(notify.$el.outerHTML).toMatchSnapshot(); + + await later(20); + expect(notify.$el.outerHTML).toMatchSnapshot(); + + Notify({ + message: 'text2', + duration: 0 + }); + + await later(); + expect(notify.$el.outerHTML).toMatchSnapshot(); + + Notify.clear(); + await later(); + expect(notify.$el.outerHTML).toMatchSnapshot(); +}); + +test('set default options', () => { + Notify.setDefaultOptions({ duration: 1000 }); + expect(Notify().duration).toEqual(1000); + Notify.resetDefaultOptions(); + expect(Notify().duration).toEqual(3000); + Notify.clear(); +}); diff --git a/packages/notify/zh-CN.md b/packages/notify/zh-CN.md new file mode 100644 index 000000000..8d86d10f5 --- /dev/null +++ b/packages/notify/zh-CN.md @@ -0,0 +1,56 @@ +## Notify 消息提示 + +### 使用指南 +``` javascript +import { Notify } from 'vant'; + +Vue.use(Notify); +``` + +### 代码演示 + +#### 基础用法 + +```js +Notify('通知内容'); +``` + +#### 自定义配置 + +```js +Notify({ + message: '通知内容', + duration: 1000, + background: '#1989fa' +}); +``` + +#### 组件内调用 + +引入 Notify 组件后,会自动在 Vue 的 prototype 上挂载 $notify 方法,便于在组件内调用。 + +```js +export default { + mounted() { + this.$notify('提示文案'); + } +} +``` + +### 方法 + +| 方法名 | 参数 | 返回值 | 介绍 | +|------|------|------|------| +| Notify | `options | message` | notify 实例 | 展示提示 | +| Notify.clear | - | `void` | 关闭提示 | +| Notify.setDefaultOptions | `options` | `void` | 修改默认配置,对所有 Notify 生效 | +| Notify.resetDefaultOptions | - | `void` | 重置默认配置,对所有 Notify 生效 | + +### Options + +| 参数 | 说明 | 类型 | 默认值 | 版本 | +|------|------|------|------|------| +| message | 展示文案 | `String` | - | 1.4.6 | +| duration | 展示时长(ms),值为 0 时,notify 不会消失 | `Number` | `3000` | 1.4.6 | +| color | 字体颜色 | `String` | `#fff` | 1.4.6 | +| background | 背景颜色 | `String` | `#f44` | 1.4.6 | diff --git a/packages/progress/index.vue b/packages/progress/index.vue index 3d4b650ee..07024c535 100644 --- a/packages/progress/index.vue +++ b/packages/progress/index.vue @@ -18,7 +18,7 @@