diff --git a/src/renderers/GridRenderer.ts b/src/renderers/GridRenderer.ts index 51913cb..74122c0 100644 --- a/src/renderers/GridRenderer.ts +++ b/src/renderers/GridRenderer.ts @@ -99,6 +99,7 @@ export class GridRenderer { } timeAxisContent.appendChild(fragment); + timeAxisContent.style.top = '-1px'; timeAxis.appendChild(timeAxisContent); return timeAxis; } @@ -176,62 +177,6 @@ export class GridRenderer { this.renderColumnContainer(columnContainer as HTMLElement, currentDate, resourceData, view); } } - - /** - * Setup grid-only event listeners (column events) - - private setupGridEventListeners(): void { - // Setup grid body mouseover listener for all-day to timed conversion - this.setupGridBodyMouseOver(); - } - */ - /** - * Setup grid body mouseover listener for all-day to timed conversion - - private setupGridBodyMouseOver(): void { - const grid = this.cachedGridContainer; - if (!grid) return; - - const columnContainer = grid.querySelector('swp-day-columns'); - if (!columnContainer) return; - - // Throttle for better performance - let lastEmitTime = 0; - const throttleDelay = 16; // ~60fps - - const gridBodyEventListener = (event: Event) => { - const now = Date.now(); - if (now - lastEmitTime < throttleDelay) { - return; - } - lastEmitTime = now; - - const target = event.target as HTMLElement; - const dayColumn = target.closest('swp-day-column'); - - if (dayColumn) { - const targetColumn = (dayColumn as HTMLElement).dataset.date; - if (targetColumn) { - // Calculate Y position relative to the column - const columnRect = dayColumn.getBoundingClientRect(); - const mouseY = (event as MouseEvent).clientY; - const targetY = mouseY - columnRect.top; - - eventBus.emit('column:mouseover', { - targetColumn, - targetY - }); - } - } - }; - - columnContainer.addEventListener('mouseover', gridBodyEventListener); - - // Store reference for cleanup - (this as any).gridBodyEventListener = gridBodyEventListener; - (this as any).cachedColumnContainer = columnContainer; - } -*/ /** * Create navigation grid container for slide animations * Now uses same implementation as initial load for consistency diff --git a/wwwroot/css/calendar-layout-css.css b/wwwroot/css/calendar-layout-css.css index d341193..a83d7ef 100644 --- a/wwwroot/css/calendar-layout-css.css +++ b/wwwroot/css/calendar-layout-css.css @@ -50,11 +50,13 @@ swp-calendar-container { swp-header-spacer { grid-column: 1; grid-row: 1; - height: calc(var(--header-height) + var(--all-day-row-height)); /* Dynamic height including all-day events */ + height: calc(var(--header-height) + var(--all-day-row-height)); + /* Dynamic height including all-day events */ background: var(--color-surface); border-right: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border); - z-index: 5; /* Higher than time-axis to cover it when scrolling */ + z-index: 5; + /* Higher than time-axis to cover it when scrolling */ position: relative; } @@ -117,7 +119,8 @@ swp-time-axis { border-right: 1px solid var(--color-border); position: relative; left: 0; - z-index: 3; /* Lower than header elements so it scrolls behind them */ + z-index: 3; + /* Lower than header elements so it scrolls behind them */ width: 60px; overflow: hidden; height: 100%; @@ -148,12 +151,15 @@ swp-hour-marker::before { position: absolute; top: -1px; left: 50px; - width: calc(100vw - 60px); /* Full viewport width minus time-axis width */ + width: calc(100vw - 60px); + /* Full viewport width minus time-axis width */ height: 1px; background: var(--color-hour-line); pointer-events: none; - z-index: 2; /* Ensure it appears above other elements */ + z-index: 2; + /* Ensure it appears above other elements */ } + /* Add hour lines to time-grid as background */ swp-time-grid::after { content: ''; @@ -162,14 +168,13 @@ swp-time-grid::after { left: 0; right: 0; bottom: 0; - min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width)); /* Dynamic width like swp-grid-lines */ - background-image: repeating-linear-gradient( - to bottom, - transparent, - transparent calc(var(--hour-height) - 1px), - var(--color-hour-line) calc(var(--hour-height) - 1px), - var(--color-hour-line) var(--hour-height) - ); + min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width)); + /* Dynamic width like swp-grid-lines */ + background-image: repeating-linear-gradient(to bottom, + transparent, + transparent calc(var(--hour-height) - 1px), + var(--color-hour-line) calc(var(--hour-height) - 1px), + var(--color-hour-line) var(--hour-height)); pointer-events: none; z-index: 1; } @@ -178,40 +183,48 @@ swp-time-grid::after { swp-calendar-header { display: grid; grid-template-columns: repeat(var(--grid-columns, 7), minmax(var(--day-column-min-width), 1fr)); - grid-template-rows: var(--header-height) auto; /* Row 1: header height, Row 2: auto for all-day events */ - min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width)); /* Dynamic width */ + grid-template-rows: var(--header-height) auto; + /* Row 1: header height, Row 2: auto for all-day events */ + min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width)); + /* Dynamic width */ background: var(--color-surface); border-bottom: 1px solid var(--color-border); position: sticky; top: 0; - z-index: 3; /* Lower than header-spacer so it slides under during horizontal scroll */ - height: calc(var(--header-height) + var(--all-day-row-height)); /* Same calculation as spacers */ - + z-index: 3; + /* Lower than header-spacer so it slides under during horizontal scroll */ + height: calc(var(--header-height) + var(--all-day-row-height)); + /* Same calculation as spacers */ + /* Force scrollbar to appear for alignment */ overflow-y: scroll; overflow-x: hidden; - - /* Firefox - hide scrollbar but keep space */ - scrollbar-width: auto; /* Normal width to match content scrollbar */ -/* All-day events container */ -swp-allday-container { - grid-column: 1 / -1; - grid-row: 2; - display: grid; - grid-template-columns: repeat(var(--grid-columns, 7), minmax(var(--day-column-min-width), 1fr)); - grid-auto-rows: var(--single-row-height); /* Each row is exactly SINGLE_ROW_HEIGHT */ - gap: 2px 0px; - padding: 0px; - align-items: center; - overflow: hidden; -} + /* Firefox - hide scrollbar but keep space */ + scrollbar-width: auto; + /* Normal width to match content scrollbar */ + + /* All-day events container */ + swp-allday-container { + grid-column: 1 / -1; + grid-row: 2; + display: grid; + grid-template-columns: repeat(var(--grid-columns, 7), minmax(var(--day-column-min-width), 1fr)); + grid-auto-rows: var(--single-row-height); + /* Each row is exactly SINGLE_ROW_HEIGHT */ + gap: 2px 0px; + padding: 0px; + align-items: center; + overflow: hidden; + } + scrollbar-color: transparent transparent; } /* WebKit browsers (Chrome, Safari, Edge) - hide scrollbar but keep space */ swp-calendar-header::-webkit-scrollbar { - width: 17px; /* Match system default scrollbar width */ + width: 17px; + /* Match system default scrollbar width */ background: transparent; } @@ -225,8 +238,10 @@ swp-calendar-header::-webkit-scrollbar-track { swp-day-header { - grid-row: 1; /* Explicitly place day headers in row 1 */ - pointer-events: auto; /* Ensure header clicks work despite parent scrollbar */ + grid-row: 1; + /* Explicitly place day headers in row 1 */ + pointer-events: auto; + /* Ensure header clicks work despite parent scrollbar */ text-align: center; border-right: 1px solid var(--color-grid-line); border-bottom: 1px solid var(--color-grid-line); @@ -313,29 +328,34 @@ swp-day-header[data-today="true"] swp-day-date { /* Ghost columns for mouseenter events */ swp-allday-column { position: relative; - opacity: 0; /* Invisible but functional */ - pointer-events: auto; /* Enable mouse events */ + opacity: 0; + /* Invisible but functional */ + pointer-events: auto; + /* Enable mouse events */ background: transparent; - z-index: 1; /* Below all-day events */ + z-index: 1; + /* Below all-day events */ height: 100%; } /* All-day events in containers */ swp-allday-container swp-allday-event { - height: 22px !important; /* Fixed height for consistent stacking */ + height: 22px !important; + /* Fixed height for consistent stacking */ position: relative !important; width: auto !important; left: auto !important; right: auto !important; top: auto !important; - margin: 1px; + margin: 1px; padding: 2px 4px; overflow: hidden; white-space: nowrap; text-overflow: ellipsis; background: hsl(208, 100%, 50%); display: flex; - z-index: 2; /* Above ghost columns */ + z-index: 2; + /* Above ghost columns */ align-items: center; justify-content: flex-start; color: #fff; @@ -389,12 +409,12 @@ swp-allday-container swp-allday-event.max-event-overflow-hide { } /* Hide time element for all-day styled events */ -swp-allday-container swp-allday-event swp-event-time{ +swp-allday-container swp-allday-event swp-event-time { display: none; } /* Adjust title display for all-day styled events */ -swp-allday-container swp-allday-event swp-event-title { +swp-allday-container swp-allday-event swp-event-title { display: block; font-size: 12px; line-height: 18px; @@ -407,6 +427,7 @@ swp-scrollable-content { scroll-behavior: smooth; position: relative; display: grid; + top: -1px; /* Height and width will be set dynamically by ScrollManager via ResizeObserver */ } @@ -431,7 +452,8 @@ swp-scrollable-content::-webkit-scrollbar-thumb:hover { /* Style native scrollbars for Firefox */ swp-scrollable-content { - scrollbar-width: auto; /* Let it use the webkit width */ + scrollbar-width: auto; + /* Let it use the webkit width */ scrollbar-color: var(--scrollbar-color, #666) var(--scrollbar-track-color, #f0f0f0); } @@ -458,7 +480,8 @@ swp-time-grid::before { background: transparent; min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width)); pointer-events: none; - display: none; /* Disabled - using per-column overlays instead */ + display: none; + /* Disabled - using per-column overlays instead */ } /* Grid lines */ @@ -468,16 +491,15 @@ swp-grid-lines { left: 0; right: 0; bottom: 0; - min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width)); /* Dynamic width */ + min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width)); + /* Dynamic width */ pointer-events: none; z-index: var(--z-grid); - background-image: repeating-linear-gradient( - to bottom, - transparent, - transparent calc(var(--hour-height) / 4 - 1px), - var(--color-grid-line-light) calc(var(--hour-height) / 4 - 1px), - var(--color-grid-line-light) calc(var(--hour-height) / 4) - ); + background-image: repeating-linear-gradient(to bottom, + transparent, + transparent calc(var(--hour-height) / 4 - 1px), + var(--color-grid-line-light) calc(var(--hour-height) / 4 - 1px), + var(--color-grid-line-light) calc(var(--hour-height) / 4)); } @@ -487,7 +509,8 @@ swp-day-columns { inset: 0; display: grid; grid-template-columns: repeat(var(--grid-columns, 7), minmax(var(--day-column-min-width), 1fr)); - min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width)); /* Dynamic width */ + min-width: calc(var(--grid-columns, 7) * var(--day-column-min-width)); + /* Dynamic width */ } @@ -508,7 +531,7 @@ swp-day-column::before { background: var(--color-non-work-hours); pointer-events: none; z-index: 2; - + /* Before work period - from day start to work start */ top: 0; height: var(--before-work-height, 0px); @@ -524,7 +547,7 @@ swp-day-column::after { background: var(--color-non-work-hours); pointer-events: none; z-index: 2; - + /* After work period - from work end to day end */ top: var(--after-work-top, 100%); bottom: 0; @@ -562,7 +585,8 @@ swp-events-layer { inset: 0; display: block; z-index: var(--z-event); - pointer-events: none; /* Allow clicks to pass through to day column */ + pointer-events: none; + /* Allow clicks to pass through to day column */ } swp-day-columns swp-event { @@ -578,7 +602,7 @@ swp-current-time-indicator { background: var(--color-current-time); pointer-events: none; z-index: var(--z-current-time); - + /* Time label */ &::before { content: attr(data-time); @@ -592,7 +616,7 @@ swp-current-time-indicator { border-radius: 3px; white-space: nowrap; } - + /* Animated dot */ &::after { content: ''; @@ -614,4 +638,4 @@ swp-calendar-container.week-transition { swp-calendar-container.week-transition-out { opacity: 0.5; -} +} \ No newline at end of file