feat(nx-dev): new main navigation menu (#22829)

It adds a new main navigation menu on the website and in the documentation, offering more choices and simpler access to different parts of the content for the visitor.

Co-authored-by: Benjamin Cabanes <3447705+bcabanes@users.noreply.github.com>
This commit is contained in:
Nicholas Cunningham 2024-04-18 09:24:34 -06:00 committed by GitHub
parent 25f598ffbe
commit 4d6cd36f5c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
21 changed files with 1206 additions and 441 deletions

View File

@ -1,4 +1,5 @@
{ {
"singleQuote": true, "singleQuote": true,
"endOfLine": "lf" "endOfLine": "lf",
"plugins": ["prettier-plugin-tailwindcss"]
} }

View File

@ -28,7 +28,7 @@ export function SourcemapInfoToolTip({
<> <>
<p className="flex grow items-center gap-2"> <p className="flex grow items-center gap-2">
<span className="font-bold">{isTarget ? 'Created' : 'Set'} by:</span> <span className="font-bold">{isTarget ? 'Created' : 'Set'} by:</span>
<span className="inline-flex grow justify-between items-center"> <span className="inline-flex grow items-center justify-between">
{docsUrlSlug ? ( {docsUrlSlug ? (
<ExternalLink <ExternalLink
text={plugin} text={plugin}
@ -46,10 +46,10 @@ export function SourcemapInfoToolTip({
); );
return ( return (
<div className="text-sm text-slate-700 dark:text-slate-400 max-w-md sm:max-w-full"> <div className="max-w-md text-sm text-slate-700 dark:text-slate-400 sm:max-w-full">
<div <div
className={twMerge( className={twMerge(
`flex flex-col font-mono py-2`, `flex flex-col py-2 font-mono`,
showLink ? 'border-b border-slate-200 dark:border-slate-700/60' : '' showLink ? 'border-b border-slate-200 dark:border-slate-700/60' : ''
)} )}
> >

View File

@ -86,8 +86,8 @@ export function AlgoliaSearch({
className="flex w-full items-center rounded-md bg-white py-1.5 px-2 text-sm leading-4 ring-1 ring-slate-300 transition dark:bg-slate-700 dark:ring-slate-900" className="flex w-full items-center rounded-md bg-white py-1.5 px-2 text-sm leading-4 ring-1 ring-slate-300 transition dark:bg-slate-700 dark:ring-slate-900"
> >
<MagnifyingGlassIcon className="h-4 w-4 flex-none" /> <MagnifyingGlassIcon className="h-4 w-4 flex-none" />
<span className="mx-3 text-xs text-slate-300 dark:text-slate-400 md:text-sm inline-flex"> <span className="mx-3 inline-flex text-xs text-slate-300 dark:text-slate-400 md:text-sm">
Search <span className="ml-1 hidden lg:inline">the docs ...</span> Search
</span> </span>
<span <span
style={{ opacity: browserDetected ? '1' : '0' }} style={{ opacity: browserDetected ? '1' : '0' }}

View File

@ -33,13 +33,6 @@
"command": "pnpm next-sitemap --config ./nx-dev/nx-dev/next-sitemap.config.js" "command": "pnpm next-sitemap --config ./nx-dev/nx-dev/next-sitemap.config.js"
} }
}, },
"sync-documentation": {
"executor": "nx:run-commands",
"outputs": ["{projectRoot}/public/documentation"],
"options": {
"command": "ts-node -P ./scripts/tsconfig.scripts.json ./scripts/documentation/nx-dev-docs-latest-sync.ts"
}
},
"generate-og-images": { "generate-og-images": {
"executor": "nx:run-commands", "executor": "nx:run-commands",
"outputs": ["{projectRoot}/public/images/open-graph"], "outputs": ["{projectRoot}/public/images/open-graph"],
@ -133,12 +126,6 @@
"parallel": false "parallel": false
} }
}, },
"export": {
"executor": "@nx/next:export",
"options": {
"buildTarget": "nx-dev:build:production"
}
},
"lint": {}, "lint": {},
"test": {} "test": {}
}, },

View File

@ -1,10 +1,10 @@
export * from './lib/announcement-banner'; export * from './lib/announcement-banner';
export * from './lib/documentation-header'; export * from './lib/headers/documentation-header';
export * from './lib/breadcrumbs'; export * from './lib/breadcrumbs';
export * from './lib/button'; export * from './lib/button';
export * from './lib/champion-card'; export * from './lib/champion-card';
export * from './lib/champion-perks'; export * from './lib/champion-perks';
export * from './lib/header'; export * from './lib/headers/header';
export * from './lib/flip-card'; export * from './lib/flip-card';
export * from './lib/nx-cloud-icon'; export * from './lib/nx-cloud-icon';
export * from './lib/footer'; export * from './lib/footer';
@ -15,3 +15,14 @@ export * from './lib/testimonial-card';
export * from './lib/typography'; export * from './lib/typography';
export * from './lib/github-star-widget'; export * from './lib/github-star-widget';
export * from './lib/youtube.component'; export * from './lib/youtube.component';
export { resourceMenuItems } from './lib/headers/menu-items';
export { solutionsMenuItems } from './lib/headers/menu-items';
export { eventItems } from './lib/headers/menu-items';
export { learnItems } from './lib/headers/menu-items';
export { useCaseItems } from './lib/headers/menu-items';
export { plans } from './lib/headers/menu-items';
export { featuresItems } from './lib/headers/menu-items';
export { DefaultMenuItem } from './lib/headers/default-menu-item';
export { MobileMenuItem } from './lib/headers/mobile-menu-item';
export { SectionsMenu } from './lib/headers/sections-menu';
export { TwoColumnsMenu } from './lib/headers/two-columns-menu';

View File

@ -1,4 +1,5 @@
import { HeartIcon } from '@heroicons/react/24/solid'; import { HeartIcon } from '@heroicons/react/24/solid';
import { ThemeSwitcher } from '@nx/nx-dev/ui-theme';
import Link from 'next/link'; import Link from 'next/link';
export function Footer(): JSX.Element { export function Footer(): JSX.Element {
@ -179,6 +180,9 @@ export function Footer(): JSX.Element {
</Link> </Link>
))} ))}
</div> </div>
<div className="flex items-center text-sm">
Preferences <ThemeSwitcher />
</div>
</div> </div>
<div className="mt-12 grid grid-cols-2 gap-8 xl:col-span-2 xl:mt-0"> <div className="mt-12 grid grid-cols-2 gap-8 xl:col-span-2 xl:mt-0">
<div className="md:grid md:grid-cols-2 md:gap-8"> <div className="md:grid md:grid-cols-2 md:gap-8">

View File

@ -0,0 +1,14 @@
import { FC, SVGProps } from 'react';
export const GitHubIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
{...props}
>
<title>GitHub</title>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12" />
</svg>
);

View File

