feat: Tag component

This commit is contained in:
chenjiahan 2020-07-05 16:44:14 +08:00
parent bd5651402a
commit 919161568a
9 changed files with 653 additions and 8 deletions

139
src-next/tag/README.md Normal file
View File

@ -0,0 +1,139 @@
# Tag
### Install
```js
import Vue from 'vue';
import { Tag } from 'vant';
Vue.use(Tag);
```
## Usage
### Basic Usage
```html
<van-tag>Tag</van-tag>
<van-tag type="primary">Tag</van-tag>
<van-tag type="success">Tag</van-tag>
<van-tag type="danger">Tag</van-tag>
<van-tag type="warning">Tag</van-tag>
```
### Round style
```html
<van-tag round>Tag</van-tag>
<van-tag round type="primary">Tag</van-tag>
<van-tag round type="success">Tag</van-tag>
<van-tag round type="danger">Tag</van-tag>
<van-tag round type="warning">Tag</van-tag>
```
### Mark style
```html
<van-tag mark>Tag</van-tag>
<van-tag mark type="primary">Tag</van-tag>
<van-tag mark type="success">Tag</van-tag>
<van-tag mark type="danger">Tag</van-tag>
<van-tag mark type="warning">Tag</van-tag>
```
### Plain style
```html
<van-tag plain>Tag</van-tag>
<van-tag plain type="primary">Tag</van-tag>
<van-tag plain type="success">Tag</van-tag>
<van-tag plain type="danger">Tag</van-tag>
<van-tag plain type="warning">Tag</van-tag>
```
### Custom Color
```html
<van-tag color="#f2826a">Tag</van-tag>
<van-tag color="#f2826a" plain>Tag</van-tag>
<van-tag color="#7232dd">Tag</van-tag>
<van-tag color="#7232dd" plain>Tag</van-tag>
<van-tag color="#ffe1e1" text-color="#ad0000">Tag</van-tag>
```
### Custom Size
```html
<van-tag type="danger">Tag</van-tag>
<van-tag type="danger" size="medium">Tag</van-tag>
<van-tag type="danger" size="large">Tag</van-tag>
```
### Closeable
```html
<van-tag
v-if="show.primary"
closeable
size="medium"
type="primary"
@close="close('primary')"
>
Tag
</van-tag>
<van-tag
v-if="show.success"
closeable
size="medium"
type="success"
@close="close('success')"
>
Tag
</van-tag>
```
```js
export default {
data() {
return {
show: {
primary: true,
success: true,
},
};
},
methods: {
close(type) {
this.show[type] = false;
},
},
};
```
## API
### Props
| Attribute | Description | Type | Default |
| --- | --- | --- | --- |
| type | Type, can be set to `primary` `success` `danger` `warning` | _string_ | `default` |
| size | Size, can be set to `large` `medium` | _string_ | - |
| color | Custom color | _string_ | - |
| plain | Whether to be plain style | _boolean_ | `false` |
| round | Whether to be round style | _boolean_ | `false` |
| mark | Whether to be mark style | _boolean_ | `false` |
| text-color | Text color | _string_ | `white` |
| closeable `v2.2.9` | Whether to be closeable | _boolean_ | `false` |
### Slots
| Name | Description |
| ------- | ------------ |
| default | Default slot |
### Events
| Event | Description | Arguments |
| ----- | ------------------------------- | -------------- |
| click | Triggered when clicked | _event: Event_ |
| close | Triggered when click close icon | - |

View File

