vuikit
Version:
A responsive Vue UI library for web site interfaces based on UIkit
472 lines (453 loc) • 13.6 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 { on, once } from './util/event';
import { css } from './util/style';
import { width, height } from './util/dimensions';
import { addClass, removeClass } from './util/class';
import { mergeData } from './util/vue';
import IconClose from './icons/close-icon';
import IconCloseLarge from './icons/close-large';
import { warn } from './util/debug';
import { query } from './util/selector';
var SHOWN = 'shown';
var HIDDEN = 'hidden';
var TOGGLE = 'update:show';
var KEYUP = 'keyup';
var constants = /*#__PURE__*/Object.freeze({
SHOWN: SHOWN,
HIDDEN: HIDDEN,
TOGGLE: TOGGLE,
KEYUP: KEYUP
});
var active;
var scrollbarWidth;
var win = typeof window !== 'undefined' && window;
var body = typeof document !== 'undefined' && document.body;
var doc = typeof document !== 'undefined' && document.documentElement;
var scroll;
var getScrollbarWidth = function () { return width(win) - doc.offsetWidth; };
var events = {
beforeEnter: function (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
var $props = ref.$props;
scrollbarWidth = getScrollbarWidth();
scroll = scroll || { x: win.pageXOffset, y: win.pageYOffset };
addClass(doc, 'uk-offcanvas-page');
addClass(body, 'uk-offcanvas-container');
if ($props.flipped) {
addClass($refs.bar, 'uk-offcanvas-bar-flip');
addClass($refs.content.parentNode, 'uk-offcanvas-flip');
}
if ($props.overlay) {
addClass(body, 'uk-offcanvas-overlay');
}
height(el);
},
afterEnter: function afterEnter (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
var $props = ref.$props;
if ($props.overlay) {
width($refs.content, width(win) - scrollbarWidth);
height($refs.content, height(win));
if (scroll) {
$refs.content.scrollTop = scroll.y;
}
}
active = el.__vkOffcanvas;
active.$emit(SHOWN);
},
afterLeave: function afterLeave (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
var $props = ref.$props;
if (!$props.overlay) {
scroll = { x: win.pageXOffset, y: win.pageYOffset };
} else if (!scroll) {
var ref$1 = $refs.content;
var x = ref$1.scrollLeft;
var y = ref$1.scrollTop;
scroll = { x: x, y: y };
}
removeClass($refs.bar, 'uk-offcanvas-bar-flip');
removeClass($refs.content.parentNode, 'uk-offcanvas-flip');
removeClass(doc, 'uk-offcanvas-page');
removeClass(body, 'uk-offcanvas-container');
removeClass(body, 'uk-offcanvas-overlay');
body.scrollTop = scroll.y;
css(body, 'overflowY', '');
css(doc, 'overflowY', '');
width($refs.content, '');
height($refs.content, '');
win.scrollTo(scroll.x, scroll.y);
scroll = null;
if (active === el.__vkOffcanvas) {
active = null;
}
el.__vkOffcanvas.$emit(HIDDEN);
}
};
on(doc, 'click', function (e) {
if (!active) {
return
}
var $refs = active.$refs;
var $props = active.$props;
var clickedOut = !$refs.bar.contains(e.target);
if (clickedOut && !$props.stuck) {
active.$emit(TOGGLE, false);
}
});
on(doc, 'keyup', function (e) {
active && active.$emit(KEYUP, e);
});
var ElementOffcanvas = {
functional: true,
render: function render (h, ref) {
var data = ref.data;
var children = ref.children;
return h('div', mergeData(data, {
class: 'uk-offcanvas',
style: {
display: 'block'
}
}), children)
}
}
var ElementOffcanvasContent = {
functional: true,
render: function render (h, ref) {
var data = ref.data;
var children = ref.children;
return h('div', mergeData(data, {
class: 'uk-offcanvas-content'
}), children)
}
}
var ElementOffcanvasBar = {
functional: true,
render: function render (h, ref) {
var data = ref.data;
var children = ref.children;
return h('div', mergeData(data, {
class: 'uk-offcanvas-bar'
}), children)
}
}
var ElementOffcanvasClose = {
functional: true,
props: {
large: {
type: Boolean,
default: false
}
},
render: function render (h, ref) {
var data = ref.data;
var props = ref.props;
var large = props.large;
var def = {
class: ['uk-offcanvas-close uk-close uk-icon', {
'uk-close-large': large
}],
attrs: {
type: 'button'
}
};
return h('button', mergeData(data, def), [
h(large ? IconCloseLarge : IconClose)
])
}
}
var TransitionNone = {
functional: true,
render: function render (h, ref) {
var data = ref.data;
var children = ref.children;
var def = {
props: {
css: false
},
on: {
enter: function (el, done) { return done(); },
leave: function (el, done) { return done(); },
beforeEnter: function beforeEnter (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
var $props = ref.$props;
events.beforeEnter(el);
css(doc, 'overflowY', scrollbarWidth && $props.overlay
? 'scroll'
: ''
);
addClass(el, 'uk-open');
addClass($refs.bar, 'uk-offcanvas-none');
},
afterEnter: function afterEnter (el) {
events.afterEnter(el);
},
afterLeave: function afterLeave (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
removeClass(el, 'uk-open');
removeClass($refs.bar, 'uk-offcanvas-none');
events.afterLeave(el);
}
}
};
return h('transition', mergeData(def, data), children)
}
}
var TransitionPush = {
functional: true,
render: function render (h, ref) {
var data = ref.data;
var children = ref.children;
var def = {
props: {
css: false
},
on: {
beforeEnter: function beforeEnter (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
var $props = ref.$props;
events.beforeEnter(el);
css(doc, 'overflowY', $props.flipped && scrollbarWidth && $props.overlay
? 'scroll'
: ''
);
addClass($refs.bar, 'uk-offcanvas-bar-animation uk-offcanvas-push');
},
enter: function enter (el, done) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
height(el);
addClass(el, 'uk-open');
addClass($refs.content, 'uk-offcanvas-content-animation');
once(el, 'transitionend', done, false, function (e) { return e.target === $refs.bar; });
},
afterEnter: function afterEnter (el) {
events.afterEnter(el);
},
beforeLeave: function beforeLeave (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
removeClass(el, 'uk-open');
removeClass($refs.content, 'uk-offcanvas-content-animation');
},
leave: function leave (el, done) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
var bar = $refs.bar;
once(el, 'transitionend', done, false, function (e) { return e.target === bar; });
},
afterLeave: function afterLeave (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
removeClass($refs.bar, 'uk-offcanvas-bar-animation uk-offcanvas-push');
events.afterLeave(el);
}
}
};
return h('transition', mergeData(def, data), children)
}
}
var TransitionSlide = {
functional: true,
render: function render (h, ref) {
var data = ref.data;
var children = ref.children;
var def = {
props: {
css: false
},
on: {
beforeEnter: function beforeEnter (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
var $props = ref.$props;
events.beforeEnter(el);
css(doc, 'overflowY', scrollbarWidth && $props.overlay
? 'scroll'
: ''
);
addClass($refs.bar, 'uk-offcanvas-bar-animation uk-offcanvas-slide');
},
enter: function enter (el, done) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
height(el);
addClass(el, 'uk-open');
once(el, 'transitionend', done, false, function (e) { return e.target === $refs.bar; });
},
afterEnter: function afterEnter (el) {
events.afterEnter(el);
},
beforeLeave: function beforeLeave (el) {
removeClass(el, 'uk-open');
},
leave: function leave (el, done) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
once(el, 'transitionend', done, false, function (e) { return e.target === $refs.bar; });
},
afterLeave: function afterLeave (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
removeClass($refs.bar, 'uk-offcanvas-bar-animation uk-offcanvas-slide');
events.afterLeave(el);
}
}
};
return h('transition', mergeData(def, data), children)
}
}
var TransitionReveal = {
functional: true,
render: function render (h, ref) {
var data = ref.data;
var children = ref.children;
var def = {
props: {
css: false
},
on: {
beforeEnter: function beforeEnter (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
var $props = ref.$props;
events.beforeEnter(el);
width($refs.content, width(win) - scrollbarWidth);
css(doc, 'overflowY', $props.flipped && scrollbarWidth && $props.overlay
? 'scroll'
: ''
);
},
enter: function enter (el, done) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
height(el);
addClass(el, 'uk-open');
addClass($refs.content, 'uk-offcanvas-content-animation');
once(el, 'transitionend', done, false, function (e) { return e.target === $refs.reveal; });
},
afterEnter: function afterEnter (el) {
events.afterEnter(el);
},
beforeLeave: function beforeLeave (el) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
removeClass(el, 'uk-open');
removeClass($refs.content, 'uk-offcanvas-content-animation');
},
leave: function leave (el, done) {
var ref = el.__vkOffcanvas;
var $refs = ref.$refs;
once(el, 'transitionend', done, false, function (e) { return e.target === $refs.reveal; });
},
afterLeave: function afterLeave (el) {
events.afterLeave(el);
}
}
};
return h('transition', mergeData(def, data), children)
}
}
var Transitions = {
none: TransitionNone,
push: TransitionPush,
slide: TransitionSlide,
reveal: TransitionReveal
};
var offcanvas = {
props: {
show: {
type: Boolean,
default: false
},
flipped: {
type: Boolean,
default: false
},
stuck: {
type: Boolean,
default: false
},
overlay: {
type: Boolean,
default: false
},
mode: {
type: String,
default: 'slide',
validator: function (val) { return /^(none|slide|push|reveal)$/.test(val); }
}
},
mounted: function mounted () {
this.$refs.content = query('.uk-offcanvas-content');
this.$refs.bar = this.$el.querySelector('.uk-offcanvas-bar');
if (process.env.NODE_ENV !== 'production' && !this.$refs.content) {
warn('Offcanvas content element not detected -> make sure to wrap the offcanvas content with `vk-offcanvas-content` component or a custom `.uk-offcanvas-content` node.', this);
}
this.$el.__vkOffcanvas = this;
},
beforeDestroy: function beforeDestroy () {
if (this.show) {
events.afterLeave(this.$el);
}
},
render: function render (h) {
var nodes = this.$slots.default || [];
var customBar = findBar(nodes);
var bar = customBar || h(ElementOffcanvasBar, nodes);
var content = h(ElementOffcanvas, {
key: this.mode,
class: {
'uk-offcanvas-overlay': this.overlay
},
directives: [{
name: 'show',
value: this.show
}]
}, [
this.mode === 'reveal'
? h('div', {
class: 'uk-offcanvas-reveal',
ref: 'reveal'
}, [ bar ])
: bar
]);
return h(Transitions[this.mode], [ content ])
}
}
function findBar (nodes) {
return nodes
.filter(function (n) { return n.tag && n.data && /offcanvas-bar/.test(getNodeClass(n)); })[0]
}
function getNodeClass (node) {
return (node.data.class || []).concat( [node.data.staticClass]).join(' ')
}
var offcanvasContent = {
name: 'VkOffcanvasContent',
functional: true,
render: ElementOffcanvasContent.render
}
var offcanvas_Bar = {
name: 'VkOffcanvasBar',
functional: true,
render: ElementOffcanvasBar.render
}
var offcanvas_Close = {
name: 'VkOffcanvasClose',
functional: true,
props: ElementOffcanvasClose.props,
render: ElementOffcanvasClose.render
}
export { constants, active, ElementOffcanvas, ElementOffcanvasContent, ElementOffcanvasBar, ElementOffcanvasClose, offcanvas as Offcanvas, offcanvasContent as OffcanvasContent, offcanvas_Bar as OffcanvasBar, offcanvas_Close as OffcanvasClose };