Components

Collapsible

The collapsible component is a utility for creating regions of content that can expand/collapse with a simple animation.

Collapsible areas are made up of two parts:

  1. The trigger element (optional). This is an actionable element that the user interacts with to toggle the state of the component. This is not necessary if the state is being toggled programmatically.
  2. The panel element. This is the content that will actually expand/collapse when the state is toggled.

The Collapsible component uses two subcomponents to represent these parts: Collapsible.Trigger and Collapsible.Panel:

import { Collapsible } from '@sproutsocial/racine'
() => {
const [open, setOpen] = useState(false)
const toggle = () => setOpen(!open)
return (
<Box>
<Collapsible isOpen={open}>
<Collapsible.Trigger>
<Button appearance="secondary" onClick={toggle} width={1}>
{open ? 'Hide' : 'Show'}
</Button>
</Collapsible.Trigger>
<Collapsible.Panel>
<Box
mt={350}
width="100%"
height="200px"
bg="neutral.100"
display="flex"
alignItems="center"
justifyContent="center"
>
Hey there!
</Box>
</Collapsible.Panel>
</Collapsible>
</Box>
)
}

In the example above, a Button is used to toggle the state, and is wrapped in the Trigger subcomponent. The content to be collapsed/expanded is wrapped in the Panel.

The state of the content is passed to the isOpen prop of the parent Collapsible component, and that state is used by Trigger and Panel to ensure that both elements are labelled appropriately for accessibility.

Properties

NameTypeDefaultDescriptionRequired?
isOpenbooleanfalse
childrenReact.Node
offsetnumber0
If the children of the collapsible panel have a top or bottom margin, it will throw off the calculations for the height of the content. The total amount of vertical margin (in pixels) can be supplied to this prop to correct this.
collapsedHeightnumber0
openHeightnumber

Subcomponents

Trigger

If the collapsible area is toggled by the user, a trigger element should be provided and wrapped in the Collapsible.Trigger subcomponent. The element will be given the appropriate ARIA attributes for accessibility.

Panel

The content that is actually expanding/collapsing should be wrapped in Collapsible.Panel. This component measures it's children and provides a simple animation for opening/closing the content.

Recipes

Because the trigger and panel elements can be rendered anywhere within a Collapsible component, you can easily create more complex behaviors and layouts by combining Collapsible with other components. Just remember that the base Collapsible component needs to be above both the panel and the trigger in the tree.

() => {
const [open, setOpen] = useState(false)
const toggle = () => setOpen(!open)
return (
<Box display="flex">
<Collapsible isOpen={open}>
<Box width="75px" mr={400}>
<Collapsible.Trigger>
<Button appearance="secondary" onClick={toggle} width={1}>
{open ? 'Hide' : 'Show'}
</Button>
</Collapsible.Trigger>
</Box>
<Box flex={1}>
<Text as="p" fontWeight="semibold" mt={-300}>
Click the button to the left if you'd like to learn more about the
content on the right.
</Text>
<Collapsible.Panel>
<Box
mt={350}
width="100%"
height="200px"
bg="neutral.100"
display="flex"
alignItems="center"
justifyContent="center"
>
Hey there!
</Box>
</Collapsible.Panel>
<Text as="p" fontSize={200} color="text.subtext" mt={300}>
Here's some footer text.
</Text>
</Box>
</Collapsible>
</Box>
)
}

Collapsible also has niche use cases where an element may need to visually display inner content while collapsed. This behavior can be achieved via the collapsedHeight and openHeight props, which basically act as min-height and max-height for open and closed states. Setting these values may trigger a scroll if your content overflows beyond the values you've selected.

() => {
const [open, setOpen] = useState(false)
const toggle = () => setOpen(!open)
return (
<Box>
<Collapsible isOpen={open} collapsedHeight={50} openHeight={100}>
<Collapsible.Trigger>
<Button appearance="secondary" onClick={toggle} width={1}>
{open ? 'Hide' : 'Show'}
</Button>
</Collapsible.Trigger>
<Collapsible.Panel>
<Box mt={350} width="100%" height="200px" bg="neutral.100">
<Text>Hey there!</Text>
<Text mt={30}>A lot to see here if you scroll.</Text>
<Text mt={30}>Oops! That's all there is.</Text>
</Box>
</Collapsible.Panel>
</Collapsible>
</Box>
)
}