Skip to content

Commit

Permalink
Add Navbar Component with nav links generated from pages
Browse files Browse the repository at this point in the history
  • Loading branch information
luciodale committed Jul 17, 2022
1 parent eb06c9e commit ab661dd
Show file tree
Hide file tree
Showing 11 changed files with 126 additions and 164 deletions.
49 changes: 19 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,6 @@
# Welcome to [Astro](https://astro.build)
# JUXT Website

[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/withastro/astro/tree/latest/examples/basics)

> 🧑‍🚀 **Seasoned astronaut?** Delete this file. Have fun!
## 🚀 Project Structure

Inside of your Astro project, you'll see the following folders and files:

```
/
├── public/
│ └── favicon.ico
├── src/
│ ├── components/
│ │ └── Layout.astro
│ └── pages/
│ └── index.astro
└── package.json
```

Astro looks for `.astro` or `.md` files in the `src/pages/` directory. Each page is exposed as a route based on its file name.

There's nothing special about `src/components/`, but that's where we like to put any Astro/React/Vue/Svelte/Preact components or layouts.

Any static assets, like images, can be placed in the `public/` directory.

## 🧞 Commands
## Quick Commands

All commands are run from the root of the project, from a terminal:

Expand All @@ -37,6 +11,21 @@ All commands are run from the root of the project, from a terminal:
| `npm run build` | Build your production site to `./dist/` |
| `npm run preview` | Preview your build locally, before deploying |

## 👀 Want to learn more?
## Components

After reading this section, you should be able to perform the most common changes to the site.

### Navbar

The Navbar can be found in `components/Navbar.astro`. The links in the Navbar are driven by the `metadata` variable that is defined at the `page` level.
For a page to appear in the Navbar, it needs a `navbar` key with optional `label` and `weight` attributes, the latter controls the position.
An example follows:

```js
// somewhere in the frontmatter of about.astro page

export const metadata = { navbar: { weight: 1 } };
```

Feel free to check [our documentation](https://docs.astro.build) or jump into our [Discord server](https://astro.build/chat).
Here, we are saying that we want the about page to be linked in the navbar (presence of navbar key) and that it has to be the first link (weight of 1).
Note that without a `label` key the label will default to the name of the `*pageName*.astro` file, so in this example it will be `about`.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,4 +33,4 @@
"prettier --write --ignore-unknown --plugin-search-dir=. ."
]
}
}
}
16 changes: 16 additions & 0 deletions src/components/NavLink.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
type NavLinkProp = {
href: string
label: string
active?: boolean
}
const { label, href, active } = Astro.props as NavLinkProp
---

<a
class:list={['hover:text-juxt transition-colors', { 'text-juxt': active }]}
href={href}
>
{label}
</a>
42 changes: 42 additions & 0 deletions src/components/Navbar.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
---
import logo from '../assets/images/logo.svg'
import { removeLeadingSlash } from '../utils'
import NavLink from './NavLink.astro'
const url = new URL(Astro.request.url)
const currentPage = url.pathname
type PageProps = {
metadata?: { navbar?: { weight?: number; label?: string } }
url: string
}
const pages = await Astro.glob<PageProps>('../pages/**/*.astro')
const pagesInNavbar = pages
.filter((page) => page?.metadata?.navbar)
.map((page) => ({
url: page.url,
weight: page.metadata?.navbar?.weight,
label: page.metadata?.navbar?.label || removeLeadingSlash(page.url),
active: page.url === currentPage
}))
.sort((a, b) => a.weight - b.weight)
---

<nav class='w-full bg-black h-14'>
<div
class='container mx-auto px-2 sm:px-12 2xl:px-0 max-w-6xl flex items-center justify-between h-full'
>
<a href='/' class='flex items-center'>
<img src={logo} width='80px' alt='Juxt Logo' />
</a>
<div
class='flex items-center gap-8 uppercase tracking-widest text-xs text-white'
>
{pagesInNavbar.map((page) => (
<NavLink href={page.url} label={page.label} active={page.active} />
))}
</div>
</div>
</nav>
30 changes: 0 additions & 30 deletions src/components/Navbar.tsx

This file was deleted.

