Collapse

Content folded behind its own heading, one panel or several, with an accordion mode that keeps one panel open at a time.

Usage

A Collapse hides content by default, so most of the choices below are about what is worth folding, what starts open, and what never goes behind a fold.

When to use

Collapse folds content under its own heading: one panel or a stack of them, each with a title that stays visible and a body that does not. Use it when the titles alone are enough to find your way, and the reader will want only one or two of the bodies.
  • A long form split into stages, where a finished stage folds away and the current one stays open.
  • An FAQ, a changelog or a terms page: many short bodies under many short titles, most of which nobody reads.
  • Secondary detail under a primary record: the raw payload under a log line, the full diff under a summary, advanced settings under the three that matter.
  • A checklist or onboarding flow, where each step's title shows its progress in extra, so the flow reads with every panel closed.
Use something else when
  • The panels are peers the reader switches between. Use Tabs. A tab list says “these are the same kind of thing, pick one”, and Tabs come with the arrow-key navigation a tab list should have.
  • The content is a detour. A Drawer or a Modal takes the reader somewhere and brings them back. Opening a Collapse pushes everything below it down the page.
  • Nothing needs hiding. Three paragraphs under three headings do not need a disclosure. A fold costs a click and a guess about what is inside.
  • There is one thing to fold. A single panel is fine, but check whether a “Show more” link or a Typography ellipsis with an expand option fits better.

Use items

Use items. The kit's Collapse has no Collapse.Panel, and the children form it served is deprecated. Pass items, each with a key, label and children.
  • Give every item a stable key. activeKey, defaultActiveKey and onChange all use the keys, so an index breaks as soon as the list is reordered or filtered.
  • Map the items from your data in one place, so the key that opens a panel and the key of the record are the same string.
  • Items take their own options. An item can set collapsible, showArrow, extra and className. forceRender renders a panel's body before it first opens, for a chart or a form inside it that has to exist while the panel is closed.

Accordion, or many open

accordion keeps at most one panel open, so opening a second closes the first. Without it (the default), any number can be open and the reader closes what they are done with.
  • Use accordion when the panels compete for attention and the reader does not need to compare two of them: a settings group, a wizard, a card stack where the open panel is the subject.
  • Allow many open when the reader is gathering. In an FAQ with three relevant answers, a diff view or a set of filters, closing one panel to read another is busywork.
  • Accordion mode changes the roles to tablist, tab and tabpanel without the keyboard support those roles promise. Read the Accessibility tab before using it for a long list.
  • A panel that closes because another opened moves the page under the cursor. Keep the stack short enough that the reader can still see where the panel they clicked ended up.

What starts open

defaultActiveKey sets which panels start open and leaves the rest to the reader. activeKey with onChange is the controlled form, for when something other than the reader decides what is open.
  • Open the panel the reader came for, and nothing else. Everything open is a page with extra chrome, and nothing open looks like an empty page.
  • The first panel is the usual default, because it is the one the reader expects.
  • Open the panel that holds an error. A validation message inside a closed panel is one nobody sees, so drive activeKey from the error state.
  • Where the stack is a workspace rather than a document, remember which panels the reader opened across visits.
  • Both props take one key or an array. With accordion only the first key is used, and the rest are ignored without a warning.

The expand icon

The arrow is what tells the reader a header is a control and not only a heading. Keep it, and use showArrow={false} on an item only when something else in its header does that job.
  • The default arrow comes from your icon pack. AntuikitProvider supplies it and sizes it with classNames.icon. Your own classNames.icon is added to that, so a color class keeps the size. You rarely need to pass expandIcon yourself.
  • expandIcon has to be a function. A plain node type-checks but is ignored, and the default arrow shows instead. Pass a function of isActive.
  • expandIconPlacement takes start (the default) or end. At the start, the reader sees the arrow before the words and knows the row opens.
  • Move it to end when the header has an extra node, so the arrow and the extra sit together on one side, as in the onboarding checklist example.
  • Pick one placement per surface. A stack whose arrow changes sides reads as two different components.
  • The default arrow rotates when a panel opens. A custom icon should change too, like a plus turning into a minus. An icon that looks the same in both states reads as a control that did not respond.

Controls in the header

Stop clicks inside the header. The whole header is one button, so a checkbox or a button in extra or label also toggles the panel. Call event.stopPropagation() in its onClick, or set collapsible="icon" so only the arrow toggles.
  • Use extra for one small control or a status, like a count or an edit button, and give an icon-only button an aria-label.
  • Set collapsible: "disabled" on an item to lock one panel, or on the Collapse to lock them all.

Bordered, borderless and ghost

Two booleans set the frame. The default is a bordered box, bordered={false} keeps only the lines between panels, and ghost removes the frame, the fill and the lines. Collapse has no variant prop.
  • Bordered is a box with a shaded header band and a line between items. Use it when the stack sits on the page and needs an edge to read as a group.
  • Borderless keeps the shaded headers and drops the frame. Use it inside something that already has an edge: a Card, a Drawer, a table cell.
  • Ghost drops the fill too, so the stack is titles on whatever is behind it. Use it in dense sidebars and on surfaces whose own color should show through.
  • One treatment per surface. Mixing bordered and ghost stacks in one column makes the difference look like a state.

Styling panels

  • Use ghost when you style the panels yourself, because it clears the item borders without !important.
  • Style the open panel by its state class. An open item carries ant-collapse-item-active, so a class like [&_.ant-collapse-item-active]:shadow-card on the Collapse follows whichever panel is open, with no state of your own.
  • Give an item its own className to frame that panel. For the header, title, body and icon of every panel, use classNames with the keys header, title, body and icon.
  • Some props were renamed. Use expandIconPlacement for expandIconPosition, destroyOnHidden for destroyInactivePanel, and size="medium" where older code has middle.

Nesting

A Collapse inside a Collapse panel works, and it is usually one level too many. Every fold is a guess the reader has to make, and a second level is a guess inside a guess.
  • Stop at two levels. Content that needs a third wants a page, a Drawer or a Tree.
  • Make the inner stack look secondary: ghost or bordered={false} inside a bordered outer stack, and size="small" for short titles. Two identical frames inside each other look like a rendering bug.
  • Keep the keys distinct across levels. The inner stack has its own onChange, and two panels sharing a key in one state object break once both are open.
  • Opening an inner panel resizes the outer one, so both animate at once. Set forceRender on the inner items when anything inside measures itself.

What never goes behind a fold

A panel is not rendered until it first opens, and it is hidden with display: none after that. Its content is invisible to the reader, to find-in-page and to a screen reader alike.
  • Errors and validation messages. If a folded field is invalid, open its panel. This is the most common Collapse bug in a form.
  • Required fields, and the submit button. A reader cannot finish a form whose remaining work is hidden behind a title that does not say what is left.
  • Anything the reader will search the page for. Reference tables, IDs, error codes. Find-in-page only searches text that is rendered.
  • Legal notices, consent text and pricing terms. Folding these is a dark pattern, and in some places it is a legal question as well.
  • The only copy of a primary action. A button that exists once, inside panel four, is a button nobody finds.