fix(frontend): ship pending card-view animation and interaction refinements

This commit is contained in:
sagitchu
2026-02-22 15:52:48 +08:00
parent 79c28103d5
commit d483258eef
16 changed files with 640 additions and 503 deletions
+69 -69
View File
@@ -6,21 +6,21 @@ import React from "react";
* Use this as the outermost wrapper inside each page component.
*/
export const AnimatedPage = ({
children,
className,
children,
className,
}: {
children: React.ReactNode;
className?: string;
children: React.ReactNode;
className?: string;
}) => (
<motion.div
animate={{ opacity: 1, y: 0 }}
className={className}
exit={{ opacity: 0, y: -8 }}
initial={{ opacity: 0, y: 16 }}
transition={{ duration: 0.28, ease: [0.25, 0.46, 0.45, 0.94] }}
>
{children}
</motion.div>
<motion.div
animate={{ opacity: 1, y: 0 }}
className={className}
exit={{ opacity: 0, y: -8 }}
initial={{ opacity: 0, y: 16 }}
transition={{ duration: 0.28, ease: [0.25, 0.46, 0.45, 0.94] }}
>
{children}
</motion.div>
);
/**
@@ -28,26 +28,26 @@ export const AnimatedPage = ({
* Children should use `staggerItem` as their `variants` prop.
*/
export const staggerContainer = {
hidden: { opacity: 0 },
show: {
opacity: 1,
transition: {
staggerChildren: 0.05,
delayChildren: 0.05,
},
hidden: { opacity: 0 },
show: {
opacity: 1,
transition: {
staggerChildren: 0.05,
delayChildren: 0.05,
},
},
};
/**
* Individual stagger item variant — fade-in + slide-up.
*/
export const staggerItem = {
hidden: { opacity: 0, y: 12 },
show: {
opacity: 1,
y: 0,
transition: { duration: 0.25, ease: [0.25, 0.46, 0.45, 0.94] },
},
hidden: { opacity: 0, y: 12 },
show: {
opacity: 1,
y: 0,
transition: { duration: 0.25, ease: [0.25, 0.46, 0.45, 0.94] },
},
};
/**
@@ -55,47 +55,47 @@ export const staggerItem = {
* Renders a `motion.div` (or `motion.ul/motion.tbody`) with stagger behaviour.
*/
export const StaggerList = ({
children,
className,
as = "div",
children,
className,
as = "div",
}: {
children: React.ReactNode;
className?: string;
as?: "div" | "ul" | "tbody";
children: React.ReactNode;
className?: string;
as?: "div" | "ul" | "tbody";
}) => {
const Component = motion[as] as React.ElementType;
const Component = motion[as] as React.ElementType;
return (
<Component
animate="show"
className={className}
initial="hidden"
variants={staggerContainer}
>
{children}
</Component>
);
return (
<Component
animate="show"
className={className}
initial="hidden"
variants={staggerContainer}
>
{children}
</Component>
);
};
/**
* Individual animated item for use inside StaggerList.
*/
export const StaggerItem = ({
children,
className,
as = "div",
children,
className,
as = "div",
}: {
children: React.ReactNode;
className?: string;
as?: "div" | "li" | "tr";
children: React.ReactNode;
className?: string;
as?: "div" | "li" | "tr";
}) => {
const Component = motion[as] as React.ElementType;
const Component = motion[as] as React.ElementType;
return (
<Component className={className} variants={staggerItem}>
{children}
</Component>
);
return (
<Component className={className} variants={staggerItem}>
{children}
</Component>
);
};
/**
@@ -103,20 +103,20 @@ export const StaggerItem = ({
* Uses opacity + translateY to avoid font blurriness caused by scale transforms.
*/
export const FadeIn = ({
children,
delay = 0,
className,
children,
delay = 0,
className,
}: {
children: React.ReactNode;
delay?: number;
className?: string;
children: React.ReactNode;
delay?: number;
className?: string;
}) => (
<motion.div
animate={{ opacity: 1, y: 0 }}
className={className}
initial={{ opacity: 0, y: 8 }}
transition={{ duration: 0.2, delay, ease: "easeOut" }}
>
{children}
</motion.div>
<motion.div
animate={{ opacity: 1, y: 0 }}
className={className}
initial={{ opacity: 0, y: 8 }}
transition={{ duration: 0.2, delay, ease: "easeOut" }}
>
{children}
</motion.div>
);