101 lines
3.7 KiB
JavaScript
101 lines
3.7 KiB
JavaScript
|
|
/**
|
||
|
|
* DragHoverManager - Handles event hover tracking
|
||
|
|
* Fully autonomous - listens to mouse events and manages hover state independently
|
||
|
|
*/
|
||
|
|
export class DragHoverManager {
|
||
|
|
constructor(eventBus) {
|
||
|
|
this.eventBus = eventBus;
|
||
|
|
this.isHoverTrackingActive = false;
|
||
|
|
this.currentHoveredEvent = null;
|
||
|
|
this.calendarContainer = null;
|
||
|
|
this.init();
|
||
|
|
}
|
||
|
|
init() {
|
||
|
|
// Wait for DOM to be ready
|
||
|
|
setTimeout(() => {
|
||
|
|
this.calendarContainer = document.querySelector('swp-calendar-container');
|
||
|
|
if (this.calendarContainer) {
|
||
|
|
this.setupEventListeners();
|
||
|
|
}
|
||
|
|
}, 100);
|
||
|
|
// Listen to drag start to deactivate hover tracking
|
||
|
|
this.eventBus.on('drag:start', () => {
|
||
|
|
this.deactivateTracking();
|
||
|
|
});
|
||
|
|
}
|
||
|
|
setupEventListeners() {
|
||
|
|
if (!this.calendarContainer)
|
||
|
|
return;
|
||
|
|
// Listen to mouseenter on events (using event delegation)
|
||
|
|
this.calendarContainer.addEventListener('mouseenter', (e) => {
|
||
|
|
const target = e.target;
|
||
|
|
const eventElement = target.closest('swp-event');
|
||
|
|
if (eventElement) {
|
||
|
|
this.handleEventMouseEnter(e, eventElement);
|
||
|
|
}
|
||
|
|
}, true); // Use capture phase
|
||
|
|
// Listen to mousemove globally to track when mouse leaves event bounds
|
||
|
|
document.body.addEventListener('mousemove', (e) => {
|
||
|
|
if (this.isHoverTrackingActive && e.buttons === 0) {
|
||
|
|
this.checkEventHover(e);
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Handle mouse enter on swp-event - activate hover tracking
|
||
|
|
*/
|
||
|
|
handleEventMouseEnter(event, eventElement) {
|
||
|
|
// Only handle hover if mouse button is up
|
||
|
|
if (event.buttons === 0) {
|
||
|
|
// Clear any previous hover first
|
||
|
|
if (this.currentHoveredEvent && this.currentHoveredEvent !== eventElement) {
|
||
|
|
this.currentHoveredEvent.classList.remove('hover');
|
||
|
|
}
|
||
|
|
this.isHoverTrackingActive = true;
|
||
|
|
this.currentHoveredEvent = eventElement;
|
||
|
|
eventElement.classList.add('hover');
|
||
|
|
this.eventBus.emit('event:hover:start', { element: eventElement });
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Check if mouse is still over the currently hovered event
|
||
|
|
*/
|
||
|
|
checkEventHover(event) {
|
||
|
|
// Only track hover when active and mouse button is up
|
||
|
|
if (!this.isHoverTrackingActive || !this.currentHoveredEvent)
|
||
|
|
return;
|
||
|
|
const rect = this.currentHoveredEvent.getBoundingClientRect();
|
||
|
|
const mouseX = event.clientX;
|
||
|
|
const mouseY = event.clientY;
|
||
|
|
// Check if mouse is still within the current hovered event
|
||
|
|
const isStillInside = mouseX >= rect.left && mouseX <= rect.right &&
|
||
|
|
mouseY >= rect.top && mouseY <= rect.bottom;
|
||
|
|
// If mouse left the event
|
||
|
|
if (!isStillInside) {
|
||
|
|
// Only disable tracking and clear if mouse is NOT pressed (allow resize to work)
|
||
|
|
if (event.buttons === 0) {
|
||
|
|
this.isHoverTrackingActive = false;
|
||
|
|
this.clearEventHover();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Clear hover state
|
||
|
|
*/
|
||
|
|
clearEventHover() {
|
||
|
|
if (this.currentHoveredEvent) {
|
||
|
|
this.currentHoveredEvent.classList.remove('hover');
|
||
|
|
this.eventBus.emit('event:hover:end', { element: this.currentHoveredEvent });
|
||
|
|
this.currentHoveredEvent = null;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
/**
|
||
|
|
* Deactivate hover tracking and clear any current hover
|
||
|
|
* Called via event bus when drag starts
|
||
|
|
*/
|
||
|
|
deactivateTracking() {
|
||
|
|
this.isHoverTrackingActive = false;
|
||
|
|
this.clearEventHover();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
//# sourceMappingURL=DragHoverManager.js.map
|