Edit page

Popover

Popover displays additional information without interrupting user flow.

Basic Usage

To implement the Popover component, you need to import it first:

import { Popover, PopoverWrapper } from '@react-ui-org/react-ui';

And use it:

See API for all available options.

Placement

Available placements are: top, right, bottom, and left. Additionally, all basic placements can be aligned to the center (default, no suffix), start (e.g. top-start), or end (e.g. bottom-end). Check Popover API for the complete list of accepted values.

PopoverWrapper

PopoverWrapper is an optional wrapper to make positioning of Popover even easier.

By default, Popover is placed relative to the closest parent element with position: relative or position: absolute. Maybe you already have one of these in your CSS. PopoverWrapper is here for situations when you don't.

<PopoverWrapper>
<Button
aria-describedby={isPopoverOpen ? 'my-popover' : undefined}
label="Want to see a popover? Click me!"
onClick={() => setIsPopoverOpen(!isPopoverOpen)}
/>
{isPopoverOpen && <Popover id="my-popover">Hello there!</Popover>}
</PopoverWrapper>

How do you know you may need PopoverWrapper?

  • You are not rendering Popover in a React portal.
  • You are using Popover in a complex layout and it does not pop up where you need it.
  • You are using Floating UI with absolute positioning strategy (see Advanced Positioning below) and your Popover keeps to be misplaced.
  • You have no idea what CSS position is and just want to get it working.

To sum it up, usually you will need either PopoverWrapper around your content or position: [ relative | absolute ] somewhere in your CSS (but you never need both!). Nevertheless, in the simplest situations, like in a single-column page layout, you may not need either of these at all.

Head to PopoverWrapper API for all available options.

Advanced Positioning

While the basic setup can be sufficient in some scenarios, dropping a Popover usually won't be so easy. To handle all tricky situations and edge cases automatically, including smart position updates to ensure Popover visibility, we recommend to involve an external library designed specifically for this purpose.

ℹī¸ The following example is using external library Floating UI. To use Floating UI, install it first:

npm install --save @floating-ui/react-dom

And import it along with Popover, e.g.:

import {
useFloating,
autoUpdate,
flip,
} from '@floating-ui/react-dom';
import { Popover } from '@react-ui-org/react-ui';

As opposed to the basic setup, Popover will be placed according to its triggering component (reference), but still recognizing the closest parent element with position: relative or position: absolute if there is any.

Popover reacts on the ref option, necessary for advanced positioning: when ref is set, Popover resets its built-in positioning and relies on provided style.

👉 Please consult Floating UI documentation to understand how it works and to get an idea of all possible cases you may need to cover.

🖱 Try scrolling the example to see how Popover placement is updated.

API

Prop nameTypeDefaultRequiredDescription
childrennode—true

Popover content.

idstringundefinedfalse

ID of the root HTML element.

placement'top' │ 'top-start' │ 'top-end' │ 'right' │ 'right-start' │ 'right-end' │ 'bottom' │ 'bottom-start' │ 'bottom-end' │ 'left' │ 'left-start' │ 'left-end''bottom'false

Popover placement affects position of the arrow. Compatible with Floating UI API.

portalIdstringnullfalse

If set, popover is rendered in the React Portal with that ID.

refFunction │ { "current": "any" }undefinedfalse

Reference forwarded to the root div element.

PopoverWrapper API

Prop nameTypeDefaultRequiredDescription
childrennode—true

Popover reference and the Popover itself.

idstringundefinedfalse

ID of the root HTML element.

tagstring"div"false

HTML tag to render. Can be any valid HTML tag of your choice, usually a block-level element.

Theming

Custom PropertyDescription
--rui-Popover__widthPopover width
--rui-Popover__paddingPopover padding
--rui-Popover__border-widthBorder width
--rui-Popover__border-colorBorder color
--rui-Popover__border-radiusCorner radius
--rui-Popover__colorText color
--rui-Popover__background-colorBackground color
--rui-Popover__box-shadowPopover box shadow