vuetify
Version:
Vue Material Component Framework
165 lines (145 loc) • 3.53 kB
text/typescript
// Styles
import './VBanner.sass'
// Extensions
import VSheet from '../VSheet'
// Components
import VAvatar from '../VAvatar'
import VIcon from '../VIcon'
import { VExpandTransition } from '../transitions'
// Mixins
import Mobile from '../../mixins/mobile'
import Toggleable from '../../mixins/toggleable'
// Utilities
import mixins from '../../util/mixins'
import {
convertToUnit,
getSlot,
} from '../../util/helpers'
// Typeslint
import { VNode } from 'vue'
/* @vue/component */
export default mixins(
VSheet,
Mobile,
Toggleable
).extend({
name: 'v-banner',
inheritAttrs: false,
props: {
app: Boolean,
icon: String,
iconColor: String,
singleLine: Boolean,
sticky: Boolean,
value: {
type: Boolean,
default: true,
},
},
computed: {
classes (): object {
return {
...VSheet.options.computed.classes.call(this),
'v-banner--has-icon': this.hasIcon,
'v-banner--is-mobile': this.isMobile,
'v-banner--single-line': this.singleLine,
'v-banner--sticky': this.isSticky,
}
},
hasIcon (): boolean {
return Boolean(this.icon || this.$slots.icon)
},
isSticky (): boolean {
return this.sticky || this.app
},
styles (): object {
const styles: Record<string, any> = { ...VSheet.options.computed.styles.call(this) }
if (this.isSticky) {
const top = !this.app
? 0
: (this.$vuetify.application.bar + this.$vuetify.application.top)
styles.top = convertToUnit(top)
styles.position = 'sticky'
styles.zIndex = 1
}
return styles
},
},
methods: {
/** @public */
toggle () {
this.isActive = !this.isActive
},
iconClick (e: MouseEvent) {
this.$emit('click:icon', e)
},
genIcon () {
if (!this.hasIcon) return undefined
let content
if (this.icon) {
content = this.$createElement(VIcon, {
props: {
color: this.iconColor,
size: 28,
},
}, [this.icon])
} else {
content = this.$slots.icon
}
return this.$createElement(VAvatar, {
staticClass: 'v-banner__icon',
props: {
color: this.color,
size: 40,
},
on: {
click: this.iconClick,
},
}, [content])
},
genText () {
return this.$createElement('div', {
staticClass: 'v-banner__text',
}, this.$slots.default)
},
genActions () {
const children = getSlot(this, 'actions', {
dismiss: () => this.isActive = false,
})
if (!children) return undefined
return this.$createElement('div', {
staticClass: 'v-banner__actions',
}, children)
},
genContent () {
return this.$createElement('div', {
staticClass: 'v-banner__content',
}, [
this.genIcon(),
this.genText(),
])
},
genWrapper () {
return this.$createElement('div', {
staticClass: 'v-banner__wrapper',
}, [
this.genContent(),
this.genActions(),
])
},
},
render (h): VNode {
return h(VExpandTransition, [
h('div', this.setBackgroundColor(this.color, {
staticClass: 'v-banner',
attrs: this.attrs$,
class: this.classes,
style: this.styles,
directives: [{
name: 'show',
value: this.isActive,
}],
}), [this.genWrapper()]),
])
},
})