UNPKG

vuikit

Version:

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

331 lines (320 loc) 8.74 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 { on } from './util/event'; import { within } from './util/filter'; import { isTouch } from './util/touch'; import { findParent, mergeData, findParents } from './util/vue'; import { pointerEnter, pointerLeave, hasTouch, isRtl } from './util/env'; import { Transition } from './core/transition'; import VkPosition, { BEFORE_POSITION } from './core/v-position'; import { css } from './util/style'; import { offset } from './util/dimensions'; import { addClass, removeClass } from './util/class'; import VkRoot from './core/v-root'; import EventsMixin from './mixins/events'; import { $ } from './util/core'; import { get } from './util/misc'; import { MouseTracker } from './util/mouse'; import { includes, isNode, isString } from './util/lang'; var SHOW = 'show'; var HIDE = 'hide'; var constants = /*#__PURE__*/Object.freeze({ SHOW: SHOW, HIDE: HIDE }); var active; if (typeof document !== 'undefined' && typeof window !== 'undefined') { on(window, 'resize', function (ref) { var defaultPrevented = ref.defaultPrevented; var justified = active && /justify/.test(active.position); if (!defaultPrevented && justified) { active.$forceUpdate(); } }); on(document.documentElement, 'click', function (ref) { var target = ref.target; var defaultPrevented = ref.defaultPrevented; if (defaultPrevented || !active) { return } var clickedInside = function (drop) { return within(target, drop.$el); }; var clickedTarget = function (drop) { return within(target, drop.$refs.target); }; while (active && !clickedInside(active) && !clickedTarget(active)) { var parent = findParent(active); active._hide(); active = parent; } }); } var toggle = { data: function () { return ({ shown: false }); }, methods: { show: function show () { this.clearTimers(); this.showTimer = setTimeout(this._show, this.delayShow); }, _show: function _show () { while (active && !this.isChildOf(active) && !this.isParentOf(active)) { var parent = findParent(active); active._hide(); active = parent; } this.shown = true; this.tracker.init(); active = this; this.$emit(SHOW); }, hide: function hide () { var hoverIdle = 200; this.clearTimers(); this.isDelaying = this.tracker.movesTo(this.$el); if (this.isDelaying) { this.hideTimer = setTimeout(this.hide, hoverIdle); } else { this.hideTimer = setTimeout(this._hide, this.delayHide); } }, _hide: function _hide () { this.shown = false; this.tracker.cancel(); if (active === this) { var parent = findParent(active); active = parent || null; } this.$emit(HIDE); }, clearTimers: function clearTimers () { clearTimeout(this.showTimer); clearTimeout(this.hideTimer); this.showTimer = null; this.hideTimer = null; }, toggle: function toggle () { this.shown ? this._hide() : this.show(); } }, mounted: function mounted () { var this$1 = this; var ref = this; var on$$1 = ref.on; var show = ref.show; var hide = ref.hide; var toggle = ref.toggle; var mode = ref.mode; var clearTimers = ref.clearTimers; this.$nextTick(function () { if (/click/.test(mode) || hasTouch) { on$$1(this$1.$refs.target, 'click', toggle); } if (/hover/.test(mode)) { on$$1(this$1.$refs.target, pointerEnter, function (e) { if (isTouch(e)) { return } e.preventDefault(); show(); }); on$$1(this$1.$refs.target, pointerLeave, function (e) { if (isTouch(e)) { return } e.preventDefault(); hide(); }); on$$1(this$1.$el, pointerLeave, hide); on$$1(this$1.$el, pointerEnter, clearTimers); } }); } } var ElementDrop = { functional: true, props: { show: { type: Boolean, default: false } }, render: function render (h, ref) { var children = ref.children; var data = ref.data; var props = ref.props; var show = props.show; return h('div', mergeData(data, { class: { 'uk-open': show }, style: { display: show ? 'block' : null } }), children) } } var props = { target: {}, boundary: {}, boundaryAlign: { type: Boolean, default: false }, flip: { type: [String, Boolean], default: true }, position: { type: String, default: ("bottom-" + (isRtl ? 'right' : 'left')), validator: function (pos) { return /^(top|bottom)-(left|right|center|justify)$/.test(pos) || /^(left|right)-(top|bottom|center|justify)$/.test(pos); } }, offset: { type: [Boolean, Number], default: false }, animation: { type: String, default: 'fade' }, duration: { type: Number, default: 200 }, mode: { type: String, default: 'click hover' }, delayShow: { type: Number, default: 0 }, delayHide: { type: Number, default: 800 }, mainClass: { type: String, default: 'uk-drop' } } var render = { mounted: function mounted () { this.$refs.target = this.queryElement(this.target) || this.$el.previousElementSibling; this.$refs.boundary = this.queryElement(this.boundary) || window; this.$forceUpdate(); }, render: function render (h) { var this$1 = this; var obj, obj$1; var ref = this; var position = ref.position; var ref$1 = this.$refs; var boundary = ref$1.boundary; var target = ref$1.target; var ref$2 = position.split('-'); var align = ref$2[1]; var ref$3 = this; var boundaryAlign = ref$3.boundaryAlign; var animation = ref$3.animation; var duration = ref$3.duration; var mainClass = ref$3.mainClass; var flip = ref$3.flip; var offset$$1 = ref$3.offset; if (!target || !boundary) { return } position = position.replace('justify', 'center'); target = boundaryAlign ? boundary : target; var def = { on: ( obj = {}, obj[BEFORE_POSITION] = function (e) { var ref = this$1; var $el = ref.$el; var alignTo = offset(target); var boundaryOffset = offset(boundary); css($el, { width: '', height: '' }); removeClass($el, (mainClass + "-stack")); if (align === 'justify') { var prop = getAxis(position) === 'y' ? 'width' : 'height'; css($el, prop, alignTo[prop]); } else if ($el.offsetWidth > Math.max(boundaryOffset.right - alignTo.left, alignTo.right - boundaryOffset.left)) { addClass($el, (mainClass + "-stack")); } }, obj), props: { show: this.shown }, class: [mainClass, ( obj$1 = {}, obj$1[(mainClass + "-boundary")] = this.boundaryAlign, obj$1)], directives: [ { name: 'show', value: this.shown }, { name: 'vk-position', value: { flip: flip, offset: offset$$1, target: target, boundary: boundary, position: position, mainClass: mainClass } } ] }; return h(Transition, { props: { name: [animation], duration: duration } }, [ h(ElementDrop, def, this.$slots.default) ]) } } function getAxis (position) { var ref = position.split('-'); var dir = ref[0]; return dir === 'top' || dir === 'bottom' ? 'y' : 'x' } var index = { name: 'VkDrop', mixins: [render, toggle, EventsMixin], directives: { VkRoot: VkRoot, VkPosition: VkPosition }, props: props, methods: { isParentOf: function isParentOf (instance) { var parents = findParents(instance); return includes(parents, this) }, isChildOf: function isChildOf (instance) { var parents = findParents(this); return includes(parents, instance) }, queryElement: function queryElement (el) { return isNode(el) ? el : isString(el) ? (get(this.$vnode.context.$refs, el) || $(el, this.$el)) : el } }, created: function created () { this.tracker = new MouseTracker(); }, beforeDestroy: function beforeDestroy () { if (this.$el.parentNode) { this.$el.parentNode.removeChild(this.$el); } } } export { constants, active, ElementDrop, index as Drop };