222 lines
4.9 KiB
Vue
222 lines
4.9 KiB
Vue
<template>
|
|
<transition-group name="overlay" :duration="600" tag="div" class="app-overlays" :class="{ 'has-multiple': instances.length > 1 }">
|
|
<div class="app-overlay-outer" :display="instance.display" v-for="(instance, index) in instances" :key="instance.id"
|
|
:style="{ transform: instance.display !== 'editor' ? null : 'translateX(' + (editorLength - index - 1) * -120 + 'px)' }"
|
|
:class="instance.class || ''">
|
|
<div class="app-overlay-bg" @click="tryRemove(instance)"></div>
|
|
<div open class="app-overlay" :data-alias="instance.alias" :style="{ width: instance.width ? (instance.width + 'px') : null }" :class="'theme-' + instance.theme" :display="instance.display">
|
|
<component :is="instance.component" :model.sync="instance.model" :config="instance" v-bind="instance" title=""></component>
|
|
</div>
|
|
</div>
|
|
</transition-group>
|
|
</template>
|
|
|
|
|
|
<script lang="ts">
|
|
import emitter from '../services/eventhub';
|
|
import { event_showOverlay, event_closeOverlays, event_finalizeOverlay, event_closeOverlay } from '../services/overlay';
|
|
import { arrayRemove } from '../utils/arrays';
|
|
import { defineComponent } from 'vue';
|
|
|
|
export default defineComponent({
|
|
name: 'app-overlays',
|
|
|
|
data: () => ({
|
|
instances: []
|
|
}),
|
|
|
|
computed: {
|
|
editorLength()
|
|
{
|
|
return this.instances.filter(x => x.display === 'editor').length;
|
|
}
|
|
},
|
|
|
|
mounted()
|
|
{
|
|
emitter.on(event_showOverlay, overlay => this.add(overlay));
|
|
emitter.on(event_closeOverlays, () => this.instances = []);
|
|
emitter.on(event_finalizeOverlay, opts => this.finalize(opts.eventType, opts.instance, opts.value, opts.force));
|
|
emitter.on(event_closeOverlay, overlay => this.remove(overlay, true));
|
|
|
|
this.$el.addEventListener('keyup', e =>
|
|
{
|
|
if (e.key === "Escape" && this.instances.length)
|
|
{
|
|
this.instances[this.instances.length - 1].close();
|
|
}
|
|
});
|
|
},
|
|
|
|
methods: {
|
|
|
|
add(instance)
|
|
{
|
|
this.instances.push(instance);
|
|
},
|
|
|
|
tryRemove(instance)
|
|
{
|
|
if (instance.softdismiss)
|
|
{
|
|
this.remove(instance);
|
|
}
|
|
},
|
|
|
|
remove(instance)
|
|
{
|
|
emitter.emit(event_finalizeOverlay, { eventType: 'close', instance, force: true });
|
|
},
|
|
|
|
finalize(eventType, instance, value, force)
|
|
{
|
|
if ((eventType === 'close' && force) || (eventType === 'confirm' && instance.autoclose))
|
|
{
|
|
arrayRemove(this.instances, instance);
|
|
}
|
|
}
|
|
}
|
|
})
|
|
</script>
|
|
|
|
|
|
<style lang="scss">
|
|
.app-overlays
|
|
{
|
|
grid-column: span 2 / auto;
|
|
}
|
|
|
|
.app-overlay-outer
|
|
{
|
|
display: flex;
|
|
position: fixed;
|
|
left: 0;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
z-index: 5;
|
|
justify-content: center;
|
|
align-items: flex-start;
|
|
transition: transform 0.55s ease-out;
|
|
|
|
& + .app-overlay-outer .app-overlay
|
|
{
|
|
//top: -10px;
|
|
}
|
|
}
|
|
|
|
.app-overlay-bg
|
|
{
|
|
position: absolute;
|
|
left: 0;
|
|
top: 0;
|
|
right: 0;
|
|
bottom: 0;
|
|
background: var(--color-overlay-shade);
|
|
z-index: 2;
|
|
opacity: 1;
|
|
}
|
|
|
|
.app-overlay
|
|
{
|
|
width: auto;
|
|
height: auto;
|
|
background: var(--color-overlay);
|
|
border-bottom-right-radius: var(--radius);
|
|
border-bottom-left-radius: var(--radius);
|
|
border: none !important;
|
|
box-shadow: var(--shadow-overlay-dialog);
|
|
padding: var(--padding);
|
|
text-align: left;
|
|
position: relative;
|
|
-webkit-backface-visibility: hidden;
|
|
z-index: 3;
|
|
color: var(--color-text);
|
|
font-size: var(--font-size);
|
|
}
|
|
|
|
.app-overlay .ui-loading
|
|
{
|
|
position: relative;
|
|
left: 50%;
|
|
margin-left: -16px;
|
|
margin-top: 20px;
|
|
margin-bottom: 20px;
|
|
}
|
|
|
|
.app-overlay .ui-headline
|
|
{
|
|
margin-bottom: var(--padding);
|
|
}
|
|
|
|
.app-overlay[display="dialog"] .ui-form-loading
|
|
{
|
|
height: 200px;
|
|
}
|
|
|
|
.app-overlay[display="editor"]
|
|
{
|
|
width: auto;
|
|
position: absolute;
|
|
left: auto;
|
|
right: 0;
|
|
top: 0;
|
|
bottom: 0;
|
|
box-shadow: var(--shadow-overlay);
|
|
background: var(--color-overlay-editor);
|
|
text-align: left;
|
|
padding: 0;
|
|
height: 100vh;
|
|
max-width: 100%;
|
|
border-bottom-right-radius: 0;
|
|
border-top-left-radius: var(--radius);
|
|
}
|
|
|
|
.overlay-enter-active, .overlay-leave-active
|
|
{
|
|
.app-overlay-bg
|
|
{
|
|
transition: opacity .3s ease;
|
|
}
|
|
|
|
.app-overlay
|
|
{
|
|
transition: transform .3s ease, opacity .3s ease;
|
|
}
|
|
|
|
.app-overlay[display="editor"]
|
|
{
|
|
transition: transform .6s ease;
|
|
}
|
|
}
|
|
|
|
.overlay-enter, .overlay-leave-to
|
|
{
|
|
.app-overlay-bg
|
|
{
|
|
opacity: 0;
|
|
}
|
|
|
|
.app-overlay
|
|
{
|
|
opacity: 0;
|
|
transform: translateY(-20px);
|
|
}
|
|
|
|
.app-overlay[display="editor"]
|
|
{
|
|
opacity: 1;
|
|
transform: scale(1) translateX(100%);
|
|
}
|
|
}
|
|
|
|
.app-confirm-buttons
|
|
{
|
|
margin-top: 40px;
|
|
}
|
|
|
|
.app-confirm p
|
|
{
|
|
line-height: 1.4;
|
|
}
|
|
</style> |