UNPKG

vuikit

Version:

A responsive Vue UI library for web site interfaces based on UIkit

251 lines (241 loc) 7.33 kB
/** * Vuikit 0.8.10 * (c) 2018 Miljan Aleksic * @license MIT **/ /* Substantial part of the code is adapted from UIkit, Copyright (c) 2013-2018 YOOtheme GmbH, getuikit.com */ import { mergeData } from './util/vue'; import IconClose from './icons/close-icon'; import { ElementIconLink } from './icon'; import { on, trigger } from './util/event'; import { pointerEnter, pointerLeave } from './util/env'; import { css } from './util/style'; import { toFloat, isObject, isString, assign } from './util/lang'; import { Transition } from './util/animation'; import { warn, tip } from './util/debug'; import { get } from './util/misc'; var ElementNotification = { functional: true, props: { position: { type: String, default: 'top-center', validator: function (val) { return /^(top|bottom)-(left|center|right)$/.test(val); } } }, render: function render (h, ref) { var props = ref.props; var data = ref.data; var children = ref.children; var position = props.position; return h('div', mergeData(data, { class: [ 'uk-notification', ("uk-notification-" + position) ] }), children) } } var ElementNotificationClose = { functional: true, render: function render (h, ref) { var data = ref.data; return h(ElementIconLink, mergeData(data, { class: 'uk-notification-close uk-close' }), [ h(IconClose) ]) } } var ElementNotificationMessage = { functional: true, props: { status: { type: String, default: '', validator: function (val) { return !val || /^(primary|success|warning|danger)$/.test(val); } } }, render: function render (h, ref) { var obj; var props = ref.props; var data = ref.data; var children = ref.children; var status = props.status; return h('div', mergeData(data, { class: ['uk-notification-message', ( obj = {}, obj[("uk-notification-message-" + status)] = status, obj)] }), children) } } var NAMESPACE = '__vkNotification'; var MessageDirective = { inserted: function inserted (el, binding, vnode) { el[NAMESPACE] = {}; var close = function () { return doClose(el, vnode); }; var opts = el[NAMESPACE].options = binding.value; if (opts.timeout) { el[NAMESPACE].timer = setTimeout(close, opts.timeout); } on(el, 'click', close); on(el, pointerEnter, function () { if (el[NAMESPACE].timer) { clearTimeout(el[NAMESPACE].timer); } }); on(el, pointerLeave, function () { if (opts.timeout) { el[NAMESPACE].timer = setTimeout(close, opts.timeout); } }); }, unbind: function unbind (el) { if (!el[NAMESPACE]) { return } clearTimeout(el[NAMESPACE].timer); delete el[NAMESPACE]; } } function doClose (el, vnode) { clearTimeout(el[NAMESPACE].timer); trigger(el, 'close'); } var MessageTransition = { functional: true, render: function render (h, ref) { var data = ref.data; var children = ref.children; var parent = ref.parent; var def = { props: { css: false, appear: true, tag: 'div' }, on: { enter: function enter (el, done) { var marginBottom = toFloat(css(el, 'marginBottom')); css(el, { opacity: 0, marginTop: -el.offsetHeight, marginBottom: 0 }); Transition.start(el, { opacity: 1, marginTop: 0, marginBottom: marginBottom }).then(done); }, leave: function leave (el, done) { Transition.start(el, { opacity: 0, marginTop: -el.offsetHeight, marginBottom: 0 }).then(done); } } }; return h('transition-group', mergeData(data, def), children) } } var isNotProd = process.env.NODE_ENV !== 'production'; var notification = { name: 'VkNotification', directives: { MessageDirective: MessageDirective }, props: assign({}, ElementNotification.props, { timeout: { type: Number, default: 5000 }, messages: { type: Array, default: function () { return []; }, validator: function (val) { if (!val.every(function (m) { return isObject(m) || isString(m); })) { isNotProd && warn('vk-notification -> each message is expected as Object or String'); return false } return true } }, status: ElementNotificationMessage.props.status }), computed: { $messages: function $messages () { var this$1 = this; var messages = this.messages.map(function (val) { var msg = isString(val) ? { message: val } : val; return assign({ status: this$1.status, timeout: this$1.timeout }, msg) }); messages = this.removeDuplicates(messages); return messages } }, methods: { triggerRemove: function triggerRemove (msg) { var this$1 = this; this.closeQueue = this.closeQueue || []; this.closeQueue.push(msg); clearTimeout(this.timer); this.timer = setTimeout(function () { var queue = [].concat( this$1.closeQueue ); var messages = [].concat( this$1.$messages ); this$1.closeQueue = []; queue.forEach(function (msg) { var index = messages.indexOf(messages.filter(function (m) { return m === msg; })[0]); messages.splice(index, 1); }); this$1.$emit('update:messages', messages); }); }, removeDuplicates: function removeDuplicates (values) { var this$1 = this; var messages = []; var isDuplicated = function (msg) { return messages.filter(function (m) { return this$1.getMessageId(m) === this$1.getMessageId(msg) }).length; }; for (var i = 0; i < values.length; i++) { if (isDuplicated(values[i])) { isNotProd && tip('vk-notification -> duplicate messages are filtered out, consider adding a unique `key` to those.'); continue } messages.push(values[i]); } return messages }, getMessageId: function getMessageId (msg) { var validKeys = ['message', 'status', 'key', 'timeout']; return Object.keys(msg) .filter(function (k) { return validKeys.filter(function (k) { return k; })[0]; }) .map(function (k) { return msg[k]; }) .join(':') } }, render: function render (h) { var this$1 = this; var ref = this; var position = ref.position; var MessageSlot = get(this, '$scopedSlots.default', function (msg) { return msg.message; }); return h(ElementNotification, { props: { position: position } }, [ h(MessageTransition, [ this.$messages.map(function (msg, index) { return h(ElementNotificationMessage, { key: this$1.getMessageId(msg), props: msg, directives: [{ name: 'message-directive', value: msg }], on: { close: function () { return this$1.triggerRemove(msg); } } }, [ MessageSlot(msg), h(ElementNotificationClose) ]); } ) ]) ]) } } export { ElementNotification, ElementNotificationClose, ElementNotificationMessage, notification as Notification };