Skip to content

Commit 6a32ddf

Browse files
Merge pull request #246 from commitd/ka-nav-menu
Adds Navigation Menu based on Radix
2 parents 15480fe + 712b4fb commit 6a32ddf

File tree

8 files changed

+1328
-0
lines changed

8 files changed

+1328
-0
lines changed

package-lock.json

Lines changed: 552 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -221,6 +221,7 @@
221221
"@radix-ui/react-switch": "0.1.1",
222222
"@radix-ui/react-tabs": "0.1.1",
223223
"@radix-ui/react-tooltip": "0.1.1",
224+
"@radix-ui/react-navigation-menu": "0.1.1",
224225
"@radix-ui/react-select": "0.1.1",
225226
"@radix-ui/react-visually-hidden": "^0.1.1",
226227
"@stitches/react": "^1.2.5"

src/components/AppBar/AppBar.stories.tsx

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
AppBarMenu,
1010
AppBarMenuItem,
1111
} from '.'
12+
import { WrappedNavigationMenu } from '../NavigationMenu'
1213

1314
export default {
1415
title: 'Components/AppBar',
@@ -63,6 +64,52 @@ export const WithMenuWithoutActions: React.FC = () => {
6364
)
6465
}
6566

67+
/**
68+
* The App Bar can also make use of a wrapped Navigation Menu in place of AppBarMenuItem for more expanded usage.
69+
* See [Navigation Menu](/docs/components-navigationmenu--default) for more details on it's use.
70+
*/
71+
export const WithNavigationMenu: React.FC = () => {
72+
const list = {
73+
trigger: 'Wrapped List',
74+
links: [
75+
{
76+
href: '/design-system-colour--page',
77+
content: {
78+
title: 'Colors',
79+
text: 'Beautiful, thought-out palettes with auto dark mode.',
80+
},
81+
},
82+
{
83+
href: '/components-icons--icon-grid',
84+
content: {
85+
title: 'Icons',
86+
text: 'A collection of available icons based on material designs.',
87+
},
88+
},
89+
],
90+
}
91+
const storybookLink = {
92+
href: 'https://components.committed.software',
93+
text: 'Storybook',
94+
}
95+
const githubLink = {
96+
href: 'https://github.com/commitd/components',
97+
text: 'Github',
98+
}
99+
100+
return (
101+
<AppBar>
102+
<AppBarHeading>Example</AppBarHeading>
103+
<AppBarMenu>
104+
<WrappedNavigationMenu items={[list, storybookLink, githubLink]} />
105+
</AppBarMenu>
106+
<AppBarActions>
107+
<AppBarButton>Login</AppBarButton>
108+
</AppBarActions>
109+
</AppBar>
110+
)
111+
}
112+
66113
export const WithReactRouter: React.FC = () => {
67114
return (
68115
<MemoryRouter>
Lines changed: 276 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,276 @@
1+
import { Meta, Story } from '@storybook/react'
2+
import React from 'react'
3+
import {
4+
NavigationMenu,
5+
NavigationMenuContent,
6+
NavigationMenuIndicator,
7+
NavigationMenuItem,
8+
NavigationMenuLink,
9+
NavigationMenuList,
10+
NavigationMenuTrigger,
11+
NavigationMenuViewport,
12+
NavigationViewportPosition,
13+
NavigationMenuContentList,
14+
NavigationMenuContentListItem,
15+
NavigationMenuContentListLink,
16+
} from '.'
17+
import { Logo } from '../Logo'
18+
import { Text } from '../Text'
19+
import { Box } from '../Box'
20+
import { WrappedNavigationMenu } from './NavigationMenu'
21+
22+
export default {
23+
title: 'Components/NavigationMenu',
24+
component: NavigationMenu,
25+
subcomponents: {
26+
NavigationMenuContent,
27+
NavigationMenuIndicator,
28+
NavigationMenuItem,
29+
NavigationMenuLink,
30+
NavigationMenuList,
31+
NavigationMenuTrigger,
32+
NavigationMenuViewport,
33+
NavigationMenuContentList,
34+
NavigationMenuContentListItem,
35+
NavigationMenuContentListLink,
36+
},
37+
} as Meta
38+
39+
const Template: Story = (args) => (
40+
<NavigationMenu>
41+
<NavigationMenuList>
42+
<NavigationMenuItem>
43+
<NavigationMenuTrigger caret={true}>Components</NavigationMenuTrigger>
44+
<NavigationMenuContent>
45+
<NavigationMenuContentList layout="row">
46+
<NavigationMenuContentListItem href="https://components.committed.software">
47+
<NavigationMenuContentListLink
48+
title="Storybook"
49+
text="A live storybook version of the current committed components."
50+
/>
51+
</NavigationMenuContentListItem>
52+
<NavigationMenuContentListItem href="/design-system-colour--page">
53+
<NavigationMenuContentListLink
54+
title="Colors"
55+
text="Beautiful, thought-out palettes with auto dark mode."
56+
/>
57+
</NavigationMenuContentListItem>
58+
<NavigationMenuContentListItem href="/components-icons--icon-grid">
59+
<NavigationMenuContentListLink
60+
title="Icons"
61+
text="A collection of available icons based on material designs."
62+
/>
63+
</NavigationMenuContentListItem>
64+
</NavigationMenuContentList>
65+
</NavigationMenuContent>
66+
</NavigationMenuItem>
67+
68+
<NavigationMenuItem>
69+
<NavigationMenuLink href="https://github.com/commitd/components">
70+
Github
71+
</NavigationMenuLink>
72+
</NavigationMenuItem>
73+
74+
<NavigationMenuIndicator />
75+
</NavigationMenuList>
76+
77+
<NavigationViewportPosition>
78+
<NavigationMenuViewport />
79+
</NavigationViewportPosition>
80+
</NavigationMenu>
81+
)
82+
83+
export const Default = Template.bind({})
84+
85+
/** Links and triggers follow the same variant formats as Buttons, namely Primary, Secondary, Tertiary and Brand. By Default, Secondary is used.*/
86+
export const Variants = () => {
87+
return (
88+
<>
89+
<NavigationMenu>
90+
<NavigationMenuList>
91+
<NavigationMenuItem>
92+
<NavigationMenuLink
93+
href="/components-button--default#variant"
94+
variant={'primary'}
95+
>
96+
Primary
97+
</NavigationMenuLink>
98+
</NavigationMenuItem>
99+
<NavigationMenuItem>
100+
<NavigationMenuLink
101+
href="/components-button--default#variant"
102+
variant={'secondary'}
103+
>
104+
Secondary
105+
</NavigationMenuLink>
106+
</NavigationMenuItem>
107+
<NavigationMenuItem>
108+
<NavigationMenuLink
109+
href="/components-button--default#variant"
110+
variant={'brand'}
111+
>
112+
Brand
113+
</NavigationMenuLink>
114+
</NavigationMenuItem>
115+
<NavigationMenuItem>
116+
<NavigationMenuLink
117+
href="/components-button--default#variant"
118+
variant={'tertiary'}
119+
>
120+
Tertiary
121+
</NavigationMenuLink>
122+
</NavigationMenuItem>
123+
<NavigationMenuIndicator />
124+
</NavigationMenuList>
125+
126+
<NavigationViewportPosition>
127+
<NavigationMenuViewport />
128+
</NavigationViewportPosition>
129+
</NavigationMenu>
130+
131+
<NavigationMenu>
132+
<NavigationMenuList>
133+
<NavigationMenuItem>
134+
<NavigationMenuTrigger caret={true} variant={'primary'}>
135+
Primary
136+
</NavigationMenuTrigger>
137+
<NavigationMenuContent>
138+
<NavigationMenuContentList layout="row"></NavigationMenuContentList>
139+
</NavigationMenuContent>
140+
</NavigationMenuItem>
141+
<NavigationMenuItem>
142+
<NavigationMenuTrigger caret={true} variant={'secondary'}>
143+
Secondary
144+
</NavigationMenuTrigger>
145+
<NavigationMenuContent>
146+
<NavigationMenuContentList layout="row"></NavigationMenuContentList>
147+
</NavigationMenuContent>
148+
</NavigationMenuItem>
149+
<NavigationMenuItem>
150+
<NavigationMenuTrigger caret={true} variant={'tertiary'}>
151+
Tertiary
152+
</NavigationMenuTrigger>
153+
<NavigationMenuContent>
154+
<NavigationMenuContentList layout="row"></NavigationMenuContentList>
155+
</NavigationMenuContent>
156+
</NavigationMenuItem>
157+
<NavigationMenuItem>
158+
<NavigationMenuTrigger caret={true} variant={'brand'}>
159+
Brand
160+
</NavigationMenuTrigger>
161+
<NavigationMenuContent>
162+
<NavigationMenuContentList layout="row"></NavigationMenuContentList>
163+
</NavigationMenuContent>
164+
</NavigationMenuItem>
165+
<NavigationMenuIndicator />
166+
</NavigationMenuList>
167+
168+
<NavigationViewportPosition>
169+
<NavigationMenuViewport />
170+
</NavigationViewportPosition>
171+
</NavigationMenu>
172+
</>
173+
)
174+
}
175+
176+
/** NavigationMenu also provides a wrapped version, aimed primary at use in [AppBar](/docs/components-appbar--default)
177+
* as show [here](/docs/components-appbar--with-navigation-menu), however can also be used elsewhere as a simplified version as shown in this example. */
178+
export const Wrapped = () => {
179+
const list = {
180+
trigger: 'Wrapped List',
181+
links: [
182+
{
183+
href: '/design-system-colour--page',
184+
content: {
185+
title: 'Colors',
186+
text: 'Beautiful, thought-out palettes with auto dark mode.',
187+
},
188+
},
189+
{
190+
href: '/components-icons--icon-grid',
191+
content: {
192+
title: 'Icons',
193+
text: 'A collection of available icons based on material designs.',
194+
},
195+
},
196+
],
197+
}
198+
const storybookLink = {
199+
href: 'https://components.committed.software',
200+
text: 'Storybook',
201+
}
202+
const githubLink = {
203+
href: 'https://github.com/commitd/components',
204+
text: 'Github',
205+
}
206+
return <WrappedNavigationMenu items={[list, storybookLink, githubLink]} />
207+
}
208+
209+
/** Content does not need to be limited to simple text based links, such as NavigationMenuContentListLink,
210+
* but instead can be any customised react node instead. */
211+
export const AlternativeContent = () => {
212+
const MyAltContent = (
213+
<NavigationMenuContentListItem
214+
href="https://components.committed.software"
215+
css={{ gridRow: 'span 3' }}
216+
>
217+
<Box
218+
css={{
219+
display: 'flex',
220+
justifyContent: 'center',
221+
flexDirection: 'column',
222+
width: '100%',
223+
height: '100%',
224+
background: `linear-gradient(135deg, $colors$grey11 0%, $colors$grey8 100%);`,
225+
borderRadius: 6,
226+
padding: 25,
227+
}}
228+
>
229+
<Logo css={{ size: '$10' }} />
230+
<Text
231+
size={4}
232+
weight={'bold'}
233+
css={{
234+
color: '$colors$brandYellow9',
235+
marginTop: 16,
236+
marginBottom: 7,
237+
}}
238+
>
239+
Components
240+
</Text>
241+
</Box>
242+
</NavigationMenuContentListItem>
243+
)
244+
245+
return (
246+
<NavigationMenu>
247+
<NavigationMenuList>
248+
<NavigationMenuItem>
249+
<NavigationMenuTrigger caret={false}>
250+
Alternative Content
251+
</NavigationMenuTrigger>
252+
<NavigationMenuContent>
253+
<NavigationMenuContentList layout="row">
254+
{MyAltContent}
255+
<NavigationMenuContentListItem href="/design-system-colour--page">
256+
<NavigationMenuContentListLink
257+
title="Colors"
258+
text="Beautiful, thought-out palettes with auto dark mode."
259+
/>
260+
</NavigationMenuContentListItem>
261+
<NavigationMenuContentListItem href="/components-icons--icon-grid">
262+
<NavigationMenuContentListLink title="Icons" />
263+
</NavigationMenuContentListItem>
264+
</NavigationMenuContentList>
265+
</NavigationMenuContent>
266+
</NavigationMenuItem>
267+
268+
<NavigationMenuIndicator />
269+
</NavigationMenuList>
270+
271+
<NavigationViewportPosition>
272+
<NavigationMenuViewport />
273+
</NavigationViewportPosition>
274+
</NavigationMenu>
275+
)
276+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import React from 'react'
2+
import { renderLight, renderDark } from 'test-utils'
3+
import { AlternativeContent, Default, Wrapped } from './NavigationMenu.stories'
4+
5+
it('renders light without error', () => {
6+
const { asFragment } = renderLight(<Default />)
7+
expect(asFragment()).toBeDefined()
8+
})
9+
10+
it('renders dark without error', () => {
11+
const { asFragment } = renderDark(<Default />)
12+
expect(asFragment()).toBeDefined()
13+
})
14+
15+
it('renders wrapped version', () => {
16+
const { asFragment } = renderLight(<Wrapped />)
17+
expect(asFragment()).toBeDefined()
18+
})
19+
20+
it('renders alternative content', () => {
21+
const { asFragment } = renderLight(<AlternativeContent />)
22+
expect(asFragment()).toBeDefined()
23+
})

0 commit comments

Comments
 (0)