feat: update context menu to use references

This commit is contained in:
julius 2025-03-11 11:04:42 +01:00
parent aa3c3df5da
commit 26ee4b84a9
Signed by: julius
GPG Key ID: C80A63E6A5FD7092

View File

@ -1,4 +1,4 @@
import { MouseEventHandler, useEffect, useState } from "react"; import { createRef, MouseEventHandler, useEffect, useState } from "react";
import { useSession } from "./Session"; import { useSession } from "./Session";
interface ContextMenuItem { interface ContextMenuItem {
@ -13,11 +13,12 @@ export default function Avatar() {
mouseX: number; mouseX: number;
mouseY: number; mouseY: number;
}>({ open: false, mouseX: 0, mouseY: 0 }); }>({ open: false, mouseX: 0, mouseY: 0 });
const contextMenuRef = createRef<HTMLUListElement>();
const avatarRef = createRef<HTMLDivElement>();
const contextMenuItems: ContextMenuItem[] = [ const contextMenuItems: ContextMenuItem[] = [
{ label: "View Profile", onClick: () => console.log("View Profile") }, { label: "View Profile", onClick: handleViewProfile },
{ label: "Edit Profile", onClick: () => console.log("Edit Profile") }, { label: "Logout", onClick: onLogout },
{ label: "Logout", onClick: () => onLogout() },
]; ];
const handleMenuClick: MouseEventHandler<HTMLDivElement> = (event) => { const handleMenuClick: MouseEventHandler<HTMLDivElement> = (event) => {
@ -40,29 +41,43 @@ export default function Avatar() {
const handleMenuClose = () => { const handleMenuClose = () => {
setContextMenu({ ...contextMenu, open: false }); setContextMenu({ ...contextMenu, open: false });
}; };
const handleCloseContextMenuOutside: MouseEventHandler<Document> = ( const handleCloseContextMenuOutside: (event: MouseEvent) => void = (ev) => {
event
) => {
if ( if (
!event.target || !(
(!(event.target as Element).closest(".context-menu") && contextMenuRef.current?.contains(ev.target as Node) ||
!(event.target as Element).closest(".avatar")) avatarRef.current?.contains(ev.target as Node)
)
) { ) {
handleMenuClose(); handleMenuClose();
} }
}; };
const [dialog, setDialog] = useState(<></>);
const dialogRef = createRef<HTMLDialogElement>();
function handleViewProfile() {
handleMenuClose();
dialogRef.current?.showModal();
setDialog(
<ul>
<li>username: {user?.username}</li>
</ul>
);
}
return ( return (
<div <div
className="avatar" className="avatar"
onContextMenu={handleMenuClick} onContextMenu={handleMenuClick}
style={{ display: user ? "block" : "none" }} style={{ display: user ? "block" : "none" }}
onClick={handleMenuClick} onClick={handleMenuClick}
ref={avatarRef}
> >
{user?.username} 👤 {user?.username}
{contextMenu.open && ( {contextMenu.open && (
<ul <ul
className="context-menu" className="context-menu"
ref={contextMenuRef}
style={{ style={{
zIndex: 3, zIndex: 3,
position: "absolute", position: "absolute",
@ -93,6 +108,15 @@ export default function Avatar() {
))} ))}
</ul> </ul>
)} )}
<dialog
id="AvatarDialog"
ref={dialogRef}
onClick={(event) => {
event.currentTarget.close();
}}
>
{dialog}
</dialog>
</div> </div>
); );
} }