forked from ProjectSegfault/website
new nav
This commit is contained in:
parent
f181774062
commit
befb74f0bb
@ -1,6 +1,6 @@
|
|||||||
<footer class="sticky top-full">
|
<footer class="sticky top-full">
|
||||||
<div
|
<div
|
||||||
class="flex flex-col justify-center sm:flex-row gap-1 border-t border-t-solid border-t-grey p-3 text-sm"
|
class="flex flex-col justify-center sm:flex-row gap-1 bg-secondary p-3 text-sm"
|
||||||
>
|
>
|
||||||
<p class="flex flex-row items-center gap-1">
|
<p class="flex flex-row items-center gap-1">
|
||||||
Made with <i class="i-simple-icons:svelte text-[#FF3E00] block" /> SvelteKit
|
Made with <i class="i-simple-icons:svelte text-[#FF3E00] block" /> SvelteKit
|
||||||
|
24
src/lib/Nav/Link.svelte
Normal file
24
src/lib/Nav/Link.svelte
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<script lang="ts">
|
||||||
|
export let link: {
|
||||||
|
href: string;
|
||||||
|
text: string;
|
||||||
|
icon?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
import { page } from "$app/stores";
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<a
|
||||||
|
href={link.href}
|
||||||
|
class="flex items-center gap-2 text-sm"
|
||||||
|
on:click
|
||||||
|
class:text-accent={link.href !== "/"
|
||||||
|
? $page.url.pathname.match(link.href)
|
||||||
|
: link.href === $page.url.pathname}
|
||||||
|
aria-label={link.text}
|
||||||
|
>
|
||||||
|
{#if link.icon}
|
||||||
|
<div class={link.icon} />
|
||||||
|
{/if}
|
||||||
|
<span class:navPlus1:hidden={link.icon}>{link.text}</span>
|
||||||
|
</a>
|
6
src/lib/Nav/Logo.svelte
Normal file
6
src/lib/Nav/Logo.svelte
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<a
|
||||||
|
href="/"
|
||||||
|
class="text-text no-underline flex items-center gap-2">
|
||||||
|
<img src="/logo.png" alt="Project Segfault logo" class="w-7">
|
||||||
|
Project Segfault</a
|
||||||
|
>
|
@ -1,144 +1,136 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import ThemeToggle from "$lib/Nav/ThemeToggle.svelte";
|
import ThemeToggle from "./ThemeToggle.svelte";
|
||||||
import { page } from "$app/stores";
|
import Link from "./Link.svelte";
|
||||||
import { slide } from "svelte/transition"
|
import Logo from "./Logo.svelte";
|
||||||
|
import { slide } from "svelte/transition";
|
||||||
import { quintOut } from "svelte/easing";
|
import { quintOut } from "svelte/easing";
|
||||||
|
|
||||||
$: currentPage = $page.url.pathname;
|
const links = [
|
||||||
|
{ href: "/instances", text: "Instances" },
|
||||||
$: innerWidth = 0;
|
{ href: "/donate", text: "Donate" },
|
||||||
|
{ href: "/pubnix", text: "Pubnix" },
|
||||||
$: isMobile = innerWidth < 1090;
|
{ href: "/contact", text: "Contact" },
|
||||||
|
{ href: "/team", text: "Team" },
|
||||||
$: hasJS = typeof Window !== "undefined";
|
|
||||||
|
|
||||||
$: showMenuButton = hasJS && isMobile;
|
|
||||||
|
|
||||||
$: menuOpen = !hasJS || (hasJS && !isMobile);
|
|
||||||
|
|
||||||
$: menuOpenMobile = isMobile && menuOpen;
|
|
||||||
|
|
||||||
$: showThemeToggle = hasJS;
|
|
||||||
|
|
||||||
const toggleMenu = () => (menuOpen = !menuOpen);
|
|
||||||
|
|
||||||
const handleNavigation = () =>
|
|
||||||
showMenuButton ? (menuOpen = false) : (menuOpen = true);
|
|
||||||
|
|
||||||
const menus = [
|
|
||||||
{ name: "Instances", url: "/instances" },
|
|
||||||
{ name: "Donate", url: "/donate" },
|
|
||||||
{ name: "Pubnix", url: "/pubnix" },
|
|
||||||
{ name: "Contact", url: "/contact" },
|
|
||||||
{ name: "Team", url: "/team" },
|
|
||||||
{
|
{
|
||||||
name: "Wiki",
|
href: "https://wiki.projectsegfau.lt/",
|
||||||
url: "https://wiki.projectsegfau.lt/",
|
text: "Wiki",
|
||||||
external: true
|
external: true
|
||||||
},
|
},
|
||||||
{ name: "Blog", url: "/blog" },
|
{ href: "/blog", text: "Blog"},
|
||||||
{
|
{
|
||||||
name: "Status",
|
href: "https://status.projectsegfau.lt/",
|
||||||
url: "https://status.projectsegfau.lt/",
|
text: "Status",
|
||||||
external: true
|
external: true
|
||||||
},
|
},
|
||||||
{ name: "Legal", url: "/legal" }
|
{ href: "/legal", text: "Legal" },
|
||||||
|
{
|
||||||
|
href: "https://matrix.to/#/#project-segfault:projectsegfau.lt/",
|
||||||
|
text: "Matrix",
|
||||||
|
icon: "i-simple-icons:matrix"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
href: "https://github.com/ProjectSegfault/",
|
||||||
|
text: "GitHub",
|
||||||
|
icon: "i-simple-icons:github"
|
||||||
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const allowedWidth = 890;
|
||||||
|
|
||||||
|
let width: number;
|
||||||
|
|
||||||
|
$: showMenu = width > allowedWidth;
|
||||||
|
|
||||||
|
const navStyles =
|
||||||
|
"flex items-center justify-between lt-navPlus1:(flex-col items-start) gap-2 p-4 bg-secondary z-50 mb-16";
|
||||||
|
|
||||||
|
const linkContainerStyles =
|
||||||
|
"flex items-center gap-4 bg-secondary children:(no-underline text-text)";
|
||||||
|
|
||||||
|
let nav: HTMLElement;
|
||||||
|
|
||||||
|
let lastScrollTop: number;
|
||||||
|
|
||||||
|
let scrollTop: number;
|
||||||
|
|
||||||
|
const handleScroll = () => {
|
||||||
|
if (!showMenu) {
|
||||||
|
if (scrollTop > lastScrollTop) {
|
||||||
|
nav.style.top = "-80px";
|
||||||
|
} else {
|
||||||
|
nav.style.top = "0";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastScrollTop = scrollTop;
|
||||||
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:window bind:innerWidth />
|
<svelte:window
|
||||||
|
bind:innerWidth={width}
|
||||||
|
bind:scrollY={scrollTop}
|
||||||
|
on:scroll={handleScroll}
|
||||||
|
/>
|
||||||
|
|
||||||
<nav
|
<nav
|
||||||
class="bg-primary {menuOpenMobile
|
class="{navStyles} sticky w-full top-0 z-50 js transition-top duration-200"
|
||||||
? 'border-none'
|
bind:this={nav}
|
||||||
: 'border-b border-b-solid border-b-grey'} {isMobile
|
|
||||||
? 'py-2'
|
|
||||||
: ''} flex px-2 flex-col justify-between nav:(flex-row items-center) {hasJS
|
|
||||||
? 'sticky top-0 z-50'
|
|
||||||
: 'border-b border-b-solid border-b-grey'}"
|
|
||||||
>
|
>
|
||||||
<div class="flex flex-row items-center justify-between">
|
<!-- Slot for the progress bar -->
|
||||||
<a
|
<slot />
|
||||||
class="flex items-center decoration-none text-text gap-2 transition-filter duration-250"
|
<div class="flex items-center justify-between w-full">
|
||||||
href="/"
|
<Logo />
|
||||||
|
<button
|
||||||
|
on:click={() => (showMenu = !showMenu)}
|
||||||
|
aria-label="Toggle menu"
|
||||||
>
|
>
|
||||||
<img
|
<div
|
||||||
src="/logo.png"
|
class="{showMenu
|
||||||
alt="Project Segfault logo"
|
|
||||||
class="h-7"
|
|
||||||
/>
|
|
||||||
<span>Project Segfault</span>
|
|
||||||
</a>
|
|
||||||
|
|
||||||
{#if showMenuButton}
|
|
||||||
<button
|
|
||||||
on:click={toggleMenu}
|
|
||||||
class="{menuOpen
|
|
||||||
? 'i-ic:outline-close'
|
? 'i-ic:outline-close'
|
||||||
: 'i-ic:outline-menu'} h-4 w-4 cursor-pointer mr-2"
|
: 'i-ic:outline-menu'} navPlus1:hidden"
|
||||||
/>
|
/>
|
||||||
{/if}
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
{#if showMenu}
|
||||||
{#if menuOpen}
|
|
||||||
<div
|
<div
|
||||||
class="links flex flex-row gap-2 {isMobile
|
class="
|
||||||
? '!children:py-2'
|
{linkContainerStyles}
|
||||||
: ''} {hasJS
|
lt-navPlus1:(flex-col !items-start fixed pl-4 pb-4 z-50 w-full left-0 top-16)
|
||||||
? 'lt-nav:(flex flex-col pt-2 gap-2 fixed bg-primary w-full left-0 top-[2.75rem] p-2 z-50 border-b-solid border-b border-b-grey shadow shadow-secondary)'
|
"
|
||||||
: 'lt-nav:(grid grid-cols-2 gap-2 pt-2 w-fit)'}"
|
|
||||||
transition:slide={{ duration: 300, easing: quintOut }}
|
transition:slide={{ duration: 300, easing: quintOut }}
|
||||||
>
|
>
|
||||||
{#each menus as { url, name, external }}
|
{#each links as link}
|
||||||
<a
|
<Link
|
||||||
class:active={url !== "/"
|
{link}
|
||||||
? currentPage.match(url)
|
on:click={() =>
|
||||||
: url === currentPage}
|
width < allowedWidth
|
||||||
href={url}
|
? (showMenu = false)
|
||||||
on:click={handleNavigation}
|
: (showMenu = true)}
|
||||||
>{#if external}
|
/>
|
||||||
<div class="i-ic:outline-open-in-new mr-2 h-4 w-4" />
|
|
||||||
{/if}
|
|
||||||
{name}
|
|
||||||
</a>
|
|
||||||
{/each}
|
{/each}
|
||||||
<a
|
<ThemeToggle />
|
||||||
href="https://matrix.to/#/#project-segfault:projectsegfau.lt/"
|
|
||||||
class="icon"
|
|
||||||
>
|
|
||||||
<div class="i-simple-icons:matrix" />
|
|
||||||
<span>Matrix</span>
|
|
||||||
</a>
|
|
||||||
<a
|
|
||||||
href="https://github.com/ProjectSegfault/"
|
|
||||||
class="icon"
|
|
||||||
>
|
|
||||||
<div class="i-simple-icons:github" />
|
|
||||||
<span>GitHub</span>
|
|
||||||
</a>
|
|
||||||
{#if showThemeToggle}
|
|
||||||
<div class="icon">
|
|
||||||
<ThemeToggle />
|
|
||||||
</div>
|
|
||||||
{/if}
|
|
||||||
</div>
|
</div>
|
||||||
{/if}
|
{/if}
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<style>
|
<noscript>
|
||||||
a.active {
|
<nav class="{navStyles} no-js">
|
||||||
@apply text-accent;
|
<Logo />
|
||||||
}
|
<div
|
||||||
|
class="
|
||||||
|
{linkContainerStyles}
|
||||||
|
lt-navPlus1:(grid grid-cols-2 p-1)
|
||||||
|
"
|
||||||
|
>
|
||||||
|
{#each links as link}
|
||||||
|
<Link {link} />
|
||||||
|
{/each}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
||||||
.links > * {
|
<style>
|
||||||
@apply py-4 px-2 text-text decoration-none transition-filter duration-250 text-sm flex items-center;
|
.js {
|
||||||
}
|
display: none;
|
||||||
|
}
|
||||||
.icon > span {
|
</style>
|
||||||
@apply text-sm nav\:hidden;
|
</noscript>
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
@apply flex items-center gap-2 text-base;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@ -24,5 +24,5 @@
|
|||||||
? 'outline-light-mode'
|
? 'outline-light-mode'
|
||||||
: 'outline-dark-mode'} h-4 w-4"
|
: 'outline-dark-mode'} h-4 w-4"
|
||||||
/>
|
/>
|
||||||
<span class="ml-2 nav:(hidden ml-1)">Toggle theme</span>
|
<span class="ml-2 navPlus1:(hidden)">Toggle theme</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -45,7 +45,8 @@ export default defineConfig({
|
|||||||
lg: "1024px",
|
lg: "1024px",
|
||||||
xl: "1280px",
|
xl: "1280px",
|
||||||
"2xl": "1536px",
|
"2xl": "1536px",
|
||||||
nav: "1090px"
|
nav: "890px",
|
||||||
|
navPlus1: "891px"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
Loading…
Reference in New Issue
Block a user