Reputation: 795
I know that I can apply motion
directly to element/HTMLtag like this:
<motion.div>some content</div>
But how can I apply it to this?
<Comp />
Without wrapping it inside another HTML element, like in React-Transition-Group
library.
Framer API provides Frame
component, but it acts like permanent additional HTML element with own styling, and it is messing my layout.
Upvotes: 10
Views: 16414
Reputation: 2656
The accepted answer brought me on the right track.
But it was still a hassle to get everything working.
Therefore, I've created a full working example of Staggering elements which are React Components. It can be found on this Github link
This core of the solution looks like this:
import React from 'react'
import {motion} from "framer-motion";
interface ListElementInterface {
name: string
}
// *** This is the React Component called in the list
// Pay attention to the ref type. Typescript is a b*tch
const ListElement = React.forwardRef(
(props: ListElementInterface, ref: React.ForwardedRef<HTMLLIElement>) => {
return (
<li ref={ref}>{props.name}</li>
)
})
export const ReactList = () => {
const datalist = [
{name: 'John'},
{name: "Alex"},
{name: "Michael"},
{name: 'Sandra'},
{name: 'Mary'}
]
const olVariants = {
show: {
transition: {
staggerChildren: 0.2
}
}
}
const liVariants = {
hidden: {opacity: 0, x: 100, transition: {duration: 0.5}},
show: {opacity: 1, x: 0, transition: {duration: 0.5}}
}
// You need to create the Motion component.
// Not possible to do something like <motion.ListElement...
const FramerMotionListElement = motion(ListElement)
return (
<>
<motion.ol
variants={olVariants}
initial="hidden"
animate="show"
className="simplelist"
>
{
datalist.map((el) => {
return (
<FramerMotionListElement
variants={liVariants}
key={el.name}
name={`React-${el.name}`}
/>
)
})
}
</motion.ol>
</>
)
}
Upvotes: 2
Reputation: 795
If anyone comes to this page seeking for the solution of how to apply motion
from Framer-Motion library to your React Component and not the direct DOM element like "div" or "span", here it is:
motion.custom()
Example of use:
import { Link } from "react-router-dom"
const MotionLink = motion.custom(Link)
return <MotionLink />
As for today it is not mentioned in the official documentation, or it is in someplace deep and hard to find.
I had found it in BUG reports here, there is a Codesanbox that illustrates my example, created by the person who reported a bug.
Edit: As mentioned by @Aleksandr K. below, use the following for Version >=4.1.3:
const MotionLink = motion(Link)
Upvotes: 30
Reputation:
motion.custom
was deprecated as of v4.0 in favour of motion(Component)
or motion("Component")
.
Your code would simply look like this
const MotionComp = motion(Comp)
return <MotionComp>some content</MotionComp>
Upvotes: 17
Reputation: 53934
Without using any internal fuctions, You just need to wrap it with any motion element:
<motion.div>
<Comp />
</motion.div>
You can notice such behavior across examples in the docs, like of Side Menu example.
Upvotes: 8