mirror of
https://github.com/element-plus/element-plus.git
synced 2026-03-13 07:51:17 +08:00
feat: add tag component
This commit is contained in:
committed by
Herrington Darkholme
parent
bb353a1633
commit
4ee1c8b078
@@ -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)
|
||||
}
|
||||
|
||||
85
packages/tag/__tests__/tag.spec.ts
Normal file
85
packages/tag/__tests__/tag.spec.ts
Normal 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);
|
||||
})
|
||||
})
|
||||
48
packages/tag/doc/basic.vue
Normal file
48
packages/tag/doc/basic.vue
Normal 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>
|
||||
5
packages/tag/doc/index.stories.ts
Normal file
5
packages/tag/doc/index.stories.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
export { default as BasicUsage} from './basic.vue'
|
||||
|
||||
export default {
|
||||
title: 'Tag',
|
||||
}
|
||||
5
packages/tag/index.ts
Normal file
5
packages/tag/index.ts
Normal 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
13
packages/tag/package.json
Normal 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"
|
||||
}
|
||||
}
|
||||
|
||||
89
packages/tag/src/index.vue
Normal file
89
packages/tag/src/index.vue
Normal 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>
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
];
|
||||
|
||||
|
||||
Reference in New Issue
Block a user