diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 74a9985e..8b5aa66c 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -21,6 +21,9 @@ export const parameters = { ), + canvas: { + sourceState: 'shown', + }, }, options: { storySort: { diff --git a/package-lock.json b/package-lock.json index 967c8603..9ae39e7a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,6 +12,7 @@ "@radix-ui/react-checkbox": "^1.0.0", "@radix-ui/react-dialog": "^1.0.0", "@radix-ui/react-dropdown-menu": "^1.0.1-rc.6", + "@radix-ui/react-navigation-menu": "^1.1.4", "@radix-ui/react-switch": "^1.0.0", "@radix-ui/react-tabs": "^1.0.0", "@radix-ui/react-tooltip": "^1.0.0", @@ -4719,6 +4720,69 @@ "react": "^16.8 || ^17.0 || ^18.0" } }, + "node_modules/@radix-ui/react-navigation-menu": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-navigation-menu/-/react-navigation-menu-1.1.4.tgz", + "integrity": "sha512-Cc+seCS3PmWmjI51ufGG7zp1cAAIRqHVw7C9LOA2TZ+R4hG6rDvHcTqIsEEFLmZO3zNVH72jOOE7kKNy8W+RtA==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-use-previous": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-navigation-menu/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.0.5.tgz", + "integrity": "sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-escape-keydown": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, "node_modules/@radix-ui/react-popper": { "version": "1.0.1-rc.7", "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.0.1-rc.7.tgz", diff --git a/package.json b/package.json index c1ba583d..3a2cb8b3 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "@radix-ui/react-checkbox": "^1.0.0", "@radix-ui/react-dialog": "^1.0.0", "@radix-ui/react-dropdown-menu": "^1.0.1-rc.6", + "@radix-ui/react-navigation-menu": "^1.1.4", "@radix-ui/react-switch": "^1.0.0", "@radix-ui/react-tabs": "^1.0.0", "@radix-ui/react-tooltip": "^1.0.0", diff --git a/src/system/Link/Link.stories.tsx b/src/system/Link/Link.stories.tsx index d553cb36..b8622a4f 100644 --- a/src/system/Link/Link.stories.tsx +++ b/src/system/Link/Link.stories.tsx @@ -9,8 +9,8 @@ import type { StoryObj } from '@storybook/react'; import { Link } from '..'; export default { + title: 'Navigation/Link', component: Link, - title: 'Link', }; type Story = StoryObj< typeof Link >; diff --git a/src/system/Nav/Nav.stories.tsx b/src/system/Nav/Nav.stories.tsx new file mode 100644 index 00000000..24ce9096 --- /dev/null +++ b/src/system/Nav/Nav.stories.tsx @@ -0,0 +1,117 @@ +/** + * External dependencies + */ +import type { StoryObj } from '@storybook/react'; + +/** + * Internal dependencies + */ +import { Nav, NavItem } from '../../system'; + +export default { + title: 'Navigation/Nav', + component: Nav, + parameters: { + docs: { + description: { + component: ` +A navigation menu is a list of links used to navigate a website. It is usually placed in a prominent position at the top of a site, or anywhere that needs a linked-navigation. + +## Guidance + +### When to use the Nav component + +- To link internal or external links in a menu format. +- To link to pages that are not part of the main navigation. + +### When to consider something else + +- If you have content inside the same page that will not affect the page Route/URL, use [Tabs](/docs/tabs--docs) component instead. +- If you are planning to have buttons in your navigation, use another navigation solution, for example: [Dropdown](/docs/dropdown--docs) component instead. + +## Accessibility Considerations guidance + +This component is based on the Radix Navigation Menu primitive, so it contains all the accessibility features from the primitive. + +- Adheres to the [navigation role requirements.](https://www.w3.org/TR/wai-aria-1.2/#navigation) +- Keyboard Interactions: https://www.radix-ui.com/primitives/docs/components/navigation-menu#keyboard-interactions + +### Usability guidance + +Pick one of the available variants: Primary or Tabs. You can use the components directly from the \`Nav\` component: + +~~~jsx filename="index.jsx" +import { Nav, NavItem } from '@automattic/components'; + + or + or +~~~ + +### Usage with Next.js framwork + +~~~jsx filename="index.jsx" +import Link from 'next/link'; + + + + + Your page name + + + +~~~ + +------- + +## Component Properties +`, + }, + }, + }, +}; + +type Story = StoryObj< typeof Nav >; + +export const Default: Story = { + render: () => ( + <> +

+ Variant: Primary +

+ + + PHP + + WordPress + New Relic + + Not accessible + + + + ), +}; + +export const Tab: Story = { + render: () => ( + <> +

+ Variant: Tab +

+ + + PHP + + WordPress + New Relic + + Not accessible + + + + ), +}; diff --git a/src/system/Nav/Nav.test.tsx b/src/system/Nav/Nav.test.tsx new file mode 100644 index 00000000..7f92efc8 --- /dev/null +++ b/src/system/Nav/Nav.test.tsx @@ -0,0 +1,51 @@ +/** @jsxImportSource theme-ui */ +/* eslint-disable @typescript-eslint/ban-ts-comment */ +// @ts-nocheck +/** + * External dependencies + */ +import { render, screen } from '@testing-library/react'; +import { axe } from 'jest-axe'; +import { ThemeUIProvider } from 'theme-ui'; + +/** + * Internal dependencies + */ +import { Nav, NavItem } from './'; + +import { theme } from '../'; + +const renderWithTheme = children => + render( { children } ); + +const renderComponent = () => + renderWithTheme( + + PHP + WordPress + + New Relic + + + Not accessible + + + ); + +describe( '