@ -1,326 +0,0 @@
import { Popover, Transition } from '@headlessui/react';
import { Bars4Icon, ChevronDownIcon } from '@heroicons/react/24/outline';
import { AlgoliaSearch } from '@nx/nx-dev/feature-search';
import { ThemeSwitcher } from '@nx/nx-dev/ui-theme';
import cx from 'classnames';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { Fragment } from 'react';
export function Header(): JSX.Element {
const router = useRouter();
const flyoutMenu = [
{
name: 'Getting started',
description: 'Jump right in and start building!',
href: '/getting-started/intro',
},
{
name: 'Nx on CI',
description: 'Learn how to efficiently use Nx on CI',
href: '/ci/intro/ci-with-nx',
},
{
name: 'Features',
description:
'Learn the features of Nx with in depth guides and explainers.',
href: '/features',
},
{
name: 'Nx Replay',
description:
'Built-in local and remote caching to speed up your tasks and save you time and money.',
href: '/features/cache-task-results',
},
{
name: 'Recipes',
description: 'Follow instructions to do common specific tasks.',
href: '/recipes',
},
{
name: 'Nx Agents',
description:
'Executes tasks remotely on different agents in parallel. Enable remote cache in one command.',
href: '/ci/features/distribute-task-execution',
},
{
name: 'Nx Console',
description:
'The official VSCode & JetBrains plugin bringing Nx to your editor.',
href: '/getting-started/editor-setup#vscode',
},
{
name: 'Set Up CI',
description: 'Configure Nx for your CI provider',
href: '/ci/recipes/set-up',
},
];
const flyoutMobileMenu = [
{
name: 'Getting started',
description: 'Jump right in and start building!',
href: '/getting-started/intro',
},
{
name: 'Blog',
description: 'Latest news from the Nx & Nx Cloud core team',
href: '/blog',
},
{
name: 'Community',
description: 'Check how to reach out and be part of the Nx community.',
href: '/community',
},
{
name: 'Launch Nx',
description: 'A week of exciting announcements about Nx and Nx Cloud!',
href: '/launch-nx',
},
{
name: 'Contact us',
description: 'Give us a call!',
href: '/contact',
},
];
return (
<div className="relative flex print:hidden">
{/*DESKTOP*/}
<div className="mx-auto hidden w-full max-w-7xl items-center justify-between space-x-10 p-4 px-8 lg:flex">
{/*LOGO*/}
<div className="flex items-center">
<Link
href="/"
className="flex items-center text-slate-900 dark:text-white"
>
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
className="h-8 w-8"
fill="currentColor"
>
<title>Nx</title>
<path d="m12 14.1-3.1 5-5.2-8.5v8.9H0v-15h3.7l5.2 8.9v-4l3 4.7zm.6-5.7V4.5H8.9v3.9h3.7zm5.6 4.1a2 2 0 0 0-2 1.3 2 2 0 0 1 2.4-.7c.4.2 1 .4 1.3.3a2.1 2.1 0 0 0-1.7-.9zm3.4 1c-.4 0-.8-.2-1.1-.6l-.2-.3a2.1 2.1 0 0 0-.5-.6 2 2 0 0 0-1.2-.3 2.5 2.5 0 0 0-2.3 1.5 2.3 2.3 0 0 1 4 .4.8.8 0 0 0 .9.3c.5 0 .4.4 1.2.5v-.1c0-.4-.3-.5-.8-.7zm2 1.3a.7.7 0 0 0 .4-.6c0-3-2.4-5.5-5.4-5.5a5.4 5.4 0 0 0-4.5 2.4l-1.5-2.4H8.9l3.5 5.4L9 19.5h3.6L14 17l1.6 2.4h3.5l-3.1-5a.7.7 0 0 1 0-.3 2.7 2.7 0 0 1 2.6-2.7c1.5 0 1.7.9 2 1.3.7.8 2 .5 2 1.5a.7.7 0 0 0 1 .6zm.4.2c-.2.3-.6.3-.8.6-.1.3.1.4.1.4s.4.2.6-.3V15z" />
</svg>
</Link>
</div>
{/*PRIMARY NAVIGATION*/}
<div className="flex-shrink-0 text-sm">
<nav
role="menu"
className="items-justified flex justify-center space-x-2 py-0.5"
>
<h2 className="sr-only">Main navigation</h2>
<Popover className="relative">
{({ open }) => (
<>
<Popover.Button
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'text group inline-flex items-center px-3 py-2 font-medium leading-tight dark:text-slate-200'
)}
>
<span className="transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500">
Documentation
</span>
<ChevronDownIcon
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'ml-2 h-5 w-5 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
aria-hidden="true"
/>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute left-1/2 z-10 mt-3 w-screen max-w-md -translate-x-1/2 transform xl:max-w-3xl">
<div className="overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black/5 dark:bg-slate-900 dark:ring-white/5">
<div className="relative grid gap-6 p-6 xl:grid-cols-2">
{flyoutMenu.map((item) => (
<Link
key={item.name}
href={item.href}
className="-m-3 flex items-start rounded-lg p-3 transition duration-150 ease-in-out hover:bg-slate-50 dark:hover:bg-slate-800/60"
>
<div className="ml-4">
<p className="text-base font-medium text-slate-900 dark:text-slate-200">
{item.name}
</p>
<p className="mt-1 text-sm text-slate-500 dark:text-slate-400">
{item.description}
</p>
</div>
</Link>
))}
</div>
</div>
</Popover.Panel>
</Transition>
</>
)}
</Popover>
<Link
href="/blog"
title="Blog"
className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
>
Blog
</Link>
<Link
href="/community"
title="Nx Community: Join us!"
className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
>
Community
</Link>
<Link
href="/launch-nx"
title="Launch Nx"
className="relative hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
>
{/*<span className="absolute top-0 right-0 -mt-1 -mr-1 flex h-3 w-3">*/}
{/* <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-blue-500 opacity-75 dark:bg-sky-500" />*/}
{/* <span className="relative inline-flex h-3 w-3 rounded-full bg-blue-500 dark:bg-sky-500" />*/}
{/*</span>*/}Launch Nx
</Link>
<Link
href="/contact"
title="Contact us"
className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
>
Contact us
</Link>
</nav>
</div>
<div className="flex-shrink-0 text-sm">
<nav className="items-justified flex justify-center space-x-1">
<AlgoliaSearch tiny={true} />
<ThemeSwitcher />
<a
title="Nx is open source, check the code on GitHub"
href="https://github.com/nrwl/nx"
target="_blank"
rel="noreferrer"
className="px-3 py-2 opacity-60 hover:opacity-90"
>
<span className="sr-only">Nx on GitHub</span>
<div className="item-center flex">
<svg
className="h-5 w-5"
viewBox="0 0 16 16"
fill="currentColor"
>
<path d="M8 0a8 8 0 0 0-2.53 15.59c.4.07.55-.17.55-.38l-.01-1.49c-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82a7.42 7.42 0 0 1 4 0c1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48l-.01 2.2c0 .21.15.46.55.38A8.01 8.01 0 0 0 16 8a8 8 0 0 0-8-8z" />
</svg>
</div>
</a>
</nav>
</div>
</div>
{/*MOBILE*/}
<div className="relative mx-auto flex w-full items-center justify-between p-4 lg:hidden">
<div className="flex flex-shrink-0">
{/*LOGO*/}
<Link
href="/"
className="flex items-center text-slate-900 dark:text-white"
>
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
className="h-8 w-8"
fill="currentColor"
>
<title>Nx</title>
<path d="M11.987 14.138l-3.132 4.923-5.193-8.427-.012 8.822H0V4.544h3.691l5.247 8.833.005-3.998 3.044 4.759zm.601-5.761c.024-.048 0-3.784.008-3.833h-3.65c.002.059-.005 3.776-.003 3.833h3.645zm5.634 4.134a2.061 2.061 0 0 0-1.969 1.336 1.963 1.963 0 0 1 2.343-.739c.396.161.917.422 1.33.283a2.1 2.1 0 0 0-1.704-.88zm3.39 1.061c-.375-.13-.8-.277-1.109-.681-.06-.08-.116-.17-.176-.265a2.143 2.143 0 0 0-.533-.642c-.294-.216-.68-.322-1.18-.322a2.482 2.482 0 0 0-2.294 1.536 2.325 2.325 0 0 1 4.002.388.75.75 0 0 0 .836.334c.493-.105.46.36 1.203.518v-.133c-.003-.446-.246-.55-.75-.733zm2.024 1.266a.723.723 0 0 0 .347-.638c-.01-2.957-2.41-5.487-5.37-5.487a5.364 5.364 0 0 0-4.487 2.418c-.01-.026-1.522-2.39-1.538-2.418H8.943l3.463 5.423-3.379 5.32h3.54l1.54-2.366 1.568 2.366h3.541l-3.21-5.052a.7.7 0 0 1-.084-.32 2.69 2.69 0 0 1 2.69-2.691h.001c1.488 0 1.736.89 2.057 1.308.634.826 1.9.464 1.9 1.541a.707.707 0 0 0 1.066.596zm.35.133c-.173.372-.56.338-.755.639-.176.271.114.412.114.412s.337.156.538-.311c.104-.231.14-.488.103-.74z" />
</svg>
</Link>
{/*MENU*/}
<div className="ml-4 flex flex-shrink-0">
<Popover className="">
{({ open }) => (
<>
<Popover.Button
type="button"
className="inline-flex flex-shrink-0 items-center rounded-md border border-slate-200 bg-slate-50/60 px-3 py-2 text-sm text-sm font-semibold font-medium capitalize leading-4 shadow-sm transition hover:bg-slate-50 focus:outline-none dark:border-slate-700 dark:bg-slate-800/60 dark:hover:bg-slate-800"
>
<Bars4Icon
className="-ml-0.5 mr-2 h-4 w-4"
aria-hidden="true"
/>
{router.pathname === '/'
? 'Home'
: router.pathname.replace('/', '')}
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute left-0 z-10 mt-3 w-screen px-2">
<div className="overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-black/5 dark:bg-slate-900 dark:ring-white/5">
<nav className="relative grid gap-8 p-8 md:grid-cols-2">
{flyoutMobileMenu.map((item) => (
<Link
key={item.name}
href={item.href}
className="-m-3 flex items-start rounded-lg p-3 transition duration-150 ease-in-out hover:bg-slate-50 dark:hover:bg-slate-800/60"
>
<div className="ml-4">
<p className="text-base font-medium text-slate-900 dark:text-slate-200">
{item.name}
</p>
<p className="mt-1 text-sm text-slate-500 dark:text-slate-400">
{item.description}
</p>
</div>
</Link>
))}
</nav>
</div>
</Popover.Panel>
</Transition>
</>
)}
</Popover>
</div>
</div>
<div className="items-justified flex flex-shrink-0 justify-center space-x-1 text-sm">
<ThemeSwitcher />
<a
title="Nx is open source, check the code on GitHub"
href="https://github.com/nrwl/nx"
target="_blank"
rel="noreferrer"
className="px-3 py-2 opacity-60 hover:opacity-90"
>
<span className="sr-only">Nx on GitHub</span>
<div className="item-center flex">
<svg className="h-5 w-5" viewBox="0 0 16 16" fill="currentColor">
<path
fillRule="evenodd"
d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"
/>
</svg>
</div>
</a>
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,56 @@
import { ElementType } from 'react';
import type { MenuItem } from './menu-items';
import cx from 'classnames';
import Link from 'next/link';
export function DefaultMenuItem({
as = 'div',
className = '',
item,
...rest
}: {
as?: ElementType;
className?: string;
item: MenuItem;
}): JSX.Element {
const hasExternalLink =
item.href.startsWith('http') || item.href.startsWith('//');
const Tag = as;
return (
<Tag
className={cx(
'relative flex flex-1 gap-4 rounded-lg py-4 px-2 transition duration-150 ease-in-out',
item.isHighlight
? 'bg-slate-50 hover:bg-slate-100 dark:bg-slate-800/80 dark:hover:bg-slate-700/60'
: 'hover:bg-slate-50 dark:hover:bg-slate-800/60',
className
)}
{...rest}
>
{item.icon ? (
<item.icon aria-hidden="true" className="h-5 w-5 shrink-0" />
) : null}
<div className="grow">
<Link
href={item.href}
title={item.name}
target={hasExternalLink ? '_blank' : '_self'}
className="text-sm font-medium text-slate-900 dark:text-slate-200"
>
{item.name}
{item.isNew ? (
<span className="float-right inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10 dark:bg-blue-400/10 dark:text-sky-400 dark:ring-sky-400/30">
new
</span>
) : null}
<span className="absolute inset-0" />
</Link>
{item.description ? (
<p className="mt-0.5 text-xs text-slate-400 dark:text-slate-500">
{item.description}
</p>
) : null}
</div>
</Tag>
);
}

