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>
<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 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">
@ -9,8 +9,8 @@
</transition>
</template>
<script lang="ts">
import { defineComponent, nextTick, onMounted, computed, PropType, ref, watch } from 'vue';
<script lang="ts" setup>
import { nextTick, onMounted, computed, ref, watch, provide } from 'vue';
import * as os from '@/os';
import { isTouchUsing } from '@/scripts/touch';
import { defaultStore } from '@/store';
@ -25,58 +25,40 @@ function getFixedContainer(el: Element | null): Element | null {
}
}
export default defineComponent({
provide: {
modal: true
},
const props = withDefaults(defineProps<{
manualShowing?: boolean;
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: {
manualShowing: {
type: Boolean,
required: false,
default: null,
},
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,
},
},
const emit = defineEmits<{
(ev: 'opening'): void;
(ev: 'click'): void;
(ev: 'esc'): void;
(ev: 'close'): void;
(ev: 'closed'): void;
}>();
emits: ['opening', 'click', 'esc', 'close', 'closed'],
provide('modal', true);
setup(props, context) {
const maxHeight = ref<number>();
const fixed = ref(false);
const transformOrigin = ref('center');
const showing = ref(true);
const content = ref<HTMLElement>();
const zIndex = os.claimZIndex(props.zPriority);
const type = computed(() => {
const maxHeight = ref<number>();
const fixed = ref(false);
const transformOrigin = ref('center');
const showing = ref(true);
const content = ref<HTMLElement>();
const zIndex = os.claimZIndex(props.zPriority);
const type = computed(() => {
if (props.preferType === 'auto') {
if (!defaultStore.state.disableDrawer && isTouchUsing && window.innerWidth < 500 && window.innerHeight < 1000) {
return 'drawer';
@ -86,33 +68,33 @@ export default defineComponent({
} else {
return props.preferType;
}
});
});
let contentClicking = false;
let contentClicking = false;
const close = () => {
const close = () => {
// eslint-disable-next-line vue/no-mutating-props
if (props.src) props.src.style.pointerEvents = 'auto';
showing.value = false;
context.emit('close');
};
emit('close');
};
const onBgClick = () => {
const onBgClick = () => {
if (contentClicking) return;
context.emit('click');
};
emit('click');
};
if (type.value === 'drawer') {
if (type.value === 'drawer') {
maxHeight.value = window.innerHeight / 2;
}
}
const keymap = {
'esc': () => context.emit('esc'),
};
const keymap = {
'esc': () => emit('esc'),
};
const MARGIN = 16;
const MARGIN = 16;
const align = () => {
const align = () => {
if (props.src == null) return;
if (type.value === 'drawer') return;
@ -202,23 +184,23 @@ export default defineComponent({
popover.style.left = left + 'px';
popover.style.top = top + 'px';
};
};
const childRendered = () => {
const childRendered = () => {
//
const el = content.value!.children[0];
el.addEventListener('mousedown', e => {
el.addEventListener('mousedown', ev => {
contentClicking = true;
window.addEventListener('mouseup', e => {
window.addEventListener('mouseup', ev => {
// click mouseup
window.setTimeout(() => {
contentClicking = false;
}, 100);
}, { passive: true, once: true });
}, { passive: true });
};
};
onMounted(() => {
onMounted(() => {
watch(() => props.src, async () => {
if (props.src) {
// eslint-disable-next-line vue/no-mutating-props
@ -237,22 +219,10 @@ export default defineComponent({
align();
}).observe(popover!);
});
});
});
return {
showing,
type,
fixed,
content,
transformOrigin,
maxHeight,
defineExpose({
close,
zIndex,
keymap,
onBgClick,
childRendered,
};
},
});
</script>