From 6fe1030dc67225f41932bbe570b448fcfa63ba73 Mon Sep 17 00:00:00 2001 From: Hana Worku Date: Wed, 29 Jul 2020 12:49:38 -0500 Subject: [PATCH 1/5] Add component and stories --- .../ButtonGroup/ButtonGroup.stories.tsx | 37 +++++++++++++++++++ src/components/ButtonGroup/ButtonGroup.tsx | 33 +++++++++++++++++ 2 files changed, 70 insertions(+) create mode 100644 src/components/ButtonGroup/ButtonGroup.stories.tsx create mode 100644 src/components/ButtonGroup/ButtonGroup.tsx diff --git a/src/components/ButtonGroup/ButtonGroup.stories.tsx b/src/components/ButtonGroup/ButtonGroup.stories.tsx new file mode 100644 index 0000000000..68769c40c6 --- /dev/null +++ b/src/components/ButtonGroup/ButtonGroup.stories.tsx @@ -0,0 +1,37 @@ +import React from 'react' +import { ButtonGroup } from './ButtonGroup' +import { Button } from '../Button/Button' +import { Link } from '../Link/Link' + +export default { + title: 'ButtonGroup', + component: ButtonGroup, + parameters: { + info: ` +USWDS 2.0 ButtonGroup component + +Source: https://designsystem.digital.gov/components/form-controls/ +`, + }, +} + +export const Default = (): React.ReactElement => ( + + + Back + + + +) + +export const Segmented = (): React.ReactElement => ( + + + + + +) diff --git a/src/components/ButtonGroup/ButtonGroup.tsx b/src/components/ButtonGroup/ButtonGroup.tsx new file mode 100644 index 0000000000..bb3ad945e6 --- /dev/null +++ b/src/components/ButtonGroup/ButtonGroup.tsx @@ -0,0 +1,33 @@ +import React from 'react' +import classnames from 'classnames' + +// Types +type ButtonGroupProps = { + children: React.ReactNode + className?: string + type?: 'default' | 'segmented' +} & JSX.IntrinsicElements['ul'] + +export function ButtonGroup( + props: ButtonGroupProps +): React.ReactElement { + const { className, children, type = 'default', ...restProps } = props + + const classes = classnames( + ' usa-button-group', + { + 'usa-button-group--segmented': type == 'segmented', + }, + className + ) + + return ( + + ) +} + +export default ButtonGroup From deddfa4ebfce8212981505a5c851d9ddd651eaa8 Mon Sep 17 00:00:00 2001 From: Hana Worku Date: Thu, 30 Jul 2020 11:29:02 -0500 Subject: [PATCH 2/5] wip --- .../ButtonGroup/ButtonGroup.test.tsx | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/components/ButtonGroup/ButtonGroup.test.tsx diff --git a/src/components/ButtonGroup/ButtonGroup.test.tsx b/src/components/ButtonGroup/ButtonGroup.test.tsx new file mode 100644 index 0000000000..b50c74d382 --- /dev/null +++ b/src/components/ButtonGroup/ButtonGroup.test.tsx @@ -0,0 +1,20 @@ +import React from 'react' +import { render } from '@testing-library/react' + +import { ButtonGroup } from './ButtonGroup' + +describe('ButtonGroup component', () => { + it('renders without errors', () => { + const { queryByTestId } = render( + + + + ) + expect(queryByTestId('buttonGroup')).toBeInTheDocument() + }) + + it('renders its children', () => { + const { queryByText } = render(My Text Input) + expect(queryByText('My Text Input')).toBeInTheDocument() + }) +}) From e40d026df6ec47fb0ff4a35eb9960ec43199e58b Mon Sep 17 00:00:00 2001 From: Hana Worku Date: Tue, 4 Aug 2020 15:14:54 -0500 Subject: [PATCH 3/5] Add tests Co-authored-by: NLT --- .../ButtonGroup/ButtonGroup.test.tsx | 50 +++++++++++++++++-- src/components/ButtonGroup/ButtonGroup.tsx | 4 +- 2 files changed, 48 insertions(+), 6 deletions(-) diff --git a/src/components/ButtonGroup/ButtonGroup.test.tsx b/src/components/ButtonGroup/ButtonGroup.test.tsx index b50c74d382..f84d7fb4b6 100644 --- a/src/components/ButtonGroup/ButtonGroup.test.tsx +++ b/src/components/ButtonGroup/ButtonGroup.test.tsx @@ -5,16 +5,58 @@ import { ButtonGroup } from './ButtonGroup' describe('ButtonGroup component', () => { it('renders without errors', () => { - const { queryByTestId } = render( + const { getByRole } = render( ) - expect(queryByTestId('buttonGroup')).toBeInTheDocument() + expect(getByRole('list')).toBeInTheDocument() + }) + + it('displays with expected styles', () => { + const { getByRole } = render( + + + + ) + expect(getByRole('list')).toHaveClass('usa-button-group') }) it('renders its children', () => { - const { queryByText } = render(My Text Input) - expect(queryByText('My Text Input')).toBeInTheDocument() + const { getByText } = render(My Text Input) + expect(getByText('My Text Input')).toBeInTheDocument() + }) + + it('handles type prop - default', () => { + const { getByRole } = render( + A child + ) + expect(getByRole('list')).not.toHaveClass('usa-button-group--segmented') + }) + + it('handles type prop - segmented', () => { + const { getByRole } = render( + A child + ) + expect(getByRole('list')).toHaveClass('usa-button-group--segmented') + }) + + it('displays list elements with expected styles', () => { + const { getByRole } = render(A child) + expect(getByRole('listitem')).toBeInTheDocument() + expect(getByRole('listitem')).toHaveClass('usa-button-group__item') + }) + + it('renders a list item wrapping each child', () => { + const { getAllByRole } = render( + +

