Popover

Popover is a non-modal dialog that floats around a trigger. It's 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, and composes the Popper component.

Import#

  • CPopover: The wrapper that provides props, state, and context to its children.
  • CPopoverTrigger: Used to wrap the reference (or trigger) element.
  • CPopoverContent: The popover itself.
  • CPopoverHeader: The header of the popover.
  • CPopoverBody: The body of the popover.
  • CPopoverFooter: The footer of the popover.
  • CPopoverArrow: A visual arrow that points to the reference (or trigger).
  • CPopoverCloseButton: A button to close the popover.
import {
  CPopover,
  CPopoverTrigger,
  CPopoverContent,
  CPopoverHeader,
  CPopoverBody,
  CPopoverFooter,
  CPopoverArrow,
  CPopoverCloseButton,
} from '@chakra-ui/vue';

Basic Usage#

When using this component, ensure the child of the CPopoverTrigger is focusable. It is essential that the user can tab to it using their keyboard to keep it accessible.

A11y: When the Popover opens, focus is sent to the CPopoverContent. When it closes, focus is returned to the trigger.

Editable Example
<c-popover>
  <c-popover-trigger>
    <c-button>Trigger</c-button>
  </c-popover-trigger>
  <c-popover-content z-index="4">
    <c-popover-arrow />
    <c-popover-close-button />
    <c-popover-header>Confirmation!</c-popover-header>
    <c-popover-body>Are you sure you want to have that milkshake?</c-popover-body>
  </c-popover-content>
</c-popover>

Rendering the Popover in a Portal#

By default, the Popover doesn't render in a Portal. To make them display in a portal, pass the usePortal prop.

You might need to Inspect Element to see this in action. Notice the CPopoverContent is rendered as a child of <body>

Editable Example
<c-popover use-portal>
  <c-popover-trigger>
    <c-button>Trigger</c-button>
  </c-popover-trigger>
  <c-popover-content z-index="4">
    <c-popover-arrow />
    <c-popover-header>Header</c-popover-header>
    <c-popover-close-button />
    <c-popover-body>
      <c-button variantColor="blue">Button</c-button>
    </c-popover-body>
    <c-popover-footer>This is the footer</c-popover-footer>
  </c-popover-content>
</c-popover>

Focus an element when Popover opens#

By default, focus is to be sent to the CPopoverContent when it opens, you might want to send focus to a specific element when it opens. Pass the initialFocusRef prop to do so.

Editable Example
<c-popover
  initialFocusRef="#next"
  placement="bottom"
>
  <c-popover-trigger>
    <c-button>Trigger</c-button>
  </c-popover-trigger>
  <c-popover-content
    z-index="4"
    color="white"
    background-color="blue.700"
    border-color="blue.700"
  >
    <c-popover-header pt="4" font-weight="bold" border="0">
      Manage Your Channels
    </c-popover-header>
    <c-popover-arrow />
    <c-popover-close-button />
    <c-popover-body>
      Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do
      eiusmod tempor incididunt ut labore et dolore.
    </c-popover-body>
    <c-popover-footer
      border="0"
      d="flex"
      align-items="center"
      justify-content="space-between"
      pb="4"
    >
      <c-box font-size="sm">Step 2 of 4</c-box>
      <c-button-group size="sm">
        <c-button variant-color="green">Setup Email</c-button>
        <c-button variant-color="blue" id="next">
          Next
        </c-button>
      </c-button-group>
    </c-popover-footer>
  </c-popover-content>
</c-popover>

Accessing the internal state#

The CPopover component exposes some variables inside its default slot scope so you can have access to the component's internal state.

  • isOpen: { Boolean } Carries the current open/closed state of the Popover component.
  • onClose : { Function } Function to close the Popover component
Editable Example
<c-popover
  initialFocusRef="#closeButton"
  placement="right"
  v-slot="{ isOpen, onClose }"
>
  <c-popover-trigger>
    <c-button>Click to {{ isOpen ? 'close' : 'open' }}</c-button>
  </c-popover-trigger>
  <c-popover-content z-index="4">
    <c-popover-header>This is the header</c-popover-header>
    <c-popover-close-button />
    <c-popover-arrow />
    <c-popover-body>
      <c-box>
        Hello. Nice to meet you! This is the body of the popover
      </c-box>
      <c-button
        mt="4"
        variantColor="blue"
        @click="onClose"
        id="closeButton"
      >
        Close
      </c-button>
    </c-popover-body>
    <c-popover-footer>This is the footer</c-popover-footer>
  </c-popover-content>
</c-popover>

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, boxShadow, and so on.

