Chakra-UI


Popover

|

Chakra Docs

|

⦾ Popover is a component that allows you to display additional content or information upon interacting with an element, such as a button or a link. The additional content typically appears in a small overlay on top of the main interface, which is why it's called a "Popover". This can be used for various purposes, such as tooltips, context menus, or even complex dialogues.

Useful implementations of the Popover component include:

  • Tooltips: Popovers can be used to provide additional information about an element when a user hovers over or focuses on it. This can be useful for explaining complex UI elements, providing hints, or showing more information about an item without taking the user away from the current screen.
  • Contextual Menus: Popovers can also be used to create context-specific menus. For example, if a user right-clicks on an item, a popover could appear with actions relevant to that item.
  • User Interaction Feedback: Popovers can be used to provide instant feedback or extra details when a user performs an action. For example, after a user submits a form, a popover could appear confirming the submission and offering next steps.
  • Form Inputs: Sometimes, a form field may require additional inputs or complex interaction. In such cases, a popover can be used to contain these interactions. For example, a date picker input could show a calendar in a popover.
  • Detail Previews: If a user interface contains a list of items, a popover could be used to show a preview of each item's details when the user hovers over or clicks the item. This can be useful to provide more information without needing to navigate away from the list.
  • Instructions/Guidance: A popover can be used to provide step-by-step instructions or guidance for a complex task, guiding the user through the process in a non-intrusive way.

Popover sub-components


A Popover component consists of several sub-components that make it customizable and flexible for a variety of use cases. Here are the main sub-components:

  • Popover: The wrapper component that encloses all the other sub-components. It manages the state and interaction logic of the popover. It also provides a context for the sub-components to communicate with each other.
  • PopoverTrigger: This is the component that triggers the opening and closing of the Popover content when interacted with (e.g., clicked or hovered). It is typically a button or a link, but it can also be any other element that can receive focus.
  • PopoverContent: This component wraps the content that will be displayed when the Popover is opened. It also positions the content relative to the trigger element.
  • PopoverHeader: This is an optional component that can be used to structure the content within the PopoverContent. It is typically used to render a title for the popover.
  • PopoverBody: This is also an optional component that can be used to structure the content within the PopoverContent. It is typically used to render the main content of the popover.
  • PopoverAnchor: This component is used to wrap the position-reference element. This is useful when you want to position the popover relative to an element other than the trigger element. For example, you can use this to position the popover relative to the trigger's parent element.
  • PopoverCloseButton: A component that renders a button to close the popover. It is typically rendered in the PopoverHeader component.
  • PopoverArrow: This is an optional component that renders an arrow pointing towards the trigger element. It is typically rendered in the PopoverContent component.

The Popover component in Chakra UI also has various props to customize its behavior and appearance. For example, you can control the position and alignment of the popover, whether it should close when the user clicks outside of it, whether it should re-focus the trigger when it closes, and so on. We will explore more of this funcitonality and customization in the examples below.

While popovers can be quite useful, it's also important to use them judiciously. Overuse of popovers can disrupt the user's experience, making it feel cluttered or overwhelming. Additionally, it's essential to ensure that popovers behave well on all devices, including touch devices where hover interactions are not available.

These components can be imported as follows:

Examples

Basic Popover


⦾ In the following example, clicking on the "Trigger Me!" button will show the popover with the title "Popover Title" and the body content "This is the content of the popover." The popover can be closed by clicking on the close button or outside of the popover.

Code

Portal Popover


⦾ The following example demonstrates the usage of a Popover component within a Portal in Chakra UI. This example consists of two similarPopover components. Both popovers have identical configurations and their PopoverContent is wrapped within a Portal.

A Portal in Chakra UI is used to render components to a DOM node that exists outside the DOM hierarchy of the parent component. This is useful when the parent's CSS or stacking context could affect the positioning or visibility of the child components. By wrapping thePopoverContent in a Portal, you ensure that the popover is displayed on top of other elements, without being affected by any parent elements' z-index or overflow properties.

In this specific example, when a user clicks the "Trigger" button, thePopoverContent appears. This content contains a PopoverArrow, a header (PopoverHeader), a close button (PopoverCloseButton), a body with a blue button (PopoverBody), and a footer (PopoverFooter).

Since this PopoverContent is rendered within a Portal, you might not immediately see the change in the DOM hierarchy unless you inspect the element using a tool like the browser's DevTools. On inspection, you'll notice that the PopoverContent is actually rendered as a direct child of the tag, rather than nested within its parent components. This example contains two buttons and two popover examples; each button will trigger a unique popover when clicked.

Code

Accessing the Internal State


⦾ In the next example component, we see an effective use of the internal state provided by the Chakra UI Popover component to control its behavior and presentation.

The component begins by creating a reference, initRef, which is a handle to a DOM element in the component - in this case, the "Close" button. This useRef hook from React is necessary to allow the Popover component to control focus placement when the popover is opened. The closeOnBlur prop is set to false to prevent the popover from automatically closing when a user clicks outside of the popover. The placement prop is set to "left" to control where the popover will appear in relation to the trigger button.

The initialFocusRef prop is set to the initRef we created earlier, so that when the popover opens, the focus will immediately move to the close button inside the popover. The children of thePopover component is a render prop function, a function that takes an object argument and returns JSX. The object passed to this function contains properties that reflect the internal state of the Popover component, specifically isOpen (a boolean indicating whether the popover is open or closed) and onClose (a function to close the popover). These are used within the component to change the behavior and appearance based on the state of the popover. The PopoverTrigger contains a button that toggles the popover. Its label changes based on whether the popover is currently open or closed, by checking the isOpen state.

