From 2a41dcf58e0924736bd0a5f5d547ed946de9dbae Mon Sep 17 00:00:00 2001 From: chenjiahan Date: Mon, 6 Jul 2020 14:12:22 +0800 Subject: [PATCH] feat: Overlay component --- src-next/overlay/README.md | 79 +++++++++++++++++++++++ src-next/overlay/README.zh-CN.md | 85 +++++++++++++++++++++++++ src-next/overlay/demo/index.vue | 72 +++++++++++++++++++++ src-next/overlay/index.js | 49 +++++++++++++++ src-next/overlay/index.less | 11 ++++ src-next/overlay/test/demo.spec.js | 4 ++ src-next/overlay/test/index.spec.js | 98 +++++++++++++++++++++++++++++ 7 files changed, 398 insertions(+) create mode 100644 src-next/overlay/README.md create mode 100644 src-next/overlay/README.zh-CN.md create mode 100644 src-next/overlay/demo/index.vue create mode 100644 src-next/overlay/index.js create mode 100644 src-next/overlay/index.less create mode 100644 src-next/overlay/test/demo.spec.js create mode 100644 src-next/overlay/test/index.spec.js diff --git a/src-next/overlay/README.md b/src-next/overlay/README.md new file mode 100644 index 000000000..31fba67b1 --- /dev/null +++ b/src-next/overlay/README.md @@ -0,0 +1,79 @@ +# Overlay + +### Install + +```js +import Vue from 'vue'; +import { Overlay } from 'vant'; + +Vue.use(Overlay); +``` + +## Usage + +### Basic Usage + +```html + + +``` + +```js +export default { + data() { + return { + show: false + } + } +}, +``` + +### Embedded Content + +```html + +
+
+
+ + + +``` + +## API + +### Props + +| Attribute | Description | Type | Default | +| --- | --- | --- | --- | +| show | Whether to show overlay | _boolean_ | `false` | +| z-index | z-index | _number \| string_ | `1` | +| duration | Animation duration | _number \| string_ | `0.3` | +| class-name | ClassName | _string_ | - | +| custom-class `v2.2.5` | Custom style | _object_ | - | +| lock-scroll `v2.6.2` | Whether to lock background scroll | _boolean_ | `true` | + +### Events + +| Event | Description | Arguments | +| ----- | ---------------------- | -------------- | +| click | Triggered when clicked | _event: Event_ | + +### Slots + +| Name | Description | +| ---------------- | ------------ | +| default `v2.2.5` | Default slot | diff --git a/src-next/overlay/README.zh-CN.md b/src-next/overlay/README.zh-CN.md new file mode 100644 index 000000000..9d70faa1b --- /dev/null +++ b/src-next/overlay/README.zh-CN.md @@ -0,0 +1,85 @@ +# Overlay 遮罩层 + +### 介绍 + +创建一个遮罩层,用于强调特定的页面元素,并阻止用户进行其他操作 + +### 引入 + +```js +import Vue from 'vue'; +import { Overlay } from 'vant'; + +Vue.use(Overlay); +``` + +## 代码演示 + +### 基础用法 + +```html + + +``` + +```js +export default { + data() { + return { + show: false + } + } +}, +``` + +### 嵌入内容 + +通过默认插槽可以在遮罩层上嵌入任意内容 + +```html + +
+
+
+ + + +``` + +## API + +### Props + +| 参数 | 说明 | 类型 | 默认值 | +| --- | --- | --- | --- | +| show | 是否展示遮罩层 | _boolean_ | `false` | +| z-index | z-index 层级 | _number \| string_ | `1` | +| duration | 动画时长,单位秒 | _number \| string_ | `0.3` | +| class-name | 自定义类名 | _string_ | - | +| custom-style `v2.2.5` | 自定义样式 | _object_ | - | +| lock-scroll `v2.6.2` | 是否锁定背景滚动,锁定时蒙层里的内容也将无法滚动 | _boolean_ | `true` | + +### Events + +| 事件名 | 说明 | 回调参数 | +| ------ | ---------- | -------------- | +| click | 点击时触发 | _event: Event_ | + +### Slots + +| 名称 | 说明 | +| ---------------- | ---------------------------------- | +| default `v2.0.5` | 默认插槽,用于在遮罩层上方嵌入内容 | diff --git a/src-next/overlay/demo/index.vue b/src-next/overlay/demo/index.vue new file mode 100644 index 000000000..a919f4f8c --- /dev/null +++ b/src-next/overlay/demo/index.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/src-next/overlay/index.js b/src-next/overlay/index.js new file mode 100644 index 000000000..87da81781 --- /dev/null +++ b/src-next/overlay/index.js @@ -0,0 +1,49 @@ +import { Transition } from 'vue'; +import { createNamespace, isDef, noop } from '../utils'; +import { preventDefault } from '../utils/dom/event'; + +const [createComponent, bem] = createNamespace('overlay'); + +function preventTouchMove(event) { + preventDefault(event, true); +} + +export default createComponent({ + props: { + show: Boolean, + zIndex: [Number, String], + duration: [Number, String], + className: null, + customStyle: Object, + lockScroll: { + type: Boolean, + default: true, + }, + }, + + setup(props, { slots }) { + return function () { + const style = { + zIndex: props.zIndex, + ...props.customStyle, + }; + + if (isDef(props.duration)) { + style.animationDuration = `${props.duration}s`; + } + + return ( + +
+ {slots.default?.()} +
+
+ ); + }; + }, +}); diff --git a/src-next/overlay/index.less b/src-next/overlay/index.less new file mode 100644 index 000000000..3b547cff9 --- /dev/null +++ b/src-next/overlay/index.less @@ -0,0 +1,11 @@ +@import '../style/var'; + +.van-overlay { + position: fixed; + top: 0; + left: 0; + z-index: @overlay-z-index; + width: 100%; + height: 100%; + background-color: @overlay-background-color; +} diff --git a/src-next/overlay/test/demo.spec.js b/src-next/overlay/test/demo.spec.js new file mode 100644 index 000000000..5c70922b5 --- /dev/null +++ b/src-next/overlay/test/demo.spec.js @@ -0,0 +1,4 @@ +import Demo from '../demo'; +import { snapshotDemo } from '../../../test/demo'; + +snapshotDemo(Demo); diff --git a/src-next/overlay/test/index.spec.js b/src-next/overlay/test/index.spec.js new file mode 100644 index 000000000..093aa569c --- /dev/null +++ b/src-next/overlay/test/index.spec.js @@ -0,0 +1,98 @@ +import { mount } from '../../../test'; +import Overlay from '..'; + +test('z-index prop', () => { + const wrapper = mount(Overlay, { + propsData: { + show: true, + zIndex: 99, + }, + }); + + expect(wrapper).toMatchSnapshot(); +}); + +test('class-name prop', () => { + const wrapper = mount(Overlay, { + propsData: { + show: true, + className: 'my-overlay', + }, + }); + + expect(wrapper).toMatchSnapshot(); +}); + +test('custom style prop', () => { + const wrapper = mount(Overlay, { + propsData: { + show: true, + customStyle: { + backgroundColor: 'red', + }, + }, + }); + + expect(wrapper).toMatchSnapshot(); +}); + +test('duration prop', () => { + const wrapper = mount(Overlay, { + propsData: { + show: true, + duration: 1, + }, + }); + + expect(wrapper).toMatchSnapshot(); +}); + +test('click event', () => { + const onClick = jest.fn(); + const wrapper = mount(Overlay, { + context: { + on: { + click: onClick, + }, + }, + }); + + wrapper.trigger('click'); + expect(onClick).toHaveBeenCalledTimes(1); +}); + +test('default slot', () => { + const wrapper = mount(Overlay, { + scopedSlots: { + default: () => 'Custom Default', + }, + }); + + expect(wrapper).toMatchSnapshot(); +}); + +test('lock-scroll prop', () => { + const onTouchMove = jest.fn(); + const wrapper = mount({ + template: ` +
+ +
+ `, + data() { + return { + lockScroll: true, + }; + }, + methods: { + onTouchMove, + }, + }); + + wrapper.find('.van-overlay').trigger('touchmove'); + expect(onTouchMove).toHaveBeenCalledTimes(0); + + wrapper.setData({ lockScroll: false }); + wrapper.find('.van-overlay').trigger('touchmove'); + expect(onTouchMove).toHaveBeenCalledTimes(1); +});