import { extractClosestEdge } from '@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge'; /** * Shared drag-and-drop state contract. * * Controllers reflect interaction state on these bare `data-*` attributes so * CSS can react — no visual styling is applied in JS. The optional theme * (`@42/styles/dnd.css`) provides overridable feedback for every component * that uses this contract; consumers can target the same attributes. * * - `data-dragging` → on the element currently being dragged * - `data-drop-target` → on a drop target while a compatible drag is over it * - `data-drop-edge` → on a drop target: where the item will land * (`top` | `bottom` | `left` | `right`) * - `data-dropped` → briefly on an element right after it was dropped */ export const DND_STATE = { dragging: 'dragging', dropTarget: 'dropTarget', edge: 'dropEdge', dropped: 'dropped', } as const; /** Flag `el` as the element currently being dragged. */ export function markDragging(el: HTMLElement): void { el.dataset[DND_STATE.dragging] = ''; } /** Remove the dragging flag from `el`. */ export function clearDragging(el: HTMLElement): void { delete el.dataset[DND_STATE.dragging]; } /** * Flag `el` as the active drop target. When `data` carries a closest edge * (from `attachClosestEdge`), also reflect it on `data-drop-edge`. */ export function markDropTarget(el: HTMLElement, data?: Record): void { el.dataset[DND_STATE.dropTarget] = ''; const edge = data ? extractClosestEdge(data) : null; if (edge) { el.dataset[DND_STATE.edge] = edge; } else { delete el.dataset[DND_STATE.edge]; } } /** Clear all drop-target state from `el`. */ export function clearDropTarget(el: HTMLElement): void { delete el.dataset[DND_STATE.dropTarget]; delete el.dataset[DND_STATE.edge]; } /** * Briefly flag `el` as just-dropped so CSS can play a settle animation, then * remove the flag. A pending timer is harmless if the element is detached * (e.g. after `destroy()`). */ export function flashDropped(el: HTMLElement, ms = 220): void { el.dataset[DND_STATE.dropped] = ''; setTimeout(() => { delete el.dataset[DND_STATE.dropped]; }, ms); }