Click
Editable Example
<c-popover>
  <c-popover-trigger>
    <c-box
      tab-index="0"
      role="button"
      aria-label="Some box"
      p="5"
      w="120px"
      bg="gray.300"
    >
      Click
    </c-box>
  </c-popover-trigger>
  <c-popover-content z-index="4" background-color="tomato" color="white">
    <c-popover-header font-weight="semibold">Customization</c-popover-header>
    <c-popover-arrow />
    <c-popover-close-button background-color="indigo.500" />
    <c-popover-body>
      Tadaa!! The arrow color and background color is customized. Check the
      props for each component.
    </c-popover-body>
  </c-popover-content>
</c-popover>

Hover Trigger#

To show the popover when you mouse over or focus on the trigger, pass the prop trigger and set it to hover. When you focus on or mouse-over the popover trigger, the popover will open.

If you quickly move your cursor to the popover content when it's open, it'll remain open till you leave.

Hover to see @swyx profile
Editable Example
<c-popover trigger="hover">
  <c-popover-trigger>
    <c-link text-decoration="underline" font-weight="bold" color="blue.500">
      Hover to see @swyx profile
    </c-link>
  </c-popover-trigger>
  <c-dark-mode>
    <c-popover-content border="0" zIndex="4" width="400px" color="white">
      <c-box p="5">
        <c-avatar
          name="swyx"
          src="https://pbs.twimg.com/profile_images/1201029434054041606/efWs7Lr9_400x400.jpg"
        />
        <c-text mt="4" fontWeight="bold">
          swyx
          <c-badge ml="3" variant="solid" font-size="xs">
            Follows you
          </c-badge>
        </c-text>
        <c-text mt="3">
          Infinite Builder working on DX @Netlify. Helping people
          #LearnInPublic
        </c-text>
      </c-box>
    </c-popover-content>
  </c-dark-mode>
</c-popover>

Accessibility#

When you see the word "trigger", it's referring to the child element of the CPopoverTrigger

Keyboard and Focus#

  • When the popover is opened, focus is moved to the CPopoverContent. If the initialFocusRef is set, then focus moves to the element with that ref, element selector, or ref returned from the function.
  • When the popover is closed, focus returns to the trigger. If you set returnFocusOnClose to false, 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 CPopoverContent, it'll remain visible.
  • If trigger is set to click:
    • Clicking the trigger or using the Space or Enter when focus is on the trigger will open the popover.
    • Clicking the trigger again will close the popover.
  • Hitting the Esc key while the popover is open and focus is within the CPopoverContent, will close the popover. If you set closeOnEsc to false, it will not close.
  • Clicking outside or blurring out of the CPopoverContent closes the popover. If you set closeOnBlur to false, it will not close.

ARIA Attributes#

  • If the trigger is set to click, the CPopoverContent element has role set to dialog. If the trigger is set to hover, the CPopoverContent has role set to tooltip.
  • The CPopoverContent has aria-labelledby set to the id of the PopoverHeader.
  • The CPopoverContent has aria-describedby set to the id of the PopoverBody.
  • The CPopoverContent has aria-hidden set to true or false depending on the open/closed state of the popover.
  • The trigger has aria-haspopup set to true to denote that it triggers a popover.
  • The trigger has aria-controls set to the id of the CPopoverContent to associate the popover and the trigger.
  • The trigger has aria-expanded set to true or false depending on the open/closed state of the popover.

Props#

CPopover Props#

NameTypeDefaultDescription
isOpenbooleanIf true, the popover is shown
defaultIsOpenbooleanIf true, the popover is shown initially.
initialFocusRefVue.ref, HTML element selector or Function : Vue.$refThe ref of the element that should receive focus when the popover opens.
triggerhover, clickclickThe interaction that triggers the popover.
placementPopperJS.placementbottomThe placement of the popover.
returnFocusOnClosebooleantrueIf true, the popover will return focus to the trigger when it closes
closeOnBlurbooleantrueIf true, the popover will close when you blur out it by clicking outside or tabbing out
closeOnEscbooleantrueIf true, close the popover when the esc key is pressed
gutternumber4The gap (in pixels) to apply between the popover and the target. Used by popper.js
usePortalbooleanfalseIf true the popover is displayed with a Portal. Rendering content inside a Portal allows the popover content to escape the physical bounds of its parent while still being positioned correctly relative to its target
onOpen() => voidCallback fired when the popover opens
onClose() => voidCallback fired when the popover closes

CPopover Slots#

NameDescription
defaultSlot for CPopover components

Other Props#

  • CPopoverContent composes CPseudoBox and has the ability to smartly position itself. Thanks to popper.js
  • CPopoverArrow, CPopoverHeader, CPopoverFooter and CPopoverBody composes CBox.
  • CPopoverCloseButton composes CPseudoBox component.

❤️ Contribute to this page

Caught a mistake or want to contribute to the documentation? Edit this page on GitHub!