From 83679e696bb2634a44c0041f8a93667ca912f1b9 Mon Sep 17 00:00:00 2001 From: Philipp Herz Date: Sun, 17 Dec 2023 19:03:56 +0100 Subject: [PATCH] Fixed the profile menu --- src/components/profile-menu/index.tsx | 29 ++++++++++++++++++--------- src/utils/clickAway.ts | 24 ++++++++++++++++++++++ 2 files changed, 43 insertions(+), 10 deletions(-) create mode 100644 src/utils/clickAway.ts diff --git a/src/components/profile-menu/index.tsx b/src/components/profile-menu/index.tsx index 4b33d11..59f06b8 100644 --- a/src/components/profile-menu/index.tsx +++ b/src/components/profile-menu/index.tsx @@ -4,16 +4,20 @@ import { Button, Menu, MenuHandler, MenuList } from '@material-tailwind/react'; -import React, { useEffect } from 'react'; +import React, { useEffect, useState } from 'react'; import { UserCircleIcon } from '@heroicons/react/24/outline'; import { useTheme } from '@/utils/theme'; import Link from 'next/link'; +import { useClickOutside } from '@/utils/clickAway'; import Icon, { ICON_SIZE } from '../icon'; import ThemeSwitch from '../theme-switch'; import { LinkText } from '../text'; const ProfileMenu = () => { const [theme, setTheme] = useTheme(); + const [open, setOpen] = useState(false); + + const ref = useClickOutside(() => open && setOpen(false)); useEffect(() => { document.documentElement.classList.remove('dark'); @@ -27,13 +31,13 @@ const ProfileMenu = () => { }[] = [ { item: - ( - - - Profile - - - ) + ( + + + Profile + + + ) }, { item: @@ -44,13 +48,18 @@ const ProfileMenu = () => {
- - + {items.map(({ item }) => (
{item} diff --git a/src/utils/clickAway.ts b/src/utils/clickAway.ts new file mode 100644 index 0000000..bfb08df --- /dev/null +++ b/src/utils/clickAway.ts @@ -0,0 +1,24 @@ +import { useEffect, useRef } from 'react'; + +export function useClickOutside(callback: () => void) { + const ref = useRef(null); + + useEffect(() => { + function handleClick(event: MouseEvent) { + const el = ref?.current; + // Do nothing if clicking ref's element or descendent elements + if (!el || el.contains(event.target as Node)) { + return; + } + + callback(); + } + + window?.addEventListener('mousedown', handleClick, { capture: true }); + return () => { + window?.removeEventListener('mousedown', handleClick, { capture: true }); + }; + }, [callback, ref]); + + return ref; +}