Popover
Popover is a non-modal dialog that floats around a trigger. It is used to display contextual information to the user, and should be paired with a clickable trigger element.
Popover is built on top of the Popper.js library.
Import#
Popover: The wrapper that provides props, state, and context to its children.PopoverTrigger: Used to wrap the reference (or trigger) element.PopoverContent: The popover itself.PopoverHeader: The header of the popover.PopoverBody: The body of the popover.PopoverArrow: A visual arrow that points to the reference (or trigger).PopoverCloseButton: A button to close the popover.
import {Popover,PopoverTrigger,PopoverContent,PopoverHeader,PopoverBody,PopoverFooter,PopoverArrow,PopoverCloseButton,} from "@chakra-ui/react"
Basic Usage#
When using this component, ensure the children passed to PopoverTrigger is
focusable. Users can tab to it using their keyboard, and it can take a ref. It
is critical for accessiblity.
A11y: When Popover opens, focus is sent to
PopoverContent. When it closes, focus is returned to the trigger.
Rendering the Popover in a Portal#
By default, the Popover doesn't render in a Portal. To make them display in a
portal, wrap the PopoverContent in a Portal
You might need to Inspect Element to see this in action. Notice that
PopoverContentis rendered as a child of<body>
Focus an element when Popover opens#
By default, focus is to sent to PopoverContent when it opens. Pass the
initialFocusRef prop to send focus to a specific element instead.
Trapping Focus within Popover#
If the popover contains a form, you might need to trap focus within the popover and close it when the user fills the form and hits "save".
You can leverage
react-focus-lock to trap focus
within the PopoverContent.
Controlled Usage#
You can control the opening and closing of the popover by passing the isOpen,
and onClose props.
Sometimes you might need to set the returnFocusOnClose prop to false to
prevent popver from returning focus to PopoverTrigger's children.
Accessing Internal state#
Chakra provides access to two internal details: isOpen and onClose. Use the
render prop pattern to gain access to them.
Customizing the Popover#
Chakra exports all the components you need to customize the look and feel of the popover. You can change the background, arrow size, box shadow and so on.
Popover Placements#
Since popover is powered by PopperJS, you can change the placement of the
popover by passing the placement prop. See the props for the
possible placement values.
Even though you specified the placement, Popover will try to reposition itself in the event that available space at the specified placement isn't enough.
Lazily mounting Popover#
By default, the Popover component renders children of PopoverContent to the
DOM, meaning that invisible popover contents are still rendered but are hidden
by styles.
If you want to defer rendering of popover content until that Popover is
opened, you can use the isLazy prop. This is useful if your PopoverContent
needs to be extra performant, or make network calls on mount that should only
happen when the component is displayed.
Accessiblity#
When you see the word "trigger", it is referring to the
childrenofPopoverTrigger
Keyboard and Focus#
- When the popover is opened, focus is moved to the
PopoverContent. If theinitialFocusRefis set, then focus moves to the element with thatref. - When the popover is closed, focus returns to the trigger. If you set
returnFocusOnClosetofalse, focus will not return. - If trigger is set to
hover:- Focusing on or mousing over the trigger will open the popover.
- Blurring or mousing out of the trigger will close the popover. If you move
your mouse into the
PopoverContent, it'll remain visible.
- If trigger is set to
click:- Clicking the trigger or using the
SpaceorEnterwhen focus is on the trigger will open the popover. - Clicking the trigger again will close the popover.
- Clicking the trigger or using the
- Hitting the
Esckey while the popover is open and focus is within thePopoverContent, will close the popover. If you setcloseOnEsctofalse, it will not close. - Clicking outside or blurring out of the
PopoverContentcloses the popover. If you setcloseOnBlurtofalse, it will not close.
ARIA Attributes#
- If the trigger is set to
click, thePopoverContentelement has role set todialog. If the trigger is set tohover, thePopoverContenthasroleset totooltip. - The
PopoverContenthasaria-labelledbyset to theidof thePopoverHeader. - The
PopoverContenthasaria-describedbyset to theidof thePopoverBody. - The
PopoverContenthasaria-hiddenset totrueorfalsedepending on the open/closed state of the popover. - The trigger has
aria-haspopupset totrueto denote that it triggers a popover. - The trigger has
aria-controlsset to theidof thePopoverContentto associate the popover and the trigger. - The trigger has
aria-expandedset totrueorfalsedepending on the open/closed state of the popover.
Props#
Popover Props#
| Name | Type | Description | Default |
|---|---|---|---|
| arrowPadding | number | The padding required to prevent the arrow from reaching the very edge of the popper. | 8 |
| arrowShadowColor | string | The `box-shadow` of the popover arrow | - |
| arrowSize | number | The size of the popover arrow | - |
| autoFocus | boolean | If `true`, focus will be transferred to the first interactive element when the popover opens | - |
| boundary | HTMLElement | "clippingParents" | "scrollParent" | The boundary area for the popper. Used within the `preventOverflow` modifier | "clippingParents" |
| children | string | number | boolean | {} | ReactElement<any, string | ((props: any) => ReactElement<any, string | ... | (new (props: any) => Component<any, any, any>)> | null) | (new (props: any) => Component<...>)> | ... 49 more ... | The content of the popover. It is usually the `PopoverTrigger`, and `PopoverContent` | - |
| closeDelay | number | - | |
| closeOnBlur | boolean | If `true`, the popover will close when you blur out it by clicking outside or tabbing out | - |
| closeOnEsc | boolean | If `true`, the popover will close when you hit the `Esc` key | - |
| colorScheme | "blue" | "cyan" | "gray" | "green" | "orange" | "pink" | "purple" | "red" | "teal" | "yellow" | "whiteAlpha" | "blackAlpha" | "linkedin" | "facebook" | "messenger" | "whatsapp" | "twitter" | "telegram" | Color Schemes for Popover are not implemented in the default theme. You can extend the theme to implement them. | - |
| defaultIsOpen | boolean | If `true`, the popover will be initially opened. | - |
| eventListeners | boolean | { scroll?: boolean; resize?: boolean | undefined; } | undefined | If provided, determines whether the popper will reposition itself on `scroll` and `resize` of the window. | - |
| flip | boolean | If `true`, the popper will change its placement and flip when it's about to overflow its boundary area. | true |
| gutter | number | The distance or margin between the reference and popper. It is used internally to create an `offset` modifier. NB: If you define `offset` prop, it'll override the gutter. | 8 |
| id | string | The html `id` attribute of the popover. If not provided, we generate a unique id. This `id` is also used to auto-generate the `aria-labelledby` and `aria-decribedby` attributes that points to the `PopoverHeader` and `PopoverBody` | - |
| initialFocusRef | RefObject<FocusableElement> | The `ref` of the element that should receive focus when the popover opens. | - |
| isLazy | boolean | Performance 🚀: If `true`, the PopoverContent rendering will be deferred until the popover is open. | - |
| isOpen | boolean | If `true`, the popover will be opened in controlled mode. | - |
| matchWidth | boolean | If `true`, the popper will match the width of the reference at all times. It's useful for `autocomplete`, `date-picker` and `select` patterns. | - |
| modifiers | Partial<Modifier<string, any>>[] | Array of popper.js modifiers. Check the docs to see the list of possible modifiers you can pass. @see Docs https://popper.js.org/docs/v2/modifiers/ | - |
| offset | [crossAxis: number, mainAxis: number] | The main and cross-axis offset to displace popper element from its reference element. | - |
| onClose | (() => void) | Callback fired when the popover closes | - |
| onOpen | (() => void) | Callback fired when the popover opens | - |
| openDelay | number | - | |
| placement | "top" | "right" | "bottom" | "left" | "auto" | "auto-start" | "auto-end" | "top-start" | "top-end" | "bottom-start" | "bottom-end" | "right-start" | "right-end" | "left-start" | "left-end" | The placement of the popper relative to its reference. | "bottom" |
| preventOverflow | boolean | If `true`, will prevent the popper from being cut off and ensure it's visible within the boundary area. | true |
| returnFocusOnClose | boolean | If `true`, focus will be returned to the element that triggers the popover when it closes | - |
| size | string | Sizes for Popover are not implemented in the default theme. You can extend the theme to implement them. | - |
| strategy | "fixed" | "absolute" | The CSS positioning strategy to use. | "absolute" |
| trigger | "click" | "hover" | The interaction that triggers the popover. `hover` - means the popover will open when you hover with mouse or focus with keyboard on the popover trigger `click` - means the popover will open on click or press `Enter` to `Space` on keyboard | - |
| variant | string | Variants for Popover are not implemented in the default theme. You can extend the theme to implement them. | - |
Other Props#
PopoverContentcomposesBoxand has the ability to smartly position itself. Thanks to popper.js.PopoverArrow,PopoverHeader,PopoverFooterandPopoverBodycomposesBox.PopoverCloseButtoncomposesBoxcomponent.