Skip to content

Commit

Permalink
feat: hamburger with sidebar menu on smartphone (#187)
Browse files Browse the repository at this point in the history
* feat: hamburger with sidebar menu on smartphone

* fix: flex on coupon page
  • Loading branch information
hmbanan666 authored Jun 28, 2024
1 parent 3087ecd commit 373de0c
Show file tree
Hide file tree
Showing 6 changed files with 253 additions and 72 deletions.
63 changes: 63 additions & 0 deletions src/lib/components/Hamburger.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<script>
export let open = false
</script>

<button class='burger' class:open onclick={() => open = !open}>
<svg width='32' height='24'>
<line id='top' x1='0' y1='2' x2='32' y2='2' />
<line id='middle' x1='0' y1='12' x2='24' y2='12' />
<line id='bottom' x1='0' y1='22' x2='32' y2='22' />
</svg>
</button>

<style>
.burger {
position: relative;
width: 48px;
height: 24px;
margin: 0;
padding: 0;
border: 0;
background-color: transparent;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
-webkit-touch-callout: none;
-webkit-user-select: none;
-khtml-user-select: none;
-moz-user-select: none;
-ms-user-select: none;
user-select: none;
}
svg {
min-height: 24px;
transition: transform 0.2s ease-in-out;
color: var(--color-text);
}
svg line {
stroke: currentColor;
stroke-width: 3;
transition: transform 0.2s ease-in-out
}
button {
z-index: 10;
}
.open svg {
color: var(--color-border);
}
.open #top {
transform: translate(6px, 0px) rotate(45deg)
}
.open #middle {
opacity: 0;
}
.open #bottom {
transform: translate(-12px, 9px) rotate(-45deg)
}
</style>
90 changes: 19 additions & 71 deletions src/lib/components/Header.svelte
Original file line number Diff line number Diff line change
@@ -1,13 +1,18 @@
<script lang='ts'>
import { page } from '$app/stores'
import MenuSmartphone from './MenuSmartphone.svelte'
import MenuDesktop from './MenuDesktop.svelte'
import Locale from './Locale.svelte'
import unit from '$lib/assets/website/unit-64.png'
import Profile from '$lib/components/Profile.svelte'
import Locale from '$lib/components/Locale.svelte'
import { page } from '$app/stores'
const locale = $page.data.locale
const t = $page.data.t
let innerWidth = 0
let open = false
</script>

<svelte:window bind:innerWidth />

