Skip to content

Commit

Permalink
feat: Add compositional Banner components (#2184)
Browse files Browse the repository at this point in the history
* Add compositional Banner components

* Re-order imports

* Add Banner test

* Add BannerButton tests

* Add BannerContent tests

* Add BannerFlag tests

* Add BannerGuidance tests

* Add BannerHeader tests

* Add BannerIcon tests

* Add BannerLockImage tests

* Add MediaBlockBody tests

* Add CustomBanner storybook example

* Import from index in story to better simulate importing from react-uswds

Co-authored-by: John Gedeon <[email protected]>
  • Loading branch information
brandonlenz and gidjin authored Sep 23, 2022
1 parent 4c021d1 commit f75e4ba
Show file tree
Hide file tree
Showing 28 changed files with 1,074 additions and 251 deletions.
199 changes: 0 additions & 199 deletions src/components/GovBanner/GovBanner.tsx

This file was deleted.

31 changes: 31 additions & 0 deletions src/components/banner/Banner/Banner.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import React from 'react'
import { render } from '@testing-library/react'
import { Banner } from './Banner'

describe('Banner component', () => {
it('renders properly', () => {
const { container } = render(<Banner>content</Banner>)

const section = container.querySelector('section')
const div = container.querySelector('div')

expect(section).toHaveClass('usa-banner')
expect(div).toHaveClass('usa-accordion')
expect(div).toHaveTextContent('content')
})

it('Allows custom classes to be passed in', () => {
const { container } = render(
<Banner className="section-class" divProps={{ className: 'div-class' }}>
content
</Banner>
)

const section = container.querySelector('section')
const div = container.querySelector('div')

expect(section).toHaveClass('usa-banner section-class')
expect(div).toHaveClass('usa-accordion div-class')
expect(div).toHaveTextContent('content')
})
})
26 changes: 26 additions & 0 deletions src/components/banner/Banner/Banner.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import React, { ReactElement } from 'react'
import classNames from 'classnames'

type BannerProps = {
divProps?: JSX.IntrinsicElements['div']
}

export const Banner = ({
children,
divProps,
className,
...sectionProps
}: BannerProps & JSX.IntrinsicElements['section']): ReactElement => {
const classes = classNames('usa-banner', className)

const { className: divClassName, ...remainingDivProps } = divProps || {}
const divClasses = classNames('usa-accordion', divClassName)

return (
<section className={classes} {...sectionProps}>
<div className={divClasses} {...remainingDivProps}>
{children}
</div>
</section>
)
}
44 changes: 44 additions & 0 deletions src/components/banner/BannerButton/BannerButton.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React from 'react'
import { render, screen } from '@testing-library/react'
import { BannerButton } from './BannerButton'

describe('BannerButton component', () => {
it('renders properly', () => {
render(<BannerButton isOpen={false}>Button Text</BannerButton>)

const button = screen.getByRole('button')
const buttonText = screen.getByText('Button Text')

expect(button).toHaveClass('usa-accordion__button usa-banner__button')
expect(button).toHaveAttribute('aria-expanded', 'false')
expect(buttonText).toHaveClass('usa-banner__button-text')
})

it('Allows custom classes to be passed in', () => {
render(
<BannerButton
isOpen={false}
className="button-class"
spanProps={{ className: 'span-class' }}>
Button Text
</BannerButton>
)

const button = screen.getByRole('button')
const buttonText = screen.getByText('Button Text')

expect(button).toHaveClass(
'usa-accordion__button usa-banner__button button-class'
)
expect(button).toHaveAttribute('aria-expanded', 'false')
expect(buttonText).toHaveClass('usa-banner__button-text span-class')
})

it('renders properly with "open" state', () => {
render(<BannerButton isOpen>Button Text</BannerButton>)

const button = screen.getByRole('button')

expect(button).toHaveAttribute('aria-expanded', 'true')
})
})
35 changes: 35 additions & 0 deletions src/components/banner/BannerButton/BannerButton.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React, { ReactElement } from 'react'
import classNames from 'classnames'

type BannerButtonProps = {
isOpen: boolean
spanProps?: JSX.IntrinsicElements['span']
}

export const BannerButton = ({
isOpen,
children,
className,
spanProps,
...buttonProps
}: BannerButtonProps & JSX.IntrinsicElements['button']): ReactElement => {
const classes = classNames(
'usa-accordion__button usa-banner__button',
className
)

const { className: spanClassName, ...remainingSpanProps } = spanProps || {}
const spanClasses = classNames('usa-banner__button-text', spanClassName)

return (
<button
type="button"
className={classes}
aria-expanded={isOpen}
{...buttonProps}>
<span className={spanClasses} {...remainingSpanProps}>
{children}
</span>
</button>
)
}
43 changes: 43 additions & 0 deletions src/components/banner/BannerContent/BannerContent.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import React from 'react'
import { render } from '@testing-library/react'
import { BannerContent } from './BannerContent'

describe('BannerContent Component', () => {
it('renders properly', () => {
const { container } = render(
<BannerContent isOpen={false}>content</BannerContent>
)

const bannerContent = container.querySelector('div')

expect(bannerContent).toHaveClass(
'usa-banner__content usa-accordion__content'
)
expect(bannerContent).toHaveTextContent('content')
expect(bannerContent).toHaveProperty('hidden', true)
})

it('Allows custom classes to be passed in', () => {
const { container } = render(
<BannerContent isOpen={false} className="div-class">
content
</BannerContent>
)

const bannerContent = container.querySelector('div')

expect(bannerContent).toHaveClass(
'usa-banner__content usa-accordion__content div-class'
)
expect(bannerContent).toHaveTextContent('content')
expect(bannerContent).toHaveProperty('hidden', true)
})

it('renders properly with "open" state', () => {
const { container } = render(<BannerContent isOpen>content</BannerContent>)

const bannerContent = container.querySelector('div')

expect(bannerContent).toHaveProperty('hidden', false)
})
})
Loading

0 comments on commit f75e4ba

Please sign in to comment.