Merge pull request 'feat: Sticky navbar' (#30) from component/navbar into main
Reviewed-on: #30
This commit is contained in:
commit
c2362e26ef
|
@ -1,6 +1,7 @@
|
|||
<script lang="ts">
|
||||
import '../app.css';
|
||||
import { page } from '$app/stores';
|
||||
import { name } from '$content/metadata.json';
|
||||
import Footer from "./Footer.svelte";
|
||||
import Navbar from "./Navbar.svelte";
|
||||
import PageTransition from "./PageTransition.svelte";
|
||||
|
@ -11,7 +12,8 @@
|
|||
<!-- Homepage has its own navbar with animations -->
|
||||
{#if $page.url.pathname != "/"}
|
||||
<div id="layout">
|
||||
<div id="navbar">
|
||||
<div id="nav">
|
||||
<p id="bio-name">{name}</p>
|
||||
<Navbar />
|
||||
<slot name="header" />
|
||||
</div>
|
||||
|
@ -31,6 +33,12 @@
|
|||
{/if}
|
||||
|
||||
<style>
|
||||
#bio-name {
|
||||
font-family: serif;
|
||||
font-size: 3rem;
|
||||
font-weight: normal;
|
||||
color: var(--name);
|
||||
}
|
||||
#layout {
|
||||
max-width: max(80vw, 100vh);
|
||||
margin-left: auto;
|
||||
|
@ -58,7 +66,7 @@
|
|||
width: min(100vw, max(50vw, 100vh));
|
||||
grid-area: content;
|
||||
}
|
||||
#navbar {
|
||||
#nav {
|
||||
align-self: right;
|
||||
padding-left: 10px;
|
||||
grid-area: nav;
|
||||
|
|
|
@ -1,43 +1,95 @@
|
|||
<script lang="ts">
|
||||
import { page } from '$app/stores';
|
||||
import { routes } from "$lib/sitemap.ts"
|
||||
import { name } from '$content/metadata.json';
|
||||
import ThemeSwitch from "$lib/components/ThemeSwitch.svelte"
|
||||
import { Rss } from "lucide-svelte";
|
||||
import { Rss, Menu } from "lucide-svelte";
|
||||
|
||||
function isCurrentLink(pathname, route) {
|
||||
return route != "/" && pathname.startsWith(route)
|
||||
|| route == "/post" && pathname.startsWith("/page");
|
||||
}
|
||||
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
let showDropdown = false;
|
||||
|
||||
function onDropdownToggle(event) {
|
||||
showDropdown = !showDropdown;
|
||||
}
|
||||
function onKeyDown(event) {
|
||||
if (event.key == "Escape") {
|
||||
showDropdown = !showDropdown;
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<div id="navbar" class="h-5 space-x-4">
|
||||
<p id="bio-name">{name}</p>
|
||||
{#each routes as item}
|
||||
<a
|
||||
class="nav-link"
|
||||
class:disabled-link={item.disabled}
|
||||
class:current-link={isCurrentLink($page.url.pathname, item.route)}
|
||||
href={item.route}>{item.name}</a>
|
||||
{/each}
|
||||
<a class="nav-link icon" href="/rss.xml"><Rss /></a>
|
||||
<div><ThemeSwitch /></div>
|
||||
</div>
|
||||
<nav
|
||||
id="navbar"
|
||||
class="h-5 space-x-4"
|
||||
class:dropdown-opened={showDropdown}>
|
||||
<div
|
||||
class="link-container"
|
||||
role="button"
|
||||
tabindex={0}
|
||||
on:keydown={onKeyDown}
|
||||
on:click={() => { showDropdown = false; }}
|
||||
>
|
||||
{#each routes as item}
|
||||
<a
|
||||
class="nav-link"
|
||||
class:disabled-link={item.disabled}
|
||||
class:current-link={isCurrentLink($page.url.pathname, item.route)}
|
||||
on:click={() => { showDropdown = false; }}
|
||||
href={item.route}>
|
||||
{item.name}
|
||||
</a>
|
||||
{/each}
|
||||
<a class="nav-link icon" href="/rss.xml"><Rss /></a>
|
||||
<div><ThemeSwitch /></div>
|
||||
</div>
|
||||
<button
|
||||
id="dropdown-toggle"
|
||||
aria-hidden="true"
|
||||
on:click={onDropdownToggle}>
|
||||
<Menu />
|
||||
</button>
|
||||
</nav>
|
||||
|
||||
<svelte:window on:keydown={onKeyDown} />
|
||||
|
||||
<style>
|
||||
#bio-name {
|
||||
font-family: serif;
|
||||
font-size: 3rem;
|
||||
font-weight: normal;
|
||||
color: var(--name);
|
||||
}
|
||||
#navbar {
|
||||
.link-container {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: flex-end;
|
||||
justify-content: between;
|
||||
position: sticky;
|
||||
top: 0;
|
||||
}
|
||||
@media (max-width: 700px) {
|
||||
#dropdown-toggle {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* mobile mode */
|
||||
@media (max-width: 768px) {
|
||||
.link-container {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100vh;
|
||||
justify-content: center;
|
||||
|
||||
margin: 0;
|
||||
padding-left: 5vw;
|
||||
padding-right: 5vw;
|
||||
|
||||
background: hsl(var(--background) / .8);
|
||||
|
||||
/* Initial hidden state */
|
||||
opacity: 0;
|
||||
transform: translateY(-100%);
|
||||
transition: transform 0.2s, opacity 0.2s;
|
||||
}
|
||||
#navbar {
|
||||
display: inline-block;
|
||||
white-space: pre-wrap;
|
||||
|
@ -45,5 +97,14 @@
|
|||
#navbar .nav-link {
|
||||
display: inline-block;
|
||||
}
|
||||
#dropdown-toggle {
|
||||
display: initial;
|
||||
z-index: 5;
|
||||
}
|
||||
.dropdown-opened > .link-container {
|
||||
opacity: 1;
|
||||
z-index: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
|
Loading…
Reference in New Issue