vuikit
Version:
A responsive Vue UI library for web site interfaces based on UIkit
251 lines (241 loc) • 7.33 kB
JavaScript
/**
* 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 };