@logicblocks/react-accordion
Version:
A headless, fully controlled, unstyled React accordion component with maximum flexibility.
75 lines (74 loc) • 2.08 kB
JavaScript
// src/Accordion.tsx
import { jsx, jsxs } from "react/jsx-runtime";
var Accordion = ({
items,
currentIndex,
onToggle,
multiple = false,
collapseOthers = false,
containerClassName,
containerStyle,
itemClassName,
itemStyle,
triggerClassName,
triggerStyle,
panelClassName,
panelStyle
}) => {
const isOpen = (index) => {
if (multiple && Array.isArray(currentIndex)) {
return currentIndex.includes(index);
}
return currentIndex === index;
};
const handleClick = (index) => {
if (multiple) {
const current = Array.isArray(currentIndex) ? currentIndex : [];
const isCurrentlyOpen = current.includes(index);
if (collapseOthers) {
onToggle(isCurrentlyOpen ? [] : [index]);
} else {
const next = isCurrentlyOpen ? current.filter((i) => i !== index) : [...current, index];
onToggle(next);
}
} else {
const isCurrentlyOpen = currentIndex === index;
onToggle(isCurrentlyOpen ? -1 : index);
}
};
return /* @__PURE__ */ jsx("div", { className: containerClassName, style: containerStyle, children: items.map((item, index) => {
const { Component } = item;
const open = isOpen(index);
const triggerId = `accordion-trigger-${index}`;
const panelId = `accordion-panel-${index}`;
return /* @__PURE__ */ jsxs("div", { className: itemClassName, style: itemStyle, children: [
/* @__PURE__ */ jsx(
"button",
{
role: "button",
id: triggerId,
"aria-controls": panelId,
"aria-expanded": open,
onClick: () => handleClick(index),
className: triggerClassName,
style: triggerStyle,
children: item.title
}
),
open && /* @__PURE__ */ jsx(
"div",
{
role: "region",
id: panelId,
"aria-labelledby": triggerId,
className: panelClassName,
style: panelStyle,
children: /* @__PURE__ */ jsx(Component, {})
}
)
] }, index);
}) });
};
export {
Accordion
};