ui icon indicating copy to clipboard operation
ui copied to clipboard

Hovercard and Tooltip does not work on disabled compnent such as button

Open cometyang opened this issue 1 year ago • 9 comments

Is this expected behavior? In some scenario, it might be useful to provide tool tip to explain why it is disabled. Can the hovercard configure to work for disabled component?

cometyang avatar Jul 25 '23 00:07 cometyang

Came here to report this as well. Particularly with the Button component.

It works when I disable the asChild directive, from this

<TooltipTrigger asChild>
  <Button disabled>Import</Button>
</TooltipTrigger>

to this:

<TooltipTrigger>
  <Button disabled>Import</Button>
</TooltipTrigger>

But then, cursor: pointer gets activated and you can actually click the button, even though it's disabled. And when you click, the tooltip disappears.

nickdotht avatar Aug 22 '23 21:08 nickdotht

This is the same behavior as the underlying Radix UI library. Radix's recommendation, applied to shadcn, for showing a Tooltip on a disable button is the following:

  <Tooltip>
    <TooltipTrigger asChild>
      <span tabIndex={0}>
        <Button disabled>Import</Button>
      </span>
    </TooltipTrigger>
    <TooltipContent>
      <p>You can't do that yet.</p>
    </TooltipContent>
  </Tooltip>

I'd imagine this is probably an intended side effect, vs being a bug.

Source: https://www.radix-ui.com/primitives/docs/components/tooltip#displaying-a-tooltip-from-a-disabled-button

zknicker avatar Aug 31 '23 21:08 zknicker

Just an update!! RadixUI no longer recommends the above solution!! https://github.com/radix-ui/website/pull/714 What would be the recommendation now? My ShadCN button still does not show tooltip when disabled!

hirenr avatar Feb 28 '24 07:02 hirenr

For those of you still wondering, I just don't use the asChild prop and add a class cursor-not-allowed to the trigger.

<TooltipProvider>
  <Tooltip>
    <TooltipTrigger className="cursor-not-allowed self-end">
      <Button disabled>Import</Button>
    </TooltipTrigger>
    <TooltipContent>
      No allowed
    </TooltipContent>
  </Tooltip>
</TooltipProvider>

TimurKr avatar Mar 22 '24 21:03 TimurKr

I used TooltipHint on a DataTable column to use Tooltip to display a hint when the user hovered over it. This component is used to display a hint when the user hovers over a column in the DataTable. If text is empty, it returns the children as is. Displaying a Tooltip is not limited to the Button, but can be done by other components as well. There is no need to pass "disabled".

import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "@/components/ui/tooltip";
import type { ReactNode } from "react";

interface Props {
  children: ReactNode;
  text: string;
  side?: "top" | "right" | "bottom" | "left";
}

export const TooltipHint = ({ children, text, side }: Props) => {
  if (!text) return <>{children}</>;

  return (
    <TooltipProvider>
      <Tooltip>
        <TooltipTrigger asChild>{children}</TooltipTrigger>
        <TooltipContent side={side}>{text}</TooltipContent>
      </Tooltip>
    </TooltipProvider>
  );
};

reference: https://www.radix-ui.com/primitives/docs/components/tooltip#custom-apis

yuyakinjo avatar Apr 08 '24 04:04 yuyakinjo

For those of you still wondering, I just don't use the asChild prop and add a class cursor-not-allowed to the trigger.

<TooltipProvider>
  <Tooltip>
    <TooltipTrigger className="cursor-not-allowed self-end">
      <Button disabled>Import</Button>
    </TooltipTrigger>
    <TooltipContent>
      No allowed
    </TooltipContent>
  </Tooltip>
</TooltipProvider>

@TimurKr This will render 2 nested buttons, not a valid html.

thisisankur0 avatar May 08 '24 15:05 thisisankur0

I guess you are right @thisisankur0, but this seems like not a big deal to me. If you really want it to be perfect, how about adding asChild in the button component and adding span as direct child?


<TooltipProvider>
  <Tooltip>
    <TooltipTrigger className="cursor-not-allowed self-end">
      <Button disabled asChild><span>Import</span></Button>
    </TooltipTrigger>
    <TooltipContent>
      No allowed
    </TooltipContent>
  </Tooltip>
</TooltipProvider>

Would that work? This way there aren't 2 button, but I haven't tested if it would work.

TimurKr avatar May 09 '24 08:05 TimurKr

Yup, much better @TimurKr. I came up with this solution and it seems to work well. Basically overriding the pointer-event-none style, seems to work as well.

<TooltipProvider>
  <Tooltip>
    <TooltipTrigger asChild className="disabled:pointer-event-auto self-end">
      <Button disabled>Import</Button>
    </TooltipTrigger>
    <TooltipContent>
      No allowed
    </TooltipContent>
  </Tooltip>
</TooltipProvider>

thisisankur0 avatar May 09 '24 13:05 thisisankur0