skip to Main Content

I have a situation where I want to use shadcn Button as a trigger for DropdownMenu, and when I make DropdownMenuTrigger asChild, it wont render the children.

I understand that there needs to be something done in this case, I tried to read and understand from this Radix Primitives Composition

I hacked together something I thought would be correct based on the link above, but nothing …

What must I do to have it working?

Here is a simple code, which results in DropdownMenuTrigger to not show children correctly.

import React from "react";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "../../../@/components/ui/dropdown-menu";
import { Button } from "../../../@/components/ui/button";
import { Menu } from "lucide-react";

const MyButton = React.forwardRef(
  (props, forwardedRef: React.Ref<HTMLButtonElement>) => (
    <Button
      {...props}
      ref={forwardedRef}
      className="py-7 size-8"
      variant={"outline"}
    >
      <Menu color="hsl(var(--supplementary))" className="size-8" />
    </Button>
  )
);

const ListingMenu = (): JSX.Element => {
  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild className="size-8">
        <MyButton />
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <DropdownMenuLabel>My Account</DropdownMenuLabel>
        <DropdownMenuSeparator />
        <DropdownMenuItem>Profile</DropdownMenuItem>
        <DropdownMenuItem>Billing</DropdownMenuItem>
        <DropdownMenuItem>Team</DropdownMenuItem>
        <DropdownMenuItem>Subscription</DropdownMenuItem>
      </DropdownMenuContent>
    </DropdownMenu>
  );
};

export default ListingMenu;

2

Answers


  1. Chosen as BEST ANSWER

    I managed to get it working by using buttonVariants helper, provided in the shadcn button component, like so

    import React from "react";
    import {
      DropdownMenu,
      DropdownMenuContent,
      DropdownMenuItem,
      DropdownMenuLabel,
      DropdownMenuSeparator,
      DropdownMenuTrigger,
    } from "../../../@/components/ui/dropdown-menu";
    import { Menu } from "lucide-react";
    import { buttonVariants } from "../../../@/components/ui/button";
    
    const ListingMenu = (): JSX.Element => {
      return (
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <button className={buttonVariants({ variant: "outline" })}>
              <Menu color="hsl(var(--supplementary))" className="size-8" />
            </button>
          </DropdownMenuTrigger>
          <DropdownMenuContent>
            <DropdownMenuLabel>My Account</DropdownMenuLabel>
            <DropdownMenuSeparator />
            <DropdownMenuItem>Profile</DropdownMenuItem>
            <DropdownMenuItem>Billing</DropdownMenuItem>
            <DropdownMenuItem>Team</DropdownMenuItem>
            <DropdownMenuItem>Subscription</DropdownMenuItem>
          </DropdownMenuContent>
        </DropdownMenu>
      );
    };
    
    export default ListingMenu;
    

  2. I assume without using "buttonVariants" helper, u can directly apply the styles and use your custom Button component inside the DropdownMenuTrigger.

    const ListingMenu = (): JSX.Element => {
      return (
        <DropdownMenu>
          <DropdownMenuTrigger asChild>
            <Button variant="outline" className="py-7 size-8">
              <Menu color="hsl(var(--supplementary))" className="size-8" />
            </Button>
          </DropdownMenuTrigger>
        ...
    

    The issue was when the DropdownMenuTrigger with asChild, it’s important to ensure that the custom component passed to it correctly forwards refs.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search