Skip to content

Commit 6a76aef

Browse files
committed
Update HeaderNav
Use NavLink again for header and footer links. Convert HeaderLogo to use Tailwind. Update anchor styles.
1 parent 9ed5e50 commit 6a76aef

File tree

4 files changed

+79
-74
lines changed

4 files changed

+79
-74
lines changed

src/components/HeaderLogo.astro

Lines changed: 5 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,45 +4,10 @@ import logo from "@/assets/brand/logo.svg";
44
import logoType from "@/assets/brand/logoType.svg";
55
---
66

7-
<div class="logo-container">
8-
<Image src={logo} alt="SF Civic Tech Logo" class="logo" loading="eager" />
9-
<div class="name">
10-
<Image src={logoType} alt="SF Civic Tech" class="logo-type" loading="eager" />
11-
<em>formerly Code for San Francisco</em>
7+
<div class="inline-flex items-end gap-[.65rem]">
8+
<Image src={logo} alt="SF Civic Tech Logo" class="h-[2.4rem] w-auto" loading="eager" />
9+
<div class="flex flex-col items-start ">
10+
<Image src={logoType} alt="SF Civic Tech" class="h-[1.15rem] w-auto mb-2" loading="eager" />
11+
<em class="font-normal text-xs text-gray-400 leading-[.6]">formerly Code for San Francisco</em>
1212
</div>
1313
</div>
14-
15-
<style>
16-
.logo-container {
17-
display: inline-flex;
18-
align-items: end;
19-
gap: .65rem;
20-
}
21-
22-
.logo {
23-
width: auto;
24-
height: 2.4rem;
25-
visibility: visible;
26-
}
27-
28-
.logo-type {
29-
width: auto;
30-
height: 1.15rem;
31-
}
32-
33-
.name {
34-
display: flex;
35-
flex-direction: column;
36-
align-items: start;
37-
gap: .25rem;
38-
position: relative;
39-
top: 1px;
40-
visibility: visible;
41-
}
42-
43-
em {
44-
color: var(--pico-muted-color);
45-
font-size: 0.6rem;
46-
line-height: 1;
47-
}
48-
</style>

src/components/HeaderNav.astro

