feat: add transitions and micro-interactions across all views

- Page transitions with slide-up/fade on route changes (App.vue)
- NavRail sliding active indicator with spring-like easing
- List enter/leave/move animations on Entries, Projects, Clients, Timer
- Modal enter/leave transitions with scale+fade on all dialogs
- Dropdown transitions with overshoot on all select/picker components
- Button feedback (scale on hover/active), card hover lift effects
- Timer pulse on start, glow on stop, floating empty state icons
- Content fade-in on Dashboard, Reports, Calendar, Timesheet
- Tag chip enter/leave animations in AppTagInput
- Progress bar smooth width transitions
- Implementation plan document
This commit is contained in:
Your Name
2026-02-18 11:33:58 +02:00
parent bd0dbaf91d
commit 04d4220604
16 changed files with 2115 additions and 144 deletions

View File

@@ -34,6 +34,10 @@ const navItems = [
const currentPath = computed(() => route.path)
const activeIndex = computed(() => {
return navItems.findIndex(item => item.path === currentPath.value)
})
function navigate(path: string) {
router.push(path)
}
@@ -41,24 +45,25 @@ function navigate(path: string) {
<template>
<nav class="w-12 flex flex-col items-center bg-bg-surface border-r border-border-subtle shrink-0">
<!-- Navigation icons -->
<div class="flex-1 flex flex-col items-center pt-2 gap-1">
<div class="relative flex-1 flex flex-col items-center pt-2 gap-1">
<!-- Sliding active indicator -->
<div
v-if="activeIndex >= 0"
class="absolute left-0 w-[2px] bg-accent transition-all duration-300"
:style="{ top: `${activeIndex * 52 + 8 + 8}px`, height: '36px' }"
style="transition-timing-function: cubic-bezier(0.22, 1, 0.36, 1);"
/>
<button
v-for="item in navItems"
:key="item.path"
@click="navigate(item.path)"
class="relative w-12 h-12 flex items-center justify-center transition-colors duration-150 group"
class="relative w-12 h-[52px] flex items-center justify-center transition-colors duration-150 group"
:class="currentPath === item.path
? 'text-text-primary'
: 'text-text-tertiary hover:text-text-secondary'"
:title="item.name"
>
<!-- Active indicator (left border) -->
<div
v-if="currentPath === item.path"
class="absolute left-0 top-2 bottom-2 w-[2px] bg-accent"
/>
<component :is="item.icon" class="w-[18px] h-[18px]" :stroke-width="1.5" />
<!-- Tooltip -->