-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* [ui] SideNavigation: add stub components * [ui] SideNavigation, -Item: update styles * [ui] bump version to 0.8.6
- Loading branch information
1 parent
0150497
commit 7cecdfc
Showing
10 changed files
with
335 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
32 changes: 32 additions & 0 deletions
32
libs/juno-ui-components/src/components/SideNavigation/SideNavigation.component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
import React, { useEffect, useState } from "react"; | ||
import PropTypes from "prop-types"; | ||
import { Stack } from "../Stack/index" | ||
|
||
|
||
/** | ||
A generic vertical side navigation component. | ||
Place TopNavigationItem components as children. | ||
*/ | ||
export const SideNavigation = ({ | ||
children, | ||
className, | ||
...props | ||
}) => { | ||
return ( | ||
<Stack direction="vertical" className={`juno-sidenavigation ${className}`} role="navigation" {...props} > | ||
{ children } | ||
</Stack> | ||
) | ||
} | ||
|
||
SideNavigation.propTypes = { | ||
/** The children of the Navigation. Typically these should be SideNavigationItem(s) */ | ||
children: PropTypes.node, | ||
/** Pass custom classname. */ | ||
className: PropTypes.string, | ||
} | ||
|
||
SideNavigation.defaultProps = { | ||
children: null, | ||
className: "", | ||
} |
28 changes: 28 additions & 0 deletions
28
libs/juno-ui-components/src/components/SideNavigation/SideNavigation.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
import React from "react" | ||
import { SideNavigation } from "./index.js" | ||
import { SideNavigationItem } from "../SideNavigationItem/SideNavigationItem.component" | ||
import { Default as SideNavigationItemStory } from "../SideNavigationItem/SideNavigationItem.stories" | ||
|
||
export default { | ||
title: "Layout/SideNavigation/SideNavigation", | ||
component: SideNavigation, | ||
argTypes: {}, | ||
} | ||
|
||
const Template = ({items, ...args}) => ( | ||
<SideNavigation {...args}> | ||
{items.map((item, i) => ( | ||
<SideNavigationItem key={i} {...item} /> | ||
))} | ||
</SideNavigation> | ||
) | ||
|
||
export const Default = Template.bind({}) | ||
Default.args = { | ||
items: [ | ||
{...SideNavigationItemStory.args}, | ||
{...SideNavigationItemStory.args}, | ||
{...SideNavigationItemStory.args, icon: "warning"}, | ||
{...SideNavigationItemStory.args, active: true}, | ||
] | ||
} |
27 changes: 27 additions & 0 deletions
27
libs/juno-ui-components/src/components/SideNavigation/SideNavigation.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
import * as React from 'react'; | ||
import { render, screen, waitFor } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { SideNavigation } from './index'; | ||
|
||
describe('SideNavigation', () => { | ||
test('render a SideNavigation', async () => { | ||
render(<SideNavigation />); | ||
expect(screen.getByRole('navigation')).toBeInTheDocument(); | ||
expect(screen.getByRole('navigation')).toHaveClass("juno-sidenavigation"); | ||
}); | ||
|
||
test("renders children as passed", async () => { | ||
render(<SideNavigation><button>Test</button></SideNavigation>) | ||
expect(screen.getByRole('button', {name: "Test"})).toBeInTheDocument(); | ||
}) | ||
|
||
test('renders custom classNames as passed', async () => { | ||
render(<SideNavigation className='my-custom-class' />); | ||
expect(screen.getByRole("navigation")).toHaveClass('my-custom-class'); | ||
}); | ||
|
||
test('renders all props as passed', async () => { | ||
render(<SideNavigation data-lol='Prop goes here' />); | ||
expect(screen.getByRole('navigation')).toHaveAttribute('data-lol', 'Prop goes here'); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { SideNavigation } from "./SideNavigation.component"; |
95 changes: 95 additions & 0 deletions
95
libs/juno-ui-components/src/components/SideNavigationItem/SideNavigationItem.component.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
import React from "react"; | ||
import PropTypes from "prop-types"; | ||
import { Icon } from "../Icon/index.js"; | ||
import { knownIcons } from "../Icon/Icon.component.js" | ||
import "./sideNavigationItem.scss" | ||
|
||
/** | ||
A SideNavigation item. Top be placed inside SideNavigation. | ||
*/ | ||
|
||
export const SideNavigationItem = ({ | ||
icon, | ||
label, | ||
ariaLabel, | ||
href, | ||
active, | ||
onClick, | ||
children, | ||
className, | ||
...props | ||
}) => { | ||
|
||
const icn = icon ? <Icon icon={icon} size="18" color="jn-text-theme-default" className={ label && label.length ? "jn-mr-1" : "" } /> : null | ||
|
||
const content = label || children | ||
|
||
const handleButtonClick = (event) => { | ||
onClick && onClick(event) | ||
} | ||
|
||
const anchor = ( | ||
<a className={`juno-sidenavigation-item ${ active ? "juno-sidenavigation-item-active" : ""} ${className}`} | ||
href={href} | ||
aria-label={ariaLabel} | ||
{...props} | ||
> | ||
{ icn } | ||
{ content } | ||
</a> | ||
) | ||
|
||
const button = ( | ||
<button | ||
className={`juno-sidenavigation-item ${ active ? "juno-sidenavigation-item-active" : ""} ${className}`} | ||
onClick={handleButtonClick} | ||
aria-label={ariaLabel} | ||
{...props} | ||
> | ||
{ icn } | ||
{ content } | ||
</button> | ||
) | ||
|
||
const plain = ( | ||
<div className={`juno-sidenavigation-item ${ active ? "juno-sidenavigation-item-active" : ""} ${className}`} | ||
aria-label={ariaLabel} | ||
{...props} | ||
> | ||
{ icn } | ||
{ label || children } | ||
</div> | ||
) | ||
|
||
return href ? anchor : onClick ? button : plain | ||
} | ||
|
||
SideNavigationItem.propTypes = { | ||
/** pass an icon name */ | ||
icon: PropTypes.oneOf(knownIcons), | ||
/** The label of the item */ | ||
label: PropTypes.string, | ||
/** Children of the item. Will overwrite label when passed */ | ||
children: PropTypes.node, | ||
/** Pass a custom className */ | ||
className: PropTypes.string, | ||
/** The aria label of the item */ | ||
ariaLabel: PropTypes.string, | ||
/** The link the item should point to. Will render the item as an anchor if passed */ | ||
href: PropTypes.string, | ||
/** Whether the item is the currently active item */ | ||
active: PropTypes.bool, | ||
/** A handler to execute once the item is clicked. Will render the item as a button element if passed */ | ||
onClick: PropTypes.func, | ||
} | ||
|
||
SideNavigationItem.defaultProps = { | ||
icon: null, | ||
label: "", | ||
children: null, | ||
className: "", | ||
ariaLabel: "", | ||
href: "", | ||
active: false, | ||
onClick: undefined, | ||
} |
40 changes: 40 additions & 0 deletions
40
libs/juno-ui-components/src/components/SideNavigationItem/SideNavigationItem.stories.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import React from "react" | ||
import { SideNavigationItem } from "./index.js" | ||
|
||
export default { | ||
title: "Layout/SideNavigation/SideNavigationItem", | ||
component: SideNavigationItem, | ||
argTypes: {}, | ||
parameters: { actions: { argTypesRegex: null } } | ||
} | ||
|
||
const Template = (args) => <SideNavigationItem {...args} /> | ||
|
||
export const Default = Template.bind({}) | ||
Default.args = { | ||
label: "Navigation Item" | ||
} | ||
|
||
export const WithIcon = Template.bind({}) | ||
WithIcon.args = { | ||
label: "Navigation Item", | ||
icon: "warning" | ||
} | ||
|
||
export const AsAnchor = Template.bind({}) | ||
AsAnchor.args = { | ||
label: "Navigation Item", | ||
href: "#" | ||
} | ||
|
||
export const AsButton = Template.bind({}) | ||
AsButton.args = { | ||
label: "Navigation Item", | ||
onClick: () => {console.log("clicked")} | ||
} | ||
|
||
export const Active = Template.bind({}) | ||
Active.args = { | ||
label: "Navigation Item", | ||
active: true | ||
} |
73 changes: 73 additions & 0 deletions
73
libs/juno-ui-components/src/components/SideNavigationItem/SideNavigationItem.test.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
import * as React from 'react'; | ||
import { render, screen, waitFor } from '@testing-library/react'; | ||
import userEvent from '@testing-library/user-event'; | ||
import { SideNavigationItem } from './index'; | ||
|
||
describe('SideNavigation', () => { | ||
|
||
test('renders a SideNavigationItem', async () => { | ||
render(<SideNavigationItem data-testid="side-nav-item" />); | ||
expect(screen.getByTestId('side-nav-item')).toBeInTheDocument(); | ||
expect(screen.getByTestId('side-nav-item')).toHaveClass("juno-sidenavigation-item"); | ||
}); | ||
|
||
test("renders an icon as passed", async () => { | ||
render(<SideNavigationItem icon="warning" />) | ||
expect(screen.getByRole("img")).toBeInTheDocument(); | ||
expect(screen.getByRole("img")).toHaveAttribute("alt", "warning"); | ||
}) | ||
|
||
test("renders a plain, non-interactive item when no href or onClick are passed", async () => { | ||
render(<SideNavigationItem data-testid="side-nav-item" />); | ||
expect(screen.queryByRole('link')).not.toBeInTheDocument(); | ||
expect(screen.queryByRole('button')).not.toBeInTheDocument(); | ||
}) | ||
|
||
test("renders as a link when a href prop is passed", async () => { | ||
render(<SideNavigationItem href="#"/>); | ||
expect(screen.getByRole("link")).toBeInTheDocument(); | ||
expect(screen.getByRole("link")).toHaveClass("juno-sidenavigation-item"); | ||
}) | ||
|
||
test("renders as a button when an onClick prop is passed", async () => { | ||
render(<SideNavigationItem onClick={()=>{console.log("click")}} />); | ||
expect(screen.getByRole("button")).toBeInTheDocument(); | ||
expect(screen.getByRole("button")).toHaveClass("juno-sidenavigation-item"); | ||
}) | ||
|
||
test('renders an active ToppNavigationItem as passed', async () => { | ||
render(<SideNavigationItem data-testid="side-nav-item" active />); | ||
expect(screen.getByTestId('side-nav-item')).toBeInTheDocument(); | ||
expect(screen.getByTestId('side-nav-item')).toHaveClass("juno-sidenavigation-item"); | ||
expect(screen.getByTestId('side-nav-item')).toHaveClass("juno-sidenavigation-item-active"); | ||
}); | ||
|
||
test('renders an aria-label as passed', async () => { | ||
render(<SideNavigationItem href="#" ariaLabel="hey nav item!" />); | ||
expect(screen.getByRole('link')).toHaveAttribute('aria-label', 'hey nav item!'); | ||
}); | ||
|
||
test("renders children as passed", async () => { | ||
render(<SideNavigationItem data-testid="side-nav-item" >Test</SideNavigationItem>) | ||
expect(screen.getByTestId('side-nav-item')).toBeInTheDocument(); | ||
expect(screen.getByTestId('side-nav-item')).toHaveTextContent("Test"); | ||
}) | ||
|
||
test("onClick handler is called as passed", () => { | ||
const onClickSpy = jest.fn() | ||
render(<SideNavigationItem onClick={onClickSpy} />) | ||
screen.getByRole("button").click() | ||
expect(onClickSpy).toHaveBeenCalled() | ||
}) | ||
|
||
test('renders custom classNames as passed', async () => { | ||
render(<SideNavigationItem data-testid="side-nav-item" className='my-custom-class' />); | ||
expect(screen.getByTestId('side-nav-item')).toHaveClass('my-custom-class'); | ||
}); | ||
|
||
test('renders all props as passed', async () => { | ||
render(<SideNavigationItem data-testid="side-nav-item" data-lol='Prop goes here' />); | ||
expect(screen.getByTestId('side-nav-item')).toHaveAttribute('data-lol', 'Prop goes here'); | ||
}); | ||
|
||
}); |
1 change: 1 addition & 0 deletions
1
libs/juno-ui-components/src/components/SideNavigationItem/index.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { SideNavigationItem } from "./SideNavigationItem.component"; |
37 changes: 37 additions & 0 deletions
37
libs/juno-ui-components/src/components/SideNavigationItem/sideNavigationItem.scss
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
.juno-sidenavigation-item { | ||
color: var(--color-text-default); | ||
font-weight: bold; | ||
display: inline-flex; | ||
align-items: center; | ||
border-left: 3px solid transparent; | ||
padding-left: 1.75rem; | ||
padding-top: .375rem; | ||
padding-bottom: 0.375rem; | ||
|
||
.juno-icon { | ||
margin-right: .5rem; | ||
} | ||
|
||
&:hover { | ||
color: var(--color-text-high); | ||
border-left: 3px solid var(--color-accent); | ||
|
||
.juno-icon { | ||
color: var(--color-text-high); | ||
margin-right: .5rem; | ||
} | ||
|
||
} | ||
|
||
&:active, | ||
&.juno-sidenavigation-item-active { | ||
color: var(--color-navigation-active); | ||
border-left: 3px solid var(--color-navigation-active); | ||
|
||
.juno-icon { | ||
color: var(--color-navigation-active); | ||
} | ||
|
||
} | ||
|
||
} |