Shane Callanan
Shane Callanan

Reputation: 521

Render a link inside PrimeReact accordion header

I'm working with the PrimeReact library, specifically their <Accordion> component (see https://primereact.org/accordion/ ). PrimeReact provides an <AccordionTab> that should be rendered as children of <Accordion>. Each tab renders a clickable header for opening/closing the tab, and the element of that header is an <a>. If I add content to the header (by using the header prop of <AccordionTab>) then the elements in the content (even if buttons or anchors) are not clickable (their onClick handlers don't even fire). I'd like to overcome this, and also prevent the default behaviour of PrimeReact (i.e. opening/closing the tab) if a child anchor/button is clicked.

I tried targeting the headerAction element via pt prop and overriding its onClick handler with a custom one that calls preventDefault()/stopPropagation() but this was to no avail.

const preventOpeningClosingIfAnotherLinkWasClicked = (evt: MouseEvent<HTMLAnchorElement, MouseEvent>) => {
    if (!evt.currentTarget.closest(`.${headerClassName}`)) {
        evt.preventDefault();
        evt.stopPropagation();
    }
};

const passThroughOptions = {
    headerAction: { onClick: preventOpeningClosingIfAnotherLinkWasClicked }
};

return (
    <AccordionTab className={headerClassName} pt={passThroughOptions} header={headerElement}>
        {child.content}
    </AccordionTab>
);

Instead of rendering <AccordionTab> as a direct child of <Accordion>, I could wrap them in a div with position: relative and make the header content a direct child of this div instead, with position: absolute to position it correctly. This would effectively render the content as a parent of the header <a> element, which I believe would make it possible for it to capture click events. But it's a quirky fix that could cause issues with the layout/styling of the tabs themselves and one I'd prefer to avoid if possible.

How can I solve this issue?

Upvotes: 0

Views: 66

Answers (1)

Anton
Anton

Reputation: 100

I wasn't able to achieve desired behavior using pt property but directly assigning onClick callback handler to the children of the <AccordingTab> allows to use the e.stopPropagation and prevent tab from collapsing/expanding.

Example:

import { Accordion, AccordionTab } from "primereact/accordion";

export const PrimeReact = () => {
  const helloWorldClick = (e) => {
    e.stopPropagation();
    console.log("I am clicked");
  };

  return (
    <>
      <Accordion activeIndex={0}>
        <AccordionTab
          header={
            <>
              <a onClick={helloWorldClick} href="google.com" target="_blank">
                My Link
              </a>

              <button onClick={helloWorldClick}>Hello World</button>
            </>
          }
        >
          <p className="m-0">
            Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do
            eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
            ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut
            aliquip ex ea commodo consequat. Duis aute irure dolor in
            reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
            pariatur. Excepteur sint occaecat cupidatat non proident, sunt in
            culpa qui officia deserunt mollit anim id est laborum.
          </p>
        </AccordionTab>
      </Accordion>
    </>
  );
};

Upvotes: 0

Related Questions