{"version":3,"sources":["../src/index.tsx","../src/ListItem.tsx"],"sourcesContent":["import React, {\n  KeyboardEvent,\n  MouseEvent,\n  useEffect,\n  useRef,\n  useState,\n} from \"react\";\nimport ListItem from \"./ListItem\";\nimport \"./style.css\";\n\ninterface AccordionItem {\n  [name: string | number | symbol]: any;\n  id: string | number;\n}\ninterface AccorionProps {\n  items: AccordionItem[];\n  multiExpand?: boolean;\n  SummaryComponent: React.ElementType;\n  DetailComponent: React.ElementType;\n  [rest: string | number | symbol]: unknown;\n}\n\nconst Accordion = ({ items, multiExpand = true, ...rest }: AccorionProps) => {\n  const [opened, setOpened] = useState<Record<string, boolean>>({});\n  const listContainerRef = useRef<HTMLUListElement>(null);\n\n  const mutationCb: MutationCallback = (list) => {\n    // this will get us the 2nd child (detail component)\n    const contentItem = (list[0].target.childNodes[1] as HTMLElement) ?? null;\n\n    if (!contentItem) return;\n    // only animate the content item class\n    if (contentItem.className !== \"acc-content\") return;\n\n    const scrollHeight = contentItem.scrollHeight;\n\n    contentItem.animate(\n      { maxHeight: `${scrollHeight}px`, opacity: 1 },\n      { duration: 100, easing: \"ease-in\", fill: \"forwards\" }\n    );\n  };\n\n  useEffect(() => {\n    if (!listContainerRef.current) return;\n    // start the observer\n    const observer = new MutationObserver(mutationCb);\n    observer.observe(listContainerRef.current, {\n      childList: true,\n      subtree: true,\n    });\n\n    return () => {\n      observer.disconnect();\n    };\n  }, []);\n\n  const closeAccordion = (id: string) => {\n    const contentItem = document.getElementById(`acc-content-${id}`);\n\n    if (!contentItem) return;\n\n    contentItem\n      .animate(\n        { maxHeight: 0, opacity: 0 },\n        { duration: 100, easing: \"ease-out\" }\n      )\n      .finished.then(() => {\n        contentItem.style.display = \"none\";\n\n        setOpened((prv) => {\n          // make a new copy and delete the id from obj\n          // after animation is finished\n          const newObj = { ...prv };\n          delete newObj[id];\n          return newObj;\n        });\n      });\n  };\n\n  const clickHandler = (e: MouseEvent | KeyboardEvent): void => {\n    let element = e.target as HTMLElement;\n\n    if (element.parentElement?.tagName === \"LI\") {\n      element = element.parentElement;\n    }\n\n    if (element.tagName !== \"LI\") return;\n\n    const id = element.getAttribute(\"id\");\n\n    if (!id) return;\n\n    const isOpen = opened[id];\n\n    if (isOpen) {\n      return closeAccordion(id);\n    }\n\n    setOpened((prv) => ({ ...prv, [id]: true }));\n\n    if (!multiExpand) {\n      const prvAccId = Object.keys(opened)[0];\n      closeAccordion(prvAccId);\n    }\n  };\n\n  const ariaHandler = (e: KeyboardEvent) => {\n    if (e.key === \" \" || e.key === \"Enter\") {\n      clickHandler(e);\n      e.preventDefault();\n    }\n  };\n\n  return (\n    <ul\n      onClick={clickHandler}\n      onKeyPress={ariaHandler}\n      ref={listContainerRef}\n      role=\"list\"\n    >\n      {items.map(({ id, ...data }) => (\n        <ListItem id={id} key={id} isOpen={opened[id]} {...data} {...rest} />\n      ))}\n    </ul>\n  );\n};\n\nexport default Accordion;\n","import React, { memo } from \"react\";\n\ninterface ListItemProps {\n  SummaryComponent: React.ElementType;\n  DetailComponent: React.ElementType;\n  id: string | number;\n  isOpen: boolean;\n}\nconst ListItem = ({\n  id,\n  isOpen,\n  SummaryComponent,\n  DetailComponent,\n  ...rest\n}: ListItemProps) => {\n  return (\n    <li\n      role=\"button\"\n      tabIndex={0}\n      aria-expanded={isOpen}\n      aria-controls={`acc-content-${id}`}\n      id={id.toString()}\n      className=\"acc-item\"\n    >\n      <SummaryComponent {...rest} isOpen={isOpen} />\n      {isOpen && (\n        <div role=\"definition\" className=\"acc-content\" id={`acc-content-${id}`}>\n          <DetailComponent {...rest} isOpen={isOpen} />\n        </div>\n      )}\n    </li>\n  );\n};\n\nexport default memo(ListItem);\n"],"mappings":"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","names":[]}