Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 25 additions & 29 deletions packages/devui-vue/devui/tag/__tests__/tag.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,39 +9,39 @@ describe('tag test', () => {
it('props type', () => {
const wrapper = mount(Tag, {
propsData: {
type: 'primary'
}
type: 'primary',
},
});
expect(wrapper.find('.devui-tag span').classes()).toContain('devui-tag-primary');
expect(wrapper.find('.devui-tag .devui-tag-item').classes()).toContain('devui-tag-primary');
});
it('props color', () => {
const wrapper = mount(Tag, {
propsData: {
color: 'red-w98' // #f66f6a rgb(246, 111, 106)
}
color: 'red-w98', // #f66f6a rgb(246, 111, 106)
},
});
expect(wrapper.find('.devui-tag span').attributes('style')).toContain('rgb(246, 111, 106)');
expect(wrapper.find('.devui-tag .devui-tag-item').attributes('style')).toContain('rgb(246, 111, 106)');
});
it('props color custom', () => {
const wrapper = mount(Tag, {
propsData: {
color: '#aa2116' // rgb(170, 33, 22)
}
color: '#aa2116', // rgb(170, 33, 22)
},
});
expect(wrapper.find('.devui-tag span').attributes('style')).toContain('rgb(170, 33, 22)');
expect(wrapper.find('.devui-tag .devui-tag-item').attributes('style')).toContain('rgb(170, 33, 22)');
});
it('props titleContent', () => {
const titleContent = 'tagTitle test';
const wrapper = mount(Tag, {
props: { titleContent }
props: { titleContent },
});
expect(wrapper.get('.devui-tag span').attributes('title')).toBe(titleContent);
expect(wrapper.get('.devui-tag .devui-tag-item').attributes('title')).toBe(titleContent);
});
it('props deletable show', async () => {
const wrapper = mount(Tag, {
propsData: {
deletable: false
}
deletable: false,
},
});
expect(wrapper.find('.remove-button').exists()).toBeFalsy();
await wrapper.setProps({ deletable: true });
Expand All @@ -50,8 +50,8 @@ describe('tag test', () => {
it('props deletable hide', async () => {
const wrapper = mount(Tag, {
propsData: {
deletable: true
}
deletable: true,
},
});
const btn = wrapper.find('.remove-button');
expect(btn.exists()).toBeTruthy();
Expand All @@ -61,8 +61,8 @@ describe('tag test', () => {
it('event tagDelete', async () => {
const wrapper = mount(Tag, {
propsData: {
deletable: true
}
deletable: true,
},
});
await wrapper.find('.remove-button').trigger('click');
expect(wrapper.emitted('tagDelete').length).toBeGreaterThan(0);
Expand All @@ -71,16 +71,12 @@ describe('tag test', () => {
it('props checked', async () => {
const wrapper = mount(Tag, {
propsData: {
type: 'primary' // 对应颜色:rgb(94, 124, 224)
}
color: 'red-w98', // 对应颜色:rgb(246, 111, 106)
},
});
expect(wrapper.find('.devui-tag span').attributes('style')).toContain(
'color: rgb(94, 124, 224);'
);
expect(wrapper.find('.devui-tag .devui-tag-item').attributes('style')).toContain('color: rgb(246, 111, 106);');
await wrapper.setProps({ checked: true });
expect(wrapper.find('.devui-tag span').attributes('style')).toContain(
'background-color: rgb(94, 124, 224);'
);
expect(wrapper.find('.devui-tag .devui-tag-item').attributes('style')).toContain('background-color: rgb(246, 111, 106);');
expect(wrapper.emitted('checkedChange').length).toBeGreaterThan(0);
});
it('event checkedChange', async () => {
Expand All @@ -101,16 +97,16 @@ describe('tag test', () => {
it('slot default string', async () => {
const wrapper = mount(Tag, {
slots: {
default: 'default slot test'
}
default: 'default slot test',
},
});
expect(wrapper.text()).toContain('default slot test');
});
it('slot default component', async () => {
const wrapper = mount(Tag, {
slots: {
default: ['<d-icon name="like"></d-icon>', 'icon component test']
}
default: ['<d-icon name="like"></d-icon>', 'icon component test'],
},
});
expect(wrapper.find('i').classes()).toContain('icon-like');
});
Expand Down
11 changes: 4 additions & 7 deletions packages/devui-vue/devui/tag/index.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,14 @@
import type { App } from 'vue';
import Tag from './src/tag';

Tag.install = function (app: App): void {
app.component(Tag.name, Tag);
};
export * from './src/tag-types';

export { Tag };

export default {
title: 'Tag 标签',
category: '数据展示',
status: '70%', // TODO: 组件若开发完成则填入"已完成",并删除该注释
status: '100%',
install(app: App): void {
app.use(Tag as any);
}
app.component(Tag.name, Tag);
},
};
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { computed } from 'vue';
import { tagProps, TagProps } from '../tag-types';
import type { ComputedRef } from 'vue';
import { TagProps } from '../tag-types';

export default function (props: TagProps) {
export default function (props: TagProps): ComputedRef<string> {
return computed(() => {
const { type, color, deletable } = props;
return `devui-tag-item devui-tag-${type || (color ? 'colorful' : '') || 'default'}${deletable ? ' devui-tag-deletable' : ''}`;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { computed } from 'vue';
import type { ComputedRef } from 'vue';
import { TagProps } from '../tag-types';

export default function (props: TagProps) {
export default function (props: TagProps): ComputedRef<string> {
return computed(() => {
const { color, type } = props;
const typeMap = {
Expand Down
32 changes: 14 additions & 18 deletions packages/devui-vue/devui/tag/src/tag.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { defineComponent, toRefs, ref, watch, onUnmounted } from 'vue';
import { tagProps, TagProps } from './tag-types';
import { useClass, useColor } from './hooks';
import { useClass, useColor } from './composables';
import './tag.scss';
// 类型声明

export default defineComponent({
name: 'DTag',
Expand All @@ -15,48 +14,45 @@ export default defineComponent({
const tagTitle = titleContent.value || '';
const isDefaultTag = () => !type.value && !color.value;
const isShow = ref(true);
// 子组件的点击事件
const handleClick = () => {
emit('click');

const handleClick = (e: MouseEvent) => {
emit('click', e);
};
const handleDelete = () => {
const handleDelete = (e: MouseEvent) => {
isShow.value = false;
emit('tagDelete');
emit('tagDelete', e);
};
const closeIconEl = () => {
return deletable.value ? (
<a class='remove-button' onClick={handleDelete}>
<a class="remove-button" onClick={handleDelete}>
{isDefaultTag() ? (
<d-icon size='12px' name='error-o' color='#adb0b8' />
<d-icon size="12px" name="error-o" color="#adb0b8" />
) : (
<d-icon size='12px' name='close' color={themeColor.value} />
<d-icon size="12px" name="close" color={themeColor.value} />
)}
</a>
) : null;
};
// tag 的 check 状态改变时触发的事件checkedChange
const unWatch = watch(checked, (newVal) => {
console.log('checkedChange');

emit('checkedChange', newVal);
});
onUnmounted(() => unWatch());

return () =>
isShow.value && (
<div class='devui-tag' onClick={handleClick} v-show={isShow.value}>
<div class="devui-tag" onClick={handleClick} v-show={isShow.value}>
<span
class={tagClass.value}
style={{
display: 'block',
color: checked.value ? '#fff' : themeColor.value,
backgroundColor: checked.value ? themeColor.value : !color.value ? '' : 'var(--devui-base-bg, #ffffff)'
backgroundColor: checked.value ? themeColor.value : !color.value ? '' : 'var(--devui-base-bg, #ffffff)',
}}
title={tagTitle}
>
title={tagTitle}>
{slots.default?.()}
{closeIconEl()}
</span>
</div>
);
}
},
});