View File

@ -1,13 +1,25 @@
import { type JSX } from 'react'; import { Fragment, type JSX } from 'react';
import { Bars3Icon, XMarkIcon } from '@heroicons/react/24/outline'; import {
ArrowUpRightIcon,
Bars3Icon,
ChevronDownIcon,
XMarkIcon,
} from '@heroicons/react/24/outline';
import { AlgoliaSearch } from '@nx/nx-dev/feature-search'; import { AlgoliaSearch } from '@nx/nx-dev/feature-search';
import { ThemeSwitcher } from '@nx/nx-dev/ui-theme';
import cx from 'classnames'; import cx from 'classnames';
import Link from 'next/link'; import Link from 'next/link';
import { useRouter } from 'next/router'; import { useRouter } from 'next/router';
import { ButtonLink } from './button'; import { ButtonLink } from '../button';
import { NxCloudIcon } from './nx-cloud-icon'; import { NxIcon } from '../nx-icon';
import { AnnouncementBanner } from './announcement-banner'; import { Popover, Transition } from '@headlessui/react';
import { TwoColumnsMenu } from './two-columns-menu';
import {
featuresItems,
resourceMenuItems,
solutionsMenuItems,
} from './menu-items';
import { SectionsMenu } from './sections-menu';
import { NxCloudIcon } from '../nx-cloud-icon';
function Menu({ tabs }: { tabs: any[] }): JSX.Element { function Menu({ tabs }: { tabs: any[] }): JSX.Element {
return ( return (
@ -197,20 +209,12 @@ export function DocumentationHeader({
href="/" href="/"
className="flex flex-grow items-center px-4 text-slate-900 dark:text-white lg:px-0" className="flex flex-grow items-center px-4 text-slate-900 dark:text-white lg:px-0"
> >
<svg <span className="sr-only">Nx</span>
role="img" <NxIcon aria-hidden="true" className="h-8 w-8" />
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
className="h-8 w-8"
fill="currentColor"
>
<title>Nx</title>
<path d="M11.987 14.138l-3.132 4.923-5.193-8.427-.012 8.822H0V4.544h3.691l5.247 8.833.005-3.998 3.044 4.759zm.601-5.761c.024-.048 0-3.784.008-3.833h-3.65c.002.059-.005 3.776-.003 3.833h3.645zm5.634 4.134a2.061 2.061 0 0 0-1.969 1.336 1.963 1.963 0 0 1 2.343-.739c.396.161.917.422 1.33.283a2.1 2.1 0 0 0-1.704-.88zm3.39 1.061c-.375-.13-.8-.277-1.109-.681-.06-.08-.116-.17-.176-.265a2.143 2.143 0 0 0-.533-.642c-.294-.216-.68-.322-1.18-.322a2.482 2.482 0 0 0-2.294 1.536 2.325 2.325 0 0 1 4.002.388.75.75 0 0 0 .836.334c.493-.105.46.36 1.203.518v-.133c-.003-.446-.246-.55-.75-.733zm2.024 1.266a.723.723 0 0 0 .347-.638c-.01-2.957-2.41-5.487-5.37-5.487a5.364 5.364 0 0 0-4.487 2.418c-.01-.026-1.522-2.39-1.538-2.418H8.943l3.463 5.423-3.379 5.32h3.54l1.54-2.366 1.568 2.366h3.541l-3.21-5.052a.7.7 0 0 1-.084-.32 2.69 2.69 0 0 1 2.69-2.691h.001c1.488 0 1.736.89 2.057 1.308.634.826 1.9.464 1.9 1.541a.707.707 0 0 0 1.066.596zm.35.133c-.173.372-.56.338-.755.639-.176.271.114.412.114.412s.337.156.538-.311c.104-.231.14-.488.103-.74z" />
</svg>
</Link> </Link>
<Link <Link
href="/getting-started/intro" href="/getting-started/intro"
className="hidden lg:flex ml-2 items-center px-4 text-slate-900 dark:text-white lg:px-0" className="ml-2 hidden items-center px-4 text-slate-900 dark:text-white lg:flex lg:px-0"
> >
<span className="text-xl font-bold uppercase tracking-wide"> <span className="text-xl font-bold uppercase tracking-wide">
Docs Docs
@ -218,66 +222,193 @@ export function DocumentationHeader({
</Link> </Link>
</div> </div>
{/*SEARCH*/} {/*SEARCH*/}
<div className="hidden w-full max-w-sm lg:inline"> <div className="hidden w-full max-w-[14rem] lg:inline">
<AlgoliaSearch /> <AlgoliaSearch />
</div> </div>
{/*NAVIGATION*/} {/*NAVIGATION*/}
<div className="hidden flex-shrink-0 lg:flex"> <div className="hidden flex-shrink-0 xl:flex">
<nav <nav
role="menu" role="menu"
className="items-justified hidden justify-center space-x-2 text-sm lg:flex" className="items-justified hidden justify-center space-x-2 text-sm lg:flex"
> >
<h2 className="sr-only">Main navigation</h2> <h2 className="sr-only">Main navigation</h2>
{/* <Link {/*FEATURES*/}
<Popover className="relative">
{({ open }) => (
<>
<Popover.Button
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'group inline-flex items-center gap-2 px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
)}
>
<span
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
>
Features
</span>
<ChevronDownIcon
aria-hidden="true"
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: '',
'h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
/>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute z-30 mt-3 w-max max-w-3xl xl:max-w-3xl">
<TwoColumnsMenu items={featuresItems} />
</Popover.Panel>
</Transition>
</>
)}
</Popover>
{/*SOLUTIONS*/}
<Popover className="relative">
{({ open }) => (
<>
<Popover.Button
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'group inline-flex items-center px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
)}
>
<span
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
>
Solutions
</span>
<ChevronDownIcon
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: '',
'ml-2 h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
aria-hidden="true"
/>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute z-30 mt-3 w-max max-w-2xl">
<SectionsMenu sections={solutionsMenuItems} />
</Popover.Panel>
</Transition>
</>
)}
</Popover>
<Link
href="/getting-started/intro"
title="Documentation"
className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
>
Documentation
</Link>
<Link
href="/blog" href="/blog"
title="Blog" title="Blog"
className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex" className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
> >
Blog Blog
</Link> */}
<Link
href="/community"
title="Nx Community: Join us!"
className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
>
Community
</Link> </Link>
<Link <a
href="/launch-nx" href="https://nx.app/pricing"
title="Launch Nx" title="Nx Cloud"
className="relative hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex" target="_blank"
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
> >
{/*<span className="absolute top-0 right-0 -mt-1 -mr-1 flex h-3 w-3">*/} CI Pricing
{/* <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-blue-500 opacity-75 dark:bg-sky-500" />*/} <ArrowUpRightIcon className="h-2 w-2 align-super" />
{/* <span className="relative inline-flex h-3 w-3 rounded-full bg-blue-500 dark:bg-sky-500" />*/} </a>
{/*</span>*/}Launch Nx {/*RESOURCES*/}
</Link> <Popover className="relative">
<Link {({ open }) => (
href="/contact" <>
title="Contact us" <Popover.Button
className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex" className={cx(
> open ? 'text-blue-500 dark:text-sky-500' : '',
Contact us 'group inline-flex items-center px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
</Link> )}
>
<span className="transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500">
Resources
</span>
<ChevronDownIcon
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: '',
'ml-2 h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
aria-hidden="true"
/>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute left-60 z-30 mt-3 w-max max-w-2xl -translate-x-1/2 transform lg:left-20">
<SectionsMenu sections={resourceMenuItems} />
</Popover.Panel>
</Transition>
</>
)}
</Popover>
</nav> </nav>
</div> </div>
<div className="hidden flex-grow lg:flex">{/* SPACER */}</div> <div className="hidden flex-grow lg:flex">{/* SPACER */}</div>
<div className="hidden w-full xl:flex"> {/*<div className="hidden w-full xl:flex">*/}
<AnnouncementBanner /> {/* <AnnouncementBanner />*/}
</div> {/*</div>*/}
<div className="hidden flex-shrink-0 lg:flex"> <div className="hidden flex-shrink-0 lg:flex">
<nav <nav
role="menu" role="menu"
className="items-justified hidden justify-center space-x-4 lg:flex" className="items-justified hidden justify-center space-x-4 lg:flex"
> >
<ThemeSwitcher /> <Link
className="hidden cursor-pointer px-3 py-2 text-sm font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
title="Contact Us"
href="/contact"
>
Contact
</Link>
<ButtonLink <ButtonLink
href="https://nx.app/?utm_source=nx.dev&utm_medium=header-menu" href="https://nx.app/?utm_source=nx.dev&utm_medium=header-menu"
title="Go to app" title="Go to app"
variant="secondary" variant="secondary"
size="small" size="small"
> >
<NxCloudIcon className="w-4 h-4" aria-hidden="true" /> <NxCloudIcon className="h-4 w-4" aria-hidden="true" />
<span>Go to app</span> <span>Go to app</span>
</ButtonLink> </ButtonLink>
</nav> </nav>

View File

@ -0,0 +1,520 @@
import { Dialog, Disclosure, Popover, Transition } from '@headlessui/react';
import {
ArrowUpRightIcon,
Bars4Icon,
ChevronDownIcon,
XMarkIcon,
} from '@heroicons/react/24/outline';
import cx from 'classnames';
import Link from 'next/link';
import { useRouter } from 'next/router';
import { Fragment, useEffect, useState } from 'react';
import { ButtonLink } from '../button';
import {
eventItems,
featuresItems,
learnItems,
plans,
resourceMenuItems,
solutionsMenuItems,
} from './menu-items';
import { NxIcon } from '../nx-icon';
import { GitHubIcon } from '../github-icon';
import { MobileMenuItem } from './mobile-menu-item';
import { SectionsMenu } from './sections-menu';
import { TwoColumnsMenu } from './two-columns-menu';
import { AlgoliaSearch } from '@nx/nx-dev/feature-search';
import { NxCloudIcon } from '../nx-cloud-icon';
export function Header(): JSX.Element {
let [isOpen, setIsOpen] = useState(false);
const router = useRouter();
// We need to close the popover if the route changes or the window is resized to prevent the popover from being stuck open.
const checkSizeAndClosePopover = () => {
const breakpoint = 1024; // This is the standard Tailwind lg breakpoint value
if (window.innerWidth < breakpoint) {
setIsOpen(false);
}
};
useEffect(() => {
window.addEventListener('resize', checkSizeAndClosePopover);
return () => {
window.removeEventListener('resize', checkSizeAndClosePopover);
};
}, []);
return (
<div className="relative flex print:hidden">
{/*DESKTOP*/}
<div className="mx-auto hidden w-full max-w-7xl items-center justify-between space-x-10 p-4 px-8 lg:flex">
{/*PRIMARY NAVIGATION*/}
<div className="flex flex-shrink-0 text-sm">
{/*LOGO*/}
<Link
href="/"
className="mr-4 flex items-center text-slate-900 dark:text-white"
>
<span className="sr-only">Nx</span>
<NxIcon aria-hidden="true" className="h-8 w-8" />
</Link>
<nav
role="menu"
className="items-justified flex items-center justify-center space-x-2 py-0.5"
>
<h2 className="sr-only">Main navigation</h2>
{/*FEATURES*/}
<Popover className="relative">
{({ open }) => (
<>
<Popover.Button
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'group inline-flex items-center gap-2 px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
)}
>
<span
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
>
Features
</span>
<ChevronDownIcon
aria-hidden="true"
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: '',
'h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
/>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute z-10 mt-3 w-max max-w-3xl xl:max-w-3xl">
<TwoColumnsMenu items={featuresItems} />
</Popover.Panel>
</Transition>
</>
)}
</Popover>
{/*SOLUTIONS*/}
<Popover className="relative">
{({ open }) => (
<>
<Popover.Button
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'group inline-flex items-center px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
)}
>
<span
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
>
Solutions
</span>
<ChevronDownIcon
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: '',
'ml-2 h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
aria-hidden="true"
/>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute z-10 mt-3 w-max max-w-2xl">
<SectionsMenu sections={solutionsMenuItems} />
</Popover.Panel>
</Transition>
</>
)}
</Popover>
<Link
href="/getting-started/intro"
title="Documentation"
className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
>
Documentation
</Link>
<Link
href="/blog"
title="Blog"
className="hidden px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
>
Blog
</Link>
<a
href="https://nx.app/pricing"
title="Nx Cloud"
target="_blank"
className="hidden gap-2 px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
>
CI Pricing
<ArrowUpRightIcon className="h-2 w-2 align-super" />
</a>
{/*RESOURCES*/}
<Popover className="relative">
{({ open }) => (
<>
<Popover.Button
className={cx(
open ? 'text-blue-500 dark:text-sky-500' : '',
'group inline-flex items-center px-3 py-2 font-medium leading-tight outline-0 dark:text-slate-200'
)}
>
<span className="transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500">
Resources
</span>
<ChevronDownIcon
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: '',
'ml-2 h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
aria-hidden="true"
/>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute left-60 z-10 mt-3 w-max max-w-2xl -translate-x-1/2 transform lg:left-20">
<SectionsMenu sections={resourceMenuItems} />
</Popover.Panel>
</Transition>
</>
)}
</Popover>
<div className="opacity-50 hover:opacity-100">
<AlgoliaSearch tiny={true} />
</div>
</nav>
</div>
{/*SECONDARY NAVIGATION*/}
<div className="flex-shrink-0 text-sm">
<nav className="flex items-center justify-center space-x-1">
<Link
className="hidden cursor-pointer px-3 py-2 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500 md:inline-flex"
title="Contact Us"
href="/contact"
>
Contact
</Link>
<ButtonLink
href="https://cloud.nx.app"
variant="secondary"
size="small"
target="_blank"
title="Log in to your Nx Cloud Account"
>
<NxCloudIcon className="h-4 w-4" aria-hidden="true" />
<span>Go to App</span>
</ButtonLink>
<a
title="Nx is open source, check the code on GitHub"
href="https://github.com/nrwl/nx"
target="_blank"
rel="noreferrer"
className="inline-flex items-center px-3 py-2 opacity-60 hover:opacity-90"
>
<span className="sr-only">Nx on GitHub</span>
<GitHubIcon aria-hidden="true" className="h-5 w-5" />
</a>
</nav>
</div>
</div>
{/*MOBILE*/}
<div className="relative mx-auto flex w-full items-center justify-between p-4 lg:hidden">
<div className="flex w-full items-center justify-between">
{/*LOGO*/}
<Link
href="/"
className="flex items-center text-slate-900 dark:text-white"
>
<span className="sr-only">Nx</span>
<NxIcon aria-hidden="true" className="h-8 w-8" />
</Link>
<div className="flex items-center gap-6">
<a
title="Nx is open source, check the code on GitHub"
href="https://github.com/nrwl/nx"
target="_blank"
rel="noreferrer"
className="inline-flex items-center px-3 py-2 opacity-60 hover:opacity-90"
>
<span className="sr-only">Nx on GitHub</span>
<GitHubIcon aria-hidden="true" className="h-5 w-5" />
</a>
{/*MENU*/}
<button onClick={() => setIsOpen(!isOpen)} className="shrink-0 p-2">
<Bars4Icon
aria-hidden="true"
title="Open navigation menu"
strokeWidth="2"
className="h-6 w-6"
/>
<span className="sr-only">Open navigation panel</span>
</button>
</div>
</div>
</div>
<Transition.Root show={isOpen} as={Fragment}>
<Dialog
as="div"
className="relative z-10"
onClose={() => setIsOpen(!isOpen)}
>
<div className="fixed inset-0" />
<div className="fixed inset-0 overflow-hidden">
<div className="absolute inset-0 overflow-hidden">
<div className="pointer-events-none fixed inset-y-0 right-0 flex max-w-full">
<Transition.Child
as={Fragment}
enter="transform transition ease-in-out duration-250 sm:duration-500"
enterFrom="translate-x-full"
enterTo="translate-x-0"
leave="transform transition ease-in-out duration-250 sm:duration-500"
leaveFrom="translate-x-0"
leaveTo="translate-x-full"
>
<Dialog.Panel className="pointer-events-auto w-screen">
<div className="flex h-full flex-col overflow-y-scroll bg-white py-6 shadow-xl dark:bg-slate-900">
<div className="px-4 sm:px-6">
<div className="flex items-start justify-between">
<Dialog.Title>
<Link
href="/"
className="flex items-center text-slate-900 dark:text-white"
>
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
className="h-8 w-8"
fill="currentColor"
>
<title>Nx</title>
<path d="M11.987 14.138l-3.132 4.923-5.193-8.427-.012 8.822H0V4.544h3.691l5.247 8.833.005-3.998 3.044 4.759zm.601-5.761c.024-.048 0-3.784.008-3.833h-3.65c.002.059-.005 3.776-.003 3.833h3.645zm5.634 4.134a2.061 2.061 0 0 0-1.969 1.336 1.963 1.963 0 0 1 2.343-.739c.396.161.917.422 1.33.283a2.1 2.1 0 0 0-1.704-.88zm3.39 1.061c-.375-.13-.8-.277-1.109-.681-.06-.08-.116-.17-.176-.265a2.143 2.143 0 0 0-.533-.642c-.294-.216-.68-.322-1.18-.322a2.482 2.482 0 0 0-2.294 1.536 2.325 2.325 0 0 1 4.002.388.75.75 0 0 0 .836.334c.493-.105.46.36 1.203.518v-.133c-.003-.446-.246-.55-.75-.733zm2.024 1.266a.723.723 0 0 0 .347-.638c-.01-2.957-2.41-5.487-5.37-5.487a5.364 5.364 0 0 0-4.487 2.418c-.01-.026-1.522-2.39-1.538-2.418H8.943l3.463 5.423-3.379 5.32h3.54l1.54-2.366 1.568 2.366h3.541l-3.21-5.052a.7.7 0 0 1-.084-.32 2.69 2.69 0 0 1 2.69-2.691h.001c1.488 0 1.736.89 2.057 1.308.634.826 1.9.464 1.9 1.541a.707.707 0 0 0 1.066.596zm.35.133c-.173.372-.56.338-.755.639-.176.271.114.412.114.412s.337.156.538-.311c.104-.231.14-.488.103-.74z" />
</svg>
<span className="sr-only">Nx</span>
</Link>
</Dialog.Title>
<div className="ml-3 flex h-7 items-center">
<button
type="button"
className="dark:hovers:text-sky-500 relative rounded-md text-slate-600 hover:text-blue-500 focus:outline-none focus:ring-2 focus:ring-blue-500 focus:ring-offset-2 dark:text-slate-400 dark:focus:ring-sky-500"
onClick={() => setIsOpen(!isOpen)}
>
<span className="absolute -inset-2.5" />
<span className="sr-only">
Close navigation panel
</span>
<XMarkIcon
aria-hidden="true"
className="h-6 w-6"
/>
</button>
</div>
</div>
</div>
<div className="relative mt-6 flex-1 px-4 sm:px-6">
<ButtonLink
href="https://cloud.nx.app"
variant="primary"
size="small"
target="_blank"
title="Log in to your Nx Cloud Account"
className="w-full"
>
Go to App
</ButtonLink>
<div className="mt-4 divide-y divide-slate-200 border-b border-slate-200 dark:divide-slate-800 dark:border-slate-800">
{/*FEATURES*/}
<Disclosure as="div">
{({ open }) => (
<>
<Disclosure.Button
className={cx(
open
? 'text-blue-500 dark:text-sky-500'
: 'tex-slate-800 dark:text-slate-200',
'flex w-full items-center justify-between py-4 text-left text-base font-medium focus:outline-none'
)}
>
<span>Features</span>
<ChevronDownIcon
aria-hidden="true"
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: 'tex-slate-800 dark:text-slate-200',
'h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
/>
</Disclosure.Button>
<Disclosure.Panel
as="ul"
className="space-y-1 pb-2"
>
{featuresItems.map((item) => (
<MobileMenuItem
key={item.name}
item={item}
/>
))}
</Disclosure.Panel>
</>
)}
</Disclosure>
{/*SOLUTIONS*/}
<Disclosure as="div">
{({ open }) => (
<>
<Disclosure.Button
className={cx(
open
? 'text-blue-500 dark:text-sky-500'
: 'tex-slate-800 dark:text-slate-200',
'flex w-full items-center justify-between py-4 text-left text-base font-medium focus:outline-none'
)}
>
<span>Solutions</span>
<ChevronDownIcon
aria-hidden="true"
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: 'tex-slate-800 dark:text-slate-200',
'h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
/>
</Disclosure.Button>
<Disclosure.Panel as="ul" className="space-y-1">
{plans.map((item) => (
<MobileMenuItem
key={item.name}
item={item}
/>
))}
</Disclosure.Panel>
</>
)}
</Disclosure>
<Link
href="/getting-started/intro"
title="Documentation"
className="block py-4 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500"
>
Documentation
</Link>
<Link
href="/blog"
title="Blog"
className="block py-4 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500"
>
Blog
</Link>
<a
href="https://nx.app/pricing"
title="Nx Cloud"
target="_blank"
className="flex w-full gap-2 py-4 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500"
>
CI Pricing
<ArrowUpRightIcon className="h-2 w-2 align-super" />
</a>
{/*RESOURCES*/}
<Disclosure as="div">
{({ open }) => (
<>
<Disclosure.Button
className={cx(
'flex w-full items-center justify-between py-4 text-left text-base font-medium focus:outline-none',
open
? 'text-blue-500 dark:text-sky-500'
: 'tex-slate-800 dark:text-slate-200'
)}
>
<span>Resources</span>
<ChevronDownIcon
aria-hidden="true"
className={cx(
open
? 'rotate-180 transform text-blue-500 dark:text-sky-500'
: 'tex-slate-800 dark:text-slate-200',
'h-3 w-3 transition duration-150 ease-in-out group-hover:text-blue-500 dark:group-hover:text-sky-500'
)}
/>
</Disclosure.Button>
<Disclosure.Panel
as="ul"
className="space-y-1 pb-2"
>
{learnItems.map((item) => (
<MobileMenuItem
key={item.name}
item={item}
/>
))}
{eventItems.map((item) => (
<MobileMenuItem
key={item.name}
item={item}
/>
))}
</Disclosure.Panel>
</>
)}
</Disclosure>
<Link
href="/contact"
title="Contact"
className="block py-4 font-medium leading-tight hover:text-blue-500 dark:text-slate-200 dark:hover:text-sky-500"
>
Contact
</Link>
</div>
</div>
</div>
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</div>
</Dialog>
</Transition.Root>
</div>
);
}