@ -0,0 +1,149 @@
# Tag 标记
### 引入
```js
import Vue from 'vue';
import { Tag } from 'vant';
Vue.use(Tag);
```
## 代码演示
### 基础用法
通过`type`属性控制标签颜色,默认为灰色
```html
<van-tag>标签</van-tag>
<van-tag type="primary">标签</van-tag>
<van-tag type="success">标签</van-tag>
<van-tag type="danger">标签</van-tag>
<van-tag type="warning">标签</van-tag>
```
### 圆角样式
通过`round`设置为圆角样式
```html
<van-tag round>标签</van-tag>
<van-tag round type="primary">标签</van-tag>
<van-tag round type="success">标签</van-tag>
<van-tag round type="danger">标签</van-tag>
<van-tag round type="warning">标签</van-tag>
```
### 标记样式
通过`mark`设置为标记样式(半圆角)
```html
<van-tag mark>标签</van-tag>
<van-tag mark type="primary">标签</van-tag>
<van-tag mark type="success">标签</van-tag>
<van-tag mark type="danger">标签</van-tag>
<van-tag mark type="warning">标签</van-tag>
```
### 空心样式
设置`plain`属性设置为空心样式
```html
<van-tag plain>标签</van-tag>
<van-tag plain type="primary">标签</van-tag>
<van-tag plain type="success">标签</van-tag>
<van-tag plain type="danger">标签</van-tag>
<van-tag plain type="warning">标签</van-tag>
```
### 自定义颜色
```html
<van-tag color="#f2826a">标签</van-tag>
<van-tag color="#f2826a" plain>标签</van-tag>
<van-tag color="#7232dd">标签</van-tag>
<van-tag color="#7232dd" plain>标签</van-tag>
<van-tag color="#ffe1e1" text-color="#ad0000">标签</van-tag>
```
### 标签大小
```html
<van-tag type="danger">标签</van-tag>
<van-tag type="danger" size="medium">标签</van-tag>
<van-tag type="danger" size="large">标签</van-tag>
```
### 可关闭标签
添加`closeable`属性表示标签是可关闭的,关闭标签时会触发`close`事件,在`close`事件中可以执行隐藏标签的逻辑
```html
<van-tag
v-if="show.primary"
closeable
size="medium"
type="primary"
@close="close('primary')"
>
标签
</van-tag>
<van-tag
v-if="show.success"
closeable
size="medium"
type="success"
@close="close('success')"
>
标签
</van-tag>
```
```js
export default {
data() {
return {
show: {
primary: true,
success: true,
},
};
},
methods: {
close(type) {
this.show[type] = false;
},
},
};
```
## API
### Props
| 参数 | 说明 | 类型 | 默认值 |
| --- | --- | --- | --- |
| type | 类型,可选值为`primary` `success` `danger` `warning` | _string_ | `default` |
| size | 大小, 可选值为`large` `medium` | _string_ | - |
| color | 标签颜色 | _string_ | - |
| plain | 是否为空心样式 | _boolean_ | `false` |
| round | 是否为圆角样式 | _boolean_ | `false` |
| mark | 是否为标记样式 | _boolean_ | `false` |
| text-color | 文本颜色,优先级高于`color`属性 | _string_ | `white` |
| closeable `v2.2.9` | 是否为可关闭标签 | _boolean_ | `false` |
### Slots
| 名称 | 说明 |
| ------- | ------------ |
| default | 标签显示内容 |
### Events
| 事件名 | 说明 | 回调参数 |
| ------ | -------------- | -------------- |
| click | 点击时触发 | _event: Event_ |
| close | 关闭标签时触发 | - |

126
src-next/tag/demo/index.vue Normal file
View File

