Skip to content

Commit

Permalink
Merge pull request #86 from geo-milev/refactor-navbar
Browse files Browse the repository at this point in the history
Refactor Navbar.svelte
  • Loading branch information
MihailMihov authored Sep 26, 2023
2 parents 6cf5c7d + 615f4c4 commit 55f1542
Show file tree
Hide file tree
Showing 4 changed files with 457 additions and 384 deletions.
173 changes: 173 additions & 0 deletions src/lib/DesktopNav.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
<script>
export let scrollMode;
export let navigationLinksLeft;
export let navigationLinksRight;
let shownSubsectionsHref = ""
let shownSubsectionLeftShift = 0;
let leftNavWidth;
let rightNavWidth;
</script>

<nav class:scrolled="{scrollMode}" class="left-nav" bind:clientWidth={leftNavWidth}>
{#each navigationLinksLeft as navigationLink, index (navigationLink.key)}
{#if !navigationLink.subsections}
<a href="{navigationLink.href}">{navigationLink.key}</a>
{:else}
<div on:mouseenter={(event) => {
shownSubsectionLeftShift = event.target.offsetLeft
shownSubsectionsHref = navigationLink.key
}}
on:mouseleave="{() => { shownSubsectionsHref = '' }}"
class="subsection-container">
<span>{navigationLink.key}</span>
<div class="subsections"
style="--subsection-width: {leftNavWidth}px"
class:open={shownSubsectionsHref === navigationLink.key}>
<div class="subsection-top">
<div class="subsection-line"></div>
<span class="subsection-title"
style="--subsection-left-shift: {shownSubsectionLeftShift - 10}px">
{navigationLink.key}</span>
</div>
{#each navigationLink.subsections as subsection}
<a href="{subsection.href}">{subsection.key}</a>
{/each}
</div>
</div>
{/if}
{/each}
</nav>

<nav class:scrolled="{scrollMode}" class="right-nav" bind:clientWidth={rightNavWidth}>
{#each navigationLinksRight as navigationLink}
{#if !navigationLink.subsections}
<a href="{navigationLink.href}">{navigationLink.key}</a>
{:else}
<div on:mouseenter={(event) => {
shownSubsectionLeftShift = event.target.offsetLeft
shownSubsectionsHref = navigationLink.href
}}
on:mouseleave="{() => { shownSubsectionsHref = '' }}"
class="subsection-container">
<span>{navigationLink.key}</span>
{#if shownSubsectionsHref === navigationLink.href}
<div class="subsections" style="--subsection-width: {rightNavWidth + 'px'}">
<div class="subsection-top">
<div class="subsection-line"></div>
<span class="subsection-title"
style="--subsection-left-shift: {shownSubsectionLeftShift - 10}px">{navigationLink.key}</span>
</div>
{#each navigationLink.subsections as subsection}
<a href="{subsection.href}">{subsection.key}</a>
{/each}
</div>
{/if}
</div>
{/if}
{/each}
</nav>

<style>
nav {
display: flex;
flex-direction: row;
column-gap: 1.5rem;
border-top: #ffffff 2px solid;
pointer-events: all;
transition: margin-bottom 250ms;
}
nav.scrolled {
margin-bottom: 1.5rem;
}
a {
text-decoration: none;
color: #ffffff;
text-transform: uppercase;
margin-top: 10px;
font-family: Roboto, serif;
}
span {
text-decoration: none;
color: #ffffff;
text-transform: uppercase;
margin-top: 10px;
font-family: Roboto, serif;
}
.subsection-container {
display: flex;
justify-content: center;
align-items: center;
flex-direction: column;
}
.subsections {
display: flex;
position: absolute;
background-color: #7d0b09;
flex-direction: column;
width: var(--subsection-width);
top: 0;
right: 0;
gap: 1rem;
max-height: 0;
margin-top: 0.5rem;
transition: max-height 300ms linear;
transform-origin: top;
overflow: hidden;
}
.subsections.open {
max-height: 25rem;
}
.subsections a {
margin-left: 8px;
}
.subsections a:last-child {
margin-left: 8px;
padding-bottom: 1rem;
}
.subsection-top {
display: flex;
width: 100%;
padding-top: 4px;
align-items: center;
position: relative;
min-height: 21px;
}
.subsection-line {
display: flex;
background-color: #FFFFFF;
height: 1px;
flex-grow: 1;
margin-right: 8px;
width: 100%;
margin-left: 8px;
}
.subsection-title {
padding-right: 4px;
padding-left: 4px;
font-family: 'Roboto', serif;
font-style: normal;
font-weight: 700;
font-size: 16px;
line-height: 18px;
color: #FFFFFF;
text-transform: uppercase;
text-align: center;
position: absolute;
height: 100%;
background-color: #7d0b09;
left: var(--subsection-left-shift)
}
</style>
210 changes: 210 additions & 0 deletions src/lib/MobileNav.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
<script>
import Close from "$lib/Close.svelte";
import NavMinus from "$lib/NavMinus.svelte";
import NavPlus from "$lib/NavPlus.svelte";
import { fly } from 'svelte/transition';
import { afterNavigate } from "$app/navigation";
import NavLines from "$lib/NavLines.svelte";
export let navigationLinksLeft;
export let navigationLinksRight;
export let scrollMode;
let isMobileMenuOpen;
const closeNavbar = () => {
isMobileMenuOpen = false;
document.body.classList.remove("no-scroll")
}
let mobileOpenSubsectionsKeys = []
let navBackground;
afterNavigate(closeNavbar)
const onBackgroundClick = (event) => {
if (event.target == navBackground) closeNavbar()
}
</script>

{#if isMobileMenuOpen}
<div class="nav-background" on:click={onBackgroundClick} bind:this={navBackground}></div>
<div class="mobile-nav" transition:fly="{{ x: 300, duration: 300 }}">
<div class="close">
<button class="icon-button" aria-label="затвори мобилна навигация" on:click={closeNavbar}>
<Close />
</button>
</div>
<nav>
{#each [...navigationLinksLeft, ...navigationLinksRight] as navigationLink}
{#if navigationLink.href}
<div class="link-wrapper">
<a href="{navigationLink.href}">{navigationLink.key}</a>
</div>
{:else}
<button class="link-wrapper" on:click={() => {
if (mobileOpenSubsectionsKeys.includes(navigationLink.key)) {
mobileOpenSubsectionsKeys = mobileOpenSubsectionsKeys
.filter((val) => val !== navigationLink.key)
} else {
mobileOpenSubsectionsKeys = [...mobileOpenSubsectionsKeys, navigationLink.key]
}
}}>
<span>{navigationLink.key}</span>
{#if mobileOpenSubsectionsKeys.includes(navigationLink.key)}
<NavMinus />
{:else}
<NavPlus />
{/if}
</button>
<div class="mobile-subsection" class:open={mobileOpenSubsectionsKeys.includes(navigationLink.key)}>
{#each navigationLink.subsections as subsection}
<a href="{subsection.href}">{subsection.key}</a>
{/each}
</div>
{/if}
{/each}
</nav>
</div>
{:else}
<div class="right-nav" class:scrolled="{scrollMode}" >
<button class="icon-button" aria-label="отвори мобилна навигация" on:click={() => {
isMobileMenuOpen = true
document.body.classList.add("no-scroll")
}}>
<NavLines></NavLines>
</button>
</div>
{/if}

<style>
nav {
display: flex;
flex-direction: row;
column-gap: 1.5rem;
border-top: #ffffff 2px solid;
pointer-events: all;
transition: margin-bottom 250ms;
}
a {
text-decoration: none;
color: #ffffff;
text-transform: uppercase;
margin-top: 10px;
font-family: Roboto, serif;
}
span {
text-decoration: none;
color: #ffffff;
text-transform: uppercase;
margin-top: 10px;
font-family: Roboto, serif;
}
.nav-background {
width: 100%;
height: 100%;
position: fixed;
top: 0;
bottom: 0;
z-index: 4;
pointer-events: all;
}
.close {
display: flex;
justify-content: flex-end;
padding: 1rem;
}
.mobile-nav {
height: 100%;
position: fixed;
min-width: 50%;
right: 0;
top: 0;
background-color: #4F0D0D;
z-index: 5;
}
.mobile-nav nav {
display: flex;
width: 100%;
height: 100%;
flex-direction: column;
border: none;
align-items: flex-start;
justify-content: flex-start;
padding: 0 1rem 1rem 1rem;
box-sizing: border-box;
}
.mobile-nav nav a, .mobile-nav nav span {
margin-top: 0;
}
.link-wrapper {
border-bottom: 1px solid #FFFFFF;
padding: 0 0 5px;
width: 100%;
justify-content: space-between;
align-items: center;
display: flex;
background-color: rgba(0, 0, 0, 0);
border-top: none;
border-left: none;
border-right: none;
font-size: 16px;
cursor: pointer;
margin-top: 15px;
}
.mobile-nav .link-wrapper a {
width: 100%;
}
.mobile-subsection {
display: flex;
flex-direction: column;
gap: 10px;
max-height: 0;
overflow: hidden;
transition: max-height 300ms ease-in;
}
.mobile-subsection.open {
max-height: 25rem;
width: 100%;
}
.mobile-subsection a:first-child {
padding-top: 4px;
}
.mobile-subsection a {
font-family: 'Roboto', serif;
font-style: normal;
font-weight: 300;
font-size: 15px;
line-height: 17px;
text-transform: none;
color: #FFFFFF;
width: 100%;
}
.icon-button {
background-color: rgba(0, 0, 0, 0);
border: none;
cursor: pointer;
pointer-events: all;
}
button {
transition: margin-bottom 250ms;
}
.scrolled button {
margin-bottom: 1.5rem;
}
</style>
Loading

0 comments on commit 55f1542

Please sign in to comment.