content logo

React Popups:

Animating Toggle Popup Menu with React JS

The pop-up we have in this post, as you can see, has animation. This pop-up opens by clicking on the button in the middle and top of the page. The pop-up opens just below the button and is displayed animated from the left corner. The corners of this pop-up are curved.

#

Tiny React Popup Code

#

React Popup Menu

#

Animating Popup Code

#

CSS Dynamic Toggle Menu

<!-- This script got from frontendfreecode.com -->
<div id="app"></div><a style="font-size: 8pt; text-decoration: none" target="_blank" href="http://frontendfreecode.com">Free Frontend</a>
                                                                            
body, * {
  margin: 0;
  padding: 0;
}
#app {
  height: 100vh;
  background: #eee;
}
.container {
  display: flex;
  align-items: center;
  justify-content: center;
}
.popup-menu-container {
  position: relative;
}
.popup-menu {
  position: absolute;
  z-index: 2;
  transform: scale(0);
  transform-origin: top left;
  width: 10rem;
  margin-top: 0.5rem;
  padding: 1rem;
  background: #fff;
  border-radius: 0.5rem;
  transition: transform 0.2s;
}
.popup-menu.shown {
  transform: scale(1);
}
const { useState, useEffect, useRef } = React;
const PopupMenu = () => {
    const [isShown, setIsShown] = useState(false);
    const popupRef = useRef();
    const documentClickHandler = useRef();
    useEffect(() => {
        documentClickHandler.current = e => {
            console.log('documentClickHandler');
            if (popupRef.current.contains(e.target)) return;
            setIsShown(false);
            removeDocumentClickHandler();
        };
    }, []);
    const removeDocumentClickHandler = () => {
        console.log('removeDocumentClickHandler');
        document.removeEventListener('click', documentClickHandler.current);
    };
    const handleToggleButtonClick = () => {
        console.log('handleToggleButtonClick');
        if (isShown) return;
        setIsShown(true);
        document.addEventListener('click', documentClickHandler.current);
    };
    const handleCloseButtonClick = () => {
        console.log('handleCloseButtonClick');
        setIsShown(false);
        removeDocumentClickHandler();
    };
    return /*#__PURE__*/(
        React.createElement("div", { className: "popup-menu-container" }, /*#__PURE__*/
            React.createElement("button", { onClick: handleToggleButtonClick }, "Toggle Menu"), /*#__PURE__*/
            React.createElement("div", {
                className: `popup-menu ${isShown ? 'shown' : ''}`,
                ref: popupRef
            }, /*#__PURE__*/
                React.createElement("div", null, "menu"), /*#__PURE__*/
                React.createElement("button", { onClick: handleCloseButtonClick }, "Close Menu"))));
};
const App = () => /*#__PURE__*/
    React.createElement("div", { className: "container" }, /*#__PURE__*/
        React.createElement(PopupMenu, null));
ReactDOM.render( /*#__PURE__*/React.createElement(App, null), document.getElementById('app'));
<script src='https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js'></script>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- This script got from frontendfreecode.com -->

<script src='https://cdnjs.cloudflare.com/ajax/libs/react/16.10.2/umd/react.production.min.js'></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.10.2/umd/react-dom.production.min.js'></script>
<style>
body, * {
  margin: 0;
  padding: 0;
}
#app {
  height: 100vh;
  background: #eee;
}
.container {
  display: flex;
  align-items: center;
  justify-content: center;
}
.popup-menu-container {
  position: relative;
}
.popup-menu {
  position: absolute;
  z-index: 2;
  transform: scale(0);
  transform-origin: top left;
  width: 10rem;
  margin-top: 0.5rem;
  padding: 1rem;
  background: #fff;
  border-radius: 0.5rem;
  transition: transform 0.2s;
}
.popup-menu.shown {
  transform: scale(1);
}
</style>

</head>
<body>
<div id="app"></div><div id="bcl"><a style="font-size:8pt;text-decoration:none;" href="http://www.devanswer.com">Free Frontend</a></div>
<script>
const { useState, useEffect, useRef } = React;
const PopupMenu = () => {
    const [isShown, setIsShown] = useState(false);
    const popupRef = useRef();
    const documentClickHandler = useRef();
    useEffect(() => {
        documentClickHandler.current = e => {
            console.log('documentClickHandler');
            if (popupRef.current.contains(e.target)) return;
            setIsShown(false);
            removeDocumentClickHandler();
        };
    }, []);
    const removeDocumentClickHandler = () => {
        console.log('removeDocumentClickHandler');
        document.removeEventListener('click', documentClickHandler.current);
    };
    const handleToggleButtonClick = () => {
        console.log('handleToggleButtonClick');
        if (isShown) return;
        setIsShown(true);
        document.addEventListener('click', documentClickHandler.current);
    };
    const handleCloseButtonClick = () => {
        console.log('handleCloseButtonClick');
        setIsShown(false);
        removeDocumentClickHandler();
    };
    return /*#__PURE__*/(
        React.createElement("div", { className: "popup-menu-container" }, /*#__PURE__*/
            React.createElement("button", { onClick: handleToggleButtonClick }, "Toggle Menu"), /*#__PURE__*/
            React.createElement("div", {
                className: `popup-menu ${isShown ? 'shown' : ''}`,
                ref: popupRef
            }, /*#__PURE__*/
                React.createElement("div", null, "menu"), /*#__PURE__*/
                React.createElement("button", { onClick: handleCloseButtonClick }, "Close Menu"))));
};
const App = () => /*#__PURE__*/
    React.createElement("div", { className: "container" }, /*#__PURE__*/
        React.createElement(PopupMenu, null));
ReactDOM.render( /*#__PURE__*/React.createElement(App, null), document.getElementById('app'));
</script>

</body>
</html>
Preview