Skip to content
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
13 changes: 8 additions & 5 deletions apps/site/components/withNavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,14 @@ const WithNavBar: FC = () => {
<WithBanner section="index" />

<NavBar
navItems={navigationItems.map(([, { label, link, target }]) => ({
link,
text: label,
target,
}))}
navItems={navigationItems.map(
([, { label, link, target, accent }]) => ({
link,
text: label,
target,
accent,
})
)}
pathname={pathname}
as={Link}
Logo={WithNodejsLogo}
Expand Down
4 changes: 3 additions & 1 deletion apps/site/hooks/useSiteNavigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ type MappedNavigationEntry = {
label: FormattedMessage;
link: string;
target?: HTMLAttributeAnchorTarget | undefined;
accent?: boolean;
};

// Provides Context replacement for variables within the Link. This is also something that is not going
Expand All @@ -44,13 +45,14 @@ const useSiteNavigation = () => {
t.rich(label, context[key] || {}) as FormattedMessage;

return Object.entries(entries).map(
([key, { label, link, items, target }]): [
([key, { label, link, items, target, accent }]): [
string,
MappedNavigationEntry,
] => [
key,
{
target,
accent,
label: label ? getFormattedMessage(label, key) : '',
link: link ? replaceLinkWithContext(link, context[key]) : '',
items: items ? mapNavigationEntries(items, context) : [],
Expand Down
6 changes: 6 additions & 0 deletions apps/site/navigation.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
"link": "https://nodejs.org/docs/latest/api/",
"label": "components.containers.navBar.links.docs"
},
"betaDocs": {
"link": "https://beta.docs.nodejs.org/",
"label": "components.containers.navBar.links.betaDocs",
"target": "_blank",
"accent": true
},
Comment thread
bmuenzenmeyer marked this conversation as resolved.
"contribute": {
"link": "https://github.com/nodejs/node/blob/main/CONTRIBUTING.md",
"label": "components.containers.navBar.links.contribute",
Expand Down
13 changes: 11 additions & 2 deletions apps/site/tests/e2e/general-behavior.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ const locators = {
mobileMenuToggleName:
englishLocale.components.containers.navBar.controls.toggle,
navLinksLocator: `[aria-label="${englishLocale.components.containers.navBar.controls.toggle}"] + div`,
// The Beta Docs link renders untranslated (English) across locales, so we
// match on its English label to skip it during translation checks.
betaDocsName: englishLocale.components.containers.navBar.links.betaDocs,
// Global UI controls
languageDropdownName: englishLocale.components.common.languageDropdown.label,
themeToggleName: englishLocale.components.header.buttons.theme,
Expand Down Expand Up @@ -55,8 +58,14 @@ const verifyTranslation = async (page: Page, locale: Locale | string) => {

// Verify each navigation link text matches an expected translation
for (const link of links) {
const linkText = await link.textContent();
expect(expectedTexts).toContain(linkText!.trim());
const linkText = (await link.textContent())!.trim();
// Skip the Beta Docs link: it renders untranslated (English) across
// locales and has no translation entry in most locale files, so it
// won't appear in `expectedTexts` for non-English locales (e.g. es).
if (linkText === locators.betaDocsName) {
continue;
}
expect(expectedTexts).toContain(linkText);
}
};

Expand Down
2 changes: 2 additions & 0 deletions apps/site/types/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export type NavigationKeys =
| 'about'
| 'download'
| 'docs'
| 'betaDocs'
| 'getInvolved'
| 'certification'
| 'learn'
Expand All @@ -26,6 +27,7 @@ export type NavigationEntry = {
link?: string;
items?: Record<string, NavigationEntry>;
target?: HTMLAttributeAnchorTarget | undefined;
accent?: boolean;
};

export type SiteNavigation = {
Expand Down
1 change: 1 addition & 0 deletions packages/i18n/src/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"about": "About",
"download": "Download",
"docs": "Docs",
"betaDocs": "Beta Docs",
Comment thread
bmuenzenmeyer marked this conversation as resolved.
"guides": "Guides",
"learn": "Learn",
"security": "Security",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,30 @@
}
}

&.accent {
@apply bg-brand-100
ring-brand-600/20
dark:bg-brand-600/15
dark:ring-brand-400/20
ring-1
ring-inset;

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should add small transition because now on hover it's pass from something transparent to solid instantly


.label {
@apply text-brand-700
dark:text-brand-400;
}

.icon {
@apply text-brand-600
dark:text-brand-400;
}

&:hover {
@apply bg-brand-200
dark:bg-brand-600/25;
}
}

&.footer {
.label {
@apply text-neutral-800
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ type NavItemProps = {
type?: NavItemType;
className?: string;
target?: HTMLAttributeAnchorTarget | undefined;
accent?: boolean;

pathname: string;
as: LinkLike;
Expand All @@ -26,12 +27,18 @@ const NavItem: FC<PropsWithChildren<NavItemProps>> = ({
children,
className,
target,
accent,
...props
}) => (
<BaseActiveLink
target={target}
href={href}
className={classNames(styles.navItem, styles[type], className)}
className={classNames(
Comment thread
bmuenzenmeyer marked this conversation as resolved.
styles.navItem,
styles[type],
{ [styles.accent]: accent },
className
)}
activeClassName={styles.active}
allowSubPath={href.startsWith('/')}
{...props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ export const Default: Story = {
text: 'Docs',
link: '/docs',
},
{
text: 'Beta Docs',
link: 'https://beta.docs.nodejs.org/',
target: '_blank',
accent: true,
},
{
text: 'Download',
link: '/download',
Expand Down
4 changes: 3 additions & 1 deletion packages/ui-components/src/Containers/NavBar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ type NavbarProps = {
text: FormattedMessage;
link: string;
target?: HTMLAttributeAnchorTarget | undefined;
accent?: boolean;
}>;
Logo: ElementType;
as: LinkLike;
Expand Down Expand Up @@ -76,13 +77,14 @@ const NavBar: FC<PropsWithChildren<NavbarProps>> = ({
<div className={classNames(styles.main, `hidden peer-checked:flex`)}>
{navItems && navItems.length > 0 && (
<div className={styles.navItems}>
{navItems.map(({ text, link, target }) => (
{navItems.map(({ text, link, target, accent }) => (
<NavItem
pathname={pathname}
as={Component}
key={link}
href={link}
target={target}
accent={accent}
>
{text}
</NavItem>
Expand Down
Loading