mirror of
				https://github.com/ProjectSegfault/website.git
				synced 2025-05-31 14:12:04 +05:30 
			
		
		
		
	new nav
This commit is contained in:
		| @@ -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" | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| }); | }); | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user