- Published on
How to Create a Dialog with Tooltip That Doesn't Reopen When Dialog Closes Using ShadCN UI
- Authors
- Name
- Ripal & Zalak
Introduction
Managing interactions between tooltips and dialogs can be tricky, especially when using libraries like ShadCN UI or Radix UI. A common challenge arises when a tooltip unexpectedly reopens after its associated dialog is closed. This guide will walk you through the process of creating a seamless user experience where tooltips only appear on intentional hover and stay hidden after a dialog is closed.
Why Use ShadCN UI/Radix UI?
ShadCN UI and Radix UI provide accessible, highly customizable components for React applications. Their declarative API simplifies complex UI interactions, including tooltips and dialogs. However, these libraries’ default behaviors sometimes require customization to meet specific UX requirements.
The Problem
In the default setup, closing a dialog may inadvertently trigger the associated tooltip, causing it to reopen. This occurs due to event propagation and state mismanagement. The solution involves proper handling of state and avoiding nested triggers.
Key Objectives:
- Ensure the tooltip stays hidden when the dialog is closed.
- Reopen the tooltip only on intentional hover over the trigger.
Step-by-Step Solution
1. Install Dependencies
Ensure you have the required libraries installed:
npm install shadcn-ui radix-ui
2. Define the Component Structure
We will use a single state to manage the dialog and ensure proper synchronization between tooltip and dialog interactions.
import { useState } from 'react'
import { Tooltip, TooltipTrigger, TooltipContent, TooltipProvider } from 'shadcn-ui/tooltip'
import { Dialog, DialogTrigger, DialogContent } from 'shadcn-ui/dialog'
import { Button } from 'shadcn-ui/button'
const TooltipDialogExample = () => {
const [isDialogOpen, setIsDialogOpen] = useState(false)
const handleDialogOpenChange = (open: boolean) => {
setIsDialogOpen(open)
}
return (
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button
variant="ghost"
onClick={() => setIsDialogOpen(true)}
className="hover:bg-accent grid aspect-square h-9 w-9 place-items-center rounded-full p-0"
>
<span className="icon-placeholder">Icon</span>
<span className="sr-only">Open Dialog</span>
</Button>
</TooltipTrigger>
<TooltipContent>
<h3 className="text-base font-semibold">Dialog Trigger</h3>
<p>Click to open the dialog.</p>
</TooltipContent>
</Tooltip>
<Dialog open={isDialogOpen} onOpenChange={handleDialogOpenChange}>
<DialogContent>
<h2 className="text-xl font-bold">Dialog Content</h2>
<p>This is the dialog content area.</p>
<Button onClick={() => setIsDialogOpen(false)}>Close Dialog</Button>
</DialogContent>
</Dialog>
</TooltipProvider>
)
}
export default TooltipDialogExample
3. Key Improvements Explained
a) Avoid Nested Triggers
Instead of wrapping a DialogTrigger
inside a TooltipTrigger
, we use a single TooltipTrigger
to manage hover interactions. This simplifies event handling.
b) Single State Management
By using one state (isDialogOpen
), we avoid conflicts between tooltip and dialog states. This ensures predictable behavior when the dialog closes.
c) Control Tooltip Visibility
Tooltips naturally disappear when their trigger loses focus or hover. With proper state synchronization, the tooltip doesn’t reopen unless explicitly re-hovered.
4. Styling
ShadCN UI components integrate seamlessly with Tailwind CSS. Use the following example styles:
.button {
@apply rounded bg-blue-500 p-2 text-white hover:bg-blue-600;
}
.tooltip {
@apply rounded bg-gray-800 px-2 py-1 text-sm text-white shadow-lg;
}
.dialog {
@apply max-w-md rounded bg-white p-4 shadow-lg;
}
5. Testing
Scenarios to Test:
- Tooltip Hover: Ensure the tooltip only appears when hovering over the trigger.
- Dialog Open/Close: Verify the dialog opens on click and the tooltip doesn’t reopen when the dialog closes.
- Re-hover: Check that the tooltip reappears on hover after the dialog is closed.
Conclusion
By following the steps above, you can create a smooth and intuitive UI where tooltips and dialogs work harmoniously. This approach not only improves user experience but also leverages the powerful capabilities of ShadCN UI and Radix UI.