Skip to content

Commit

Permalink
feat(Footer,FooterNav): use size prop, deprecate boolean sizes (#239)
Browse files Browse the repository at this point in the history
* feat(Footer,FooterNav): use size prop, deprecate boolean sizes

* fixes #233

* feat(Footer,FooterNav): update stories for size prop enum
  • Loading branch information
ahobson authored Jun 9, 2020
1 parent 5b60cdf commit c5abdc4
Show file tree
Hide file tree
Showing 8 changed files with 167 additions and 37 deletions.
22 changes: 11 additions & 11 deletions src/components/Footer/Footer/Footer.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ import { SocialLinks } from '../SocialLinks/SocialLinks'
import { TextInput } from '../../forms/TextInput/TextInput'

// assets
import logoImg from 'uswds/src/img/logo-img.png'
import logoImg from 'uswds/dist/img/logo-img.png'

export default {
title: 'Footer/Footer',
parameters: {
info: `
USWDS 2.0 Footer component
Source: https://designsystem.digital.gov/components/form-controls/#footer
`,
`,
},
}

Expand Down Expand Up @@ -52,13 +52,13 @@ const SignUpForm = (): React.ReactElement => {

export const SlimFooter = (): React.ReactElement => (
<Footer
slim
size="slim"
returnToTop={returnToTop}
primary={
<div className="usa-footer__primary-container grid-row">
<div className="mobile-lg:grid-col-8">
<FooterNav
slim
size="slim"
links={Array(4).fill(
<a className="usa-footer__primary-link" href="#">
Primary Link
Expand Down Expand Up @@ -99,11 +99,11 @@ export const SlimFooter = (): React.ReactElement => (

export const MediumFooter = (): React.ReactElement => (
<Footer
medium
size="medium"
returnToTop={returnToTop}
primary={
<FooterNav
medium
size="medium"
links={Array(4).fill(
<a className="usa-footer__primary-link" href="#">
Primary Link
Expand Down Expand Up @@ -173,14 +173,14 @@ export const MediumFooter = (): React.ReactElement => (

export const BigFooter = (): React.ReactElement => (
<Footer
big
size="big"
returnToTop={returnToTop}
primary={
<div className="grid-container">
<div className="grid-row grid-gap">
<div className="tablet:grid-col-8">
<FooterNav
big
size="big"
links={[
[
'Topic',
Expand Down Expand Up @@ -286,15 +286,15 @@ export const BigFooter = (): React.ReactElement => (

export const MobileBigFooter = (): React.ReactElement => (
<Footer
big
size="big"
returnToTop={returnToTop}
primary={
<div className="grid-container">
<div className="grid-row grid-gap">
<div className="tablet:grid-col-8">
<FooterNav
isMobile
big
size="big"
links={[
[
'Topic',
Expand Down
50 changes: 50 additions & 0 deletions src/components/Footer/Footer/Footer.test.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React from 'react'
import { render } from '@testing-library/react'

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

const nav = (
Expand Down Expand Up @@ -45,4 +47,52 @@ describe('Footer component', () => {
)
expect(getByText('Return To Top')).toBeInTheDocument()
})

describe('renders size classes', () => {
beforeEach(() => {
jest.clearAllMocks()
})

it.each([
['big', 'usa-footer--big'],
['medium', 'usa-footer--medium'],
['slim', 'usa-footer--slim'],
])('when size is %s should include class %s', (sizeString, uswdsClass) => {
const size = sizeString as 'big' | 'medium' | 'slim'
const { container } = render(
<Footer
primary={nav}
secondary={address}
returnToTop={returnToTop}
size={size}
/>
)
expect(container.querySelector('footer')).toHaveClass(uswdsClass)
expect(deprecationWarning).toHaveBeenCalledTimes(0)
})

it.each([
['big', 'slim', 'usa-footer--big'],
['medium', 'big', 'usa-footer--medium'],
['slim', 'medium', 'usa-footer--slim'],
])(
'prefers size to deprecated %s',
(sizeString, deprecatedKey, uswdsClass) => {
const size = sizeString as 'big' | 'medium' | 'slim'
const deprecatedProps: { [key: string]: boolean } = {}
deprecatedProps[`${deprecatedKey}`] = true
const { container } = render(
<Footer
primary={nav}
secondary={address}
returnToTop={returnToTop}
size={size}
{...deprecatedProps}
/>
)
expect(container.querySelector('footer')).toHaveClass(uswdsClass)
expect(deprecationWarning).toHaveBeenCalledTimes(1)
}
)
})
})
31 changes: 28 additions & 3 deletions src/components/Footer/Footer/Footer.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
import React from 'react'
import classnames from 'classnames'
import { deprecationWarning } from '../../../deprecation'

type FooterProps = {
size?: 'big' | 'medium' | 'slim'
/**
* @deprecated since 1.6.0, use size
*/
big?: boolean
/**
* @deprecated since 1.6.0, use size
*/
medium?: boolean
/**
* @deprecated since 1.6.0, use size
*/
slim?: boolean
/**
* Component for "return to top" button/handling
Expand All @@ -20,6 +31,7 @@ type FooterProps = {
}

export const Footer = ({
size,
big,
medium,
slim,
Expand All @@ -28,12 +40,25 @@ export const Footer = ({
secondary,
...footerAttributes
}: FooterProps & React.HTMLAttributes<HTMLElement>): React.ReactElement => {
if (big) {
deprecationWarning('Footer property big is deprecated. Use size')
}
if (medium) {
deprecationWarning('Footer property medium is deprecated. Use size')
}
if (slim) {
deprecationWarning('Footer property slim is deprecated. Use size')
}

const isBig = size ? size === 'big' : big
const isMedium = size ? size === 'medium' : medium
const isSlim = size ? size === 'slim' : slim
const classes = classnames(
'usa-footer',
{
'usa-footer--big': big,
'usa-footer--medium': medium,
'usa-footer--slim': slim,
'usa-footer--big': isBig,
'usa-footer--medium': isMedium,
'usa-footer--slim': isSlim,
},
footerAttributes.className
)
Expand Down
14 changes: 7 additions & 7 deletions src/components/Footer/FooterNav/FooterNav.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ export default {
parameters: {
info: `
Display single list of nav items, or grouped nav items in an extended nav. Used in USWDS 2.0 Footer component.
Source: https://designsystem.digital.gov/components/form-controls/#footer
`,
},
Expand All @@ -18,7 +18,7 @@ export default {
export const SlimFooterNav = (): React.ReactElement => (
<FooterNav
aria-label="Footer navigation"
slim
size="slim"
links={Array(4).fill(
<a className="usa-footer__primary-link" href="#">
PrimaryLink
Expand All @@ -30,7 +30,7 @@ export const SlimFooterNav = (): React.ReactElement => (
export const MediumFooterNav = (): React.ReactElement => (
<FooterNav
aria-label="Footer navigation"
medium
size="medium"
links={Array(4).fill(
<a className="usa-footer__primary-link" href="#">
PrimaryLink
Expand All @@ -41,11 +41,11 @@ export const MediumFooterNav = (): React.ReactElement => (

export const BigFooterNav = (): React.ReactElement => (
<Footer
big
size="big"
primary={
<FooterNav
aria-label="Footer navigation"
big
size="big"
links={[
['Topic', ...Array(3).fill(<a href="#">Secondary link</a>)],
[
Expand All @@ -65,11 +65,11 @@ export const BigFooterNav = (): React.ReactElement => (

export const MobileBigFooterNav = (): React.ReactElement => (
<Footer
big
size="big"
primary={
<FooterNav
aria-label="Footer navigation"
big
size="big"
isMobile
links={[
['Topic', ...Array(3).fill(<a href="#">Secondary link</a>)],
Expand Down
44 changes: 37 additions & 7 deletions src/components/Footer/FooterNav/FooterNav.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
import React from 'react'
import { render } from '@testing-library/react'

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

const links = Array(4).fill(
Expand Down Expand Up @@ -42,30 +44,58 @@ describe('FooterNav component', () => {
expect(getAllByText('Primary Link').length).toBe(4)
})

it('renders links with "big" prop', () => {
const { container, getAllByText } = render(<FooterNav links={links} big />)
it('renders links with size="big"', () => {
const { container, getAllByText } = render(
<FooterNav links={links} size="big" />
)
expect(container.querySelectorAll('a').length).toBe(4)
expect(getAllByText('Primary Link').length).toBe(4)
})

it('renders extended link sections with "big" prop', () => {
const { container } = render(<FooterNav links={extendedLinks} big />)
it('renders extended link sections with size="big"', () => {
const { container } = render(<FooterNav links={extendedLinks} size="big" />)

expect(container.querySelectorAll('a').length).toBe(5)
expect(container.querySelectorAll('section').length).toBe(2)
})

it('renders list headings with "big" prop', () => {
it('renders list headings with size="big"', () => {
const { container, getByText } = render(
<FooterNav links={extendedLinks} big />
<FooterNav links={extendedLinks} size="big" />
)
expect(container.querySelectorAll('h4').length).toBe(2)
expect(getByText('Types of Cats')).toBeInTheDocument()
expect(getByText('Musical Gifts')).toBeInTheDocument()
})

it('does not render extended nav links without "big" prop', () => {
it('does not render extended nav links without size="big"', () => {
const { container } = render(<FooterNav links={extendedLinks} />)
expect(container.querySelectorAll('a').length).toBe(0)
})

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

it.each([
['big', 'slim', 5],
['medium', 'big', 0],
['slim', 'big', 0],
])(
'prefers size to deprecated %s',
(sizeString, deprecatedKey, renderedNavLinkCount) => {
const size = sizeString as 'big' | 'medium' | 'slim'
const deprecatedProps: { [key: string]: boolean } = {}
deprecatedProps[`${deprecatedKey}`] = true
const { container } = render(
<FooterNav links={extendedLinks} size={size} {...deprecatedProps} />
)
expect(container.querySelectorAll('a').length).toBe(
renderedNavLinkCount
)
expect(deprecationWarning).toHaveBeenCalledTimes(1)
}
)
})
})
Loading

0 comments on commit c5abdc4

Please sign in to comment.