Skip to content

Commit

Permalink
fix(Accordion): make 'openItems' act as value
Browse files Browse the repository at this point in the history
Closes UXD-1225
  • Loading branch information
ajkl2533 committed Jul 17, 2023
1 parent 9b7234e commit a8261f7
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 16 deletions.
18 changes: 13 additions & 5 deletions src/components/Accordion/Accordion.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import React, { useState } from 'react';
import { Meta, Story } from '@storybook/react/types-6-0';
import { includes } from 'ramda';

import { Inline, Stack } from '../layout';
import { HexGrade } from '../HexGrade';
Expand Down Expand Up @@ -72,7 +73,7 @@ CustomTitleElement.args = {
};

export const AcordionWithExternalManagement: Story<AccordionProps> = () => {
const [openItems, setOpenItems] = useState<string[]>([]);
const [openItems, setOpenItems] = useState<(string | number)[]>([]);
const handleOnClick = (id: string) => {
if (!openItems.includes(id)) {
const newItems = [id];
Expand All @@ -91,16 +92,23 @@ export const AcordionWithExternalManagement: Story<AccordionProps> = () => {
<Inline gap="xl">
<Stack gap="sm" justify="flex-start">
<Button variant="text" onClick={() => handleOnClick('first')}>
First section
{includes('first', openItems) && '->'} First section
</Button>
<Button variant="text" onClick={() => handleOnClick('second')}>
Second section
{includes('second', openItems) && '->'} Second section
</Button>
<Button variant="text" onClick={() => handleOnClick('third')}>
Third section
{includes('third', openItems) && '->'} Third section
</Button>
</Stack>
<Accordion items={localItems} openItems={openItems} />
<Accordion
isCollapsedOnOpen={false}
items={localItems}
openItems={openItems}
onChange={(ids) => {
setOpenItems(ids);
}}
/>
</Inline>
);
};
Expand Down
29 changes: 19 additions & 10 deletions src/components/Accordion/Accordion.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,29 +30,37 @@ function filterState(
if (isCollapsedOnOpen) {
return [item];
}

return [...state, item];
}

const Accordion = React.forwardRef<HTMLDivElement, AccordionProps>(
(
{ isCollapsedOnOpen = true, items, openItems, className, ...props },
{
isCollapsedOnOpen = true,
items,
openItems,
className,
onChange,
...props
},
ref,
) => {
const [openIds, setOpenIds] = useState(pickOpen(items));

useEffect(
() =>
openItems?.forEach((item: AccordionItemId) =>
setOpenIds((state) => filterState(state, item, isCollapsedOnOpen)),
),
[openItems, isCollapsedOnOpen],
);
useEffect(() => {
if (openItems !== undefined) {
setOpenIds(isCollapsedOnOpen ? [openItems[0]] : openItems);
}
}, [openItems, isCollapsedOnOpen]);

const handleClick = useCallback(
(id: AccordionItemId) => {
setOpenIds((state) => filterState(state, id, isCollapsedOnOpen));
const nextState = filterState(openIds, id, isCollapsedOnOpen);
setOpenIds(nextState);
onChange?.(nextState);
},
[setOpenIds, isCollapsedOnOpen],
[openIds, setOpenIds, onChange, isCollapsedOnOpen],
);

return (
Expand All @@ -78,6 +86,7 @@ Accordion.propTypes = {
isCollapsedOnOpen: PropTypes.bool,
className: PropTypes.string,
openItems: PropTypes.arrayOf(AccordionItemIdPropType),
onChange: PropTypes.func,
};

export default Accordion;
3 changes: 2 additions & 1 deletion src/components/Accordion/Accordion.types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,8 @@ export interface AccordionProps {
isCollapsedOnOpen?: boolean;
items: AccordionItem[];
className?: string;
openItems: AccordionItemId[];
openItems?: AccordionItemId[];
onChange?: (openIds: AccordionItemId[]) => void;
}

export const AccordionItemIdPropType = PropTypes.oneOfType([
Expand Down

0 comments on commit a8261f7

Please sign in to comment.