ui
ui copied to clipboard
Hovercard and Tooltip does not work on disabled compnent such as button
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?
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.
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
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!
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>
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
For those of you still wondering, I just don't use the
asChild
prop and add a classcursor-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.
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.
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>