Skip to content

Commit

Permalink
Support for motion(Fragment) (#2527)
Browse files Browse the repository at this point in the history
* Adding support for react fragment

* Updating example

* v11.0.6-alpha.0

* Version

* Updating size

* Removing invalid props from Fragment

* v11.0.6-alpha.1

* Latest
  • Loading branch information
mattgperry authored Feb 23, 2024
1 parent 14c7320 commit 5c4e338
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 27 deletions.
11 changes: 5 additions & 6 deletions dev/examples/Animation-variants.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
import React from "react"
import { motion, useMotionValue } from "framer-motion"

const MotionFragment = motion(React.Fragment)

export function App() {
const backgroundColor = useMotionValue("#f00")
const [isActive, setIsActive] = React.useState(true)
return (
<motion.div
initial="initial"
animate={isActive ? "to" : "initial"}
onClick={() => setIsActive(!isActive)}
>
<MotionFragment initial="initial" animate={isActive ? "to" : "initial"}>
<motion.div>
<motion.div
variants={{
Expand All @@ -20,10 +18,11 @@ export function App() {
backgroundColor: "#00f",
},
}}
onClick={() => setIsActive(!isActive)}
style={{ ...box, backgroundColor }}
/>
</motion.div>
</motion.div>
</MotionFragment>
)
}

Expand Down
6 changes: 3 additions & 3 deletions dev/package.json
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
{
"name": "framer-motion--dev",
"version": "11.0.5",
"version": "11.0.6-alpha.1",
"private": true,
"scripts": {
"dev": "webpack serve --config ./webpack/config.js --hot"
},
"dependencies": {
"@react-three/drei": "^7.27.3",
"@react-three/fiber": "^8.2.2",
"framer-motion": "^11.0.5",
"framer-motion-3d": "^11.0.5",
"framer-motion": "^11.0.6-alpha.1",
"framer-motion-3d": "^11.0.6-alpha.1",
"path-browserify": "^1.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
Expand Down
2 changes: 1 addition & 1 deletion lerna.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"version": "11.0.5",
"version": "11.0.6-alpha.1",
"packages": [
"packages/*"
],
Expand Down
6 changes: 3 additions & 3 deletions packages/framer-motion-3d/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "framer-motion-3d",
"version": "11.0.5",
"version": "11.0.6-alpha.1",
"description": "A simple and powerful React animation library for @react-three/fiber",
"main": "dist/cjs/index.js",
"module": "dist/es/index.mjs",
Expand Down Expand Up @@ -46,7 +46,7 @@
"postpublish": "git push --tags"
},
"dependencies": {
"framer-motion": "^11.0.5",
"framer-motion": "^11.0.6-alpha.1",
"react-merge-refs": "^2.0.1"
},
"peerDependencies": {
Expand All @@ -60,5 +60,5 @@
"@react-three/test-renderer": "^9.0.0",
"@rollup/plugin-commonjs": "^22.0.1"
},
"gitHead": "789e502ed2ae98982e7f0ec10f42896fb82ee6e1"
"gitHead": "e2fbe34a0b3c031b5fc856e1b4c4124479c4b754"
}
6 changes: 3 additions & 3 deletions packages/framer-motion/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "framer-motion",
"version": "11.0.5",
"version": "11.0.6-alpha.1",
"description": "A simple and powerful JavaScript animation library",
"main": "dist/cjs/index.js",
"module": "dist/es/index.mjs",
Expand Down Expand Up @@ -85,7 +85,7 @@
"bundlesize": [
{
"path": "./dist/size-rollup-motion.js",
"maxSize": "31.24 kB"
"maxSize": "31.26 kB"
},
{
"path": "./dist/size-rollup-m.js",
Expand Down Expand Up @@ -116,5 +116,5 @@
"maxSize": "32.1 kB"
}
],
"gitHead": "789e502ed2ae98982e7f0ec10f42896fb82ee6e1"
"gitHead": "e2fbe34a0b3c031b5fc856e1b4c4124479c4b754"
}
16 changes: 16 additions & 0 deletions packages/framer-motion/src/motion/__tests__/ssr.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import { motionValue } from "../../value"
import { AnimatePresence } from "../../components/AnimatePresence"
import { Reorder } from "../../components/Reorder"

const MotionFragment = motion(React.Fragment)

