AdminKitDocs
Components

React Bootstrap Popovers

A React Bootstrap popover with a title and body: opens on click next to its element, closes on Escape or a click outside, positioned by Floating UI.

Pro

This component is only available in AdminKit PRO. Learn more.

A popover holds more than a tooltip: a small overlay with an optional title and a body, opened with a click. Use it for a short explanation next to a setting, or for details the user asks to see.

Popover is a React component that wraps the element that opens it. Floating UI places the overlay and Bootstrap's CSS styles it, so there is no Bootstrap JavaScript, Popper or react-bootstrap involved. Popovers are part of the PRO version of AdminKit for React.

A click on the element opens the popover to its right. It closes on a second click, on Escape and on a click outside both the element and the popover. The popover renders in a portal on document.body.

Example

import { Popover } from "@/components/bootstrap/overlay";

export function DeleteHint() {
  return (
    <Popover title="Delete project" content="Archived projects can be deleted from Settings.">
      <button type="button" className="btn btn-danger">Click to toggle popover</button>
    </Popover>
  );
}

Props

PropTypeDefaultDescription
titleReactNodeThe .popover-header, an h3; no header without it
contentReactNodeThe .popover-body
placement"top" | "bottom" | "left" | "right""right"The side of the element it appears on
trigger("hover" | "focus" | "click")[]["click"]The events that open it
childrenReactElementOne element that opens the popover

Popover clones its child to add a ref, the trigger handlers and aria-describedby. So the child is one element: an HTML element, or a component that passes ref and the other props on to one. The child's own handlers still run. With the click trigger, the popover prevents the click's default action, so a link as the child does not navigate.

The component is in src/components/bootstrap/overlay.tsx, together with Tooltip.

Four directions

Put the popover where it covers the least: placement picks the side. Without room there, the popover flips to the opposite side. It stays 8px from the edges of the window.

<Popover title="Popover on top" content="Shown above the button." placement="top">
  <button type="button" className="btn btn-secondary me-2 mb-2">Popover on top</button>
</Popover>
<Popover title="Popover on bottom" content="Shown below the button." placement="bottom">
  <button type="button" className="btn btn-secondary me-2 mb-2">Popover on bottom</button>
</Popover>
<Popover title="Popover on left" content="Shown to the left of the button." placement="left">
  <button type="button" className="btn btn-secondary me-2 mb-2">Popover on left</button>
</Popover>
<Popover title="Popover on right" content="Shown to the right of the button." placement="right">
  <button type="button" className="btn btn-secondary me-2 mb-2">Popover on right</button>
</Popover>

Hover and focus

Sometimes a popover should open without a click, as a tooltip does. trigger={["hover", "focus"]} opens it while the pointer is over the element or while the element has the focus. Use it to explain a disabled button. The button gets no events, so the popover goes on a focusable span around it.

<Popover
  title="Read only"
  content="Ask an owner for edit access."
  trigger={["hover", "focus"]}
>
  <span className="d-inline-block" tabIndex={0}>
    <button type="button" className="btn btn-primary" disabled>Edit</button>
  </span>
</Popover>

Accessibility

  • The popover has role="tooltip". While it is open, the element has aria-describedby with the popover's id, so screen readers read the popover's text with the element.
  • The focus stays on the element when the popover opens, and the popover sits at the end of document.body, far from the element in the Tab order. Keep the content to text. For links, buttons or form fields, use a dropdown or a modal.
  • Escape closes the popover. Open it from a button, or an element with tabIndex={0}, so keyboard users can reach it.

Last updated on

On this page