first child

+

second child

+
+ ) + const listItems = getAllByRole('listitem') + expect(listItems[0]).toHaveTextContent('first child') + expect(listItems[1]).toHaveTextContent('second child') + expect(listItems.length).toBe(2) }) }) diff --git a/src/components/ButtonGroup/ButtonGroup.tsx b/src/components/ButtonGroup/ButtonGroup.tsx index bb3ad945e6..6bcad4d593 100644 --- a/src/components/ButtonGroup/ButtonGroup.tsx +++ b/src/components/ButtonGroup/ButtonGroup.tsx @@ -14,7 +14,7 @@ export function ButtonGroup( const { className, children, type = 'default', ...restProps } = props const classes = classnames( - ' usa-button-group', + 'usa-button-group', { 'usa-button-group--segmented': type == 'segmented', }, @@ -22,7 +22,7 @@ export function ButtonGroup( ) return ( -
    +
      {React.Children.map(children, (child: React.ReactNode) => { return
    • {child}
    • })} From 7a68b513f9ac0d5bf3236297612862c0e7e59d35 Mon Sep 17 00:00:00 2001 From: Hana Worku Date: Tue, 4 Aug 2020 15:17:41 -0500 Subject: [PATCH 4/5] Cleanup --- src/components/ButtonGroup/ButtonGroup.stories.tsx | 4 ++-- src/components/ButtonGroup/ButtonGroup.test.tsx | 10 +++++----- src/components/ButtonGroup/ButtonGroup.tsx | 5 +---- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/src/components/ButtonGroup/ButtonGroup.stories.tsx b/src/components/ButtonGroup/ButtonGroup.stories.tsx index 68769c40c6..a07a5aaae3 100644 --- a/src/components/ButtonGroup/ButtonGroup.stories.tsx +++ b/src/components/ButtonGroup/ButtonGroup.stories.tsx @@ -10,13 +10,13 @@ export default { info: ` USWDS 2.0 ButtonGroup component -Source: https://designsystem.digital.gov/components/form-controls/ +Source: https://designsystem.digital.gov/components/button-groups/ `, }, } export const Default = (): React.ReactElement => ( - + Back diff --git a/src/components/ButtonGroup/ButtonGroup.test.tsx b/src/components/ButtonGroup/ButtonGroup.test.tsx index f84d7fb4b6..491c70c793 100644 --- a/src/components/ButtonGroup/ButtonGroup.test.tsx +++ b/src/components/ButtonGroup/ButtonGroup.test.tsx @@ -13,6 +13,11 @@ describe('ButtonGroup component', () => { expect(getByRole('list')).toBeInTheDocument() }) + it('renders its children', () => { + const { getByText } = render(My Text Input) + expect(getByText('My Text Input')).toBeInTheDocument() + }) + it('displays with expected styles', () => { const { getByRole } = render( @@ -22,11 +27,6 @@ describe('ButtonGroup component', () => { expect(getByRole('list')).toHaveClass('usa-button-group') }) - it('renders its children', () => { - const { getByText } = render(My Text Input) - expect(getByText('My Text Input')).toBeInTheDocument() - }) - it('handles type prop - default', () => { const { getByRole } = render( A child diff --git a/src/components/ButtonGroup/ButtonGroup.tsx b/src/components/ButtonGroup/ButtonGroup.tsx index 6bcad4d593..e2867f6cea 100644 --- a/src/components/ButtonGroup/ButtonGroup.tsx +++ b/src/components/ButtonGroup/ButtonGroup.tsx @@ -1,16 +1,13 @@ import React from 'react' import classnames from 'classnames' -// Types type ButtonGroupProps = { children: React.ReactNode className?: string type?: 'default' | 'segmented' } & JSX.IntrinsicElements['ul'] -export function ButtonGroup( - props: ButtonGroupProps -): React.ReactElement { +export const ButtonGroup = (props: ButtonGroupProps): React.ReactElement => { const { className, children, type = 'default', ...restProps } = props const classes = classnames( From aef4b02c6e470a18072cafa442259967c4f98fc8 Mon Sep 17 00:00:00 2001 From: Hana Worku Date: Tue, 4 Aug 2020 15:25:37 -0500 Subject: [PATCH 5/5] Export component --- src/index.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/index.ts b/src/index.ts index 138487d77d..b68bb9214b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -6,6 +6,7 @@ export { Alert } from './components/Alert/Alert' export { Accordion } from './components/Accordion/Accordion' export { GovBanner } from './components/GovBanner/GovBanner' export { Button } from './components/Button/Button' +export { ButtonGroup } from './components/ButtonGroup/ButtonGroup' export { Link } from './components/Link/Link' export { Table } from './components/Table/Table' export { Tag } from './components/Tag/Tag'