Skip to content
This repository was archived by the owner on Feb 10, 2025. It is now read-only.

feat: Add Navbar #53

Merged
merged 5 commits into from
Nov 27, 2024
Merged
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
12 changes: 12 additions & 0 deletions src/assets/icons/checker.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/icons/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export { default as UserIcon } from "./user.svg?react";
export { default as VerifiedBadgeIcon } from "./verifiedBadge.svg?react";
export { default as GlobeIcon } from "./globe.svg?react";
export { default as ExplorerIcon } from "./explorer.svg?react";
export { default as CheckerIcon } from "./checker.svg?react";

// Social Media Icons
export { default as GithubIcon } from "./github.svg?react";
Expand Down
4 changes: 4 additions & 0 deletions src/assets/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export {default as GitcoinLogo} from "./gitcoinlogo.png";
export {default as DefaultLogo} from "./default_logo.png";
export {default as DefaultBanner} from "./default_banner.jpg";
export {default as GitcoinBanner} from "./gitcoinbanner.png";
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import * as React from "react";
import { IconLabel } from "@/components/IconLabel";
import { useCredentialverification } from "@/features/checker/hooks";
import { ProjectApplicationForManager, ProjectMetadata } from "@/features/checker/services/allo";
import { isVerified } from "@/lib/passport/credentialVerification";
import { IconType } from "@/primitives/Icon";

export interface ProjectSummaryProps {
Expand Down
2 changes: 1 addition & 1 deletion src/primitives/Button/Button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ const Button = React.forwardRef<HTMLButtonElement, ButtonProps>(
{...props}
>
{icon && iconPosition === "left" && <span>{icon}</span>}
{value && <span className={cn(icon ? "" : "mt-0.5", "font-mono")}>{value}</span>}
{value && <span className={"font-mono"}>{value}</span>}
{icon && iconPosition === "right" && <span>{icon}</span>}
</Comp>
);
Expand Down
23 changes: 23 additions & 0 deletions src/primitives/Navbar/Navbar.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Meta, Title, Primary, Stories, Controls, Story } from "@storybook/blocks";
import { Navbar } from "./Navbar";
import * as NavbarStories from "./Navbar.stories";

# Navbar

<Meta of={NavbarStories} />

The Navbar component displays a navigation bar with optional logos and text. It can also render children elements on the right.

# Example

## Default

<Story of={NavbarStories.Default} />

# Controls

<Controls />

# Other variations

<Stories/>
80 changes: 80 additions & 0 deletions src/primitives/Navbar/Navbar.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
import type { Meta, StoryObj } from "@storybook/react";

import { DefaultLogo } from "@/assets";
import { CheckerIcon } from "@/assets/icons";

import { Button } from "../Button";
import { Navbar } from "./Navbar";

// Adjust the path as needed

const meta = {
title: "Primitives/Navbar",
component: Navbar,
args: {
text: "My Navbar",
},
argTypes: {
primaryLogo: {
control: "text",
},
secondaryLogo: {
control: "text",
},
primaryLogoLink: {
control: "text",
},
secondaryLogoLink: {
control: "text",
},
textLink: {
control: "text",
},
text: {
control: "text",
},
children: {
control: "text",
},
},
} satisfies Meta<typeof Navbar>;

export default meta;

type Story = StoryObj<typeof Navbar>;

export const Default: Story = {
args: {
primaryLogoLink: "#",
secondaryLogo: CheckerIcon,
secondaryLogoLink: "#",
textLink: "#",
},
};

export const WithSecondaryLogo: Story = {
args: {
primaryLogoLink: "#",
secondaryLogo: DefaultLogo,
secondaryLogoLink: "#",
textLink: "#",
},
};

export const WithCustomTextAndWithoutDivider: Story = {
args: {
primaryLogoLink: "#",
text: "Custom Navbar",
textLink: "#",
showDivider: false,
},
};

export const WithChildren: Story = {
args: {
secondaryLogo: DefaultLogo,
secondaryLogoLink: "#",
textLink: "#",
children: <Button value="Connect Wallet" />,
},
};
82 changes: 82 additions & 0 deletions src/primitives/Navbar/Navbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import * as React from "react";

import { tv } from "tailwind-variants";

import { GitcoinLogo } from "@/assets";

const defaultLogo = GitcoinLogo;

const navbarVariants = tv({
slots: {
base: "top-0 flex h-[64px] w-full shrink-0 flex-col items-center justify-center gap-2 p-[10px_80px]",
container: "flex w-full items-center justify-between",
leftSection: "flex items-center gap-4",
logo: "h-10 max-w-12",
divider: "h-4 border-r border-grey-700",
text: "text-lg font-semibold",
rightSection: "flex items-center",
},
});

export interface NavbarProps {
primaryLogo?: string | React.FunctionComponent<React.SVGAttributes<SVGElement>>;
secondaryLogo?: string | React.FunctionComponent<React.SVGAttributes<SVGElement>>;
showDivider?: boolean;
text: string;
primaryLogoLink?: string;
secondaryLogoLink?: string;
textLink?: string;
children?: React.ReactNode;
}

export const Navbar = ({
primaryLogo,
secondaryLogo,
showDivider = true,
text,
primaryLogoLink,
secondaryLogoLink,
textLink,
children,
}: NavbarProps) => {
const {
base,
container,
leftSection,
logo,
divider,
text: textStyle,
rightSection,
} = navbarVariants();

const renderLogo = (
img: string | React.FunctionComponent<React.SVGAttributes<SVGElement>> | undefined,
) => {
if (!img) {
return <img src={defaultLogo} alt="Default Logo" className={logo()} />;
}

if (typeof img === "string") {
return <img src={img} alt="Logo" className={logo()} />;
}

const LogoComponent = img;
return <LogoComponent className={logo()} />;
};

return (
<nav className={base()}>
<div className={container()}>
<div className={leftSection()}>
<a href={primaryLogoLink || "#"}>{renderLogo(primaryLogo)}</a>
{showDivider && <div className={divider()}></div>}
{secondaryLogo && <a href={secondaryLogoLink || "#"}>{renderLogo(secondaryLogo)}</a>}
<a href={textLink || "#"} className={textStyle()}>
{text}
</a>
</div>
<div className={rightSection()}>{children}</div>
</div>
</nav>
);
};