import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
interface chapterProps{
selectedChapter:number;
setSelectedChapter:React.Dispatch<React.SetStateAction<number>>;
chapters:any;
}
export default function Chapters(props: chapterProps) {
console.log("whats in selected chapter", props?.selectedChapter);
return (
<>
<div className="w-full flex flex-col space-y-4">
{props?.chapters?.map((value: any, index: number) => {
console.log("whats in chapter map", value);
return (
<Accordion
type="single"
collapsible
className="w-full bg-white p-4"
key={index}
defaultValue={`item-${props?.selectedChapter}`}
>
<AccordionItem value={`item-${index}`} key={index}>
<AccordionTrigger>
<div className="w-full text-left flex flex-col space-y-4">
<p className="mx-0 text-[#04445E] font-semibold text-2xl">
{value?.chaptername}
</p>
</>)}
</div>
</AccordionTrigger>
<AccordionContent key={index}>
{value?.chapterContent &&
value?.chapterContent?.map((content: any, i: number) => {
return (
<div className="flex space-y-6 flex-col">
<p className="text-2xl text-[#011E29]">
{content.name}
</p>
<div className="flex space-x-4 text-[#011E29]">
<p className="">{content.type}</p>
<p>{content.time}</p>
</div>
</div>
);
})}
</AccordionContent>
</AccordionItem>
</Accordion>
);
})}
</div>
</>
);
}
Above is my code where I am trying to control ShadcnUI Accordion "open" and "close" using a state variable called "selectedChapter", I'm able to set the default AccordionItem open (i,e. "item-0") because default value of my state variable is also 0 but when state variable value changes (example: selectedChapter = 2) after the initial rendering, the AccordionItem with value "item-2" doesn't open
Note: here I'm passing "selectedChapter" state as props from parent component and most of the time it is controlled by parent component itself, Yes i can use "setSelectedChapter" from this component but my concern is with state change from parent component.
Thanks for helping:)
In RadixUI, The headless UI behind Shadcn/ui, You can make the accordion conrolled by the
valueandonValueChangeprops.The state type depends on Accordion's
typeprop. Whentype="single", the state is of typestring. When usingtype="multiple"the state will bestring[].In your component, you need two things:
Move the
<Accordion>wrapper arround the loop, so it can controll all accordions. currently in your implementation every item has its own state. and changedefaultValuetovalueandonValueChange