@ -0,0 +1,126 @@
<template>
<demo-section>
<demo-block :title="t('basicUsage')">
<van-tag>{{ t('tag') }}</van-tag>
<van-tag type="primary">{{ t('tag') }}</van-tag>
<van-tag type="success">{{ t('tag') }}</van-tag>
<van-tag type="danger">{{ t('tag') }}</van-tag>
<van-tag type="warning">{{ t('tag') }}</van-tag>
</demo-block>
<demo-block :title="t('round')">
<van-tag round>{{ t('tag') }}</van-tag>
<van-tag round type="primary">{{ t('tag') }}</van-tag>
<van-tag round type="success">{{ t('tag') }}</van-tag>
<van-tag round type="danger">{{ t('tag') }}</van-tag>
<van-tag round type="warning">{{ t('tag') }}</van-tag>
</demo-block>
<demo-block :title="t('mark')">
<van-tag mark>{{ t('tag') }}</van-tag>
<van-tag mark type="primary">{{ t('tag') }}</van-tag>
<van-tag mark type="success">{{ t('tag') }}</van-tag>
<van-tag mark type="danger">{{ t('tag') }}</van-tag>
<van-tag mark type="warning">{{ t('tag') }}</van-tag>
</demo-block>
<demo-block :title="t('plain')">
<van-tag plain>{{ t('tag') }}</van-tag>
<van-tag plain type="primary">{{ t('tag') }}</van-tag>
<van-tag plain type="success">{{ t('tag') }}</van-tag>
<van-tag plain type="danger">{{ t('tag') }}</van-tag>
<van-tag plain type="warning">{{ t('tag') }}</van-tag>
</demo-block>
<demo-block :title="t('customColor')">
<van-tag color="#f2826a">{{ t('tag') }}</van-tag>
<van-tag color="#f2826a" plain>{{ t('tag') }}</van-tag>
<van-tag color="#7232dd">{{ t('tag') }}</van-tag>
<van-tag color="#7232dd" plain>{{ t('tag') }}</van-tag>
<van-tag color="#ffe1e1" text-color="#ad0000">{{ t('tag') }}</van-tag>
</demo-block>
<demo-block :title="t('customSize')">
<van-tag type="success">{{ t('tag') }}</van-tag>
<van-tag type="success" size="medium">{{ t('tag') }}</van-tag>
<van-tag type="success" size="large">{{ t('tag') }}</van-tag>
</demo-block>
<demo-block :title="t('closeable')">
<van-tag
v-if="show.primary"
size="medium"
closeable
type="primary"
@close="close('primary')"
>
{{ t('tag') }}
</van-tag>
<van-tag
v-if="show.success"
size="medium"
closeable
type="success"
@close="close('success')"
>
{{ t('tag') }}
</van-tag>
</demo-block>
</demo-section>
</template>
<script>
export default {
i18n: {
'zh-CN': {
plain: '空心样式',
round: '圆角样式',
mark: '标记样式',
closeable: '可关闭标签',
customColor: '自定义颜色',
customSize: '标签大小',
},
'en-US': {
plain: 'Plain style',
round: 'Round style',
mark: 'Mark style',
closeable: 'Closeable',
customColor: 'Custom Color',
customSize: 'Custom Size',
},
},
data() {
return {
show: {
primary: true,
success: true,
},
};
},
methods: {
close(tag) {
this.show[tag] = false;
},
},
};
</script>
<style lang="less">
@import '../../style/var';
.demo-tag {
background-color: @white;
.van-tag {
&:first-of-type {
margin-left: @padding-md;
}
}
.van-tag + .van-tag {
margin-left: @padding-xs;
}
}
</style>

66
src-next/tag/index.js Normal file
View File

@ -0,0 +1,66 @@
// Utils
import { createNamespace } from '../utils';
import { BORDER_SURROUND } from '../utils/constant';
// Components
import Icon from '../icon';
const [createComponent, bem] = createNamespace('tag');
export default createComponent({
props: {
size: String,
mark: Boolean,
color: String,
plain: Boolean,
round: Boolean,
textColor: String,
closeable: Boolean,
type: {
type: String,
default: 'default',
},
},
setup(props, { slots, emit }) {
return function () {
const { type, mark, plain, color, round, size } = props;
const key = plain ? 'color' : 'backgroundColor';
const style = { [key]: color };
if (props.textColor) {
style.color = props.textColor;
}
const classes = { mark, plain, round };
if (size) {
classes[size] = size;
}
const CloseIcon = props.closeable && (
<Icon
name="cross"
class={bem('close')}
onClick={(event) => {
event.stopPropagation();
emit('close');
}}
/>
);
return (
<transition name={props.closeable ? 'van-fade' : null}>
<span
key="content"
style={style}
class={[bem([classes, type]), { [BORDER_SURROUND]: plain }]}
>
{slots.default?.()}
{CloseIcon}
</span>
</transition>
);
};
},
});

90
src-next/tag/index.less Normal file
View File

@ -0,0 +1,90 @@
@import '../style/var';
.van-tag {
display: inline-flex;
align-items: center;
padding: @tag-padding;
color: @tag-text-color;
font-size: @tag-font-size;
line-height: normal;
border-radius: @tag-border-radius;
&::after {
border-color: currentColor;
border-radius: @tag-border-radius * 2;
}
&--default {
background-color: @tag-default-color;
&.van-tag--plain {
color: @tag-default-color;
}
}
&--danger {
background-color: @tag-danger-color;
&.van-tag--plain {
color: @tag-danger-color;
}
}
&--primary {
background-color: @tag-primary-color;
&.van-tag--plain {
color: @tag-primary-color;
}
}
&--success {
background-color: @tag-success-color;
&.van-tag--plain {
color: @tag-success-color;
}
}
&--warning {
background-color: @tag-warning-color;
&.van-tag--plain {
color: @tag-warning-color;
}
}
&--plain {
background-color: @tag-plain-background-color;
}
&--mark {
padding-right: 0.7em;
&,
&::after {
border-radius: 0 @tag-round-border-radius @tag-round-border-radius 0;
}
}
&--round {
&,
&::after {
border-radius: @tag-round-border-radius;
}
}
&--medium {
font-size: @tag-medium-font-size;
}
&--large {
font-size: @tag-large-font-size;
}
&__close {
min-width: 1em;
margin-left: 2px;
cursor: pointer;
}
}

