Skip to content

Commit

Permalink
refactor: remove unneccesary accordion wrapper
Browse files Browse the repository at this point in the history
  • Loading branch information
timoheddes committed Aug 21, 2023
1 parent 73375ac commit 8d0dba7
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 30 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -53,26 +53,24 @@ export const Dynamic: IStory = {
},
render: ({ linked, sectionCount }) => {
return (
<Accordion.Root>
<Accordion.Sections linked={linked}>
{sampleSections
.slice(0, sectionCount)
.map(
(
{ title, children, onOpen, onClose }: IAccordionSectionProps,
index,
) => (
<Accordion.Section
onOpen={onOpen}
onClose={onClose}
title={title}
key={index}
>
{children}
</Accordion.Section>
),
)}
</Accordion.Sections>
<Accordion.Root linked={linked}>
{sampleSections
.slice(0, sectionCount)
.map(
(
{ title, children, onOpen, onClose }: IAccordionSectionProps,
index,
) => (
<Accordion.Section
onOpen={onOpen}
onClose={onClose}
title={title}
key={index}
>
{children}
</Accordion.Section>
),
)}
</Accordion.Root>
);
},
Expand Down
95 changes: 90 additions & 5 deletions packages/libs/react-ui/src/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,97 @@
import { IAccordionSectionsProps } from '.';
import {
accordionContentWrapperClass,
accordionSectionClass,
accordionTitleClass,
accordionTitleVariants,
} from './Accordion.css';
import useLinked from './useLinked';
import { IAccordionSectionProps } from '.';

import classNames from 'classnames';
import type { FC, FunctionComponentElement } from 'react';
import React from 'react';
import React, { useCallback, useEffect } from 'react';

export interface IAccordionRootProps {
children?: FunctionComponentElement<IAccordionSectionsProps>;
children?: FunctionComponentElement<IAccordionSectionProps>[];
linked?: boolean;
openSection?: number;
}

export const AccordionRoot: FC<IAccordionRootProps> = ({ children }) => {
return <div data-testid="kda-accordion-wrapper">{children}</div>;
export const AccordionRoot: FC<IAccordionRootProps> = ({
children,
linked = false,
openSection,
}) => {
const { usingLinked, setUsingLinked, openSections, setOpenSections } =
useLinked(openSection);

useEffect(() => {
setUsingLinked(linked);
if (linked && openSections.length > 1) {
const lastOpen = openSections.pop() || -1;
setOpenSections([lastOpen]);
}
}, [linked]);

const handleToggleSection = useCallback(
(
index: number,
{ onOpen, onClose }: Pick<IAccordionSectionProps, 'onOpen' | 'onClose'>,
): void => {
const isOpen = openSections.includes(index);
if (isOpen) {
setOpenSections(openSections.filter((i) => i !== index));
onClose?.();
} else {
setOpenSections(usingLinked ? [index] : [...openSections, index]);
onOpen?.();
}
},
[openSections, usingLinked],
);

return (
<div data-testid="kda-accordion-sections">
{React.Children.map(children, (section, sectionIndex) => (
<section
className={accordionSectionClass}
data-testid="kda-accordion-section"
>
<div
data-testid="kda-accordion-section-title"
onClick={() =>
handleToggleSection(sectionIndex, {
onOpen: section?.props.onOpen,
onClose: section?.props.onClose,
})
}
className={classNames(
accordionTitleClass,
accordionTitleVariants[
openSections.includes(sectionIndex) ? 'opened' : 'closed'
],
)}
>
{React.cloneElement(
section as React.ReactElement<
HTMLElement | IAccordionSectionProps,
| string
| React.JSXElementConstructor<
JSX.Element & IAccordionSectionProps
>
>,
{
isOpen: openSections.includes(sectionIndex),
},
)}
</div>
{openSections.includes(sectionIndex) && section && (
<div className={accordionContentWrapperClass}>
{section.props.children}
</div>
)}
</section>
))}
</div>
);
};
6 changes: 1 addition & 5 deletions packages/libs/react-ui/src/components/Accordion/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,17 @@ import type { IAccordionRootProps } from './Accordion';
import { AccordionRoot } from './Accordion';
import type { IAccordionSectionProps } from './AccordionSection';
import { AccordionSection } from './AccordionSection';
import type { IAccordionSectionsProps } from './AccordionSections';
import { AccordionSections } from './AccordionSections';

import type { FC } from 'react';

export { IAccordionRootProps, IAccordionSectionProps, IAccordionSectionsProps };
export { IAccordionRootProps, IAccordionSectionProps };

export interface IAccordionProps {
Root: FC<IAccordionRootProps>;
Sections: FC<IAccordionSectionsProps>;
Section: FC<IAccordionSectionProps>;
}

export const Accordion: IAccordionProps = {
Root: AccordionRoot,
Sections: AccordionSections,
Section: AccordionSection,
};

0 comments on commit 8d0dba7

Please sign in to comment.