server/assets/js/react/components/FadeIn.tsx

61 lines
1.5 KiB
TypeScript
Raw Normal View History

2023-12-04 13:42:32 +00:00
import * as React from "react"
2023-12-06 02:46:27 +00:00
import { MotionProps, motion, useReducedMotion } from "framer-motion"
2023-12-04 13:42:32 +00:00
const FadeInStaggerContext = React.createContext(false)
export function FadeIn({ ...props }) {
let shouldReduceMotion = useReducedMotion()
let isInStaggerGroup = React.useContext(FadeInStaggerContext)
return (
<motion.div
variants={{
hidden: { opacity: 0, y: shouldReduceMotion ? 0 : 24 },
visible: { opacity: 1, y: 0 },
}}
transition={{ duration: 0.5 }}
{...(isInStaggerGroup
? {}
: {
initial: "hidden",
whileInView: "visible",
2023-12-06 02:46:27 +00:00
viewport: {
once: true,
2023-12-06 16:06:22 +00:00
margin: "0px 0px -120px",
2023-12-06 02:46:27 +00:00
},
2023-12-04 13:42:32 +00:00
})}
{...props}
/>
)
}
2023-12-06 02:46:27 +00:00
export type FadeInStaggerProps = {
faster?: boolean
className?: string
} & MotionProps
export const FadeInStagger = React.forwardRef(function FadeInStagger(
props: FadeInStaggerProps,
ref: React.ForwardedRef<HTMLDivElement>
) {
const { faster = false, ...other } = props
// Consider dropping framer-motion:
// https://github.com/framer/motion/issues/776
2023-12-04 13:42:32 +00:00
return (
<FadeInStaggerContext.Provider value={true}>
<motion.div
2023-12-06 02:46:27 +00:00
ref={ref}
2023-12-04 13:42:32 +00:00
initial="hidden"
whileInView="visible"
2023-12-06 02:46:27 +00:00
viewport={{
once: true,
margin: "0px 0px -200px",
}}
2023-12-04 13:42:32 +00:00
transition={{ staggerChildren: faster ? 0.12 : 0.2 }}
2023-12-06 02:46:27 +00:00
{...other}
2023-12-04 13:42:32 +00:00
/>
</FadeInStaggerContext.Provider>
)
2023-12-06 02:46:27 +00:00
})