View File

@ -0,0 +1,214 @@
import {
AcademicCapIcon,
ArrowPathIcon,
BoltIcon,
CircleStackIcon,
CodeBracketIcon,
CubeIcon,
NewspaperIcon,
PlayCircleIcon,
ShareIcon,
Squares2X2Icon,
} from '@heroicons/react/24/outline';
import { FC, SVGProps } from 'react';
import { NxAgentsIcon } from '../nx-agents-icon';
import { NxReplayIcon } from '../nx-replay-icon';
export interface MenuItem {
name: string;
href: string;
description: string | null;
icon: FC<SVGProps<SVGSVGElement>> | null;
isHighlight: boolean;
isNew: boolean;
}
export const featuresItems: MenuItem[] = [
{
name: 'Task Running',
// description: 'Run one or many tasks in parallel.',
description: null,
href: '/features/run-tasks',
icon: BoltIcon,
isNew: false,
isHighlight: false,
},
{
name: 'Local Caching',
// description: 'Speeds up your local workflow.',
description: null,
href: '/features/cache-task-results',
icon: CircleStackIcon,
isNew: false,
isHighlight: false,
},
{
name: 'Nx Graph',
// description: 'See interactions for tasks and modules.',
description: null,
href: '/features/explore-graph',
icon: ShareIcon,
isNew: false,
isHighlight: false,
},
{
name: 'Automated updates',
// description: 'Keep running on latest without effort.',
description: null,
href: '/features/automate-updating-dependencies',
icon: ArrowPathIcon,
isNew: false,
isHighlight: false,
},
{
name: 'Module Boundaries',
// description: 'Partition your code into defined units.',
description: null,
href: '/features/enforce-module-boundaries',
icon: Squares2X2Icon,
isNew: false,
isHighlight: false,
},
{
name: 'Nx Release',
// description: 'Versioning, changelog, publishing.',
description: null,
href: '/features/manage-releases',
icon: CubeIcon,
isNew: true,
isHighlight: false,
},
{
name: 'Nx Replay',
description: 'Zero-config, fast & secure remote cache solution.',
href: '/ci/features/remote-cache',
icon: NxReplayIcon,
isNew: false,
isHighlight: true,
},
{
name: 'Nx Agents',
description:
'One-line config for distributing tasks, E2E tests split & flaky tasks rerun.',
href: '/ci/features/distribute-task-execution',
icon: NxAgentsIcon,
isNew: true,
isHighlight: true,
},
];
export const plans: MenuItem[] = [
{
name: 'Nx Cloud',
description:
'End-to-end solution for smart, efficient and maintainable CI.',
href: 'https://nx.app',
icon: null,
isNew: false,
isHighlight: false,
},
{
name: 'Nx Enterprise',
description:
'The ultimate Nx & Nx Cloud toolchain, tailored to your needs.',
href: 'https://nx.app/enterprise',
icon: null,
isNew: false,
isHighlight: false,
},
];
const useCaseItems: MenuItem[] = [
{
name: 'Get actionable feedback',
description: 'Enhanced analysis & analytics of your workflows.',
href: '',
icon: null,
isNew: false,
isHighlight: false,
},
{
name: 'Reduce CI timings with remote caching',
description: 'Share task results & artifacts between CI & teams.',
href: '',
icon: null,
isNew: false,
isHighlight: false,
},
{
name: 'Performant task distribution at scale',
description: 'Faster & cheaper CI workflows.',
href: '',
icon: null,
isNew: false,
isHighlight: false,
},
{
name: 'Improve E2E time execution on CI',
description: 'Automatic task splitting.',
href: '',
icon: null,
isNew: false,
isHighlight: false,
},
];
export const learnItems: MenuItem[] = [
{
name: 'Step by step tutorials',
description: null,
href: '/getting-started/intro#learn-nx',
icon: AcademicCapIcon,
isNew: false,
isHighlight: false,
},
{
name: 'Code examples for your stack',
description: null,
href: '/showcase/example-repos',
icon: CodeBracketIcon,
isNew: false,
isHighlight: false,
},
{
name: 'Video tutorials',
description: null,
href: 'https://www.youtube.com/@nxdevtools',
icon: PlayCircleIcon,
isNew: false,
isHighlight: false,
},
{
name: 'Newsletter',
description: null,
href: 'https://go.nrwl.io/nx-newsletter',
icon: NewspaperIcon,
isNew: false,
isHighlight: false,
},
];
export const eventItems: MenuItem[] = [
{
name: 'Nx Conf',
description:
'In person & virtual conference about latest monorepo advancements.',
href: '/conf',
icon: null,
isNew: false,
isHighlight: false,
},
{
name: 'Webinars',
description:
'Virtual courses to get a deeper understanding on monorepos animated by the Nx team.',
href: 'https://go.nx.dev/april-webinar',
icon: null,
isNew: false,
isHighlight: false,
},
];
export const solutionsMenuItems = {
'Helping you grow': plans,
// 'Use cases': useCaseItems
};
export const resourceMenuItems = {
Learn: learnItems,
Events: eventItems,
};

