feat: smooth navigation adjustment and time grid actions
- Implemented View Transition API for Week Navigation (simultaneous slide-out/slide-in). - Added Task Action Icons (Notes, Delete) to Time Grid tasks. - Refactored navigate function to use startViewTransition. - Updated globals.css with View Transition keyframes and rules.
This commit is contained in:
parent
d92a8c7210
commit
3aad7b5371
@ -1445,12 +1445,14 @@ h3 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Fix 2: Task Hover Actions */
|
/* Fix 2: Task Hover Actions */
|
||||||
.teuxdeux-task-item {
|
.teuxdeux-task-item,
|
||||||
|
.time-slot-task {
|
||||||
/* Ensure positioning context for absolute actions if needed, though flex is used */
|
/* Ensure positioning context for absolute actions if needed, though flex is used */
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.teuxdeux-task-item .task-actions {
|
.teuxdeux-task-item .task-actions,
|
||||||
|
.time-slot-task .task-actions {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
gap: 2px;
|
gap: 2px;
|
||||||
@ -1461,7 +1463,8 @@ h3 {
|
|||||||
padding-left: 8px;
|
padding-left: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.teuxdeux-task-item:hover .task-actions {
|
.teuxdeux-task-item:hover .task-actions,
|
||||||
|
.time-slot-task:hover .task-actions {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1563,4 +1566,71 @@ h3 {
|
|||||||
|
|
||||||
.teuxdeux-btn-primary:hover {
|
.teuxdeux-btn-primary:hover {
|
||||||
background: #333;
|
background: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* --- VIEW TRANSITION ANIMATION (TeuxDeux-like) --- */
|
||||||
|
|
||||||
|
.teuxdeux-days-grid {
|
||||||
|
view-transition-name: week-grid;
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideOutToLeft {
|
||||||
|
to {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInFromRight {
|
||||||
|
from {
|
||||||
|
transform: translateX(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideOutToRight {
|
||||||
|
to {
|
||||||
|
transform: translateX(100%);
|
||||||
|
opacity: 0.8;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@keyframes slideInFromLeft {
|
||||||
|
from {
|
||||||
|
transform: translateX(-100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
to {
|
||||||
|
transform: translateX(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
::view-transition-group(week-grid) {
|
||||||
|
animation-duration: 0.5s;
|
||||||
|
animation-timing-function: ease-in-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Next Week: Old slides Left, New enters from Right */
|
||||||
|
[data-transition-direction="next"]::view-transition-old(week-grid) {
|
||||||
|
animation: slideOutToLeft 0.5s ease-in-out both;
|
||||||
|
mix-blend-mode: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-transition-direction="next"]::view-transition-new(week-grid) {
|
||||||
|
animation: slideInFromRight 0.5s ease-in-out both;
|
||||||
|
mix-blend-mode: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Prev Week: Old slides Right, New enters from Left */
|
||||||
|
[data-transition-direction="prev"]::view-transition-old(week-grid) {
|
||||||
|
animation: slideOutToRight 0.5s ease-in-out both;
|
||||||
|
mix-blend-mode: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-transition-direction="prev"]::view-transition-new(week-grid) {
|
||||||
|
animation: slideInFromLeft 0.5s ease-in-out both;
|
||||||
|
mix-blend-mode: normal;
|
||||||
}
|
}
|
||||||
@ -203,11 +203,16 @@ export default function TeuxDeuxView() {
|
|||||||
// Navigation handlers with proper slide animation
|
// Navigation handlers with proper slide animation
|
||||||
// Simplified: Immediate state update with slide-in animation to prevent blank flash
|
// 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') => {
|
||||||
setCurrentWeekStart(newDate);
|
// Use View Transition API for smooth 'TeuxDeux' slide (simultaneous old/new)
|
||||||
setSlideDirection(direction === 'left' ? 'in-left' : 'in-right');
|
if (typeof document !== 'undefined' && 'startViewTransition' in document) {
|
||||||
|
document.documentElement.dataset.transitionDirection = direction === 'left' ? 'next' : 'prev';
|
||||||
// Clear animation after it completes
|
(document as any).startViewTransition(() => {
|
||||||
setTimeout(() => setSlideDirection(null), 500);
|
setCurrentWeekStart(newDate);
|
||||||
|
setSlideDirection(null);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setCurrentWeekStart(newDate);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const goToPrevWeek = () => navigate(new Date(currentWeekStart.getTime() - 7 * 24 * 60 * 60 * 1000), 'right');
|
const goToPrevWeek = () => navigate(new Date(currentWeekStart.getTime() - 7 * 24 * 60 * 60 * 1000), 'right');
|
||||||
@ -565,7 +570,15 @@ export default function TeuxDeuxView() {
|
|||||||
toggleTask(task.id);
|
toggleTask(task.id);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{task.title}
|
<span style={{ display: 'block', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flex: 1 }}>{task.title}</span>
|
||||||
|
<div className="task-actions">
|
||||||
|
<button className="task-action-btn" onClick={(e) => { e.stopPropagation(); setSelectedTaskForNotes(task); }} title="Notes">
|
||||||
|
<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"><line x1="3" y1="12" x2="21" y2="12"></line><line x1="3" y1="6" x2="21" y2="6"></line><line x1="3" y1="18" x2="21" y2="18"></line></svg>
|
||||||
|
</button>
|
||||||
|
<button className="task-action-btn delete" onClick={(e) => { e.stopPropagation(); deleteTask(task.id); }} title="Delete">
|
||||||
|
<svg viewBox="0 0 24 24" width="14" height="14" stroke="currentColor" strokeWidth="2" fill="none" strokeLinecap="round" strokeLinejoin="round"><line x1="5" y1="12" x2="19" y2="12"></line></svg>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
{isActive && (
|
{isActive && (
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user