framer / motion

Open source, production-ready animation and gesture library for React
https://framer.com/motion
MIT License
22.41k stars 740 forks source link

[BUG] `filter` style type mismatch with using `motion()` with `next/image` #2303

Closed bradlc closed 9 months ago

bradlc commented 9 months ago

Error message

Type 'MotionValue<string>' is not assignable to type '(Filter & (MotionValue<any> | MotionValue<string> | MotionValue<number> | CustomValueType | Filter)) | undefined'.
  Type 'MotionValue<string>' is not assignable to type '"none" & MotionValue<number>'.
    Type 'MotionValue<string>' is not assignable to type '"none"'.(2322)

Reproduction

https://www.typescriptlang.org/play?#code/JYWwDg9gTgLgBAKjgQwM5wEoFNkGN4BmUEIcA5FDvmQFCiSxwDecIEMwEAdgDRwCuqLAFl2nLgBUs4ADbIYWOAF84REuSLIQWKAFo2HbrXrR4ASRDIA5orWkyXLAA8YAelDWstGjKzxRhlwWnnAAvKxi3AAUwTYAlDQ0BPxc+OJwAIJgYFFxzDRwcL6EwDIKUGECQgHiUrLyWAAGAEYy-FBRABxgTnGNBXCUMO1ccAA8NdyxiqgwAJ6+oUwsBKXlyiquAHw0SkA

mattgperry commented 9 months ago

Equally

<Image style={{filter: "test"}} />

Throws a type error, which would be the equivalent of this.

grzegorzxpatyk commented 2 weeks ago

For anyone with similar issue - here's how I fixed it.

Firstly I created MotionImage component according to the framer motion docs - custom components.

Example from the docs.

const Component = React.forwardRef((props, ref) => (
    <div ref={ref} />
))

const MotionComponent = motion(Component)

Then I simply used Omit to omit style prop from next/image ImageProps interface. I believe there could be more narrow typed solution depending on your needs.

import { motion } from 'framer-motion';
import Image, { ImageProps } from 'next/image';
import { forwardRef } from 'react';

const ForwardImage = forwardRef<HTMLImageElement, Omit<ImageProps, 'style'>>(
    function ImageWrapper(props, ref) {
        return <Image {...props} ref={ref} />;
    }
);

export const MotionImage = motion(ForwardImage);

Hope this helps!