From f070ed8bb7a952a418a57d1040bbe74c1a813d1f Mon Sep 17 00:00:00 2001 From: Yehor Potebenko <hitechnic.uu68@gmail.com> Date: Fri, 14 Apr 2023 08:18:24 +0200 Subject: [PATCH] feat: add display logic to popups --- src/js/modules/main/Popup.mjs | 71 +++++++++++++++++++++++++++++++++++ src/pages/main/index.html | 10 ++--- src/pages/main/script.mjs | 30 +++++++++++++++ src/pages/main/style.scss | 20 ++++++++++ 4 files changed, 126 insertions(+), 5 deletions(-) create mode 100644 src/js/modules/main/Popup.mjs diff --git a/src/js/modules/main/Popup.mjs b/src/js/modules/main/Popup.mjs new file mode 100644 index 0000000..27e0c12 --- /dev/null +++ b/src/js/modules/main/Popup.mjs @@ -0,0 +1,71 @@ +const TIMEOUT = 800; +let unlock = true; + +const lockPaddingElements = document.querySelectorAll('.lock-padding'); + +function bodyLock() { + const lockPaddingValue = `${ + window.innerWidth - document.querySelector('.wrapper').offsetWidth + }px`; + + if (lockPaddingValue.length > 0) + for (let i = 0; i < lockPaddingElements.length; i++) { + const el = lockPaddingElements[i]; + el.style.paddingRight = lockPaddingValue; + } + + document.body.style.paddingRight = lockPaddingValue; + document.body.classList.add('lock'); + + unlock = false; + setTimeout(() => { + unlock = true; + }, TIMEOUT); +} + +function bodyUnlock() { + setTimeout(() => { + for (let i = 0; i < lockPaddingElements.length; i++) { + const el = lockPaddingElements[i]; + el.style.paddingRight = '0px'; + } + + document.body.style.paddingRight = '0px'; + document.body.classList.remove('lock'); + }, TIMEOUT); + + unlock = false; + setTimeout(() => { + unlock = true; + }, TIMEOUT); +} + +export default class Popup { + static close(popupActive, doUnlock = true) { + if (unlock) { + popupActive.classList.remove('open'); + if (doUnlock) bodyUnlock(); + } + } + + static closeOnEscape(event) { + if (event.key === 'Escape') { + const popupActive = document.querySelector('.popup.open'); + this.close(popupActive); + } + } + + static open(currentPopup) { + if (currentPopup && unlock) { + const popupActive = document.querySelector('.popup.open'); + + if (popupActive) this.close(popupActive, false); + else bodyLock(); + + currentPopup.classList.add('open'); + currentPopup.addEventListener('click', (e) => { + if (!e.target.closest('.popup__content')) this.close(e.target.closest('.popup')); + }); + } + } +} diff --git a/src/pages/main/index.html b/src/pages/main/index.html index 68c83c0..61cd90f 100644 --- a/src/pages/main/index.html +++ b/src/pages/main/index.html @@ -9,12 +9,12 @@ <body> <div class="wrapper"> <!-- * HEADER --> - <header class="header"> + <header class="header lock-padding"> <div class="header__container _container"> <nav class="header__body"> <ul class="header__menu menu"> <li class="menu__item"> - <a href="#"> + <a href="#todo-popup" class="menu__link popup-link"> <img class="menu__item_img" src="../../assets/images/main/icons/tasks.svg" @@ -23,7 +23,7 @@ </a> </li> <li class="menu__item"> - <a href="#"> + <a href="#" class="menu__link popup-link"> <img class="menu__item_img" src="../../assets/images/main/icons/profile.svg" @@ -52,10 +52,10 @@ </main> <!-- * TODO POPUP --> - <div class="todo-popup popup"> + <div id="todo-popup" class="todo-popup popup"> <div class="todo-popup__body popup__body"> <div class="todo-popup__content popup__content"> - <a href="#" class="todo-popup__close popup__close" + <a href="#header" class="todo-popup__close popup__close" ><img src="../../assets/images/main/icons/close.svg" alt="Close Modal" diff --git a/src/pages/main/script.mjs b/src/pages/main/script.mjs index 94fbf42..34d8236 100644 --- a/src/pages/main/script.mjs +++ b/src/pages/main/script.mjs @@ -1,2 +1,32 @@ import './index.html'; import './style.scss'; +import Popup from '../../js/modules/main/Popup.mjs'; + +const popupLinks = document.querySelectorAll('.popup-link'); +const popupCloseIcon = document.querySelectorAll('.popup__close'); + +document.addEventListener('keydown', (e) => { + Popup.closeOnEscape(e); +}); + +if (popupLinks.length > 0) + for (let i = 0; i < popupLinks.length; i++) { + const popupLink = popupLinks[i]; + + popupLink.addEventListener('click', (e) => { + const popupName = popupLink.getAttribute('href').replace('#', ''); + const currentPopup = document.getElementById(popupName); + Popup.open(currentPopup); + e.preventDefault(); + }); + } + +if (popupCloseIcon.length > 0) + for (let i = 0; i < popupCloseIcon.length; i++) { + const el = popupCloseIcon[i]; + + el.addEventListener('click', (e) => { + Popup.close(el.closest('.popup')); + e.preventDefault(); + }); + } diff --git a/src/pages/main/style.scss b/src/pages/main/style.scss index e041487..aa175eb 100644 --- a/src/pages/main/style.scss +++ b/src/pages/main/style.scss @@ -11,6 +11,12 @@ @include _container(1370px, 10px); } +body { + &.lock { + overflow: hidden; + } +} + .header { position: fixed; top: 0; @@ -74,6 +80,9 @@ width: 100%; height: 100%; background: $transparent-dark-red; + opacity: 0; + visibility: hidden; + transition: all 0.8s ease 0s; z-index: 999; &__body { @@ -86,6 +95,8 @@ &__content { text-align: right; + transition: all 0.8s ease 0s; + transform: perspective(600px) translate(0px, -100%) rotateX(45deg); > * { &:first-child { @@ -93,6 +104,15 @@ } } } + + &.open { + opacity: 1; + visibility: visible; + } + + &.open &__content { + transform: perspective(600px) translate(0px, 0%) rotateX(0deg); + } } .todo-popup { -- GitLab