Skip to main content

Popover

Allows users to click an element to display a pop-up box.

github
View source code

Migration Information

For teams migrating from the V1 to V2 component, please refer to the migration guide for changes to the component.
Component Guide
import { Popover } from '@uhg-abyss/web/ui/Popover';
    () => {
    return <Popover content="Popover content">Click to open popover</Popover>;
    };

    Default popover trigger​

    If no children are passed to the Popover component, the default trigger will be the "help" IconSymbol.

    Heading​

    The title prop accepts a string and is used to set the title of the popover, as well as aria labels.

    For further customization, you can use the heading prop to pass a ReactNode, which is not used for aria labeling. Even when using a custom heading, it is recommended to still set the title prop for accessibility purposes.

    To hide the close button in the heading, set the showClose prop to false.

    Accessibility note​

    For accessibility, always define a heading in Popovers. Without a heading (title), the popover dialog will not have an accessible name. Some automated accessibility (like Deque Axe) may report this as an issue.

    Content​

    The content prop accepts a ReactNode. This allows for the flexibility to accommodate basic text as well as full custom UI layouts within body of the popover.

    Custom popover trigger​

    To utilize a custom trigger element, wrap with the Popover component with the custom element to replace the default and trigger the opening of the popover.

    Position​

    Use the position prop to change the position of the Popover relative to its target. The valid options are 'top', 'right', 'bottom', and 'left'. The default value is 'top'.

    Warning

    The Popover will automatically reposition itself to stay within the viewport. This may result in the Popover not appearing on the side defined by the position prop and/or not being center-aligned with the target element. Additionally, the use of 'right' and 'left' on mobile screens is highly discouraged; prefer using 'top' and 'bottom' instead. The example below shows one method of achieving this.

    Controlled open state​

    Use a combination of the onOpenChange and open props to use a controlled state for opening and closing the popover.

    Aria label​

    Use the ariaLabel prop to provide a more specific accessible name for the default trigger button when no custom children are passed. If ariaLabel is not provided, the default trigger uses "title Info". If no title is provided, it will just be "Info".

    When should I use a tooltip vs a popover?​

    Glad you asked! There are several considerations when deciding between a Tooltip or a Popover:

    Purpose of content​

    • A Tooltip is a hint or a tip about what an interactive element does. Tooltips are meant to help clarify or provide supplementary instruction for an element on hover or upon receiving focus. They should not be used to add additional content nor should they include interactive elements such as links. Tooltips should not receive mouse or keyboard focus. Try to position tooltips so they do not overlap and cover other content on the screen. This helps keep all content readable by all users and reduces concerns regarding WCAG 2.1 SC 1.4.13: Content on Hover or Focusopens in a new window

    • A Popover should be used to provide additional content to static text, such as definitions of words, informational blurbs, or additional product details. They can receive focus and can contain links and other interactive elements.

    Size of content​

    • Since Tooltips are only meant to tell the purpose of an element they should be short and to the point, for example: "Click X to do X" or "User post count".

    • Popovers, on the other hand, can be much more verbose, they can include a heading, lines of text in the body, links, etc.

    Interactions​

    • Tooltips should only be visible on mouse hover or upon receiving focus. For this reason, if you need to be able to read the content while interacting with other parts of the page then a Tooltip will not work. They should be dismissible using the "escape" key. They should be used on interactive elements where a mouse click or keyboard activation would otherwise trigger the elements primary function.

    • Popovers must be triggered to appear, whether via mouse click or via keyboard navigation. They must be dismissible, whether by clicking on other parts of the page, clicking the Popover target, or a specific close button/icon (depending on implementation). For this reason, you can set up a Popover to allow you to interact with other elements on the page while still being able to read its content. On top of this, since Popovers will remain open when mousing out of their target, you can add additional buttons or interactions within them.

    Conclusion​

    If you want to give a short hint or supplemental instructions for an interactive element (such as a submit button), use a Tooltip.

    If you want to add additional content to a static element that might include headings, body text, links, etc, and you need the content to remain open even after mousing away or the element losing focus, then use a Popover.

    It should be noted that any vital information users need to complete an action or make a decision should be displayed directly in the page text or button label, rather than a Tooltip or a Popover. Critical information hidden in a Tooltip or a Popover might not be discovered by all users and could create accessibility issues.

    Popover Props​

    Name
    Type
    DefaultRequiredA11yDescription
    ariaLabel
    string | undefined
    The aria-label for the default trigger button when no children are provided
    This improves accessibility for screen reader users
    children
    string | number | bigint | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<...> | null | undefined
    The Popover trigger element
    className
    string | undefined
    CSS class name to apply to each element within the component
    content
    string | number | bigint | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<...> | null | undefined
    Content displayed in the Popover
    css
    CSSProperties | Partial<Record<"abyss-popover-wrapper" | "abyss-popover-title" | "abyss-popover-root" | "abyss-popover-trigger" | "abyss-popover-content-container" | ... 4 more ... | "abyss-popover-trigger-icon", CSSProperties>> | undefined
    Object containing CSS styling to apply; uses the classes listed in the "Integration" tab of the component's documentation
    See CSS Prop Styling for more information
    data-testid
    string | undefined
    Suffix used to create a unique ID used for automated testing
    See Component Testing for more information
    disableDefaultProviderProps
    boolean | undefined
    false
    If set to true, the component will not use the DefaultPropsProvider values.

    If you aren’t using the DefaultPropsProvider, this prop can be ignored.
    heading
    string | number | bigint | boolean | ReactElement<any, string | JSXElementConstructor<any>> | Iterable<ReactNode> | ReactPortal | Promise<...> | null | undefined
    The heading element for the Popover, which can be used instead of title
    hiddenFrom
    Breakpoint | undefined
    When defined, the component is hidden once the screen width reaches the specified breakpoint.
    onKeyDown
    KeyboardEventHandler<HTMLDivElement> | undefined
    Handler for keydown events within the Popover content.
    onOpenChange
    ((open: boolean) => void) | undefined
    Callback function executed when the open state of the Popover changes
    open
    boolean | undefined
    false
    If true, the Popover is open; must be used with onOpenChange
    position
    "left" | "right" | "top" | "bottom" | undefined
    'top'
    The side of the trigger element where the Popover will appear
    showClose
    boolean | undefined
    true
    If false, the Popover will not display a close button
    slotProps
    Partial<Record<ToSlotKey<{ wrapper: LeafSlotDef<"div", undefined>; closeButton: LeafSlotDef<"button", undefined>; closeIcon: LeafSlotDef<"span", undefined>; ... 6 more ...; arrow: LeafSlotDef<...>; }, "popover">, SlotPropsLeafValue>> | undefined
    Props to pass to individual internal slots of the component.
    See slotProps for more information
    title
    string | undefined
    The title of the Popover
    visibleFrom
    Breakpoint | undefined
    When defined, the component is hidden until the screen width reaches the specified breakpoint.
    width
    string | number | undefined
    343px
    The width of the Popover container

    Popover Classes​

    Class NameDescription
    .abyss-popover-arrowPopover array notch
    .abyss-popover-close-buttonPopover close button
    .abyss-popover-close-iconPopover close button Icon
    .abyss-popover-content-containerPopover body content
    .abyss-popover-layout-wrapperWrapper for managing layout of title/content and close button. Shifts based on presence of a title.
    .abyss-popover-rootThe root popover container
    .abyss-popover-titlePopover title
    .abyss-popover-triggerPopover trigger button
    .abyss-popover-trigger-iconPopover default trigger icon
    .abyss-popover-wrapperOutermost local Popover wrapper

    Keyboard Interactions​

    KeyDescription
    EscClose Popover
    SpaceClose Popover when close button is present

    Component Tokens​

    Tip

    Click on the token row to copy the token to your clipboard.

    Popover Tokens​

    Token NameValue
    popover.color.border
    #CBCCCD
    popover.color.icon.active
    #000000
    popover.color.icon.hover
    #323334
    popover.color.icon.rest
    #4B4D4F
    popover.color.surface
    #FFFFFF
    popover.color.text.heading
    #323334
    popover.color.text.paragraph
    #4B4D4F
    popover.border-radius.all.container
    8px
    popover.border-width
    1px
    popover.sizing.all.icon
    24px
    popover.spacing.gap.horizontal.header
    16px
    popover.spacing.gap.vertical.container
    2px
    popover.spacing.padding.all.container
    16px
    popover.spacing.padding.notch
    4px
    popover.elevation
    0px 6px 8px -2px rgba(0,0,0,0.16)
    Table of Contents