All files / src/render/dom/utils filter-props.ts

87.5% Statements 14/16
84.62% Branches 11/13
75% Functions 3/4
100% Lines 14/14

Press n or j to go to the next uncovered block, b, p or k for the previous block.

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 55 56 57 58 59 60 61  34x   34x       34x 36x     36x 5718x                               34x           34x         34x         1410x   1410x 5718x             1296x       1410x    
import { MotionProps } from "../../../motion/types"
import { isValidMotionProp } from "../../../motion/utils/valid-prop"
 
let shouldForward = (key: string) => !isValidMotionProp(key)
 
export type IsValidProp = (key: string) => boolean
 
export function loadExternalIsValidProp(isValidProp?: IsValidProp) {
    Iif (!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
 * 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 {
    /**
     * 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`.
}
 
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
}