Skip to content

Commit

Permalink
feat: add custom dragstart event and improve drag enter/leave handling
Browse files Browse the repository at this point in the history
  • Loading branch information
colecrouter committed Nov 26, 2024
1 parent 0ba36d3 commit cf4f62e
Show file tree
Hide file tree
Showing 2 changed files with 30 additions and 14 deletions.
4 changes: 4 additions & 0 deletions src/lib/actions/draggable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ export function draggable<T>(node: HTMLElement, options: DragDropOptions<T>) {

node.classList.add(...draggingClass);
options.callbacks?.onDragStart?.(dndState as DragDropState<T>);

// **Dispatch the custom event that bubbles up to the container**
const customEvent = new CustomEvent('dragstart-on-container', { bubbles: true });
node.dispatchEvent(customEvent);
}

function handleDragEnd() {
Expand Down
40 changes: 26 additions & 14 deletions src/lib/actions/droppable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,34 +5,35 @@ const DEFAULT_DRAG_OVER_CLASS = 'drag-over';

export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
const dragOverClass = (options.attributes?.draggingClass || DEFAULT_DRAG_OVER_CLASS).split(' ');
let dragEnterCounter = 0; // Initialize the counter

function handleDragEnter(event: DragEvent) {
if (options.disabled) return;
event.preventDefault();

const target = event.target as HTMLElement;
dragEnterCounter++;

dndState.targetContainer = options.container;
dndState.targetElement = target;
dndState.targetElement = event.target as HTMLElement;

node.classList.add(...dragOverClass);
options.callbacks?.onDragEnter?.(dndState as DragDropState<T>);
}
if (dragEnterCounter === 1) {
node.classList.add(...dragOverClass);
options.callbacks?.onDragEnter?.(dndState as DragDropState<T>);
}
}

function handleDragLeave(event: DragEvent) {
if (options.disabled) return;

const target = event.target as HTMLElement;

// check if element is still being dragged over
if (!dndState.targetElement?.isSameNode(target)) return;

node.classList.remove(...dragOverClass);
dragEnterCounter--;

options.callbacks?.onDragLeave?.(dndState as DragDropState<T>);
if (dragEnterCounter === 0) {
node.classList.remove(...dragOverClass);
options.callbacks?.onDragLeave?.(dndState as DragDropState<T>);

dndState.targetContainer = null;
dndState.targetElement = null;
dndState.targetContainer = null;
dndState.targetElement = null;
}
}

function handleDragOver(event: DragEvent) {
Expand All @@ -50,6 +51,7 @@ export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
if (options.disabled) return;
event.preventDefault();

dragEnterCounter = 0; // Reset the counter
node.classList.remove(...dragOverClass);

try {
Expand All @@ -64,6 +66,14 @@ export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
}
}

function handleDragStartOnContainer(event: Event) {
if (options.disabled) return;

// Reset the counter and remove the class
dragEnterCounter = 0;
node.classList.remove(...dragOverClass);
}

function handlePointerOver(event: PointerEvent) {
if (options.disabled || !dndState.isDragging) return;

Expand Down Expand Up @@ -91,6 +101,7 @@ export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
node.addEventListener('dragleave', handleDragLeave);
node.addEventListener('dragover', handleDragOver);
node.addEventListener('drop', handleDrop);
node.addEventListener('dragstart-on-container', handleDragStartOnContainer);

node.addEventListener('pointerover', handlePointerOver);
node.addEventListener('pointerout', handlePointerOut);
Expand All @@ -106,6 +117,7 @@ export function droppable<T>(node: HTMLElement, options: DragDropOptions<T>) {
node.removeEventListener('dragleave', handleDragLeave);
node.removeEventListener('dragover', handleDragOver);
node.removeEventListener('drop', handleDrop);
node.removeEventListener('dragstart-on-container', handleDragStartOnContainer);

node.removeEventListener('pointerover', handlePointerOver);
node.removeEventListener('pointerout', handlePointerOut);
Expand Down

0 comments on commit cf4f62e

Please sign in to comment.