Material-UI Popover コンポーネントの表示位置を細かく操作する


こんにちは、 Gaji-Labo アシスタントエンジニアの石垣です。

今回は Material-UI の Popover コンポーネントを使っている時に、Popover の位置操作で少し迷った部分があったので Popover の仕様についてまとめたいと思います。

Popover の基本的な使用方法

Popover コンポーネントは、その名の通り起点の要素の上から別のコンテンツをポップオーバーで表示させられるコンポーネントです。

基本的には以下のように実装して使用します。

import { ReactElement, useRef, useState } from "react";

import { Popover, Button } from "@material-ui/core";
import { withStyles } from "@material-ui/core/styles";

export function ExamplePopover(): ReactElement {
  const [open, setOpen] = useState(false);
  const divRef = useRef(null);
  return (
    <div ref={divRef}>
      <Button onClick={() => setOpen(!open)} variant="outlined">
        Open
      </Button>
      <StyledPopover
        open={open}
        anchorEl={divRef.current}
        onClose={() => setOpen(!open)}
        anchorOrigin={{
          vertical: "bottom",
          horizontal: "left",
        }}
        transformOrigin={{
          vertical: "top",
          horizontal: "left",
        }}
      >
        Content
      </StyledPopover>
    </div>
  );
}

使用するにあたって特に重要なのが以下の4つの Props です。

  • open: 表示/非表示を切り替える
  • anchorEl: 表示位置の起点となる要素を渡す
  • anchorOrigin: anchorEl のどの位置からポップオーバーさせるかを指定する
  • transformOrigin: anchorEl のどの方向へ向かってポップオーバーさせるかを指定する

anchorOrigintransformOrigin については公式のドキュメントで実際に触りながら確認することができます。

Props を変えて実際の挙動を確認することができる

anchorOrigin, transformOrigin をより細かく設定する

anchorOrigintransformOrigintop bottom left right の4つの文字列を渡して位置を操作することができますが、実際はより細かい位置を調整したいとなる時があるかと思います。

そんな時は、Popover に getContentAnchorEl={null} を渡すと px 単位で操作することができます。

<StyledPopover
  open={open}
  anchorEl={divRef.current}
  onClose={() => setOpen(!open)}
  getContentAnchorEl={null}
  anchorOrigin={{
    vertical: 50,
    horizontal: 50,
  }}
  transformOrigin={{
    vertical: "top",
    horizontal: "left",
  }}
>
  Content
</StyledPopover>

anchorOrigin に数値を渡すと、anchorOrigin={{ vertical: "top", horizontal: "left", }} の状態から、下/右方向に数値の px 分移動します。

ボタンを起点にして anchorOrigin に数値を渡した状態。50px 分右下に移動している

transformOrigin に数値を渡すと、 verticalanchorOriginvertical で指定した方向に数値の px 分移動します。
horizontal の時は特殊で、 anchorOriginhorizontalleft の際は left に数値の px 分移動しますが、 right だった場合は画面の右端から数値の px 分の位置に表示されます。

anchorOrigin={{
  vertical: "top",
  horizontal: "left",
}}
transformOrigin={{
  vertical: 20,
  horizontal: 20,
}}
transformOrigin に数値を渡した状態。右下から 20px 分左上に移動している
anchorOrigin={{
  vertical: "top",
  horizontal: "right",
}}
transformOrigin={{
  vertical: 20,
  horizontal: 20,
}}
transformOrigin に数値を渡した状態。画面幅の右端から 20px 分移動している

まとめ

数値分だけ操作する方法は公式ドキュメントに情報が少なく、ハマることも多いのではないかと思いまとめました。

Material-UI を使用している方の参考にしていただけたら幸いです。

Gaji-Laboでは、React経験が豊富なフロントエンドエンジニアを募集しています

弊社ではReactの知見で事業作りに貢献したいフロントエンドエンジニアを募集しています。大きな制作会社や事業会社とはひと味もふた味も違うGaji-Laboを味わいに来ませんか?

もちろん、一緒にお仕事をしてくださるパートナーさんも随時募集中です。まずはお気軽に声をかけてください。お仕事お問い合わせや採用への応募、共に大歓迎です!

求人応募してみる!

投稿者 Ishigaki Shotaro

未経験から Gaji-Labo に入社。現在は React/TypeScript/Next.js の案件で MUI を使ったコンポーネント組み込みを担当。プロジェクトチームのリードとして共に組み込み作業をしているメンバーの進行管理も行っています。休日はだいたい家で音楽を聴いており、たまにライブに出かけています。