From cff23e114fbebd5841527eec189cabc56c82b272 Mon Sep 17 00:00:00 2001 From: etesam Date: Wed, 22 Nov 2023 23:31:12 -0500 Subject: [PATCH] :bug: Fixed bug in context provider in `` --- packages/react-magic-motion/tests/index.tsx | 12 ++++++- .../tests/magic-motion.test.tsx | 31 ++++++++++++++++- .../utils/magic-animation.ts | 34 ++++++++++++++----- 3 files changed, 66 insertions(+), 11 deletions(-) diff --git a/packages/react-magic-motion/tests/index.tsx b/packages/react-magic-motion/tests/index.tsx index f1380a6..6c7c3dc 100644 --- a/packages/react-magic-motion/tests/index.tsx +++ b/packages/react-magic-motion/tests/index.tsx @@ -1,4 +1,4 @@ -import { forwardRef, useRef, cloneElement } from "react"; +import { forwardRef, useRef, cloneElement, createContext } from "react"; import type { ReactElement, ReactNode } from "react"; export function TestComponent({ @@ -48,3 +48,13 @@ export function cloneRootElem(rootElem: ReactElement): ReactNode { exit: { opacity: 0 }, }); } + +const ContextExample = createContext({}); + +export function ContextProviderParent(): JSX.Element { + return ( + +
Testing
+
+ ); +} diff --git a/packages/react-magic-motion/tests/magic-motion.test.tsx b/packages/react-magic-motion/tests/magic-motion.test.tsx index 1cc16b6..a307096 100644 --- a/packages/react-magic-motion/tests/magic-motion.test.tsx +++ b/packages/react-magic-motion/tests/magic-motion.test.tsx @@ -2,10 +2,16 @@ import { render } from "@testing-library/react"; import { beforeAll, describe, expect, test, vi, afterEach } from "vitest"; import "@testing-library/jest-dom"; import { motion } from "framer-motion"; +import { Profiler } from "react"; import { convertChildrenToMotionChildren } from "../utils/magic-animation"; import { MagicExit } from "../magic-exit"; import { MagicMotion } from "../magic-motion"; -import { TestComponent, ParentComponent, ForwardedRefParent } from "."; +import { + TestComponent, + ParentComponent, + ForwardedRefParent, + ContextProviderParent, +} from "."; describe(" tests", () => { const consoleMock = vi @@ -370,4 +376,27 @@ describe(" tests", () => { ); }); + + test("a context provider child", () => { + render( + + + + ); + }); + + test("a react profiler child", () => { + render( + + { + return "ok"; + }} + > +
test
+
+
+ ); + }); }); diff --git a/packages/react-magic-motion/utils/magic-animation.ts b/packages/react-magic-motion/utils/magic-animation.ts index c4ec8c4..179568a 100644 --- a/packages/react-magic-motion/utils/magic-animation.ts +++ b/packages/react-magic-motion/utils/magic-animation.ts @@ -1,7 +1,13 @@ import type { FunctionComponent, Ref, ReactNode, ReactElement } from "react"; import { Children, createElement, isValidElement } from "react"; import { isMotionComponent, m } from "framer-motion"; -import { isForwardRef, isPortal } from "react-is"; +import { + isForwardRef, + isPortal, + isContextConsumer, + isContextProvider, + isProfiler, +} from "react-is"; import { FORBIDDENELEMENTMESSAGE, FUNCTIONCOMPONENTMESSAGE, @@ -17,6 +23,20 @@ function isNodeText(node: ReactNode): boolean { ); } +export function getIfComponentCanBeConverted( + node: React.ReactPortal | ReactElement, + nodeType: string | React.ComponentType +): boolean { + return ( + !isMotionComponent(nodeType) && + !isPortal(node) && + !isProfiler(node) && + !isForwardRef(node) && + !isContextProvider(node) && + !isContextConsumer(node) + ); +} + /** Sets the `layout` property depending on the type of the children*/ export function getLayoutValueFromChildren( children: ReactNode @@ -81,7 +101,7 @@ export function convertChildrenToMotionChildren( } // Checks if the child is a function component - let parent:ReactNode = null; + let parent: ReactNode = null; while (typeof node.type === "function") { if (isLoggingEnabled) logSuccess(FUNCTIONCOMPONENTMESSAGE(node.type.name)); @@ -105,14 +125,10 @@ export function convertChildrenToMotionChildren( // @ts-expect-error - This is a hack to get around the fact that the ref type is not correct const nodeRef = isPortal(node) ? null : (node.ref as Ref); - - // If the child is a motion component or forwardRef, we use that as the type otherwise convert it to a motion component - const shouldConvertNodeToMotionComponent = isMotionComponent(node.type) || isForwardRef(node) - + + // If the child is a motion component or forwardRef, we use that as the type otherwise convert it to a motion component const typeOfNewElement = ( - shouldConvertNodeToMotionComponent - ? node.type - : m[childType] + getIfComponentCanBeConverted(node, node.type) ? m[childType] : node.type ) as string | FunctionComponent; const newElemChildren = convertChildrenToMotionChildren(