radix-ui / primitives

Radix Primitives is an open-source UI component library for building high-quality, accessible design systems and web apps. Maintained by @workos.
https://radix-ui.com/primitives
MIT License
14.82k stars 717 forks source link

Tooltip does not work with TooltipTrigger asChild property #2959

Closed Fesyse closed 1 week ago

Fesyse commented 2 weeks ago

Bug report

Tooltip does not work, when in TooltipTrigger with asChild property have children as a component

It seems to work only if asChild removed, and then i have nested button in button (im using next.js, and it warn's me for that) or i need to put just button tag instead of component that renders it in TooltipTrigger

Current Behavior

https://github.com/radix-ui/primitives/assets/147377970/8ba62460-eb3a-46ca-8bee-8e45b714eb31

Expected behavior

Work with asChild property, where children is component that renders button

Reproducible example

CodeSandbox Template

Your environment

Software Name(s) Version
Radix Package(s) @radix-ui/react-tooltip ^1.0.7
React n/a 18.3.1
Browser Firefox Developer edition
Assistive tech
Node n/a 21.6.1
npm/yarn/pnpm pnpm 9.3.0
Operating System Windows 10 22H2
vladmoroz commented 1 week ago

In order for asChild to work, your component needs to forward the ref and the props to an element

izakfilmalter commented 1 week ago

I am running into the same issue with React 19. I have ref being passed to the component.

button.tsx

export interface ButtonProps
  extends ButtonHTMLAttributes<HTMLButtonElement>,
    VariantProps<typeof buttonVariants> {
  asChild?: boolean
  loading?: boolean
  ref?: Ref<HTMLButtonElement>
}

export const Button: FC<ButtonProps> = ({
  className,
  variant,
  size,
  asChild = false,
  loading = false,
  disabled = false,
  ref,
  ...props
}) => {
  const Comp = pipe(
    asChild,
    Boolean.match({ onFalse: () => 'button', onTrue: () => Slot }),
  )

  return (
    <Comp
      className={cn(buttonVariants({ variant, size }), className)}
      ref={ref}
      // eslint-disable-next-line @typescript-eslint/ban-ts-comment
      // @ts-ignore
      disabled={disabled || loading}
      {...props}
    />
  )
}

notificationsButton.tsx

    <Tooltip>
      <TooltipTrigger asChild>
        <Button variant={'secondary'} size={'icon'} className={'relative'}>
          <NotificationIcon className={'h-5 w-5'} />
        </Button>
      </TooltipTrigger>
      <TooltipContent>Notifications</TooltipContent>
    </Tooltip>