수정
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
import React, { useCallback, useEffect, useLayoutEffect, useRef, useState } from 'react';
|
||||
import { createPortal } from 'react-dom';
|
||||
import {
|
||||
bindPaletteDragOverlayElement,
|
||||
notifyPaletteDragCancel,
|
||||
notifyPaletteDragEnd,
|
||||
notifyPaletteDragMove,
|
||||
registerPaletteDragOverlay,
|
||||
type PaletteDragOverlaySession,
|
||||
} from '../../utils/paletteDragSession';
|
||||
|
||||
/**
|
||||
* Tauri WebView — 드래그 중 전체 화면 overlay 가 pointer 이벤트·drop 을 수신
|
||||
*/
|
||||
export default function PaletteDragOverlay() {
|
||||
const [session, setSession] = useState<PaletteDragOverlaySession | null>(null);
|
||||
const [cursor, setCursor] = useState({ x: 0, y: 0 });
|
||||
const overlayRef = useRef<HTMLDivElement | null>(null);
|
||||
|
||||
useEffect(() => {
|
||||
registerPaletteDragOverlay({
|
||||
mount: next => {
|
||||
setCursor({ x: next.x, y: next.y });
|
||||
setSession(next);
|
||||
},
|
||||
unmount: () => setSession(null),
|
||||
bindElement: el => {
|
||||
overlayRef.current = el as HTMLDivElement | null;
|
||||
},
|
||||
});
|
||||
return () => registerPaletteDragOverlay(null);
|
||||
}, []);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
bindPaletteDragOverlayElement(overlayRef.current);
|
||||
return () => bindPaletteDragOverlayElement(null);
|
||||
}, [session]);
|
||||
|
||||
useLayoutEffect(() => {
|
||||
if (!session || !overlayRef.current) return;
|
||||
try {
|
||||
overlayRef.current.setPointerCapture(session.pointerId);
|
||||
} catch {
|
||||
/* body capture fallback */
|
||||
}
|
||||
}, [session]);
|
||||
|
||||
const onPointerMove = useCallback((e: React.PointerEvent) => {
|
||||
if (!session || e.pointerId !== session.pointerId) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
setCursor({ x: e.clientX, y: e.clientY });
|
||||
notifyPaletteDragMove(e.clientX, e.clientY);
|
||||
}, [session]);
|
||||
|
||||
const onPointerUp = useCallback((e: React.PointerEvent) => {
|
||||
if (!session || e.pointerId !== session.pointerId) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
notifyPaletteDragEnd(e.clientX, e.clientY);
|
||||
}, [session]);
|
||||
|
||||
const onPointerCancel = useCallback((e: React.PointerEvent) => {
|
||||
if (!session || e.pointerId !== session.pointerId) return;
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
notifyPaletteDragCancel(e.clientX, e.clientY);
|
||||
}, [session]);
|
||||
|
||||
if (!session) return null;
|
||||
|
||||
return createPortal(
|
||||
<div
|
||||
ref={overlayRef}
|
||||
className="se-palette-drag-overlay"
|
||||
onPointerMove={onPointerMove}
|
||||
onPointerUp={onPointerUp}
|
||||
onPointerCancel={onPointerCancel}
|
||||
>
|
||||
<div
|
||||
className="se-palette-drag-overlay-label"
|
||||
style={{ left: cursor.x, top: cursor.y }}
|
||||
>
|
||||
{session.payload.label}
|
||||
</div>
|
||||
</div>,
|
||||
document.body,
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user