Skip to content

Commit

Permalink
feat: add navigation menu
Browse files Browse the repository at this point in the history
  • Loading branch information
mdeliatf authored Jul 23, 2024
1 parent 4a6d617 commit 236407b
Show file tree
Hide file tree
Showing 7 changed files with 656 additions and 131 deletions.
1 change: 1 addition & 0 deletions components/Navigation/Navigation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ const baseNavItemCss = css({
color: '$navButtonText',
border: 'none',
minHeight: '$7',
width: '100%',
px: '$3',
py: '$2',
borderRadius: '$3',
Expand Down
72 changes: 72 additions & 0 deletions components/NavigationMenu/NavigationMenu.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
import { GearIcon, PersonIcon } from '@radix-ui/react-icons';
import { Meta, StoryFn } from '@storybook/react';
import React from 'react';

import { modifyVariantsForStory } from '../../utils/modifyVariantsForStory';
import { Container } from '../Container';
import { Link } from '../Link';
import { NavigationItem } from '../Navigation';
import { Text } from '../Text';
import {
NavigationMenu,
NavigationMenuContent,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuProps,
NavigationMenuTrigger,
NavigationMenuVariants,
} from './NavigationMenu';

const BaseNavigationMenu = (props: NavigationMenuProps): JSX.Element => (
<NavigationMenu {...props} />
);

const NavigationMenuForStory = modifyVariantsForStory<NavigationMenuVariants, NavigationMenuProps>(
BaseNavigationMenu,
);

const Component: Meta<typeof NavigationMenuForStory> = {
title: 'Components/NavigationMenu',
component: NavigationMenuForStory,
};

const Template: StoryFn<typeof NavigationMenuForStory> = (args) => (
<Container>
<NavigationMenuForStory {...args}>
<NavigationMenuList>
<NavigationMenuItem>
<NavigationMenuTrigger>
<Text css={{ cursor: 'pointer' }}>Links</Text>
</NavigationMenuTrigger>
<NavigationMenuContent css={{ display: 'flex', flexDirection: 'column', gap: '$1' }}>
<NavigationMenuLink asChild>
<Link href="#">A link</Link>
</NavigationMenuLink>
<NavigationMenuLink asChild>
<Link href="#">Another link</Link>
</NavigationMenuLink>
</NavigationMenuContent>
</NavigationMenuItem>

<NavigationMenuItem>
<NavigationMenuTrigger>
<Text css={{ cursor: 'pointer' }}>Navigation items</Text>
</NavigationMenuTrigger>
<NavigationMenuContent>
<NavigationMenuLink>
<NavigationItem startAdornment={<PersonIcon />}>Profile</NavigationItem>
</NavigationMenuLink>
<NavigationMenuLink>
<NavigationItem startAdornment={<GearIcon />}>Settings</NavigationItem>
</NavigationMenuLink>
</NavigationMenuContent>
</NavigationMenuItem>
</NavigationMenuList>
</NavigationMenuForStory>
</Container>
);

export const Basic: StoryFn<typeof NavigationMenuForStory> = Template.bind({});

export default Component;
104 changes: 104 additions & 0 deletions components/NavigationMenu/NavigationMenu.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
import * as NavigationMenuPrimitive from '@radix-ui/react-navigation-menu';
import React from 'react';

import { CSS, styled, VariantProps } from '../../stitches.config';
import { elevationVariants } from '../Elevation';
import { panelStyles } from '../Panel';

// #region Root

const StyledRoot = styled(NavigationMenuPrimitive.Root, {
ul: {
m: 0,
p: 0,
listStyleType: 'none',
li: {
position: 'relative',
display: 'inline',
},
},
});

export type NavigationMenuProps = React.ComponentProps<typeof NavigationMenuPrimitive.Root> & {
children: React.ReactNode;
css?: CSS;
};

export type NavigationMenuVariants = VariantProps<typeof NavigationMenu>;

export const NavigationMenu = React.forwardRef<
React.ElementRef<typeof StyledRoot>,
NavigationMenuProps
>(({ children, ...props }, fowardedRef) => (
<StyledRoot {...props} ref={fowardedRef}>
{children}
</StyledRoot>
));

// #endregion Root

// #region Content

const StyledContent = styled(NavigationMenuPrimitive.Content, panelStyles, {
position: 'absolute',
left: 0,
zIndex: 1,
p: '$2',
color: '$hiContrast',
'&:focus': {
outline: 'none',
},
variants: {
elevation: elevationVariants,
},
defaultVariants: {
elevation: 2,
},
});

type NavigationMenuPrimitiveContentProps = Omit<
React.ComponentProps<typeof NavigationMenuPrimitive.Content>,
'as'
>;

export type NavigationMenuContentProps = NavigationMenuPrimitiveContentProps &
VariantProps<typeof StyledContent> & {
css?: CSS;
};

export const NavigationMenuContent = React.forwardRef<
React.ElementRef<typeof StyledContent>,
NavigationMenuContentProps
>(({ children, elevation, ...props }, fowardedRef) => (
<StyledContent elevation={elevation} {...props} ref={fowardedRef}>
{children}
</StyledContent>
));

// #endregion Content

// #region Trigger

const StyledTrigger = styled(NavigationMenuPrimitive.Trigger, {
backgroundColor: 'transparent',
border: 'none',
});

export type NavigationMenuTriggerProps = React.ComponentProps<
typeof NavigationMenuPrimitive.Trigger
> &
VariantProps<typeof StyledContent> & {
css?: CSS;
};

export const NavigationMenuTrigger = ({ children, ...props }: NavigationMenuTriggerProps) => (
<StyledTrigger {...props}>{children}</StyledTrigger>
);

// #endregion Trigger

export const NavigationMenuIndicator = NavigationMenuPrimitive.Indicator;
export const NavigationMenuItem = NavigationMenuPrimitive.Item;
export const NavigationMenuLink = NavigationMenuPrimitive.Link;
export const NavigationMenuList = NavigationMenuPrimitive.List;
export const NavigationMenuViewport = NavigationMenuPrimitive.Viewport;
1 change: 1 addition & 0 deletions components/NavigationMenu/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './NavigationMenu';
10 changes: 10 additions & 0 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,16 @@ export {
NavigationItem,
NavigationLink,
} from './components/Navigation';
export {
NavigationMenu,
NavigationMenuContent,
NavigationMenuIndicator,
NavigationMenuItem,
NavigationMenuLink,
NavigationMenuList,
NavigationMenuTrigger,
NavigationMenuViewport,
} from './components/NavigationMenu';
export {
NavigationTreeDrawer,
NavigationTreeContainer,
Expand Down
15 changes: 8 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
"@radix-ui/react-id": "^1.0.0",
"@radix-ui/react-label": "^2.0.0",
"@radix-ui/react-menu": "^2.0.1",
"@radix-ui/react-navigation-menu": "^1.2.0",
"@radix-ui/react-popover": "^1.0.2",
"@radix-ui/react-portal": "^1.0.1",
"@radix-ui/react-progress": "^1.0.1",
Expand All @@ -90,13 +91,13 @@
"@semantic-release/release-notes-generator": "^10.0.3",
"@stitches/react": "1.2.7",
"@storybook/addon-actions": "^8.2.2",
"@storybook/addon-docs": "^8.2.2",
"@storybook/addon-essentials": "^8.2.2",
"@storybook/addon-docs": "^8.2.5",
"@storybook/addon-essentials": "^8.2.5",
"@storybook/addon-links": "^8.2.2",
"@storybook/builder-vite": "^8.2.2",
"@storybook/builder-vite": "^8.2.5",
"@storybook/preview-api": "^8.2.2",
"@storybook/react": "^8.2.2",
"@storybook/react-vite": "^8.2.2",
"@storybook/react": "^8.2.5",
"@storybook/react-vite": "^8.2.5",
"@storybook/theming": "^8.2.2",
"@types/jest": "^27.4.1",
"@types/jest-axe": "^3.5.3",
Expand All @@ -114,13 +115,13 @@
"lodash.merge": "^4.6.2",
"np": "^8.0.4",
"patch-package": "^8.0.0",
"prettier": "^2.1.2",
"prettier": "^3.3.3",
"react": "18.2.0",
"react-dom": "18.2.0",
"rollup": "^2.70.1",
"rollup-plugin-typescript2": "^0.36.0",
"semantic-release": "^19.0.2",
"storybook": "^8.2.2",
"storybook": "^8.2.5",
"storybook-dark-mode": "^4.0.2",
"tinycolor2": "^1.4.2",
"typescript": "5.4.5",
Expand Down
Loading

0 comments on commit 236407b

Please sign in to comment.