I am working on a website and currently i am having an svg icon for logout. when icon is clicked an overlay is popped up with signout option. when user clicks on signout it should do certain operation and when user clicks outside div overlay should be hidden. i am failing to achieve this.
i tried to give focus to div by using tabIndex but then signout option is not clickable anymore.
Header.js
import React, { Component } from "react";
import ReactDOM from "react-dom";
class MainHeader extends React.Component {
constructor(props) {
super(props);
this.state = {
logOutShown: false
};
}
render() {
var guiResult = [];
if (this.state.logOutShown) {
guiResult.push(
<div className="Login__Overlay__Frame">
<div className="User__Login__Overlay">
<div className="Login__Content" tabIndex="1" onFocus={this.alerting.bind(this)} onBlur={this.toggleOverlay.bind(this)}>Signout</div>
</div>
</div>
);
}
return (
<div className="Header__Icon">
<div className="Icons__Log__In" tabIndex="0" onClick={this.validate.bind(this)} onBlur={this.toggleOverlay.bind(this)}/>
{guiResult}
</div>
);
}
toggleOverlay(){
console.log("toggle overlay");
this.setState({ logOutShown: false});
}
validate() {
console.log("validate:");
this.setState(
{
logOutShown: true
}
);
}
Detecting an outside click of a functional component Let's build an HTML tooltip by creating a React functional component named InfoBox . The tooltip will appear when the user clicks a button, and it will be closed if the user clicks outside of the tooltip component.
So, for detecting a click outside an element, it would be best if you add a listener to the whole document element. Consequently, the main loop will go up the DOM from the clicked target element to search if the ancestor of that element belongs to the flyout container.
We will detect the click event and use it to close the dropdown ui component when the user clicks outside the element scope in React application. To give you the clear picture, we will start with creating a basic app, creating component, design dropdown using custom CSS.
Here we go: abandon stop propagation, go back to listening to the document object, and use the node. contains API to determine whether a click event happens outside the dropdown menu. If it does, hide the dropdown menu, since we need to use ref to save the DOM node in React in order to use the API.
You can use a well writen library like this one: react-outside-click-handler
example:
import OutsideClickHandler from 'react-outside-click-handler';
function MyComponent() {
return (
<OutsideClickHandler
onOutsideClick={() => {
alert('You clicked outside of this component!!!');
}}
>
Hello World
</OutsideClickHandler>
);
}
Edit:
As I am editing this comment today, a lot of new library bring this feature to your code.
If you use a components library check if an util exists in it. (chakra, mantine, material-ui).
Other solution exists inside hooks libraries like react-use.
Here is a simple example, I'm using React hooks here instead of classes, but you can use classes too..
The main part is the onClick on the container div, if you run the example below and click on the dialog it won't close it, but clicking on the overlay will.
The e.stopPropagation()
on the container div is what stops the events on the contents firing the events on the overlay. Instead of using stopPropagation
, another option is checking the target
& currentTarget
inside the overlay onClick..
const {useState} = React;
function Overlay(props) {
const {contents} = props;
const [open, setOpen] = useState(true);
if (open) {
return <div className="overlay" onClick={() => setOpen(false)}>
<div onClick={(e) => {
//stop clicks getting to the overlay
e.stopPropagation();
}}className="overlay-container">
{contents()}
</div>
</div>
}
return null;
}
ReactDOM.render(<React.Fragment>
This is some content to overlay.<br/>
for testing..
<Overlay contents={() =>
<div>This is the contents, clicking here wont effect ovelay</div>
}/>
</React.Fragment>, document.querySelector('#mount'));
.overlay {
position: fixed;
background-color: rgba(100,100,100,0.5);
left: 0;
top: 0;
bottom: 0;
right: 0;
}
.overlay-container {
border: 1px solid black;
background-color: white;
position: absolute;
top: 30px;
left: 30px;
width: 200px;
height: 80px;
padding: 5px;
}
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div id="mount"></div>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With