Accordion

Content area that can be collapsed and expanded.

Setting Focus

<StatefulAccordion data-test="Accordion-default">
    <AccordionItem>
      <AccordionHeader data-test="Accordion-Header-1">
        <BasicHeader title="Title 1" />
      
      <AccordionPanel>Content of the panel 1.</AccordionPanel>
    </AccordionItem>
    <AccordionItem focused>
      <AccordionHeader data-test="Accordion-Header-2">
        <BasicHeader title="Title 2 (initially focused)" />
      </AccordionHeader>
      <AccordionPanel>Content of the panel 2.</AccordionPanel>
    </AccordionItem>
  </StatefulAccordion>
</Playground>

Controlled

{() => {
    class StateManager extends React.Component {
      constructor(props, context) {
        super(props, context)
        this.state = {
          isOpenByIndex: {
            0: true,
            1: false,
          },
          canExpandAll: true,
        }
        this.toggle = this.toggle.bind(this)
        this.toggleAll = this.toggleAll.bind(this)
      }
      toggle(index) {
        const newOpenState = Object.assign({}, this.state.isOpenByIndex, {
          [index]: !this.state.isOpenByIndex[index],
        })
        const anyClosed = Object.values(newOpenState).some(isOpen => !isOpen)
        this.setState({
          isOpenByIndex: newOpenState,
          canExpandAll: anyClosed,
        })
      }
      toggleAll() {
        const willExpandAll = this.state.canExpandAll
        if (willExpandAll) {
          const allOpen = Object.keys(this.state.isOpenByIndex).reduce(
            (acc, panelId) => {
              return Object.assign({}, acc, {
                [panelId]: true,
              })
            },
            {},
          )
          this.setState({
            isOpenByIndex: allOpen,
            canExpandAll: false,
          })
        } else {
          const allClosed = Object.keys(this.state.isOpenByIndex).reduce(
            (acc, panelId) => {
              return Object.assign({}, acc, {
                [panelId]: false,
              })
            },
            {},
          )
          this.setState({
            isOpenByIndex: allClosed,
            canExpandAll: true,
          })
        }
      }
      render() {
        const toggleAllButton = (
          <Button onClick={this.toggleAll}>
            {this.state.canExpandAll ? 'Expand All' : 'Collapse All'}
          
        )
        return (
          <SpacedGroup direction="vertical">
            {toggleAllButton}
            <Accordion data-test="Accordion-controlled" onSelect={this.toggle}>
              <AccordionItem open={this.state.isOpenByIndex[0]}>
                <AccordionHeader data-test="Accordion-Header-1">
                  <BasicHeader title="Title 1" />
                </AccordionHeader>
                <AccordionPanel>Content of the panel 1.</AccordionPanel>
              </AccordionItem>
              <AccordionItem open={this.state.isOpenByIndex[1]}>
                <AccordionHeader data-test="Accordion-Header-2">
                  <BasicHeader title="Title 2" />
                </AccordionHeader>
                <AccordionPanel>Content of the panel 2.</AccordionPanel>
              </AccordionItem>
            </Accordion>
          </SpacedGroup>
        )
      }
    }
    return <StateManager />
  }}
</Playground>

Basic

<StatefulAccordion data-test="Accordion-default">
    <AccordionItem open={true}>
      <AccordionHeader data-test="Accordion-Header-1">
        {({ arrow }) => {
          return <SpacedGroup center>{arrow} Title 1
        }}
      </AccordionHeader>
      <AccordionPanel>Content of the panel 1.</AccordionPanel>
    </AccordionItem>
    <AccordionItem>
      <AccordionHeader data-test="Accordion-Header-2">
        <BasicHeader title="Title 2" />
      </AccordionHeader>
      <AccordionPanel>Content of the panel 2.</AccordionPanel>
    </AccordionItem>
  </StatefulAccordion>
</Playground>

Many Expandable

<StatefulAccordion manyExpandable={true} data-test="Accordion-manyexpandable">
    <AccordionItem>
      <AccordionHeader data-test="Accordion-Header-1">
        <BasicHeader title="Title 1" />
      
      <AccordionPanel>Content of the panel 1.</AccordionPanel>
    </AccordionItem>
    <AccordionItem>
      <AccordionHeader data-test="Accordion-Header-2">
        <BasicHeader title="Title 2" />
      </AccordionHeader>
      <AccordionPanel>Content of the panel 2.</AccordionPanel>
    </AccordionItem>
  </StatefulAccordion>
</Playground>

All Collapsable

