Skip to content

Commit

Permalink
Merge pull request #1410 from framer/feature/inject-is-valid-prop
Browse files Browse the repository at this point in the history
Adding isValidProp to MotionConfig
  • Loading branch information
mergetron[bot] committed Jan 12, 2022
2 parents a876db4 + 8e7667a commit 4f2b596
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 11 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Expand Up @@ -2,6 +2,12 @@

Framer Motion adheres to [Semantic Versioning](http://semver.org/).

## [5.6.0] 2022-01-12

### Added

- `isValidProp` prop to `MotionConfig` that allows the injection of custom detection of valid React props.

## [5.5.8] 2022-01-12

### Fixed
Expand Down
21 changes: 21 additions & 0 deletions src/components/MotionConfig/__tests__/index.test.tsx
@@ -0,0 +1,21 @@
import { render } from "../../../../jest.setup"
import { motion } from "../../../render/dom/motion"
import { MotionConfig } from "../"
import * as React from "react"

describe("custom properties", () => {
test("renders", () => {
const Component = () => {
return (
<MotionConfig isValidProp={(key) => key !== "data-foo"}>
<motion.div data-foo="bar" data-bar="foo" />
</MotionConfig>
)
}

const { container } = render(<Component />)

expect(container.firstChild).not.toHaveAttribute("data-foo")
expect(container.firstChild).toHaveAttribute("data-bar")
})
})
13 changes: 12 additions & 1 deletion src/components/MotionConfig/index.tsx
@@ -1,10 +1,15 @@
import * as React from "react"
import { useContext, useMemo } from "react"
import { MotionConfigContext } from "../../context/MotionConfigContext"
import {
loadExternalIsValidProp,
IsValidProp,
} from "../../render/dom/utils/filter-props"
import { useConstant } from "../../utils/use-constant"

export interface MotionConfigProps extends Partial<MotionConfigContext> {
children?: React.ReactNode
isValidProp?: IsValidProp
}

/**
Expand All @@ -24,7 +29,13 @@ export interface MotionConfigProps extends Partial<MotionConfigContext> {
*
* @public
*/
export function MotionConfig({ children, ...config }: MotionConfigProps) {
export function MotionConfig({
children,
isValidProp,
...config
}: MotionConfigProps) {
isValidProp && loadExternalIsValidProp(isValidProp)

/**
* Inherit props from any parent MotionConfig components
*/
Expand Down
1 change: 1 addition & 0 deletions src/projection/node/create-projection-node.ts
Expand Up @@ -680,6 +680,7 @@ export function createProjectionNode<I>({
measured,
actual: this.removeElementScroll(measured),
}

this.layoutCorrected = createBox()
this.isLayoutDirty = false
this.projectionDelta = undefined
Expand Down
26 changes: 16 additions & 10 deletions src/render/dom/utils/filter-props.ts
Expand Up @@ -3,6 +3,16 @@ import { isValidMotionProp } from "../../../motion/utils/valid-prop"

let shouldForward = (key: string) => !isValidMotionProp(key)

export type IsValidProp = (key: string) => boolean

export function loadExternalIsValidProp(isValidProp?: IsValidProp) {
if (!isValidProp) return

// Explicitly filter our events
shouldForward = (key: string) =>
key.startsWith("on") ? !isValidMotionProp(key) : isValidProp(key)
}

/**
* Emotion and Styled Components both allow users to pass through arbitrary props to their components
* to dynamically generate CSS. They both use the `@emotion/is-prop-valid` package to determine which
Expand All @@ -17,16 +27,12 @@ let shouldForward = (key: string) => !isValidMotionProp(key)
* actually required.
*/
try {
const emotionIsPropValid = require("@emotion/is-prop-valid").default

shouldForward = (key: string) => {
// Handle events explicitly as Emotion validates them all as true
if (key.startsWith("on")) {
return !isValidMotionProp(key)
} else {
return emotionIsPropValid(key)
}
}
/**
* We attempt to import this package but require won't be defined in esm environments, in that case
* isPropValid will have to be provided via `MotionContext`. In a 6.0.0 this should probably be removed
* in favour of explicit injection.
*/
loadExternalIsValidProp(require("@emotion/is-prop-valid").default)
} catch {
// We don't need to actually do anything here - the fallback is the existing `isPropValid`.
}
Expand Down

0 comments on commit 4f2b596

Please sign in to comment.