[755] 객체 선택 시 Del/Backspace 즉시 삭제 #823

Merged
ysCha merged 1 commits from dev into dev-deploy 2026-05-07 12:17:55 +09:00
2 changed files with 55 additions and 17 deletions

View File

@ -1,5 +1,5 @@
'use client'
import { useEffect } from 'react'
import { useEffect, useRef } from 'react'
import '@/styles/contents.scss'
import { useRecoilState, useRecoilValue } from 'recoil'
import { contextMenuListState, contextMenuState } from '@/store/contextMenu'
@ -15,8 +15,13 @@ export default function QContextMenu(props) {
const contextMenuList = useRecoilValue(contextMenuListState)
const currentObject = useRecoilValue(currentObjectState)
const { tempGridMode, setTempGridMode } = useTempGrid()
const { handleKeyup } = useContextMenu()
const { handleKeyup, triggerDelete } = useContextMenu()
const { addDocumentEventListener, removeDocumentEvent } = useEvent()
// [TMP-DEL 2026-05-07] Del : ref
const handleKeyupRef = useRef(handleKeyup)
handleKeyupRef.current = handleKeyup
const triggerDeleteRef = useRef(triggerDelete)
triggerDeleteRef.current = triggerDelete
// const { addDocumentEventListener, removeDocumentEvent } = useContext(EventContext)
const getYPosition = (e) => {
@ -39,7 +44,7 @@ export default function QContextMenu(props) {
y: window.innerHeight / 2 < e.pageY ? getYPosition(e) : e.pageY,
}
setContextMenu({ visible: true, ...position, currentMousePos: canvasProps.getPointer(e) })
addDocumentEventListener('keyup', document, handleKeyup)
// [TMP-DEL 2026-05-07] keyup useEffect . .
}
}
@ -52,7 +57,7 @@ export default function QContextMenu(props) {
// e.preventDefault()
if (contextMenu.visible) {
setContextMenu({ ...contextMenu, visible: false })
removeDocumentEvent('keyup')
// [TMP-DEL 2026-05-07] Del keyup
}
}
@ -64,13 +69,33 @@ export default function QContextMenu(props) {
document.addEventListener('click', handleOutsideClick)
return () => {
removeDocumentEvent('keyup')
// [TMP-DEL 2026-05-07] keyup useEffect lifecycle . wrappedKeyup
document.removeEventListener('click', handleClick)
document.removeEventListener('click', handleOutsideClick)
canvasProps?.upperCanvasEl.removeEventListener('contextmenu', handleContextMenu) //
}
}, [contextRef, contextMenuList, currentObject])
// [TMP-DEL 2026-05-07] Del . (M/C ) handleKeyup .
// input/textarea/contentEditable .
useEffect(() => {
if (!currentObject) {
removeDocumentEvent('keyup')
return
}
const wrappedKeyup = (e) => {
const el = document.activeElement
if (el && (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA' || el.isContentEditable)) return
if (e.key === 'Delete' || e.key === 'Backspace') {
triggerDeleteRef.current()
return
}
handleKeyupRef.current(e)
}
addDocumentEventListener('keyup', document, wrappedKeyup)
return () => removeDocumentEvent('keyup')
}, [currentObject])
return (
<>
{contextMenu.visible && (

View File

@ -114,6 +114,24 @@ export function useContextMenu() {
if (menu) handleClick(null, menu)
}
// [TMP-DEL 2026-05-07] Del 키용: 현재 contextMenu 에서 삭제 메뉴를 찾아 실행
// 매칭 규칙: id === 'remove' 또는 id 가 'Remove' 로 끝남 (단, 'wallLineRemove' 제외, 'RemoveAll' 제외)
const triggerDelete = () => {
let target = null
for (const group of contextMenu) {
for (const item of group) {
const id = item?.id || ''
if (id === 'wallLineRemove') continue
if (id === 'remove' || id.endsWith('Remove')) {
target = item
break
}
}
if (target) break
}
if (target?.fn) handleClick(null, target)
}
useEffect(() => {
currentMenuSetting()
}, [gridColor, currentMenu])
@ -132,8 +150,7 @@ export function useContextMenu() {
[
{
id: 'dormerRemove',
shortcut: ['d', 'D'],
name: `${getMessage('contextmenu.remove')}(D)`,
name: getMessage('contextmenu.remove'),
fn: () => deleteObject(),
},
{
@ -206,8 +223,7 @@ export function useContextMenu() {
},
{
id: 'roofMaterialRemove',
shortcut: ['d', 'D'],
name: `${getMessage('contextmenu.remove')}(D)`,
name: getMessage('contextmenu.remove'),
fn: () => deleteObject(),
},
{
@ -300,8 +316,7 @@ export function useContextMenu() {
},
{
id: 'roofMaterialRemove',
shortcut: ['d', 'D'],
name: `${getMessage('contextmenu.remove')}(D)`,
name: getMessage('contextmenu.remove'),
fn: () => deleteObject(),
},
{
@ -364,8 +379,7 @@ export function useContextMenu() {
},
{
id: 'auxiliaryRemove',
shortcut: ['d', 'D'],
name: `${getMessage('contextmenu.auxiliary.remove')}(D)`,
name: getMessage('contextmenu.auxiliary.remove'),
fn: () => {
if (!currentObject) return
const roof = canvas.getObjects().filter((obj) => obj.id === currentObject.attributes.roofId)[0]
@ -474,8 +488,7 @@ export function useContextMenu() {
},
{
id: 'openingRemove',
shortcut: ['d', 'D'],
name: `${getMessage('contextmenu.remove')}(D)`,
name: getMessage('contextmenu.remove'),
fn: () => deleteObject(),
},
{
@ -677,8 +690,7 @@ export function useContextMenu() {
},
{
id: 'remove',
shortcut: ['d', 'D'],
name: `${getMessage('contextmenu.remove')}(D)`,
name: getMessage('contextmenu.remove'),
fn: () => deleteObject(),
},
{
@ -973,5 +985,6 @@ export function useContextMenu() {
setCurrentContextMenu,
handleClick,
handleKeyup,
triggerDelete, // [TMP-DEL 2026-05-07]
}
}