Skip to main content

Hover Card

An hover card allows sighted users to preview content available behind a link

Twitter
Properties

Features

  • Customize side, alignment, offsets
  • Optionally render a pointing arrow
  • Supports custom open and close delays
  • Opens on hover only
  • Ignored by screen readers

Installation

To use the hover card machine in your project, run the following command in your command line:

npm install @zag-js/hover-card @zag-js/vue # or yarn add @zag-js/hover-card @zag-js/vue

Anatomy

To set up the hover card correctly, you'll need to understand its anatomy and how we name its parts.

Each part includes a data-part attribute to help identify them in the DOM.

Usage

First, import the hover card package into your project

import * as hoverCard from "@zag-js/hover-card"

The hover card package exports two key functions:

  • machine — The state machine logic for the hover card widget.
  • connect — The function that translates the machine's state to JSX attributes and event handlers.

Next, import the required hooks and functions for your framework and use the hover-card machine in your project 🔥

<script setup> import * as hoverCard from "@zag-js/hover-card" import { normalizeProps, useMachine } from "@zag-js/vue" import { computed, Teleport } from "vue" const service = useMachine(hoverCard.machine, { id: "1" }) const api = computed(() => hoverCard.connect(service, normalizeProps)) </script> <template> <a href="https://twitter.com/zag_js" target="_blank" v-bind="api.getTriggerProps()" > Twitter </a> <Teleport to="body" v-if="api.open"> <div v-bind="api.getPositionerProps()"> <div v-bind="api.getContentProps()"> <div v-bind="api.getArrowProps()"> <div v-bind="api.getArrowTipProps()" /> </div> Twitter Preview </div> </div> </Teleport> </template>

Setting the initial state

To make an hover card open by default, set the defaultOpen property to true

const service = useMachine(hoverCard.machine, { defaultOpen: true, })

Listening for open state changes

When the hover card is opened or closed, the onOpenChange callback is invoked.

const service = useMachine(hoverCard.machine, { onOpenChange(details) { // details => { open: boolean } console.log("hovercard is:", details.open ? "opened" : "closed") }, })

Styling guide

Earlier, we mentioned that each hover card part has a data-part attribute added to them to select and style them in the DOM.

[data-part="trigger"] { /* styles for trigger */ } [data-part="content"] { /* styles for content */ }

Open and closed state

The hover card exposes a data-state attribute that can be used to style the hover card based on its open-close state.

[data-part="trigger"][data-state="open|closed"] { /* styles for open or closed state */ } [data-part="content"][data-state="open|closed"] { /* styles for open or closed state */ }

Arrow

Zag exposes some variable that can be used to style the arrow.

[data-part="arrow"] { /* styles for arrow */ --arrow-background: white; --arrow-size: 8px; }
[data-part="content"] { /* styles for content */ }

Methods and Properties

Machine Context

The hover card machine exposes the following context properties:

  • idsPartial<{ trigger: string; content: string; positioner: string; arrow: string; }>The ids of the elements in the popover. Useful for composition.
  • onOpenChange(details: OpenChangeDetails) => voidFunction called when the hover card opens or closes.
  • openDelaynumberThe duration from when the mouse enters the trigger until the hover card opens.
  • closeDelaynumberThe duration from when the mouse leaves the trigger or content until the hover card closes.
  • openbooleanThe controlled open state of the hover card
  • defaultOpenbooleanThe initial open state of the hover card when rendered. Use when you don't need to control the open state of the hover card.
  • positioningPositioningOptionsThe user provided options used to position the popover content
  • dir"ltr" | "rtl"The document's text/writing direction.
  • idstringThe unique identifier of the machine.
  • getRootNode() => ShadowRoot | Node | DocumentA root node to correctly resolve document in custom environments. E.x.: Iframes, Electron.
  • onPointerDownOutside(event: PointerDownOutsideEvent) => voidFunction called when the pointer is pressed down outside the component
  • onFocusOutside(event: FocusOutsideEvent) => voidFunction called when the focus is moved outside the component
  • onInteractOutside(event: InteractOutsideEvent) => voidFunction called when an interaction happens outside the component

Machine API

The hover card api exposes the following methods:

  • openbooleanWhether the hover card is open
  • setOpen(open: boolean) => voidFunction to open the hover card
  • reposition(options?: Partial<PositioningOptions>) => voidFunction to reposition the popover

Data Attributes

Trigger
data-scope
hover-card
data-part
trigger
data-placement
The placement of the trigger
data-state
"open" | "closed"
Content
data-scope
hover-card
data-part
content
data-state
"open" | "closed"
data-placement
The placement of the content

Accessibility

Keyboard Interactions

The hover card is intended for mouse users only so will not respond to keyboard navigation.

Edit this page on GitHub