1+ /* eslint-disable @typescript-eslint/no-explicit-any */
12"use client" ;
2- import { ReactNode } from "react" ;
3+ import React , { ReactNode } from "react" ;
34import { motion , Variants } from "motion/react" ;
4- import React from "react" ;
5+ import { JSX } from "react/jsx-runtime " ;
56
67export type PresetType =
78 | "fade"
@@ -15,6 +16,8 @@ export type PresetType =
1516 | "rotate"
1617 | "swing" ;
1718
19+ type As = keyof JSX . IntrinsicElements | React . ComponentType < any > ;
20+
1821export type AnimatedGroupProps = {
1922 children : ReactNode ;
2023 className ?: string ;
@@ -23,15 +26,13 @@ export type AnimatedGroupProps = {
2326 item ?: Variants ;
2427 } ;
2528 preset ?: PresetType ;
26- as ?: React . ElementType ;
27- asChild ?: React . ElementType ;
29+ as ?: As ;
30+ asChild ?: As ;
2831} ;
2932
3033const defaultContainerVariants : Variants = {
3134 visible : {
32- transition : {
33- staggerChildren : 0.1 ,
34- } ,
35+ transition : { staggerChildren : 0.1 } ,
3536 } ,
3637} ;
3738
@@ -42,74 +43,59 @@ const defaultItemVariants: Variants = {
4243
4344const presetVariants : Record < PresetType , Variants > = {
4445 fade : { } ,
45- slide : {
46- hidden : { y : 20 } ,
47- visible : { y : 0 } ,
48- } ,
49- scale : {
50- hidden : { scale : 0.8 } ,
51- visible : { scale : 1 } ,
52- } ,
53- blur : {
54- hidden : { filter : "blur(4px)" } ,
55- visible : { filter : "blur(0px)" } ,
56- } ,
46+ slide : { hidden : { y : 20 } , visible : { y : 0 } } ,
47+ scale : { hidden : { scale : 0.8 } , visible : { scale : 1 } } ,
48+ blur : { hidden : { filter : "blur(4px)" } , visible : { filter : "blur(0px)" } } ,
5749 "blur-slide" : {
5850 hidden : { filter : "blur(4px)" , y : 20 } ,
5951 visible : { filter : "blur(0px)" , y : 0 } ,
6052 } ,
6153 zoom : {
6254 hidden : { scale : 0.5 } ,
63- visible : {
64- scale : 1 ,
65- transition : { type : "spring" , stiffness : 300 , damping : 20 } ,
66- } ,
55+ visible : { scale : 1 , transition : { type : "spring" , stiffness : 300 , damping : 20 } } ,
6756 } ,
6857 flip : {
6958 hidden : { rotateX : - 90 } ,
70- visible : {
71- rotateX : 0 ,
72- transition : { type : "spring" , stiffness : 300 , damping : 20 } ,
73- } ,
59+ visible : { rotateX : 0 , transition : { type : "spring" , stiffness : 300 , damping : 20 } } ,
7460 } ,
7561 bounce : {
7662 hidden : { y : - 50 } ,
77- visible : {
78- y : 0 ,
79- transition : { type : "spring" , stiffness : 400 , damping : 10 } ,
80- } ,
63+ visible : { y : 0 , transition : { type : "spring" , stiffness : 400 , damping : 10 } } ,
8164 } ,
8265 rotate : {
8366 hidden : { rotate : - 180 } ,
84- visible : {
85- rotate : 0 ,
86- transition : { type : "spring" , stiffness : 200 , damping : 15 } ,
87- } ,
67+ visible : { rotate : 0 , transition : { type : "spring" , stiffness : 200 , damping : 15 } } ,
8868 } ,
8969 swing : {
9070 hidden : { rotate : - 10 } ,
91- visible : {
92- rotate : 0 ,
93- transition : { type : "spring" , stiffness : 300 , damping : 8 } ,
94- } ,
71+ visible : { rotate : 0 , transition : { type : "spring" , stiffness : 300 , damping : 8 } } ,
9572 } ,
9673} ;
9774
98- const addDefaultVariants = ( variants : Variants ) => ( {
99- hidden : { ...defaultItemVariants . hidden , ...variants . hidden } ,
100- visible : { ...defaultItemVariants . visible , ...variants . visible } ,
75+ const addDefaultVariants = ( variants ? : Variants ) : Variants => ( {
76+ hidden : { ...( defaultItemVariants . hidden || { } ) , ...( ( variants ? .hidden as object ) || { } ) } ,
77+ visible : { ...( defaultItemVariants . visible || { } ) , ...( ( variants ? .visible as object ) || { } ) } ,
10178} ) ;
10279
80+ // Prefer built-in motion tags (motion.div, motion.section, etc.)
81+ // and fall back to motion.create for custom components.
82+ function getMotionComponent ( as : As ) {
83+ const maybeIntrinsic = ( motion as any ) [ as as any ] ;
84+ if ( maybeIntrinsic ) return maybeIntrinsic as React . ComponentType < any > ;
85+ return ( motion as any ) . create ( as as string | React . ComponentType < any > ) as React . ComponentType < any > ;
86+ }
87+
10388function AnimatedGroup ( { children, className, variants, preset, as = "div" , asChild = "div" } : AnimatedGroupProps ) {
10489 const selectedVariants = {
10590 item : addDefaultVariants ( preset ? presetVariants [ preset ] : { } ) ,
10691 container : addDefaultVariants ( defaultContainerVariants ) ,
10792 } ;
93+
10894 const containerVariants = variants ?. container || selectedVariants . container ;
10995 const itemVariants = variants ?. item || selectedVariants . item ;
11096
111- const MotionComponent = React . useMemo ( ( ) => motion . create ( as as keyof JSX . IntrinsicElements ) , [ as ] ) ;
112- const MotionChild = React . useMemo ( ( ) => motion . create ( asChild as keyof JSX . IntrinsicElements ) , [ asChild ] ) ;
97+ const MotionComponent = React . useMemo ( ( ) => getMotionComponent ( as ) , [ as ] ) ;
98+ const MotionChild = React . useMemo ( ( ) => getMotionComponent ( asChild ) , [ asChild ] ) ;
11399
114100 return (
115101 < MotionComponent initial = "hidden" animate = "visible" variants = { containerVariants } className = { className } >
0 commit comments