187 lines
4.6 KiB
JavaScript
187 lines
4.6 KiB
JavaScript
// Styles
|
|
import "../../../src/components/VBadge/VBadge.sass"; // Components
|
|
|
|
import VIcon from '../VIcon/VIcon'; // Mixins
|
|
|
|
import Colorable from '../../mixins/colorable';
|
|
import Themeable from '../../mixins/themeable';
|
|
import Toggleable from '../../mixins/toggleable';
|
|
import Transitionable from '../../mixins/transitionable';
|
|
import { factory as PositionableFactory } from '../../mixins/positionable'; // Utilities
|
|
|
|
import mixins from '../../util/mixins';
|
|
import { convertToUnit, getSlot } from '../../util/helpers';
|
|
export default mixins(Colorable, PositionableFactory(['left', 'bottom']), Themeable, Toggleable, Transitionable).extend({
|
|
name: 'v-badge',
|
|
props: {
|
|
avatar: Boolean,
|
|
bordered: Boolean,
|
|
color: {
|
|
type: String,
|
|
default: 'primary'
|
|
},
|
|
content: {
|
|
required: false
|
|
},
|
|
dot: Boolean,
|
|
label: {
|
|
type: String,
|
|
default: '$vuetify.badge'
|
|
},
|
|
icon: String,
|
|
inline: Boolean,
|
|
offsetX: [Number, String],
|
|
offsetY: [Number, String],
|
|
overlap: Boolean,
|
|
tile: Boolean,
|
|
transition: {
|
|
type: String,
|
|
default: 'scale-rotate-transition'
|
|
},
|
|
value: {
|
|
default: true
|
|
}
|
|
},
|
|
computed: {
|
|
classes() {
|
|
return {
|
|
'v-badge--avatar': this.avatar,
|
|
'v-badge--bordered': this.bordered,
|
|
'v-badge--bottom': this.bottom,
|
|
'v-badge--dot': this.dot,
|
|
'v-badge--icon': this.icon != null,
|
|
'v-badge--inline': this.inline,
|
|
'v-badge--left': this.left,
|
|
'v-badge--overlap': this.overlap,
|
|
'v-badge--tile': this.tile,
|
|
...this.themeClasses
|
|
};
|
|
},
|
|
|
|
computedBottom() {
|
|
return this.bottom ? 'auto' : this.computedYOffset;
|
|
},
|
|
|
|
computedLeft() {
|
|
if (this.isRtl) {
|
|
return this.left ? this.computedXOffset : 'auto';
|
|
}
|
|
|
|
return this.left ? 'auto' : this.computedXOffset;
|
|
},
|
|
|
|
computedRight() {
|
|
if (this.isRtl) {
|
|
return this.left ? 'auto' : this.computedXOffset;
|
|
}
|
|
|
|
return !this.left ? 'auto' : this.computedXOffset;
|
|
},
|
|
|
|
computedTop() {
|
|
return this.bottom ? this.computedYOffset : 'auto';
|
|
},
|
|
|
|
computedXOffset() {
|
|
return this.calcPosition(this.offsetX);
|
|
},
|
|
|
|
computedYOffset() {
|
|
return this.calcPosition(this.offsetY);
|
|
},
|
|
|
|
isRtl() {
|
|
return this.$vuetify.rtl;
|
|
},
|
|
|
|
// Default fallback if offsetX
|
|
// or offsetY are undefined.
|
|
offset() {
|
|
if (this.overlap) return this.dot ? 8 : 12;
|
|
return this.dot ? 2 : 4;
|
|
},
|
|
|
|
styles() {
|
|
if (this.inline) return {};
|
|
return {
|
|
bottom: this.computedBottom,
|
|
left: this.computedLeft,
|
|
right: this.computedRight,
|
|
top: this.computedTop
|
|
};
|
|
}
|
|
|
|
},
|
|
methods: {
|
|
calcPosition(offset) {
|
|
return `calc(100% - ${convertToUnit(offset || this.offset)})`;
|
|
},
|
|
|
|
genBadge() {
|
|
const lang = this.$vuetify.lang;
|
|
const label = this.$attrs['aria-label'] || lang.t(this.label);
|
|
const data = this.setBackgroundColor(this.color, {
|
|
staticClass: 'v-badge__badge',
|
|
style: this.styles,
|
|
attrs: {
|
|
'aria-atomic': this.$attrs['aria-atomic'] || 'true',
|
|
'aria-label': label,
|
|
'aria-live': this.$attrs['aria-live'] || 'polite',
|
|
title: this.$attrs.title,
|
|
role: this.$attrs.role || 'status'
|
|
},
|
|
directives: [{
|
|
name: 'show',
|
|
value: this.isActive
|
|
}]
|
|
});
|
|
const badge = this.$createElement('span', data, [this.genBadgeContent()]);
|
|
if (!this.transition) return badge;
|
|
return this.$createElement('transition', {
|
|
props: {
|
|
name: this.transition,
|
|
origin: this.origin,
|
|
mode: this.mode
|
|
}
|
|
}, [badge]);
|
|
},
|
|
|
|
genBadgeContent() {
|
|
// Dot prop shows no content
|
|
if (this.dot) return undefined;
|
|
const slot = getSlot(this, 'badge');
|
|
if (slot) return slot;
|
|
if (this.content) return String(this.content);
|
|
if (this.icon) return this.$createElement(VIcon, this.icon);
|
|
return undefined;
|
|
},
|
|
|
|
genBadgeWrapper() {
|
|
return this.$createElement('span', {
|
|
staticClass: 'v-badge__wrapper'
|
|
}, [this.genBadge()]);
|
|
}
|
|
|
|
},
|
|
|
|
render(h) {
|
|
const badge = [this.genBadgeWrapper()];
|
|
const children = [getSlot(this)];
|
|
const {
|
|
'aria-atomic': _x,
|
|
'aria-label': _y,
|
|
'aria-live': _z,
|
|
role,
|
|
title,
|
|
...attrs
|
|
} = this.$attrs;
|
|
if (this.inline && this.left) children.unshift(badge);else children.push(badge);
|
|
return h('span', {
|
|
staticClass: 'v-badge',
|
|
attrs,
|
|
class: this.classes
|
|
}, children);
|
|
}
|
|
|
|
});
|
|
//# sourceMappingURL=VBadge.js.map
|