Skip to Content
Dashflow Logo

Collapsible Component

A comprehensive guide to using the Collapsible component with examples, props, and best practices.


Overview

The Collapsible component provides a way to show and hide content with a smooth animation. It's commonly used for FAQ sections, settings panels, and any content that needs to be toggled on and off.

Basic Usage

import { Collapsible } from '@dashflowx/core'
export default function CollapsibleExample() {
const [isOpen, setIsOpen] = useState(false);
return (
<Collapsible
isOpen={isOpen}
onOpenChange={setIsOpen}
title="Click to expand"
collapsibleContent={<div>This content can be toggled</div>}
/>
)
}

Preview:

Click to expand

Loading Button...

Props

PropTypeDefaultDescription
isOpenbooleanfalseWhether the collapsible is open
onOpenChangefunction-Callback when open state changes
titlestring'Collapsible Title'The title text for the collapsible
collapsibleContentJSX.Element-The content to show/hide
classNamestring''Additional CSS classes for the container
titleContainerClassNamestring''Additional CSS classes for the title container
titleClassNamestring''Additional CSS classes for the title
contentClassNamestring''Additional CSS classes for the content

Examples

Basic Collapsible

const [isOpen, setIsOpen] = useState(false);
<Collapsible
isOpen={isOpen}
onOpenChange={setIsOpen}
title="Basic Collapsible"
collapsibleContent={<p>This is the collapsible content.</p>}
/>

Preview:

Basic Collapsible

Loading Button...

FAQ Section

const [openItems, setOpenItems] = useState<string[]>([]);
const toggleItem = (id: string) => {
setOpenItems(prev =>
prev.includes(id)
? prev.filter(item => item !== id)
: [...prev, id]
);
};
const faqItems = [
{
id: '1',
question: 'What is this service?',
answer: 'This is a comprehensive service that provides various features and functionality.'
},
{
id: '2',
question: 'How do I get started?',
answer: 'You can get started by creating an account and following our onboarding process.'
}
];
<div className="space-y-4">
{faqItems.map(item => (
<Collapsible
key={item.id}
isOpen={openItems.includes(item.id)}
onOpenChange={() => toggleItem(item.id)}
title={item.question}
collapsibleContent={<p>{item.answer}</p>}
/>
))}
</div>

Preview:

What is this service?

Loading Button...

Settings Panel

const [isOpen, setIsOpen] = useState(false);
<Collapsible
isOpen={isOpen}
onOpenChange={setIsOpen}
title="Advanced Settings"
collapsibleContent={
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">Setting 1</label>
<input type="text" className="w-full border rounded px-3 py-2" />
</div>
<div>
<label className="block text-sm font-medium mb-2">Setting 2</label>
<select className="w-full border rounded px-3 py-2">
<option>Option 1</option>
<option>Option 2</option>
</select>
</div>
</div>
}
/>

Preview:

Advanced Settings

Loading Button...

Custom Styled Collapsible

<Collapsible
isOpen={isOpen}
onOpenChange={setIsOpen}
title="Custom Styled"
collapsibleContent={<p>This collapsible has custom styling.</p>}
className="border-2 border-blue-500 rounded-xl"
titleContainerClassName="bg-blue-50"
titleClassName="text-blue-800"
contentClassName="bg-blue-25"
/>

Preview:

Custom Styled

Loading Button...

Common Use Cases

FAQ Section

const faqData = [
{
id: '1',
question: 'How do I reset my password?',
answer: 'You can reset your password by clicking the "Forgot Password" link on the login page.'
},
{
id: '2',
question: 'Can I change my email address?',
answer: 'Yes, you can change your email address in the account settings section.'
},
{
id: '3',
question: 'Is there a mobile app?',
answer: 'Yes, we have mobile apps available for both iOS and Android devices.'
}
];
<div className="max-w-2xl mx-auto space-y-4">
<h2 className="text-2xl font-bold text-center mb-8">Frequently Asked Questions</h2>
{faqData.map(item => (
<Collapsible
key={item.id}
isOpen={openItems.includes(item.id)}
onOpenChange={() => toggleItem(item.id)}
title={item.question}
collapsibleContent={<p className="text-gray-600">{item.answer}</p>}
/>
))}
</div>

Documentation Sections

const docSections = [
{
id: 'installation',
title: 'Installation',
content: (
<div className="space-y-3">
<p>Follow these steps to install the package:</p>
<ol className="list-decimal list-inside space-y-1">
<li>Run <code>npm install package-name</code></li>
<li>Import the component in your file</li>
<li>Use the component in your JSX</li>
</ol>
</div>
)
},
{
id: 'usage',
title: 'Usage',
content: (
<div className="space-y-3">
<p>Here's how to use the component:</p>
<pre className="bg-gray-100 p-3 rounded text-sm">
<code>{`<Component prop="value" />`}</code>
</pre>
</div>
)
}
];
<div className="space-y-4">
{docSections.map(section => (
<Collapsible
key={section.id}
isOpen={openItems.includes(section.id)}
onOpenChange={() => toggleItem(section.id)}
title={section.title}
collapsibleContent={section.content}
/>
))}
</div>

