Steps in the right direction for animated date change

This commit is contained in:
Janus Knudsen 2025-08-12 00:07:39 +02:00
parent 5e966ddea2
commit f50f5ad53b
7 changed files with 378 additions and 37 deletions

View file

@ -112,28 +112,65 @@ export class NavigationManager {
}
}
/**
* POC-style animation transition - creates new grid container and slides it in
*/
private animateTransition(direction: 'prev' | 'next', targetWeek: Date): void {
const calendarContainer = document.querySelector('swp-calendar-container');
const container = document.querySelector('swp-calendar-container');
const currentGrid = container?.querySelector('swp-grid-container');
if (!calendarContainer) {
console.warn('NavigationManager: Calendar container not found');
if (!container || !currentGrid) {
console.warn('NavigationManager: Required DOM elements not found');
return;
}
// Add transition class for visual feedback
calendarContainer.classList.add('week-transition');
// Brief fade effect
setTimeout(() => {
calendarContainer.classList.add('week-transition-out');
console.log(`NavigationManager: Starting ${direction} animation to ${targetWeek.toDateString()}`);
// Create new grid container (POC approach)
const newGrid = document.createElement('swp-grid-container');
newGrid.innerHTML = `
<swp-calendar-header></swp-calendar-header>
<swp-scrollable-content>
<swp-time-grid>
<swp-grid-lines></swp-grid-lines>
<swp-day-columns></swp-day-columns>
</swp-time-grid>
</swp-scrollable-content>
`;
// Position new grid off-screen (POC positioning)
newGrid.style.position = 'absolute';
newGrid.style.top = '0';
newGrid.style.left = '0';
newGrid.style.width = '100%';
newGrid.style.height = '100%';
newGrid.style.transform = direction === 'next' ? 'translateX(100%)' : 'translateX(-100%)';
// Add to container
container.appendChild(newGrid);
// Render new content for target week
this.renderWeekContent(newGrid, targetWeek);
// Animate transition (POC animation)
requestAnimationFrame(() => {
// Slide out current grid
(currentGrid as HTMLElement).style.transform = direction === 'next' ? 'translateX(-100%)' : 'translateX(100%)';
(currentGrid as HTMLElement).style.opacity = '0.5';
// Update the week after fade starts
// Slide in new grid
newGrid.style.transform = 'translateX(0)';
// Clean up after animation (POC cleanup)
setTimeout(() => {
// Update currentWeek
currentGrid.remove();
newGrid.style.position = 'relative';
// Update currentWeek only after animation is complete (POC logic)
this.currentWeek = new Date(targetWeek);
this.animationQueue--;
// If this was the last queued animation, ensure we're in sync
// If this was the last queued animation, ensure we're in sync (POC sync)
if (this.animationQueue === 0) {
this.currentWeek = new Date(this.targetWeek);
}
@ -145,13 +182,70 @@ export class NavigationManager {
weekEnd: DateUtils.addDays(this.currentWeek, 6)
});
// Remove transition classes
setTimeout(() => {
calendarContainer.classList.remove('week-transition', 'week-transition-out');
}, 150);
}, 150); // Half of transition duration
}, 50);
console.log(`NavigationManager: Completed ${direction} animation`);
}, 400); // Match POC timing
});
}
/**
* Render week content in the new grid container
*/
private renderWeekContent(gridContainer: HTMLElement, weekStart: Date): void {
const header = gridContainer.querySelector('swp-calendar-header');
const dayColumns = gridContainer.querySelector('swp-day-columns');
if (!header || !dayColumns) return;
// Clear existing content
header.innerHTML = '';
dayColumns.innerHTML = '';
// Render headers for target week
const days = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
for (let i = 0; i < 7; i++) {
const date = new Date(weekStart);
date.setDate(date.getDate() + i);
const headerElement = document.createElement('swp-day-header');
if (this.isToday(date)) {
headerElement.dataset.today = 'true';
}
headerElement.innerHTML = `
<swp-day-name>${days[date.getDay()]}</swp-day-name>
<swp-day-date>${date.getDate()}</swp-day-date>
`;
headerElement.dataset.date = this.formatDate(date);
header.appendChild(headerElement);
}
// Render day columns for target week
for (let i = 0; i < 7; i++) {
const column = document.createElement('swp-day-column');
const date = new Date(weekStart);
date.setDate(date.getDate() + i);
column.dataset.date = this.formatDate(date);
const eventsLayer = document.createElement('swp-events-layer');
column.appendChild(eventsLayer);
dayColumns.appendChild(column);
}
// NOTE: Removed POC event emission to prevent interference with production code
// POC events should not trigger production event rendering
// this.eventBus.emit(EventTypes.WEEK_CONTENT_RENDERED, { ... });
}
// Utility functions (from POC)
private formatDate(date: Date): string {
return `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`;
}
private isToday(date: Date): boolean {
const today = new Date();
return date.toDateString() === today.toDateString();
}
private updateWeekInfo(): void {