Monet
@etched/monet 0.0.1

Popover

Ported

Closes the popover. Use render for a button: render={<Button>Done</Button>}.

Kumo source
import { Button } from "@etched/monet/button";
import { PopoverClose, PopoverContent, PopoverDescription, PopoverRoot, PopoverTitle, PopoverTrigger } from "@etched/monet/popover";

export function Preview() {
  return (
    <PopoverRoot>
      <PopoverTrigger render={<Button>Run 1,284</Button>} />
      <PopoverContent>
        <PopoverTitle>Run 1,284</PopoverTitle>
        <PopoverDescription>Passed on bench B-14 in 42 minutes.</PopoverDescription>
        <div className="row">
          <PopoverClose render={<Button size="sm">Done</Button>} />
        </div>
      </PopoverContent>
    </PopoverRoot>
  );
}

Installation

import { PopoverClose, PopoverContent, PopoverDescription, PopoverRoot, PopoverTitle, PopoverTrigger } from "@etched/monet/popover";

Examples

Title, description and close

openOnHover opens the popover on hover as well as on click.

import { BellIcon } from "@phosphor-icons/react";
import { Button } from "@etched/monet/button";
import { PopoverClose, PopoverContent, PopoverDescription, PopoverRoot, PopoverTitle, PopoverTrigger } from "@etched/monet/popover";

export function TitleDescriptionAndClose() {
  return (
    <div className="row">
      <PopoverRoot>
        <PopoverTrigger render={<Button shape="square" aria-label="Notifications" icon={<BellIcon />} />} />
        <PopoverContent>
          <PopoverTitle>Notifications</PopoverTitle>
          <PopoverDescription>You are all caught up.</PopoverDescription>
        </PopoverContent>
      </PopoverRoot>
      <PopoverRoot>
        <PopoverTrigger render={<Button>Run 1,284</Button>} />
        <PopoverContent align="start">
          <PopoverTitle>Run 1,284</PopoverTitle>
          <PopoverDescription>Passed on bench B-14 in 42 minutes.</PopoverDescription>
          <div className="row">
            <PopoverClose render={<Button size="sm">Done</Button>} />
          </div>
        </PopoverContent>
      </PopoverRoot>
      <PopoverRoot>
        <PopoverTrigger openOnHover delay={200} render={<Button variant="ghost">Hover for owner</Button>} />
        <PopoverContent>
          <PopoverTitle>Ana Ruiz</PopoverTitle>
          <PopoverDescription>Owns 12 chips at TPE-2.</PopoverDescription>
        </PopoverContent>
      </PopoverRoot>
    </div>
  );
}

Sides

import { Button } from "@etched/monet/button";
import { PopoverContent, PopoverDescription, PopoverRoot, PopoverTrigger, type PopoverSide } from "@etched/monet/popover";

const sides: PopoverSide[] = ["top", "right", "bottom", "left"];

export function Sides() {
  return (
    <div className="row">
      {sides.map((side) => (
        <PopoverRoot key={side}>
          <PopoverTrigger render={<Button variant="outline">{side}</Button>} />
          <PopoverContent side={side}>
            <PopoverDescription>On the {side}.</PopoverDescription>
          </PopoverContent>
        </PopoverRoot>
      ))}
    </div>
  );
}

Accessibility

  • Enter or Space on the trigger opens it and moves focus into the panel. Escape closes it and returns focus to the trigger.
  • The panel is a dialog, named by PopoverTitle and described by PopoverDescription. The trigger has aria-haspopup="dialog" and aria-expanded.
  • Focus is not trapped: Tab out of the panel closes it. A popover that opens on hover (openOnHover) does not take focus.
  • Add a PopoverTitle, so the dialog has a name. Give an icon-only trigger an aria-label.

API reference

PopoverContent

PropTypeDefaultDescription
classNamestring–Class on the panel, for layout such as width.
positionMethodBaseTooltip.Positioner.Props["positionMethod"]"absolute""fixed" escapes sticky headers and other stacking contexts.
anchorBaseTooltip.Positioner.Props["anchor"]–Position against this element, ref or virtual element instead of the trigger, for example a whole row.
containerBaseTooltip.Portal.Props["container"]document.bodyThe element the popup renders into (a portal), for example a shadow root.
side"top" | "bottom" | "left" | "right""bottom"
align"start" | "center" | "end""center"
sideOffsetnumber8Pixels between the trigger and the popover.
alignOffsetnumber0Pixels along the alignment axis.
arrowbooleantrueShows the arrow that points at the trigger.
initialFocusPopup["initialFocus"]–The element that gets focus when the popover opens. By default, the panel itself.
finalFocusPopup["finalFocus"]–The element that gets focus when the popover closes. By default, the trigger.
aria-labelstring–Names a panel that has no visible PopoverTitle.
childrenReactNode–

PopoverDescription

PropTypeDefaultDescription
classNamestring–

PopoverTitle

PropTypeDefaultDescription
classNamestring–