Popover

Display popover section relative to given target element
Import

Usage

Popover is more complex and customizable alternative to Tooltip component.

import React, { useState } from 'react';
import { Popover, Text, Button, Image } from '@mantine/core';
function Demo() {
const [opened, setOpened] = useState(false);
return (
<Popover
opened={opened}
onClose={() => setOpened(false)}
target={<Button onClick={() => setOpened((o) => !o)}>Toggle popover</Button>}
bodyStyle={{ width: 200 }}
position="bottom"
withArrow
>
<div style={{ display: 'flex' }}>
<Image
src="./logo.svg"
width={30}
height={30}
style={{ minWidth: 30, marginRight: 15 }}
/>
<Text size="sm">Thanks for stopping by and checking Mantine, you are awesome!</Text>
</div>
</Popover>
);
}

Examples

Show on focus

This example uses onFocusCapture and onBlurCapture events on Popover component to determine if any element inside has focus:

Strong password should include letters in lower and uppercase, at least 1 number, at least 1 special symbol

With form

By default focus trap inside popover is active, you can place forms inside and focus will be kept inside popover:

BH
Bob Handsome
bob@handsome.inc

Show on hover

To show popover on hover add onMouseEnter and onMouseLeave handlers to element that should trigger popover. Note that in this case you have to disable focus trap with noFocusTrap prop:

Hover badge to see popover
import React, { useState } from 'react';
import { Popover, Badge, Image, Text } from '@mantine/core';
function Demo() {
const [opened, setOpened] = useState(false);
return (
<Popover
opened={opened}
onClose={() => setOpened(false)}
position="bottom"
placement="center"
withArrow
noFocusTrap
noEscape
transition="slide-up"
bodyStyle={{ width: 260, pointerEvents: 'none' }}
target={
<Badge onMouseEnter={() => setOpened(true)} onMouseLeave={() => setOpened(false)}>
Hover badge to see popover
</Badge>
}
>
<div style={{ display: 'flex' }}>
<Image
src="./logo.svg"
width={30}
height={30}
style={{ minWidth: 30, marginRight: 15 }}
/>
<Text size="sm">Thanks for stopping by and checking Mantine, you are awesome!</Text>
</div>
</Popover>
);
}

Position and placement

Popover position relative to target element is defined by:

  • position – popover side – top, bottom, right or left, defaults to top
  • placement – popover placement relative to position – start, center or end, defaults to center
  • gutter – space between popover and target element in px, defaults to 10px
<Popover position="bottom" placement="end" gutter={10} />

All positions and placement:

top-start
top-center
top-end
right-start
right-center
right-end
bottom-start
bottom-center
bottom-end
left-start
left-center
left-end

Control behavior

By default popover:

  • has focus trap
  • closes when escape key is pressed
  • closes when outside click is registered

Usually it is a good idea to turn these settings of if you show popover on focus or hover:

<Popover
noFocusTrap // -> disable focus trap
noEscape // -> disable escape key press handling
noClickOutside // -> disable outside click handling
/>

Close button and title

Popover includes optional close button and title:

  • set withCloseButton prop to show close button, add closeButtonLabel to set aria-label attribute on close button
  • set title prop to add title at the top of popover
<Popover title="Popover title" withCloseButton closeButtonLabel="Close popover" />

Control appearance

To change popover appearance use:

  • radius – applies border-radius from theme.radius
  • spacing – adds padding to all sides of popover from theme.spacing
  • shadow – add box-shadow from theme.shadows
Badge with popover
Radius
Spacing
Shadow
<Popover
opened
target={<Badge>Badge with popover</Badge>}
>
{/* children */}
</Popover>

For additional modifications of popover body styles use bodyClassName or bodyStyle props:

// Add inline styles to popover body
<Popover bodyStyle={{ width: 200, pointerEvents: 'none' }} />
// Or with className
<Popover bodyClassName="my-class-name" />

Initial focus

Popover uses use-focus-trap to manage focus. To specify initial focus element add data-autofocus attribute:

<Popover>
<input />
{/* Second input in modal will have initial focus */}
<input data-autofocus />
<input />
</Popover>

Server side rendering

By default Popover uses random id to connect title and body via aria- attributes. This will result in hydration mismatch if you use opened popover (closed popover do not require this step) during ssr. To avoid that set static id:

<Popover id="my-popover" opened />