feat: add alert

This commit is contained in:
homer 2020-08-17 22:23:45 +08:00 committed by jeremywu
parent 10394abde0
commit 54b5d94e47
9 changed files with 248 additions and 1924 deletions

View File

@ -0,0 +1,73 @@
import { mount } from '@vue/test-utils'
import Alert from '../src/index.vue'
const AXIOM = 'Rem is the best girl'
describe('Alert.vue', () => {
test('render test & class', () => {
const wrapper = mount(Alert, {
props: {
title: AXIOM,
showIcon: true,
},
})
expect(wrapper.find('.el-alert__title').text()).toEqual(AXIOM)
expect(wrapper.find('.el-alert').classes()).toContain('el-alert--info')
})
test('type', () => {
const wrapper = mount(Alert, {
props: {
title: 'test',
type: 'success',
showIcon: true,
},
})
expect(wrapper.find('.el-alert').classes()).toContain('el-alert--success')
expect(wrapper.find('.el-alert__icon').classes()).toContain('el-icon-success')
})
test('description', () => {
const wrapper = mount(Alert, {
props: {
title: 'Dorne',
description: AXIOM,
showIcon: true,
},
})
expect(wrapper.find('.el-alert__description').text()).toEqual(AXIOM)
})
test('theme', () => {
const wrapper = mount(Alert, {
props: {
title: 'test',
effect: 'dark',
},
})
expect(wrapper.find('.el-alert').classes()).toContain('is-dark')
})
test('title slot', () => {
const wrapper = mount(Alert, {
slots: {
title: AXIOM,
},
})
expect(wrapper.find('.el-alert__title').text()).toEqual(AXIOM)
})
test('close', async () => {
const wrapper = mount(Alert, {
props: {
closeText: 'close',
},
})
const closeBtn = wrapper.find('.el-alert__closebtn')
expect(closeBtn.exists()).toBe(true)
await closeBtn.trigger('click')
expect(wrapper.emitted()).toBeDefined()
})
})

View File

@ -0,0 +1,51 @@
<template>
<div>
<div>
<el-alert
title="success alert"
type="success"
/>
<el-alert
title="info alert"
type="info"
/>
<el-alert
title="warning alert"
type="warning"
/>
<el-alert
title="error alert"
type="error"
/>
</div>
<div>
<el-alert
title="success alert"
type="success"
show-icon
/>
<el-alert
title="info alert"
type="info"
effect="dark"
/>
<el-alert
title="warning alert"
type="warning"
:closable="false"
/>
<el-alert
title="error alert"
type="error"
center
/>
</div>
</div>
</template>
<style scoped>
.el-alert {
margin: 6px;
}
</style>

View File

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

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

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

View File

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

View File

@ -0,0 +1,98 @@
<template>
<transition name="el-alert-fade">
<div
v-show="visible"
class="el-alert"
:class="[typeClass, center ? 'is-center' : '', 'is-' + effect]"
role="alert"
>
<i v-if="showIcon" class="el-alert__icon" :class="[ iconClass, isBigIcon ]"></i>
<div class="el-alert__content">
<span v-if="title || $slots.title" class="el-alert__title" :class="[ isBoldTitle ]">
<slot name="title">{{ title }}</slot>
</span>
<p class="el-alert__description">
<slot>
{{ description }}
</slot>
</p>
<i
v-if="closable"
class="el-alert__closebtn"
:class="{ 'is-customed': closeText !== '', 'el-icon-close': closeText === '' }"
@click="close"
>
{{ closeText }}
</i>
</div>
</div>
</transition>
</template>
<script lang='ts'>
import { defineComponent, computed, ref, PropType } from 'vue'
const TYPE_CLASSES_MAP = {
'success': 'el-icon-success',
'warning': 'el-icon-warning',
'error': 'el-icon-error',
}
export default defineComponent({
name: 'ElAlert',
props: {
title: {
type: String,
default: '',
},
description: {
type: String,
default: '',
},
type: {
type: String as PropType<'success' | 'info' | 'error' | 'warning'>,
default: 'info',
},
closable: {
type: Boolean,
default: true,
},
closeText: {
type: String,
default: '',
},
showIcon: Boolean,
center: Boolean,
effect: {
type: String,
default: 'light',
validator: (value: string): boolean => ['light', 'dark'].indexOf(value) > -1,
},
},
emits: ['click'],
setup(props, ctx) {
// state
const visible = ref(true)
// computed
const typeClass = computed(() => `el-alert--${ props.type }`)
const iconClass = computed(() => TYPE_CLASSES_MAP[props.type] || 'el-icon-info')
const isBigIcon = computed(() => props.description || ctx.slots.default ? 'is-big' : '')
const isBoldTitle = computed(() => props.description || ctx.slots.default ? 'is-bold' : '')
// methods
const close = (evt) => {
visible.value = false
ctx.emit('click', evt)
}
return {
visible,
typeClass,
iconClass,
isBigIcon,
isBoldTitle,
close,
}
},
})
</script>

View File

@ -1,4 +1,5 @@
import type { App } from 'vue'
import ElAlert from '@element-plus/alert'
import ElAvatar from '@element-plus/avatar'
import ElBacktop from '@element-plus/backtop'
import ElButton from '@element-plus/button'
@ -24,6 +25,7 @@ import ElSteps from '@element-plus/steps'
import ElCollapse from '@element-plus/collapse'
export {
ElAlert,
ElAvatar,
ElBacktop,
ElLayout,
@ -50,6 +52,7 @@ export {
}
export default function install(app: App): void {
ElAlert(app)
ElAvatar(app)
ElBacktop(app)
ElButton(app)

View File

@ -14,6 +14,7 @@
"url": "https://github.com/element-plus/element-plus/issues"
},
"dependencies": {
"@element-plus/alert": "^0.0.0",
"@element-plus/avatar": "^0.0.0",
"@element-plus/badge": "^0.0.0",
"@element-plus/backtop": "^0.0.0",

1924
yarn.lock

File diff suppressed because it is too large Load Diff