If the sections are equal in weight and the reader switches between them, take CdsTabs. For a hierarchy of nested nodes take CdsTree, and for a block that simply separates content — CdsCard.
Anatomy
Panels always live inside a CdsExpandablePanels group: it keeps track of which panels are open and shares the common settings. Each panel is a title button with a state icon plus the content it reveals.
Variations
Panel group
CdsExpandablePanel does not work without the CdsExpandablePanels wrapper — the group is what handles expansion. A simple panel is built from the title and text props, without slots. By default one panel stays open: opening the next one collapses the previous.
Appearance
The appearance prop sets the background of the panels: primary for a regular page, secondary for a colored backdrop, transparent when the panel sits inside an already styled block (a card, a sidebar).
The gap prop changes the spacing between panels — it accepts a number or a string with CSS units.
Layout
The variant="accordion" prop removes the spacing and glues the panels into a single block with shared rounded corners. A list of several questions then reads as one table instead of a set of cards.
Expansion
The multiple prop allows several panels to stay open at once. Through v-model you read and set what is expanded: the index of the panel (or its value) in the regular mode, and an array in multiple. The mandatory prop forbids collapsing the last open panel, and max limits how many can be expanded at the same time.
States
The disabled prop blocks a single panel when set on the panel, and all of them when set on the group: the title stops responding and loses contrast. The readonly prop leaves the panels in their current state — use it in a view mode where the content has to be visible but there is nothing to toggle.
Icons
The state icon comes from the expand-icon and collapse-icon props — on the group, on the panel or on an individual title; the value from the closest level wins. The action slot of the title replaces the icon entirely and receives the state of the panel, and hide-actions removes it altogether.
Slots
The title and text props are enough for a text panel. As soon as the title needs a counter, a status or an icon, assemble it from CdsExpandablePanelTitle and CdsExpandablePanelContent.
| Slot | Description |
|---|---|
CdsExpandablePanels → default | Panels of the group. Slot props carry the next and prev navigation |
CdsExpandablePanel → title | Title content. Replaces the text from title |
CdsExpandablePanel → text | Expandable content. Replaces the text from text |
CdsExpandablePanelTitle → default | Title content. Slot props: expanded, disabled, readonly |
CdsExpandablePanelTitle → action | Expansion icon. Slot props: the same panel state |
Guidelines
Scenarios
Questions and answers
The classic case for accordion: the whole list of questions stays visible and an answer opens on click. Only one answer is open at a time, so the reader does not lose their place in the list. The content renders only after the first expansion; if the answers have to show up in search results, turn on eager.
Form with a summary
The title shows the current value, and the expanded panel holds the field that changes it. The default slot of the title receives expanded, so the caption can change on the fly. Such a form takes little space and keeps what has already been filled in visible.
Filters in a sidebar
Groups of filters in a side panel: multiple keeps the needed sections open, transparent removes the extra background, and a badge in the title shows how many conditions are selected in a collapsed group.
Step-by-step filling
The group slot hands over next and prev — buttons inside a panel move the reader to the next step, while mandatory prevents closing all of the steps at once. For long wizards with per-step validation take CdsSteps.
API
CdsExpandablePanels
Props
| Name | Type | Default | Description |
|---|---|---|---|
appearance | "primary" | "secondary" | "transparent" | undefined | 'primary' | Appearance of the panels |
collapseIcon | IconValue | undefined | 'chevron-up' | Icon shown when the panel is expanded and can be collapsed |
disabled | boolean | null | undefined | null | Disabled state |
eager | boolean | undefined | — | Renders the content of the component right away. Useful when you have content that is not in the DOM but has to be indexed for SEO. |
expandIcon | IconValue | undefined | 'chevron-down' | Icon shown when the panel is collapsed and can be expanded |
focusable | boolean | undefined | — | Highlights the title with a background on focus |
gap | string | number | undefined | — | Spacing between the panels |
hideActions | boolean | undefined | — | Hides the expand/collapse icon |
hover | boolean | undefined | true | Highlights the title with a background on hover |
mandatory | boolean | "force" | undefined | — | Requires at least one item to stay selected |
max | number | undefined | — | Maximum number of items that can be selected |
modelValue | any | — | Value of the selected items of the group |
multiple | boolean | undefined | — | Allows selecting several items at once |
readonly | boolean | null | undefined | null | Read-only state |
required | boolean | "force" | undefined | — | Requires at least one item to stay selected |
selectedClass | string | undefined | — | CSS class applied in the selected state |
static | boolean | undefined | — | Turns off the animation of the title |
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
theme | string | undefined | — | Component theme |
variant | "default" | "accordion" | undefined | 'default' | Display variant of the panel group |
Events
| Name | Type | Description |
|---|---|---|
update:modelValue | [value: unknown] | Fires when the set of selected panels changes. |
Slots
| Name | Type | Description |
|---|---|---|
default | CdsExpandablePanelsSlotProps | Panels of the group. The slot props carry the navigation between panels. |
Exposed
| Name | Type | Description |
|---|---|---|
next | () => void | Expands the next panel |
prev | () => void | Expands the previous panel |
CdsExpandablePanel
Props
| Name | Type | Default | Description |
|---|---|---|---|
collapseIcon | IconValue | undefined | 'chevron-up' | Icon shown when the panel is expanded and can be collapsed |
disabled | boolean | null | undefined | null | Disabled state |
eager | boolean | undefined | — | Renders the content of the component right away. Useful when you have content that is not in the DOM but has to be indexed for SEO. |
expandIcon | IconValue | undefined | 'chevron-down' | Icon shown when the panel is collapsed and can be expanded |
focusable | boolean | undefined | — | Highlights the title with a background on focus |
height | string | number | undefined | — | Component height |
hideActions | boolean | undefined | — | Hides the expand/collapse icon |
hover | boolean | undefined | true | Highlights the title with a background on hover |
maxHeight | string | number | undefined | — | Maximum component height |
maxWidth | string | number | undefined | — | Maximum component width |
minHeight | string | number | undefined | — | Minimum component height |
minWidth | string | number | undefined | — | Minimum component width |
readonly | boolean | null | undefined | null | Read-only state |
selectedClass | string | undefined | — | CSS class applied in the selected state |
static | boolean | undefined | — | Turns off the animation of the title |
tag | string | JSXComponent<any> | undefined | 'div' | Custom HTML tag or component to render |
text | string | undefined | — | Text of the expandable content of the panel |
title | string | undefined | — | Text of the panel title |
value | any | — | Value of the component within the group |
width | string | number | undefined | — | Component width |
Events
| Name | Type | Description |
|---|---|---|
group:selected | [value: { value: boolean; }] | Fires when the panel is expanded or collapsed. |
Slots
| Name | Type | Description |
|---|---|---|
default | any | Arbitrary content of the panel. |
text | any | Expandable content of the panel. |
title | any | Content of the panel title. |
Exposed
| Name | Type | Description |
|---|---|---|
isSelected | boolean | The panel is expanded |
select | (value: boolean) => void | Expands or collapses the panel |
toggle | () => void | Toggles the expansion of the panel |
CdsExpandablePanelTitle
Props
| Name | Type | Default | Description |
|---|---|---|---|
collapseIcon | IconValue | undefined | 'chevron-up' | Icon shown when the panel is expanded and can be collapsed |
expandIcon | IconValue | undefined | 'chevron-down' | Icon shown when the panel is collapsed and can be expanded |
focusable | boolean | undefined | — | Highlights the title with a background on focus |
height | string | number | undefined | — | Component height |
hideActions | boolean | undefined | — | Hides the expand/collapse icon |
hover | boolean | undefined | true | Highlights the title with a background on hover |
maxHeight | string | number | undefined | — | Maximum component height |
maxWidth | string | number | undefined | — | Maximum component width |
minHeight | string | number | undefined | — | Minimum component height |
minWidth | string | number | undefined | — | Minimum component width |
readonly | boolean | null | undefined | null | Read-only state |
static | boolean | undefined | — | Turns off the animation of the title |
width | string | number | undefined | — | Component width |
Slots
| Name | Type | Description |
|---|---|---|
action | CdsExpandablePanelTitleSlotProps | Expand/collapse icon. The slot props carry the state of the panel. |
default | CdsExpandablePanelTitleSlotProps | Content of the title. The slot props carry the state of the panel. |
Exposed
| Name | Type | Description |
|---|---|---|
isSelected | boolean | The panel is expanded |
toggle | () => void | Toggles the expansion of the panel |
CdsExpandablePanelContent
Props
| Name | Type | Default | Description |
|---|---|---|---|
eager | boolean | undefined | — | Renders the content of the component right away. Useful when you have content that is not in the DOM but has to be indexed for SEO. |
Slots
| Name | Type | Description |
|---|---|---|
default | any | Expandable content of the panel. |