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

feat: Added Navbar component #6072

Merged
merged 22 commits into from
Nov 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
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
2 changes: 1 addition & 1 deletion components/Common/LanguageDropDown/index.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ export const Default: Story = {
{ name: 'French', code: 'fr' },
{ name: 'Spanish', code: 'es' },
],
currentLanguage: { name: 'English', code: 'en' },
currentLanguage: 'en',
},
};

Expand Down
4 changes: 2 additions & 2 deletions components/Common/LanguageDropDown/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ type SimpleLocaleConfig = Pick<LocaleConfig, 'name' | 'code'>;

type LanguageDropDownProps = {
onChange?: (newLocale: SimpleLocaleConfig) => void;
currentLanguage: SimpleLocaleConfig;
currentLanguage: string;
availableLanguages: SimpleLocaleConfig[];
};

Expand Down Expand Up @@ -45,7 +45,7 @@ const LanguageDropdown: FC<LanguageDropDownProps> = ({
key={code}
onClick={() => onChange({ name, code })}
className={classNames(styles.dropDownItem, {
[styles.currentDropDown]: code === currentLanguage.code,
[styles.currentDropDown]: code === currentLanguage,
})}
>
{name}
Expand Down
108 changes: 108 additions & 0 deletions components/Containers/NavigationBar/index.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
.container {
@apply border-neutral-200
dark:border-neutral-900
md:flex
md:h-16
md:flex-row
md:items-center
md:gap-8
md:border-b
md:px-8;
}

.nodeIconAndMobileItemsToggler {
@apply flex
h-16
shrink-0
items-center
border-b
border-neutral-200
px-4
dark:border-neutral-900
md:flex
md:h-full
md:items-center
md:border-0
md:px-0;
}

.nodeIconWrapper {
@apply h-[30px]
flex-1;
}

.nodejsLogoDark {
@apply h-6
w-20
dark:hidden;
}

.nodejsLogoLight {
@apply hidden
h-6
w-20
dark:block;
}

.navInteractionIcon {
@apply h-6
w-6;
}

.sidebarItemTogglerLabel {
@apply block
cursor-pointer
md:hidden;
}

.main {
@apply hidden
flex-1
flex-col
md:flex
md:flex-row
md:items-center;
}

.navItems {
@apply flex
flex-col
gap-1
border-b
border-neutral-200
p-4
dark:border-neutral-900
md:flex-1
md:flex-row
md:border-0
md:p-0;
}

.actionsWrapper {
@apply flex
items-center
gap-2
border-b
border-neutral-200
p-4
dark:border-neutral-900
md:border-0
md:p-0;
}

.ghIconWrapper {
@apply h-9
w-9
rounded-md
p-2;

svg {
@apply fill-neutral-700
dark:fill-neutral-300;
}

&:hover {
@apply bg-neutral-100
dark:bg-neutral-900;
}
}
48 changes: 48 additions & 0 deletions components/Containers/NavigationBar/index.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import type { Meta as MetaObj, StoryObj } from '@storybook/react';

import NavigationBar from './index';

type Story = StoryObj<typeof NavigationBar>;
type Meta = MetaObj<typeof NavigationBar>;

export const Default: Story = {
args: {
navItems: [
{
text: 'Learn',
href: '/learn',
},
{
text: 'About',
href: '/about',
},
{
text: 'Docs',
href: '/docs',
},
{
text: 'Download',
href: '/download',
},
{
text: 'Blog',
href: '/blog',
},
{
text: 'Certification',
href: 'https://openjsf.org/certification',
},
],
languages: {
availableLanguages: [
{ name: 'English', code: 'en' },
{ name: 'French', code: 'fr' },
{ name: 'Spanish', code: 'es' },
],
currentLanguage: 'en',
},
onThemeTogglerClick: () => {},
},
};

export default { component: NavigationBar } as Meta;
80 changes: 80 additions & 0 deletions components/Containers/NavigationBar/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
'use client';

import Hamburger from '@heroicons/react/24/solid/Bars3Icon';
import XMark from '@heroicons/react/24/solid/XMarkIcon';
import * as Label from '@radix-ui/react-label';
import { useState } from 'react';
import type { FC, ComponentProps } from 'react';

import LanguageDropdown from '@/components/Common/LanguageDropDown';
import ThemeToggle from '@/components/Common/ThemeToggle';
import NavItem from '@/components/Containers/NavItem';
import GithubLogo from '@/components/Icons/GitHubLogo';
import NodejsLogoDark from '@/components/Icons/NodejsLogoDark';
import NodejsLogoLight from '@/components/Icons/NodejsLogoLight';

import style from './index.module.css';

type NavItem = { text: string; href: string };

type NavbarProps = {
navItems: NavItem[];
languages: ComponentProps<typeof LanguageDropdown>;
onThemeTogglerClick: () => void;
};

const navInteractionIcons = {
show: <Hamburger className={style.navInteractionIcon} />,
close: <XMark className={style.navInteractionIcon} />,
};

const NavigationBar: FC<NavbarProps> = ({
navItems,
languages,
onThemeTogglerClick,
}) => {
const [isMenuOpen, setIsMenuOpen] = useState(false);
return (
<nav className={`${style.container}`}>
<div className={style.nodeIconAndMobileItemsToggler}>
<div className={style.nodeIconWrapper}>
<NodejsLogoDark className={style.nodejsLogoDark} />
<NodejsLogoLight className={style.nodejsLogoLight} />
</div>
<Label.Root
onClick={() => setIsMenuOpen(prev => !prev)}
className={style.sidebarItemTogglerLabel}
htmlFor="sidebarItemToggler"
>
{navInteractionIcons[isMenuOpen ? 'close' : 'show']}
</Label.Root>
</div>
<input className="peer hidden" id="sidebarItemToggler" type="checkbox" />
<div className={`${style.main} peer-checked:flex`}>
<div className={style.navItems}>
{navItems.map(({ text, href }) => (
<NavItem key={text} href={href}>
{text}
</NavItem>
))}
</div>
<div className={style.actionsWrapper}>
<ThemeToggle onClick={onThemeTogglerClick} />
<LanguageDropdown
availableLanguages={languages.availableLanguages}
currentLanguage={languages.currentLanguage}
/>
<a
className={style.ghIconWrapper}
href="https://github.com/nodejs/node"
ovflowd marked this conversation as resolved.
Show resolved Hide resolved
aria-label="Node.js Github"
>
<GithubLogo />
</a>
</div>
</div>
</nav>
);
};

export default NavigationBar;
16 changes: 16 additions & 0 deletions components/Icons/GitHubLogo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { FC, HTMLAttributes } from 'react';

const GitHubLogo: FC<HTMLAttributes<SVGElement>> = props => (
<svg
width="20"
height="20"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
{...props}
>
<path d="M10 1.25C5.16562 1.25 1.25 5.16562 1.25 10C1.25 13.8719 3.75469 17.1422 7.23281 18.3016C7.67031 18.3781 7.83437 18.1156 7.83437 17.8859C7.83437 17.6781 7.82344 16.9891 7.82344 16.2563C5.625 16.6609 5.05625 15.7203 4.88125 15.2281C4.78281 14.9766 4.35625 14.2 3.98438 13.9922C3.67812 13.8281 3.24063 13.4234 3.97344 13.4125C4.6625 13.4016 5.15469 14.0469 5.31875 14.3094C6.10625 15.6328 7.36406 15.2609 7.86719 15.0312C7.94375 14.4625 8.17344 14.0797 8.425 13.8609C6.47813 13.6422 4.44375 12.8875 4.44375 9.54062C4.44375 8.58906 4.78281 7.80156 5.34062 7.18906C5.25313 6.97031 4.94687 6.07344 5.42812 4.87031C5.42812 4.87031 6.16094 4.64063 7.83437 5.76719C8.53438 5.57031 9.27813 5.47187 10.0219 5.47187C10.7656 5.47187 11.5094 5.57031 12.2094 5.76719C13.8828 4.62969 14.6156 4.87031 14.6156 4.87031C15.0969 6.07344 14.7906 6.97031 14.7031 7.18906C15.2609 7.80156 15.6 8.57812 15.6 9.54062C15.6 12.8984 13.5547 13.6422 11.6078 13.8609C11.925 14.1344 12.1984 14.6594 12.1984 15.4797C12.1984 16.65 12.1875 17.5906 12.1875 17.8859C12.1875 18.1156 12.3516 18.3891 12.7891 18.3016C14.5261 17.7152 16.0355 16.5988 17.1048 15.1096C18.1741 13.6204 18.7495 11.8333 18.75 10C18.75 5.16562 14.8344 1.25 10 1.25Z" />
</svg>
);

export default GitHubLogo;
Loading
Loading