This commit is contained in:
tamaina 2023-08-01 14:28:44 +00:00
parent 93e8317da1
commit 485f89d262
5 changed files with 39 additions and 11 deletions

View File

@ -39,7 +39,7 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkSwitchButton :class="$style.switchButton" :checked="item.ref" :disabled="item.disabled" @toggle="switchItem(item)" /> <MkSwitchButton :class="$style.switchButton" :checked="item.ref" :disabled="item.disabled" @toggle="switchItem(item)" />
<span :class="$style.switchText">{{ item.text }}</span> <span :class="$style.switchText">{{ item.text }}</span>
</button> </button>
<button v-else-if="item.type === 'parent'" role="menuitem" :tabindex="i" class="_button" :class="[$style.item, $style.parent, { [$style.childShowing]: childShowingItem === item }]" @mouseenter="showChildren(item, $event)"> <button v-else-if="item.type === 'parent'" class="_button" role="menuitem" :tabindex="i" :class="[$style.item, $style.parent, { [$style.childShowing]: childShowingItem === item }]" @mouseenter.stop="showChildren(item, $event)">
<i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i> <i v-if="item.icon" class="ti-fw" :class="[$style.icon, item.icon]"></i>
<span>{{ item.text }}</span> <span>{{ item.text }}</span>
<span :class="$style.caret"><i class="ti ti-chevron-right ti-fw"></i></span> <span :class="$style.caret"><i class="ti ti-chevron-right ti-fw"></i></span>
@ -170,10 +170,9 @@ async function showChildren(item: MenuParent, ev: MouseEvent) {
} }
if (props.asDrawer) { if (props.asDrawer) {
os.popupMenu(children as Ref<MenuItem[]>, ev.currentTarget ?? ev.target, { os.popupMenu(children as Ref<MenuItem[]>, ev.currentTarget ?? ev.target).finally(() => {
onClosing: () => { console.log('child drawer close');
close(); emit('close');
}
}); });
emit('hide'); emit('hide');
} else { } else {
@ -356,6 +355,7 @@ onBeforeUnmount(() => {
} }
&.parent { &.parent {
pointer-events: auto;
display: flex; display: flex;
align-items: center; align-items: center;
cursor: default; cursor: default;

View File

@ -30,7 +30,7 @@ SPDX-License-Identifier: AGPL-3.0-only
[$style.transition_modal_leaveTo]: transitionName === 'modal', [$style.transition_modal_leaveTo]: transitionName === 'modal',
[$style.transition_send_leaveTo]: transitionName === 'send', [$style.transition_send_leaveTo]: transitionName === 'send',
})" })"
:duration="transitionDuration" appear @afterLeave="emit('closed')" @enter="emit('opening')" @afterEnter="onOpened" :duration="transitionDuration" appear @afterLeave="afterLeave" @enter="emit('opening')" @afterEnter="onOpened"
> >
<div v-show="manualShowing != null ? manualShowing : showing" v-hotkey.global="keymap" :class="[$style.root, { [$style.drawer]: type === 'drawer', [$style.dialog]: type === 'dialog', [$style.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="[$style.root, { [$style.drawer]: type === 'drawer', [$style.dialog]: type === 'dialog', [$style.popup]: type === 'popup' }]" :style="{ zIndex, pointerEvents: (manualShowing != null ? manualShowing : showing) ? 'auto' : 'none', '--transformOrigin': transformOrigin }">
<div data-cy-bg :data-cy-transparent="isEnableBgTransparent" class="_modalBg" :class="[$style.bg, { [$style.bgTransparent]: isEnableBgTransparent }]" :style="{ zIndex }" @click="onBgClick" @mousedown="onBgClick" @contextmenu.prevent.stop="() => {}"></div> <div data-cy-bg :data-cy-transparent="isEnableBgTransparent" class="_modalBg" :class="[$style.bg, { [$style.bgTransparent]: isEnableBgTransparent }]" :style="{ zIndex }" @click="onBgClick" @mousedown="onBgClick" @contextmenu.prevent.stop="() => {}"></div>
@ -42,7 +42,7 @@ SPDX-License-Identifier: AGPL-3.0-only
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { nextTick, normalizeClass, onMounted, onUnmounted, provide, watch } from 'vue'; import { nextTick, normalizeClass, onMounted, onUnmounted, onBeforeUnmount, provide, watch } 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';
@ -61,7 +61,12 @@ function getFixedContainer(el: Element | null): Element | null {
type ModalTypes = 'popup' | 'dialog' | 'drawer'; type ModalTypes = 'popup' | 'dialog' | 'drawer';
const props = withDefaults(defineProps<{ const props = withDefaults(defineProps<{
/**
* 手動で表示/非表示を切り替える
* falseに切り替えてもclosedは発火されないためcloseを呼ぶ必要がある
*/
manualShowing?: boolean | null; manualShowing?: boolean | null;
anchor?: { x: string; y: string; }; anchor?: { x: string; y: string; };
src?: HTMLElement | null; src?: HTMLElement | null;
preferType?: ModalTypes | 'auto'; preferType?: ModalTypes | 'auto';
@ -85,6 +90,7 @@ const emit = defineEmits<{
(ev: 'esc'): void; (ev: 'esc'): void;
(ev: 'close'): void; (ev: 'close'): void;
(ev: 'closed'): void; (ev: 'closed'): void;
(ev: 'hide'): void; // afterLeave
}>(); }>();
provide('modal', true); provide('modal', true);
@ -93,6 +99,7 @@ let maxHeight = $ref<number>();
let fixed = $ref(false); let fixed = $ref(false);
let transformOrigin = $ref('center'); let transformOrigin = $ref('center');
let showing = $ref(true); let showing = $ref(true);
let manuallyClosed = $ref(false);
let content = $shallowRef<HTMLElement>(); let content = $shallowRef<HTMLElement>();
const zIndex = os.claimZIndex(props.zPriority); const zIndex = os.claimZIndex(props.zPriority);
let useSendAnime = $ref(false); let useSendAnime = $ref(false);
@ -141,10 +148,20 @@ function close(opts: { useSendAnimation?: boolean } = {}) {
// 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 = false; showing = false;
manuallyClosed = true;
emit('close'); emit('close');
} }
function onBgClick() { function afterLeave() {
emit('hide');
console.log('closed?', props.manualShowing, manuallyClosed);
if (props.manualShowing === null || manuallyClosed) {
emit('closed');
}
}
function onBgClick(e) {
console.log(e);
if (contentClicking) return; if (contentClicking) return;
emit('click'); emit('click');
} }

View File

@ -4,8 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
--> -->
<template> <template>
<MkModal ref="modal" v-slot="{ type, maxHeight }" :manualShowing="manualShowing" :zPriority="'high'" :src="src" :transparentBg="true" @click="close" @close="emit('closing')" @closed="emit('closed')"> <MkModal ref="modal" v-slot="{ type, maxHeight }" :manualShowing="manualShowing" :zPriority="'high'" :src="src" :transparentBg="true" @click="click" @close="emit('closing')" @closed="emit('closed')">
<MkMenu :items="items" :align="align" :width="width" :max-height="maxHeight" :asDrawer="type === 'drawer'" :class="{ [$style.drawer]: type === 'drawer' }" @close="close" @hide="manualShowing = false"/> <MkMenu :items="items" :align="align" :width="width" :max-height="maxHeight" :asDrawer="type === 'drawer'" :class="{ [$style.drawer]: type === 'drawer' }" @close="_close" @hide="manualShowing = false"/>
</MkModal> </MkModal>
</template> </template>
@ -31,6 +31,16 @@ const emit = defineEmits<{
let modal = $shallowRef<InstanceType<typeof MkModal>>(); let modal = $shallowRef<InstanceType<typeof MkModal>>();
const manualShowing = ref(true); const manualShowing = ref(true);
function click() {
console.log('popup menu click');
close();
}
function _close() {
console.log('popup menu close event');
close();
}
function close() { function close() {
if (!modal) return; if (!modal) return;
manualShowing.value = false; manualShowing.value = false;

View File

@ -550,6 +550,7 @@ export function popupMenu(items: MenuItem[] | Ref<MenuItem[]>, src?: HTMLElement
viaKeyboard: options?.viaKeyboard, viaKeyboard: options?.viaKeyboard,
}, { }, {
closed: () => { closed: () => {
console.log('closed detected');
resolve(); resolve();
dispose(); dispose();
}, },

View File

@ -330,7 +330,7 @@ export function getUserMenu(user: misskey.entities.UserDetailed, router: Router
} }
const cleanup = () => { const cleanup = () => {
if (_DEV_) console.log('user menu cleanup', cleanups); console.log('user menu cleanup', cleanups);
cleanups.forEach(cleanup => cleanup()); cleanups.forEach(cleanup => cleanup());
}; };