129 lines
3.1 KiB
TypeScript
129 lines
3.1 KiB
TypeScript
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={shouldReduceMotion ? false : { opacity: 0, y: 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={shouldReduceMotion ? false : { opacity: 0, y: 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={shouldReduceMotion ? false : { opacity: 0, y: 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>) {
|
|
const { shouldReduceMotion } = useMotionConfig()
|
|
|
|
return (
|
|
<motion.tr
|
|
initial={shouldReduceMotion ? false : { opacity: 0 }}
|
|
animate={{ opacity: 1 }}
|
|
transition={{ duration: 0.3 }}
|
|
className={className}
|
|
{...props}
|
|
>
|
|
{children}
|
|
</motion.tr>
|
|
)
|
|
}
|