Easily animate elements when they come into view.
1'use client';
2import { ReactNode, useRef } from 'react';
3import {
4 motion,
5 useInView,
6 Variant,
7 Transition,
8 UseInViewOptions,
9} from 'motion/react';
10
11export type InViewProps = {
12 children: ReactNode;
13 variants?: {
14 hidden: Variant;
15 visible: Variant;
16 };
17 transition?: Transition;
18 viewOptions?: UseInViewOptions;
19 as?: React.ElementType;
20};
21
22const defaultVariants = {
23 hidden: { opacity: 0 },
24 visible: { opacity: 1 },
25};
26
27export function InView({
28 children,
29 variants = defaultVariants,
30 transition,
31 viewOptions,
32 as = 'div',
33}: InViewProps) {
34 const ref = useRef(null);
35 const isInView = useInView(ref, viewOptions);
36
37 const MotionComponent = motion[as as keyof typeof motion] as typeof as;
38
39 return (
40 <MotionComponent
41 ref={ref}
42 initial='hidden'
43 animate={isInView ? 'visible' : 'hidden'}
44 variants={variants}
45 transition={transition}
46 >
47 {children}
48 </MotionComponent>
49 );
50}
51