Attic is a cozy space with lofty ambitions. attic.social
11
fork

Configure Feed

Select the types of activity you want to include in your feed.

nav component

+63 -12
+48
src/components/nav.svelte
··· 1 + <script lang="ts" module> 2 + import type { PublicUserData } from "$lib/valibot"; 3 + 4 + type Props = { 5 + user?: PublicUserData; 6 + }; 7 + </script> 8 + 9 + <script lang="ts"> 10 + import { page } from "$app/state"; 11 + 12 + let { user }: Props = $props(); 13 + 14 + const pathname = $derived(page.url.pathname); 15 + 16 + const nav = $derived.by(() => { 17 + const nav = [ 18 + { 19 + name: "attic.social", 20 + href: "/", 21 + current: pathname === "/", 22 + }, 23 + ]; 24 + if (user) { 25 + nav.push( 26 + { 27 + name: "bookmarks", 28 + href: `/bookmarks/${user.did}`, 29 + current: pathname.startsWith("/bookmarks"), 30 + }, 31 + { 32 + name: "settings", 33 + href: "/settings", 34 + current: pathname.startsWith("/settings"), 35 + }, 36 + ); 37 + } 38 + return nav; 39 + }); 40 + </script> 41 + 42 + <nav> 43 + {#each nav as item} 44 + <a href={item.href} aria-current={item.current ? "page" : undefined}> 45 + {item.name} 46 + </a> 47 + {/each} 48 + </nav>
+8 -1
src/css/base/global.css
··· 43 43 padding-block: 30px; 44 44 45 45 & > nav { 46 + column-gap: 20px; 46 47 display: flex; 47 48 flex-wrap: wrap; 48 - gap: 20px; 49 + row-gap: 10px; 49 50 50 51 & a { 51 52 display: block; 53 + 54 + &[aria-current] { 55 + &:not(:hover) { 56 + color: rgb(var(--color-light-yellow)); 57 + } 58 + } 52 59 } 53 60 } 54 61 }
+2 -2
src/css/base/typography.css
··· 14 14 } 15 15 16 16 a:where([href]:not([class])) { 17 - --anchor-underline-color: oklch(from currentColor l c h / 0.6); 17 + --anchor-underline-color: rgb(from currentColor r g b / 0.6); 18 18 --anchor-underline-offset: 0.2em; 19 19 --anchor-underline-thickness: 2px; 20 20 color: rgb(var(--color-yellow)); ··· 25 25 text-underline-offset: var(--anchor-underline-offset); 26 26 27 27 &:hover { 28 - --anchor-underline-color: oklch(from currentColor l c h / 0.1); 28 + --anchor-underline-color: rgb(from currentColor r g b / 0.1); 29 29 color: rgb(var(--color-light-yellow)); 30 30 } 31 31 }
+4 -9
src/routes/+layout.svelte
··· 1 1 <script lang="ts"> 2 2 import { dev } from "$app/environment"; 3 + import Nav from "$components/nav.svelte"; 3 4 import "$css/main.css"; 4 5 import { pointer } from "$lib/dialog.svelte.js"; 5 6 import { onMount } from "svelte"; 7 + 8 + let { data, children } = $props(); 6 9 7 10 onMount(() => { 8 11 if (dev === false) { ··· 14 17 pointer.ref.showPopover(); 15 18 } 16 19 }); 17 - 18 - let { data, children } = $props(); 19 20 </script> 20 21 21 22 <svelte:head> ··· 34 35 </svelte:head> 35 36 36 37 <header> 37 - <nav> 38 - <a href="/">attic.social</a> 39 - {#if data.user} 40 - <a href="/bookmarks/{data.user.did}">bookmarks</a> 41 - <a href="/settings">settings</a> 42 - {/if} 43 - </nav> 38 + <Nav user={data.user} /> 44 39 </header> 45 40 46 41 <main>
+1
svelte.config.js
··· 8 8 alias: { 9 9 $css: "src/css", 10 10 $lexicons: "src/lexicons", 11 + $components: "src/components", 11 12 $static: "static", 12 13 }, 13 14 env: {