2025-10-07 17:16:00 +02:00
|
|
|
import { eventBus } from '../core/EventBus';
|
|
|
|
|
import { CoreEvents } from '../constants/CoreEvents';
|
|
|
|
|
|
2025-10-06 23:38:01 +02:00
|
|
|
export class ResizeHandleManager {
|
2025-10-07 17:16:00 +02:00
|
|
|
private resizeZoneHeight = 15; // Must match CSS ::after height
|
|
|
|
|
private cachedEvents: HTMLElement[] = [];
|
2025-10-06 23:38:01 +02:00
|
|
|
|
|
|
|
|
public initialize(): void {
|
2025-10-07 17:16:00 +02:00
|
|
|
this.refreshEventCache();
|
2025-10-06 23:38:01 +02:00
|
|
|
this.setupEventListeners();
|
|
|
|
|
}
|
|
|
|
|
|
2025-10-07 17:16:00 +02:00
|
|
|
private refreshEventCache(): void {
|
|
|
|
|
this.cachedEvents = Array.from(
|
|
|
|
|
document.querySelectorAll<HTMLElement>('swp-day-columns swp-event')
|
|
|
|
|
);
|
|
|
|
|
}
|
2025-10-06 23:38:01 +02:00
|
|
|
|
2025-10-07 17:16:00 +02:00
|
|
|
private setupEventListeners(): void {
|
2025-10-06 23:38:01 +02:00
|
|
|
document.addEventListener('mousemove', (e: MouseEvent) => {
|
|
|
|
|
this.handleGlobalMouseMove(e);
|
|
|
|
|
});
|
|
|
|
|
|
2025-10-07 17:16:00 +02:00
|
|
|
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());
|
2025-10-06 23:38:01 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private handleGlobalMouseMove(e: MouseEvent): void {
|
2025-10-07 17:16:00 +02:00
|
|
|
// Check all cached events to see if mouse is in their resize zone
|
|
|
|
|
const events = this.cachedEvents;
|
2025-10-06 23:38:01 +02:00
|
|
|
|
|
|
|
|
events.forEach(eventElement => {
|
|
|
|
|
const rect = eventElement.getBoundingClientRect();
|
|
|
|
|
const mouseY = e.clientY;
|
|
|
|
|
const mouseX = e.clientX;
|
|
|
|
|
|
|
|
|
|
// Check if mouse is within element bounds horizontally
|
|
|
|
|
const isInHorizontalBounds = mouseX >= rect.left && mouseX <= rect.right;
|
|
|
|
|
|
2025-10-07 17:16:00 +02:00
|
|
|
// Check if mouse is in bottom resize zone of the element
|
2025-10-06 23:38:01 +02:00
|
|
|
const distanceFromBottom = rect.bottom - mouseY;
|
|
|
|
|
const isInResizeZone = distanceFromBottom >= 0 && distanceFromBottom <= this.resizeZoneHeight;
|
|
|
|
|
|
|
|
|
|
if (isInHorizontalBounds && isInResizeZone) {
|
|
|
|
|
this.showResizeIndicator(eventElement);
|
2025-10-07 17:16:00 +02:00
|
|
|
console.log(`✅ In resize zone - bottom ${this.resizeZoneHeight}px`);
|
2025-10-06 23:38:01 +02:00
|
|
|
} else {
|
|
|
|
|
this.hideResizeIndicator(eventElement);
|
|
|
|
|
}
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private showResizeIndicator(eventElement: HTMLElement): void {
|
|
|
|
|
// Check if indicator already exists
|
|
|
|
|
let indicator = eventElement.querySelector<HTMLElement>('swp-resize-indicator');
|
|
|
|
|
|
|
|
|
|
if (!indicator) {
|
|
|
|
|
indicator = document.createElement('swp-resize-indicator');
|
|
|
|
|
eventElement.appendChild(indicator);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
eventElement.setAttribute('data-resize-hover', 'true');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private hideResizeIndicator(eventElement: HTMLElement): void {
|
|
|
|
|
const indicator = eventElement.querySelector<HTMLElement>('swp-resize-indicator');
|
|
|
|
|
if (indicator) {
|
|
|
|
|
indicator.remove();
|
|
|
|
|
}
|
|
|
|
|
eventElement.removeAttribute('data-resize-hover');
|
|
|
|
|
}
|
|
|
|
|
}
|