From 6d2bf057a54eedf3ebaa8e38b1c1a05a0e710199 Mon Sep 17 00:00:00 2001 From: julius Date: Tue, 11 Mar 2025 12:33:35 +0100 Subject: [PATCH] feat: more robust context menu --- src/App.css | 4 ++++ src/Avatar.tsx | 26 ++++++++++++++++++++------ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/src/App.css b/src/App.css index b78ffd3..f1cfd2e 100644 --- a/src/App.css +++ b/src/App.css @@ -400,6 +400,10 @@ button, width: fit-content; border: 3px solid black; margin: 0 auto 16px auto; + + ul { + min-width: 100px; + } } .user-info { diff --git a/src/Avatar.tsx b/src/Avatar.tsx index dca33bd..a0aaafb 100644 --- a/src/Avatar.tsx +++ b/src/Avatar.tsx @@ -51,7 +51,7 @@ export default function Avatar() { event.preventDefault(); setContextMenu({ open: !contextMenu.open, - allowOpen: false, + allowOpen: contextMenu.allowOpen, mouseX: event.clientX + 4, mouseY: event.clientY + 2, }); @@ -68,6 +68,16 @@ export default function Avatar() { const handleMenuClose = () => { setContextMenu({ ...contextMenu, open: false }); + setContextMenu((prevContextMenu) => ({ + ...prevContextMenu, + allowOpen: false, + })); + setTimeout(() => { + setContextMenu((prevContextMenu) => ({ + ...prevContextMenu, + allowOpen: true, + })); + }, 100); }; const handleCloseContextMenuOutside: (event: MouseEvent) => void = (ev) => { @@ -76,9 +86,8 @@ export default function Avatar() { contextMenuRef.current?.contains(ev.target as Node) || avatarRef.current?.contains(ev.target as Node) ) - ) { + ) handleMenuClose(); - } }; const [dialog, setDialog] = useState(<>); @@ -87,7 +96,6 @@ export default function Avatar() { function handleViewProfile() { handleMenuClose(); if (user) { - setContextMenu({ ...contextMenu, allowOpen: false }); dialogRef.current?.showModal(); setDialog(UserInfo(user)); } @@ -98,7 +106,13 @@ export default function Avatar() { className="avatar" onContextMenu={handleMenuClick} style={{ display: user ? "block" : "none" }} - onClick={handleMenuClick} + onClick={(event) => { + if (contextMenu.open && event.target === avatarRef.current) { + handleMenuClose(); + } else { + handleMenuClick(event); + } + }} ref={avatarRef} > 👤 {user?.username} @@ -140,8 +154,8 @@ export default function Avatar() { id="AvatarDialog" ref={dialogRef} onClick={(event) => { + event.stopPropagation(); event.currentTarget.close(); - setContextMenu({ ...contextMenu, allowOpen: true }); }} > {dialog}