From 5e1d4380d9e077485c1473c6ff41e4b4cfa7783a Mon Sep 17 00:00:00 2001 From: kent Date: Mon, 1 Dec 2025 22:19:53 +0900 Subject: [PATCH] =?UTF-8?q?fix:=20=EB=A9=94=EB=89=B4=20=EB=93=9C=EB=9E=98?= =?UTF-8?q?=EA=B7=B8=20=EC=8B=9C=EA=B0=81=EC=A0=81=20=ED=94=BC=EB=93=9C?= =?UTF-8?q?=EB=B0=B1=20=EB=B0=8F=20=EC=88=9C=EC=84=9C=EB=B3=80=EA=B2=BD=20?= =?UTF-8?q?=EB=B2=84=EA=B7=B8=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - forceFallback: true 추가 (네이티브 드래그 → 자체 구현) → mousemove 이벤트 정상 발생, 인디케이터/하이라이트 작동 - 드래그 중 텍스트 선택 방지 (body.is-dragging + user-select: none) - 순서변경(reorder) 시 원래 부모 유지 (계층 변경 버그 수정) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- resources/views/menus/index.blade.php | 57 +++++++++++++++++++++------ 1 file changed, 46 insertions(+), 11 deletions(-) diff --git a/resources/views/menus/index.blade.php b/resources/views/menus/index.blade.php index 6fffb0bd..ca9868c0 100644 --- a/resources/views/menus/index.blade.php +++ b/resources/views/menus/index.blade.php @@ -122,6 +122,38 @@ class="bg-white rounded-lg shadow-sm overflow-hidden"> z-index: 100; transition: width 0.15s, left 0.15s; } + + /* SortableJS fallback 모드 스타일 (forceFallback: true) */ + .sortable-fallback { + opacity: 0.9; + background: white !important; + box-shadow: 0 4px 12px rgba(0,0,0,0.15); + border-radius: 4px; + z-index: 9998 !important; + } + + /* 드래그 중 텍스트 선택 방지 */ + .sortable-drag, .sortable-chosen, .sortable-ghost { + user-select: none !important; + -webkit-user-select: none !important; + } + + /* 드래그 핸들 영역 텍스트 선택 방지 */ + .drag-handle { + user-select: none; + -webkit-user-select: none; + } + + /* 드래그 중 전체 페이지 텍스트 선택 방지 */ + body.is-dragging { + user-select: none !important; + -webkit-user-select: none !important; + cursor: grabbing !important; + } + body.is-dragging * { + user-select: none !important; + -webkit-user-select: none !important; + } @endpush @@ -268,9 +300,13 @@ function onDragMove(e) { } // SortableJS 초기화 - 노션 스타일 인덴트 + // forceFallback: true → 네이티브 드래그 대신 자체 구현 사용 (mousemove 이벤트 정상 발생) tbody.sortableInstance = new Sortable(tbody, { handle: '.drag-handle', animation: 150, + forceFallback: true, // 브라우저 네이티브 드래그 비활성화 → mousemove 정상 작동 + fallbackClass: 'sortable-fallback', + fallbackOnBody: true, ghostClass: 'bg-blue-50', chosenClass: 'bg-blue-100', dragClass: 'shadow-lg', @@ -281,6 +317,9 @@ function onDragMove(e) { currentDragItem = evt.item; dragIndicator = createDragIndicator(); + // 드래그 중 텍스트 선택 방지 + document.body.classList.add('is-dragging'); + // 마우스 이동 이벤트 리스너 추가 document.addEventListener('mousemove', onDragMove); document.addEventListener('touchmove', onDragMove); @@ -297,6 +336,9 @@ function onDragMove(e) { removeDragIndicator(); currentDragItem = null; + // 드래그 중 텍스트 선택 방지 해제 + document.body.classList.remove('is-dragging'); + const movedItem = evt.item; const menuId = parseInt(movedItem.dataset.menuId); const currentDepth = parseInt(movedItem.dataset.depth) || 0; @@ -352,17 +394,10 @@ function onDragMove(e) { } // 수평 이동 없음 → 같은 레벨에서 순서만 변경 else { - // 위 행과 같은 부모로 (기존 동작) - if (newIndex > 0) { - const prevRow = rows[newIndex - 1]; - if (prevRow) { - const prevParentIdRaw = prevRow.dataset.parentId; - newParentId = prevParentIdRaw === '' ? null : (prevParentIdRaw ? parseInt(prevParentIdRaw) : null); - } - } else { - newParentId = null; - } - console.log('↔ REORDER: 위 행과 같은 레벨로, newParentId:', newParentId); + // 원래 부모 유지 (순서만 변경, 계층 변경 안함) + newParentId = oldPid; + action = 'reorder'; + console.log('↔ REORDER: 같은 부모 유지, parentId:', newParentId); } const parentChanged = oldPid !== newParentId;