<Accordion.Panel isOpen={true}> doesn't work also setOpen and isOpen doesn't work with props
Describe the bug In the project, I need to manage the accordions panel and be able to open and close them, but I can't, I also checked the Flowbite codes and realized that they are not written correctly.
Expected behavior I want to manage isOpen and setOpen from the accordion panel and they work correctly.
Screenshots
System information:
- Device: Mac
- Browser: Chrome
Project information:
- Tailwind: ^3.2.4
- Flowbite: ^1.6.0
- Flowbite React: ^0.4.2
- Type: Next.js - 13.4.1
Sorry, I don't get the problem. Can you give more details? All the examples inside the documentation page seem to work properly.
You can get the source code to the examples here: https://github.com/themesberg/flowbite-react/blob/main/src/docs/pages/AccordionPage.tsx
PS: If you cold add a video demonstrating the problem, it would be better to understand, or to provide a sample project.
Sorry, I don't get the problem. Can you give more details? All the examples inside the documentation page seem to work properly.
You can get the source code to the examples here: https://github.com/themesberg/flowbite-react/blob/main/src/docs/pages/AccordionPage.tsx
PS: If you cold add a video demonstrating the problem, it would be better to understand, or to provide a sample project.
I have a form for the user's profile in each accordion panel, and I want the user to see a SAVE button at the end of each accordion panel and open the next accordion panel after clicking the button. It means that I can control which accordion panel is open with a state and manage its opening and closing.
Sorry, I don't get the problem. Can you give more details? All the examples inside the documentation page seem to work properly.
You can get the source code to the examples here: https://github.com/themesberg/flowbite-react/blob/main/src/docs/pages/AccordionPage.tsx
PS: If you cold add a video demonstrating the problem, it would be better to understand, or to provide a sample project.
please read this : https://github.com/themesberg/flowbite-react/tree/main/src/lib/components/Accordion
And see how the logic of isOpen and setOpen is written in Accordion.tsx and AccordionPanel.tsx files.
I still don't get it. Can you provide an example project?
I'm also having this problem myself. In a very simple use case:
const [isOpen, setIsOpen] = useState(false);
const toggleAccordion = () => {
setIsOpen(!isOpen);
console.log(isOpen)
};
return (
<>
<Accordion>
<AccordionPanel isOpen={isOpen}>
<AccordionTitle theme={accordionTitleTheme}>Hello</AccordionTitle>
<AccordionContent>World</AccordionContent>
</AccordionPanel>
</Accordion>
<Button onClick={toggleAccordion}>
{isOpen ? 'Close Accordion' : 'Open Accordion'}
</Button>
</>);
Does not seem to open or close the accordion panel accordingly. The isOpen state is being changed, but the state is not being reflected by the accordionPanel.
To note here is that I've also attempted using the setOpen prop for AccordionPanel, which imo is lacking documentation on how it's supposed to be used. As someone trying to use AccordionPanel, the setOpen prop is lacking description on how it's supposed to be used, and what it's for.
@realvandi documentation update should be coming soon. The library wasn't released yet, so, it is expected to have missing documentation, but the code is always your best friend in this case.
@rluders thanks for the quick response, it's very much appreciated. In the meanwhile, any hints on what could be done in order to trigger the opening/closing of the AccordionPanel? I can't seem to figure out what's wrong, even after reading through the code. Any answer would be much appreciated, thanks again for responding
@IuriPires can you help on this one? I'm not sure when I'll have time to test it right now.
@IuriPires can you help on this one? I'm not sure when I'll have time to test it right now.
Sure!!
Could someone confirm if the issue still exists?
Stumbled upon this thread since I ran into the same problem. I believe this is still an issue. My use case calls for the accordion panels to default open.
<Accordion alwaysOpen>
<Accordion.Panel isOpen={true}>
<Accordion.Title>
One
</Accordion.Title>
<Accordion.Content>
1
</Accordion.Content>
</Accordion.Panel>
<Accordion.Panel isOpen={true}>
<Accordion.Title>
Two
</Accordion.Title>
<Accordion.Content>
2
</Accordion.Content>
</Accordion.Panel>
</Accordion>
Here, only the "One" accordion panel is open when both should be open. I am using the latest npm version [email protected]
I believe the setOpen callback may also not fire as well. (I assume this is meant to fire when the panel opens?)
Is this working? I'm trying the isOpen prop and it's not responding. Please help
<Accordion>
<Accordion.Panel itemID="panel1" >
<Accordion.Title>Panel 1</Accordion.Title>
<Accordion.Content>
panel 1 content
</Accordion.Content>
</Accordion.Panel>
<Accordion.Panel itemID="panel2" isOpen={true}>
<Accordion.Title>Panel 2</Accordion.Title>
<Accordion.Content>
panel 2 content
</Accordion.Content>
</Accordion.Panel>
</Accordion>
anyone managed to make it work?
I'm also having the issue. any one got a fix?
Same issue here
same issue here, trying to use isOpen to make all panels open by default but it is not working
In my Case I was tried to use accordion with map iterator but it does not work properly.
I hope this usage can help someone.
const [isClosed, setIsClosed] = useState<boolean[]>(matchedHistory.map(() => true));
const handleOpen = (index: number) => {
const newIsClosed = [...isClosed];
newIsClosed[index] = !isClosed[index];
setIsClosed(newIsClosed);
};
const handleOnPanel = (index: number) => {
setIsClosed(items.map(() => true));
};
<Accordion collapseAll arrowIcon={() => null}> // Remove existing default arrowIcon
{ items.map((item,index) => (
<Accordion.Panel key={index}>
<Accordion.Title
onClick={() => handleOpen(index)}
>
<span>{Items.title}</span>
<AccordionArrow isOpen={!isClosed[index]} /> // AccordionArrowIcon goes here
</Accordion.Title>
<Accordion.Content hidden={isClosed[index]}> // Decide the content to hide or shown
<p>
<b>item.content</b>
</p>
<Button onClick={() => handleOnPanel(index)}>SomeButton</Button>
</Accordion.Content>
</Accordion.Panel>
))}
</Accordion>
And this is arrow icon component above. Just incase you want to use library here is url clsx twMerge
const AccordionArrow = ({ isOpen }: { isOpen: boolean }) => (
<svg
stroke="currentColor"
fill="currentColor"
strokeWidth="0"
viewBox="0 0 20 20"
aria-hidden="true"
className={twMerge(
"h-6 w-6 shrink-0",
clsx(isOpen ? "rotate-180" : "rotate-0"),
)}
data-testid="flowbite-accordion-arrow"
xmlns="http://www.w3.org/2000/svg"
>
<path
fillRule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clipRule="evenodd"
></path>
</svg>
);
This is still an issue, have not found a workaround
I'm running into this as well, version 0.11.1 here. Do we know if #1404 fixes the issue, assuming it hasn't bitrotted? Odd that it hasn't even been commented on.
Unfortunately we'll have to rewrite the component from scratch, entirely, the current state its... yeah, not much to say.
I am using flowbite-react version 0.10.2 Having a workaround. Since the main context logic is inside AccordionPanel, and can be fully replaced by passing alwaysOpen={false}. So I made my own <HomemadeAccordion /> to replace original <Accordion /> like the following, then I can fully controlled which tab to open.
const HomemadeAccordion = (props: AccordionProps) => {
const [isOpen, setOpen] = useState(props.collapseAll ? -1 : 0);
const panels = useMemo(
() =>
Children.map(props.children, (child, i) =>
cloneElement(child, {
alwaysOpen: props.alwaysOpen,
arrowIcon: child.props.arrowIcon ?? props.arrowIcon ?? ChevronDown,
flush: props.flush,
isOpen: child.props.isOpen ?? isOpen === i,
setOpen:
child.props.setOpen ?? (() => setOpen(isOpen === i ? -1 : i)),
}),
),
[props.alwaysOpen, props.arrowIcon, props.children, props.flush, isOpen],
);
const theme = merge(fbTheme.accordion.root, props.theme);
return (
<div
className={cn(
theme.base,
theme.flush[props.flush ? "on" : "off"],
props.className,
)}
data-testid="flowbite-accordion"
{...props}
>
{panels}
</div>
);
};
in this case, i can fully controlled the <Accordion.Panel /> open state
const [accordionOpen, setAccordionOpen] = useState<string[] | null>(null);
<HomemadeAccordion>
{[
{
title: t("Test Section"),
id: "test",
content: "Test Content 1",
},
{
title: t("Test Section 2"),
id: "test2",
content: "Test Content 2",
},
].map((section) => (
<Accordion.Panel
key={section.id}
alwaysOpen={false}
flush={false}
isOpen={accordionOpen?.includes(section.id) || false}
setOpen={() => setAccordionOpen((prev) => xor(prev, [section.id]))}
>
<Accordion.Title>{section.title}</Accordion.Title>
<Accordion.Content>{section.content}</Accordion.Content>
</Accordion.Panel>
))}
</HomemadeAccordion>