11import { createContext , useCallback , useContext , useRef } from 'react' ;
22import type { ChessDragData } from '@constants' ;
33
4- // Types
54export interface DragSession {
65 dragData : ChessDragData ;
76 ghost : HTMLDivElement ;
@@ -20,7 +19,6 @@ export interface DragContextValue {
2019 unregisterDropTarget ( id : string ) : void ;
2120}
2221
23- // Context
2422export const DragCtx = createContext < DragContextValue > ( {
2523 active : null ,
2624 overId : null ,
@@ -33,7 +31,6 @@ export function useDragContext() {
3331 return useContext ( DragCtx ) ;
3432}
3533
36- // Draggable
3734interface UseDraggableOptions {
3835 data : ChessDragData ;
3936 cellSize : number ;
@@ -71,12 +68,31 @@ export function useDraggable({
7168
7269 const ghost = document . createElement ( 'div' ) ;
7370 ghost . setAttribute ( 'aria-hidden' , 'true' ) ;
74- ghost . style . cssText = `position:fixed;top:0;left:0;width:${ size } px;height:${ size } px;pointer-events:none;z-index:9999;will-change:transform;transform:translate(${ e . clientX - half } px,${ e . clientY - half } px);` ;
71+ ghost . style . cssText = [
72+ `position:fixed` ,
73+ `top:0` ,
74+ `left:0` ,
75+ `width:${ size } px` ,
76+ `height:${ size } px` ,
77+ `pointer-events:none` ,
78+ `z-index:9999` ,
79+ `will-change:transform` ,
80+ `transform:translate(${ e . clientX - half } px,${ e . clientY - half } px)`
81+ ] . join ( ';' ) ;
7582
7683 const img = document . createElement ( 'img' ) ;
7784 img . src = imageSrc ;
7885 img . draggable = false ;
79- img . style . cssText = `width:100%;height:100%;object-fit:contain;opacity:0.92;filter:drop-shadow(0 3px 8px rgba(0,0,0,0.55));pointer-events:none;user-select:none;-webkit-user-select:none;` ;
86+ img . style . cssText = [
87+ 'width:100%' ,
88+ 'height:100%' ,
89+ 'object-fit:contain' ,
90+ 'opacity:0.9' ,
91+ 'filter:drop-shadow(0 2px 6px rgba(0,0,0,0.4))' ,
92+ 'pointer-events:none' ,
93+ 'user-select:none' ,
94+ '-webkit-user-select:none'
95+ ] . join ( ';' ) ;
8096 ghost . appendChild ( img ) ;
8197
8298 _startDrag ( { dragData : dataRef . current , ghost, halfSize : half } ) ;
@@ -88,27 +104,22 @@ export function useDraggable({
88104 return { isDragging, onPointerDown } ;
89105}
90106
91- // Droppable
92107interface UseDroppableOptions {
93108 id : string ;
94109 data : Record < string , unknown > ;
95110}
96111
97112export function useDroppable ( { id, data } : UseDroppableOptions ) {
98113 const { overId, registerDropTarget, unregisterDropTarget } = useDragContext ( ) ;
99- const dataRef = useRef ( data ) ;
100- dataRef . current = data ;
101- const registerRef = useRef ( registerDropTarget ) ;
102- registerRef . current = registerDropTarget ;
103- const unregisterRef = useRef ( unregisterDropTarget ) ;
104- unregisterRef . current = unregisterDropTarget ;
114+ const stateRef = useRef ( { data, registerDropTarget, unregisterDropTarget } ) ;
115+ stateRef . current = { data, registerDropTarget, unregisterDropTarget } ;
105116
106117 const setNodeRef = useCallback (
107118 ( el : HTMLElement | null ) => {
108119 if ( el ) {
109- registerRef . current ( id , el , dataRef . current ) ;
120+ stateRef . current . registerDropTarget ( id , el , stateRef . current . data ) ;
110121 } else {
111- unregisterRef . current ( id ) ;
122+ stateRef . current . unregisterDropTarget ( id ) ;
112123 }
113124 } ,
114125 [ id ]
0 commit comments