feat(ui): 添加克制页面动效

This commit is contained in:
2026-05-12 00:30:16 +08:00
parent 602f969117
commit 2dabbd1281
3 changed files with 164 additions and 36 deletions
+126
View File
@@ -0,0 +1,126 @@
import { motion, useReducedMotion } from 'motion/react'
import type { ComponentPropsWithoutRef, ReactNode } from 'react'
export function useMotionConfig() {
const shouldReduceMotion = useReducedMotion()
return { shouldReduceMotion }
}
export function MotionHeader({
children,
delay = 0,
className,
...props
}: { children: ReactNode; delay?: number } & ComponentPropsWithoutRef<typeof motion.header>) {
const { shouldReduceMotion } = useMotionConfig()
return (
<motion.header
initial={{ opacity: 0, y: shouldReduceMotion ? 0 : 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay, ease: [0.25, 0.1, 0.25, 1] }}
className={className}
{...props}
>
{children}
</motion.header>
)
}
export function MotionSection({
children,
delay = 0,
className,
...props
}: { children: ReactNode; delay?: number } & ComponentPropsWithoutRef<typeof motion.section>) {
const { shouldReduceMotion } = useMotionConfig()
return (
<motion.section
initial={{ opacity: 0, y: shouldReduceMotion ? 0 : 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay, ease: [0.25, 0.1, 0.25, 1] }}
className={className}
{...props}
>
{children}
</motion.section>
)
}
export function MotionDiv({
children,
delay = 0,
className,
...props
}: { children: ReactNode; delay?: number } & ComponentPropsWithoutRef<typeof motion.div>) {
const { shouldReduceMotion } = useMotionConfig()
return (
<motion.div
initial={{ opacity: 0, y: shouldReduceMotion ? 0 : 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5, delay, ease: [0.25, 0.1, 0.25, 1] }}
className={className}
{...props}
>
{children}
</motion.div>
)
}
export function MotionCardArticle({
children,
className,
...props
}: { children: ReactNode } & ComponentPropsWithoutRef<typeof motion.article>) {
const { shouldReduceMotion } = useMotionConfig()
return (
<motion.article
whileHover={shouldReduceMotion ? {} : { y: -2 }}
transition={{ duration: 0.2, ease: 'easeOut' }}
className={className}
{...props}
>
{children}
</motion.article>
)
}
export function MotionCardDiv({
children,
className,
...props
}: { children: ReactNode } & ComponentPropsWithoutRef<typeof motion.div>) {
const { shouldReduceMotion } = useMotionConfig()
return (
<motion.div
whileHover={shouldReduceMotion ? {} : { y: -2 }}
transition={{ duration: 0.2, ease: 'easeOut' }}
className={className}
{...props}
>
{children}
</motion.div>
)
}
export function MotionTableRow({
children,
className,
...props
}: { children: ReactNode } & ComponentPropsWithoutRef<typeof motion.tr>) {
return (
<motion.tr
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
transition={{ duration: 0.3 }}
className={className}
{...props}
>
{children}
</motion.tr>
)
}