Improves drag and drop with edge scrolling
Enhances the drag and drop experience by integrating edge scrolling, allowing users to scroll the calendar view while dragging events. Fixes issues with event positioning during scrolling by compensating for scroll changes during drag operations. Also, adds mock events to data.
This commit is contained in:
parent
a0344c6143
commit
faf8b50593
3 changed files with 244 additions and 60 deletions
|
|
@ -18,6 +18,7 @@ import {
|
|||
DragColumnChangeEventPayload
|
||||
} from '../types/EventTypes';
|
||||
import { MousePosition } from '../types/DragDropTypes';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
|
||||
export class DragDropManager {
|
||||
private eventBus: IEventBus;
|
||||
|
|
@ -41,6 +42,12 @@ export class DragDropManager {
|
|||
// Movement threshold to distinguish click from drag
|
||||
private readonly dragThreshold = 5; // pixels
|
||||
|
||||
// Scroll compensation
|
||||
private scrollableContent: HTMLElement | null = null;
|
||||
private initialScrollTop = 0;
|
||||
private initialCloneTop = 0;
|
||||
private isScrollCompensating = false; // Track if scroll compensation is active
|
||||
private scrollListener: ((e: Event) => void) | null = null;
|
||||
|
||||
// Smooth drag animation
|
||||
private dragAnimationId: number | null = null;
|
||||
|
|
@ -53,6 +60,8 @@ export class DragDropManager {
|
|||
// Get config values
|
||||
const gridSettings = calendarConfig.getGridSettings();
|
||||
|
||||
|
||||
|
||||
this.init();
|
||||
}
|
||||
|
||||
|
|
@ -98,6 +107,9 @@ export class DragDropManager {
|
|||
// Initialize column bounds cache
|
||||
ColumnDetectionUtils.updateColumnBoundsCache();
|
||||
|
||||
|
||||
|
||||
|
||||
// Listen to resize events to update cache
|
||||
window.addEventListener('resize', () => {
|
||||
ColumnDetectionUtils.updateColumnBoundsCache();
|
||||
|
|
@ -108,6 +120,25 @@ export class DragDropManager {
|
|||
ColumnDetectionUtils.updateColumnBoundsCache();
|
||||
});
|
||||
|
||||
this.eventBus.on(CoreEvents.GRID_RENDERED, (event: Event) => {
|
||||
this.handleGridRendered(event as CustomEvent);
|
||||
});
|
||||
|
||||
// Listen to edge-scroll events to control scroll compensation
|
||||
this.eventBus.on('edgescroll:started', () => {
|
||||
this.isScrollCompensating = true;
|
||||
console.log('🎬 DragDropManager: Edge-scroll started - disabling continueDrag()');
|
||||
});
|
||||
|
||||
this.eventBus.on('edgescroll:stopped', () => {
|
||||
this.isScrollCompensating = false;
|
||||
console.log('🛑 DragDropManager: Edge-scroll stopped - enabling continueDrag()');
|
||||
});
|
||||
|
||||
}
|
||||
private handleGridRendered(event: CustomEvent) {
|
||||
this.scrollableContent = document.querySelector('swp-scrollable-content');
|
||||
this.scrollableContent!.addEventListener('scroll', this.handleScroll.bind(this), { passive: true });
|
||||
}
|
||||
|
||||
private handleMouseDown(event: MouseEvent): void {
|
||||
|
|
@ -151,6 +182,8 @@ export class DragDropManager {
|
|||
* Optimized mouse move handler with consolidated position calculations
|
||||
*/
|
||||
private handleMouseMove(event: MouseEvent): void {
|
||||
|
||||
if (this.isScrollCompensating) return;
|
||||
//this.currentMouseY = event.clientY;
|
||||
// this.lastMousePosition = { x: event.clientX, y: event.clientY };
|
||||
|
||||
|
|
@ -195,6 +228,8 @@ export class DragDropManager {
|
|||
// Start drag
|
||||
this.isDragStarted = true;
|
||||
|
||||
|
||||
|
||||
// Set high z-index on event-group if exists, otherwise on event itself
|
||||
const eventGroup = this.originalElement!.closest<HTMLElement>('swp-event-group');
|
||||
if (eventGroup) {
|
||||
|
|
@ -209,7 +244,7 @@ export class DragDropManager {
|
|||
|
||||
const dragStartPayload: DragStartEventPayload = {
|
||||
originalElement: this.originalElement!,
|
||||
draggedClone: this.draggedClone,
|
||||
draggedClone: this.draggedClone,
|
||||
mousePosition: this.mouseDownPosition,
|
||||
mouseOffset: this.mouseOffset,
|
||||
columnBounds: this.currentColumn
|
||||
|
|
@ -221,6 +256,7 @@ export class DragDropManager {
|
|||
|
||||
|
||||
private continueDrag(currentPosition: MousePosition): void {
|
||||
|
||||
if (!this.draggedClone!.hasAttribute("data-allday")) {
|
||||
// Calculate raw position from mouse (no snapping)
|
||||
const column = ColumnDetectionUtils.getColumnBounds(currentPosition);
|
||||
|
|
@ -269,6 +305,7 @@ export class DragDropManager {
|
|||
*/
|
||||
private handleMouseUp(event: MouseEvent): void {
|
||||
this.stopDragAnimation();
|
||||
this.removeScrollListener();
|
||||
|
||||
if (this.originalElement) {
|
||||
|
||||
|
|
@ -339,6 +376,7 @@ export class DragDropManager {
|
|||
console.log('🚫 DragDropManager: Cancelling drag - mouse left grid container');
|
||||
|
||||
this.cleanupAllClones();
|
||||
this.removeScrollListener();
|
||||
|
||||
this.originalElement.style.opacity = '';
|
||||
this.originalElement.style.cursor = '';
|
||||
|
|
@ -415,6 +453,51 @@ export class DragDropManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle scroll during drag - compensate clone position
|
||||
*/
|
||||
private handleScroll(): void {
|
||||
if (!this.isDragStarted || !this.draggedClone || !this.scrollableContent || !this.isScrollCompensating) return;
|
||||
|
||||
// First time scrolling - save initial positions NOW!
|
||||
|
||||
this.initialScrollTop = this.scrollableContent.scrollTop;
|
||||
this.initialCloneTop = parseFloat(this.draggedClone.style.top || '0');
|
||||
|
||||
console.log('💾 DragDropManager: Scroll compensation started', {
|
||||
initialScrollTop: this.initialScrollTop,
|
||||
initialCloneTop: this.initialCloneTop
|
||||
});
|
||||
|
||||
|
||||
const currentScrollTop = this.scrollableContent.scrollTop;
|
||||
const totalScrollDelta = currentScrollTop - this.initialScrollTop;
|
||||
|
||||
// Beregn ny position baseret på initial position + total scroll delta
|
||||
const newTop = this.initialCloneTop + totalScrollDelta;
|
||||
this.draggedClone.style.top = `${newTop}px`;
|
||||
|
||||
console.log('📜 DragDropManager: Scroll compensation', {
|
||||
initialScrollTop: this.initialScrollTop,
|
||||
currentScrollTop,
|
||||
totalScrollDelta,
|
||||
initialCloneTop: this.initialCloneTop,
|
||||
newTop
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove scroll listener
|
||||
*/
|
||||
private removeScrollListener(): void {
|
||||
if (this.scrollListener && this.scrollableContent) {
|
||||
this.scrollableContent.removeEventListener('scroll', this.scrollListener);
|
||||
this.scrollListener = null;
|
||||
}
|
||||
this.isScrollCompensating = false;
|
||||
this.initialScrollTop = 0;
|
||||
this.initialCloneTop = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop drag animation
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue