@ishitatsuyuki/oruga-next
Version:
UI components for Vue.js and CSS framework agnostic
205 lines (198 loc) • 6.39 kB
JavaScript
'use strict';
var vue = require('vue');
var helpers = require('./helpers.js');
var config = require('./config.js');
var BaseComponentMixin = require('./BaseComponentMixin-a03c02e3.js');
var Icon = require('./Icon-172f9998.js');
var ssr = require('./ssr-4e5033ea.js');
/**
* A simple loading overlay
* @displayName Loading
* @style _loading.scss
*/
var script = vue.defineComponent({
name: 'OLoading',
components: {
[Icon.script.name]: Icon.script
},
mixins: [BaseComponentMixin.BaseComponentMixin],
configField: 'loading',
emits: ['update:active', 'close', 'update:full-page'],
props: {
/** Whether loading is active or not, use v-model:active to make it two-way binding */
active: Boolean,
/** @ignore */
programmatic: Object,
/** @ignore */
promise: Promise,
container: [Object, Function, ssr.HTMLElement],
/** Loader will overlay the full page */
fullPage: {
type: Boolean,
default: true
},
/* Custom animation (transition name) */
animation: {
type: String,
default: () => { return helpers.getValueByPath(config.getOptions(), 'loading.animation', 'fade'); }
},
/** Can close Loading by pressing escape or clicking outside */
canCancel: {
type: Boolean,
default: false
},
/** Callback function to call after user canceled (pressed escape / clicked outside) */
onCancel: {
type: Function,
default: () => { }
},
/** Icon name */
icon: {
type: String,
default: () => { return helpers.getValueByPath(config.getOptions(), 'loading.icon', 'loading'); }
},
/** Enable spin effect on icon */
iconSpin: {
type: Boolean,
default: true
},
iconSize: {
type: String,
default: 'medium'
},
rootClass: [String, Function, Array],
overlayClass: [String, Function, Array],
iconClass: [String, Function, Array],
fullPageClass: [String, Function, Array]
},
data() {
return {
isActive: this.active || false,
displayInFullPage: this.fullPage
};
},
watch: {
active(value) {
this.isActive = value;
},
fullPage(value) {
this.displayInFullPage = value;
}
},
computed: {
rootClasses() {
return [
this.computedClass('rootClass', 'o-load'),
{ [this.computedClass('fullPageClass', 'o-load--fullpage')]: this.displayInFullPage }
];
},
overlayClasses() {
return [
this.computedClass('overlayClass', 'o-load__overlay')
];
},
iconClasses() {
return [
this.computedClass('iconClass', 'o-load__icon')
];
}
},
methods: {
/**
* Close the Modal if canCancel.
*/
cancel(method) {
if (!this.canCancel || !this.isActive)
return;
this.close({ action: 'cancel', method });
},
/**
* Emit events, and destroy modal if it's programmatic.
*/
close() {
this.onCancel.apply(null, arguments);
this.$emit('close');
this.$emit('update:active', false);
// Timeout for the animation complete before destroying
if (this.programmatic) {
if (this.programmatic.instances) {
this.programmatic.instances.remove(this);
}
if (this.programmatic.resolve) {
this.programmatic.resolve.apply(null, arguments);
}
this.isActive = false;
window.requestAnimationFrame(() => {
helpers.removeElement(this.$el);
});
}
},
/**
* Keypress event that is bound to the document.
*/
keyPress({ key }) {
if (key === 'Escape' || key === 'Esc')
this.cancel('escape');
}
},
created() {
if (typeof window !== 'undefined') {
document.addEventListener('keyup', this.keyPress);
}
},
mounted() {
if (this.programmatic) {
if (this.programmatic.instances) {
this.programmatic.instances.add(this);
}
// Insert the Loading component in body tag
// only if it's programmatic
if (!this.container) {
document.body.appendChild(this.$el);
}
else {
this.displayInFullPage = false;
this.$emit('update:full-page', false);
this.container.appendChild(this.$el);
}
this.isActive = true;
}
},
beforeUnmount() {
if (typeof window !== 'undefined') {
document.removeEventListener('keyup', this.keyPress);
}
}
});
function render(_ctx, _cache, $props, $setup, $data, $options) {
const _component_o_icon = vue.resolveComponent("o-icon");
return vue.openBlock(), vue.createBlock(vue.Transition, {
name: _ctx.animation
}, {
default: vue.withCtx(() => [_ctx.isActive ? (vue.openBlock(), vue.createBlock("div", {
key: 0,
class: _ctx.rootClasses
}, [vue.createVNode("div", {
class: _ctx.overlayClasses,
onClick: _cache[1] || (_cache[1] = $event => _ctx.cancel('outside'))
}, null, 2
/* CLASS */
), vue.renderSlot(_ctx.$slots, "default", {}, () => [vue.createVNode(_component_o_icon, {
icon: _ctx.icon,
spin: _ctx.iconSpin,
size: _ctx.iconSize,
class: _ctx.iconClasses,
both: ""
}, null, 8
/* PROPS */
, ["icon", "spin", "size", "class"])])], 2
/* CLASS */
)) : vue.createCommentVNode("v-if", true)]),
_: 1
}, 8
/* PROPS */
, ["name"]);
}
script.render = render;
script.__file = "src/components/loading/Loading.vue";
exports.script = script;