refactor(client): use setup sugar

This commit is contained in:
syuilo 2022-01-28 12:14:21 +09:00
parent 875f1b76e7
commit f098fb2dae

View file

@ -1,5 +1,5 @@
<template> <template>
<transition :name="$store.state.animation ? (type === 'drawer') ? 'modal-drawer' : (type === 'popup') ? 'modal-popup' : 'modal' : ''" :duration="$store.state.animation ? 200 : 0" appear @after-leave="$emit('closed')" @enter="$emit('opening')" @after-enter="childRendered"> <transition :name="$store.state.animation ? (type === 'drawer') ? 'modal-drawer' : (type === 'popup') ? 'modal-popup' : 'modal' : ''" :duration="$store.state.animation ? 200 : 0" appear @after-leave="emit('closed')" @enter="emit('opening')" @after-enter="childRendered">
<div v-show="manualShowing != null ? manualShowing : showing" v-hotkey.global="keymap" class="qzhlnise" :class="{ drawer: type === 'drawer', dialog: type === 'dialog' || type === 'dialog:top', popup: type === 'popup' }" :style="{ zIndex, pointerEvents: (manualShowing != null ? manualShowing : showing) ? 'auto' : 'none', '--transformOrigin': transformOrigin }"> <div v-show="manualShowing != null ? manualShowing : showing" v-hotkey.global="keymap" class="qzhlnise" :class="{ drawer: type === 'drawer', dialog: type === 'dialog' || type === 'dialog:top', popup: type === 'popup' }" :style="{ zIndex, pointerEvents: (manualShowing != null ? manualShowing : showing) ? 'auto' : 'none', '--transformOrigin': transformOrigin }">
<div class="bg _modalBg" :class="{ transparent: transparentBg && (type === 'popup') }" :style="{ zIndex }" @click="onBgClick" @contextmenu.prevent.stop="() => {}"></div> <div class="bg _modalBg" :class="{ transparent: transparentBg && (type === 'popup') }" :style="{ zIndex }" @click="onBgClick" @contextmenu.prevent.stop="() => {}"></div>
<div ref="content" class="content" :class="{ fixed, top: type === 'dialog:top' }" :style="{ zIndex }" @click.self="onBgClick"> <div ref="content" class="content" :class="{ fixed, top: type === 'dialog:top' }" :style="{ zIndex }" @click.self="onBgClick">
@ -9,8 +9,8 @@
</transition> </transition>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { defineComponent, nextTick, onMounted, computed, PropType, ref, watch } from 'vue'; import { nextTick, onMounted, computed, ref, watch, provide } from 'vue';
import * as os from '@/os'; import * as os from '@/os';
import { isTouchUsing } from '@/scripts/touch'; import { isTouchUsing } from '@/scripts/touch';
import { defaultStore } from '@/store'; import { defaultStore } from '@/store';
@ -25,58 +25,40 @@ function getFixedContainer(el: Element | null): Element | null {
} }
} }
export default defineComponent({ const props = withDefaults(defineProps<{
provide: { manualShowing?: boolean;
modal: true srcCenter?: boolean;
}, src?: HTMLElement;
preferType?: string;
zPriority?: 'low' | 'middle' | 'high';
noOverlap?: boolean;
transparentBg?: boolean;
}>(), {
manualShowing: null,
src: null,
preferType: 'auto',
zPriority: 'low',
noOverlap: true,
transparentBg: false,
});
props: { const emit = defineEmits<{
manualShowing: { (ev: 'opening'): void;
type: Boolean, (ev: 'click'): void;
required: false, (ev: 'esc'): void;
default: null, (ev: 'close'): void;
}, (ev: 'closed'): void;
srcCenter: { }>();
type: Boolean,
required: false
},
src: {
type: Object as PropType<HTMLElement>,
required: false,
default: null,
},
preferType: {
required: false,
type: String,
default: 'auto',
},
zPriority: {
type: String as PropType<'low' | 'middle' | 'high'>,
required: false,
default: 'low',
},
noOverlap: {
type: Boolean,
required: false,
default: true,
},
transparentBg: {
type: Boolean,
required: false,
default: false,
},
},
emits: ['opening', 'click', 'esc', 'close', 'closed'], provide('modal', true);
setup(props, context) { const maxHeight = ref<number>();
const maxHeight = ref<number>(); const fixed = ref(false);
const fixed = ref(false); const transformOrigin = ref('center');
const transformOrigin = ref('center'); const showing = ref(true);
const showing = ref(true); const content = ref<HTMLElement>();
const content = ref<HTMLElement>(); const zIndex = os.claimZIndex(props.zPriority);
const zIndex = os.claimZIndex(props.zPriority); const type = computed(() => {
const type = computed(() => {
if (props.preferType === 'auto') { if (props.preferType === 'auto') {
if (!defaultStore.state.disableDrawer && isTouchUsing && window.innerWidth < 500 && window.innerHeight < 1000) { if (!defaultStore.state.disableDrawer && isTouchUsing && window.innerWidth < 500 && window.innerHeight < 1000) {
return 'drawer'; return 'drawer';
@ -86,33 +68,33 @@ export default defineComponent({
} else { } else {
return props.preferType; return props.preferType;
} }
}); });
let contentClicking = false; let contentClicking = false;
const close = () => { const close = () => {
// eslint-disable-next-line vue/no-mutating-props // eslint-disable-next-line vue/no-mutating-props
if (props.src) props.src.style.pointerEvents = 'auto'; if (props.src) props.src.style.pointerEvents = 'auto';
showing.value = false; showing.value = false;
context.emit('close'); emit('close');
}; };
const onBgClick = () => { const onBgClick = () => {
if (contentClicking) return; if (contentClicking) return;
context.emit('click'); emit('click');
}; };
if (type.value === 'drawer') { if (type.value === 'drawer') {
maxHeight.value = window.innerHeight / 2; maxHeight.value = window.innerHeight / 2;
} }
const keymap = { const keymap = {
'esc': () => context.emit('esc'), 'esc': () => emit('esc'),
}; };
const MARGIN = 16; const MARGIN = 16;
const align = () => { const align = () => {
if (props.src == null) return; if (props.src == null) return;
if (type.value === 'drawer') return; if (type.value === 'drawer') return;
@ -202,23 +184,23 @@ export default defineComponent({
popover.style.left = left + 'px'; popover.style.left = left + 'px';
popover.style.top = top + 'px'; popover.style.top = top + 'px';
}; };
const childRendered = () => { const childRendered = () => {
// //
const el = content.value!.children[0]; const el = content.value!.children[0];
el.addEventListener('mousedown', e => { el.addEventListener('mousedown', ev => {
contentClicking = true; contentClicking = true;
window.addEventListener('mouseup', e => { window.addEventListener('mouseup', ev => {
// click mouseup // click mouseup
window.setTimeout(() => { window.setTimeout(() => {
contentClicking = false; contentClicking = false;
}, 100); }, 100);
}, { passive: true, once: true }); }, { passive: true, once: true });
}, { passive: true }); }, { passive: true });
}; };
onMounted(() => { onMounted(() => {
watch(() => props.src, async () => { watch(() => props.src, async () => {
if (props.src) { if (props.src) {
// eslint-disable-next-line vue/no-mutating-props // eslint-disable-next-line vue/no-mutating-props
@ -237,22 +219,10 @@ export default defineComponent({
align(); align();
}).observe(popover!); }).observe(popover!);
}); });
}); });
return { defineExpose({
showing,
type,
fixed,
content,
transformOrigin,
maxHeight,
close, close,
zIndex,
keymap,
onBgClick,
childRendered,
};
},
}); });
</script> </script>