View File

@ -0,0 +1,54 @@
import { ElementType } from 'react';
import type { MenuItem } from './menu-items';
import cx from 'classnames';
import Link from 'next/link';
export function MobileMenuItem({
as = 'div',
className = '',
item,
...rest
}: {
as?: ElementType;
className?: string;
item: MenuItem;
}): JSX.Element {
const hasExternalLink =
item.href.startsWith('http') || item.href.startsWith('//');
const Tag = as;
return (
<Tag
className={cx(
'relative flex flex-1 items-center gap-2 rounded-lg py-3',
item.isHighlight ? 'bg-slate-50 px-2 dark:bg-slate-800/80' : '',
className
)}
{...rest}
>
{item.icon ? (
<item.icon aria-hidden="true" className="h-4 w-4 shrink-0" />
) : null}
<div className="grow">
<Link
href={item.href}
title={item.name}
target={hasExternalLink ? '_blank' : '_self'}
className="text-sm font-medium text-slate-900 dark:text-slate-200"
>
{item.name}
{item.isNew ? (
<span className="float-right inline-flex items-center rounded-md bg-blue-50 px-2 py-1 text-xs font-medium text-blue-700 ring-1 ring-inset ring-blue-700/10 dark:bg-blue-400/10 dark:text-sky-400 dark:ring-sky-400/30">
new
</span>
) : null}
<span className="absolute inset-0" />
</Link>
{item.description ? (
<p className="mt-0.5 text-xs text-slate-400 dark:text-slate-500">
{item.description}
</p>
) : null}
</div>
</Tag>
);
}

