From b4af5a92110f548b965695edce926154da1f46c3 Mon Sep 17 00:00:00 2001 From: Janus Knudsen Date: Wed, 17 Sep 2025 22:08:27 +0200 Subject: [PATCH] Improves all-day event hover detection Enhances the all-day event selection by creating transparent, full-height columns for each day, which enables more accurate and reliable hover detection across all-day events. Now selects all-day events by hovering on the entire column, not just day headers. --- src/managers/HeaderManager.ts | 7 ++++--- src/renderers/AllDayEventRenderer.ts | 28 ++++++++++++++++++++++++++++ wwwroot/css/calendar-layout-css.css | 12 ++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/managers/HeaderManager.ts b/src/managers/HeaderManager.ts index a89457f..0028b69 100644 --- a/src/managers/HeaderManager.ts +++ b/src/managers/HeaderManager.ts @@ -50,11 +50,12 @@ export class HeaderManager { const target = event.target as HTMLElement; - // Optimized element detection - only handle day headers + // Optimized element detection - handle day headers and all-day columns const dayHeader = target.closest('swp-day-header'); + const allDayColumn = target.closest('swp-allday-column'); - if (dayHeader) { - const hoveredElement = dayHeader as HTMLElement; + if (dayHeader || allDayColumn) { + const hoveredElement = (dayHeader || allDayColumn) as HTMLElement; const targetDate = hoveredElement.dataset.date; // Get header renderer for coordination diff --git a/src/renderers/AllDayEventRenderer.ts b/src/renderers/AllDayEventRenderer.ts index a1725ce..bf779a7 100644 --- a/src/renderers/AllDayEventRenderer.ts +++ b/src/renderers/AllDayEventRenderer.ts @@ -26,12 +26,40 @@ export class AllDayEventRenderer { if (!this.container) { this.container = document.createElement('swp-allday-container'); header.appendChild(this.container); + + // Create ghost columns for mouseenter events + this.createGhostColumns(); } } } return this.container; } + /** + * Create ghost columns for mouseenter events + */ + private createGhostColumns(): void { + if (!this.container) return; + + // Get all day headers to create matching ghost columns + const dayHeaders = document.querySelectorAll('swp-day-header'); + dayHeaders.forEach((header, index) => { + const ghostColumn = document.createElement('swp-allday-column'); + const headerElement = header as HTMLElement; + + // Copy date from corresponding day header + if (headerElement.dataset.date) { + ghostColumn.dataset.date = headerElement.dataset.date; + } + + // Set grid column position (1-indexed) + ghostColumn.style.gridColumn = (index + 1).toString(); + ghostColumn.style.gridRow = '1 / -1'; // Span all rows + + this.container!.appendChild(ghostColumn); + }); + } + /** * Render an all-day event using factory pattern */ diff --git a/wwwroot/css/calendar-layout-css.css b/wwwroot/css/calendar-layout-css.css index 12d5322..b9d447c 100644 --- a/wwwroot/css/calendar-layout-css.css +++ b/wwwroot/css/calendar-layout-css.css @@ -288,11 +288,23 @@ swp-allday-container { overflow: hidden; } +/* Ghost columns for mouseenter events */ +swp-allday-column { + position: relative; + opacity: 0; /* Invisible but functional */ + pointer-events: auto; /* Enable mouse events */ + background: transparent; + z-index: 1; /* Below all-day events */ + height: 100%; +} + /* All-day events in containers */ swp-allday-event { height: 22px; /* Fixed height for consistent stacking */ background: #ff9800; /* Default orange background */ display: flex; + position: relative; + z-index: 2; /* Above ghost columns */ align-items: center; justify-content: flex-start; color: #fff;