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:
- 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.
- 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><Boxmt={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
Name | Type | Default | Description | Required? |
---|---|---|---|---|
isOpen | boolean | false | ||
children | React.ReactNode | |||
offset | number | 0 | 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. | |
collapsedHeight | number | 0 | ||
openHeight | number |
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 thecontent on the right.</Text><Collapsible.Panel><Boxmt={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>)}