Adds header drawer and event drag interactions
Introduces HeaderDrawerRenderer and HeaderDrawerLayoutEngine to support dragging events into an all-day header drawer Enables dynamic event placement and conversion between timed and all-day events through new drag interactions Implements flexible layout calculation for header items with column and row management Extends DragDropManager to handle header zone interactions Adds new event types for header drag events
This commit is contained in:
parent
026d83eb32
commit
6723658fd9
11 changed files with 850 additions and 4 deletions
|
|
@ -8,7 +8,10 @@ import {
|
|||
IDragMovePayload,
|
||||
IDragEndPayload,
|
||||
IDragCancelPayload,
|
||||
IDragColumnChangePayload
|
||||
IDragColumnChangePayload,
|
||||
IDragEnterHeaderPayload,
|
||||
IDragMoveHeaderPayload,
|
||||
IDragLeaveHeaderPayload
|
||||
} from '../types/DragTypes';
|
||||
|
||||
interface DragState {
|
||||
|
|
@ -39,6 +42,7 @@ export class DragDropManager {
|
|||
private pendingElement: HTMLElement | null = null;
|
||||
private pendingMouseOffset: IMousePosition | null = null;
|
||||
private container: HTMLElement | null = null;
|
||||
private inHeader = false;
|
||||
|
||||
private readonly DRAG_THRESHOLD = 5;
|
||||
private readonly INTERPOLATION_FACTOR = 0.3;
|
||||
|
|
@ -159,6 +163,7 @@ export class DragDropManager {
|
|||
// Cleanup
|
||||
this.dragState.element.classList.remove('dragging');
|
||||
this.dragState = null;
|
||||
this.inHeader = false;
|
||||
};
|
||||
|
||||
private initializeDrag(element: HTMLElement, mouseOffset: IMousePosition, e: PointerEvent): void {
|
||||
|
|
@ -217,6 +222,12 @@ export class DragDropManager {
|
|||
private updateDragTarget(e: PointerEvent): void {
|
||||
if (!this.dragState) return;
|
||||
|
||||
// Check header zone first
|
||||
this.checkHeaderZone(e);
|
||||
|
||||
// Skip normal grid handling if in header
|
||||
if (this.inHeader) return;
|
||||
|
||||
// Check for column change
|
||||
const columnAtPoint = this.getColumnAtPoint(e.clientX);
|
||||
if (columnAtPoint && columnAtPoint !== this.dragState.currentColumn) {
|
||||
|
|
@ -244,6 +255,74 @@ export class DragDropManager {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if pointer is in header zone and emit appropriate events
|
||||
*/
|
||||
private checkHeaderZone(e: PointerEvent): void {
|
||||
if (!this.dragState) return;
|
||||
|
||||
const headerViewport = document.querySelector('swp-header-viewport');
|
||||
if (!headerViewport) return;
|
||||
|
||||
const rect = headerViewport.getBoundingClientRect();
|
||||
const isInHeader = e.clientY < rect.bottom;
|
||||
|
||||
if (isInHeader && !this.inHeader) {
|
||||
// Entered header
|
||||
this.inHeader = true;
|
||||
|
||||
const payload: IDragEnterHeaderPayload = {
|
||||
eventId: this.dragState.eventId,
|
||||
element: this.dragState.element,
|
||||
sourceColumnIndex: this.getColumnIndex(this.dragState.columnElement),
|
||||
sourceDate: this.dragState.columnElement.dataset.date || '',
|
||||
title: this.dragState.element.querySelector('swp-event-title')?.textContent || '',
|
||||
colorClass: [...this.dragState.element.classList].find(c => c.startsWith('is-')),
|
||||
itemType: 'event',
|
||||
duration: 1
|
||||
};
|
||||
|
||||
this.eventBus.emit(CoreEvents.EVENT_DRAG_ENTER_HEADER, payload);
|
||||
} else if (!isInHeader && this.inHeader) {
|
||||
// Left header
|
||||
this.inHeader = false;
|
||||
|
||||
const payload: IDragLeaveHeaderPayload = {
|
||||
eventId: this.dragState.eventId
|
||||
};
|
||||
|
||||
this.eventBus.emit(CoreEvents.EVENT_DRAG_LEAVE_HEADER, payload);
|
||||
} else if (isInHeader) {
|
||||
// Moving within header
|
||||
const column = this.getColumnAtX(e.clientX);
|
||||
if (column) {
|
||||
const payload: IDragMoveHeaderPayload = {
|
||||
eventId: this.dragState.eventId,
|
||||
columnIndex: this.getColumnIndex(column),
|
||||
dateKey: column.dataset.date || ''
|
||||
};
|
||||
|
||||
this.eventBus.emit(CoreEvents.EVENT_DRAG_MOVE_HEADER, payload);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column index (0-based) for a column element
|
||||
*/
|
||||
private getColumnIndex(column: HTMLElement): number {
|
||||
if (!this.container) return 0;
|
||||
const columns = Array.from(this.container.querySelectorAll('swp-day-column'));
|
||||
return columns.indexOf(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get column at X coordinate (alias for getColumnAtPoint)
|
||||
*/
|
||||
private getColumnAtX(clientX: number): HTMLElement | null {
|
||||
return this.getColumnAtPoint(clientX);
|
||||
}
|
||||
|
||||
/**
|
||||
* Find column element at given X coordinate
|
||||
*/
|
||||
|
|
@ -323,5 +402,6 @@ export class DragDropManager {
|
|||
this.eventBus.emit(CoreEvents.EVENT_DRAG_CANCEL, payload);
|
||||
|
||||
this.dragState = null;
|
||||
this.inHeader = false;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue