quasar-framework
Version:
Simultaneously build desktop/mobile SPA websites & phone/tablet apps with VueJS
184 lines (163 loc) • 4.68 kB
JavaScript
import { QAlert } from '../components/alert'
import uid from '../utils/uid'
import clone from '../utils/clone'
import { ready } from '../utils/dom'
import { isSSR } from './platform'
const positionList = [
'top-left', 'top-right',
'bottom-left', 'bottom-right',
'top', 'bottom', 'left', 'right', 'center'
]
function init ({ $q, Vue }) {
const node = document.createElement('div')
document.body.appendChild(node)
this.__vm = new Vue({
name: 'q-notifications',
data: {
notifs: {
center: [],
left: [],
right: [],
top: [],
'top-left': [],
'top-right': [],
bottom: [],
'bottom-left': [],
'bottom-right': []
}
},
methods: {
add (config) {
if (!config) {
console.error('Notify: parameter required')
return false
}
let notif
if (typeof config === 'string') {
notif = {
message: config,
position: 'bottom'
}
}
else {
notif = clone(config)
}
if (notif.position) {
if (!positionList.includes(notif.position)) {
console.error(`Notify: wrong position: ${notif.position}`)
return false
}
}
else {
notif.position = 'bottom'
}
notif.__uid = uid()
if (notif.timeout === void 0) {
notif.timeout = 5000
}
const close = () => {
this.remove(notif)
}
if (notif.actions) {
notif.actions = config.actions.map(item => {
const
handler = item.handler,
action = clone(item)
action.handler = typeof handler === 'function'
? () => {
handler()
close()
}
: () => close()
return action
})
}
if (notif.closeBtn) {
const btn = [{
closeBtn: true,
label: notif.closeBtn,
handler: close
}]
notif.actions = notif.actions
? notif.actions.concat(btn)
: btn
}
if (notif.timeout) {
notif.__timeout = setTimeout(() => {
close()
}, notif.timeout + /* show duration */ 1000)
}
const action = notif.position.indexOf('top') > -1 ? 'unshift' : 'push'
this.notifs[notif.position][action](notif)
return close
},
remove (notif) {
if (notif.__timeout) { clearTimeout(notif.__timeout) }
const index = this.notifs[notif.position].indexOf(notif)
if (index !== -1) {
const ref = this.$refs[`notif_${notif.__uid}`]
if (ref && ref.$el) {
const el = ref.$el
el.style.left = `${el.offsetLeft}px`
el.style.width = getComputedStyle(el).width
}
this.notifs[notif.position].splice(index, 1)
if (typeof notif.onDismiss === 'function') {
notif.onDismiss()
}
}
}
},
render (h) {
return h('div', { staticClass: 'q-notifications' }, positionList.map(pos => {
const
vert = ['left', 'center', 'right'].includes(pos) ? 'center' : (pos.indexOf('top') > -1 ? 'top' : 'bottom'),
align = pos.indexOf('left') > -1 ? 'start' : (pos.indexOf('right') > -1 ? 'end' : 'center'),
classes = ['left', 'right'].includes(pos) ? `items-${pos === 'left' ? 'start' : 'end'} justify-center` : (pos === 'center' ? 'flex-center' : `items-${align}`)
return h('transition-group', {
key: pos,
staticClass: `q-notification-list q-notification-list-${vert} fixed column ${classes}`,
tag: 'div',
props: {
name: `q-notification-${pos}`,
mode: 'out-in'
}
}, this.notifs[pos].map(notif => {
return h(QAlert, {
ref: `notif_${notif.__uid}`,
key: notif.__uid,
staticClass: 'q-notification',
props: notif
}, [ notif.message ])
}))
}))
}
})
this.__vm.$mount(node)
$q.notify = this.create.bind(this)
}
export default {
create (opts) {
if (isSSR) {
return
}
if (this.__vm !== void 0) {
return this.__vm.add(opts)
}
ready(() => {
setTimeout(() => {
this.create(opts)
})
})
},
__installed: false,
install (args) {
if (this.__installed) { return }
this.__installed = true
if (!isSSR) {
ready(() => {
init.call(this, args)
})
}
}
}