Default

const CollapsibleOpen = () => {
    const [opened, setOpen] = React.useState(false)
    return (
        <Card>
            <Card.Section>
                <div className="d-f justify-content-between align-items-center">
                    Name
                    <BodyText subdued>(800) 555-1234</BodyText>
                    {
                        opened
                        ? <Button primary small onClick={() => setOpen(!opened)}>Save</Button>
                        : <Button primary small fill="subtle" onClick={() => setOpen(!opened)}>Edit</Button>
                    }
                </div>
            <Collapsible open={opened}>
                <Form className="m-t-2">
                    <Form.Input label="First Name" placeholder="First Name" />
                    <Form.Input label="First Name" placeholder="Last Name" />
                    <Form.Input label="Phone Number" placeholder="(800) 555-1234" />
                </Form>
            </Collapsible>
            </Card.Section>
        </Card>
    )
}

render ( CollapsibleOpen )

Animate

Collapsible can be configured to open and close with a transition effect. This is useful when the area being open is not large or a performance hit on slower computers.

const CollapsibleAnimate = () => {
    const [opened, setOpen] = React.useState(true)
    return (
        <Card>
            <Card.Section>
                <div className="d-f justify-content-between align-items-center">
                    Name
                    <BodyText subdued>(800) 555-1234</BodyText>
                    {
                        opened
                        ? <Button primary small onClick={() => setOpen(!opened)}>Save</Button>
                        : <Button primary small fill="subtle" onClick={() => setOpen(!opened)}>Edit</Button>
                    }
                </div>
            <Collapsible animate open={opened}>
                <Form className="m-t-2">
                    <Form.Input label="First Name" placeholder="First Name" />
                    <Form.Input label="First Name" placeholder="Last Name" />
                    <Form.Input label="Phone Number" placeholder="(800) 555-1234" />
                </Form>
            </Collapsible>
            </Card.Section>
        </Card>
    )
}
render ( CollapsibleAnimate )

Examples

Basic

const CollapsibleAnimate = () => {
    const [opened, setOpen] = React.useState(false)
    return (
        <div>
            <Button full fill="outline" primary onClick={() => setOpen(!opened)}>
                What is Anvil?
            </Button>
            <Collapsible open={opened}>
                <BodyText className="m-t-2">
                    Design guidelines and development tools for building products at ServiceTitan.
                </BodyText>
            </Collapsible>
        </div>
    )
}
render ( CollapsibleAnimate )

Accordion

A variation where only one or no section in a list of collapsible sections is open at a time.

const AccordionExample = () => {
    const [value, setValue] = React.useState(0)
    const cards = ['1', '2', '3', '4']
    return (
        <Card>
            {cards.map((card, index) => (
                <Card.Section key={index}>
                    <div className="d-f justify-content-between align-items-center">
                        <BodyText bold className="m-0">Section Title</BodyText>
                        <Button iconName={value == card ? "expand_less" : "expand_more"} small fill="subtle" onClick={() => setValue(value == card ? 0 : card)} />
                    </div>
                    <Collapsible open={value == card}>
                        <BodyText className="m-t-2">
                            Collapsible content.
                            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
                            incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
                            exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
                            irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
                            pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia
                            deserunt mollit anim id est laborum.
                        </BodyText>
                    </Collapsible>
                </Card.Section>
            ))}
        </Card>
    )
}
render ( AccordionExample )

When to collapse content

In general, content should not be collapsed by default, as it can hide important information and require additional interactions to access it. Some use general use cases of collapsed content include:

  • When the content has secondary value on the page, such as viewing details on a single item.
  • When space is cramped, particularly on smaller displays.
  • When information is not yet relevant, such as in a Flow Card.
  • When using, the preferred control for the component is a Button variation.

Importing

import { Collapsible } from '@servicetitan/design-system';