-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #48 from MetroStar/CSG-717
CSG-717: Add USWDS List component to USWDS Comet package.
- Loading branch information
Showing
5 changed files
with
144 additions
and
0 deletions.
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
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 { default } from './list'; |
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 from 'react'; | ||
import { StoryFn, Meta } from '@storybook/react'; | ||
import { List } from '../../index'; | ||
import { ListItem, ListProps } from './list'; | ||
|
||
const meta: Meta<typeof List> = { | ||
title: 'USWDS/List', | ||
component: List, | ||
argTypes: { | ||
id: { required: true }, | ||
type: { control: 'select' }, | ||
variant: { control: 'select' }, | ||
}, | ||
}; | ||
export default meta; | ||
|
||
const Template: StoryFn<typeof List> = (args: ListProps) => <List {...args}>Button</List>; | ||
|
||
const items = [ | ||
{ id: 'item-1', value: 'Item 1' }, | ||
{ id: 'item-2', value: 'Item 2' }, | ||
{ id: 'item-3', value: 'Item 3' }, | ||
] as ListItem[]; | ||
|
||
export const Default = Template.bind({}); | ||
Default.args = { | ||
id: 'list-1', | ||
type: 'unordered', | ||
variant: 'default', | ||
items, | ||
className: '', | ||
}; |
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,39 @@ | ||
import React from 'react'; | ||
import '@testing-library/jest-dom'; | ||
import { render } from '@testing-library/react'; | ||
import List, { ListItem } from './list'; | ||
|
||
describe('List', () => { | ||
const items = [ | ||
{ id: 'item-1', value: 'Item 1' }, | ||
{ id: 'item-2', value: 'Item 2' }, | ||
{ id: 'item-3', value: 'Item 3' }, | ||
] as ListItem[]; | ||
|
||
test('should render the default component', () => { | ||
const { baseElement } = render(<List id="list-1" items={items} />); | ||
expect(baseElement.querySelector('#list-1')).toBeTruthy(); | ||
expect(baseElement.querySelector('ul')).toBeTruthy(); | ||
expect(baseElement.querySelectorAll('li')).toHaveLength(3); | ||
}); | ||
|
||
test('should render the component as ordered', () => { | ||
const { baseElement } = render(<List id="list-1" type="ordered" items={items} />); | ||
expect(baseElement.querySelector('#list-1')).toBeTruthy(); | ||
expect(baseElement.querySelector('ol')).toBeTruthy(); | ||
}); | ||
|
||
test('should render the component as unstyled', () => { | ||
const { baseElement } = render(<List id="list-1" variant="unstyled" items={items} />); | ||
expect(baseElement.querySelector('#list-1')).toBeTruthy(); | ||
expect(baseElement.querySelector('ul')).toBeTruthy(); | ||
expect(baseElement.querySelector('#list-1')).toHaveClass('usa-list--unstyled'); | ||
}); | ||
|
||
test('should render the component with custom class', () => { | ||
const { baseElement } = render(<List id="list-1" className="some-class" items={items} />); | ||
expect(baseElement.querySelector('#list-1')).toBeTruthy(); | ||
expect(baseElement.querySelector('ul')).toBeTruthy(); | ||
expect(baseElement.querySelector('#list-1')).toHaveClass('some-class'); | ||
}); | ||
}); |
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,71 @@ | ||
import React, { ReactNode } from 'react'; | ||
import classnames from 'classnames'; | ||
|
||
export interface ListItem { | ||
id: string; | ||
value: ReactNode; | ||
} | ||
|
||
export interface ListProps { | ||
/** | ||
* The unique identifier for this component | ||
*/ | ||
id: string; | ||
/** | ||
* The type of list to display | ||
*/ | ||
type?: 'ordered' | 'unordered'; | ||
/** | ||
* The style variant of list to display | ||
*/ | ||
variant?: 'default' | 'unstyled'; | ||
/** | ||
* A custom class to apply to the component | ||
*/ | ||
className?: string; | ||
/** | ||
* The list of items to display | ||
*/ | ||
items: ListItem[]; | ||
} | ||
|
||
/** | ||
* A list organizes information into discrete sequential sections. | ||
*/ | ||
export const List = ({ | ||
id, | ||
type = 'unordered', | ||
variant = 'default', | ||
className, | ||
items, | ||
...listProps | ||
}: ListProps): React.ReactElement => { | ||
const classes = classnames( | ||
'usa-list', | ||
{ | ||
'usa-list--unstyled': variant === 'unstyled', | ||
}, | ||
className, | ||
); | ||
|
||
const getChildren = (items: ListItem[]): React.ReactNode => | ||
items.map((item) => { | ||
return ( | ||
<li id={item.id} key={item.id}> | ||
{item.value} | ||
</li> | ||
); | ||
}); | ||
|
||
return type === 'unordered' ? ( | ||
<ul id={id} className={classes} {...listProps}> | ||
{getChildren(items)} | ||
</ul> | ||
) : ( | ||
<ol id={id} className={classes} {...listProps}> | ||
{getChildren(items)} | ||
</ol> | ||
); | ||
}; | ||
|
||
export default List; |