Accordion
Expandable content panels. Supports single or multiple expansion, icons, disabled items, and custom content via snippets.
Playground
Experiment with different props in real-time.
Basic Usage
Pass an array of items with label and content.
<script lang="ts">
import { Accordion } from 'sv5ui';
const items = [
{ label: 'What is sv5ui?', content: 'A modern Svelte 5 UI component library.' },
{ label: 'Is it free?', content: 'Yes, sv5ui is open source and free to use.' },
{ label: 'How do I install it?', content: 'Run npm install sv5ui in your project.' }
];
</script>
<Accordion {items} />Multiple
Allow multiple items to be expanded simultaneously.
<Accordion type="multiple" {items} />With Icons
Add leading icons to each item.
<Accordion items={[
{ label: 'Account', icon: 'lucide:user', content: 'Manage your account settings.' },
{ label: 'Notifications', icon: 'lucide:bell', content: 'Configure notification preferences.' },
{ label: 'Security', icon: 'lucide:shield', content: 'Update your security settings.' }
]} />Disabled Items
Disable individual items to prevent expansion.
<Accordion items={[
{ label: 'Available', content: 'This item can be expanded.' },
{ label: 'Disabled', content: 'Cannot expand.', disabled: true },
{ label: 'Also Available', content: 'This item can be expanded too.' }
]} />Disabled (Global)
Disable the entire accordion to prevent any item from being expanded.
<!-- Disable the entire accordion -->
<Accordion disabled items={[
{ label: 'Item 1', content: 'All items are disabled.' },
{ label: 'Item 2', content: 'None can be expanded.' },
{ label: 'Item 3', content: 'The entire accordion is disabled.' }
]} />Default Open
Set an item to be expanded by default with the value prop.
<Accordion value="1" items={[
{ label: 'First', content: 'Closed by default.', value: '0' },
{ label: 'Second', content: 'Open by default.', value: '1' },
{ label: 'Third', content: 'Closed by default.', value: '2' }
]} />Custom Trailing Icon
Replace the default chevron with a custom icon.
<Accordion trailingIcon="lucide:plus" items={[
{ label: 'Question 1', content: 'Answer to question 1.' },
{ label: 'Question 2', content: 'Answer to question 2.' }
]} />Per-Item Trailing Icon
Override the trailing icon on individual items.
<Accordion items={[
{ label: 'Download', trailingIcon: 'lucide:download', content: 'Download the latest version.' },
{ label: 'Settings', trailingIcon: 'lucide:settings', content: 'Configure your preferences.' },
{ label: 'Default Icon', content: 'Uses the default chevron icon.' }
]} />Keyboard Loop
Enable loop to cycle focus from the last item back to the first when navigating with keyboard arrows.
<!-- Focus cycles from last to first item with arrow keys -->
<Accordion loop {items} />Custom Snippets
Use snippets to fully customize trigger and content rendering.
Unlimited projects, priority support, and advanced analytics.
Everything in Pro plus team collaboration and admin controls.
Custom solutions, dedicated support, and SLA guarantees.
<Accordion {items}>
{#snippet label({ item, open })}
<div class="flex flex-col">
<span class="font-semibold">{item.label}</span>
<span class="text-on-surface/50 text-xs">
{open ? 'Click to collapse' : 'Click to expand'}
</span>
</div>
{/snippet}
{#snippet trailing({ open })}
<Icon name={open ? 'lucide:minus' : 'lucide:plus'} class="size-4 text-primary" />
{/snippet}
{#snippet body({ item })}
<div class="flex items-start gap-3">
<Icon name="lucide:check" class="mt-0.5 size-4 text-success" />
<p class="text-sm">{item.content}</p>
</div>
{/snippet}
</Accordion>UI Slots
Use the ui prop to override classes on internal elements.
| Slot | Description |
|---|---|
root | Root accordion container |
item | Individual item container with border |
header | Header flex wrapper |
trigger | Clickable trigger button |
content | Animated content wrapper |
body | Body text content |
leadingIcon | Leading icon element |
trailingIcon | Trailing icon element (chevron) |
label | Label text element |
Snippets
| Name | Props | Description |
|---|---|---|
leading | { item, index, open } | Custom leading section |
label | { item, index, open } | Custom label content |
trailing | { item, index, open } | Custom trailing section |
content | { item, index, open } | Custom entire content area |
body | { item, index, open } | Custom body inside default wrapper |
Props
| Prop | Type | Default |
|---|---|---|
items | AccordionItem[] | - |
type | 'single' | 'multiple' | 'single' |
value | string | string[] | - |
onValueChange | (value: string | string[]) => void | - |
trailingIcon | string | 'lucide:chevron-down' |
loop | boolean | false |
disabled | boolean | false |
orientation | 'vertical' | 'horizontal' | 'vertical' |
forceMount | boolean | false |
class | string | - |
ui | Record<Slot, Class> | - |
Item Props
| Prop | Type | Default |
|---|---|---|
label | string | - |
icon | string | - |
trailingIcon | string | - |
content | string | - |
value | string | index |
disabled | boolean | false |
class | string | - |
ui | Record<Slot, Class> | - |