Tessina UI
Tessina UI
GitHubIntroduction
InstallationUsageTheming
Components
ButtonIconButtonLinkSpinnerBadgeAvatarStatusChipShortcutSkeletonSurfaceProgressMeterRating
LabelFieldFieldsetCheckboxRadioSwitchSliderSelectComboboxSearchTextareaNumberFieldDate PickerTime PickerOTP InputFile UploadCalendar
AlertBannerToastTooltip
TabsAccordionCollapsibleBreadcrumbPaginationStepperSegmentedControlButtonGroupToggleButtonToggleGroupToolbarNavigation MenuMenubarBottom NavSidebar
Split ButtonFABDropdown MenuContextMenuCommandPopoverHoverCard
ContainerStackFlexGridAspectRatioSpacerCardCarouselDividerScroll Area
Table
ChatBubblePromptInputCodeBlock
ModalAlertDialogDrawerAction SheetTop Header MobileTop Header DesktopEmptyStateForm
Contributing
ComponentsNavigation Blocks

Collapsible

A single disclosure that animates open and closed — built on Base UI's Collapsible primitive with four variants, five sizes, intent accents, and full RTL support.

Playground

Installation

pnpm add @tessinaui/ui

Usage

import {
  CollapsibleRoot,
  CollapsibleHeader,
  CollapsibleTrigger,
  CollapsiblePanel,
} from "@tessinaui/ui";
<CollapsibleRoot variant="outline">
  <CollapsibleHeader>
    <CollapsibleTrigger>Show advanced options</CollapsibleTrigger>
  </CollapsibleHeader>
  <CollapsiblePanel>
    Tweak request timeouts, retry policy, and SDK telemetry — most teams leave
    these on the defaults.
  </CollapsiblePanel>
</CollapsibleRoot>

Showcase

When to use

Reach for Collapsible whenever you have a single block of secondary content that should be hidden by default and revealed on demand. Common cases: advanced form options, FAQ teasers, "show more" sections, expandable list rows.

If you have multiple related disclosures stacked together, prefer Accordion — it adds keyboard navigation between items and a single-or-multiple-open semantic.

API Reference

CollapsibleRoot props

PropTypeDefaultDescription
size"xs" | "sm" | "md" | "lg" | "xl""md"Scales trigger padding, text, indicator, and panel padding
variant"ghost" | "outline" | "filled" | "elevated""ghost"Visual treatment — ghost is just trigger + panel, the others wrap everything in a card
rounded"none" | "sm" | "md" | "lg" | "full""md"Card corner radius (only applies to non-ghost variants)
intent"none" | "primary" | "error" | "warning" | "success" | "info""none"Adds a subtle border accent to non-ghost variants
dir"ltr" | "rtl""ltr"Text direction — flips trigger row and indicator placement
openboolean—Controlled open state
defaultOpenbooleanfalseUncontrolled initial open state
onOpenChange(open: boolean) => void—Called when the panel opens or closes
disabledbooleanfalseDisables the trigger and prevents toggling
renderReactElement | (props, state) => ReactElement—Base UI polymorphic prop — replace the rendered element or compose with a custom component (equivalent to Radix asChild)

CollapsibleHeader props

A flex row container that respects the root's dir. Use it to place a title, badge, or extra actions next to the trigger. Accepts all standard <div> HTML attributes plus className for overrides.

CollapsibleTrigger props

PropTypeDefaultDescription
indicator"chevron" | "plus-minus" | "caret" | "none""chevron"Built-in indicator icon set
indicatorPosition"start" | "end""end"Logical position — flips with dir="rtl"
customIndicatorReactNode—Render a custom icon instead of the built-in indicator
fullWidthbooleantrueStretch the trigger to fill its container
renderReactElement | (props, state) => ReactElement—Base UI polymorphic prop — render as a different element (e.g. an <a> or another component) while preserving trigger behaviour
nativeButtonbooleantrueWhether to render a real <button> element

Renders a <button> underneath. Animates the indicator on the trigger's data-panel-open state. Accepts all standard button HTML attributes.

CollapsiblePanel props

PropTypeDefaultDescription
keepMountedbooleanfalseKeep the panel in the DOM while closed
hiddenUntilFoundbooleanfalseUse hidden="until-found" so closed content is reachable by browser find-in-page
withPaddingbooleantrueApply default panel padding (set to false when wrapping a Card or other padded surface)
renderReactElement | (props, state) => ReactElement—Base UI polymorphic prop — render as a different element while preserving panel behaviour

Animates open and close via Base UI's --collapsible-panel-height CSS variable, transitioning the height with no layout-thrashing measurement.

Notes

  • Built on @base-ui/react/collapsible, which exposes the open state on the trigger as data-panel-open and on the panel as data-open / data-closed.
  • The animation transitions height between 0 and var(--collapsible-panel-height) — works for any content height without explicit measurement.
  • For multi-item disclosures, prefer Accordion. For floating revealed content, prefer Popover or HoverCard.

Accordion

Vertically stacked expandable items with animated open/close transitions, two variants, five sizes, and full keyboard navigation.

Breadcrumb

Navigation trail showing the user's location in a hierarchy, with support for collapsed items, custom separators, and RTL.

On this page

PlaygroundInstallationUsageShowcaseWhen to useAPI ReferenceCollapsibleRoot propsCollapsibleHeader propsCollapsibleTrigger propsCollapsiblePanel propsNotes