From 40f6547d99d4c0827784ffe531221de151117cb9 Mon Sep 17 00:00:00 2001 From: Max <133934232+Kleostro@users.noreply.github.com> Date: Fri, 10 May 2024 14:30:43 +0300 Subject: [PATCH] feat(RSS-ECOMM-3_33): implement burger menu (#221) feat: implement burger menu --- src/app/styles/variables.scss | 1 + .../Navigation/view/NavigationView.ts | 2 +- .../view/navigationView.module.scss | 3 +- .../view/notFoundPageView.module.scss | 8 +- src/shared/img/svg/cat.svg | 256 ------------------ src/shared/img/svg/dark.svg | 3 + src/shared/img/svg/drop.svg | 10 + src/shared/img/svg/heartFill.svg | 3 + src/shared/img/svg/heartOutline.svg | 3 + src/shared/img/svg/house.svg | 3 + src/shared/img/svg/light.svg | 10 + src/shared/img/svg/plant.svg | 10 + src/shared/img/svg/search.svg | 3 + src/shared/img/svg/settings.svg | 3 + .../Catalog/view/catalogView.module.scss | 22 +- src/widgets/Header/model/HeaderModel.ts | 1 - src/widgets/Header/view/HeaderView.ts | 59 +++- .../Header/view/headerView.module.scss | 139 +++++++++- .../LoginForm/view/loginForm.module.scss | 1 + .../view/registrationForm.module.scss | 3 +- 20 files changed, 266 insertions(+), 277 deletions(-) delete mode 100644 src/shared/img/svg/cat.svg create mode 100644 src/shared/img/svg/dark.svg create mode 100644 src/shared/img/svg/drop.svg create mode 100644 src/shared/img/svg/heartFill.svg create mode 100644 src/shared/img/svg/heartOutline.svg create mode 100644 src/shared/img/svg/house.svg create mode 100644 src/shared/img/svg/light.svg create mode 100644 src/shared/img/svg/plant.svg create mode 100644 src/shared/img/svg/search.svg create mode 100644 src/shared/img/svg/settings.svg diff --git a/src/app/styles/variables.scss b/src/app/styles/variables.scss index f0e0c8b1..a1a72362 100644 --- a/src/app/styles/variables.scss +++ b/src/app/styles/variables.scss @@ -48,5 +48,6 @@ --small-br: 5px; --medium-br: 5px; --large-br: 10px; + --regular-font: 400 10px 'Cerapro', sans-serif; } } diff --git a/src/entities/Navigation/view/NavigationView.ts b/src/entities/Navigation/view/NavigationView.ts index f544dff0..6874485e 100644 --- a/src/entities/Navigation/view/NavigationView.ts +++ b/src/entities/Navigation/view/NavigationView.ts @@ -36,9 +36,9 @@ class NavigationView { tag: 'nav', }); this.navigation.append( - this.toMainLink.getHTML(), this.toLoginLink.getHTML(), this.toRegisterLink.getHTML(), + this.toMainLink.getHTML(), this.toCatalogLink.getHTML(), this.toAboutLink.getHTML(), ); diff --git a/src/entities/Navigation/view/navigationView.module.scss b/src/entities/Navigation/view/navigationView.module.scss index a54eba4d..d241dfc4 100644 --- a/src/entities/Navigation/view/navigationView.module.scss +++ b/src/entities/Navigation/view/navigationView.module.scss @@ -4,14 +4,15 @@ align-self: center; justify-content: center; order: 2; + margin: 0 auto; height: 70px; - gap: var(--extra-small-offset); } .link { position: relative; display: flex; align-items: center; + padding: 0 calc(var(--extra-small-offset) / 2); height: 100%; font: var(--regular-font); letter-spacing: 1px; diff --git a/src/pages/NotFoundPage/view/notFoundPageView.module.scss b/src/pages/NotFoundPage/view/notFoundPageView.module.scss index 00192d75..1a10ac8a 100644 --- a/src/pages/NotFoundPage/view/notFoundPageView.module.scss +++ b/src/pages/NotFoundPage/view/notFoundPageView.module.scss @@ -2,9 +2,11 @@ position: relative; display: flex; flex-direction: column; - margin: 0 auto; + align-self: center; + margin: 0 var(--small-offset); border-bottom: calc(var(--extra-small-offset) / 2) solid var(--steam-green-800); - padding: calc(var(--extra-large-offset) / 2) var(--extra-large-offset); + border-radius: var(--medium-br); + padding: var(--small-offset); padding-bottom: calc(var(--extra-large-offset) / 2 + calc(var(--extra-small-offset) / 2)); max-width: 500px; background-color: var(--white); @@ -50,8 +52,10 @@ } .toMainButton { + align-self: center; border-radius: var(--small-br); padding: calc(var(--extra-small-offset) / 2) var(--small-offset); + width: max-content; font: var(--bold-font); letter-spacing: 1px; color: var(--white); diff --git a/src/shared/img/svg/cat.svg b/src/shared/img/svg/cat.svg deleted file mode 100644 index d95e2f33..00000000 --- a/src/shared/img/svg/cat.svg +++ /dev/null @@ -1,256 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/src/shared/img/svg/dark.svg b/src/shared/img/svg/dark.svg new file mode 100644 index 00000000..52a09c06 --- /dev/null +++ b/src/shared/img/svg/dark.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/shared/img/svg/drop.svg b/src/shared/img/svg/drop.svg new file mode 100644 index 00000000..42d5a616 --- /dev/null +++ b/src/shared/img/svg/drop.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/shared/img/svg/heartFill.svg b/src/shared/img/svg/heartFill.svg new file mode 100644 index 00000000..a966541e --- /dev/null +++ b/src/shared/img/svg/heartFill.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/shared/img/svg/heartOutline.svg b/src/shared/img/svg/heartOutline.svg new file mode 100644 index 00000000..f03bfb5c --- /dev/null +++ b/src/shared/img/svg/heartOutline.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/shared/img/svg/house.svg b/src/shared/img/svg/house.svg new file mode 100644 index 00000000..05834259 --- /dev/null +++ b/src/shared/img/svg/house.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/shared/img/svg/light.svg b/src/shared/img/svg/light.svg new file mode 100644 index 00000000..f22381e4 --- /dev/null +++ b/src/shared/img/svg/light.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/shared/img/svg/plant.svg b/src/shared/img/svg/plant.svg new file mode 100644 index 00000000..cecc5817 --- /dev/null +++ b/src/shared/img/svg/plant.svg @@ -0,0 +1,10 @@ + + + + + + + + + + diff --git a/src/shared/img/svg/search.svg b/src/shared/img/svg/search.svg new file mode 100644 index 00000000..05834259 --- /dev/null +++ b/src/shared/img/svg/search.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/shared/img/svg/settings.svg b/src/shared/img/svg/settings.svg new file mode 100644 index 00000000..05834259 --- /dev/null +++ b/src/shared/img/svg/settings.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/widgets/Catalog/view/catalogView.module.scss b/src/widgets/Catalog/view/catalogView.module.scss index e7ce5615..3c4d88cc 100644 --- a/src/widgets/Catalog/view/catalogView.module.scss +++ b/src/widgets/Catalog/view/catalogView.module.scss @@ -1,12 +1,12 @@ -.catalog { - display: flex; - width: 500px; - height: 500px; - background-color: var(--noble-gray-300); -} +// .catalog { +// display: flex; +// width: 500px; +// height: 500px; +// background-color: var(--noble-gray-300); +// } -.itemsList { - width: 500px; - height: 500px; - background-color: var(--noble-gray-800); -} +// .itemsList { +// width: 500px; +// height: 500px; +// background-color: var(--noble-gray-800); +// } diff --git a/src/widgets/Header/model/HeaderModel.ts b/src/widgets/Header/model/HeaderModel.ts index 25c9f439..fb1606a7 100644 --- a/src/widgets/Header/model/HeaderModel.ts +++ b/src/widgets/Header/model/HeaderModel.ts @@ -56,7 +56,6 @@ class HeaderModel { private init(): boolean { this.view.getWrapper().append(this.navigation.getHTML()); - this.checkAuthUser(); this.checkCurrentUser(); this.setLogoHandler(); this.observeCurrentUser(); diff --git a/src/widgets/Header/view/HeaderView.ts b/src/widgets/Header/view/HeaderView.ts index a7a175b0..10fc3a63 100644 --- a/src/widgets/Header/view/HeaderView.ts +++ b/src/widgets/Header/view/HeaderView.ts @@ -13,6 +13,8 @@ import observeCurrentLanguage from '@/shared/utils/observeCurrentLanguage.ts'; import styles from './headerView.module.scss'; class HeaderView { + private burgerButton: ButtonModel; + private header: HTMLElement; private linkLogo: LinkModel; @@ -36,8 +38,50 @@ class HeaderView { this.toProfileLink = this.createToProfileLink(); this.switchLanguageButton = this.createSwitchLanguageButton(); this.navigationWrapper = this.createNavigationWrapper(); + this.burgerButton = this.createBurgerButton(); this.wrapper = this.createWrapper(); this.header = this.createHTML(); + + document.addEventListener('click', ({ target }) => { + if ( + target !== this.navigationWrapper && + this.burgerButton.getHTML().classList.contains(styles.open) && + target !== this.burgerButton.getHTML() + ) { + this.burgerButton.getHTML().classList.toggle(styles.open); + this.navigationWrapper.classList.toggle(styles.open); + document.body.classList.toggle(styles.stopScroll); + } + }); + } + + private createBurgerButton(): ButtonModel { + this.burgerButton = new ButtonModel({ + classes: [styles.burgerButton], + }); + + const burgerLine1 = createBaseElement({ + cssClasses: [styles.burgerLine], + tag: 'span', + }); + const burgerLine2 = createBaseElement({ + cssClasses: [styles.burgerLine], + tag: 'span', + }); + const burgerLine3 = createBaseElement({ + cssClasses: [styles.burgerLine], + tag: 'span', + }); + + this.burgerButton.getHTML().addEventListener('click', () => { + this.burgerButton.getHTML().classList.toggle(styles.open); + this.navigationWrapper.classList.toggle(styles.open); + document.body.classList.toggle(styles.stopScroll); + }); + + this.burgerButton.getHTML().append(burgerLine1, burgerLine2, burgerLine3); + + return this.burgerButton; } private createHTML(): HTMLElement { @@ -92,6 +136,7 @@ class HeaderView { this.toCartLink.getHTML(), this.toProfileLink.getHTML(), ); + return this.navigationWrapper; } @@ -174,10 +219,14 @@ class HeaderView { tag: 'div', }); - this.wrapper.append(this.linkLogo.getHTML(), this.navigationWrapper); + this.wrapper.append(this.linkLogo.getHTML(), this.navigationWrapper, this.burgerButton.getHTML()); return this.wrapper; } + public getBurgerButton(): ButtonModel { + return this.burgerButton; + } + public getHTML(): HTMLElement { return this.header; } @@ -205,6 +254,14 @@ class HeaderView { public getWrapper(): HTMLDivElement { return this.wrapper; } + + public hideNavigationWrapper(): void { + this.navigationWrapper.classList.add(styles.hidden); + } + + public showNavigationWrapper(): void { + this.navigationWrapper.classList.remove(styles.hidden); + } } export default HeaderView; diff --git a/src/widgets/Header/view/headerView.module.scss b/src/widgets/Header/view/headerView.module.scss index 36a4e71b..e634af5a 100644 --- a/src/widgets/Header/view/headerView.module.scss +++ b/src/widgets/Header/view/headerView.module.scss @@ -15,14 +15,33 @@ margin: 0 auto; padding: 0 var(--small-offset); max-width: 1440px; + + @media (max-width: 576px) { + padding: 0 var(--extra-small-offset); + } } .navigationWrapper { + position: fixed; + right: -100%; + top: 0; + z-index: 2; display: flex; + flex-direction: column; align-items: center; order: 3; - margin-left: auto; - gap: var(--extra-small-offset); + padding: 70px var(--extra-small-offset) 0; + width: 20%; + height: 100%; + background-color: #8c998f2b; + transform: none; + transition: transform 0.3s; + backdrop-filter: blur(2px); + gap: var(--medium-offset); + + &.open { + transform: translateX(-500%); + } } .switchLanguageButton { @@ -50,7 +69,6 @@ .logo { order: 1; - margin-right: auto; width: 40px; height: 40px; @@ -68,6 +86,16 @@ } } } + + @media (max-width: 576px) { + width: 30px; + height: 30px; + + svg { + width: 30px; + height: 30px; + } + } } .logoutButton { @@ -160,3 +188,108 @@ .hidden { display: none; } + +.burgerButton { + position: relative; + z-index: 10; + order: 4; + width: 25px; + height: 20px; +} + +.burgerLine { + position: absolute; + border-radius: 2px; + background-color: var(--steam-green-800); + transition: 0.3s cubic-bezier(0.8, 0.5, 0.2, 1.4); + pointer-events: none; +} + +.burgerButton:hover .burgerLine:nth-child(1), +.burgerButton:hover .burgerLine:nth-child(2), +.burgerButton:hover .burgerLine:nth-child(3) { + background-color: var(--steam-green-700); +} + +.burgerButton:not(.open):hover .burgerLine:nth-child(1), +.burgerButton:not(.open):hover .burgerLine:nth-child(2), +.burgerButton:not(.open):hover .burgerLine:nth-child(3) { + left: 0; + display: block; + width: 100%; + height: 2px; + transition: 0.3s cubic-bezier(0.8, 0.5, 0.2, 1.4); +} + +.burgerButton:not(.open):hover .burgerLine:nth-child(1) { + top: -2px; +} + +.burgerButton:not(.open):hover .burgerLine:nth-child(2) { + top: 9px; +} + +.burgerButton:not(.open):hover .burgerLine:nth-child(3) { + bottom: -2px; +} + +.burgerButton > .burgerLine:nth-child(1), +.burgerButton > .burgerLine:nth-child(2), +.burgerButton > .burgerLine:nth-child(3) { + position: absolute; + left: 0; + display: block; + width: 100%; + height: 2px; +} + +.burgerButton > .burgerLine:nth-child(1) { + top: 0; +} + +.burgerButton > .burgerLine:nth-child(2) { + top: 9px; +} + +.burgerButton > .burgerLine:nth-child(3) { + bottom: 0; +} + +.burgerButton.open { + transform: rotate(-90deg); +} + +.burgerButton.open .burgerLine:nth-child(1), +.burgerButton.open .burgerLine:nth-child(2), +.burgerButton.open .burgerLine:nth-child(3) { + background-color: var(--steam-green-800); + transition: 0.3s cubic-bezier(0.8, 0.5, 0.2, 1.4); +} + +.burgerButton.open .burgerLine:nth-child(1) { + left: 5px; + top: 12px; + width: 20px; + transform: rotate(90deg); + transition-delay: 150ms; +} + +.burgerButton.open .burgerLine:nth-child(2) { + left: 3px; + top: 17px; + width: 15px; + transform: rotate(45deg); + transition-delay: 50ms; +} + +.burgerButton.open .burgerLine:nth-child(3) { + left: 13px; + top: 17px; + width: 14px; + transform: rotate(-45deg); + transition-delay: 100ms; +} + +.stopScroll { + overflow: hidden; +} diff --git a/src/widgets/LoginForm/view/loginForm.module.scss b/src/widgets/LoginForm/view/loginForm.module.scss index a18626cf..66481a1a 100644 --- a/src/widgets/LoginForm/view/loginForm.module.scss +++ b/src/widgets/LoginForm/view/loginForm.module.scss @@ -88,6 +88,7 @@ height: 24px; background-color: transparent; transform: translate(-12%, 0); + cursor: pointer; svg { width: 20px; diff --git a/src/widgets/RegistrationForm/view/registrationForm.module.scss b/src/widgets/RegistrationForm/view/registrationForm.module.scss index f92b5577..3fc6024f 100644 --- a/src/widgets/RegistrationForm/view/registrationForm.module.scss +++ b/src/widgets/RegistrationForm/view/registrationForm.module.scss @@ -119,6 +119,7 @@ height: 24px; background-color: transparent; transform: translate(-12%, 0); + cursor: pointer; svg { width: 20px; @@ -146,7 +147,7 @@ } @media (max-width: 768px) { - top: 24px; + top: 18px; } }