UNPKG

vuikit

Version:

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

282 lines (277 loc) 8.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 { $ } 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;