View File

@ -0,0 +1,17 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`renders demo correctly 1`] = `
<div>
<div><span class="van-tag van-tag--default">标签</span> <span class="van-tag van-tag--primary">标签</span> <span class="van-tag van-tag--success">标签</span> <span class="van-tag van-tag--danger">标签</span> <span class="van-tag van-tag--warning">标签</span></div>
<div><span class="van-tag van-tag--round van-tag--default">标签</span> <span class="van-tag van-tag--round van-tag--primary">标签</span> <span class="van-tag van-tag--round van-tag--success">标签</span> <span class="van-tag van-tag--round van-tag--danger">标签</span> <span class="van-tag van-tag--round van-tag--warning">标签</span></div>
<div><span class="van-tag van-tag--mark van-tag--default">标签</span> <span class="van-tag van-tag--mark van-tag--primary">标签</span> <span class="van-tag van-tag--mark van-tag--success">标签</span> <span class="van-tag van-tag--mark van-tag--danger">标签</span> <span class="van-tag van-tag--mark van-tag--warning">标签</span></div>
<div><span class="van-tag van-tag--plain van-tag--default van-hairline--surround">标签</span> <span class="van-tag van-tag--plain van-tag--primary van-hairline--surround">标签</span> <span class="van-tag van-tag--plain van-tag--success van-hairline--surround">标签</span> <span class="van-tag van-tag--plain van-tag--danger van-hairline--surround">标签</span> <span class="van-tag van-tag--plain van-tag--warning van-hairline--surround">标签</span></div>
<div><span class="van-tag van-tag--default" style="background-color: rgb(242, 130, 106);">标签</span> <span class="van-tag van-tag--plain van-tag--default van-hairline--surround" style="color: rgb(242, 130, 106);">标签</span> <span class="van-tag van-tag--default" style="background-color: rgb(114, 50, 221);">标签</span> <span class="van-tag van-tag--plain van-tag--default van-hairline--surround" style="color: rgb(114, 50, 221);">标签</span> <span class="van-tag van-tag--default" style="background-color: rgb(255, 225, 225); color: rgb(173, 0, 0);">标签</span></div>
<div><span class="van-tag van-tag--success">标签</span> <span class="van-tag van-tag--medium van-tag--success">标签</span> <span class="van-tag van-tag--large van-tag--success">标签</span></div>
<div><span class="van-tag van-tag--medium van-tag--primary" name="van-fade">
标签
<i class="van-icon van-icon-cross van-tag__close"><!----></i></span> <span class="van-tag van-tag--medium van-tag--success" name="van-fade">
标签
<i class="van-icon van-icon-cross van-tag__close"><!----></i></span></div>
</div>
`;

View File

@ -0,0 +1,4 @@
import Demo from '../demo';
import { snapshotDemo } from '../../../test/demo';
snapshotDemo(Demo);

View File

@ -0,0 +1,54 @@
import Tag from '..';
import { mount } from '../../../test';
test('click event', () => {
const click = jest.fn();
const wrapper = mount(Tag, {
context: {
on: {
click,
},
},
});
wrapper.trigger('click');
expect(click).toHaveBeenCalledTimes(1);
});
test('close event', () => {
const close = jest.fn();
const wrapper = mount(Tag, {
propsData: {
closeable: true,
},
context: {
on: {
close,
},
},
});
wrapper.find('.van-tag__close').trigger('click');
expect(close).toHaveBeenCalledTimes(1);
});
test('should not trigger click event when close', () => {
const close = jest.fn();
const click = jest.fn();
const wrapper = mount(Tag, {
propsData: {
closeable: true,
},
context: {
on: {
close,
click,
},
},
});
wrapper.find('.van-tag__close').trigger('click');
expect(close).toHaveBeenCalledTimes(1);
expect(click).toHaveBeenCalledTimes(0);
});

View File

@ -277,10 +277,10 @@ module.exports = {
// path: 'swipe',
// title: 'Swipe 轮播',
// },
// {
// path: 'tag',
// title: 'Tag 标记',
// },
{
path: 'tag',
title: 'Tag 标记',
},
],
},
{
@ -611,10 +611,10 @@ module.exports = {
// path: 'swipe',
// title: 'Swipe',
// },
// {
// path: 'tag',
// title: 'Tag',
// },
{
path: 'tag',
title: 'Tag',
},
],
},
{