React how to open child components with smooth rendering?

Viewed 156

I am trying to replicate smooth rendering of child components onClick but I am stuck and not sure what to use

Example of what i want to achieve

The animation that gets triggered on toggling the bootstrap accordion

https://getbootstrap.com/docs/5.0/components/accordion/

I have created a minimum reproducible example of my problem like this

Code

index.js

import "./styles.css";
import { useState } from "react";

export default function App() {
  const [isExpanded, setIsExpanded] = useState(false);
  return (
    <div className="App">
      <div className="flex">
        <ul>hello</ul>
        <button onClick={() => setIsExpanded((prev) => !prev)}>
          {isExpanded ? "-" : "+"}
        </button>
      </div>
      {isExpanded ? (
        <>
          <p>Item1</p>
          <p>Item1</p>
          <p>Item1</p>
          <p>Item1</p>
        </>
      ) : null}
    </div>
  );
}

styles.css

.App {
  font-family: sans-serif;
  text-align: center;
}

.flex {
  display: flex;
  justify-content: center;
  align-items: center;
  gap: 20px;
}

.flex button {
  height: 20px;
  background-color: red;
  color: white;
}

.flex button:hover {
  cursor: pointer;
}

CodeSandbox link

https://codesandbox.io/s/festive-meadow-v0cnz?file=/src/App.js

1 Answers

You can achieve this effect by using max-height & toggling the class. So your component items area would become this:

<div class={`content ${isExpanded ? 'active': ''}`}>
  <p>Item1</p>
  <p>Item1</p>
  <p>Item1</p>
  <p>Item1</p>
</div>

and then add this to your styles:

.content {
  border: 1px solid #000;
  max-height: 0;
  overflow: hidden;
  opacity: 0;
  transition: max-height 200ms ease, opacity 200ms ease;
}
.content.active {
  max-height: 1000px;
  opacity: 1;
  transition: max-height 600ms ease, opacity 200ms ease;
}
Related