Improves event resize handle interaction

Enhances the resize handle indicator for calendar events by using cached event elements for efficiency.

This eliminates the need to constantly query the DOM, and only refreshes the cache on relevant event changes.

Additionally updates the resize indicator style for improved visual clarity and user experience.
This commit is contained in:
Janus C. H. Knudsen 2025-10-07 17:16:00 +02:00
parent a9819a8bf1
commit 70dce9fd59
2 changed files with 49 additions and 44 deletions

View file

@ -1,39 +1,37 @@
import { eventBus } from '../core/EventBus';
import { CoreEvents } from '../constants/CoreEvents';
export class ResizeHandleManager {
private resizeZoneHeight =15; // Must match CSS ::after height
private lastHoveredEvent: HTMLElement | null = null;
private resizeZoneHeight = 15; // Must match CSS ::after height
private cachedEvents: HTMLElement[] = [];
public initialize(): void {
this.refreshEventCache();
this.setupEventListeners();
}
private refreshEventCache(): void {
this.cachedEvents = Array.from(
document.querySelectorAll<HTMLElement>('swp-day-columns swp-event')
);
}
private setupEventListeners(): void {
// Listen to global mouseover from document
document.addEventListener('mouseover', (e: MouseEvent) => {
this.handleGlobalMouseOver(e);
});
document.addEventListener('mousemove', (e: MouseEvent) => {
this.handleGlobalMouseMove(e);
});
document.addEventListener('mouseout', (e: MouseEvent) => {
this.handleGlobalMouseOut(e);
});
}
private handleGlobalMouseOver(e: MouseEvent): void {
const target = e.target as HTMLElement;
const eventElement = target.closest<HTMLElement>('swp-day-columns swp-event');
if (eventElement) {
this.lastHoveredEvent = eventElement;
}
eventBus.on(CoreEvents.GRID_RENDERED, () => this.refreshEventCache());
eventBus.on(CoreEvents.EVENTS_RENDERED, () => this.refreshEventCache());
eventBus.on(CoreEvents.EVENT_CREATED, () => this.refreshEventCache());
eventBus.on(CoreEvents.EVENT_UPDATED, () => this.refreshEventCache());
eventBus.on(CoreEvents.EVENT_DELETED, () => this.refreshEventCache());
eventBus.on('drag:end', () => this.refreshEventCache());
}
private handleGlobalMouseMove(e: MouseEvent): void {
// Check all events to see if mouse is in their resize zone
const events = document.querySelectorAll<HTMLElement>('swp-day-columns swp-event');
// Check all cached events to see if mouse is in their resize zone
const events = this.cachedEvents;
events.forEach(eventElement => {
const rect = eventElement.getBoundingClientRect();
@ -43,13 +41,13 @@ export class ResizeHandleManager {
// Check if mouse is within element bounds horizontally
const isInHorizontalBounds = mouseX >= rect.left && mouseX <= rect.right;
// Check if mouse is in bottom 25px of the element
// Check if mouse is in bottom resize zone of the element
const distanceFromBottom = rect.bottom - mouseY;
const isInResizeZone = distanceFromBottom >= 0 && distanceFromBottom <= this.resizeZoneHeight;
if (isInHorizontalBounds && isInResizeZone) {
this.showResizeIndicator(eventElement);
console.log('✅ In resize zone - bottom 25px');
console.log(`✅ In resize zone - bottom ${this.resizeZoneHeight}px`);
} else {
this.hideResizeIndicator(eventElement);
}
@ -75,15 +73,4 @@ export class ResizeHandleManager {
}
eventElement.removeAttribute('data-resize-hover');
}
private handleGlobalMouseOut(e: MouseEvent): void {
const target = e.target as HTMLElement;
const eventElement = target.closest<HTMLElement>('swp-day-columns swp-event');
if (eventElement) {
// Don't remove immediately - let mousemove handle it
}
}
}