Improves drag and drop for timed and all-day events

Refactors drag and drop handling to use a cloned event element,
ensuring correct positioning and styling during drag operations
for both regular timed events and all-day events.

This change streamlines the drag and drop process by:
- Creating a clone of the dragged event at the start of the drag.
- Passing the clone through the drag events.
- Handling all-day events with the AllDayManager
- Handling regular timed events with the EventRendererManager

This resolves issues with event positioning and styling during
drag, especially when moving events across columns or between
all-day and timed sections.
This commit is contained in:
Janus C. H. Knudsen 2025-09-26 22:53:49 +02:00
parent 0553089085
commit 9dfd4574d8
5 changed files with 62 additions and 45 deletions

View file

@ -16,7 +16,7 @@ import { DragOffset, StackLinkData } from '../types/DragDropTypes';
export interface EventRendererStrategy {
renderEvents(events: CalendarEvent[], container: HTMLElement): void;
clearEvents(container?: HTMLElement): void;
handleDragStart?(originalElement: HTMLElement, eventId: string, mouseOffset: DragOffset, column: string): void;
handleDragStart?(payload: import('../types/EventTypes').DragStartEventPayload): void;
handleDragMove?(eventId: string, snappedY: number, column: string, mouseOffset: DragOffset): void;
handleDragAutoScroll?(eventId: string, snappedY: number): void;
handleDragEnd?(eventId: string, originalElement: HTMLElement, draggedClone: HTMLElement, finalColumn: string, finalY: number): void;
@ -160,30 +160,31 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
/**
* Handle drag start event
*/
public handleDragStart(originalElement: HTMLElement, eventId: string, mouseOffset: DragOffset, column: string): void {
public handleDragStart(payload: import('../types/EventTypes').DragStartEventPayload): void {
const originalElement = payload.draggedElement;
const eventId = originalElement.dataset.eventId || '';
const mouseOffset = payload.mouseOffset;
const column = payload.column || '';
this.originalEvent = originalElement;
// Remove stacking styling during drag will be handled by new system
// Use the clone from the payload instead of creating a new one
this.draggedClone = payload.draggedClone;
// Create SwpEventElement from existing DOM element and clone it
const originalSwpEvent = SwpEventElement.fromExistingElement(originalElement);
const clonedSwpEvent = originalSwpEvent.createClone();
if (this.draggedClone) {
// Apply drag styling
this.applyDragStyling(this.draggedClone);
// Get the cloned DOM element
this.draggedClone = clonedSwpEvent.getElement();
// Apply drag styling
this.applyDragStyling(this.draggedClone);
// Add to current column's events layer (not directly to column)
const columnElement = document.querySelector(`swp-day-column[data-date="${column}"]`);
if (columnElement) {
const eventsLayer = columnElement.querySelector('swp-events-layer');
if (eventsLayer) {
eventsLayer.appendChild(this.draggedClone);
} else {
// Fallback to column if events layer not found
columnElement.appendChild(this.draggedClone);
// Add to current column's events layer (not directly to column)
const columnElement = document.querySelector(`swp-day-column[data-date="${column}"]`);
if (columnElement) {
const eventsLayer = columnElement.querySelector('swp-events-layer');
if (eventsLayer) {
eventsLayer.appendChild(this.draggedClone);
} else {
// Fallback to column if events layer not found
columnElement.appendChild(this.draggedClone);
}
}
}