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.