skip to Main Content

I tried to copy this code and convert native javascript to React, everything but the transition works (the content suddenly grows but it has no animation)

import { useState } from "react"

import { FaMinus, FaPlus } from "react-icons/fa"

function Accordion({ title, content }: { title: string; content: string }) {
  const [expanded, setExpanded] = useState(false)
  const toggleExpanded = () => setExpanded((current) => !current)

  return (
    <div className={`transition hover:bg-indigo-50 ${expanded ? "bg-indigo-50" : "bg-white"}`} onClick={toggleExpanded}>
      <div className="accordion-header cursor-pointer transition flex space-x-5 px-5 items-center h-16 select-none">
        {expanded ? <FaMinus className="text-indigo-500" /> : <FaPlus className="text-indigo-500" />}
        <h3>{title}</h3>
      </div>
      <div className={`px-5 pt-0 overflow-hidden transition ${expanded ? "max-h-fit" : "max-h-0"}`}>
        <p className="leading-6 font-light pl-9 pb-4 text-justify">{content}</p>
      </div>
    </div>
  )
}

function AccordionWrapper() {
  return (
    <div className="h-screen bg-gradient-to-br from-pink-50 to-indigo-100 grid place-items-center">
      <div className="w-6/12 mx-auto rounded border">
        <div className="bg-white p-10 shadow-sm">
          <h3 className="text-lg font-medium text-gray-800">Several Windows stacked on each other</h3>
          <p className="text-sm font-light text-gray-600 my-3">The accordion is a graphical control element comprising a vertically stacked list of items such as labels or thumbnails</p>
          <div className="h-1 w-full mx-auto border-b my-5"></div>
          <Accordion title="What is term?" content="Our asked sex point her she seems. New plenty she horses parish design you. Stuff sight equal of my woody. Him children bringing goodness suitable she entirely put far daughter." />
        </div>
      </div>
    </div>
  )
}

2

Answers


  1. Chosen as BEST ANSWER

    You need more styles that just transition, you will need to add overflow-hidden transition-[max-height] duration-500 ease-in to the div that you want to change it's max-height

    Also as explained in this question you can't use max-h-fit, you will need to set a value for it max-h-40

    const { useState } = React
    
    const minusIcon = '-'
    const plusIcon = '+'
    
    function Accordion({ title, content }) {
      const [expanded, setExpanded] = useState(false)
      const toggleExpanded = () => setExpanded((current) => !current)
    
      return (
        <div className="my-2 sm:my-4 md:my-6 shadow-sm cursor-pointer bg-white" onClick={toggleExpanded}>
          <div className="px-6 text-left items-center h-20 select-none flex justify-between flex-row">
            <h5 className="flex-1">
              {title}
            </h5>
            <div className="flex-none pl-2">{expanded ? minusIcon : plusIcon}</div>
          </div>
          <div className={`px-6 pt-0 overflow-hidden transition-[max-height] duration-500 ease-in ${expanded ? "max-h-40" : "max-h-0"}`}>
            <p className="pb-4 text-left">
              {content}
            </p>
          </div>
        </div>
      )
    }
    
    const lorem = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."
    
    ReactDOM.createRoot(
        document.getElementById("root")
    ).render(
        <div className='py-16 md:py-20 lg:py-24 px-4 bg-black'>
          <section className="max-w-6xl mx-auto text-center">
            <Accordion title="Accordion #1" content={lorem} />
            <Accordion title="Accordion #2" content={lorem} />
            <Accordion title="Accordion #3" content={lorem} />
          </section>
        </div>
    );
    <div id="root"></div>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://unpkg.com/react@18/umd/react.development.js" crossorigin></script>
    <script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js" crossorigin></script>


  2. When you use transition class only that properties transition when they change:
    color, background-color, border-color, text-decoration-color, fill, stroke, opacity, box-shadow, transform, filter, backdrop-filter

    You should use transition-all class instead of transition.

    tailwind docs

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search