ant-design-vue/components/tag/Tag.jsx

153 lines
3.6 KiB
Vue
Raw Normal View History

2018-09-16 21:36:22 +08:00
import PropTypes from '../_util/vue-types'
2017-11-09 15:58:53 +08:00
import Icon from '../icon'
2018-02-05 19:12:41 +08:00
import getTransitionProps from '../_util/getTransitionProps'
import omit from 'omit.js'
2018-09-16 21:36:22 +08:00
import Wave from '../_util/wave'
import { hasProp, getOptionProps } from '../_util/props-util'
import BaseMixin from '../_util/BaseMixin'
2017-11-09 15:58:53 +08:00
export default {
2018-04-08 21:17:20 +08:00
name: 'ATag',
2018-09-16 21:36:22 +08:00
mixins: [BaseMixin],
2017-11-09 15:58:53 +08:00
props: {
2018-09-16 21:36:22 +08:00
prefixCls: PropTypes.string.def('ant-tag'),
color: PropTypes.string,
closable: PropTypes.bool,
visible: PropTypes.bool,
},
model: {
prop: 'visible',
event: 'close.visible',
2017-11-09 15:58:53 +08:00
},
data () {
2018-09-16 21:36:22 +08:00
const props = getOptionProps(this)
let state = {}
if ('visible' in props) {
state = {
_visible: props.visible,
_closed: !props.visible,
}
}
state = {
_closing: false,
_closed: false,
_visible: true,
...state,
2017-11-09 15:58:53 +08:00
}
2018-09-16 21:36:22 +08:00
this.pre_visible = state._visible
return state
2017-11-09 15:58:53 +08:00
},
2018-09-16 21:36:22 +08:00
watch: {
visible (val) {
this.setState({
_visible: val,
})
2017-11-09 15:58:53 +08:00
},
2018-09-16 21:36:22 +08:00
},
updated () {
this.$nextTick(() => {
if (this.pre_visible && !this.$data._visible) {
this.close()
} else if (!this.pre_visible && this.$data._visible) {
this.show()
2017-11-09 15:58:53 +08:00
}
2018-09-16 21:36:22 +08:00
this.pre_visible = this.$data._visible
})
2017-11-09 15:58:53 +08:00
},
methods: {
2018-09-16 21:36:22 +08:00
handleIconClick (e) {
2017-11-09 15:58:53 +08:00
this.$emit('close', e)
2018-09-16 21:36:22 +08:00
this.$emit('close.visible', false)
if (e.defaultPrevented || hasProp(this, 'visible')) {
return
}
this.setState({ _visible: false })
},
close () {
if (this.$data._closing || this.$data._closed) {
2017-11-09 15:58:53 +08:00
return
}
2018-09-16 21:36:22 +08:00
const dom = this.$el
dom.style.width = `${dom.getBoundingClientRect().width}px`
// It's Magic Code, don't know why
dom.style.width = `${dom.getBoundingClientRect().width}px`
this.setState({
_closing: true,
})
},
show () {
this.setState({
_closed: false,
})
},
animationEnd (_, existed) {
if (!existed && !this.$data._closed) {
this.setState({
_closed: true,
_closing: false,
})
const afterClose = this.afterClose
if (afterClose) {
afterClose()
}
} else {
this.setState({
_closed: false,
})
}
},
isPresetColor (color) {
if (!color) { return false }
return (
/^(pink|red|yellow|orange|cyan|green|blue|purple|geekblue|magenta|volcano|gold|lime)(-inverse)?$/
.test(color)
)
2017-11-09 15:58:53 +08:00
},
},
2018-09-16 21:36:22 +08:00
2018-02-05 19:12:41 +08:00
render () {
2018-09-16 21:36:22 +08:00
const { prefixCls, closable, color } = this.$props
const closeIcon = closable ? <Icon type='cross' onClick={this.handleIconClick} /> : ''
const isPresetColor = this.isPresetColor(color)
const cls = {
[`${prefixCls}`]: true,
[`${prefixCls}-${color}`]: isPresetColor,
[`${prefixCls}-has-color`]: (color && !isPresetColor),
[`${prefixCls}-close`]: this.$data._closing,
}
const tagStyle = {
backgroundColor: (color && !isPresetColor) ? color : null,
}
const tag = this.$data._closed ? <span /> : (
<div
v-show={!this.$data._closing}
{...{ on: omit(this.$listeners, ['close']) }}
class={cls}
style={tagStyle}
>
{this.$slots.default}
{closeIcon}
</div>
)
const transitionProps = this.$data._closed ? {} : getTransitionProps(`${prefixCls}-zoom`, {
afterLeave: () => this.animationEnd(undefined, false),
afterEnter: () => this.animationEnd(undefined, true),
2018-02-05 19:12:41 +08:00
})
return (
2018-09-16 21:36:22 +08:00
<Wave>
<transition
{...transitionProps}
>
{tag}
</transition>
</Wave>
2018-02-05 19:12:41 +08:00
)
},
2017-11-09 15:58:53 +08:00
}
2018-03-19 10:16:27 +08:00