View File

@ -0,0 +1,27 @@
import type { MenuItem } from './menu-items';
import { DefaultMenuItem } from './default-menu-item';
export function SectionsMenu({
sections,
}: {
sections: Record<string, MenuItem[]>;
}): JSX.Element {
return (
<div className="flex flex-col gap-2 overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-slate-200 dark:bg-slate-900 dark:ring-slate-800">
<div className="divide-y divide-slate-200 dark:divide-slate-800">
{Object.keys(sections).map((section) => (
<div>
<h5 className="px-4 pt-6 text-sm text-slate-500 dark:text-slate-400">
{section}
</h5>
<div className="grid grid-cols-2 gap-2 p-2">
{sections[section].map((item) => (
<DefaultMenuItem key={item.name} item={item} />
))}
</div>
</div>
))}
</div>
</div>
);
}

View File

@ -0,0 +1,23 @@
import type { MenuItem } from './menu-items';
import { DefaultMenuItem } from './default-menu-item';
export function TwoColumnsMenu({ items }: { items: MenuItem[] }): JSX.Element {
return (
<div className="flex flex-col gap-2 overflow-hidden rounded-lg bg-white shadow-lg ring-1 ring-slate-200 dark:bg-slate-900 dark:ring-slate-800">
<div className="grid grid-cols-2 gap-2 p-2">
{items
.filter((i) => !i.isHighlight)
.map((item) => (
<DefaultMenuItem key={item.name} item={item} />
))}
<div className="col-span-2 flex gap-2">
{items
.filter((i) => i.isHighlight)
.map((item) => (
<DefaultMenuItem key={item.name} item={item} />
))}
</div>
</div>
</div>
);
}

View File

@ -0,0 +1,17 @@
import { FC, SVGProps } from 'react';
export const NxAgentsIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="none"
{...props}
>
<path
strokeLinejoin="round"
d="M21 12.5h-4m4 0a1 1 0 1 0 2 0 1 1 0 0 0-2 0Zm-2 8h-5v-3m5 3a1 1 0 1 0 2 0 1 1 0 0 0-2 0Zm-16-8h4m-4 0a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm2 8h5v-3m-5 3a1 1 0 1 1-2 0 1 1 0 0 1 2 0Zm0-17h5v4m-5-4a1 1 0 1 0-2 0 1 1 0 0 0 2 0Zm14 0h-5v4m5-4a1 1 0 1 1 2 0 1 1 0 0 1-2 0Zm-3 14H8a1 1 0 0 1-1-1v-8a1 1 0 0 1 1-1h8a1 1 0 0 1 1 1v8a1 1 0 0 1-1 1Zm-5-8h2l-.667 1.875L14 11.346 11.333 15.5l.334-2.77H10l1-3.23Z"
/>
</svg>
);

View File

