fchat-rising/components/Modal.vue

127 lines
4.0 KiB
Vue
Raw Normal View History

2017-09-02 01:50:31 +00:00
<template>
2018-01-06 16:14:21 +00:00
<span v-show="isShown">
2019-09-17 17:14:14 +00:00
<div class="modal" @mousedown.self="hideWithCheck()" style="display:flex;justify-content:center">
2019-01-03 17:38:17 +00:00
<div class="modal-dialog" :class="dialogClass" style="display:flex;align-items:center;margin-left:0;margin-right:0">
<div class="modal-content" style="max-height:100%">
2018-01-06 16:14:21 +00:00
<div class="modal-header" style="flex-shrink:0">
<h4 class="modal-title">
<slot name="title">{{action}}</slot>
</h4>
<button type="button" class="close" @click="hide" aria-label="Close" v-show="!keepOpen">&times;</button>
2018-01-06 16:14:21 +00:00
</div>
2018-07-20 01:12:26 +00:00
<div class="modal-body" style="overflow:auto;-webkit-overflow-scrolling:auto" tabindex="-1">
2018-01-06 16:14:21 +00:00
<slot></slot>
</div>
<div class="modal-footer" v-if="buttons">
<button type="button" class="btn btn-secondary" @click="hideWithCheck" v-if="showCancel">Cancel</button>
2022-12-25 05:44:55 +00:00
<button type="button" class="btn" :class="buttonClass" @click="submit" :disabled="shouldBeDisabled()">
2018-01-06 16:14:21 +00:00
{{submitText}}
</button>
</div>
2017-09-02 01:50:31 +00:00
</div>
</div>
</div>
<div class="modal-backdrop show"></div>
2018-01-06 16:14:21 +00:00
</span>
2017-09-02 01:50:31 +00:00
</template>
<script lang="ts">
2019-01-03 17:38:17 +00:00
import {Component, Hook, Prop} from '@f-list/vue-ts';
2017-09-02 01:50:31 +00:00
import Vue from 'vue';
2018-01-06 16:14:21 +00:00
import {getKey} from '../chat/common';
import {Keys} from '../keys';
2018-01-06 16:14:21 +00:00
const dialogStack: Modal[] = [];
window.addEventListener('keydown', (e) => {
if(getKey(e) === Keys.Escape && dialogStack.length > 0) dialogStack[dialogStack.length - 1].hideWithCheck();
2018-01-06 16:14:21 +00:00
});
window.addEventListener('backbutton', (e) => {
if(dialogStack.length > 0) {
e.stopPropagation();
e.preventDefault();
2018-07-20 01:12:26 +00:00
dialogStack[dialogStack.length - 1].hide();
}
}, true);
2017-09-02 01:50:31 +00:00
2018-07-20 01:12:26 +00:00
export let isShowing = false;
2017-09-02 01:50:31 +00:00
@Component
export default class Modal extends Vue {
@Prop({default: ''})
readonly action!: string;
2019-09-17 17:14:14 +00:00
@Prop
2017-09-02 01:50:31 +00:00
readonly dialogClass?: {string: boolean};
@Prop({default: true})
readonly buttons!: boolean;
2017-09-02 01:50:31 +00:00
@Prop({default: () => ({'btn-primary': true})})
readonly buttonClass!: {string: boolean};
2019-09-17 17:14:14 +00:00
@Prop
2017-09-02 01:50:31 +00:00
readonly disabled?: boolean;
@Prop({default: true})
readonly showCancel!: boolean;
2019-09-17 17:14:14 +00:00
@Prop
2017-09-02 01:50:31 +00:00
readonly buttonText?: string;
isShown = false;
2022-12-25 05:44:55 +00:00
2018-01-06 16:14:21 +00:00
keepOpen = false;
2022-12-25 05:44:55 +00:00
forcedDisabled = false;
2017-09-02 01:50:31 +00:00
get submitText(): string {
return this.buttonText !== undefined ? this.buttonText : this.action;
}
2022-12-25 05:44:55 +00:00
forceDisabled(disabled: boolean): void {
this.forcedDisabled = disabled;
}
shouldBeDisabled(): boolean {
return this.disabled || this.forcedDisabled;
}
2017-09-02 01:50:31 +00:00
submit(e: Event): void {
this.$emit('submit', e);
2018-01-06 16:14:21 +00:00
if(!e.defaultPrevented) this.hideWithCheck();
2017-09-02 01:50:31 +00:00
}
2018-07-20 01:12:26 +00:00
show(keepOpen: boolean = false): void {
2018-01-06 16:14:21 +00:00
this.keepOpen = keepOpen;
2023-03-12 05:43:58 +00:00
if(this.isShown) {
this.$emit('reopen');
return;
}
2018-07-20 01:12:26 +00:00
this.isShown = true;
2018-01-06 16:14:21 +00:00
dialogStack.push(this);
this.$emit('open');
2018-07-20 01:12:26 +00:00
isShowing = true;
2017-09-02 01:50:31 +00:00
}
hide(): void {
this.isShown = false;
2018-01-06 16:14:21 +00:00
this.$emit('close');
dialogStack.pop();
2018-07-20 01:12:26 +00:00
if(dialogStack.length === 0) isShowing = false;
2018-01-06 16:14:21 +00:00
}
hideWithCheck(): void {
2018-01-06 16:14:21 +00:00
if(this.keepOpen) return;
this.hide();
2017-09-02 01:50:31 +00:00
}
2019-01-03 17:38:17 +00:00
@Hook('beforeDestroy')
2017-09-02 01:50:31 +00:00
beforeDestroy(): void {
if(this.isShown) this.hide();
}
}
</script>
<style>
.flex-modal .modal-body > .form-group {
margin-left: 0;
margin-right: 0;
}
2020-03-14 21:24:49 +00:00
.modal-body:focus {
outline: none !important;
}
</style>