SAEL

Accordion

A vertically stacked set of interactive headings that each reveal an associated section of content built with Headless UI.

Made by imskyleen
Loading...

Installation

Usage

<Accordion>
  <AccordionItem>
    <AccordionButton>Accordion Item 1</AccordionButton>
    <AccordionPanel>Accordion Content 1</AccordionPanel>
  </AccordionItem>
  <AccordionItem>
    <AccordionButton>Accordion Item 2</AccordionButton>
    <AccordionPanel>Accordion Content 2</AccordionPanel>
  </AccordionItem>
  <AccordionItem>
    <AccordionButton>Accordion Item 3</AccordionButton>
    <AccordionPanel>Accordion Content 3</AccordionPanel>
  </AccordionItem>
</Accordion>

Props

Animate UI props

AccordionButton

Prop

Type

AccordionPanel

Prop

Type

Don't delete from the DOM

The choice made is the same as Headless UI, i.e. to remove the element from the DOM for accessibility and performance reasons. However, this may pose a problem for SEO. If you want your Accordion content to be taken into account by Google, please replace the DisclosurePanel component with (because the Accordion component is based on the Disclosure component):

components/animate-ui/headless/disclosure.tsx
function DisclosurePanel<TTag extends React.ElementType = typeof motion.div>(
  props: DisclosurePanelProps<TTag>,
) {
  const {
    className,
    children,
    transition = { type: 'spring', stiffness: 150, damping: 22 },
    as = motion.div,
    unmount,
    ...rest
  } = props;
  const { isOpen } = useDisclosure();

  return (
    <DisclosurePanelPrimitive
      static
      as={as as React.ElementType}
      unmount={unmount}
    >
      {(bag) => (
        <motion.div
          initial={false}
          animate={
            isOpen
              ? { height: 'auto', opacity: 1, '--mask-stop': '100%' }
              : { height: 0, opacity: 0, '--mask-stop': '0%' }
          }
          transition={transition}
          style={{
            maskImage:
              'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',
            WebkitMaskImage:
              'linear-gradient(black var(--mask-stop), transparent var(--mask-stop))',
          }}
          className={cn('overflow-hidden', className)}
          ref={ref}
          {...rest}
        >
          {typeof children === 'function' ? children(bag) : children}
        </motion.div>
      )}
    </DisclosurePanelPrimitive>
  );
}

Credits

  • We use Headless UI for the disclosure component.
  • We take our inspiration from Shadcn UI for the accordion style.

On this page