<header>
<div class='left logo'>
{#if $page.url.pathname === `/${locale}`}
Expand All @@ -17,30 +22,15 @@
<img src={unit} alt="" />
</a>
{/if}
</div>

<nav>
<ul>
<li aria-current={$page.url.pathname === `/${locale}` ? 'page' : undefined}>
<a href='/{locale}'>{t.header.menu.home}</a>
</li>
<li aria-current={$page.url.pathname === `/${locale}/about` ? 'page' : undefined}>
<a href='/{locale}/about'>{t.header.menu.about}</a>
</li>
<li aria-current={$page.url.pathname === `/${locale}/character` ? 'page' : undefined}>
<a href='/{locale}/character'>{t.header.menu.characters}</a>
</li>
<li aria-current={$page.url.pathname === `/${locale}/coupon` ? 'page' : undefined}>
<a href='/{locale}/coupon'>{t.header.menu.coupon}</a>
</li>
</ul>
</nav>

<Locale />

<div class='right'>
<Profile />
<Locale />
</div>

{#if innerWidth < 768}
<MenuSmartphone bind:sidebar={open} />
{:else}
<MenuDesktop />
{/if}
</header>

<style>
Expand All @@ -52,9 +42,11 @@
align-items: center;
}
.left, .right {
.left {
flex-grow: 1;
flex-basis: 0;
display: flex;
align-items: center;
}
@keyframes skewRandom {
Expand Down Expand Up @@ -84,48 +76,4 @@
animation-direction: alternate-reverse;
transform-origin: 50% 50%;
}
nav {
display: flex;
justify-content: center;
}
nav a {
display: flex;
height: 100%;
align-items: center;
color: var(--color-text);
font-weight: 700;
font-size: 1rem;
text-transform: uppercase;
letter-spacing: 0;
text-decoration: none;
transition: color 0.2s linear;
}
nav a:hover {
color: var(--color-accent-1);
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
gap: 1.2em;
list-style: none;
}
li {
position: relative;
display: flex;
gap: 0.2em;
height: 100%;
}
li[aria-current='page'] a {
color: var(--color-accent-1);
}
</style>
2 changes: 1 addition & 1 deletion src/lib/components/Locale.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,6 @@

<style>
select {
margin: 0 2em;
margin: 0;
}
</style>
79 changes: 79 additions & 0 deletions src/lib/components/MenuDesktop.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<script>
import Profile from './Profile.svelte'
import { page } from '$app/stores'
const locale = $page.data.locale
const t = $page.data.t
</script>

<nav>
<ul>
<li aria-current={$page.url.pathname === `/${locale}` ? 'page' : undefined}>
<a href='/{locale}'>{t.header.menu.home}</a>
</li>
<li aria-current={$page.url.pathname === `/${locale}/about` ? 'page' : undefined}>
<a href='/{locale}/about'>{t.header.menu.about}</a>
</li>
<li aria-current={$page.url.pathname === `/${locale}/character` ? 'page' : undefined}>
<a href='/{locale}/character'>{t.header.menu.characters}</a>
</li>
<li aria-current={$page.url.pathname === `/${locale}/coupon` ? 'page' : undefined}>
<a href='/{locale}/coupon'>{t.header.menu.coupon}</a>
</li>
</ul>
</nav>

<div class='right'>
<Profile />
</div>

<style>
.right {
flex-grow: 1;
flex-basis: 0;
}
nav {
display: flex;
justify-content: center;
}
nav a {
display: flex;
height: 100%;
align-items: center;
color: var(--color-text);
font-weight: 700;
font-size: 1rem;
text-transform: uppercase;
letter-spacing: 0;
text-decoration: none;
transition: color 0.2s linear;
}
nav a:hover {
color: var(--color-accent-1);
}
ul {
position: relative;
padding: 0;
margin: 0;
display: flex;
justify-content: center;
align-items: center;
gap: 1.2em;
list-style: none;
}
li {
position: relative;
display: flex;
gap: 0.2em;
height: 100%;
}
li[aria-current='page'] a {
color: var(--color-accent-1);
}
</style>
83 changes: 83 additions & 0 deletions src/lib/components/MenuSmartphone.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<script>
import Hamburger from './Hamburger.svelte'
import Profile from './Profile.svelte'
import { page } from '$app/stores'
const locale = $page.data.locale
const t = $page.data.t
export let sidebar = false
function closeSidebar() {
sidebar = false
}
</script>

<aside class:open={sidebar}>
<nav>
<ul>
<li aria-current={$page.url.pathname === `/${locale}` ? 'page' : undefined}>
<a href='/{locale}' onclick={closeSidebar}>{t.header.menu.home}</a>
</li>
<li aria-current={$page.url.pathname === `/${locale}/about` ? 'page' : undefined}>
<a href='/{locale}/about' onclick={closeSidebar}>{t.header.menu.about}</a>
</li>
<li aria-current={$page.url.pathname === `/${locale}/character` ? 'page' : undefined}>
<a href='/{locale}/character' onclick={closeSidebar}>{t.header.menu.characters}</a>
</li>
<li aria-current={$page.url.pathname === `/${locale}/coupon` ? 'page' : undefined}>
<a href='/{locale}/coupon' onclick={closeSidebar}>{t.header.menu.coupon}</a>
</li>
</ul>
</nav>
</aside>

<div class='profile-block'>
<Profile />
</div>

<Hamburger bind:open={sidebar} />

<style>
aside {
left: -100%;
transition: left 0.2s ease-in-out;
position: absolute;
top: 0;
bottom: 0;
width: 100%;
height: 100vh;
background-color: var(--color-bg-accent-1);
z-index: 10;
}
nav {
padding: 0 2em;
}
nav ul {
padding: 0;
}
nav ul li {
list-style: none;
font-size: 1.5rem;
padding: 0.25em 0;
}
nav ul li a {
color: #fff;
}
li[aria-current='page'] a {
color: var(--color-border);
}
.open {
left: 0
}
.profile-block {
margin-right: 0.5em;
}
</style>
8 changes: 8 additions & 0 deletions src/routes/[lang]/(website)/coupon/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -113,9 +113,17 @@
.latest-coupons .block {
display: flex;
flex-direction: row;
flex-wrap: wrap;
gap: 1em;
}
@media (max-width: 620px) {
.latest-coupons .block {
flex-direction: column;
}
}
.latest-coupons .block .card {
border: 2px solid var(--color-border-2);
padding: 1em;
Expand Down

0 comments on commit 373de0c

Please sign in to comment.