Hover Card
For sighted users to preview content available behind a link.
<%= render Shadcn::HoverCardComponent.new do |card| %>
<% card.with_trigger do %>
<span class="underline cursor-pointer">Hover over me</span>
<% end %>
<% card.with_card_content do %>
<p class="text-sm">This is the hover card content.</p>
<% end %>
<% end %>
Installation
Add the component to your project:
rails generate shadcn:add hover_card
Usage
<%= render Shadcn::HoverCardComponent.new do |card| %>
<% card.with_trigger do %>
<span class="underline cursor-pointer">Hover over me</span>
<% end %>
<% card.with_card_content do %>
<p class="text-sm">This is the hover card content.</p>
<% end %>
<% end %>
Examples
Basic
A simple hover card with text content.
<%= render Shadcn::HoverCardComponent.new do |card| %>
<% card.with_trigger do %>
<span class="underline cursor-pointer">Hover over me</span>
<% end %>
<% card.with_card_content do %>
<p class="text-sm">This is the hover card content.</p>
<% end %>
<% end %>
User Profile Preview
Display user information on hover, commonly used for social media style mentions.
<%= render Shadcn::HoverCardComponent.new do |card| %>
<% card.with_trigger do %>
<a href="#" class="underline">@nextjs</a>
<% end %>
<% card.with_card_content do %>
<div class="flex justify-between space-x-4">
<%= render Shadcn::AvatarComponent.new(src: "https://github.com/vercel.png", alt: "@nextjs", fallback: "VR") %>
<div class="space-y-1">
<h4 class="text-sm font-semibold">@nextjs</h4>
<p class="text-sm">The React Framework - created and maintained by @vercel.</p>
<div class="flex items-center pt-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1 opacity-70" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clip-rule="evenodd" />
</svg>
<span class="text-xs text-muted-foreground">Joined December 2021</span>
</div>
</div>
</div>
<% end %>
<% end %>
Link Preview
Show a preview of external links on hover.
<%= render Shadcn::HoverCardComponent.new do |card| %>
<% card.with_trigger do %>
<a href="https://github.com/rails/rails" class="text-primary hover:underline">
Ruby on Rails
</a>
<% end %>
<% card.with_card_content do %>
<div class="space-y-2">
<h4 class="text-sm font-semibold">Ruby on Rails</h4>
<p class="text-sm text-muted-foreground">
A web-application framework that includes everything needed to create
database-backed web applications according to the Model-View-Controller (MVC) pattern.
</p>
<div class="flex items-center pt-2">
<span class="text-xs text-muted-foreground">github.com/rails/rails</span>
</div>
</div>
<% end %>
<% end %>
Custom Delays
Customize the delay before the card opens and closes. Useful for adjusting the hover sensitivity.
<%= render Shadcn::HoverCardComponent.new(open_delay: 200, close_delay: 100) do |card| %>
<% card.with_trigger do %>
<span class="underline cursor-pointer">Quick hover (200ms open, 100ms close)</span>
<% end %>
<% card.with_card_content do %>
<p class="text-sm">This card appears faster and closes quicker.</p>
<% end %>
<% end %>
Positioning
Control where the hover card appears relative to the trigger using the side and align options.
<div class="flex gap-4 flex-wrap">
<%= render Shadcn::HoverCardComponent.new do |card| %>
<% card.with_trigger do %>
<%= render Shadcn::ButtonComponent.new(variant: :outline) { "Top" } %>
<% end %>
<% card.with_card_content(side: :top) do %>
<p class="text-sm">Appears on top</p>
<% end %>
<% end %>
<%= render Shadcn::HoverCardComponent.new do |card| %>
<% card.with_trigger do %>
<%= render Shadcn::ButtonComponent.new(variant: :outline) { "Right" } %>
<% end %>
<% card.with_card_content(side: :right) do %>
<p class="text-sm">Appears on right</p>
<% end %>
<% end %>
<%= render Shadcn::HoverCardComponent.new do |card| %>
<% card.with_trigger do %>
<%= render Shadcn::ButtonComponent.new(variant: :outline) { "Bottom" } %>
<% end %>
<% card.with_card_content(side: :bottom) do %>
<p class="text-sm">Appears on bottom</p>
<% end %>
<% end %>
<%= render Shadcn::HoverCardComponent.new do |card| %>
<% card.with_trigger do %>
<%= render Shadcn::ButtonComponent.new(variant: :outline) { "Left" } %>
<% end %>
<% card.with_card_content(side: :left) do %>
<p class="text-sm">Appears on left</p>
<% end %>
<% end %>
</div>
Top Position
<%= render Shadcn::HoverCard.new do |card| %>
<% card.with_trigger do %>
<%= render Shadcn::Button.new(variant: :outline) { "Top" } %>
<% end %>
<% card.with_card_content(side: :top) do %>
<p class="text-sm">Appears on top</p>
<% end %>
<% end %>
Custom Delay
<%= render Shadcn::HoverCard.new(open_delay: 200, close_delay: 100) do |card| %>
<% card.with_trigger do %>
<span class="underline cursor-pointer">Quick hover (200ms open, 100ms close)</span>
<% end %>
<% card.with_card_content do %>
<p class="text-sm">This card appears faster and closes quicker.</p>
<% end %>
<% end %>
With Avatar
<%= render Shadcn::HoverCard.new do |card| %>
<% card.with_trigger do %>
<a href="#" class="underline">@nextjs</a>
<% end %>
<% card.with_card_content do %>
<div class="flex justify-between space-x-4">
<%= render Shadcn::Avatar.new(src: "https://github.com/vercel.png", alt: "@nextjs", fallback: "VR") %>
<div class="space-y-1">
<h4 class="text-sm font-semibold">@nextjs</h4>
<p class="text-sm">The React Framework - created and maintained by @vercel.</p>
<div class="flex items-center pt-2">
<svg xmlns="http://www.w3.org/2000/svg" class="h-4 w-4 mr-1 opacity-70" viewBox="0 0 20 20" fill="currentColor">
<path fill-rule="evenodd" d="M6 2a1 1 0 00-1 1v1H4a2 2 0 00-2 2v10a2 2 0 002 2h12a2 2 0 002-2V6a2 2 0 00-2-2h-1V3a1 1 0 10-2 0v1H7V3a1 1 0 00-1-1zm0 5a1 1 0 000 2h8a1 1 0 100-2H6z" clip-rule="evenodd" />
</svg>
<span class="text-xs text-muted-foreground">Joined December 2021</span>
</div>
</div>
</div>
<% end %>
<% end %>
API Reference
HoverCardComponent
| Prop | Type | Default | Description |
|---|---|---|---|
| open_delay |
Integer
|
700
|
Delay in milliseconds before the card opens on hover |
| close_delay |
Integer
|
300
|
Delay in milliseconds before the card closes after mouse leaves |
Slots
| Slot | Props | Description |
|---|---|---|
| with_trigger | - | The element that triggers the hover card (link, button, etc.) |
| with_card_content |
side:,
align:
|
The content to display in the hover card |
HoverCardContentComponent
| Prop | Type | Default | Description |
|---|---|---|---|
| side |
Symbol
|
:bottom
|
Position of the card relative to trigger: :top, :right, :bottom, :left |
| align |
Symbol
|
:center
|
Alignment of the card: :start, :center, :end |
Stimulus Controller
This component requires JavaScript. The Stimulus controller shadcn--hover-card provides interactivity.
Manages hover card visibility with configurable delays for opening and closing. Handles mouse and keyboard events for accessibility.
Installation
Add to your config/importmap.rb:
pin "shadcn", to: "index.esm.js"
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails-stimulus
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails-stimulus"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
yarn add shadcn-rails-stimulus
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails-stimulus"
const application = Application.start()
registerShadcnControllers(application)
Install the package:
npm install shadcn-rails-stimulus
Then in your app/javascript/controllers/index.js:
import { Application } from "@hotwired/stimulus"
import { registerShadcnControllers } from "shadcn-rails-stimulus"
const application = Application.start()
registerShadcnControllers(application)
Or import just this controller:
import HoverCardController from "shadcn-rails-stimulus/controllers/hover_card_controller"
application.register("shadcn--hover-card", HoverCardController)
Targets
| Name | Description |
|---|---|
| trigger | The element that triggers the hover card to appear |
| content | The hover card content container |
Values
| Name | Type | Default | Description |
|---|---|---|---|
| openDelay | Number |
700
|
Delay in milliseconds before opening |
| closeDelay | Number |
300
|
Delay in milliseconds before closing |
Actions
| Action | Description |
|---|---|
| open | Opens the hover card immediately |
| close | Closes the hover card immediately |
| scheduleOpen | Schedules the card to open after openDelay |
| scheduleClose | Schedules the card to close after closeDelay |
TypeScript
Type definitions are included. Import types as needed:
import type { HoverCardController } from "shadcn-rails-stimulus"
Accessibility
- Uses
role="tooltip"for proper screen reader announcement - Responds to both mouse hover and keyboard focus events
- Content appears on hover and focus, disappears on blur and mouse leave
- Configurable delays prevent accidental triggers from brief mouse movements
- Mouse can move over the card content without it closing
- For sighted users only - does not provide accessible alternative for screen reader users
- Consider providing the same information through other means for non-sighted users
On This Page