Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add icons and refactor navbar to support mobile view #400

Open
wants to merge 1 commit into
base: development
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions components/IconBars/IconBars.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Meta, StoryObj } from "@storybook/react";
import IconBars from "./IconBars";
export default {
title: "Iconos/Bars",
component: IconBars,
} as Meta<typeof IconBars>;
export const DefaultIconBars: StoryObj<typeof IconBars> = {
args: {},
};
export const WhiteIconBars: StoryObj<typeof IconBars> = {
args: {
className: "fill-white",
},
};
22 changes: 22 additions & 0 deletions components/IconBars/IconBars.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { render, screen } from "@testing-library/react";
import IconBars from "./IconBars";

describe("XMark", () => {
it("IconBars renders correctly", () => {
render(<IconBars />);
});

it("XMark component adds className prop", () => {
const className = "fill-white";
render(<IconBars className={className} />);
const svgElement = screen.getByTestId(className);
expect(svgElement).toHaveClass(className);
});

it("XMark has aria-hidden attribute", () => {
const className = "fill-white";
render(<IconBars className={className} />);
const svgElement = screen.getByTestId(className);
expect(svgElement).toHaveAttribute("aria-hidden", "true");
});
});
24 changes: 24 additions & 0 deletions components/IconBars/IconBars.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
type IconBarsProps = {
className?: string;
};

const IconBars = ({ className }: IconBarsProps) => {
return (
<svg
width="23"
height="16"
viewBox="0 0 23 16"
fill="none"
xmlns="http://www.w3.org/2000/svg"
className={className}
data-testid={className}
aria-hidden="true"
>
<rect width="23" height="4" rx="1" fill="#D2451A" />
<rect y="6" width="23" height="4" rx="1" fill="#D2451A" />
<rect y="12" width="23" height="4" rx="1" fill="#D2451A" />
</svg>
);
};

export default IconBars;
120 changes: 99 additions & 21 deletions components/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,100 @@
"use client";
import React from "react";
import Link from "next/link";
import { usePathname } from "next/navigation";
import React from "react";
import { Disclosure } from "@headlessui/react";
import type { NavbarLink } from "types/layout";
import { Logo } from "../Logo/Logo";
import XMark from "components/XMark/XMark";
import IconBars from "components/IconBars/IconBars";

interface NavbarLinkProps extends React.HTMLProps<HTMLLIElement> {
route: string;
}

interface NavbarProps extends Partial<React.HTMLProps<HTMLElement>> {
interface NavbarProps {
links: NavbarLink[];
}

export const Navbar = ({ links, ...props }: NavbarProps) => {
export const Navbar = ({ links }: NavbarProps) => {
const pathname = usePathname();
const isCurrentIndex = pathname === "/";

return (
<nav aria-label="Navegacion principal" {...props}>
<div className="mx-auto flex max-w-[1000px] items-center justify-between">
<Link
aria-label="Home"
href={"/"}
aria-current={isCurrentIndex ? "page" : false}
>
<Logo className="h-auto w-28" />
</Link>
<ul className="flex flex-row space-x-[55px] self-start border-b-[0.5px] border-b-gray pt-1">
{links.map(({ url, name }) => (
<NavbarItem key={name} route={url}>
{name}
</NavbarItem>
))}
</ul>
</div>
</nav>
<Disclosure as="nav" aria-label="Navegacion principal">
{({ open, close }) => (
<>
<div className="mx-auto flex max-w-[1000px] items-center justify-between">
<Link
aria-label="Home"
href={"/"}
aria-current={isCurrentIndex ? "page" : false}
>
<Logo className="h-auto w-20 sm:w-28 p-2" />
</Link>

{/* Mobile menu open button*/}
<Disclosure.Button className="sm:hidden p-2">
{!open && (
<div className="flex items-center space-x-5 text-orange">
<p
className="font-outfit text-base font-bold"
data-text="Menú"
>
Menú
</p>
<IconBars className="block h-6 w-6" aria-hidden="true" />
</div>
)}
</Disclosure.Button>

{/* nav items desktop */}
<ul className="flex-row space-x-[55px] self-start border-b-[0.5px] border-b-gray pt-1 hidden sm:flex">
{links.map(({ url, name }) => (
<NavbarItem key={name} route={url}>
{name}
</NavbarItem>
))}
</ul>

{/* nav items mobile */}
<Disclosure.Panel
className={`${
open ? "block" : "hidden"
} sm:hidden fixed inset-0 z-50 bg-orange`}
>
{/* Mobile menu close button*/}
{open && (
<div className="flex justify-end">
<Disclosure.Button className="p-6 ">
<div className="flex items-center space-x-5">
<p
className="font-outfit text-base font-bold text-white"
data-text="Cerrar"
>
Cerrar
</p>
<XMark className="block h-6 w-6" aria-hidden="true" />
</div>
</Disclosure.Button>
</div>
)}
<div className="flex flex-col space-y-9 px-6">
{links.map(({ url, name }) => (
<NavBarItemMobile
key={name}
route={url}
onClick={() => close()}
>
{name}
</NavBarItemMobile>
))}
</div>
</Disclosure.Panel>
</div>
</>
)}
</Disclosure>
);
};

Expand Down Expand Up @@ -62,3 +122,21 @@ export const NavbarItem = ({ children, route, ...props }: NavbarLinkProps) => {
</li>
);
};

const NavBarItemMobile = ({ children, route, ...props }: NavbarLinkProps) => {
const pathname = usePathname();
const isCurrent = pathname === route;

return (
<li className={`flex h-[36px] rounded-none`} key={route} {...props}>
<Link
data-text={children}
className="block overflow-hidden font-outfit font-extrabold text-xl text-white"
href={route}
aria-current={isCurrent ? "page" : false}
>
{children}
</Link>
</li>
);
};