

본 컴포넌트는 단일 파일 구조 내에서 **"제어(Controlled)"**와 "비제어(Uncontrolled)" 방식을 모두 지원하며, CSS Grid를 활용하여 내부 컨텐츠의 높이에 상관없이 제공하도록 설계되었다.
| 파일명 | 유형 | 주요 역할 |
|---|---|---|
Accordion.tsx |
Client | 높이 애니메이션 로직과 열림/닫힘 상태 관리를 담당하는 아코디언 컴포넌트 |
defaultOpen을 통한 자체 상태 관리뿐만 아니라, 외부 프롭(isOpen, onToggle)을 통한 제어 가능grid-template-rows를 조절하는 방식을 사용하여, 고정 높이 지정 없이도 가변적인 컨텐츠에 대해 슬라이드 효과를 구현useIcon 속성을 통해 상단 트리거 형태의 FAQ 스타일과 하단 트리거 형태의 상세 정보 스타일을 선택할 수 있다.cn 유틸리티 함수를 사용하여 기본 테마와 사용자가 주입한 커스텀 className이 충돌 없이 안전하게 병합된다.모든 표준 HTML 속성을 지원하며, 아래의 커스텀 속성을 추가로 가진다.
| Props | 설명 |
|---|---|
title: React.ReactNode |
아코디언 헤더에 표시될 메인 제목이다. |
subTitle?: React.ReactNode |
하단 버튼 모드(useIcon={false}) 시 표시될 보조 텍스트이다. |
isOpen?: boolean |
외부에서 아코디언의 상태를 직접 제어할 때 주입한다. |
defaultOpen?: boolean(기본값: false) |
초기 렌더링 시 아코디언의 열림 상태를 결정한다. |
onToggle?: () => void |
상태 전환 시 실행될 콜백 함수다. |
useIcon?: boolean(기본값: true) |
아이콘이 포함된 상단 트리거 사용 여부를 결정한다. |
children: React.ReactNode |
아코디언 내부에 펼쳐질 컨텐츠 영역. |
아이콘과 제목이 포함된 가장 보편적인 형태로, 질문 답변(FAQ) 등에 권장된다.
import { Accordion } from "@/shared/ui/accordion";
export default function FaqPage() {
return (
<div className="flex flex-col gap-2">
<Accordion title="서비스 이용 방법" defaultOpen={true}>
회원가입 후 모든 서비스를 자유롭게 이용하실 수 있습니다.
</Accordion>
<Accordion title="결제 수단 안내">
신용카드, 계좌이체, 간편결제 등 다양한 수단을 지원합니다.
</Accordion>
</div>
);
}
제목은 고정되어 보이고, 하단 버튼을 통해 상세 내용을 펼치고 접을 때 사용한다.