Skip to content

Commit

Permalink
fixed dragging for gapMatch and graphicGapMatch
Browse files Browse the repository at this point in the history
  • Loading branch information
Marcelh1983 committed Dec 13, 2024
1 parent 5fa0f8d commit 3aa721f
Show file tree
Hide file tree
Showing 14 changed files with 217 additions and 113 deletions.
8 changes: 6 additions & 2 deletions src/lib/decorators/live-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ export function liveQuery(querySelector: string, options?: LiveQueryOptions) {
proto.connectedCallback = function (this: ElemClass) {
connectedCallback.call(this);
const callback = (mutationList: MutationRecord[]) => {
const elementsToWatch = Array.from(this.querySelectorAll(querySelector));
const elementsToWatch = Array.from(this.querySelectorAll(querySelector)).concat(
Array.from(this.shadowRoot?.querySelectorAll(querySelector) || [])
);
for (const mutation of mutationList) {
const addedNodes = Array.from(mutation.addedNodes).map(e => e as Element);
const removedNodes = Array.from(mutation.addedNodes).map(e => e as Element);
Expand All @@ -54,7 +56,9 @@ export function liveQuery(querySelector: string, options?: LiveQueryOptions) {
observer = new MutationObserver(callback);
observer.observe(this, { childList: true, subtree: true });

const elementsAdded = this.querySelectorAll(querySelector) ?? [];
const elementsAdded = Array.from(this.querySelectorAll(querySelector)).concat(
Array.from(this.shadowRoot?.querySelectorAll(querySelector) || [])
);
(this[decoratedFnName] as unknown as UpdateHandler)(Array.from(elementsAdded), []);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
type Point = { x: number; y: number };

export class TouchDragAndDrop {
public draggables: HTMLElement[] = [];
public droppables: HTMLElement[] = [];
public dragContainers: HTMLElement[] = [];

private touchStartTime = 0; // Timestamp of the first touch
private touchStartPoint = null; // Point of the first touch
private lastClickTime = 0; // Timestamp of the previous click
Expand All @@ -12,7 +16,6 @@ export class TouchDragAndDrop {
private initialTransform = ''; // Original transform style
private hasDispatchedDragStart = false; // Flag to ensure dragstart event is dispatched once
private rootNode: Node = null; // Root node for boundary calculations

private allDropzones: HTMLElement[] = []; // All dropzones for keyboard navigation

private dataTransfer = {
Expand Down Expand Up @@ -55,24 +58,58 @@ export class TouchDragAndDrop {
document.addEventListener('touchcancel', this.handleTouchCancel.bind(this), { passive: false });
}

addDraggableElements(draggables: Element[]) {
draggables.forEach(el => {
el.setAttribute('tabindex', '0'); // Make draggable elements focusable
// el.addEventListener('focus', () => (this.focusedElement = el as HTMLElement));
// el.addEventListener('blur', () => (this.focusedElement = null));
dragContainersModified(addedDragContainers: HTMLElement[], removedDragContainers: HTMLElement[]) {
for (const removedContainer of removedDragContainers) {
if (this.dragContainers.includes(removedContainer)) {
this.dragContainers = this.dragContainers.filter(container => container !== removedContainer);
this.allDropzones = this.allDropzones.filter(dropzone => dropzone !== removedContainer);
}
}
for (const dragContainer of addedDragContainers) {
if (!this.dragContainers.includes(dragContainer)) {
this.dragContainers.push(dragContainer);
this.allDropzones.push(dragContainer);
}
}
}

el.addEventListener('touchstart', this.handleTouchStart.bind(this), { passive: false });
el.addEventListener('mousedown', this.handleTouchStart.bind(this), { passive: false });
});
draggablesModified(addedDraggables: HTMLElement[], removedDraggables: HTMLElement[]) {
for (const removedDraggable of removedDraggables) {
if (this.draggables.includes(removedDraggable)) {
this.draggables = this.draggables.filter(draggable => draggable !== removedDraggable);
removedDraggable.removeAttribute('tabindex');
removedDraggable.removeEventListener('touchstart', this.handleTouchStart.bind(this));
removedDraggable.removeEventListener('mousedown', this.handleTouchStart.bind(this));
}
}
for (const draggable of addedDraggables) {
if (!this.draggables.includes(draggable)) {
this.draggables.push(draggable);
// draggables.forEach(el => {
draggable.setAttribute('tabindex', '0'); // Make draggable elements focusable
// el.addEventListener('focus', () => (this.focusedElement = el as HTMLElement));
// el.addEventListener('blur', () => (this.focusedElement = null));

draggable.addEventListener('touchstart', this.handleTouchStart.bind(this), { passive: false });
draggable.addEventListener('mousedown', this.handleTouchStart.bind(this), { passive: false });
// });
}
}
}

private getInteraction(el: HTMLElement) {
// Find the closest parent where the tagname ends with '-interaction'
let parent = el;
while (parent && !parent.tagName.toLocaleLowerCase().endsWith('-interaction')) {
parent = parent.parentElement;
droppablesModified(addedDroppables: HTMLElement[], removedDroppables: HTMLElement[]) {
for (const removedDroppable of removedDroppables) {
if (this.droppables.includes(removedDroppable)) {
this.droppables = this.droppables.filter(droppable => droppable !== removedDroppable);
this.allDropzones = this.allDropzones.filter(dropzone => dropzone !== removedDroppable);
}
}
for (const droppable of addedDroppables) {
if (!this.droppables.includes(droppable)) {
this.droppables.push(droppable);
this.allDropzones.push(droppable);
}
}
return parent;
}

private handleTouchStart(e) {
Expand Down Expand Up @@ -117,11 +154,6 @@ export class TouchDragAndDrop {

private handleTouchMove(e) {
if (this.isDraggable && this.dragSource) {
const interaction = this.getInteraction(this.dragSource);
this.allDropzones = [
...(Array.from(interaction.querySelectorAll('[dropzone]')) as HTMLElement[]),
...(Array.from(interaction.shadowRoot?.querySelectorAll('[dropzone]')) as HTMLElement[])
];
const { x, y } = this.getEventCoordinates(e);
const currentTouch = { clientX: x, clientY: y };

Expand Down Expand Up @@ -214,13 +246,12 @@ export class TouchDragAndDrop {
}

private handleTouchEnd(e) {
this.allDropzones = [];
// this.allDropzones = [];
this.touchEndTriggered = true;
this.isDraggable = false;
let dropFound = false;

// console.log('dropFound', dropFound);

if (this.currentDropTarget) {
this.dispatchCustomEvent(this.currentDropTarget, 'drop');
this.dispatchCustomEvent(this.dragSource, 'dragend');
Expand Down Expand Up @@ -325,14 +356,14 @@ export class TouchDragAndDrop {
return null;
}

if (element.hasAttribute('dropzone')) {
if (this.allDropzones.includes(element)) {
return element;
}

// Traverse up the DOM tree to find an ancestor with 'dropzone' attribute
// Traverse up the DOM tree to find an ancestor that is included in all dropzones
let currentElement = element.parentElement;
while (currentElement) {
if (currentElement.hasAttribute('dropzone')) {
if (this.allDropzones.includes(currentElement)) {
return currentElement;
}
currentElement = currentElement.parentElement;
Expand All @@ -346,7 +377,7 @@ export class TouchDragAndDrop {
}
}

// No element with 'dropzone' found
// No dropzone found
return null;
}

Expand Down Expand Up @@ -449,7 +480,6 @@ export class TouchDragAndDrop {
this.touchStartTime = 0;
this.touchStartPoint = null;
this.touchEndTriggered = false;
this.allDropzones = [];
this.dataTransfer = {
data: {},
setData(type, val) {
Expand Down
Loading

0 comments on commit 3aa721f

Please sign in to comment.