forked from Navy.gif/webserver-framework-frontend
close element if clicked outside
This commit is contained in:
parent
74b4c343ea
commit
583e2eb8af
@ -1,24 +1,41 @@
|
||||
import React from "react";
|
||||
import React, { useRef } from "react";
|
||||
import '../css/components/UserControls.css';
|
||||
import { useLoginContext } from "../structures/UserContext";
|
||||
import ClickDetector from "../util/ClickDetector";
|
||||
import { clearSession, post } from "../util/Util";
|
||||
|
||||
const UserControls = () => {
|
||||
|
||||
const [user] = useLoginContext();
|
||||
const [user, updateUser] = useLoginContext();
|
||||
const detailsRef = useRef();
|
||||
|
||||
if (!user) return;
|
||||
|
||||
return <details className='dropdown user-controls'>
|
||||
<summary className="is-vertical-align">
|
||||
Hello {user.displayName}
|
||||
<img className="profile-picture" src="https://cdn.discordapp.com/avatars/187613017733726210/ee764860975d78bfd52652c6ddaed47b.webp?size=64"></img>
|
||||
</summary>
|
||||
<div className="card">
|
||||
<p><a href="#">Profile</a></p>
|
||||
<hr/>
|
||||
<p><a href="#" className="text-error">Logout</a></p>
|
||||
</div>
|
||||
</details>;
|
||||
const logOut = async () => {
|
||||
const response = await post('/api/logout');
|
||||
if (response.status === 200) {
|
||||
clearSession();
|
||||
updateUser();
|
||||
}
|
||||
};
|
||||
|
||||
return <ClickDetector callback={() => {
|
||||
if (detailsRef.current) detailsRef.current.removeAttribute('open');
|
||||
}}>
|
||||
<details ref={detailsRef} className='dropdown user-controls'>
|
||||
<summary className="is-vertical-align">
|
||||
Hello {user.displayName}
|
||||
<img className="profile-picture" src="https://cdn.discordapp.com/avatars/187613017733726210/ee764860975d78bfd52652c6ddaed47b.webp?size=64"></img>
|
||||
</summary>
|
||||
|
||||
<div className="card">
|
||||
<p><a href="#">Profile</a></p>
|
||||
<hr />
|
||||
<p><a onClick={logOut} href="#" className="text-error">Logout</a></p>
|
||||
</div>
|
||||
|
||||
</details>
|
||||
</ClickDetector >;
|
||||
|
||||
};
|
||||
|
||||
|
35
src/util/ClickDetector.js
Normal file
35
src/util/ClickDetector.js
Normal file
@ -0,0 +1,35 @@
|
||||
import React, { useEffect, useRef } from "react";
|
||||
|
||||
const alerter = (ref, callback) => {
|
||||
useEffect(() => {
|
||||
|
||||
const listener = (event) => {
|
||||
if (ref.current && !ref.current.contains(event.target)) {
|
||||
return callback();
|
||||
}
|
||||
};
|
||||
|
||||
document.addEventListener('mousedown', listener);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('mousedown', listener);
|
||||
};
|
||||
|
||||
}, [ref]);
|
||||
};
|
||||
|
||||
// Component wrapper to enable listening for clicks outside of the given component
|
||||
const ClickDetector = ({ children, callback }) => {
|
||||
|
||||
const wrapperRef = useRef(null);
|
||||
alerter(wrapperRef, callback);
|
||||
|
||||
return (
|
||||
<div ref={wrapperRef}>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
export default ClickDetector;
|
Reference in New Issue
Block a user