Skip to content

CdsExpandablePanel

An expandable panel hides the details behind a title: you see the list of topics and open only the one you need. Take it for FAQs, optional settings and long descriptions that turn a page into an endless feed.

Storybook GitLab Figma
Test coverage: no tests

This component has no automated tests yet: its behavior is verified manually only.

API in specs
0 / 70 props, events, slots and exposed members with a test
Test cases
0 unit · 0 browser
Code coverage
18.4% lines · 0% branches measured in v4.0.0-alpha.13
A11y (axe)
1 recommendations in 13 stories measured in v4.0.0-alpha.11

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.

SlotDescription
CdsExpandablePanels → defaultPanels of the group. Slot props carry the next and prev navigation
CdsExpandablePanel → titleTitle content. Replaces the text from title
CdsExpandablePanel → textExpandable content. Replaces the text from text
CdsExpandablePanelTitle → defaultTitle content. Slot props: expanded, disabled, readonly
CdsExpandablePanelTitle → actionExpansion 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

NameTypeDefaultDescription
appearance"primary" | "secondary" | "transparent" | undefined'primary'Appearance of the panels
collapseIconIconValue | undefined'chevron-up'Icon shown when the panel is expanded and can be collapsed
disabledboolean | null | undefinednullDisabled state
eagerboolean | 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.
expandIconIconValue | undefined'chevron-down'Icon shown when the panel is collapsed and can be expanded
focusableboolean | undefined—Highlights the title with a background on focus
gapstring | number | undefined—Spacing between the panels
hideActionsboolean | undefined—Hides the expand/collapse icon
hoverboolean | undefinedtrueHighlights the title with a background on hover
mandatoryboolean | "force" | undefined—Requires at least one item to stay selected
maxnumber | undefined—Maximum number of items that can be selected
modelValueany—Value of the selected items of the group
multipleboolean | undefined—Allows selecting several items at once
readonlyboolean | null | undefinednullRead-only state
requiredboolean | "force" | undefined—Requires at least one item to stay selected
selectedClassstring | undefined—CSS class applied in the selected state
staticboolean | undefined—Turns off the animation of the title
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render
themestring | undefined—Component theme
variant"default" | "accordion" | undefined'default'Display variant of the panel group

Events

NameTypeDescription
update:modelValue[value: unknown]Fires when the set of selected panels changes.

Slots

NameTypeDescription
defaultCdsExpandablePanelsSlotPropsPanels of the group. The slot props carry the navigation between panels.

Exposed

NameTypeDescription
next() => voidExpands the next panel
prev() => voidExpands the previous panel

CdsExpandablePanel ​

Props

NameTypeDefaultDescription
collapseIconIconValue | undefined'chevron-up'Icon shown when the panel is expanded and can be collapsed
disabledboolean | null | undefinednullDisabled state
eagerboolean | 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.
expandIconIconValue | undefined'chevron-down'Icon shown when the panel is collapsed and can be expanded
focusableboolean | undefined—Highlights the title with a background on focus
heightstring | number | undefined—Component height
hideActionsboolean | undefined—Hides the expand/collapse icon
hoverboolean | undefinedtrueHighlights the title with a background on hover
maxHeightstring | number | undefined—Maximum component height
maxWidthstring | number | undefined—Maximum component width
minHeightstring | number | undefined—Minimum component height
minWidthstring | number | undefined—Minimum component width
readonlyboolean | null | undefinednullRead-only state
selectedClassstring | undefined—CSS class applied in the selected state
staticboolean | undefined—Turns off the animation of the title
tagstring | JSXComponent<any> | undefined'div'Custom HTML tag or component to render
textstring | undefined—Text of the expandable content of the panel
titlestring | undefined—Text of the panel title
valueany—Value of the component within the group
widthstring | number | undefined—Component width

Events

NameTypeDescription
group:selected[value: { value: boolean; }]Fires when the panel is expanded or collapsed.

Slots

NameTypeDescription
defaultanyArbitrary content of the panel.
textanyExpandable content of the panel.
titleanyContent of the panel title.

Exposed

NameTypeDescription
isSelectedbooleanThe panel is expanded
select(value: boolean) => voidExpands or collapses the panel
toggle() => voidToggles the expansion of the panel

CdsExpandablePanelTitle ​

Props

NameTypeDefaultDescription
collapseIconIconValue | undefined'chevron-up'Icon shown when the panel is expanded and can be collapsed
expandIconIconValue | undefined'chevron-down'Icon shown when the panel is collapsed and can be expanded
focusableboolean | undefined—Highlights the title with a background on focus
heightstring | number | undefined—Component height
hideActionsboolean | undefined—Hides the expand/collapse icon
hoverboolean | undefinedtrueHighlights the title with a background on hover
maxHeightstring | number | undefined—Maximum component height
maxWidthstring | number | undefined—Maximum component width
minHeightstring | number | undefined—Minimum component height
minWidthstring | number | undefined—Minimum component width
readonlyboolean | null | undefinednullRead-only state
staticboolean | undefined—Turns off the animation of the title
widthstring | number | undefined—Component width

Slots

NameTypeDescription
actionCdsExpandablePanelTitleSlotPropsExpand/collapse icon. The slot props carry the state of the panel.
defaultCdsExpandablePanelTitleSlotPropsContent of the title. The slot props carry the state of the panel.

Exposed

NameTypeDescription
isSelectedbooleanThe panel is expanded
toggle() => voidToggles the expansion of the panel

CdsExpandablePanelContent ​

Props

NameTypeDefaultDescription
eagerboolean | 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

NameTypeDescription
defaultanyExpandable content of the panel.