# Accordion Collapsible accordion component for organizing content into expandable sections. ## Tag `Accordion` ## Props | Prop | Type | Default | Description | | :--- | :--- | :--- | :--- | | `title` | `string \| VNode \| Signal` | Required | Accordion section title | | `open` | `boolean \| Signal` | `false` | Whether the accordion is expanded | | `name` | `string` | `auto-generated` | Group name for radio-style accordions | | `class` | `string` | `''` | Additional CSS classes | | `children` | `VNode \| Array` | Required | Content to display when expanded | | `items` | `Array` | `-` | Array of accordion items (alternative API) | ## Live Examples ### Basic Accordion

Live Demo

```js const { Accordion, Div, Mount } = window; const BasicDemo = () => { const open1 = $(false); const open2 = $(false); const open3 = $(false); return Div({ class: 'flex flex-col gap-2' }, [ Accordion({ title: 'Section 1', open: open1, children: Div({ class: 'p-2' }, 'Content for section 1. This is a basic accordion section.') }), Accordion({ title: 'Section 2', open: open2, children: Div({ class: 'p-2' }, 'Content for section 2. You can put any content here.') }), Accordion({ title: 'Section 3', open: open3, children: Div({ class: 'p-2' }, 'Content for section 3. Accordions are great for FAQs.') }) ]); }; Mount(BasicDemo, '#demo-basic'); ``` ### Group Accordion (Radio Style)

Live Demo

```js const { Accordion, Div, Mount } = window; const GroupDemo = () => { const openSection = $('section1'); return Div({ class: 'flex flex-col gap-2' }, [ Accordion({ name: 'group', title: 'Section 1', open: () => openSection() === 'section1', children: Div({ class: 'p-2' }, 'Content for section 1. Only one section can be open at a time.') }), Accordion({ name: 'group', title: 'Section 2', open: () => openSection() === 'section2', children: Div({ class: 'p-2' }, 'Content for section 2. Opening this will close section 1.') }), Accordion({ name: 'group', title: 'Section 3', open: () => openSection() === 'section3', children: Div({ class: 'p-2' }, 'Content for section 3. This is useful for FAQ sections.') }) ]); }; Mount(GroupDemo, '#demo-group'); ``` ### Using Items Array

Live Demo

```js const { Accordion, Div, Mount } = window; const ItemsDemo = () => { const openItems = $({ item1: true, item2: false, item3: false }); return Accordion({ items: [ { title: 'First Item', open: () => openItems().item1, children: Div({ class: 'p-2' }, 'This is the content of the first item.') }, { title: 'Second Item', open: () => openItems().item2, children: Div({ class: 'p-2' }, 'This is the content of the second item.') }, { title: 'Third Item', open: () => openItems().item3, children: Div({ class: 'p-2' }, 'This is the content of the third item.') } ] }); }; Mount(ItemsDemo, '#demo-items'); ``` ### FAQ Accordion

Live Demo

```js const { Accordion, Div, Mount } = window; const FaqDemo = () => { const openFaq = $('faq1'); const faqs = [ { id: 'faq1', question: 'What is this component?', answer: 'This is an accordion component built with DaisyUI and Tailwind CSS for creating collapsible content sections.' }, { id: 'faq2', question: 'How do I use it?', answer: 'Simply import the Accordion component and pass title and children props.' }, { id: 'faq3', question: 'Can I have multiple open?', answer: 'Yes! By default, accordions can be opened independently.' } ]; return Div({ class: 'flex flex-col gap-2' }, faqs.map(faq => Accordion({ name: 'faq-group', title: faq.question, open: () => openFaq() === faq.id, children: Div({ class: 'p-2 text-sm' }, faq.answer) }) )); }; Mount(FaqDemo, '#demo-faq'); ``` ### With Rich Content

Live Demo

```js const { Accordion, Div, Span, Mount } = window; const RichDemo = () => { const open1 = $(true); const open2 = $(false); return Div({ class: 'flex flex-col gap-2' }, [ Accordion({ title: Span({ class: 'flex items-center gap-2' }, ['📊', 'Statistics']), open: open1, children: Div({ class: 'p-2' }, [ Div({ class: 'grid grid-cols-2 gap-4' }, [ Div({ class: 'stat bg-base-100 rounded-lg p-3' }, [ Div({ class: 'stat-title' }, 'Users'), Div({ class: 'stat-value text-lg' }, '1,234') ]), Div({ class: 'stat bg-base-100 rounded-lg p-3' }, [ Div({ class: 'stat-title' }, 'Revenue'), Div({ class: 'stat-value text-lg' }, '$45,678') ]) ]) ]) }), Accordion({ title: Span({ class: 'flex items-center gap-2' }, ['👥', 'Team Members']), open: open2, children: Div({ class: 'p-2 space-y-2' }, [ Div({ class: 'flex items-center gap-3 p-2 hover:bg-base-100 rounded-lg' }, [ Div({ class: 'avatar placeholder' }, [ Div({ class: 'bg-primary text-primary-content rounded-full w-10 h-10 flex items-center justify-center' }, 'JD') ]), Div({ class: 'flex-1' }, [ Div({ class: 'font-medium' }, 'John Doe'), Div({ class: 'text-sm opacity-70' }, 'Developer') ]) ]) ]) }) ]); }; Mount(RichDemo, '#demo-rich'); ``` ### Form Accordion

