MaterialUIのMenuをクリックしたマウスポインター位置に表示させる
はじめに
昨日、MaterialUIのMenuを右クリックで表示させるという記事を書いた。
その後、Menuをクリックしたマウスポインター位置に表示させるようにする実装もしてみたのでまとめておく。
方法
一般的なMenu
は、anchorEl
というプロパティにMenuを表示する対象となるElementを渡す。
これをクリックしたマウスポインター位置に表示したい場合は、anchorReference
とanchorPosition
というプロパティを使用する。
<Menu
anchorReference="anchorPosition"
anchorPosition={anchorPostion}
>
anchorPosition
に渡す値の型は以下。
type AnchorPosition = { top: number; left: number } | null;
アプリケーション内におけるマウスポインターの相対位置のtop
とleft
が必要となる。
これらの値はクリックイベントのclientY
とclientX
から取得することができる。サンプルコードは以下。
type AnchorPosition = { top: number; left: number } | null;
const [menuAnchorPosition, setMenuAnchorPosition] = useState<AnchorPosition | null>(null);
const onClick = (event: React.MouseEvent<HTMLElement>) => {
setMenuAnchorPosition({ top: event.clientY, left: event.clientX });
};
const onCloseMenu = () => {
setMenuAnchorPosition(null)
}
return (
<div>
<Button onClick={onClick}>
Click Target
</Button>
<Menu
open={Boolean(anchorPosition)}
onClose={onCloseMenu}
anchorReference="anchorPosition"
anchorPosition={anchorPostion}
>
<MenuItem onClick={onCloseMenu}>Item</MenuItem>
</Menu>
</div>
)
これでクリックした位置にMenuが表示されるようになった。
おわり
今回のクリック位置にMenuを表示させるのは、クリックする対象が大きい場合に有効だと感じた。
アイコンクリック時に表示させる場合はクリック位置とMenuの表示位置が遠くないので気にならない。
一方、クリック対象のサイズが大きい場合はその距離が大きくなってしまう可能性があり、そうなると今回のような対処が有効になってくるように感じた。ただし、クリック対象がMenuと重なってしまう可能性もあるのでケースバイケースで考慮するようにしたい。