콜아웃 패널 토글 닫힘 방지
This commit is contained in:
@@ -80,6 +80,11 @@ const inlineColorSwatches = {
|
||||
|
||||
const languageOptions = ['', 'javascript', 'html', 'css', 'vue', 'json', 'bash', 'markdown', 'sql']
|
||||
|
||||
/** @type {number|null} 패널 내부 포인터 조작 상태 해제 타이머 */
|
||||
let panelPointerInsideTimer = null
|
||||
/** @type {boolean} 패널 내부 포인터 조작 중 여부 */
|
||||
let isPanelPointerInside = false
|
||||
|
||||
/**
|
||||
* 배경 라벨을 반환한다.
|
||||
* @param {string} background - 배경 키
|
||||
@@ -395,6 +400,19 @@ const commitImagePixelWidthChange = (imageIndex, image, event) => {
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 패널 내부 포인터 조작 중에는 포커스 이탈로 패널이 닫히지 않게 유지한다.
|
||||
* @returns {void}
|
||||
*/
|
||||
const markPanelPointerInside = () => {
|
||||
window.clearTimeout(panelPointerInsideTimer)
|
||||
isPanelPointerInside = true
|
||||
emit('panel-focus-in')
|
||||
panelPointerInsideTimer = window.setTimeout(() => {
|
||||
isPanelPointerInside = false
|
||||
}, 300)
|
||||
}
|
||||
|
||||
/**
|
||||
* 포커스가 패널 밖으로 나갔을 때만 이탈 이벤트를 보낸다.
|
||||
* @param {FocusEvent} event - focusout 이벤트
|
||||
@@ -408,8 +426,16 @@ const onPanelFocusOut = (event) => {
|
||||
return
|
||||
}
|
||||
|
||||
if (isPanelPointerInside) {
|
||||
return
|
||||
}
|
||||
|
||||
emit('panel-focus-out')
|
||||
}
|
||||
|
||||
onBeforeUnmount(() => {
|
||||
window.clearTimeout(panelPointerInsideTimer)
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
@@ -417,6 +443,7 @@ const onPanelFocusOut = (event) => {
|
||||
class="admin-editor-block-panel absolute inset-0 z-20 flex flex-col bg-white shadow-[-8px_0_24px_rgba(15,23,42,0.08)] transition-transform duration-300 ease-out"
|
||||
:class="open ? 'translate-x-0' : 'translate-x-full pointer-events-none'"
|
||||
:aria-hidden="!open"
|
||||
@pointerdown.capture="markPanelPointerInside"
|
||||
@focusin="emit('panel-focus-in')"
|
||||
@focusout="onPanelFocusOut"
|
||||
>
|
||||
@@ -555,16 +582,20 @@ const onPanelFocusOut = (event) => {
|
||||
</span>
|
||||
</label>
|
||||
|
||||
<div class="grid gap-2">
|
||||
<div
|
||||
class="admin-editor-block-panel__callout-icon-options grid gap-2 transition-opacity"
|
||||
:class="panel.calloutEmojiEnabled ? '' : 'opacity-45'"
|
||||
>
|
||||
<p class="text-sm font-semibold text-[#394047]">
|
||||
아이콘
|
||||
</p>
|
||||
<input
|
||||
class="rounded border border-[#d7dde2] bg-[#eff1f2] px-3 py-2 text-sm text-[#15171a] outline-none transition-colors focus:border-[#8e9cac]"
|
||||
class="rounded border border-[#d7dde2] bg-[#eff1f2] px-3 py-2 text-sm text-[#15171a] outline-none transition-colors focus:border-[#8e9cac] disabled:cursor-not-allowed"
|
||||
:value="panel.calloutEmoji"
|
||||
type="text"
|
||||
maxlength="4"
|
||||
placeholder="💡"
|
||||
:disabled="!panel.calloutEmojiEnabled"
|
||||
@input="emit('update-callout-options', { calloutEmojiEnabled: true, calloutEmoji: $event.target.value })"
|
||||
>
|
||||
<div class="grid grid-cols-5 gap-2">
|
||||
@@ -572,8 +603,9 @@ const onPanelFocusOut = (event) => {
|
||||
v-for="emoji in CALLOUT_EMOJI_OPTIONS"
|
||||
:key="`callout-emoji-${emoji}`"
|
||||
class="grid h-10 place-items-center rounded border text-lg transition"
|
||||
:class="panel.calloutEmoji === emoji && panel.calloutEmojiEnabled ? 'border-[#15171a] bg-white' : 'border-[#dce0e5] bg-[#fafafa] hover:bg-white'"
|
||||
:class="panel.calloutEmojiEnabled && panel.calloutEmoji === emoji ? 'border-[#15171a] bg-white' : panel.calloutEmojiEnabled ? 'border-[#dce0e5] bg-[#fafafa] hover:bg-white' : 'cursor-not-allowed border-[#dce0e5] bg-[#f4f5f6] text-[#a4adb8]'"
|
||||
type="button"
|
||||
:disabled="!panel.calloutEmojiEnabled"
|
||||
@mousedown.prevent
|
||||
@click="emit('update-callout-options', { calloutEmojiEnabled: true, calloutEmoji: emoji })"
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user