diff --git a/src/v2/constants/CoreEvents.ts b/src/v2/constants/CoreEvents.ts index 0472d9a..c101d89 100644 --- a/src/v2/constants/CoreEvents.ts +++ b/src/v2/constants/CoreEvents.ts @@ -35,6 +35,7 @@ export const CoreEvents = { EVENT_DRAG_MOVE: 'event:drag-move', EVENT_DRAG_END: 'event:drag-end', EVENT_DRAG_CANCEL: 'event:drag-cancel', + EVENT_DRAG_COLUMN_CHANGE: 'event:drag-column-change', // System events ERROR: 'system:error', diff --git a/src/v2/features/event/EventRenderer.ts b/src/v2/features/event/EventRenderer.ts index 107e229..253b4bb 100644 --- a/src/v2/features/event/EventRenderer.ts +++ b/src/v2/features/event/EventRenderer.ts @@ -1,8 +1,10 @@ -import { ICalendarEvent } from '../../types/CalendarTypes'; +import { ICalendarEvent, IEventBus } from '../../types/CalendarTypes'; import { EventService } from '../../storage/events/EventService'; import { DateService } from '../../core/DateService'; import { IGridConfig } from '../../core/IGridConfig'; import { calculateEventPosition } from '../../utils/PositionUtils'; +import { CoreEvents } from '../../constants/CoreEvents'; +import { IDragColumnChangePayload } from '../../types/DragTypes'; /** * EventRenderer - Renders calendar events to the DOM @@ -16,8 +18,35 @@ export class EventRenderer { constructor( private eventService: EventService, private dateService: DateService, - private gridConfig: IGridConfig - ) {} + private gridConfig: IGridConfig, + private eventBus: IEventBus + ) { + this.setupDragListeners(); + } + + /** + * Setup listeners for drag-drop events + */ + private setupDragListeners(): void { + this.eventBus.on(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, (e) => { + const payload = (e as CustomEvent).detail; + this.handleColumnChange(payload); + }); + } + + /** + * Handle event moving to a new column during drag + */ + private handleColumnChange(payload: IDragColumnChangePayload): void { + const eventsLayer = payload.newColumn.querySelector('swp-events-layer'); + if (!eventsLayer) return; + + // Move element to new column + eventsLayer.appendChild(payload.element); + + // Preserve Y position + payload.element.style.top = `${payload.currentY}px`; + } /** * Render events for visible dates into day columns diff --git a/src/v2/managers/DragDropManager.ts b/src/v2/managers/DragDropManager.ts index b60d1c7..2b2ecaf 100644 --- a/src/v2/managers/DragDropManager.ts +++ b/src/v2/managers/DragDropManager.ts @@ -7,7 +7,8 @@ import { IDragStartPayload, IDragMovePayload, IDragEndPayload, - IDragCancelPayload + IDragCancelPayload, + IDragColumnChangePayload } from '../types/DragTypes'; interface DragState { @@ -17,6 +18,7 @@ interface DragState { startY: number; mouseOffset: IMousePosition; columnElement: HTMLElement; + currentColumn: HTMLElement; targetY: number; currentY: number; animationId: number; @@ -36,6 +38,7 @@ export class DragDropManager { private mouseDownPosition: IMousePosition | null = null; private pendingElement: HTMLElement | null = null; private pendingMouseOffset: IMousePosition | null = null; + private container: HTMLElement | null = null; private readonly DRAG_THRESHOLD = 5; private readonly INTERPOLATION_FACTOR = 0.3; @@ -49,6 +52,7 @@ export class DragDropManager { * Initialize drag-drop on a container element */ init(container: HTMLElement): void { + this.container = container; container.addEventListener('pointerdown', this.handlePointerDown); document.addEventListener('pointermove', this.handlePointerMove); document.addEventListener('pointerup', this.handlePointerUp); @@ -169,6 +173,7 @@ export class DragDropManager { startY, mouseOffset, columnElement, + currentColumn: columnElement, targetY: Math.max(0, targetY), currentY: startY, animationId: 0 @@ -193,6 +198,22 @@ export class DragDropManager { private updateDragTarget(e: PointerEvent): void { if (!this.dragState) return; + // Check for column change + const columnAtPoint = this.getColumnAtPoint(e.clientX); + if (columnAtPoint && columnAtPoint !== this.dragState.currentColumn) { + const payload: IDragColumnChangePayload = { + eventId: this.dragState.eventId, + element: this.dragState.element, + previousColumn: this.dragState.currentColumn, + newColumn: columnAtPoint, + currentY: this.dragState.currentY + }; + + this.eventBus.emit(CoreEvents.EVENT_DRAG_COLUMN_CHANGE, payload); + this.dragState.currentColumn = columnAtPoint; + this.dragState.columnElement = columnAtPoint; + } + const columnRect = this.dragState.columnElement.getBoundingClientRect(); const targetY = e.clientY - columnRect.top - this.dragState.mouseOffset.y; @@ -204,6 +225,22 @@ export class DragDropManager { } } + /** + * Find column element at given X coordinate + */ + private getColumnAtPoint(clientX: number): HTMLElement | null { + if (!this.container) return null; + + const columns = this.container.querySelectorAll('swp-day-column'); + for (const col of columns) { + const rect = col.getBoundingClientRect(); + if (clientX >= rect.left && clientX <= rect.right) { + return col as HTMLElement; + } + } + return null; + } + private animateDrag = (): void => { if (!this.dragState) return; diff --git a/src/v2/types/DragTypes.ts b/src/v2/types/DragTypes.ts index 0b72b3a..ab611f3 100644 --- a/src/v2/types/DragTypes.ts +++ b/src/v2/types/DragTypes.ts @@ -37,3 +37,11 @@ export interface IDragCancelPayload { element: HTMLElement; startY: number; // Position to animate back to } + +export interface IDragColumnChangePayload { + eventId: string; + element: HTMLElement; + previousColumn: HTMLElement; + newColumn: HTMLElement; + currentY: number; +}