feat: refine animation strategy (day shift vs week slide)

- Implemented mixed View Transition strategy:
  - Week Navigation: Full container slide.
  - Day Navigation: Per-column 'Magic Move' shift.
- Updated navigate function to track navType.
- Updated styling to apply view-transition-name dynamically.
This commit is contained in:
mARTin 2026-02-01 14:53:45 +01:00
parent 3aad7b5371
commit a4c4670662
2 changed files with 19 additions and 9 deletions

View File

@ -1570,10 +1570,13 @@ h3 {
/* --- VIEW TRANSITION ANIMATION (TeuxDeux-like) --- */
.teuxdeux-days-grid {
/* Only apply Container transitions (Full Slide) when navType is 'week' */
[data-nav-type="week"] .teuxdeux-days-grid {
view-transition-name: week-grid;
}
/* When navType="day", NO name on container, so columns animate individually via inline view-transition-name */
@keyframes slideOutToLeft {
to {
transform: translateX(-100%);

View File

@ -202,11 +202,14 @@ export default function TeuxDeuxView() {
// Navigation handlers with proper slide animation
// Simplified: Immediate state update with slide-in animation to prevent blank flash
const navigate = (newDate: Date, direction: 'left' | 'right') => {
const navigate = (newDate: Date, direction: 'left' | 'right', type: 'day' | 'week') => {
// Use View Transition API for smooth 'TeuxDeux' slide (simultaneous old/new)
if (typeof document !== 'undefined' && 'startViewTransition' in document) {
document.documentElement.dataset.transitionDirection = direction === 'left' ? 'next' : 'prev';
(document as any).startViewTransition(() => {
const doc = document as any;
doc.documentElement.dataset.transitionDirection = direction === 'left' ? 'next' : 'prev';
doc.documentElement.dataset.navType = type;
doc.startViewTransition(() => {
setCurrentWeekStart(newDate);
setSlideDirection(null);
});
@ -215,10 +218,10 @@ export default function TeuxDeuxView() {
}
};
const goToPrevWeek = () => navigate(new Date(currentWeekStart.getTime() - 7 * 24 * 60 * 60 * 1000), 'right');
const goToNextWeek = () => navigate(new Date(currentWeekStart.getTime() + 7 * 24 * 60 * 60 * 1000), 'left');
const goToPrevDay = () => navigate(new Date(currentWeekStart.getTime() - 24 * 60 * 60 * 1000), 'right');
const goToNextDay = () => navigate(new Date(currentWeekStart.getTime() + 24 * 60 * 60 * 1000), 'left');
const goToPrevWeek = () => navigate(new Date(currentWeekStart.getTime() - 7 * 24 * 60 * 60 * 1000), 'right', 'week');
const goToNextWeek = () => navigate(new Date(currentWeekStart.getTime() + 7 * 24 * 60 * 60 * 1000), 'left', 'week');
const goToPrevDay = () => navigate(new Date(currentWeekStart.getTime() - 24 * 60 * 60 * 1000), 'right', 'day');
const goToNextDay = () => navigate(new Date(currentWeekStart.getTime() + 24 * 60 * 60 * 1000), 'left', 'day');
const goToToday = () => setCurrentWeekStart(getStartOfWeek(new Date()));
// Task CRUD operations
@ -511,7 +514,11 @@ export default function TeuxDeuxView() {
{/* Day Columns */}
<main className={`teuxdeux-days-grid cols-${viewDays} ${slideDirection ? `slide-${slideDirection}` : ''}`}>
{getVisibleDays().map((date) => (
<div key={date.toISOString()} className="teuxdeux-day-column">
<div
key={date.toISOString()}
className="teuxdeux-day-column"
style={{ viewTransitionName: `day-${date.getFullYear()}-${date.getMonth()}-${date.getDate()}` } as any}
>
{/* Day Header */}
<header className="teuxdeux-day-header">
<div className="teuxdeux-day-date">{formatDateHeader(date)}</div>