<StatefulAccordion allCollapsable={true} data-test="Accordion-allcollapsable">
    <AccordionItem>
      <AccordionHeader data-test="Accordion-Header-1">
        <BasicHeader title="Title 1" />
      
      <AccordionPanel>Content of the panel 1.</AccordionPanel>
    </AccordionItem>
    <AccordionItem>
      <AccordionHeader data-test="Accordion-Header-2">
        <BasicHeader title="Title 2" />
      </AccordionHeader>
      <AccordionPanel>Content of the panel 2.</AccordionPanel>
    </AccordionItem>
  </StatefulAccordion>
</Playground>

Disable Border

<StatefulAccordion disableBorder={true}>
    <AccordionItem>
      <AccordionHeader data-test="Accordion-Header-1">
        <BasicHeader title="Title 1" />
      
      <AccordionPanel>Content of the panel 1.</AccordionPanel>
    </AccordionItem>
    <AccordionItem>
      <AccordionHeader data-test="Accordion-Header-2">
        <BasicHeader title="Title 2" />
      </AccordionHeader>
      <AccordionPanel>Content of the panel 2.</AccordionPanel>
    </AccordionItem>
  </StatefulAccordion>
</Playground>

Disabled Header

<StatefulAccordion>
    <AccordionItem disabled>
      <AccordionHeader data-test="Accordion-Header-1">
        <BasicHeader title="Title 1" />
      
      <AccordionPanel>Content of the panel 1.</AccordionPanel>
    </AccordionItem>
    <AccordionItem disabled>
      <AccordionHeader data-test="Accordion-Header-2">
        <BasicHeader title="Title 2" />
      </AccordionHeader>
      <AccordionPanel>Content of the panel 2.</AccordionPanel>
    </AccordionItem>
  </StatefulAccordion>
</Playground>

Disable Dividers

<StatefulAccordion disableDividers={true}>
    <AccordionItem>
      <AccordionHeader data-test="Accordion-Header-1">
        <BasicHeader title="Title 1" />
      
      <AccordionPanel>Content of the panel 1.</AccordionPanel>
    </AccordionItem>
    <AccordionItem>
      <AccordionHeader data-test="Accordion-Header-2">
        <BasicHeader title="Title 2" />
      </AccordionHeader>
      <AccordionPanel>Content of the panel 2.</AccordionPanel>
    </AccordionItem>
  </StatefulAccordion>
</Playground>

Status

<StatefulAccordion>
    <AccordionItem status="success">
      <AccordionHeader data-test="Accordion-Header-1">
        <BasicHeader title="Title 1" />
      
      <AccordionPanel>Content of the panel 1.</AccordionPanel>
    </AccordionItem>
    <AccordionItem status="failure">
      <AccordionHeader data-test="Accordion-Header-2">
        <BasicHeader title="Title 2" />
      </AccordionHeader>
      <AccordionPanel>
        <StatefulAccordion>
          <AccordionItem status="success">
            <AccordionHeader data-test="Accordion-Header-1">
              <BasicHeader title="Title 1" />
            </AccordionHeader>
            <AccordionPanel>Content of the panel 1.</AccordionPanel>
          </AccordionItem>
          <AccordionItem status="failure">
            <AccordionHeader data-test="Accordion-Header-2">
              <BasicHeader title="Title 2" />
            </AccordionHeader>
            <AccordionPanel>Content of the panel 2.</AccordionPanel>
          </AccordionItem>
        </StatefulAccordion>
      </AccordionPanel>
    </AccordionItem>
  </StatefulAccordion>
</Playground>

Disable Panel Padding

<StatefulAccordion>
    <AccordionItem disablePadding>
      <AccordionHeader data-test="Accordion-Header-1">
        <BasicHeader title="Title 1" />
      
      <AccordionPanel>Content of the panel 1.</AccordionPanel>
    </AccordionItem>
    <AccordionItem disablePadding>
      <AccordionHeader data-test="Accordion-Header-2">
        <BasicHeader title="Title 2" />
      </AccordionHeader>
      <AccordionPanel>Content of the panel 2.</AccordionPanel>
    </AccordionItem>
  </StatefulAccordion>
</Playground>

Long

{() => {
    const items = Array.from(Array(5).keys()).map(index => {
      const title = 'Title ' + index
      const content = 'Content of Panel ' + index
      return (
        <AccordionItem key={index}>
          <AccordionHeader>
            <BasicHeader title={title} />
          
          <AccordionPanel>{content}</AccordionPanel>
        </AccordionItem>
      )
    })
    return <StatefulAccordion>{items}</StatefulAccordion>
  }}
</Playground>

API

StatfulAccordion (Uncontrolled)

Accordion (Controlled)

AccordionItem

AccordionHeader

AccordionPanel