Search code examples
reactjsanimationheightframer-motion

Animating height using Framer Motion not working in React


So, I have been trying to use Framer Motion for my React project. I basically want to animate the height from 0 to "auto", when the div gets rendered. I tried the below code, but the height is not getting animated

<motion.div
  initial={{ height: 0 }}
  animate={{ height: "auto" }}
  transition={{ duration: 0.5 }}
  key={searchQuery?.length}
>

When I replaced height with width, the animation works fine, but can't figure out why the height is not getting animated. And I was unable to find any proper documentation regarding this.

Here is the CodeSandbox Link for demo.


Solution

  • Fixed versinn

    What was wrong?

    Your conditional rendering logic was in the wrong place, AnimatePresence works only if its direct child disappears.

    exit prop was missing

    key prop has to be stable, it can't be the length of the string

    overflow: hidden have to be added so the children are invisible

    Final code:

    export default function App() {
      const ref = useRef(null);
      const [isActive, setIsActive] = useState(false);
      const [searchQuery, setSearchQuery] = useState("");
    
      return (
        <div className="App">
          <h1>Hello CodeSandbox</h1>
          <h2>Start editing to see some magic happen!</h2>
          <div>
            <input
              placeholder={"Enter Keyword"}
              value={searchQuery}
              onChange={(e) => {
                setSearchQuery(e.target.value);
              }}
            />
            <AnimatePresence>
              {searchQuery?.length >= 1 && (
                <motion.div
                  style={{ overflow: "hidden" }}
                  initial={{ height: 0 }}
                  animate={{ height: "auto" }}
                  transition={{ duration: 0.5 }}
                  exit={{ height: 0 }}
                  key={"container"}
                >
                  {dataList?.map((listItem) => (
                    <div
                      style={{
                        padding: "1rem",
                        color: "#E090EE",
                        borderBottom: "1px solid #E1E1E1",
                      }}
                    >
                      {listItem.activity_title}
                    </div>
                  ))}
                </motion.div>
              )}
            </AnimatePresence>
          </div>
        </div>
      );
    }