From e8eaed6ff5def5a4fd0e4901272cf16c2af9a396 Mon Sep 17 00:00:00 2001 From: zenn Date: Fri, 24 Jul 2026 16:50:25 +0900 Subject: [PATCH] =?UTF-8?q?=EC=BD=9C=EC=95=84=EC=9B=83=20=ED=8C=A8?= =?UTF-8?q?=EB=84=90=20=ED=86=A0=EA=B8=80=20=EB=8B=AB=ED=9E=98=20=EB=B0=A9?= =?UTF-8?q?=EC=A7=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- components/admin/AdminEditorBlockPanel.vue | 38 ++++++++++++++++++++-- docs/map.md | 2 +- docs/spec.md | 2 +- docs/update.md | 5 +++ package-lock.json | 4 +-- package.json | 2 +- 6 files changed, 45 insertions(+), 8 deletions(-) diff --git a/components/admin/AdminEditorBlockPanel.vue b/components/admin/AdminEditorBlockPanel.vue index 824b1a1..c90c5c4 100644 --- a/components/admin/AdminEditorBlockPanel.vue +++ b/components/admin/AdminEditorBlockPanel.vue @@ -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) +})