feat: enhance dashboard components with framer-motion animations

- Added motion effects to Donut, Gauge, Header, NoData, Sparkline components for improved user experience.
- Implemented initial and animate properties for SVG elements to create smooth transitions.
- Introduced new motion primitives for reusable animations across components.
- Updated UI elements like badges and buttons with hover effects and transitions.
- Enhanced skeleton and spinner components for better loading states.
- Created a motion library for consistent animation variants and utility constants.
This commit is contained in:
asepharyana
2026-07-23 17:55:57 +07:00
parent e528b6a726
commit 22cdc2e84b
17 changed files with 1500 additions and 486 deletions
+189
View File
@@ -0,0 +1,189 @@
/**
* Reusable Framer Motion animation variants and utility constants
* for consistent, performant animations across the hub.
*/
// ─── DOM variants ────────────────────────────────────────────
export const fadeIn = {
hidden: { opacity: 0 },
visible: { opacity: 1, transition: { duration: 0.5, ease: "easeOut" } },
};
export const fadeInUp = {
hidden: { opacity: 0, y: 20 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.5, ease: [0.25, 0.1, 0, 1] as const },
},
};
export const fadeInDown = {
hidden: { opacity: 0, y: -16 },
visible: {
opacity: 1,
y: 0,
transition: { duration: 0.4, ease: [0.25, 0.1, 0, 1] as const },
},
};
export const fadeInLeft = {
hidden: { opacity: 0, x: -20 },
visible: {
opacity: 1,
x: 0,
transition: { duration: 0.5, ease: [0.25, 0.1, 0, 1] as const },
},
};
export const fadeInRight = {
hidden: { opacity: 0, x: 20 },
visible: {
opacity: 1,
x: 0,
transition: { duration: 0.5, ease: [0.25, 0.1, 0, 1] as const },
},
};
export const scaleIn = {
hidden: { opacity: 0, scale: 0.9 },
visible: {
opacity: 1,
scale: 1,
transition: { duration: 0.4, ease: [0.25, 0.1, 0, 1] as const },
},
};
export const scaleInSpring = {
hidden: { opacity: 0, scale: 0.85 },
visible: {
opacity: 1,
scale: 1,
transition: {
type: "spring" as const,
stiffness: 200,
damping: 20,
mass: 0.8,
},
},
};
// ─── Stagger container ───────────────────────────────────────
export const stagger = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.06,
delayChildren: 0.1,
ease: [0.25, 0.1, 0, 1] as const,
},
},
};
export const staggerFast = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.04,
delayChildren: 0.05,
},
},
};
export const staggerSlow = {
hidden: { opacity: 0 },
visible: {
opacity: 1,
transition: {
staggerChildren: 0.1,
delayChildren: 0.15,
},
},
};
// ─── SVG / Path animation ────────────────────────────────────
export const drawPath = {
hidden: { pathLength: 0, opacity: 0 },
visible: {
pathLength: 1,
opacity: 1,
transition: { duration: 1.2, ease: [0.25, 0.1, 0, 1] as const },
},
};
export const growWidth = {
hidden: { scaleX: 0, transformOrigin: "left" },
visible: {
scaleX: 1,
transformOrigin: "left",
transition: { duration: 0.8, ease: [0.25, 0.1, 0, 1] as const },
},
};
// ─── Hover / Tap presets ─────────────────────────────────────
export const hoverLift = {
whileHover: { y: -2, transition: { duration: 0.2 } },
whileTap: { y: 0, transition: { duration: 0.1 } },
};
export const hoverGlow = {
whileHover: {
boxShadow: "0 0 20px oklch(0.7 0.15 75 / 0.25)",
transition: { duration: 0.25 },
},
};
export const tapScale = {
whileTap: { scale: 0.97, transition: { duration: 0.1 } },
};
// ─── Counter / number animation ──────────────────────────────
export const counterProps = {
initial: { opacity: 0, y: 8 },
animate: { opacity: 1, y: 0 },
transition: { duration: 0.4, ease: [0.25, 0.1, 0, 1] as const },
};
// ─── Duration presets ────────────────────────────────────────
export const duration = {
fast: 0.2,
normal: 0.4,
slow: 0.6,
slower: 0.8,
} as const;
// ─── Transition presets ──────────────────────────────────────
export const spring = {
type: "spring" as const,
stiffness: 200,
damping: 20,
mass: 0.8,
};
export const springBouncy = {
type: "spring" as const,
stiffness: 300,
damping: 15,
mass: 0.7,
};
export const springGentle = {
type: "spring" as const,
stiffness: 120,
damping: 14,
mass: 1,
};
export const smoothEase = {
ease: [0.25, 0.1, 0, 1] as [number, number, number, number],
duration: 0.5,
};