Skip to content
61 changes: 61 additions & 0 deletions src/components/Accordion/Accordion.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Disclosure } from "@headlessui/react";
import clsx from "clsx";
import React, { Children } from "react";
import PropTypes from "prop-types";
import { SlideDown } from "../Animation/SlideDown";
import { ChevronRightIcon } from "../../icons/ChevronRightIcon";

export const Accordion = ({ children }) => {
const childrenArray = Children.toArray(children);
return (
<Disclosure>
{({ open }) => (
<>
<Disclosure.Button className="flex items-center">
<div className="mr-2" data-testid="accordion-dropdown-icon">
<ChevronRightIcon className={clsx(open && "rotate-90")} />
</div>

{childrenArray.filter((child) => child?.type === Header)}
</Disclosure.Button>

<SlideDown isOpen={open}>{childrenArray.filter((child) => child?.type === Body)}</SlideDown>
</>
)}
</Disclosure>
);
};

const Header = ({ className, children, ...rest }) => {
return (
<div className={clsx("flex items-center space-x-3", className)} {...rest}>
{children}
</div>
);
};

Accordion.Header = Header;

const Body = ({ className, children, ...rest }) => {
return (
<Disclosure.Panel as="div" className={clsx("p-2 pb-10", className)} {...rest}>
{children}
</Disclosure.Panel>
);
};

Accordion.Body = Body;

Accordion.prototype = {
children: PropTypes.node,
};

Header.prototype = {
className: PropTypes.string,
children: PropTypes.node,
};

Body.prototype = {
className: PropTypes.string,
children: PropTypes.node,
};
1 change: 1 addition & 0 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ export { RelativeDateRange } from "./components/DatePicker/RelativeDateRange";
export { DatePickerPopover } from "./components/DatePicker/DatePickerPopover";
export { InlineValuePopover } from "./components/Forms/InlineValuePopover";
export { ImageUpload } from "./components/ImageUpload";
export { Accordion } from "./components/Accordion/Accordion";

// Utilities
export { Currency } from "./components/Utilities/Currency";
Expand Down
63 changes: 63 additions & 0 deletions src/stories/DataDisplay/Accordion.stories.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from "react";
import { Accordion } from "../../components/Accordion/Accordion";

const AccordionStories = {
title: "Data Display/Accordion",
component: Accordion,
parameters: {
docs: {
description: {
component: "Accordions are collapsible content UI element",
},
}
},
args: {
heading: "This is Accordion heading",
headingClass: "text-xl",
content: `Space, the final frontier. These are the voyages of the starship Enterprise.
Its five year mission: to explore strange new worlds, to seek out new life and
new civilizations, to boldly go where no man has gone before!`,
contentClass: "p1"
},
argTypes: {
heading: {
type: { required: false },
description: "This is accordion heading",
control: { type: "text" },
},
headingClass: {
type: { required: false },
control: { type: "text" },
table: {
type: { summary: "Classes for heading" },
},
},
content: {
type: { required: false },
description: "This is body content",
control: { type: "text" },
},
contentClass: {
type: { required: false },
control: { type: "text" },
table: {
type: { summary: "Classes for content"},
},
}
},
};

export const Default = ({ children, heading, headingClass, content }) => {
return (
<Accordion>
<Accordion.Header className={headingClass}>
{ heading }
</Accordion.Header>
<Accordion.Body>
{ content }
</Accordion.Body>
</Accordion>
)
};

export default AccordionStories;
Loading