Skip to content

Commit ba17bc8

Browse files
Navbar rebasement (#35)
* feat: Create `burgerMenu` and `closeIcon` svg files * refactor!: Implement Alpine.js for handling navbar interactivity + Add `Link.astro` Navbar original interactivity was built using JS vanilla. Looking to materialize current navbar mockup design, offcanvas menu was rebuilt using Alpine.js to refactor some feautures and incorporate new ones --like a close button * refactor!: Implement interactivity, order and formatting enhancements for `Navbar.astro` - Group Navbar and children components within a dedicated folder - Set `close()` method to `Link.astro` for closing offcanvas menu when clicking any option - Enhance code formatting * fix: Avoid re-declarations in `OffcanvasMenu.astro` Details: Renamed `Link` interface to `LinkBody` * fix: Address click event bug in `Link.astro` While testing screen size change from mobile to desktop, and click in any link in menu, offcanvas menu activated (and we don't want this in desktop view). This commit implements a new condition in `Link.astro` click event for avoiding this. * fix: expected } but instead the file ends biomejs/biome#4141 --------- Co-authored-by: Brayen Gavilanes <[email protected]>
1 parent a415053 commit ba17bc8

File tree

8 files changed

+138
-69
lines changed

8 files changed

+138
-69
lines changed

public/icons/burgerMenu.svg

+3
Loading

public/icons/closeIcon.svg

+3
Loading

src/components/Navbar.astro

-67
This file was deleted.

src/components/Navbar/Link.astro

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
interface Props {
3+
text: string;
4+
href: string;
5+
size?: string;
6+
}
7+
8+
const { text, href, size } = Astro.props;
9+
---
10+
<!--
11+
Link component:
12+
- Handles navigation within the app.
13+
- (Within offcanvas menu) clicking a link triggers `toggleMenu()` to close the menu and navigate to the selected section.
14+
15+
* IMPORTANT: This logic applies only to relevant use cases. External links or non-interactive links might require adjustments.
16+
-->
17+
<div @click="openMenu && toggleMenu()">
18+
<a
19+
href={href}
20+
class={`font-gabarito text-gray-300 ${size} tracking-wide px-3 py-2 rounded-md hover:text-white`}
21+
>
22+
{text}
23+
</a>
24+
</div>

src/components/Navbar/Navbar.astro

+53
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
---
2+
import Link from "./Link.astro";
3+
4+
import burgerMenuIcon from "../../../public/icons/burgerMenu.svg?raw";
5+
import OffcanvasMenu from "./OffcanvasMenu.astro";
6+
7+
const links = [
8+
{ text: "Inicio", href: "/" },
9+
{ text: "Comunidades", href: "/communities" },
10+
{ text: "Eventos", href: "/events" },
11+
{ text: "Voluntariado", href: "/#about-us" },
12+
];
13+
---
14+
<!--
15+
Navbar component:
16+
- Includes Alpine.js state (`openMenu`) and method (`toggleMenu`) to manage the offcanvas menu interactivity.
17+
- Alpine.js directives control visibility (`x-bind:class`), user interaction (`@click`), and transitions (`x-transition`) in father and children components.
18+
- Links are rendered dynamically.
19+
-->
20+
21+
<nav
22+
x-data="{
23+
openMenu: false,
24+
25+
toggleMenu() {
26+
this.openMenu = !this.openMenu;
27+
}
28+
}"
29+
class="bg-gray-800 w-full fixed z-10"
30+
>
31+
<div class="container mx-auto px-4 py-2 flex justify-between items-center">
32+
<a href="/" class="font-gabarito text-white text-lg font-bold">Ecuador In Tech</a>
33+
34+
<!-- Burger menu button -->
35+
<button
36+
@click="toggleMenu()"
37+
id="mobile-menu-button"
38+
class="block lg:hidden"
39+
>
40+
<Fragment set:html={burgerMenuIcon} />
41+
</button>
42+
43+
<!-- Links -->
44+
<div class="hidden lg:flex lg:items-center lg:space-x-8">
45+
{links.slice(1).map((link) => (
46+
<Link href={link.href} text={link.text} size="text-[0.95rem]"/>
47+
))}
48+
</div>
49+
</div>
50+
51+
<!-- Mobile menu -->
52+
<OffcanvasMenu links={links}/>
53+
</nav>
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
import closeIcon from "../../../public/icons/closeIcon.svg?raw";
3+
import Link from "./Link.astro";
4+
5+
interface LinkBody {
6+
text: string;
7+
href: string;
8+
}
9+
10+
const { links } = Astro.props;
11+
---
12+
<!--
13+
OffcanvasMenu component:
14+
- Interactivity relies on Alpine.js:
15+
1. Visibility: Managed by `x-bind:class`, implements Tailwind classes relying on the `openMenu` state from `Navbar`.
16+
2. Transitions: Implemented using `x-transition.origin.top.left` for smooth animations.
17+
3. Blinking prevention: Uses `x-cloak` to hide elements until Alpine.js initializes.
18+
- User actions (clicking the burger menu or links) trigger `toggleMenu()` to open/close the menu.
19+
-->
20+
21+
<div
22+
x-cloak
23+
x-bind:class="{
24+
'translate-x-0 ': openMenu,
25+
'-translate-x-full duration-400': !openMenu
26+
}"
27+
class="fixed top-0 left-0 w-full h-full bg-gray-800 text-white transform transition-transform duration-300"
28+
>
29+
<!-- Close button -->
30+
<a
31+
@click="toggleMenu()"
32+
class="w-full flex flex-row justify-end px-4 py-3 text-white cursor-pointer"
33+
>
34+
<Fragment set:html={closeIcon} />
35+
</a>
36+
37+
<!-- Links -->
38+
<ul class="flex flex-col items-center justify-center h-full p-4">
39+
{
40+
links.map((link: LinkBody) => (
41+
<div class="block my-4 px-4 uppercase text-xl hover:font-medium">
42+
<Link href={link.href} text={link.text} />
43+
</div>
44+
))
45+
}
46+
<div class="h-[10%]"></div>
47+
</ul>
48+
</div>

src/layouts/Layout.astro

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
import Footer from "../components/Footer.astro";
3-
import Navbar from "../components/Navbar.astro";
3+
import Navbar from "../components/Navbar/Navbar.astro";
44
55
// Incorporate global styles file to whole website
66
import "../styles/globals.css";

src/styles/globals.css

+6-1
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,14 @@
3333
}
3434

3535
span,
36-
svg {
36+
svg{
3737
@apply text-sm;
3838
}
39+
40+
/* Avoids undesired offcanvas menu 'blink' when closing */
41+
[x-cloak] {
42+
display: none !important;
43+
}
3944

4045
/* Components custom styles */
4146
.faqs-container {

0 commit comments

Comments
 (0)