Skip to content

Commit

Permalink
Merge pull request #630 from ably/web-4082-accordion-forward-ref
Browse files Browse the repository at this point in the history
[WEB-4082] Allow forwardRef on Accordion
  • Loading branch information
jamiehenson authored Feb 3, 2025
2 parents f3fd053 + c5de15e commit d7dbf8b
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 63 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@ably/ui",
"version": "15.3.5",
"version": "15.3.6",
"description": "Home of the Ably design system library ([design.ably.com](https://design.ably.com)). It provides a showcase, development/test environment and a publishing pipeline for different distributables.",
"repository": {
"type": "git",
Expand Down
131 changes: 69 additions & 62 deletions src/core/Accordion.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { ReactNode, useMemo, useState } from "react";
import React, { ReactNode, useMemo, useState, forwardRef } from "react";
import {
AccordionContent,
AccordionItem,
Expand Down Expand Up @@ -138,68 +138,75 @@ const AccordionRow = ({
);
};

const Accordion = ({
data,
theme = "transparent",
icons = {
closed: { name: "icon-gui-plus-outline" },
open: { name: "icon-gui-minus-outline" },
},
options,
...props
}: AccordionProps) => {
const openIndexes = useMemo(() => {
const indexValues = data.map((_, i) => `accordion-item-${i}`);
return options?.fullyOpen
? indexValues
: indexValues.filter((_, index) =>
options?.defaultOpenIndexes?.includes(index),
);
}, [options?.defaultOpenIndexes, options?.fullyOpen, data.length]);
const Accordion = forwardRef<HTMLDivElement, AccordionProps>(
(
{
data,
theme = "transparent",
icons = {
closed: { name: "icon-gui-plus-outline" },
open: { name: "icon-gui-minus-outline" },
},
options,
...props
},
ref,
) => {
const openIndexes = useMemo(() => {
const indexValues = data.map((_, i) => `accordion-item-${i}`);
return options?.fullyOpen
? indexValues
: indexValues.filter((_, index) =>
options?.defaultOpenIndexes?.includes(index),
);
}, [options?.defaultOpenIndexes, options?.fullyOpen, data.length]);

const [openRowValues, setOpenRowValues] = useState<string | string[]>(
openIndexes,
);
const innerAccordion = data.map((item, index) => (
<AccordionRow
key={item.name}
name={item.name}
rowIcon={item.icon}
toggleIcons={icons}
theme={theme}
options={options}
index={index}
onClick={() => {
item.onClick?.(index);
}}
openRowValues={openRowValues}
>
{item.content}
</AccordionRow>
));
const [openRowValues, setOpenRowValues] = useState<string | string[]>(
openIndexes,
);
const innerAccordion = data.map((item, index) => (
<AccordionRow
key={item.name}
name={item.name}
rowIcon={item.icon}
toggleIcons={icons}
theme={theme}
options={options}
index={index}
onClick={() => {
item.onClick?.(index);
}}
openRowValues={openRowValues}
>
{item.content}
</AccordionRow>
));

return (
<div {...props}>
{options?.autoClose ? (
<RadixAccordion
type="single"
collapsible
defaultValue={openIndexes[0]}
onValueChange={(values) => setOpenRowValues(values)}
>
{innerAccordion}
</RadixAccordion>
) : (
<RadixAccordion
type="multiple"
defaultValue={openIndexes}
onValueChange={(values) => setOpenRowValues(values)}
>
{innerAccordion}
</RadixAccordion>
)}
</div>
);
};
return (
<div ref={ref} {...props}>
{options?.autoClose ? (
<RadixAccordion
type="single"
collapsible
defaultValue={openIndexes[0]}
onValueChange={(values) => setOpenRowValues(values)}
>
{innerAccordion}
</RadixAccordion>
) : (
<RadixAccordion
type="multiple"
defaultValue={openIndexes}
onValueChange={(values) => setOpenRowValues(values)}
>
{innerAccordion}
</RadixAccordion>
)}
</div>
);
},
);

Accordion.displayName = "Accordion";

export default Accordion;

0 comments on commit d7dbf8b

Please sign in to comment.