@ -0,0 +1,14 @@
import { FC, SVGProps } from 'react';
export const NxIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
{...props}
>
<title>Nx</title>
<path d="m12 14.1-3.1 5-5.2-8.5v8.9H0v-15h3.7l5.2 8.9v-4l3 4.7zm.6-5.7V4.5H8.9v3.9h3.7zm5.6 4.1a2 2 0 0 0-2 1.3 2 2 0 0 1 2.4-.7c.4.2 1 .4 1.3.3a2.1 2.1 0 0 0-1.7-.9zm3.4 1c-.4 0-.8-.2-1.1-.6l-.2-.3a2.1 2.1 0 0 0-.5-.6 2 2 0 0 0-1.2-.3 2.5 2.5 0 0 0-2.3 1.5 2.3 2.3 0 0 1 4 .4.8.8 0 0 0 .9.3c.5 0 .4.4 1.2.5v-.1c0-.4-.3-.5-.8-.7zm2 1.3a.7.7 0 0 0 .4-.6c0-3-2.4-5.5-5.4-5.5a5.4 5.4 0 0 0-4.5 2.4l-1.5-2.4H8.9l3.5 5.4L9 19.5h3.6L14 17l1.6 2.4h3.5l-3.1-5a.7.7 0 0 1 0-.3 2.7 2.7 0 0 1 2.6-2.7c1.5 0 1.7.9 2 1.3.7.8 2 .5 2 1.5a.7.7 0 0 0 1 .6zm.4.2c-.2.3-.6.3-.8.6-.1.3.1.4.1.4s.4.2.6-.3V15z" />
</svg>
);

View File

@ -0,0 +1,17 @@
import { FC, SVGProps } from 'react';
export const NxReplayIcon: FC<SVGProps<SVGSVGElement>> = (props) => (
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
stroke="currentColor"
fill="none"
{...props}
>
<path
strokeLinecap="round"
d="m8.625 2.621-.014.004c-.317.09-.622.22-.907.387m4.796-.965-.014-.002a3.958 3.958 0 0 0-.986.002m3.875.574.014.004c.317.09.622.22.907.387m-.92 18.367.013-.004c.317-.09.622-.22.907-.387m-4.796.965.014.002c.328.04.659.04.986-.002m-3.875-.574-.014-.004a3.96 3.96 0 0 1-.907-.387M21.38 8.625l-.004-.014a3.96 3.96 0 0 0-.387-.907m.965 4.796.002-.014c.04-.328.04-.659-.002-.986m-.574 3.875-.004.014a3.96 3.96 0 0 1-.387.907m-18.367-.92.004.013c.09.317.22.622.387.907M2.047 11.5l-.002.014c-.04.328-.04.659.002.986m.574-3.875.004-.014c.09-.317.22-.622.387-.907M7.5 10.516h9m-9 0a1.5 1.5 0 0 1 0-3h9a1.5 1.5 0 0 1 0 3m-9 0a1.5 1.5 0 0 0 0 3m9-3a1.5 1.5 0 0 1 0 3m-6.412-4.5h.01m-1.883 0h.01m-.725 4.5h9m-9 0a1.5 1.5 0 0 0 0 3h9a1.5 1.5 0 0 0 0-3m-6.412-1.5h.01m-1.883 0h.01m1.863 3h.01m-1.883 0h.01M3 4.516a1.5 1.5 0 1 0 3 0 1.5 1.5 0 0 0-3 0Zm15 0a1.5 1.5 0 1 0 3 0 1.5 1.5 0 0 0-3 0Zm-15 15a1.5 1.5 0 1 0 3 0 1.5 1.5 0 0 0-3 0Zm15 0a1.5 1.5 0 1 0 3 0 1.5 1.5 0 0 0-3 0Z"
/>
</svg>
);

View File