Filter Options

const [filtersOpen, setFiltersOpen] = useState(false);
<Collapsible
isOpen={filtersOpen}
onOpenChange={setFiltersOpen}
title="Filter Options"
collapsibleContent={
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium mb-2">Category</label>
<select className="w-full border rounded px-3 py-2">
<option>All Categories</option>
<option>Technology</option>
<option>Design</option>
</select>
</div>
<div>
<label className="block text-sm font-medium mb-2">Price Range</label>
<select className="w-full border rounded px-3 py-2">
<option>Any Price</option>
<option>Under $50</option>
<option>$50 - $100</option>
</select>
</div>
</div>
}
/>

Help Sections

const helpSections = [
{
id: 'getting-started',
title: 'Getting Started',
content: (
<div className="space-y-3">
<p>Welcome! Here's how to get started:</p>
<ul className="list-disc list-inside space-y-1">
<li>Create your account</li>
<li>Complete your profile</li>
<li>Explore the features</li>
</ul>
</div>
)
},
{
id: 'troubleshooting',
title: 'Troubleshooting',
content: (
<div className="space-y-3">
<p>Having issues? Try these solutions:</p>
<ul className="list-disc list-inside space-y-1">
<li>Check your internet connection</li>
<li>Clear your browser cache</li>
<li>Contact support if problems persist</li>
</ul>
</div>
)
}
];

Best Practices

Clear Titles

Use clear and descriptive titles for collapsible sections.

// ✅ Good - Clear title
<Collapsible
title="How do I reset my password?"
collapsibleContent={<p>Answer content...</p>}
/>
// ❌ Avoid - Unclear title
<Collapsible
title="Question 1"
collapsibleContent={<p>Answer content...</p>}
/>

Consistent State Management

Use consistent state management patterns for multiple collapsibles.

// ✅ Good - Consistent state management
const [openItems, setOpenItems] = useState<string[]>([]);
const toggleItem = (id: string) => {
setOpenItems(prev =>
prev.includes(id)
? prev.filter(item => item !== id)
: [...prev, id]
);
};

Appropriate Content Length

Keep collapsible content concise and focused.

// ✅ Good - Concise content
<Collapsible
title="Quick Answer"
collapsibleContent={<p>Short, focused answer.</p>}
/>
// ❌ Avoid - Too much content
<Collapsible
title="Long Answer"
collapsibleContent={<div>Very long content that should probably be on its own page...</div>}
/>

Accessible Implementation

Ensure collapsibles are accessible to all users.

// ✅ Good - Accessible
<Collapsible
title="Accessible Section"
collapsibleContent={<p>Content with proper ARIA attributes</p>}
/>

Visual Hierarchy

Use collapsibles to create clear visual hierarchy.

// ✅ Good - Clear hierarchy
<div className="space-y-4">
<h2>Main Section</h2>
<Collapsible title="Subsection 1" />
<Collapsible title="Subsection 2" />
</div>

Customization

Custom Styling

You can customize the collapsible appearance using CSS classes:

<Collapsible
title="Custom Styled"
collapsibleContent={<p>Custom content</p>}
className="border-2 border-purple-500 rounded-xl shadow-lg"
titleContainerClassName="bg-purple-50"
titleClassName="text-purple-800 font-bold"
contentClassName="bg-purple-25"
/>

Different Themes

Use different themes for different contexts:

// Light theme
<Collapsible
title="Light Theme"
collapsibleContent={<p>Light themed content</p>}
className="bg-white border-gray-200"
/>
// Dark theme
<Collapsible
title="Dark Theme"
collapsibleContent={<p>Dark themed content</p>}
className="bg-gray-900 border-gray-700 text-white"
/>

Size Variations

Use different sizes for different emphasis levels:

// Small collapsible
<Collapsible
title="Small"
collapsibleContent={<p>Small content</p>}
className="w-64"
/>
// Large collapsible
<Collapsible
title="Large"
collapsibleContent={<p>Large content</p>}
className="w-full max-w-4xl"
/>

Advanced Usage

Multiple Collapsibles

Manage multiple collapsibles with shared state:

const [openSections, setOpenSections] = useState<Set<string>>(new Set());
const toggleSection = (id: string) => {
setOpenSections(prev => {
const newSet = new Set(prev);
if (newSet.has(id)) {
newSet.delete(id);
} else {
newSet.add(id);
}
return newSet;
});
};

Accordion Behavior

Create accordion behavior where only one item can be open:

const [openItem, setOpenItem] = useState<string | null>(null);
const toggleItem = (id: string) => {
setOpenItem(prev => prev === id ? null : id);
};

Dynamic Content

Use dynamic content in collapsibles:

const [content, setContent] = useState('Initial content');
<Collapsible
title="Dynamic Content"
collapsibleContent={<p>{content}</p>}
/>
  • Accordion: For multiple collapsible sections
  • Disclosure: For simple show/hide functionality
  • Tabs: For tabbed content
  • Modal: For overlay content
  • Sheet: For slide-out content

API Reference

For the complete API reference and advanced usage patterns, see the Collapsible API documentation.

Edit this page on GitHub