DocsBlog
  • 1.1.2

  • light

    dark

    system

    Switch mode
  • Cerberus

    Acheron

    Elysium

Get Started
Components
Data Grid
Signals
Styling
Theming

Concepts

OverviewCompositionCerberus ContextTesting

Layout

Aspect RatioBleedBoxCenterContainerDividerFlexFloatGridGroupLink OverlayScrollableStackWrap

Components

AccordionAdmonitionAvatarButtonCarouselCheckboxClipboardCollapsibleComboboxConfirm ModalCTAModalDate PickerDialogFieldFieldsetFile UploaderIcon ButtonInputLoading StatesMenuNotificationsNumber InputPaginationPin InputProgressPrompt ModalRadioRatingSelectSplit ButtonSwitchTableTabsTagTextTextareaToggleTooltip

Utilities

Client OnlyDownload TriggerEnvironmentFeature FlagsFocus TrapForFormat ByteFormat NumberFormat Relative TimeFrameHighlightJSON Tree ViewLocaleLocal StoragePortalPresenceShowsplitPropsTheme

Collapsible

Used to expand and collapse additional content.

  • npm
  • source
  • recipe
  • Ark
import { Collapsible } from '@cerberus/react'

Usage

The Collapsible component allows you to show or hide content with a trigger. It is useful for accordions, dropdowns, and expandable sections.

Initial Open

Use the defaultOpen prop to render the collapsible in an open state by default.

Partial Height

Use the collapsedHeight prop to show a preview of the content when collapsed.

Effects

To turn off the animation effect, you can set the effect prop to none on the Collapsible.Content component.

Controlled

Use the open and onOpenChange props to control the collapsible state.

Customization

You can customize the Collapsible component any way you like with style props and data-selectors.

Primitives

You can utilize the primitive components to build a custom collapsible solution.

ComponentDescription
CollapsibleRootThe context provider of the collapsible.
CollapsibleTriggerThe button that toggles the collapsible.
CollapsibleIndicatorThe indicator that shows the state.
CollapsibleContentThe content of the collapsible.

Data Attributes

The primitives additionally use the following data attributes for custom styling:

NameValueDescription
data-scopecollapsibleThe scope of the components.
data-partrootThe root container part.
data-parttriggerThe trigger part.
data-partindicatorThe indicator part.
data-partcontentThe content part.
data-state"open" | "closed"The state of the content.

API

Collapsible

The Collapsible component is an Object containing all the primitive components.

Root Props

PropTypeRequiredDescription
asChildbooleanNoUse the provided child element as the default rendered element, combining their props and behavior.
collapsedHeightstring | numberNoThe height of the content when collapsed.
collapsedWidthstring | numberNoThe width of the content when collapsed.
defaultOpenbooleanNoThe initial open state of the collapsible when rendered. Use when you don't need to control the open state of the collapsible.
disabledbooleanNoWhether the collapsible is disabled.
effect"none" | "fadeIin" | "expandIn"NoThe animation effect of the content when collapsed.
idsPartial<{ root: string; content: string; trigger: string }>NoThe ids of the elements in the collapsible. Useful for composition.
lazyMountbooleanNoWhether to enable lazy mounting
onExitCompleteVoidFunctionNoThe callback invoked when the exit animation completes.
onOpenChange(details: OpenChangeDetails) => voidNoThe callback invoked when the open state changes.
openbooleanNoThe controlled open state of the collapsible.
unmountOnExitbooleanNoWhether to unmount on exit.

You can see additional options for the Root component.

Parts

The CollapsibleParts API is the same as the Collapsible component.

On this page

  • Edit this page on Github
Copy
'use client'

import { Box, HStack } from '@/styled-system/jsx'
import { ChevronDown } from '@carbon/icons-react'
import { Collapsible } from '@cerberus/react'

export function BasicDemo() {
  return (
    <HStack h="full" w="3/4">
      <Collapsible.Root w="full">
        <Collapsible.Trigger asChild>
          <HStack gap="sm" userSelect="none">
            <Collapsible.Indicator
              transform="rotate(-90deg)"
              transition="transform 0.2s"
              _open={{ transform: 'rotate(0deg)' }}
            >
              <ChevronDown />
            </Collapsible.Indicator>
            Toggle
          </HStack>
        </Collapsible.Trigger>

        <Collapsible.Content>
          <Box
            border="1px solid"
            borderColor="page.border.initial"
            p="md"
            mt="sm"
            rounded="md"
            w="full"
          >
            Collapsible content goes here.
          </Box>
        </Collapsible.Content>
      </Collapsible.Root>
    </HStack>
  )
}
Copy
'use client'

import { Box } from '@/styled-system/jsx'
import { Collapsible } from '@cerberus/react'

