# HoverCard

- Page: https://jiguang132.com/resources/mantine/docs/hover-card
- Resource: Mantine Core (https://jiguang132.com/resources/mantine.md)
- All guides: https://jiguang132.com/resources/mantine/docs.md

Install: `npm install @mantine/core@9.7.1 @mantine/hooks@9.7.1`

## Version and compatibility

Pinned Mantine Core 9.7.1 requires React and React DOM `^19.2.0` and matching `@mantine/hooks@9.7.1`, from the installed npm package's peerDependencies. Do not force it into React 18 or another incompatible version. Explain upgrade impact and agree on a plan with the project owner; do not hide conflicts with --force/--legacy-peer-deps. The native Provider enables `theme.respectReducedMotion` and uses `forceColorScheme` for light/dark.

## Use case

Show contextual content around a hover target.

## Native props used by this example

These props are extracted from the local typechecked JSX and grouped by their owning native component. This is not an exhaustive prop list; see pinned source signatures and inheritance below.

This minimal example passes children only; no additional props are invented. Optional props are in the source reference.

## Interaction and state checks

Current scenarios: Default. Check actual behavior after selecting supported disabled/error/read-only scenarios; components without those native states do not receive invented universal props. Verify keyboard focus and exits, then connect changed values through the native callback signature.

## Business integration boundary

Demo content/state is local, without server persistence, authorization or fetching. A static display component is not a completed business workflow.

## Host setup

Install pinned @mantine/core and @mantine/hooks, import @mantine/core/styles.css at the entry and use MantineProvider. The example's theme/variant are JGuang-authored host props, not universal native component APIs; forceColorScheme synchronizes the app theme. Native implementation source is a reading reference: use npm exports rather than copying internal engines. This batch covers Core, not dates/charts/forms extension packages. Detailed upstream prose remains English.


## Runnable usage

```tsx
import { useState } from 'react';
import * as M from '@mantine/core';
import '@mantine/core/styles.css';


function ComponentPreview({ variant = 'Default' }: { variant?: string }) {
const content = <M.Text>Build something beautiful / 构建美好的界面</M.Text>;
return <M.HoverCard><M.HoverCard.Target><M.Button>Hover me</M.Button></M.HoverCard.Target><M.HoverCard.Dropdown>{content}</M.HoverCard.Dropdown></M.HoverCard>;
}
export default function Example({ variant = 'Default', theme = 'light' }: { variant?: string; theme?: 'light' | 'dark' }) {
return <M.MantineProvider forceColorScheme={theme} theme={{ respectReducedMotion: true }}><ComponentPreview variant={variant} /></M.MantineProvider>;
}

```


## Preview states

Default

The example uses the native Mantine API. For supported input demos, change the local variant to Disabled, Invalid or Read only; these are example labels, not new component props. Keep the documented data, controlled values, stores and compound children when adapting the example.



## Usage



## Delays

Set open and close delays in ms with the `openDelay` and `closeDelay` props:



## HoverCard delay group

Use the `HoverCard.Group` component to sync open and close delays of multiple `HoverCard` components:



## Activation events

The `events` prop determines which interactions open the dropdown. Fields that are not specified
keep their default values, for example `events={{ focus: false }}` disables focus activation
and leaves hover activation enabled:

<DataTable
  head={['Field', 'Default', 'Description']}
  data={[
    [<code>hover</code>, <code>true</code>, 'Dropdown is opened when the target is hovered with a mouse'],
    [<code>focus</code>, <code>true</code>, 'Dropdown is opened when the target is focused with the keyboard'],
    [
      <code>touch</code>,
      <code>false</code>,
      <>
        Dropdown is opened when the target is tapped on a touch device, requires <code>hover</code>{' '}
        to be enabled
      </>,
    ],
  ]}
/>

Focus activation uses [:focus-visible](https://developer.mozilla.org/en-US/docs/Web/CSS/:focus-visible)
semantics: the dropdown is opened when the target is focused with the keyboard, but not when it
is focused by a mouse click.

`touch` is disabled by default because there is no hover on touch devices – the first tap would
open the dropdown instead of activating the target. Enable it only if the target does not have its
own tap action. `touch` extends hover activation, it has no effect if `hover` is disabled.



## Keyboard interactions

<DataTable
  head={['Key', 'Description']}
  data={[
    ['Tab', <>Moves focus to the target, opens the dropdown if <code>events.focus</code> is enabled</>],
    ['Escape', <>Closes the dropdown, can be disabled with <code>{'closeOnEscape={false}'}</code></>],
  ]}
/>

The dropdown is also closed when the user presses outside of the target and the dropdown
(`pointerdown` event), set `closeOnClickOutside={false}` to disable this behavior. Note that the
`clickOutsideEvents` prop is not supported by `HoverCard`: outside press is always detected with
the `pointerdown` event.



## Interactive dropdown

By default, the dropdown is closed as soon as the pointer leaves the target: if there is a gap
between the target and the dropdown, or if the pointer travels diagonally over unrelated elements,
the dropdown closes before the pointer reaches it.

Set the `interactive` prop to keep the dropdown open while the pointer travels toward it. It is
required by [WCAG 1.4.13](https://www.w3.org/WAI/WCAG21/Understanding/content-on-hover-or-focus.html)
if the dropdown contains interactive content. Note that an interactive dropdown intercepts pointer
events of the content it overlaps:



## With interactive elements

`HoverCard` is displayed only when the mouse is over the target element or dropdown.
You can use anchors and buttons within dropdowns, using inputs is not recommended:



## Dropdown role

The `role` prop controls the accessible relation between the target and the dropdown:

<DataTable
  head={['Value', 'Target attributes', 'Dropdown attributes']}
  data={[
    [
      <>
        <code>dialog</code> (default)
      </>,
      <>
        <code>aria-haspopup="dialog"</code>, <code>aria-expanded</code>, <code>aria-controls</code>
      </>,
      <>
        <code>role="dialog"</code>, <code>aria-labelledby</code>
      </>,
    ],
    [<code>tooltip</code>, <code>aria-describedby</code>, <code>role="tooltip"</code>],
  ]}
/>

Use `role="tooltip"` if the dropdown contains only descriptive content – its content is then
announced by screen readers as the description of the target.

Keep the default `role="dialog"` if the dropdown contains headings, links, buttons or any other
content that is not a plain description of the target.




## Accessibility

`HoverCard` can be opened with a mouse and with the keyboard, and is announced by screen readers:

- The target is focusable if it is an interactive element (a button or a link). If the target is
  not interactive, add `tabIndex={0}` to it to make it reachable with the keyboard.
- Focusing the target with the keyboard opens the dropdown, `Escape` and a press outside of the
  target and the dropdown close it.
- `onDismiss` is called when the dropdown is closed with `Escape` key or with a press outside of
  the target and the dropdown.
- `aria-haspopup`, `aria-expanded`, `aria-controls` and `aria-describedby` attributes are managed
  by the component, see the [Dropdown role](#dropdown-role) section.
- The `returnFocus` prop is ignored while focus activation is enabled (`events.focus`, the
  default): focus is already on the target when the dropdown is opened with the keyboard, and
  returning it after the target was blurred would trap keyboard users on the target. `Escape`
  pressed inside the dropdown always returns focus to the target.

### Limitations

The dropdown is rendered in a portal at the end of `document.body`, it is not a part of the tab
order of the page. Keyboard users can open, read and dismiss the dropdown, but **cannot move focus
into it** – links and buttons inside the dropdown are not reachable with the keyboard.

If the dropdown contains interactive content, that content must also be available elsewhere on the
page. Do not use the `trapFocus` prop to work around this limitation: focus cannot be moved into
the dropdown in the first place, and trapping focus in a hover-triggered element strands keyboard
users.

With `withinPortal={false}` the dropdown is rendered next to the target and focus can be moved into
it with `Tab`, but moving focus out of the dropdown with `Tab` does not close it – the dropdown is
closed with `Escape`, with a press outside or when the pointer leaves the target.

Hover and focus activations do not coordinate: if the pointer leaves the target while the target is
focused with the keyboard, the dropdown is closed after `closeDelay` and is not reopened until the
target is blurred and focused again.


## Source-backed parameter reference

Implementation signatures and types are generated from the pinned local source. Optional props, native inherited types, union branches and never exclusions are preserved. A forwardRef implementation's ref is a React reference, not an additional business prop.


```ts
HoverCard(props: HoverCardProps)
```



```ts
export interface HoverCardEvents {
  /** Determines whether the dropdown should be opened when the target is hovered @default true */
  hover?: boolean;

  /** Determines whether the dropdown should be opened when the target is focused with the keyboard @default true */
  focus?: boolean;

  /** Determines whether the dropdown should be opened when the target is tapped on touch devices. Requires `hover` to be enabled @default false */
  touch?: boolean;
}

export interface HoverCardProps extends Omit<PopoverProps, 'opened' | 'onChange'> {
  /** Initial opened state */
  initiallyOpened?: boolean;

  /** Called when the dropdown is opened */
  onOpen?: () => void;

  /** Called when the dropdown is closed */
  onClose?: () => void;

  /**
   * Delay in ms before the dropdown opens after mouse enters the target.
   * Overridden by HoverCard.Group delay if used within a group.
   * @default 0
   */
  openDelay?: number;

  /**
   * Delay in ms before the dropdown closes after mouse leaves the target or dropdown.
   * Overridden by HoverCard.Group delay if used within a group.
   * @default 150
   */
  closeDelay?: number;

  /**
   * Determines which events open the dropdown. Fields that are not specified keep their default values.
   * @default { hover: true, focus: true, touch: false }
   */
  events?: HoverCardEvents;

  /**
   * If set, the dropdown stays open while the pointer travels from the target to the dropdown
   * and remains over it. Set it if the dropdown contains interactive content.
   * @default false
   */
  interactive?: boolean;

  /**
   * Accessible relation between the target and the dropdown. `dialog` sets `aria-haspopup`,
   * `aria-expanded` and `aria-controls` on the target, `tooltip` sets `aria-describedby` instead
   * and should be used if the dropdown contains only descriptive content.
   * @default 'dialog'
   */
  role?: 'dialog' | 'tooltip';

  /** Determines whether the dropdown should be closed when the user presses outside of the target and the dropdown @default true */
  closeOnClickOutside?: boolean;

  /** Not supported by `HoverCard`: outside press is always detected with the `pointerdown` event. Use `closeOnClickOutside` to disable it. */
  clickOutsideEvents?: string[];

  /**
   * Determines whether focus should be returned to the target when the dropdown closes.
   * Ignored when focus activation is enabled (`events.focus`, the default), otherwise moving
   * focus away from the target would return it and reopen the dropdown.
   * `Escape` pressed inside the dropdown always returns focus to the target.
   * @default false
   */
  returnFocus?: boolean;

  /** Called when the dropdown is closed with `Escape` key or with a press outside of the target and the dropdown */
  onDismiss?: () => void;
}
```


### Native and external types

External types remain defined by React or native dependencies, not manually expanded into guessed props. The installed version's TypeScript definitions are authoritative.


```ts
Omit<PopoverProps, 'opened' | 'onChange'>
PopoverProps
```

---

Index of all JGuang resources: https://jiguang132.com/llms.txt
