Accordion

A set of vertically stacked, interactive headings that reveal content sections with smooth animations using Framer Motion

Framer Motion Accordion

What is a UI component?
A UI (User Interface) component is a modular, reusable element that serves a specific function within a graphical user interface. Examples include buttons, input fields, dropdown menus, sliders.
Why are components important?
UI Component Traits
Does Component Improve UX?
component design challenges?
Some common challenges include maintaining consistency across different devices and screen sizes, ensuring compatibility with various browsers and assistive technologies with ease of use.
Ensure Responsiveness

Installation

npm install framer-motion
accordion.tsx
// @ts-nocheck
import React, { ReactNode } from 'react'
import { AnimatePresence, motion } from 'framer-motion'
import { ChevronDown } from 'lucide-react'
import { cn } from '@/lib/utils'
 
const AccordionContext = React.createContext({})
const useAccordion = () => React.useContext(AccordionContext)
 
export function AccordionContainer({
  children,
  className,
}: {
  children: ReactNode
  className?: string
}) {
  return (
    <div className={cn('grid grid-cols-2 gap-1', className)}>{children}</div>
  )
}
export function AccordionWrapper({ children }) {
  return <div>{children}</div>
}
 
export function Accordion({
  children,
  multiple,
  defaultValue,
}: {
  children: ReactNode
  multiple?: boolean
  defaultValue?: string | undefined | string[]
}) {
  const [activeIndex, setActiveIndex] = React.useState(
    multiple ? (defaultValue ? [defaultValue] : []) : [defaultValue]
  )
 
  function onChangeIndex(value) {
    setActiveIndex((currentActiveIndex) => {
      if (!multiple) {
        return value === currentActiveIndex ? null : value
      }
 
      if (currentActiveIndex.includes(value)) {
        return currentActiveIndex.filter((i) => i !== value)
      }
 
      return [...currentActiveIndex, value]
    })
  }
 
  return React.Children.map(children, (child) => {
    const value = child.props.value
    const isActive = multiple
      ? Array.isArray(activeIndex) && activeIndex.includes(value)
      : Array.isArray(activeIndex)
        ? activeIndex[0].includes(value)
        : activeIndex === value
 
    return (
      <AccordionContext.Provider value={{ isActive, value, onChangeIndex }}>
        <>{child}</>
      </AccordionContext.Provider>
    )
  })
}
 
export function AccordionItem({ children, value }) {
  const { isActive } = useAccordion()
 
  return (
    <div
      className={`rounded-lg overflow-hidden mb-2  ${
        isActive
          ? 'active border-2 dark:border-[#656fe2]  border-[#F2F2F2] dark:bg-[#E0ECFB] bg-[#F2F2F2]'
          : 'bg-transparent border-2 dark:hover:border-[#656fe2]'
      }
    `}
      value={value}
    >
      {children}
    </div>
  )
}
 
export function AccordionHeader({
  children,
  icon,
}: {
  children: ReactNode
  icon?: any
}) {
  const { isActive, value, onChangeIndex } = useAccordion()
 
  return (
    <motion.div
      className={`p-4 cursor-pointer transition-all font-semibold    dark:text-white text-black dark:hover:bg-[#1e2a78] hover:bg-[#F2F2F2] dark:hover:text-white hover:text-black flex justify-between items-center ${
        isActive
          ? 'active  dark:bg-[#1e2a78] bg-[#F2F2F2] '
          : 'dark:bg-[#11112b] bg-white'
      }
      `}
      onClick={() => onChangeIndex(value)}
    >
      {children}
      {icon ? (
        <div
          className={`${
            isActive ? 'rotate-45 ' : 'rotate-0 '
          } transition-transform`}
        >
          {icon}
        </div>
      ) : (
        <>
          <ChevronDown
            className={`${
              isActive ? 'rotate-180 ' : 'rotate-0 '
            } transition-transform`}
          />
        </>
      )}
    </motion.div>
  )
}
 
export function AccordionPanel({ children }) {
  const { isActive } = useAccordion()
 
  return (
    <AnimatePresence initial={true}>
      {isActive && (
        <motion.div
          initial={{ height: 0, overflow: 'hidden' }}
          animate={{ height: 'auto', overflow: 'hidden' }}
          exit={{ height: 0 }}
          transition={{ type: 'spring', duration: 0.3, bounce: 0 }}
          className={`dark:bg-white bg-[#F2F2F2]
          `}
        >
          <motion.article
            initial={{ clipPath: 'polygon(0 0, 100% 0, 100% 0, 0 0)' }}
            animate={{ clipPath: 'polygon(0 0, 100% 0, 100% 100%, 0% 100%)' }}
            exit={{
              clipPath: 'polygon(0 0, 100% 0, 100% 0, 0 0)',
            }}
            transition={{
              type: 'spring',
              duration: 0.4,
              bounce: 0,
            }}
            className={`p-3 bg-transparent text-black `}
          >
            {children}
          </motion.article>
        </motion.div>
      )}
    </AnimatePresence>
  )
}
 

Structure

props/apis
    <Accordion defaultValue={['item-1']} multiple>
        <AccordionItem value="item-1">
          <AccordionHeader icon={<Plus />}>
          </AccordionHeader>
          <AccordionPanel>
          </AccordionPanel>
        </AccordionItem>
        <AccordionItem value="item-2">
          <AccordionHeader icon={<Plus />}>
          </AccordionHeader>
          <AccordionPanel>
          </AccordionPanel>
        </AccordionItem>
        <AccordionItem value="item-3">
          <AccordionHeader icon={<Plus />}>
          </AccordionHeader>
          <AccordionPanel>
          </AccordionPanel>
        </AccordionItem>
    </Accordion>

Single Layout

What is a UI component?
A UI (User Interface) component is a modular, reusable element that serves a specific function within a graphical user interface. Examples include buttons, input fields, dropdown menus, sliders, and checkboxes.
Why are UI components important?
UI components promote consistency, efficiency, and scalability in software development. They allow developers to reuse code, maintain a consistent look and feel across an application, and easily make updates or modifications without affecting the entire system.
Key characteristics of UI components?

Multi Layout

What is a UI component?
Why are UI components important?
UI components promote consistency, efficiency, and scalability in software development. They allow developers to reuse code, maintain a consistent look and feel across an application, and easily make updates or modifications without affecting the entire system.
Key characteristics of UI components?

Props

PropTypeDefaultDescription
defaultValuestringstring[]undefined
multiplebooleanfalseWhether the accordion allows multiple items to be active at the same time
childrenReactNode[]undefinedThe accordion items, including their headers and panels
classNamestring''Optional CSS class for styling the accordion wrapper

Radix Accordion

Radix Accordion

Single accordion

Yes. It adheres to the WAI-ARIA design pattern.

Multilayout accordion

Yes. It adheres to the WAI-ARIA design pattern.