Skip to content

Commit

Permalink
feat(NavList): use type prop, deprecate boolean types (#262)
Browse files Browse the repository at this point in the history
* fixes #234
  • Loading branch information
ahobson authored Jun 24, 2020
1 parent e986638 commit 7c83154
Show file tree
Hide file tree
Showing 8 changed files with 92 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ const Section = ({
// eslint-disable-next-line jsx-a11y/no-noninteractive-element-interactions
<section className={classes} onClick={onToggle} onKeyPress={onToggle}>
<h4 className="usa-footer__primary-link">{primaryLinkOrHeading}</h4>
<NavList footerSecondary items={secondaryLinks} />
<NavList type="footerSecondary" items={secondaryLinks} />
</section>
)
}
4 changes: 2 additions & 2 deletions src/components/header/ExtendedNav/ExtendedNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ export const ExtendedNav = (
<nav className={classes} {...navProps}>
<div className="usa-nav__inner">
<NavCloseButton onClick={onToggleMobileNav} />
<NavList items={primaryItems} primary={true} />
<NavList items={primaryItems} type="primary" />
<div className="usa-nav__secondary">
<NavList items={secondaryItems} secondary={true} />
<NavList items={secondaryItems} type="secondary" />
{children}
</div>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/header/MegaMenu/MegaMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const MegaMenu = (
<div className="grid-row grid-gap-4">
{items.map((listItems, i) => (
<div className="usa-col" key={`subnav_col_${i}`}>
<NavList items={listItems} megamenu={true} {...ulProps} />
<NavList items={listItems} type="megamenu" {...ulProps} />
</div>
))}
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/header/Menu/Menu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const Menu = (
props: MenuProps & React.HTMLAttributes<HTMLUListElement>
): React.ReactElement => {
const { items, isOpen, ...listProps } = props
return <NavList items={items} subnav={true} hidden={!isOpen} {...listProps} />
return <NavList items={items} type="subnav" hidden={!isOpen} {...listProps} />
}

export default Menu
2 changes: 1 addition & 1 deletion src/components/header/NavList/NavList.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,5 +21,5 @@ const testItems = [
]

export const BasicNavList = (): React.ReactElement => (
<NavList items={testItems} primary={true} />
<NavList items={testItems} type="primary" />
)
35 changes: 34 additions & 1 deletion src/components/header/NavList/NavList.test.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import React from 'react'
import { render } from '@testing-library/react'

jest.mock('../../../deprecation')
import { deprecationWarning } from '../../../deprecation'
import { NavList } from './NavList'

const testItems = ['item 1', 'item 2', 'item 3']

describe('NavList component', () => {
it('renders without errors', () => {
const { container } = render(<NavList items={testItems} primary={true} />)
const { container } = render(<NavList items={testItems} type="primary" />)
expect(container.querySelector('.usa-nav__primary')).toBeInTheDocument()
expect(
container.querySelector('.usa-nav__primary-item')
Expand All @@ -20,4 +22,35 @@ describe('NavList component', () => {
expect(getByText('item 2')).toBeInTheDocument()
expect(getByText('item 3')).toBeInTheDocument()
})

describe('renders with type prop', () => {
beforeEach(() => {
jest.clearAllMocks()
})

it.each([
['primary', 'secondary', '.usa-nav__primary-item'],
['secondary', 'subnav', '.usa-nav__secondary-links'],
['subnav', 'megamenu', '.usa-nav__submenu'],
['megamenu', 'footerSecondary', '.usa-nav__submenu-list'],
['footerSecondary', 'primary', '.usa-list'],
])(
'prefers type to deprecated %s',
(typeString, deprecatedKey, expectedClass) => {
const type = typeString as
| 'primary'
| 'secondary'
| 'subnav'
| 'megamenu'
| 'footerSecondary'
const deprecatedProps: { [key: string]: boolean } = {}
deprecatedProps[`${deprecatedKey}`] = true
const { container } = render(
<NavList items={testItems} type={type} {...deprecatedProps} />
)
expect(container.querySelector(expectedClass)).toBeInTheDocument()
expect(deprecationWarning).toHaveBeenCalledTimes(1)
}
)
})
})
60 changes: 51 additions & 9 deletions src/components/header/NavList/NavList.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,29 @@
import React from 'react'
import classnames from 'classnames'
import { deprecationWarning } from '../../../deprecation'

interface NavListProps {
items: React.ReactNode[]
type?: 'primary' | 'secondary' | 'subnav' | 'megamenu' | 'footerSecondary'
/**
* @deprecated since 1.6.0, use size
*/
primary?: boolean
/**
* @deprecated since 1.6.0, use size
*/
secondary?: boolean
/**
* @deprecated since 1.6.0, use size
*/
subnav?: boolean
/**
* @deprecated since 1.6.0, use size
*/
megamenu?: boolean
/**
* @deprecated since 1.6.0, use size
*/
footerSecondary?: boolean
}

Expand All @@ -15,6 +32,7 @@ export const NavList = (
): React.ReactElement => {
const {
items,
type,
primary,
secondary,
subnav,
Expand All @@ -24,22 +42,46 @@ export const NavList = (
...ulProps
} = props

if (primary) {
deprecationWarning('NavList property primary is deprecated. Use type')
}
if (secondary) {
deprecationWarning('NavList property secondary is deprecated. Use type')
}
if (subnav) {
deprecationWarning('NavList property subnav is deprecated. Use type')
}
if (megamenu) {
deprecationWarning('NavList property megamenu is deprecated. Use type')
}
if (footerSecondary) {
deprecationWarning(
'NavList property footerSecondary is deprecated. Use type'
)
}

const isPrimary = type ? type === 'primary' : primary
const isSecondary = type ? type === 'secondary' : secondary
const isSubnav = type ? type === 'subnav' : subnav
const isMegamenu = type ? type === 'megamenu' : megamenu
const isFooterSecondary = type ? type === 'footerSecondary' : footerSecondary

const ulClasses = classnames(
{
'usa-nav__primary usa-accordion': primary,
'usa-nav__secondary-links': secondary,
'usa-nav__submenu': subnav,
'usa-nav__submenu-list': megamenu,
'usa-list usa-list--unstyled': footerSecondary,
'usa-nav__primary usa-accordion': isPrimary,
'usa-nav__secondary-links': isSecondary,
'usa-nav__submenu': isSubnav,
'usa-nav__submenu-list': isMegamenu,
'usa-list usa-list--unstyled': isFooterSecondary,
},
className
)

const liClasses = classnames({
'usa-nav__primary-item': primary,
'usa-nav__secondary-item': secondary,
'usa-nav__submenu-item': subnav || megamenu,
'usa-footer__secondary-link': footerSecondary,
'usa-nav__primary-item': isPrimary,
'usa-nav__secondary-item': isSecondary,
'usa-nav__submenu-item': isSubnav || isMegamenu,
'usa-footer__secondary-link': isFooterSecondary,
})

return (
Expand Down
2 changes: 1 addition & 1 deletion src/components/header/PrimaryNav/PrimaryNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export const PrimaryNav = (
return (
<nav className={classes} {...navProps}>
<NavCloseButton onClick={onToggleMobileNav} />
<NavList items={items} primary={true} />
<NavList items={items} type="primary" />
{children}
</nav>
)
Expand Down

0 comments on commit 7c83154

Please sign in to comment.