Skip to content

Demos#

Basic usage#

<Popover
  trigger={({ active, ...triggerProps }) => (
    <Button icon="question" {...triggerProps} selected={active} />
  )}
  title="Need help?"
>
  Popover content that appears when the custom trigger button is toggled.
</Popover>

Without close button#

<Popover
  hideCloseButton
  trigger={(triggerProps) => (
    <Button text="More info" variant="secondary" {...triggerProps} />
  )}
  title="More information"
  content={({ close }) => (
    <Flex.Stack>
      <P>
        This popover hides the default close button. You can still close it
        programmatically by calling the provided helpers.
      </P>
      <Button text="Dismiss" variant="secondary" onClick={close} />
    </Flex.Stack>
  )}
/>

Controlled state#

An external trigger can control open. Focus returns to the trigger after closing, including when the content updates the state directly.

const Example = () => {
  const [open, setOpen] = useState(false)
  const anchorRef = useRef<HTMLDivElement>(null)
  return (
    <Flex.Stack>
      <div ref={anchorRef}>
        <Button
          text="Open controlled popover"
          aria-expanded={open}
          aria-controls="controlled-popover-content"
          onClick={() => setOpen(!open)}
        />
      </div>
      <Popover
        id="controlled-popover-content"
        open={open}
        onOpenChange={setOpen}
        targetElement={anchorRef}
        title="Controlled state"
      >
        <Flex.Stack>
          <P>
            Closing also returns focus to the opener when the positioning
            target is a wrapper.
          </P>
          <Button text="Done" onClick={() => setOpen(false)} />
        </Flex.Stack>
      </Popover>
      <Button text="Another action" variant="secondary" />
    </Flex.Stack>
  )
}
render(<Example />)
Suggest an edit