function runTests(render: (components: any) => string) {
test("doesn't throw", () => {
render(
Expand All @@ -21,6 +23,20 @@ function runTests(render: (components: any) => string) {
expect(true).toBe(true)
})

test("doesn't throw when rendering Fragment", () => {
render(
<MotionFragment
initial={{ x: 100 }}
whileTap={{ opacity: 0 }}
drag
layout
layoutId="a"
style={{ opacity: 1 }}
/>
)

expect(true).toBe(true)
})
test("correctly renders HTML", () => {
const y = motionValue(200)
const div = render(
Expand Down
50 changes: 50 additions & 0 deletions packages/framer-motion/src/motion/__tests__/variant.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import { motionValue } from "../../value"
import { useState } from "react"
import { nextFrame } from "../../gestures/__tests__/utils"

const MotionFragment = motion(React.Fragment)

describe("animate prop as variant", () => {
test("animates to set variant", async () => {
const variants: Variants = {
Expand Down Expand Up @@ -423,6 +425,54 @@ describe("animate prop as variant", () => {
return expect(promise).resolves.toBe(0.1)
})

/**
* This test enshrines the behaviour that when a value is removed from an element as the result of a parent variant,
* it should fallback to the style prop. This is a bug in Framer Motion - the desired behaviour is that it falls
* back to the defined variant in initial. However, changing this behaviour would break generated code in Framer
* so we can't fix it until we find a migration path out of that.
*/
test("FRAMER BUG: When a value is removed from an element as the result of a parent variant, fallback to style", async () => {
const Component = ({ animate }: { animate?: string }) => {
return (
<MotionFragment initial="a" animate={animate}>
<motion.div
data-testid="child"
variants={{
a: { opacity: 0.5 },
b: { opacity: 1 },
c: {},
}}
transition={{ type: false }}
style={{ opacity: 0 }}
/>
</MotionFragment>
)
}

const { getByTestId, rerender } = render(<Component />)
const element = getByTestId("child")
expect(element).toHaveStyle("opacity: 0.5")

rerender(<Component animate="a" />)
rerender(<Component animate="a" />)

await nextFrame()

expect(element).toHaveStyle("opacity: 0.5")

rerender(<Component animate="b" />)
rerender(<Component animate="b" />)

await nextFrame()
expect(element).toHaveStyle("opacity: 1")

rerender(<Component animate="c" />)
rerender(<Component animate="c" />)

await nextFrame()
expect(element).toHaveStyle("opacity: 0") // Contained in variant a, which is set as initial
})

test("initial: false correctly propagates", async () => {
const promise = new Promise((resolve) => {
const opacity = motionValue(0.5)
Expand Down
11 changes: 5 additions & 6 deletions packages/framer-motion/src/render/dom/use-render.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { createElement, useMemo } from "react"
import { Fragment, createElement, useMemo } from "react"
import { useHTMLProps } from "../html/use-props"
import { filterProps } from "./utils/filter-props"
import { isSVGComponent } from "./utils/is-svg-component"
Expand Down Expand Up @@ -28,11 +28,10 @@ export function createUseRender(forwardMotionProps = false) {
typeof Component === "string",
forwardMotionProps
)
const elementProps = {
...filteredProps,
...visualProps,
ref,
}
const elementProps =
Component !== Fragment
? { ...filteredProps, ...visualProps, ref }
: {}

/**
* If component has been handed a motion value as its child,
Expand Down
10 changes: 5 additions & 5 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8010,8 +8010,8 @@ __metadata:
cache-loader: ^1.2.5
convert-tsconfig-paths-to-webpack-aliases: ^0.9.2
fork-ts-checker-webpack-plugin: ^6.2.0
framer-motion: ^11.0.5
framer-motion-3d: ^11.0.5
framer-motion: ^11.0.6-alpha.1
framer-motion-3d: ^11.0.6-alpha.1
path-browserify: ^1.0.1
react: ^18.2.0
react-dom: ^18.2.0
Expand Down Expand Up @@ -8080,14 +8080,14 @@ __metadata:
languageName: unknown
linkType: soft

"framer-motion-3d@^11.0.5, framer-motion-3d@workspace:packages/framer-motion-3d":
"framer-motion-3d@^11.0.6-alpha.1, framer-motion-3d@workspace:packages/framer-motion-3d":
version: 0.0.0-use.local
resolution: "framer-motion-3d@workspace:packages/framer-motion-3d"
dependencies:
"@react-three/fiber": ^8.2.2
"@react-three/test-renderer": ^9.0.0
"@rollup/plugin-commonjs": ^22.0.1
framer-motion: ^11.0.5
framer-motion: ^11.0.6-alpha.1
react-merge-refs: ^2.0.1
peerDependencies:
"@react-three/fiber": ^8.2.2
Expand All @@ -8097,7 +8097,7 @@ __metadata:
languageName: unknown
linkType: soft

"framer-motion@^11.0.5, framer-motion@workspace:packages/framer-motion":
"framer-motion@^11.0.6-alpha.1, framer-motion@workspace:packages/framer-motion":
version: 0.0.0-use.local
resolution: "framer-motion@workspace:packages/framer-motion"
dependencies:
Expand Down

0 comments on commit 5c4e338

Please sign in to comment.