Skip to content

Accordion

TIP

Don't specify padding and margin for Accordion.Item.Collapse, this will break the animation.

Basic usage

By default, the accordion has the secondary theme (use property).

tsx
import React from 'react';
import Accordion from 'intergalactic/accordion';
import { Box } from 'intergalactic/flex-box';

const Demo = () => {
  const [value, onChange] = React.useState([0]);

  return (
    <Accordion value={value} onChange={(value) => onChange(value)}>
      {[...new Array(3)].map((_, index) => (
        <Accordion.Item value={index} key={index} disabled={index === 2}>
          <Accordion.Item.Toggle pb={2}>
            <Accordion.Item.ToggleButton>
              <Accordion.Item.Chevron mr={2} />
              Section {index + 1}
            </Accordion.Item.ToggleButton>
          </Accordion.Item.Toggle>
          <Accordion.Item.Collapse>
            <Box p='12px 24px 24px'>{`Hello Section ${index + 1}`}</Box>
          </Accordion.Item.Collapse>
        </Accordion.Item>
      ))}
    </Accordion>
  );
};

export default Demo;

One section opening

value can take both values: single and array of values. By changing it, you change the behavior of the component.

tsx
import React from 'react';
import Accordion from 'intergalactic/accordion';
import { Box } from 'intergalactic/flex-box';

const Demo = () => {
  const [value, onChange] = React.useState(null); // or []
  return (
    <Accordion value={value} onChange={onChange}>
      {[...new Array(3)].map((_, index) => (
        <Accordion.Item value={index} key={index} disabled={index === 2}>
          <Accordion.Item.Toggle pb={2}>
            <Accordion.Item.ToggleButton tag={'h3'}>
              <Accordion.Item.Chevron mr={2} />
              Section {index + 1}
            </Accordion.Item.ToggleButton>
          </Accordion.Item.Toggle>
          <Accordion.Item.Collapse>
            <Box p='12px 24px 24px'>{`Hello Section ${index + 1}`}</Box>
          </Accordion.Item.Collapse>
        </Accordion.Item>
      ))}
    </Accordion>
  );
};

export default Demo;

Primary theme

Pass use='primary' to enable the primary theme for the accordion.

tsx
import React from 'react';
import Accordion from 'intergalactic/accordion';
import { Box } from 'intergalactic/flex-box';

const Demo = () => {
  return (
    <Accordion use='primary'>
      {[...new Array(3)].map((_, index) => (
        <Accordion.Item value={index} key={index} disabled={index === 2}>
          <Accordion.Item.Toggle pb={2}>
            <Accordion.Item.ToggleButton>
              <Accordion.Item.Chevron mr={2} />
              Section {index + 1}
            </Accordion.Item.ToggleButton>
          </Accordion.Item.Toggle>
          <Accordion.Item.Collapse>
            <Box p='12px 24px 24px'>{`Hello Section ${index + 1}`}</Box>
          </Accordion.Item.Collapse>
        </Accordion.Item>
      ))}
    </Accordion>
  );
};

export default Demo;

Custom styles for selected toggle

You can customize accordion styles if needed.

For example, to find out whether an element is selected and to highlight it, pass the function into the body of the element.

tsx
import React from 'react';
import Accordion from 'intergalactic/accordion';
import { Box } from 'intergalactic/flex-box';

const cn = (...classes: any[]) => classes.filter(Boolean).join(' ');

const Demo = () => {
  return (
    <>
      <style>
        {`
          /* In this example we are forced to use more specific css-selectors to override the default Vitepress styles */
          .vp-doc h3.styled-accordion-item {
            background-color: var(--intergalactic-bg-secondary-neutral);
            padding: var(--intergalactic-spacing-2x) var(--intergalactic-spacing-3x);
            color: var(--intergalactic-text-primary);
            margin-bottom: var(--intergalactic-spacing-05x);
          }
          .vp-doc h3.styled-accordion-item:first-of-type {
            border-radius: var(--intergalactic-control-rounded) var(--intergalactic-control-rounded) 0 0;
          }
          .vp-doc h3.styled-accordion-item:last-of-type {
            border-radius: 0 0 var(--intergalactic-control-rounded) var(--intergalactic-control-rounded);
          }
          .vp-doc h3.styled-accordion-item-selected {
            background-color: var(--intergalactic-bg-secondary-neutral-hover);
            color: #000;
          }
        `}
      </style>
      <Accordion>
        {[...new Array(3)].map((_, index) => (
          <Accordion.Item value={index} key={index}>
            {({ selected }) => (
              <>
                <Accordion.Item.Toggle
                  className={cn(
                    'styled-accordion-item',
                    selected && 'styled-accordion-item-selected',
                  )}
                >
                  <Accordion.Item.ToggleButton>
                    <Accordion.Item.Chevron mr={2} />
                    Section {index + 1}
                  </Accordion.Item.ToggleButton>
                </Accordion.Item.Toggle>
                <Accordion.Item.Collapse>
                  <Box p='12px 32px'>{`Hello Section ${index + 1}`}</Box>
                </Accordion.Item.Collapse>
              </>
            )}
          </Accordion.Item>
        ))}
      </Accordion>
    </>
  );
};

export default Demo;

SEO friendly accordion

By default, collapsed sections are not rendered in the DOM. If you need to render all sections, pass preserveNode to the Accordion.Item.Collapse component.

tsx
import React from 'react';
import Accordion from 'intergalactic/accordion';
import { Box } from 'intergalactic/flex-box';

const Demo = () => {
  const [value, onChange] = React.useState([0]);

  return (
    <Accordion value={value} onChange={(value) => onChange(value)}>
      {[...new Array(3)].map((_, index) => (
        <Accordion.Item value={index} key={index} disabled={index === 2}>
          <Accordion.Item.Toggle pb={2}>
            <Accordion.Item.ToggleButton>
              <Accordion.Item.Chevron mr={2} />
              Section {index + 1}
            </Accordion.Item.ToggleButton>
          </Accordion.Item.Toggle>
          <Accordion.Item.Collapse preserveNode>
            <Box p='12px 24px 24px'>{`Hello Section ${index + 1}`}</Box>
          </Accordion.Item.Collapse>
        </Accordion.Item>
      ))}
    </Accordion>
  );
};

export default Demo;

Released under the MIT License.

Released under the MIT License.