Live Demo

```js const { Accordion, Div, Span, Button, Input, Radio, Mount } = window; const FormAccordion = () => { const openStep = $('step1'); const formData = $({ name: '', email: '', address: '', payment: 'credit' }); const updateField = (field, value) => { formData({ ...formData(), [field]: value }); }; const nextStep = () => { if (openStep() === 'step1') openStep('step2'); else if (openStep() === 'step2') openStep('step3'); }; const prevStep = () => { if (openStep() === 'step2') openStep('step1'); else if (openStep() === 'step3') openStep('step2'); }; const handleSubmit = () => { window.Toast('Form submitted!', 'alert-success', 2000); }; return Div({ class: 'flex flex-col gap-2' }, [ Accordion({ name: 'form-steps', title: Span({ class: 'flex items-center gap-2' }, ['1️⃣', 'Personal Information']), open: () => openStep() === 'step1', children: Div({ class: 'p-4 space-y-4' }, [ Input({ label: 'Full Name', value: () => formData().name, placeholder: 'Enter your name', oninput: (e) => updateField('name', e.target.value) }), Input({ label: 'Email', type: 'email', value: () => formData().email, placeholder: 'email@example.com', oninput: (e) => updateField('email', e.target.value) }), Div({ class: 'flex justify-end mt-2' }, [ Button({ class: 'btn btn-primary btn-sm', onclick: nextStep, disabled: () => !formData().name || !formData().email }, 'Next →') ]) ]) }), Accordion({ name: 'form-steps', title: Span({ class: 'flex items-center gap-2' }, ['2️⃣', 'Address']), open: () => openStep() === 'step2', children: Div({ class: 'p-4 space-y-4' }, [ Input({ label: 'Address', value: () => formData().address, placeholder: 'Street address', oninput: (e) => updateField('address', e.target.value) }), Div({ class: 'flex justify-between mt-2' }, [ Button({ class: 'btn btn-ghost btn-sm', onclick: prevStep }, '← Back'), Button({ class: 'btn btn-primary btn-sm', onclick: nextStep }, 'Next →') ]) ]) }), Accordion({ name: 'form-steps', title: Span({ class: 'flex items-center gap-2' }, ['3️⃣', 'Payment']), open: () => openStep() === 'step3', children: Div({ class: 'p-4 space-y-4' }, [ Div({ class: 'flex flex-col gap-2' }, [ Radio({ label: 'Credit Card', value: () => formData().payment, radioValue: 'credit', onclick: () => updateField('payment', 'credit') }), Radio({ label: 'PayPal', value: () => formData().payment, radioValue: 'paypal', onclick: () => updateField('payment', 'paypal') }), Radio({ label: 'Bank Transfer', value: () => formData().payment, radioValue: 'bank', onclick: () => updateField('payment', 'bank') }) ]), Div({ class: 'flex justify-between mt-2' }, [ Button({ class: 'btn btn-ghost btn-sm', onclick: prevStep }, '← Back'), Button({ class: 'btn btn-success btn-sm', onclick: handleSubmit }, 'Submit') ]) ]) }) ]); }; Mount(FormAccordion, '#demo-form'); ``` ### All Variants

Live Demo

```js const { Accordion, Div, Span, Mount } = window; const VariantsDemo = () => { const open1 = $(true); const open2 = $(false); const open3 = $(false); return Div({ class: 'flex flex-col gap-4' }, [ Div({ class: 'text-sm font-bold' }, 'Default Accordion'), Accordion({ title: 'Default style', open: open1, children: Div({ class: 'p-2' }, 'Default accordion with standard styling.') }), Div({ class: 'text-sm font-bold mt-2' }, 'Custom Styling'), Accordion({ title: Span({ class: 'text-primary font-bold' }, 'Primary Title'), open: open2, class: 'bg-primary/5 border-primary/20', children: Div({ class: 'p-2' }, 'Accordion with custom styling and primary color.') }), Div({ class: 'text-sm font-bold mt-2' }, 'With Icons'), Accordion({ title: Span({ class: 'flex items-center gap-2' }, ['✨', 'Featured Content']), open: open3, children: Div({ class: 'p-2' }, 'Accordion with emoji icons in the title.') }) ]); }; Mount(VariantsDemo, '#demo-variants'); ```