The PopoverContent component, wrapped in a Portal for better positioning and stacking behavior, contains the content of the popover. It includes a header, a close button, a body with a greeting and a placeholder image, and a footer. The close button inside the popover uses the onClose function passed to the render prop to close the popover when clicked. By leveraging the internal state provided by the Chakra UI Popover component, this component achieves a high level of interactivity and control over the user experience.

Code

Defining Focus


⦾ The following example component is a React function component that implements a popover functionality with a select option. The component displays an input field and a "Select" button. When the user interacts with the input field, a popover is triggered, showing a list of positive adjectives. The user can select an adjective from the list, and upon clicking the "Select" button, a modal appears with a confirmation message displaying the selected adjective.

The use of initialFocusRef ensures that the input field inside the popover receives focus when the popover is opened. Additionally, the use of ref on the "Select" button enables focusing on the button after the popover is closed. This implementation provides a user-friendly and accessible way for users to seemlessly interact with the fewest number of clicks.

I am

Code

Popover Customization


⦾ In this example, we will create a custom popover with a unique background color, arrow color, and button color, and we'll also specify its placement. The Popover's placement prop is set to "right-start", positioning it to the right of the trigger, aligning with the start edge of the trigger.

The PopoverTrigger contains a Box which acts as the clickable area to toggle the popover. The Box has a tabIndex of 0, which allows it to be focusable and navigable via keyboard, a role of "button"

By using the props available on each component as shown in this example, you can customize almost every aspect of the popover's appearance. This allows you to design a popover that perfectly fits your application's style and theme.

Code

Popover Placement


⦾ The purpose of this component is to show you the full range of possibilities, so you can choose the one that works best for your needs. You might want your popover to appear in a certain place to make it more noticeable, or to fit better with the layout of your page. Here you can see a visual representation of the different placements available for the popover component.

Below is a dropdown menu that contains all of the placement options for popovers. It is set to "auto placement" by default. But you can choose from the options to see how a popover placement renders in relation to its trigger element. Just click on the giant button-box to see it in action!

Each placement position is a combination of two parts: an edge (top, bottom, left, or right) and an alignment (start, end, or none). Because these types of spatial relationships can be a bit tricky at first to comprehend, here's what each placement means:

  • auto-start, auto, auto-end: The auto placements will position the popover relative to the trigger based on the available space in the viewport. If 'start' or 'end' is specified, it will align the popover accordingly if space permits.
  • top-start, top, top-end: These placements will position the popover above the trigger element. top-start aligns the start of the popover with the start of the trigger, top centers it, and top-end aligns the end of the popover with the end of the trigger.
  • bottom-start, bottom, bottom-end: These placements will position the popover below the trigger element. Similar to the top placements, bottom-start aligns the start of the popover with the start of the trigger, bottom centers it, and bottom-end aligns the end of the popover with the end of the trigger.
  • left-start, left, left-end: These placements will position the popover to the left of the trigger element. left-start aligns the top of the popover with the top of the trigger, leftcenters it, and left-end aligns the bottom of the popover with the bottom of the trigger.
  • right-start, right, right-end: hese placements will position the popover to the right of the trigger element. right-start aligns the top of the popover with the top of the trigger, right centers it, and right-end aligns the bottom of the popover with the bottom of the trigger.

Code

Additional Functionality and Considerations:


  • Deferred Rendering of Popover: Usually, the Popover component preloads all the child elements of PopoverContent onto the DOM even if they are not immediately visible. However, if you prefer that the popover content gets rendered only when the Popover is activated, you can make use of the isLazy property. This can be especially handy when your PopoverContent needs to be highly efficient or if it needs to perform network calls upon mounting, which should only occur when the component is actually shown.
  • Ease of Use: Whenever the term "trigger" is mentioned, it pertains to the elements contained within the PopoverTrigger. Similarly, the term "content" refers to the elements contained within the PopoverContent.
  • Keyboard Usage and Focus Management: Upon opening the popover, the focus shifts to the PopoverContent. If the initialFocusRef is specified, then the focus will go to the respective element. When the popover is closed, the focus reverts back to the trigger. If returnFocusOnClose is set to false, this reversion won't occur. The opening and closing of the popover can be controlled through both mouse movements and keyboard inputs, and these interactions can be configured based on whether the trigger is set to "hover" or "click".
  • ARIA Roles and Properties: The PopoverContent is assigned a role depending on whether the trigger is set to "click" or "hover", respectively corresponding to "dialog" and "tooltip". Additionally, the PopoverContent has several ARIA properties set to improve accessibility. These include aria-labelledby which links to the PopoverHeader's id, aria-describedby pointing to the id of the PopoverBody, and aria-hidden that toggles depending on whether the popover is open or closed. The trigger also has several ARIA attributes: aria-haspopup indicating it activates a popover, aria-controls linking to the id of the PopoverContent, and aria-expanded reflecting the open/closed state of the popover.

Did you know?

Creative Idea No. 1

Dynamic Content: The content inside your Popover can be dynamic. This means you can alter the content based on user interactions or other state changes in your application. Let's consider an example where we display user details in a Popover upon clicking a user's name. Here's how you might do it

Code

Creative Idea No. 2

Popover Form: You can include a form within a Popover. This can be useful when you need to collect simple information from a user without directing them to a new page. Here's an example of how to create a subscription form within a Popover.

Code

Creative Idea No. 3

Manual Control: You can manually control the open and close state of a Popover using the isOpen and onOpen/onClose props. This could be useful when you need to trigger the popover from somewhere else in your component.

Code

copyright © 2023 IHeartComponents | evanmarie.com

Chakra-UIRemix

Special thanks to Stefan Bohacek / Generative Placeholders.