Improves all-day event container creation and animation
Refactors all-day event container creation to be lazy, improving initial load performance. The container is now created and animated into view only when needed, specifically when the first event is dragged into the all-day section. This avoids unnecessary DOM manipulation and improves the perceived responsiveness of the calendar.
This commit is contained in:
parent
daa332e8db
commit
2c934a7a1a
2 changed files with 38 additions and 22 deletions
|
|
@ -31,6 +31,8 @@ export abstract class BaseHeaderRenderer implements HeaderRenderer {
|
||||||
// Find the calendar header element to animate
|
// Find the calendar header element to animate
|
||||||
const calendarHeader = dayHeader.closest('swp-calendar-header') as HTMLElement;
|
const calendarHeader = dayHeader.closest('swp-calendar-header') as HTMLElement;
|
||||||
if (calendarHeader) {
|
if (calendarHeader) {
|
||||||
|
// Ensure container exists BEFORE animation
|
||||||
|
this.createAllDayMainStructure(calendarHeader);
|
||||||
this.animateHeaderExpansion(calendarHeader);
|
this.animateHeaderExpansion(calendarHeader);
|
||||||
}
|
}
|
||||||
console.log('BaseHeaderRenderer: Header expanded for all-day row');
|
console.log('BaseHeaderRenderer: Header expanded for all-day row');
|
||||||
|
|
@ -38,21 +40,11 @@ export abstract class BaseHeaderRenderer implements HeaderRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ensure all-day main container and initial stack level exist (called automatically after header render)
|
* Ensure all-day containers exist - but don't create them initially, use lazy creation
|
||||||
*/
|
*/
|
||||||
ensureAllDayContainers(calendarHeader: HTMLElement): void {
|
ensureAllDayContainers(calendarHeader: HTMLElement): void {
|
||||||
const root = document.documentElement;
|
// Do nothing initially - containers will be created when first needed
|
||||||
const currentHeight = parseInt(getComputedStyle(root).getPropertyValue('--all-day-row-height') || '0');
|
console.log('BaseHeaderRenderer: All-day containers will be created lazily when first event is dragged');
|
||||||
|
|
||||||
// If all-day row doesn't exist yet, set it up without animation
|
|
||||||
if (currentHeight === 0) {
|
|
||||||
root.style.setProperty('--all-day-row-height', `${ALL_DAY_CONSTANTS.SINGLE_ROW_HEIGHT}px`);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Always ensure main container and initial stack level exist
|
|
||||||
this.createAllDayMainStructure(calendarHeader);
|
|
||||||
|
|
||||||
console.log('BaseHeaderRenderer: Ensured all-day main structure exists');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private animateHeaderExpansion(calendarHeader: HTMLElement): void {
|
private animateHeaderExpansion(calendarHeader: HTMLElement): void {
|
||||||
|
|
@ -63,8 +55,17 @@ export abstract class BaseHeaderRenderer implements HeaderRenderer {
|
||||||
// Find header spacer
|
// Find header spacer
|
||||||
const headerSpacer = document.querySelector('swp-header-spacer') as HTMLElement;
|
const headerSpacer = document.querySelector('swp-header-spacer') as HTMLElement;
|
||||||
|
|
||||||
// Animate both header and spacer simultaneously
|
// Find or create all-day container (it should exist but be hidden)
|
||||||
|
let allDayContainer = calendarHeader.querySelector('swp-allday-container') as HTMLElement;
|
||||||
|
if (!allDayContainer) {
|
||||||
|
// Create container if it doesn't exist
|
||||||
|
allDayContainer = document.createElement('swp-allday-container');
|
||||||
|
calendarHeader.appendChild(allDayContainer);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Animate header, spacer, and container simultaneously
|
||||||
const animations = [
|
const animations = [
|
||||||
|
// Header height animation
|
||||||
calendarHeader.animate([
|
calendarHeader.animate([
|
||||||
{ height: `${currentHeaderHeight}px` },
|
{ height: `${currentHeaderHeight}px` },
|
||||||
{ height: `${targetHeight}px` }
|
{ height: `${targetHeight}px` }
|
||||||
|
|
@ -72,9 +73,20 @@ export abstract class BaseHeaderRenderer implements HeaderRenderer {
|
||||||
duration: 150,
|
duration: 150,
|
||||||
easing: 'ease-out',
|
easing: 'ease-out',
|
||||||
fill: 'forwards'
|
fill: 'forwards'
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Container visibility and height animation
|
||||||
|
allDayContainer.animate([
|
||||||
|
{ height: '0px', opacity: '0' },
|
||||||
|
{ height: `${ALL_DAY_CONSTANTS.SINGLE_ROW_HEIGHT}px`, opacity: '1' }
|
||||||
|
], {
|
||||||
|
duration: 150,
|
||||||
|
easing: 'ease-out',
|
||||||
|
fill: 'forwards'
|
||||||
})
|
})
|
||||||
];
|
];
|
||||||
|
|
||||||
|
// Add spacer animation if spacer exists
|
||||||
if (headerSpacer) {
|
if (headerSpacer) {
|
||||||
animations.push(
|
animations.push(
|
||||||
headerSpacer.animate([
|
headerSpacer.animate([
|
||||||
|
|
@ -93,11 +105,10 @@ export abstract class BaseHeaderRenderer implements HeaderRenderer {
|
||||||
// Set the CSS variable after animation
|
// Set the CSS variable after animation
|
||||||
root.style.setProperty('--all-day-row-height', `${ALL_DAY_CONSTANTS.SINGLE_ROW_HEIGHT}px`);
|
root.style.setProperty('--all-day-row-height', `${ALL_DAY_CONSTANTS.SINGLE_ROW_HEIGHT}px`);
|
||||||
|
|
||||||
// Create all-day main structure after animation
|
|
||||||
this.createAllDayMainStructure(calendarHeader);
|
|
||||||
|
|
||||||
// Notify ScrollManager about header height change
|
// Notify ScrollManager about header height change
|
||||||
eventBus.emit('header:height-changed');
|
eventBus.emit('header:height-changed');
|
||||||
|
|
||||||
|
console.log('HeaderRenderer: All-day container animated to visible');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -106,12 +117,13 @@ export abstract class BaseHeaderRenderer implements HeaderRenderer {
|
||||||
let container = calendarHeader.querySelector('swp-allday-container');
|
let container = calendarHeader.querySelector('swp-allday-container');
|
||||||
|
|
||||||
if (!container) {
|
if (!container) {
|
||||||
// Create simple all-day container
|
// Create simple all-day container (initially hidden)
|
||||||
container = document.createElement('swp-allday-container');
|
container = document.createElement('swp-allday-container');
|
||||||
calendarHeader.appendChild(container);
|
calendarHeader.appendChild(container);
|
||||||
|
console.log('HeaderRenderer: Created swp-allday-container (initially hidden)');
|
||||||
|
} else {
|
||||||
|
console.log('HeaderRenderer: swp-allday-container already exists');
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log('Created simple all-day container');
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -267,7 +267,7 @@ swp-day-header[data-today="true"] swp-day-date {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* All-day container - simple container with dynamic grid-template-rows */
|
/* All-day container - initially hidden, animated in when first event is dragged */
|
||||||
swp-allday-container {
|
swp-allday-container {
|
||||||
grid-column: 1 / -1; /* Span all columns */
|
grid-column: 1 / -1; /* Span all columns */
|
||||||
grid-row: 2; /* Second row of calendar header */
|
grid-row: 2; /* Second row of calendar header */
|
||||||
|
|
@ -278,7 +278,11 @@ swp-allday-container {
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
min-height: var(--allday-event-height, 26px);
|
|
||||||
|
/* Initially hidden - no CSS transitions, use Web Animations API */
|
||||||
|
height: 0;
|
||||||
|
min-height: 0;
|
||||||
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* All-day events in containers */
|
/* All-day events in containers */
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue