Improves all-day event rendering and animation
Refactors all-day event handling to enhance user experience. Introduces dynamic height animation for all-day event rows, adapting to the number of overlapping events. This ensures efficient use of screen space and prevents unnecessary scrolling. Additionally, events now store all relevant data, and the header height is checked and animated after navigation. The previous HeaderRenderer.ts file has been refactored.
This commit is contained in:
parent
58d6ad2ed2
commit
542a6874d0
3 changed files with 121 additions and 32 deletions
|
|
@ -5,6 +5,7 @@ import { ALL_DAY_CONSTANTS } from '../core/CalendarConfig';
|
|||
import { CalendarConfig } from '../core/CalendarConfig';
|
||||
import { DateCalculator } from '../utils/DateCalculator';
|
||||
import { eventBus } from '../core/EventBus';
|
||||
import { CoreEvents } from '../constants/CoreEvents';
|
||||
|
||||
/**
|
||||
* Interface for event rendering strategies
|
||||
|
|
@ -63,6 +64,15 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
const { eventId, targetDate, headerRenderer } = (event as CustomEvent).detail;
|
||||
this.handleConvertToAllDay(eventId, targetDate, headerRenderer);
|
||||
});
|
||||
|
||||
// Handle navigation period change (when slide animation completes)
|
||||
eventBus.on(CoreEvents.PERIOD_CHANGED, () => {
|
||||
// Animate all-day height after navigation completes
|
||||
import('./HeaderRenderer').then(({ DateHeaderRenderer }) => {
|
||||
const headerRenderer = new DateHeaderRenderer();
|
||||
headerRenderer.checkAndAnimateAllDayHeight();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -278,10 +288,14 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
const allDayContainer = calendarHeader.querySelector('swp-allday-container');
|
||||
if (!allDayContainer) return;
|
||||
|
||||
// Extract title
|
||||
// Extract all original event data
|
||||
const titleElement = clone.querySelector('swp-event-title');
|
||||
const eventTitle = titleElement ? titleElement.textContent || 'Untitled' : 'Untitled';
|
||||
|
||||
const timeElement = clone.querySelector('swp-event-time');
|
||||
const eventTime = timeElement ? timeElement.textContent || '' : '';
|
||||
const eventDuration = timeElement ? timeElement.getAttribute('data-duration') || '' : '';
|
||||
|
||||
// Calculate column index
|
||||
const dayHeaders = document.querySelectorAll('swp-day-header');
|
||||
let columnIndex = 1;
|
||||
|
|
@ -291,15 +305,19 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
}
|
||||
});
|
||||
|
||||
// Create all-day event
|
||||
// Create all-day event with standardized data attributes
|
||||
const allDayEvent = document.createElement('swp-allday-event');
|
||||
allDayEvent.dataset.eventId = clone.dataset.eventId || '';
|
||||
allDayEvent.dataset.title = eventTitle;
|
||||
allDayEvent.dataset.start = `${targetDate}T${eventTime.split(' - ')[0]}:00`;
|
||||
allDayEvent.dataset.end = `${targetDate}T${eventTime.split(' - ')[1]}:00`;
|
||||
allDayEvent.dataset.type = clone.dataset.type || 'work';
|
||||
allDayEvent.dataset.duration = eventDuration;
|
||||
allDayEvent.textContent = eventTitle;
|
||||
|
||||
// Position in grid
|
||||
(allDayEvent as HTMLElement).style.gridColumn = columnIndex.toString();
|
||||
(allDayEvent as HTMLElement).style.gridRow = '1';
|
||||
// grid-row will be set by checkAndAnimateAllDayHeight() based on actual position
|
||||
|
||||
// Remove original clone
|
||||
if (clone.parentElement) {
|
||||
|
|
@ -311,8 +329,16 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
|
||||
// Update reference
|
||||
this.draggedClone = allDayEvent;
|
||||
|
||||
// Check if height animation is needed
|
||||
import('./HeaderRenderer').then(({ DateHeaderRenderer }) => {
|
||||
const headerRenderer = new DateHeaderRenderer();
|
||||
headerRenderer.checkAndAnimateAllDayHeight();
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Fade out and remove element
|
||||
*/
|
||||
|
|
@ -487,8 +513,14 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
// Create the all-day event element
|
||||
const allDayEvent = document.createElement('swp-allday-event');
|
||||
allDayEvent.textContent = event.title;
|
||||
allDayEvent.setAttribute('data-event-id', event.id);
|
||||
allDayEvent.setAttribute('data-type', event.type || 'work');
|
||||
|
||||
// Set data attributes directly from CalendarEvent
|
||||
allDayEvent.dataset.eventId = event.id;
|
||||
allDayEvent.dataset.title = event.title;
|
||||
allDayEvent.dataset.start = event.start;
|
||||
allDayEvent.dataset.end = event.end;
|
||||
allDayEvent.dataset.type = event.type;
|
||||
allDayEvent.dataset.duration = event.metadata?.duration?.toString() || '60';
|
||||
|
||||
// Set grid position (column and row)
|
||||
(allDayEvent as HTMLElement).style.gridColumn = span.columnSpan > 1
|
||||
|
|
@ -510,7 +542,11 @@ export abstract class BaseEventRenderer implements EventRendererStrategy {
|
|||
protected renderEvent(event: CalendarEvent, container: Element, config: CalendarConfig): void {
|
||||
const eventElement = document.createElement('swp-event');
|
||||
eventElement.dataset.eventId = event.id;
|
||||
eventElement.dataset.title = event.title;
|
||||
eventElement.dataset.start = event.start;
|
||||
eventElement.dataset.end = event.end;
|
||||
eventElement.dataset.type = event.type;
|
||||
eventElement.dataset.duration = event.metadata?.duration?.toString() || '60';
|
||||
|
||||
// Calculate position based on time
|
||||
const position = this.calculateEventPosition(event, config);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue