Accordion

각각 콘텐츠 섹션을 표시하는 세로로 쌓인 대화형 제목 집합입니다.

Example

It can only be viewed in a mobile.

Steps

Prerequisite

Install Pacakge

npm install lucide-react classnames

Copy Code

components/Accordion/index.tsx
'use client'
 
import { memo, useState } from 'react'
import { ChevronUpIcon } from 'lucide-react'
import { cn } from 'utils'
 
export interface Props {
  title: string
  content: string
}
 
function Accordion({ title, content }: Props) {
  const [isOpen, setIsOpen] = useState<boolean>(false)
  const [height, setHeight] = useState<number>(0)
  return (
    <li className="select-none rounded-2xl border border-neutral-200 bg-neutral-50 px-6 dark:border-neutral-800 dark:bg-neutral-900">
      <div
        onClick={() => setIsOpen(() => !isOpen)}
        className="flex cursor-pointer items-center justify-between py-6"
      >
        <h3 className="text-lg font-medium text-neutral-900 dark:text-white">
          {title}
        </h3>
        <button className="text-neutral-400">
          <ChevronUpIcon
            className={cn('h-6 w-6 duration-150', {
              '-rotate-180': isOpen
            })}
          />
        </button>
      </div>
      <section
        style={{ maxHeight: isOpen ? height : 0 }}
        className={cn(
          'overflow-hidden transition-[max-height] duration-150',
          isOpen ? 'ease-in' : 'ease-in-out'
        )}
      >
        <div
          ref={(ref) => {
            const height = ref?.scrollHeight
            if (height) setHeight(height)
          }}
          className="border-t border-neutral-200 py-6 dark:border-neutral-800"
        >
          {content}
        </div>
      </section>
    </li>
  )
}
 
export default memo(Accordion)

Usage

<ul className="space-y-4">
  <Accordion title="JavaScript" content="자바스크립트란..." />
  <Accordion title="Python" content="파이썬이란..." />
  <Accordion title="Kotlin" content="코틀린이란..." />
</ul>

Props

NameTypeDefault
titlestring
contentstring