9.4 KiB
Hover Card
Allows sighted users to preview content available behind a link.
Import
Copyts
import { HoverCard } from "@kobalte/core/hover-card";
// or
import { Root, Trigger, ... } from "@kobalte/core/hover-card";
// or (deprecated)
import { HoverCard } from "@kobalte/core";
Copyts
import { HoverCard } from "@kobalte/core/hover-card";
// or
import { Root, Trigger, ... } from "@kobalte/core/hover-card";
// or (deprecated)
import { HoverCard } from "@kobalte/core";
Features
- Opens on hover only.
- Supports custom open and close delays.
- Optionally render a pointing arrow.
- Ignored by screen readers.
- Can be controlled or uncontrolled.
Anatomy
The hovercard consists of:
- HoverCard: The root container for a hovercard.
- HoverCard.Trigger: The link that opens the hovercard.
- HoverCard.Portal: Portals its children into the
bodywhen the hovercard is open. - HoverCard.Content: Contains the content to be rendered when the hovercard is open.
- HoverCard.Arrow: An optional arrow element to render alongside the hovercard.
Copytsx
<HoverCard>
<HoverCard.Trigger />
<HoverCard.Portal>
<HoverCard.Content>
<HoverCard.Arrow />
</HoverCard.Content>
</HoverCard.Portal>
</HoverCard>
Copytsx
<HoverCard>
<HoverCard.Trigger />
<HoverCard.Portal>
<HoverCard.Content>
<HoverCard.Arrow />
</HoverCard.Content>
</HoverCard.Portal>
</HoverCard>
Example
index.tsxstyle.css
Copytsx
import { HoverCard } from "@kobalte/core/hover-card";
import "./style.css";
function App() {
return (
<HoverCard>
<HoverCard.Trigger
class="hovercard__trigger"
href="https://twitter.com/mlfabien"
target="_blank"
>
@MLFabien
</HoverCard.Trigger>
<HoverCard.Portal>
<HoverCard.Content class="hovercard__content">
<HoverCard.Arrow />
<img
src="https://pbs.twimg.com/profile_images/1509139491671445507/pzWYjlYN_400x400.jpg"
alt="Fabien MARIE-LOUISE"
class="hovercard__avatar"
/>
<h2 class="hovercard__title">Fabien MARIE-LOUISE</h2>
<p class="hovercard__description">
Developer and UI Design enthusiast. Building UI related stuffs for @solid_js
</p>
</HoverCard.Content>
</HoverCard.Portal>
</HoverCard>
);
}
Copytsx
import { HoverCard } from "@kobalte/core/hover-card";
import "./style.css";
function App() {
return (
<HoverCard>
<HoverCard.Trigger
class="hovercard__trigger"
href="https://twitter.com/mlfabien"
target="_blank"
>
@MLFabien
</HoverCard.Trigger>
<HoverCard.Portal>
<HoverCard.Content class="hovercard__content">
<HoverCard.Arrow />
<img
src="https://pbs.twimg.com/profile_images/1509139491671445507/pzWYjlYN_400x400.jpg"
alt="Fabien MARIE-LOUISE"
class="hovercard__avatar"
/>
<h2 class="hovercard__title">Fabien MARIE-LOUISE</h2>
<p class="hovercard__description">
Developer and UI Design enthusiast. Building UI related stuffs for @solid_js
</p>
</HoverCard.Content>
</HoverCard.Portal>
</HoverCard>
);
}
Usage
Default open
An initial, uncontrolled open value can be provided using the defaultOpen prop.
Copytsx
<HoverCard defaultOpen>...</HoverCard>
Copytsx
<HoverCard defaultOpen>...</HoverCard>
Controlled open
The open prop can be used to make the open state controlled. The onOpenChange event is fired when the user pointer enter or leave the trigger, and receives the new value.
Copytsx
import { createSignal } from "solid-js";
function ControlledExample() {
const [open, setOpen] = createSignal(false);
return (
<HoverCard open={open()} onOpenChange={setOpen}>
...
</HoverCard>
);
}
Copytsx
import { createSignal } from "solid-js";
function ControlledExample() {
const [open, setOpen] = createSignal(false);
return (
<HoverCard open={open()} onOpenChange={setOpen}>
...
</HoverCard>
);
}
Origin-aware animations
We expose a CSS custom property --kb-hovercard-content-transform-origin which can be used to animate the content from its computed origin.
Copycss
/* style.css */
.hovercard__content {
transform-origin: var(--kb-hovercard-content-transform-origin);
animation: contentHide 250ms ease-in forwards;
}
.hovercard__content[data-expanded] {
animation: contentShow 250ms ease-out;
}
@keyframes contentShow {
from {
opacity: 0;
transform: scale(0.96);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes contentHide {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.96);
}
}
Copycss
/* style.css */
.hovercard__content {
transform-origin: var(--kb-hovercard-content-transform-origin);
animation: contentHide 250ms ease-in forwards;
}
.hovercard__content[data-expanded] {
animation: contentShow 250ms ease-out;
}
@keyframes contentShow {
from {
opacity: 0;
transform: scale(0.96);
}
to {
opacity: 1;
transform: scale(1);
}
}
@keyframes contentHide {
from {
opacity: 1;
transform: scale(1);
}
to {
opacity: 0;
transform: scale(0.96);
}
}
API Reference
HoverCard
HoverCard is equivalent to the Root import from @kobalte/core/hover-card (and deprecated HoverCard.Root).
| Prop | Description |
|---|---|
| open | booleanThe controlled open state of the hovercard. |
| defaultOpen | booleanThe default open state when initially rendered. Useful when you do not need to control the open state. |
| onOpenChange | (open: boolean) => voidEvent handler called when the open state of the hovercard changes. |
| openDelay | numberThe duration from when the mouse enters the trigger until the hovercard opens. |
| closeDelay | numberThe duration from when the mouse leaves the trigger or content until the hovercard closes. |
| ignoreSafeArea | booleanWhether to close the hovercard even if the user cursor is inside the safe area between the trigger and hovercard. |
| id | stringA unique identifier for the component. The id is used to generate id attributes for nested components. If no id prop is provided, a generated id will be used. |
| forceMount | booleanUsed to force mounting the hovercard (portal and content) when more control is needed. Useful when controlling animation with SolidJS animation libraries. |
HoverCard also accepts the following props to customize the placement of the HoverCard.Content.
| Prop | Description |
|---|---|
| getAnchorRect | `(anchor?: HTMLElement) => AnchorRect |
| placement | PlacementThe placement of the hovercard. |
| gutter | numberThe distance between the hovercard and the trigger element. By default, it's 0 plus half of the arrow offset, if it exists. |
| shift | numberThe skidding of the hovercard along the trigger element. |
| flip | `boolean |
| slide | booleanWhether the hovercard should slide when it overflows. |
| overlap | booleanWhether the hovercard can overlap the trigger element when it overflows. |
| sameWidth | booleanWhether the hovercard should have the same width as the trigger element. This will be exposed to CSS as --kb-popper-anchor-width. |
| fitViewport | booleanWhether the hovercard should fit the viewport. If this is set to true, the hovercard content will have maxWidth and maxHeight set to the viewport size. This will be exposed to CSS as --kb-popper-available-width and --kb-popper-available-height. |
| hideWhenDetached | booleanWhether to hide the hovercard when the trigger element becomes occluded. |
| detachedPadding | numberThe minimum padding in order to consider the trigger element occluded. |
| arrowPadding | numberThe minimum padding between the arrow and the hovercard corner. |
| overflowPadding | numberThe minimum padding between the hovercard and the viewport edge. This will be exposed to CSS as --kb-popper-overflow-padding. |
HoverCard.Content
The popper positioner will copy the same z-index as the HoverCard.Content.
HoverCard.Trigger
HoverCard.Trigger consists of Link.
| Data attribute | Description |
|---|---|
| data-expanded | Present when the hovercard is open. |
| data-closed | Present when the hovercard is close. |
HoverCard.Content share the same data-attributes.
Rendered elements
| Component | Default rendered element |
|---|---|
HoverCard |
none |
HoverCard.Trigger |
a |
HoverCard.Portal |
Portal |
HoverCard.Content |
div |
HoverCard.Arrow |
div |
Accessibility
Keyboard Interactions
The hover card is intended for mouse users only so will not respond to keyboard navigation.
Previous←File FieldNextImage→