feat: add tag component

This commit is contained in:
bastarder
2020-07-24 15:34:03 +08:00
committed by Herrington Darkholme
parent bb353a1633
commit 4ee1c8b078
10 changed files with 258 additions and 3 deletions

View File

@@ -1,12 +1,14 @@
import type { App } from 'vue'
import ElButton from '@element-plus/button'
import ElBadge from '@element-plus/badge'
import ElTag from '@element-plus/tag'
export {
ElButton, ElBadge,
ElButton, ElBadge, ElTag
}
export default function install(app: App) {
ElButton(app)
ElBadge(app)
ElTag(app)
}

View File

@@ -0,0 +1,85 @@
import {mount} from '@vue/test-utils'
import Tag from '../src/index.vue'
const AXIOM = 'Rem is the best girl'
describe('Tag.vue', () => {
test('render text & class', () => {
const instance = mount(Tag, {
slots: {
default: AXIOM
},
})
expect(instance.text()).toEqual(AXIOM)
const vm = instance.vm;
expect(vm.$el.classList.contains('el-tag')).toEqual(true);
expect(vm.$el.classList.contains('el-tag__close')).toEqual(false);
expect(vm.$el.classList.contains('is-hit')).toEqual(false);
expect(vm.$el.classList.contains('md-fade-center')).toEqual(false);
})
test('type', () => {
const instance = mount(Tag, {
props: {
type: 'primary'
},
})
const vm = instance.vm;
expect(vm.$el.classList.contains('el-tag--primary')).toEqual(true);
})
test('hit', () => {
const instance = mount(Tag, {
props: {
hit: true
},
})
const vm = instance.vm;
expect(vm.$el.classList.contains('is-hit')).toEqual(true);
})
test('closeable', () => {
const instance = mount(Tag, {
props: {
closable: true,
},
})
const closeBtn = instance.find('.el-tag .el-tag__close');
expect(closeBtn.exists()).toBe(true);
})
test('closeTransition', () => {
const instance = mount(Tag, {
props: {
closeTransition: true,
},
})
const vm = instance.vm;
expect(vm.$el.classList.contains('md-fade-center')).toEqual(false);
})
test('color', () => {
const instance = mount(Tag, {
props: {
color: 'rgb(0, 0, 0)',
},
})
const vm = instance.vm;
expect(vm.$el.style.backgroundColor).toEqual('rgb(0, 0, 0)');
})
test('theme', () => {
const instance = mount(Tag, {
props: {
effect: 'dark',
},
})
const vm = instance.vm;
const el = vm.$el;
expect(el.className.indexOf('el-tag--dark') > -1).toEqual(true);
expect(el.className.indexOf('el-tag--light') > -1).toEqual(false);
expect(el.className.indexOf('el-tag--plain') > -1).toEqual(false);
})
})

View File

@@ -0,0 +1,48 @@
<template>
<el-tag closable>默认标签</el-tag>
<el-tag size="medium" closable>中等标签</el-tag>
<el-tag size="small" closable>小型标签</el-tag>
<el-tag size="mini" closable>超小标签</el-tag>
<div class="tag-group">
<span class="tag-group__title">Dark</span>
<el-tag
v-for="item in items"
:key="item.label"
:type="item.type"
effect="dark">
{{ item.label }}
</el-tag>
</div>
<div class="tag-group">
<span class="tag-group__title">Plain</span>
<el-tag
v-for="item in items"
:key="item.label"
:type="item.type"
effect="plain">
{{ item.label }}
</el-tag>
</div>
</template>
<style scoped>
.el-tag {
margin: 6px;
}
</style>
<script>
export default {
data() {
return {
items: [
{ type: '', label: '标签一' },
{ type: 'success', label: '标签二' },
{ type: 'info', label: '标签三' },
{ type: 'danger', label: '标签四' },
{ type: 'warning', label: '标签五' }
]
}
}
}
</script>

View File

@@ -0,0 +1,5 @@
export { default as BasicUsage} from './basic.vue'
export default {
title: 'Tag',
}

5
packages/tag/index.ts Normal file
View File

@@ -0,0 +1,5 @@
import { App } from 'vue'
import Tag from './src/index.vue'
export default (app: App) => {
app.component(Tag.name, Tag)
}

13
packages/tag/package.json Normal file
View File

@@ -0,0 +1,13 @@
{
"name": "@element-plus/tag",
"version": "0.0.0",
"main": "dist/index.js",
"license": "MIT",
"dependencies": {
"vue": "^3.0.0-rc.1"
},
"devDependencies": {
"@vue/test-utils": "^2.0.0-beta.0"
}
}

View File

@@ -0,0 +1,89 @@
<template>
<span
v-if="!disableTransitions"
:class="classes"
:style="{ backgroundColor: color }"
@click="handleClick"
>
<slot />
<i
v-if="closable"
class="el-tag__close el-icon-close"
@click="handleClose"
></i>
</span>
<transition v-else name="el-zoom-in-center">
<span
:class="classes"
:style="{ backgroundColor: color }"
@click="handleClick"
>
<slot />
<i
v-if="closable"
class="el-tag__close el-icon-close"
@click="handleClose"
></i>
</span>
</transition>
</template>
<script lang='ts'>
import { h, computed } from 'vue';
const ELEMENT: {
size?: number;
} = {}
export default {
name: "ElTag",
props: {
closable: Boolean,
type: String,
hit: Boolean,
disableTransitions: Boolean,
color: String,
size: String,
effect: {
type: String,
default: 'light',
validator: (val: string): boolean => {
return ['dark', 'light', 'plain'].indexOf(val) !== -1;
}
},
},
setup(props, ctx) {
// computed
const tagSize = computed(() => {
// todo ctx.$ELEMENT
return props.size || (ELEMENT || {}).size
})
const classes = computed(() => {
const { type, hit, effect } = props;
return [
"el-tag",
type ? `el-tag--${type}` : "",
tagSize ? `el-tag--${tagSize.value}` : "",
effect ? `el-tag--${effect}` : "",
hit && "is-hit",
]
})
// methods
const handleClose = (event) => {
event.stopPropagation();
ctx.emit('close', event);
}
const handleClick = (event) => {
ctx.emit('close', event);
}
return {
tagSize,
classes,
handleClose,
handleClick,
}
},
};
</script>

View File

@@ -3,7 +3,8 @@
<router-view />
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/button">Button</router-link>
<router-link to="/button">Button</router-link> |
<router-link to="/tag">Tag</router-link>
</div>
</div>
</template>

View File

@@ -1,4 +1,6 @@
import ButtonInstall from '@element-plus/button/index'
import TagInstall from '@element-plus/tag/index'
export const installAll = (app) => {
ButtonInstall(app)
ButtonInstall(app);
TagInstall(app);
}

View File

@@ -1,10 +1,15 @@
import { RouteRecordRaw, createRouter, createWebHistory } from "vue-router";
import Button from "@element-plus/button/doc/index.vue";
import Tag from "@element-plus/tag/doc/index.vue";
const routes: Array<RouteRecordRaw> = [
{
path: "/button",
component: Button
},
{
path: "/tag",
component: Tag
}
];