vuikit
Version:
A responsive Vue UI library for web site interfaces based on UIkit
282 lines (277 loc) • 8.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 { $ } from './util/core';
import { css } from './util/style';
import { warn } from './util/debug';
import { isTouch } from './util/touch';
import { Promise } from './util/promise';
import { matches } from './util/selector';
import { Animation } from './util/animation';
import { isVisible } from './util/filter';
import { on, trigger } from './util/event';
import { hasAttr, attr } from './util/attr';
import { append, remove } from './util/dom';
import { pointerEnter, pointerDown, pointerLeave } from './util/env';
import { isNumeric, assign, isString, hyphenate } from './util/lang';
import { positionAt, flipPosition, offset } from './util/dimensions';
import { addClass, toggleClass, removeClasses, removeClass } from './util/class';
var NAMESPACE = '__vkTooltip';
var index = {
bind: function bind (el, binding, vnode) {
el[NAMESPACE] = {
vnode: vnode,
state: null,
options: getOptions({ binding: binding })
};
if (hasAttr(el, 'title')) {
el[NAMESPACE].attrTitle = attr(el, 'title');
attr(el, { title: '' });
}
el[NAMESPACE].title = el[NAMESPACE].options.title || el[NAMESPACE].attrTitle;
},
inserted: function inserted (el, binding, vnode) {
bindEvents(el);
},
componentUpdated: function componentUpdated (el, binding, vnode) {
el[NAMESPACE].options = getOptions({ binding: binding });
el[NAMESPACE].title = el[NAMESPACE].options.title || el[NAMESPACE].attrTitle;
},
unbind: function unbind (el, binding, vnode) {
if (!el[NAMESPACE]) {
return
}
_hide(el);
attr(el, { title: el[NAMESPACE].attrTitle || null });
el[NAMESPACE].unbindEvents();
delete el[NAMESPACE];
}
}
function bindEvents (el) {
var events = [
on(el, ("focus " + pointerEnter + " " + pointerDown), function (e) {
if (e.type !== pointerDown || !isTouch(e)) {
show(el);
}
}),
on(el, 'blur', function (e) { return hide(el); }),
on(el, pointerLeave, function (e) {
if (!isTouch(e)) {
hide(el);
}
})
];
el[NAMESPACE].unbindEvents = function () { return events.forEach(function (unbind) { return unbind(); }); };
}
function toggleIn (el) {
var ref = el[NAMESPACE].options;
var cls = ref.cls;
var position = ref.position;
var animation = ref.animation;
var duration = ref.duration;
if (!trigger(el, 'beforeShow')) {
return Promise.reject()
}
var origin = el[NAMESPACE].origin = getOrigin(position);
var tooltip = el[NAMESPACE].tooltip = createTooltip(el);
positionTooltip(el);
addClass(tooltip, cls);
el[NAMESPACE].hideTimer = setInterval(function () {
if (!isVisible(el)) {
hide(el);
}
}, 150);
el[NAMESPACE].state = 'in';
trigger(el, 'show');
return Animation
.in(tooltip, ("uk-animation-" + (animation[0])), duration, origin)
.then(function () {
el[NAMESPACE].state = 'active';
trigger(el, 'shown');
})
.catch(function () {})
}
function toggleOut (el) {
var ref = el[NAMESPACE];
var tooltip = ref.tooltip;
var ref$1 = el[NAMESPACE].options;
var animation = ref$1.animation;
var duration = ref$1.duration;
if (!trigger(el, 'beforeHide')) {
return Promise.reject()
}
Animation.cancel(tooltip);
el[NAMESPACE].state = 'out';
trigger(el, 'hide');
if (!animation[1]) {
return Promise.resolve().then(function () { return _hide(el); })
}
return Animation
.out(tooltip, ("uk-animation-" + (animation[1])), duration, origin)
.then(function () { return _hide(el); })
.catch(function () {})
}
function show (el) {
var ref = el[NAMESPACE].options;
var delay = ref.delay;
var ref$1 = el[NAMESPACE];
var state = ref$1.state;
var title = ref$1.title;
if (!title || state === 'active' || el[NAMESPACE].showTimer) {
return
}
if (state === 'out') {
Animation.cancel(el);
_hide(el);
}
el[NAMESPACE].showTimer = setTimeout(function () { return toggleIn(el); }, delay);
}
function hide (el) {
if (!el[NAMESPACE]) {
return
}
var ref = el[NAMESPACE];
var state = ref.state;
clearAllTimers(el);
if (state === 'out' || (matches(el, 'input') && isFocused(el))) {
return
}
toggleOut(el);
}
function _hide (el) {
if (!el[NAMESPACE]) {
return
}
var ref = el[NAMESPACE];
var tooltip = ref.tooltip;
var ref$1 = el[NAMESPACE].options;
var cls = ref$1.cls;
attr(el, 'aria-expanded', false);
removeClass(tooltip, cls);
tooltip && remove(tooltip);
el[NAMESPACE].state = null;
el[NAMESPACE].tooltip = null;
trigger(el, 'hidden');
}
function clearAllTimers (el) {
clearTimeout(el[NAMESPACE].showTimer);
clearTimeout(el[NAMESPACE].hideTimer);
el[NAMESPACE].showTimer = null;
el[NAMESPACE].hideTimer = null;
}
function positionTooltip (el) {
var target = el;
var ref = el[NAMESPACE];
var tooltip = ref.tooltip;
var ref$1 = el[NAMESPACE].options;
var clsPos = ref$1.clsPos;
var position = ref$1.position;
var ref$2 = el[NAMESPACE].options;
var offset$$1 = ref$2.offset;
var node;
var ref$3 = position.split('-');
var dir = ref$3[0];
var align = ref$3[1]; if ( align === void 0 ) align = 'center';
removeClasses(tooltip, (clsPos + "-(top|bottom|left|right)(-[a-z]+)?"));
css(tooltip, { top: '', left: '' });
var axis = getAxis(position);
offset$$1 = isNumeric(offset$$1)
? offset$$1
: (node = $(offset$$1))
? offset(node)[axis === 'x' ? 'left' : 'top'] - offset(target)[axis === 'x' ? 'right' : 'bottom']
: 0;
var elAttach = axis === 'x'
? ((flipPosition(dir)) + " " + align)
: (align + " " + (flipPosition(dir)));
var targetAttach = axis === 'x'
? (dir + " " + align)
: (align + " " + dir);
var elOffset = axis === 'x'
? ("" + (dir === 'left' ? -1 * offset$$1 : offset$$1))
: ("" + (dir === 'top' ? -1 * offset$$1 : offset$$1));
var targetOffset = null;
var ref$4 = positionAt(
tooltip,
target,
elAttach,
targetAttach,
elOffset,
targetOffset,
true
).target;
var x = ref$4.x;
var y = ref$4.y;
dir = axis === 'x' ? x : y;
align = axis === 'x' ? y : x;
toggleClass(tooltip, (clsPos + "-" + dir + "-" + align), el[NAMESPACE].options.offset === false);
return {
dir: dir,
align: align
}
}
function getOptions (ctx) {
var ref = ctx.binding;
var value = ref.value;
var modifiers = ref.modifiers;
if (isString(value)) {
value = { title: value };
}
if (Object.keys(modifiers).length) {
var firstKey = Object.keys(modifiers)[0];
modifiers = { position: firstKey };
}
var options = assign({
delay: 0,
title: '',
offset: false,
duration: 100,
position: 'top',
container: true,
cls: 'uk-active',
clsPos: 'uk-tooltip',
animation: 'scale-up'
}, modifiers, value);
options.position = hyphenate(options.position);
options.animation = options.animation.split(' ');
if (process.env.NODE_ENV !== 'production') {
var pos = options.position;
if (!(/^(top|bottom)-(left|right)$/.test(pos) || /^(top|bottom|left|right)$/.test(pos))) {
warn(("v-vk-tooltip -> '" + pos + "' is not a valid position value"), ctx.vnode);
}
}
return options
}
function getAxis (position) {
var ref = position.split('-');
var dir = ref[0];
return dir === 'top' || dir === 'bottom' ? 'y' : 'x'
}
function getContainer (el) {
var ref = el[NAMESPACE];
var vnode = ref.vnode;
var ref$1 = el[NAMESPACE].options;
var container = ref$1.container;
return (container === true && vnode.context.$root.$el) || (container && $(container))
}
function createTooltip (el) {
var ref = el[NAMESPACE];
var title = ref.title;
var ref$1 = el[NAMESPACE].options;
var clsPos = ref$1.clsPos;
return append(getContainer(el), ("<div class=\"" + clsPos + "\" aria-hidden>\n <div class=\"" + clsPos + "-inner\">" + title + "</div>\n </div>"))
}
function getOrigin (position) {
var dir = position[0];
var align = position[1];
return getAxis(position) === 'y'
? ((flipPosition(dir)) + "-" + align)
: (align + "-" + (flipPosition(dir)))
}
function isFocused (el) {
return el === document.activeElement
}
export default index;