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).
import Accordion from '@semcore/ui/accordion';
import type { AccordionProps, AccordionCollapseProps } from '@semcore/ui/accordion';
import { Box } from '@semcore/ui/base-components';
import type { BoxProps } from '@semcore/ui/base-components';
import React from 'react';
type ExampleAccordionProps = AccordionProps & { duration?: number } & AccordionCollapseProps & BoxProps;
const Demo = (props: ExampleAccordionProps) => {
const [value, onChange] = React.useState([0]);
return (
<Accordion value={value} onChange={(value: any) => onChange(value)} duration={props.duration} use={props.use}>
{[...new Array(3)].map((_, index) => (
<Accordion.Item value={index} key={index} disabled={index === 2}>
<Accordion.Item.Toggle pb={2} w={props.w} h={props.h}>
<Accordion.Item.ToggleButton>
<Accordion.Item.Chevron mr={2} />
Section
{' '}
{index + 1}
</Accordion.Item.ToggleButton>
</Accordion.Item.Toggle>
<Accordion.Item.Collapse overflowHidden={props.overflowHidden} defaultHeight={props.defaultHeight}>
<Box p='12px 24px 24px'>{`Hello Section ${index + 1}`}</Box>
</Accordion.Item.Collapse>
</Accordion.Item>
))}
</Accordion>
);
};
export const defaultProps: ExampleAccordionProps = {
duration: undefined,
use: undefined,
overflowHidden: undefined,
defaultHeight: undefined,
w: undefined,
h: undefined,
};
Demo.defaultProps = defaultProps;
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.
import Accordion from '@semcore/ui/accordion';
import { Box } from '@semcore/ui/base-components';
import React from 'react';
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>
<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;
Heading tag
By default, Accordion.Item.Toggle is set to an h3 heading level, but you can change it if needed.
import Accordion from '@semcore/ui/accordion';
import { Box } from '@semcore/ui/base-components';
import React from 'react';
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} tag='h2'>
<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;
Primary theme
Pass use='primary' to enable the primary theme for the accordion.
import Accordion from '@semcore/ui/accordion';
import { Box } from '@semcore/ui/base-components';
import React from 'react';
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.
import Accordion from '@semcore/ui/accordion';
import { Box } from '@semcore/ui/base-components';
import React from 'react';
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 aren't rendered in the DOM. If you need to render all sections, pass preserveNode to the Accordion.Item.Collapse component.
import Accordion from '@semcore/ui/accordion';
import { Box } from '@semcore/ui/base-components';
import React from 'react';
const Demo = () => {
const [value, onChange] = React.useState([0]);
return (
<Accordion value={value} onChange={(value: any) => onChange(value)}>
{[...new Array(3)].map((_, index) => (
<Accordion.Item value={index} key={index} disabled={index === 1}>
<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}`}
{' '}
<a href='#'>Some focusable link in content</a>
</Box>
</Accordion.Item.Collapse>
</Accordion.Item>
))}
</Accordion>
);
};
export default Demo;