Lines changed: 30 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
---
2+
import HeaderLogo from "./HeaderLogo.astro";
3+
import NavLink from "./NavLink.astro";
24
import {
35
meetupURL,
46
getStartedURL,
@@ -7,46 +9,47 @@ import {
79
donateURL,
810
projectsURL,
911
} from "@/utils/urls";
10-
import HeaderLogo from "@/components/HeaderLogo.astro";
1112
13+
const activeClass = "text-muted relative after:content-[''] after:absolute after:left-0 after:top-[calc(1em+.2rem)] after:w-2 after:h-1 after:bg-primary";
1214
const routes = [
13-
{ label: "Join", href: getStartedURL },
15+
{ label: "Get Started", href: getStartedURL },
1416
{ label: "Events", href: meetupURL },
1517
{ label: "Projects", href: projectsURL },
1618
{ label: "Blog", href: blogURL },
1719
{ label: "About", href: aboutURL },
1820
{ label: "Donate", href: donateURL, highlight: true }
1921
];
20-
2122
---
2223

2324
<header class="w-full bg-white">
24-
<div class="max-w-[920px] mx-auto px-4 py-4 flex justify-between items-center">
25-
<a href="/" class="flex items-center">
25+
<nav class="py-4 flex justify-between items-center">
26+
<NavLink href="/">
2627
<HeaderLogo />
27-
</a>
28-
<nav>
29-
<div class="hidden md:flex items-center space-x-6">
28+
</NavLink>
29+
<ul class="hidden md:flex items-center space-x-6">
3030
{routes.map((route) => (
31-
<a
32-
href={route.href}
33-
class={`no-underline hover:underline text-lg transition-colors ${
34-
route.highlight
35-
? "bg-[var(--color-sf-red)] text-white px-4 py-2 rounded-lg hover:bg-[#d54d4b]"
36-
: "text-gray-800 hover:text-[var(--color-sf-red)]"
37-
}`}
38-
>
39-
{route.label}
40-
</a>
31+
<li>
32+
<NavLink
33+
href={route.href}
34+
class:list={[
35+
"font-condensed font-semibold text-lg text-stone-800",
36+
route.highlight && "bg-primary text-white px-4 py-2 rounded-lg hover:bg-[#d54d4b] hover:no-underline"
37+
]}
38+
activeClass={activeClass}
39+
>
40+
{route.label}
41+
</NavLink>
42+
</li>
4143
))}
42-
</div>
43-
<button class="md:hidden text-gray-800" id="mobile-menu-button">
44-
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
45-
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
46-
</svg>
47-
</button>
48-
</nav>
49-
</div>
44+
<li>
45+
<button class="md:hidden text-stone-800" id="mobile-menu-button">
46+
<svg xmlns="http://www.w3.org/2000/svg" class="h-6 w-6" fill="none" viewBox="0 0 24 24" stroke="currentColor">
47+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
48+
</svg>
49+
</button>
50+
</li>
51+
</ul>
52+
</nav>
5053
<!-- Mobile menu -->
5154
<div class="md:hidden hidden bg-white w-full absolute" id="mobile-menu">
5255
<div class="px-4 py-2 space-y-2">
@@ -56,7 +59,7 @@ const routes = [
5659
class={`block font-[var(--font-barlow)] font-bold text-lg py-2 ${
5760
route.highlight
5861
? "text-[var(--color-sf-red)]"
59-
: "text-gray-800"
62+
: "text-stone-800"
6063
}`}
6164
>
6265
{route.label}

src/components/NavLink.astro

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,41 @@
11
---
2+
import { base } from "@/utils/urls";
3+
24
interface Props {
3-
href: string;
5+
href: string;
6+
class?: string;
7+
activeClass?: string;
48
}
5-
const { href } = Astro.props;
9+
10+
// we can destructure `class` from props, but we have to rename it so it won't
11+
// trigger syntax errors in the JS
12+
const {
13+
href,
14+
class: className,
15+
activeClass,
16+
// activeClass = "text-muted decoration-inherit cursor-default pointer-events-none",
17+
} = Astro.props;
18+
const baseURL = import.meta.env.BASE_URL.replace(/\/$/, "");
19+
// remove the base URL from the beginning of the current page so we can match
20+
// it against the href prop, which shouldn't include any base URL. because of
21+
// annoying differences between dev and build modes, due to this behavior
22+
// (https://github.com/withastro/astro/issues/5630), we also have to remove
23+
// any trailing slash so currentPage can match the href.
24+
const currentPage = Astro.url.pathname
25+
.replace(baseURL, "")
26+
.replace(/(?<=\w)\/$/, "");
27+
// set the attribute to undefined when it's not the current page so
28+
// aria-current="false" isn't added to the anchor
29+
const ariaCurrent = currentPage === href ? "page" : undefined;
630
---
7-
<a href={href} class="text-current no-underline hover:underline">
31+
<a href={base(href)}
32+
aria-current={ariaCurrent}
33+
class:list={[
34+
"font-normal text-current no-underline hover:underline",
35+
className,
36+
ariaCurrent && "text-muted! decoration-inherit cursor-default pointer-events-none",
37+
ariaCurrent && activeClass,
38+
]}
39+
>
840
<slot />
941
</a>

src/styles/global.css

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
--color-primary: var(--color-sf-red);
99
--color-text-base: black;
1010
--color-background-base: white;
11+
--color-muted: var(--color-stone-500);
1112

1213
--text-sm: 1rem; /* 16px */
1314
--text-base: 1.125rem; /* 18px */
@@ -51,9 +52,6 @@
5152
}
5253

5354
body {
54-
/*
55-
font-family: var(--font-body);
56-
*/
5755
color: var(--color-text-base);
5856
background-color: var(--color-background-base);
5957
}
@@ -64,7 +62,14 @@
6462

6563
a:where(a:not([role=button])), [role=link] {
6664
color: var(--color-sf-red);
67-
@apply underline font-semibold;
65+
@apply underline
66+
font-semibold
67+
transition
68+
duration-300
69+
ease-out
70+
underline-offset-[.2rem]
71+
decoration-primary/25
72+
hover:decoration-primary;
6873
}
6974
}
7075

0 commit comments

Comments
 (0)