51 changes: 12 additions & 39 deletions src/layouts/Layout.astro
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
---
export interface Props {
title: string
import Navbar from '../components/Navbar.astro'
import { capitalizeFirstLetter, removeLeadingSlash } from '../utils'
type LayoutProps = {
title?: string
navbar?: boolean
}
const { title } = Astro.props as Props
const url = new URL(Astro.request.url)
const currentPage = removeLeadingSlash(removeLeadingSlash(url.pathname))
const { title, navbar } = Astro.props as LayoutProps
---

<!DOCTYPE html>
Expand All @@ -13,44 +20,10 @@ const { title } = Astro.props as Props
<meta name='viewport' content='width=device-width' />
<link rel='icon' type='image/x-icon' href='/favicon.ico' />
<link rel='stylesheet' href='/styles/inter.css' />
<title>{title}</title>
<title>{title || capitalizeFirstLetter(currentPage)}</title>
</head>
<body>
{navbar && <Navbar client:visible />}
<slot></slot>
<style>
:root {
--font-size-base: clamp(1rem, 0.34vw + 0.91rem, 1.19rem);
--font-size-lg: clamp(1.2rem, 0.7vw + 1.2rem, 1.5rem);
--font-size-xl: clamp(2.44rem, 2.38vw + 1.85rem, 3.75rem);

--color-text: hsl(12, 5%, 4%);
--color-bg: hsl(10, 21%, 95%);
--color-border: hsl(17, 24%, 90%);
}

html {
font-family: system-ui, sans-serif;
font-size: var(--font-size-base);
color: var(--color-text);
background-color: var(--color-bg);
}

body {
margin: 0;
}

:global(h1) {
font-size: var(--font-size-xl);
}

:global(h2) {
font-size: var(--font-size-lg);
}

:global(code) {
font-family: Menlo, Monaco, Lucida Console, Liberation Mono,
DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace;
}
</style>
</body>
</html>
9 changes: 9 additions & 0 deletions src/pages/about.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
import Layout from '../layouts/Layout.astro'
export const metadata = { navbar: { weight: 1 } }
---

<Layout navbar={true}>
<main>about page here</main>
</Layout>
65 changes: 1 addition & 64 deletions src/pages/index.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,9 @@
import Layout from '../layouts/Layout.astro'
import Card from '../components/Card.astro'
import Counter from '../components/Counter.jsx'
import Navbar from '../components/Navbar.jsx'
---

<Navbar client:visible />
<Layout title='Welcome to Astro.'>
<Layout title='Welcome to Astro.' navbar={true}>
<main>
<h1>Welcome to <span class='text-gradient'>Astro</span></h1>
<p class='instructions'>
Expand Down Expand Up @@ -41,64 +39,3 @@ import Navbar from '../components/Navbar.jsx'
</ul>
</main>
</Layout>

<style>
:root {
--astro-gradient: linear-gradient(0deg, #4f39fa, #da62c4);
}

h1 {
margin: 2rem 0;
}

main {
margin: auto;
padding: 1em;
max-width: 60ch;
}

.text-gradient {
font-weight: 900;
background-image: var(--astro-gradient);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-size: 100% 200%;
background-position-y: 100%;
border-radius: 0.4rem;
animation: pulse 4s ease-in-out infinite;
}

@keyframes pulse {
0%,
100% {
background-position-y: 0%;
}

50% {
background-position-y: 80%;
}
}

.instructions {
line-height: 1.6;
margin: 1rem 0;
background: #4f39fa;
padding: 1rem;
border-radius: 0.4rem;
color: var(--color-bg);
}

.instructions code {
font-size: 0.875em;
border: 0.1em solid var(--color-border);
border-radius: 4px;
padding: 0.15em 0.25em;
}

.link-card-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(24ch, 1fr));
gap: 1rem;
padding: 0;
}
</style>
9 changes: 9 additions & 0 deletions src/pages/technology.astro
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
import Layout from '../layouts/Layout.astro'
export const metadata = { navbar: { weight: 2 } }
---

<Layout title='Technology' navbar={true}>
<main>technolgoy page here</main>
</Layout>
14 changes: 14 additions & 0 deletions src/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/** Remove \ and / from beginning of string */
export function removeLeadingSlash(path: string) {
return path.replace(/^[/\\]+/, "");
}

/** Remove \ and / from end of string */
export function removeTrailingSlash(path: string) {
return path.replace(/[/\\]+$/, "");
}

// capitalize first letter of string
export function capitalizeFirstLetter(str: string) {
return str.charAt(0).toUpperCase() + str.slice(1);
}
3 changes: 3 additions & 0 deletions tailwind.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@ module.exports = {
fontFamily: {
sans: ["Inter", ...defaultTheme.fontFamily.sans],
},
colors: {
juxt: "#f4901d",
},
},
},
plugins: [],
Expand Down

0 comments on commit ab661dd

Please sign in to comment.