전략편집기 목록방식 추가오류 수정

This commit is contained in:
Macbook
2026-06-18 08:58:54 +09:00
parent bde65b6ef8
commit 914afc9d5a
5 changed files with 121 additions and 187 deletions
+41 -7
View File
@@ -77,11 +77,30 @@ type HtmlPaletteDropRouter = (
let htmlDropRouter: HtmlPaletteDropRouter | null = null;
let htmlDropCommitted = false;
let paletteDropConsumed = false;
export function wasPaletteHtmlDropCommitted(): boolean {
return htmlDropCommitted;
}
/** 목록 편집기 등 — 드래그 하이라이트 클래스 일괄 제거 */
export function clearPaletteDropHighlights(): void {
if (typeof document === 'undefined') return;
document.querySelectorAll('.sp-drag-over').forEach(el => {
el.classList.remove('sp-drag-over');
});
}
function resetPaletteDropConsumed(): void {
paletteDropConsumed = false;
}
function tryConsumePaletteDrop(): boolean {
if (paletteDropConsumed) return false;
paletteDropConsumed = true;
return true;
}
export function setHtmlPaletteDropRouter(router: HtmlPaletteDropRouter | null): void {
htmlDropRouter = router;
}
@@ -180,10 +199,15 @@ function finishDrag(phase: 'end' | 'cancel', xy: { x: number; y: number }) {
if (phase === 'end') {
suppressClickUntil = Date.now() + 400;
dispatchEnd(dropXY, payload);
if (tryConsumePaletteDrop()) {
dispatchEnd(dropXY, payload);
} else {
emit({ phase: 'end', x: dropXY.x, y: dropXY.y, payload });
}
} else {
emit({ phase: 'cancel', x: dropXY.x, y: dropXY.y, payload });
}
clearPaletteDropHighlights();
cleanupDrag();
}
@@ -197,6 +221,8 @@ function mountDragOverlay(
activePayload = payload;
activePointerId = pointerId;
lastDragClientXY = { x: xy.x, y: xy.y };
resetPaletteDropConsumed();
clearPaletteDropHighlights();
document.body.classList.add('se-palette-drag-active');
armPaletteDragScrollLock();
overlayController?.mount({
@@ -375,9 +401,12 @@ function installHtmlPaletteDragGlobals() {
const payload = activeHtmlDragPayload;
const xy = lastHtmlDragClientXY;
if (htmlPaletteDragActive && !htmlDropCommitted && payload && xy && htmlDropRouter) {
htmlDropRouter(xy.x, xy.y, payload);
if (tryConsumePaletteDrop()) {
htmlDropRouter(xy.x, xy.y, payload);
}
}
htmlDropCommitted = false;
clearPaletteDropHighlights();
stopHtmlDragMouseTracking();
htmlPaletteDragActive = false;
lastHtmlDragClientXY = null;
@@ -390,9 +419,11 @@ function installHtmlPaletteDragGlobals() {
e.stopPropagation();
const payload = readPaletteHtmlDragDataFromEvent(e) ?? activeHtmlDragPayload;
if (!payload || !htmlDropRouter || htmlDropCommitted) return;
if (!tryConsumePaletteDrop()) return;
htmlDropCommitted = true;
const x = e.clientX !== 0 || e.clientY !== 0 ? e.clientX : (lastHtmlDragClientXY?.x ?? 0);
const y = e.clientX !== 0 || e.clientY !== 0 ? e.clientY : (lastHtmlDragClientXY?.y ?? 0);
clearPaletteDropHighlights();
htmlDropRouter(x, y, payload);
}, true);
}
@@ -432,6 +463,8 @@ export function endHtmlDragMouseTracking(): void {
export function markPaletteHtmlDragStart(): void {
htmlPaletteDragActive = true;
htmlDropCommitted = false;
resetPaletteDropConsumed();
clearPaletteDropHighlights();
lastHtmlDragClientXY = null;
}
@@ -484,15 +517,16 @@ export function readPaletteHtmlDragData(e: React.DragEvent): PaletteDragPayload
export function findPaletteDropKeyAtPoint(x: number, y: number): string | null {
const hosts = Array.from(document.querySelectorAll<HTMLElement>('[data-palette-drop-key]'));
for (let i = hosts.length - 1; i >= 0; i--) {
const host = hosts[i];
let best: { key: string; area: number } | null = null;
for (const host of hosts) {
const key = host.dataset.paletteDropKey;
if (!key) continue;
const rect = host.getBoundingClientRect();
if (x >= rect.left && x <= rect.right && y >= rect.top && y <= rect.bottom) {
return key;
}
if (x < rect.left || x > rect.right || y < rect.top || y > rect.bottom) continue;
const area = rect.width * rect.height;
if (!best || area < best.area) best = { key, area };
}
if (best) return best.key;
for (const el of elementsUnderDragPoint(x, y)) {
const host = el.closest('[data-palette-drop-key]') as HTMLElement | null;
if (host?.dataset.paletteDropKey) return host.dataset.paletteDropKey;