@ -5,10 +5,10 @@ import {
SunIcon, SunIcon,
} from '@heroicons/react/24/outline'; } from '@heroicons/react/24/outline';
import cx from 'classnames'; import cx from 'classnames';
import { Fragment } from 'react'; import { ElementType, Fragment } from 'react';
import { useTheme } from './theme.provider'; import { Theme, useTheme } from './theme.provider';
export function ThemeSwitcher() { export function ThemeSwitcher(): JSX.Element {
const [theme, setTheme] = useTheme(); const [theme, setTheme] = useTheme();
const themeMap = { const themeMap = {
dark: { dark: {
@ -24,23 +24,24 @@ export function ThemeSwitcher() {
icon: <ComputerDesktopIcon className="h-4 w-4" />, icon: <ComputerDesktopIcon className="h-4 w-4" />,
}, },
}; };
const availableThemes = [ const availableThemes: { label: string; value: Theme; icon: ElementType }[] =
{ [
label: 'Light', {
value: 'light', label: 'Light',
icon: <SunIcon className="mr-4 h-4 w-4" />, value: 'light',
}, icon: SunIcon,
{ },
label: 'Dark', {
value: 'dark', label: 'Dark',
icon: <MoonIcon className="mr-4 h-4 w-4" />, value: 'dark',
}, icon: MoonIcon,
{ },
label: 'System', {
value: 'system', label: 'System',
icon: <ComputerDesktopIcon className="mr-4 h-4 w-4" />, value: 'system',
}, icon: ComputerDesktopIcon,
]; },
];
return ( return (
<div className="inline-block"> <div className="inline-block">
@ -66,13 +67,13 @@ export function ThemeSwitcher() {
leaveFrom="transform opacity-100 scale-100" leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95" leaveTo="transform opacity-0 scale-95"
> >
<Listbox.Options className="absolute top-full right-0 z-50 mt-2 w-36 origin-top-right divide-y divide-slate-100 rounded-md bg-white shadow-lg ring-1 ring-black/5 focus:outline-none dark:divide-slate-800 dark:bg-slate-900 dark:ring-white/5"> <Listbox.Options className="absolute top-full -right-10 z-50 mt-2 w-36 origin-top-right divide-y divide-slate-100 rounded-md bg-white shadow-lg ring-1 ring-black/5 focus:outline-none dark:divide-slate-800 dark:bg-slate-900 dark:ring-white/5">
{availableThemes.map(({ value, label, icon }) => ( {availableThemes.map((t) => (
<Listbox.Option key={value} value={value} as={Fragment}> <Listbox.Option key={t.value} value={t.value} as={Fragment}>
{({ active, selected }) => ( {({ active, selected }) => (
<li <li
className={cx( className={cx(
'flex cursor-pointer items-center px-4 py-2 text-sm', 'flex cursor-pointer items-center gap-2 px-4 py-2 text-sm',
{ {
'bg-slate-100 dark:bg-slate-800/60': active, 'bg-slate-100 dark:bg-slate-800/60': active,
'text-blue-500 dark:text-sky-500': active || selected, 'text-blue-500 dark:text-sky-500': active || selected,
@ -80,8 +81,8 @@ export function ThemeSwitcher() {
} }
)} )}
> >
{icon} <t.icon aria-hidden="true" className="h-4 w-4 shrink-0" />
{label} {t.label}
</li> </li>
)} )}
</Listbox.Option> </Listbox.Option>

View File

@ -124,7 +124,6 @@
"@types/marked": "^2.0.0", "@types/marked": "^2.0.0",
"@types/node": "18.19.8", "@types/node": "18.19.8",
"@types/npm-package-arg": "6.1.1", "@types/npm-package-arg": "6.1.1",
"@types/prettier": "^2.6.2",
"@types/react": "18.2.33", "@types/react": "18.2.33",
"@types/react-dom": "18.2.14", "@types/react-dom": "18.2.14",
"@types/semver": "^7.5.2", "@types/semver": "^7.5.2",
@ -169,7 +168,7 @@
"esbuild": "0.19.5", "esbuild": "0.19.5",
"eslint": "8.57.0", "eslint": "8.57.0",
"eslint-config-next": "14.0.4", "eslint-config-next": "14.0.4",
"eslint-config-prettier": "9.0.0", "eslint-config-prettier": "9.1.0",
"eslint-plugin-cypress": "2.14.0", "eslint-plugin-cypress": "2.14.0",
"eslint-plugin-import": "2.27.5", "eslint-plugin-import": "2.27.5",
"eslint-plugin-jsx-a11y": "6.7.1", "eslint-plugin-jsx-a11y": "6.7.1",
@ -245,8 +244,8 @@
"postcss-import": "~14.1.0", "postcss-import": "~14.1.0",
"postcss-preset-env": "~7.5.0", "postcss-preset-env": "~7.5.0",
"postcss-url": "~10.1.3", "postcss-url": "~10.1.3",
"prettier": "^2.6.2", "prettier": "^2.7.1",
"prettier-plugin-tailwindcss": "^0.1.5", "prettier-plugin-tailwindcss": "^0.1.13",
"pretty-quick": "^3.1.0", "pretty-quick": "^3.1.0",
"raw-loader": "^4.0.2", "raw-loader": "^4.0.2",
"react-markdown": "^8.0.7", "react-markdown": "^8.0.7",
@ -375,4 +374,3 @@
] ]
} }
} }

32
pnpm-lock.yaml generated
View File

@ -289,7 +289,7 @@ devDependencies:
version: 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.3.0-beta.3)(verdaccio@5.15.4) version: 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(js-yaml@4.1.0)(nx@18.3.0-beta.3)(verdaccio@5.15.4)
'@nx/eslint-plugin': '@nx/eslint-plugin':
specifier: 18.3.0-beta.3 specifier: 18.3.0-beta.3
version: 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@7.4.0)(eslint-config-prettier@9.0.0)(eslint@8.57.0)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4) version: 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@7.4.0)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4)
'@nx/jest': '@nx/jest':
specifier: 18.3.0-beta.3 specifier: 18.3.0-beta.3
version: 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.3.0-beta.3)(ts-node@10.9.1)(typescript@5.4.2)(verdaccio@5.15.4) version: 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.3.0-beta.3)(ts-node@10.9.1)(typescript@5.4.2)(verdaccio@5.15.4)
@ -449,9 +449,6 @@ devDependencies:
'@types/npm-package-arg': '@types/npm-package-arg':
specifier: 6.1.1 specifier: 6.1.1
version: 6.1.1 version: 6.1.1
'@types/prettier':
specifier: ^2.6.2
version: 2.7.1
'@types/react': '@types/react':
specifier: 18.2.33 specifier: 18.2.33
version: 18.2.33 version: 18.2.33
@ -585,8 +582,8 @@ devDependencies:
specifier: 14.0.4 specifier: 14.0.4
version: 14.0.4(eslint@8.57.0)(typescript@5.4.2) version: 14.0.4(eslint@8.57.0)(typescript@5.4.2)
eslint-config-prettier: eslint-config-prettier:
specifier: 9.0.0 specifier: 9.1.0
version: 9.0.0(eslint@8.57.0) version: 9.1.0(eslint@8.57.0)
eslint-plugin-cypress: eslint-plugin-cypress:
specifier: 2.14.0 specifier: 2.14.0
version: 2.14.0(eslint@8.57.0) version: 2.14.0(eslint@8.57.0)
@ -813,10 +810,10 @@ devDependencies:
specifier: ~10.1.3 specifier: ~10.1.3
version: 10.1.3(postcss@8.4.19) version: 10.1.3(postcss@8.4.19)
prettier: prettier:
specifier: ^2.6.2 specifier: ^2.7.1
version: 2.7.1 version: 2.7.1
prettier-plugin-tailwindcss: prettier-plugin-tailwindcss:
specifier: ^0.1.5 specifier: ^0.1.13
version: 0.1.13(prettier@2.7.1) version: 0.1.13(prettier@2.7.1)
pretty-quick: pretty-quick:
specifier: ^3.1.0 specifier: ^3.1.0
@ -7819,10 +7816,10 @@ packages:
- verdaccio - verdaccio
dev: true dev: true
/@nrwl/eslint-plugin-nx@18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@7.4.0)(eslint-config-prettier@9.0.0)(eslint@8.57.0)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4): /@nrwl/eslint-plugin-nx@18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@7.4.0)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4):
resolution: {integrity: sha512-M1XcAYnavTKZTC/kj1D4fYx9w2Q5Rbr6nyQ8vuZpukwWgxoDiNZ7CcHBdsUYO6EyFL3b331iCpQgcK+8tmSAhA==} resolution: {integrity: sha512-M1XcAYnavTKZTC/kj1D4fYx9w2Q5Rbr6nyQ8vuZpukwWgxoDiNZ7CcHBdsUYO6EyFL3b331iCpQgcK+8tmSAhA==}
dependencies: dependencies:
'@nx/eslint-plugin': 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@7.4.0)(eslint-config-prettier@9.0.0)(eslint@8.57.0)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4) '@nx/eslint-plugin': 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@7.4.0)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4)
transitivePeerDependencies: transitivePeerDependencies:
- '@babel/traverse' - '@babel/traverse'
- '@swc-node/register' - '@swc-node/register'
@ -8477,7 +8474,7 @@ packages:
- verdaccio - verdaccio
dev: true dev: true
/@nx/eslint-plugin@18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@7.4.0)(eslint-config-prettier@9.0.0)(eslint@8.57.0)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4): /@nx/eslint-plugin@18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@7.4.0)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4):
resolution: {integrity: sha512-3LNegAAk+ENBwM7frkoC7WSZ/K1n05mCDZOc6jKdHhP68KNiS1NeHn872l66qDgyf1Lb/qFizlZACWoVWVtkOw==} resolution: {integrity: sha512-3LNegAAk+ENBwM7frkoC7WSZ/K1n05mCDZOc6jKdHhP68KNiS1NeHn872l66qDgyf1Lb/qFizlZACWoVWVtkOw==}
peerDependencies: peerDependencies:
'@typescript-eslint/parser': ^6.13.2 || ^7.0.0 '@typescript-eslint/parser': ^6.13.2 || ^7.0.0
@ -8486,7 +8483,7 @@ packages:
eslint-config-prettier: eslint-config-prettier:
optional: true optional: true
dependencies: dependencies:
'@nrwl/eslint-plugin-nx': 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@7.4.0)(eslint-config-prettier@9.0.0)(eslint@8.57.0)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4) '@nrwl/eslint-plugin-nx': 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(@typescript-eslint/parser@7.4.0)(eslint-config-prettier@9.1.0)(eslint@8.57.0)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4)
'@nx/devkit': 18.3.0-beta.3(nx@18.3.0-beta.3) '@nx/devkit': 18.3.0-beta.3(nx@18.3.0-beta.3)
'@nx/js': 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4) '@nx/js': 18.3.0-beta.3(@swc-node/register@1.8.0)(@swc/core@1.3.86)(@types/node@18.19.8)(nx@18.3.0-beta.3)(typescript@5.4.2)(verdaccio@5.15.4)
'@typescript-eslint/parser': 7.4.0(eslint@8.57.0)(typescript@5.4.2) '@typescript-eslint/parser': 7.4.0(eslint@8.57.0)(typescript@5.4.2)
@ -8494,7 +8491,7 @@ packages:
'@typescript-eslint/utils': 7.4.0(eslint@8.57.0)(typescript@5.4.2) '@typescript-eslint/utils': 7.4.0(eslint@8.57.0)(typescript@5.4.2)
chalk: 4.1.2 chalk: 4.1.2
confusing-browser-globals: 1.0.11 confusing-browser-globals: 1.0.11
eslint-config-prettier: 9.0.0(eslint@8.57.0) eslint-config-prettier: 9.1.0(eslint@8.57.0)
jsonc-eslint-parser: 2.1.0 jsonc-eslint-parser: 2.1.0
semver: 7.6.0 semver: 7.6.0
tslib: 2.6.2 tslib: 2.6.2
@ -13165,6 +13162,7 @@ packages:
/@types/prettier@2.7.1: /@types/prettier@2.7.1:
resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==} resolution: {integrity: sha512-ri0UmynRRvZiiUJdiz38MmIblKK+oH30MztdBVR95dv/Ubw6neWSb8u1XpRb72L4qsZOhz+L+z9JD40SJmfWow==}
dev: false
/@types/pretty-hrtime@1.0.1: /@types/pretty-hrtime@1.0.1:
resolution: {integrity: sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==} resolution: {integrity: sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ==}
@ -18946,8 +18944,8 @@ packages:
- supports-color - supports-color
dev: true dev: true
/eslint-config-prettier@9.0.0(eslint@8.57.0): /eslint-config-prettier@9.1.0(eslint@8.57.0):
resolution: {integrity: sha512-IcJsTkJae2S35pRsRAwoCE+925rJJStOdkKnLVgtE+tEpqU0EVVM7OqrwxqgptKdX29NUwC82I5pXsGFIgSevw==} resolution: {integrity: sha512-NSWl5BFQWEPi1j4TjVNItzYV7dZXZ+wP6I6ZhrBGpChQhZRUaElihE9uRRkcbRnNb76UMKDF3r+WTmNcGPKsqw==}
hasBin: true hasBin: true
peerDependencies: peerDependencies:
eslint: '>=7.0.0' eslint: '>=7.0.0'
@ -23371,6 +23369,8 @@ packages:
peerDependenciesMeta: peerDependenciesMeta:
webpack: webpack:
optional: true optional: true
webpack-sources:
optional: true
dependencies: dependencies:
webpack: 5.88.0(@swc/core@1.3.86)(esbuild@0.19.5) webpack: 5.88.0(@swc/core@1.3.86)(esbuild@0.19.5)
webpack-sources: 3.2.3 webpack-sources: 3.2.3
@ -23383,6 +23383,8 @@ packages:
peerDependenciesMeta: peerDependenciesMeta:
webpack: webpack:
optional: true optional: true
webpack-sources:
optional: true
dependencies: dependencies:
webpack: 5.90.3(@swc/core@1.3.86)(esbuild@0.20.1) webpack: 5.90.3(@swc/core@1.3.86)(esbuild@0.20.1)
webpack-sources: 3.2.3 webpack-sources: 3.2.3