Issue
I am trying to build an APP in which the side menu items will be different on different page Layouts. I do not want to hardcode the link instead trying to make it reusable. But the menu is not expanding when wrapping it with the react-router-dom.
TestMenuAccordion.tsx:
import { useState } from "react";
const Accordion = ({
controllerElement,
contentDescription,
children,
}: any) => {
const [isExpanded, setIsExpanded] = useState(false);
return (
<div className="w-full mt-4">
<div
aria-expanded={isExpanded}
aria-controls={contentDescription}
aria-label={(isExpanded ? "hide " : "show ") + contentDescription}
onClick={() => setIsExpanded((prevIsExpanded) => !prevIsExpanded)}
>
{controllerElement(isExpanded)}
</div>
{isExpanded && (
<div id={contentDescription} className="w-full">
{children}
</div>
)}
</div>
);
};
export default Accordion;
TestMenu.tsx
import Accordion from "./TestMenuAccordion";
// import "./SideNav.css";
import { Link } from "react-router-dom";
export function SideNavEx(
props: any,
{ children }: { children: React.ReactNode },
) {
return (
<Accordion
controllerElement={(isExpanded: any) => (
<button className={isExpanded ? "selected" : "not-selected"}>
{props.label} {isExpanded ? "-" : "+"}
</button>
)}
contentDescription="menu items"
>
<ul className="sideNav">{children}</ul>
</Accordion>
);
}
export function GeneralMenuItems(props: any) {
return (
<Link to={props.url}>
<li>{props.text}</li>
</Link>
);
}
PageLayout.tsx
import { Outlet } from "react-router-dom";
import { SideNavEx, GeneralMenuItems } from "./TestMenu";
const PageLayout = () => {
return (
<>
<section className="container pt-5 pb-40 px-4 mx-auto grid md:px-8 md:grid-cols-10 md:text-left">
<div className="px-4 col-span-10 md:col-span-5 lg:col-span-3">
<SideNavEx label={"General side Menu "}>
<GeneralMenuItems url={"/Generalmenu1"} text={"Genetal Item 1"} />
<GeneralMenuItems url={"/Generalmenu2"} text={"Genetal Item 2"} />
<GeneralMenuItems url={"/Generalmenu3"} text={"Genetal Item 3"} />
</SideNavEx>
</div>
<div className="px-4 pt-4 col-span-10 md:col-span-5 lg:col-span-7">
<Outlet />
</div>
</section>
</>
);
};
export default PageLayout;
I am working with React version 18.2 and React-Router-DOM version 6.21.
Solution
It would seem you have mis-declared the SideNavEx
component. React components take a single props object, but you have declared that SideNavEx
takes two arguments.
Based on the usage it seems you should just remove the first arg, props: any
, leaving a single props object with a destructured children
prop typed as React.ReactNode
, and add the missing label
prop.
export function SideNavEx(
{ children, label }: { children: React.ReactNode; label: string }
) {
return (
<Accordion
controllerElement={(isExpanded: boolean) => (
<button className={isExpanded ? "selected" : "not-selected"}>
{label} {isExpanded ? "-" : "+"}
</button>
)}
contentDescription="menu items"
>
<ul className="sideNav">{children}</ul>
</Accordion>
);
}
Answered By - Drew Reese
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.