-
Notifications
You must be signed in to change notification settings - Fork 743
/
filter-props.ts
54 lines (48 loc) · 1.96 KB
/
filter-props.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import { MotionProps } from "../../../motion/types"
import { isValidMotionProp } from "../../../motion/utils/valid-prop"
let shouldForward = (key: string) => !isValidMotionProp(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
* of these should be passed to the underlying DOM node.
*
* However, when styling a Motion component `styled(motion.div)`, both packages pass through *all* props
* as it's seen as an arbitrary component rather than a DOM node. Motion only allows arbitrary props
* passed through the `custom` prop so it doesn't *need* the payload or computational overhead of
* `@emotion/is-prop-valid`, however to fix this problem we need to use it.
*
* By making it an optionalDependency we can offer this functionality only in the situations where it's
* 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)
}
}
} catch {
// We don't need to actually do anything here - the fallback is the existing `isPropValid`.
}
export function filterProps(
props: MotionProps,
isDom: boolean,
forwardMotionProps: boolean
) {
const filteredProps = {}
for (const key in props) {
if (
shouldForward(key) ||
(forwardMotionProps === true && isValidMotionProp(key)) ||
(!isDom && !isValidMotionProp(key)) ||
// If trying to use native HTML drag events, forward drag listeners
(props["draggable"] && key.startsWith("onDrag"))
) {
filteredProps[key] = props[key]
}
}
return filteredProps
}