export function CustomDemo() {
  return (
    <Collapsible.Root w="full">
      <Collapsible.Trigger
        color="danger.text.100"
        bgColor="danger.surface.initial"
        px="sm"
        w="full"
      >
        Custom Toggle
      </Collapsible.Trigger>
      <Collapsible.Content>
        <Box w="full">Custom collapsible content.</Box>
      </Collapsible.Content>
    </Collapsible.Root>
  )
}
Copy
'use client'

import { Box, HStack } from '@/styled-system/jsx'
import { ChevronDown } from '@carbon/icons-react'
import { Collapsible } from '@cerberus/react'

export function OpenDemo() {
  return (
    <HStack h="full" w="3/4">
      <Collapsible.Root defaultOpen w="full">
        <Collapsible.Trigger asChild>
          <HStack gap="sm" userSelect="none">
            <Collapsible.Indicator
              transform="rotate(-90deg)"
              transition="transform 0.2s"
              _open={{ transform: 'rotate(0deg)' }}
            >
              <ChevronDown />
            </Collapsible.Indicator>
            Toggle
          </HStack>
        </Collapsible.Trigger>

        <Collapsible.Content>
          <Box
            border="1px solid"
            borderColor="page.border.initial"
            p="md"
            mt="sm"
            rounded="md"
            w="full"
          >
            Collapsible content goes here.
          </Box>
        </Collapsible.Content>
      </Collapsible.Root>
    </HStack>
  )
}
Copy
'use client'

import { Box, HStack } from '@/styled-system/jsx'
import { Button, Collapsible } from '@cerberus/react'

export function PartialDemo() {
  return (
    <HStack h="full" w="3/4">
      <Collapsible.Root collapsedHeight="100px" w="full">
        <Collapsible.Content effect="fade">
          <Box
            border="1px solid"
            borderColor="page.border.initial"
            p="md"
            mt="sm"
            rounded="md"
            w="full"
          >
            It is a long established fact that a reader will be distracted by the
            readable content of a page when looking at its layout. The point of using
            Lorem Ipsum is that it has a more-or-less normal distribution of letters, as
            opposed to using 'Content here, content here', making it look like readable
            English. Many desktop publishing packages and web page editors now use Lorem
            Ipsum as their default model text, and a search for 'lorem ipsum' will
            uncover many web sites still in their infancy. Various versions have evolved
            over the years, sometimes by accident, sometimes on purpose (injected humour
            and the like).
          </Box>
        </Collapsible.Content>

        <Collapsible.Trigger asChild>
          <Button mt="md" usage="outlined-subtle">
            Show More
          </Button>
        </Collapsible.Trigger>
      </Collapsible.Root>
    </HStack>
  )
}
Copy
'use client'

import { Box, HStack } from '@/styled-system/jsx'
import { Collapsible } from '@cerberus/react'

export function FadeDemo() {
  return (
    <HStack h="full" w="17rem">
      <Collapsible.Root>
        <Collapsible.Trigger>Toggle</Collapsible.Trigger>
        <Collapsible.Content effect="none">
          <Box
            border="1px solid"
            borderColor="page.border.initial"
            p="md"
            rounded="md"
            w="full"
          >
            Collapsible content goes here.
          </Box>
        </Collapsible.Content>
      </Collapsible.Root>
    </HStack>
  )
}
Copy
'use client'

import { Box, Stack } from '@/styled-system/jsx'
import { Collapsible, type OpenChangeDetails, Text } from '@cerberus/react'
import { useSignal } from '@cerberus/signals'

export function ControlledDemo() {
  const [open, setOpen] = useSignal<boolean>(false)

  return (
    <Stack gap="4" w="3/4">
      <Text textStyle="label-sm">Status: {open ? 'Open' : 'Closed'}</Text>

      <Collapsible.Root
        open={open}
        onOpenChange={(e: OpenChangeDetails) => setOpen(e.open)}
        w="full"
      >
        <Collapsible.Trigger paddingY="3">Toggle Collapsible</Collapsible.Trigger>
        <Collapsible.Content>
          <Box padding="4" borderWidth="1px">
            This collapsible is controlled by external state. You can open and close it
            using the buttons above or by clicking the trigger.
          </Box>
        </Collapsible.Content>
      </Collapsible.Root>
    </Stack>
  )
}
Toggle
Collapsible content goes here.
Custom collapsible content.
Toggle
Collapsible content goes here.
It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English. Many desktop publishing packages and web page editors now use Lorem Ipsum as their default model text, and a search for 'lorem ipsum' will uncover many web sites still in their infancy. Various versions have evolved over the years, sometimes by accident, sometimes on purpose (injected humour and the like).
Collapsible content goes here.

Status: Closed

This collapsible is controlled by external state. You can open and close it using the buttons above or by clicking the trigger.