Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Material ui popover how to anchor to another element (different from event target)

Well typically when we use popover we set the anchor during a mouse event to event.currentTarget.

However this is impossible in certain situations and undesired in others. - How can I set the popover anchor element directly?

import React from "react";
import Popover from "@material-ui/core/Popover";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";

export default function SimplePopover() {
  const [anchorEl, setAnchorEl] = React.useState(null);

  function handleClick(event) {
    //setAnchorEl(event.currentTarget);
    setAnchorEl(); //How to refer to the div?
  }

  function handleClose() {
    setAnchorEl(null);
  }

  const open = Boolean(anchorEl);
  const id = open ? "simple-popover" : undefined;

  return (
    <div>
      <Typography>Anchor point of popover here</Typography>
      <Button aria-describedby={id} variant="contained" onClick={handleClick}>
        Open Popover
      </Button>
      <Popover
        id={id}
        open={open}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: "bottom",
          horizontal: "center"
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "center"
        }}
      >
        <Typography>The content of the Popover.</Typography>
      </Popover>
    </div>
  );
}

demo

like image 484
paul23 Avatar asked Jul 09 '19 17:07

paul23


2 Answers

You can use a ref to get at whichever element you want to use as the anchor:

import React from "react";
import Popover from "@material-ui/core/Popover";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";

export default function SimplePopover() {
  const [anchorEl, setAnchorEl] = React.useState(null);
  const divRef = React.useRef();
  function handleClick() {
    setAnchorEl(divRef.current);
  }

  function handleClose() {
    setAnchorEl(null);
  }

  const open = Boolean(anchorEl);
  const id = open ? "simple-popover" : undefined;

  return (
    <div ref={divRef}>
      <Typography>Anchor point of popover here</Typography>
      <Button aria-describedby={id} variant="contained" onClick={handleClick}>
        Open Popover
      </Button>
      <Popover
        id={id}
        open={open}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: "bottom",
          horizontal: "center"
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "center"
        }}
      >
        <Typography>The content of the Popover.</Typography>
      </Popover>
    </div>
  );
}

Edit Use ref for anchorEl

like image 110
Ryan Cogswell Avatar answered Oct 20 '22 23:10

Ryan Cogswell


This is a small variation from Ryan Cogswell example to open automatically the Popover:

https://codesandbox.io/s/use-ref-for-anchorel-forked-ou7eo

import React, { useEffect } from "react";
import Popover from "@material-ui/core/Popover";
import Typography from "@material-ui/core/Typography";
import Button from "@material-ui/core/Button";

export default function SimplePopover() {
  const [anchorEl, setAnchorEl] = React.useState(null);
  const divRef = React.useRef();
  function handleClick() {
    setAnchorEl(divRef.current);
  }

  function handleClose() {
    setAnchorEl(null);
  }

  useEffect(() => {
    setAnchorEl(divRef.current);
  }, [divRef]);

  const open = Boolean(anchorEl);
  const id = open ? "simple-popover" : undefined;

  return (
    <div>
      <Typography>Anchor point of popover here</Typography>
      <Button
        ref={divRef}
        aria-describedby={id}
        variant="contained"
        onClick={handleClick}
      >
        Open Popover
      </Button>
      <Popover
        id={id}
        open={open}
        anchorEl={anchorEl}
        onClose={handleClose}
        anchorOrigin={{
          vertical: "bottom",
          horizontal: "center"
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "center"
        }}
      >
        <Typography>The content of the Popover.</Typography>
      </Popover>
    </div>
  );
}
like image 1
Ricardo Cardona Ramirez Avatar answered Oct 21 '22 00:10

Ricardo Cardona Ramirez