React、cssでドロアーのメニューを実装したときのメモです。画面外からメニューが出てきます。
MUIやChakraUIなどのライブラリは使用しておりません。
左から出るメニューと右から出るメニューを作成しました。
左から出るメニューに関しては、closeボタン押下でメニューを閉じます。
右から出るメニューに関しては、メニュー外をクリックするとメニューを閉じます。
左から出るメニュー
DrawerMenuLeftのcssを当ててメニューを画面外に表示します。メニューアイコン押下時は.DrawerMenuLeft--isOpenのcssを追加で当てることでメニューが画面内に移動します。
.DrawerMenuLeft {
transition: all 0.3s ease-in-out;
transform: translate(-200px);
position: fixed;
}
.DrawerMenuLeft--isOpen {
transform: translate(0);
}
const [isOpenLeft, setIsOpenLeft] = useState<boolean>(false);
const onMenuColseLeft = () => {
setIsOpenLeft(false);
};
const onMenuIconClickRight = () => {
setIsOpenRight(true);
};
:
:
return (
<>
:
:
<nav
className={`DrawerMenuLeft ${isOpenLeft && "DrawerMenuLeft--isOpen"}`}
>
<ul>menu-left</ul>
<button className="CloseButton" onClick={onMenuColseLeft}>
close
</button>
</nav>
右から出るメニュー
DrawerMenuRightのcssを当ててメニューを画面外に表示します。メニュー外クリック時は.DrawerMenuRight--isOpenのcssを追加で当てることでメニューが画面内に移動します。
右側なので、起点はright: 0;としています。また、今回はクリック座標とメニューの座標を比較することで、メニュー外でクリックされたと判断しました。
※メニューの下に全画面表示のラベル等を表示してそこをクリックするとメニューを消す方法もあります
.DrawerMenuRight {
transition: all 0.3s ease-in-out;
right: 0;
transform: translate(200px);
position: fixed;
}
.DrawerMenuRight--isOpen {
transform: translate(0);
}
const [isOpenLeft, setIsOpenLeft] = useState<boolean>(false);
const concernedElement = document.querySelector(".DrawerMenuRight");
const handleClickOutside = useCallback(
(e: MouseEvent): void => {
if (concernedElement && isOpenRight) {
if (
e.pageX < concernedElement.getBoundingClientRect().x ||
e.pageY >
concernedElement.getBoundingClientRect().y +
concernedElement.clientHeight
) {
setIsOpenRight(false);
}
}
},
[isOpenRight, concernedElement]
);
const onMenuIconClickRight = () => {
setIsOpenRight(true);
};
useEffect(() => {
document.addEventListener("click", handleClickOutside, true);
return () => {
document.removeEventListener("click", handleClickOutside, true);
};
}, [handleClickOutside]);
:
:
return (
<>
:
:
<nav
className={`DrawerMenuRight ${isOpenRight && "DrawerMenuRight--isOpen"}`}
>
<ul>menu-right</ul>
</nav>
参考
https://medium.com/@albertchu539/how-to-make-an-app-drawer-with-react-hooks-and-css-1338ae57afb4
https://blog.logrocket.com/detect-click-outside-react-component-how-to/