Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Extract chip component for better reusability (#5065)
* Extract MultiAutoComplete.Item to separate Chip component for better reusability * Add onClick handler to chip * Only show delete icon when onDelete callback is set * Fix phpstan error * Add additional test for clickable Chip item
- Loading branch information
Showing
15 changed files
with
244 additions
and
138 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
56 changes: 56 additions & 0 deletions
56
src/Sulu/Bundle/AdminBundle/Resources/js/components/Chip/Chip.js
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,56 @@ | ||
// @flow | ||
import React from 'react'; | ||
import classNames from 'classnames'; | ||
import Icon from '../../components/Icon'; | ||
import chipStyles from './chip.scss'; | ||
|
||
type Props<T> = {| | ||
children: string, | ||
disabled: boolean, | ||
onClick?: (value: T) => void, | ||
onDelete?: (value: T) => void, | ||
value: T, | ||
|}; | ||
|
||
export default class Chip<T> extends React.Component<Props<T>> { | ||
static defaultProps = { | ||
disabled: false, | ||
}; | ||
|
||
handleClick = () => { | ||
const {onClick, value} = this.props; | ||
|
||
if (onClick) { | ||
onClick(value); | ||
} | ||
}; | ||
|
||
handleDelete = () => { | ||
const {onDelete, value} = this.props; | ||
|
||
if (onDelete) { | ||
onDelete(value); | ||
} | ||
}; | ||
|
||
render() { | ||
const {children, disabled, onClick, onDelete} = this.props; | ||
|
||
const chipClass = classNames( | ||
chipStyles.chip, | ||
{ | ||
[chipStyles.disabled]: disabled, | ||
[chipStyles.clickable]: !!onClick, | ||
} | ||
); | ||
|
||
return ( | ||
<button className={chipClass} onClick={this.handleClick}> | ||
{children} | ||
{!disabled && onDelete && | ||
<Icon className={chipStyles.icon} name="su-times" onClick={this.handleDelete} /> | ||
} | ||
</button> | ||
); | ||
} | ||
} |
44 changes: 44 additions & 0 deletions
44
src/Sulu/Bundle/AdminBundle/Resources/js/components/Chip/README.md
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,44 @@ | ||
Chips are compact elements that represent an attribute in its used context. It can e.g. be used to display tags in a tag | ||
selection or can indicate that a list is filtered. | ||
|
||
```javascript | ||
<div style={{backgroundColor: 'white', padding: '10px'}}> | ||
<Chip>Tag 1</Chip> | ||
</div> | ||
``` | ||
|
||
Chips can also be displayed in a disabled state: | ||
|
||
```javascript | ||
<div style={{backgroundColor: 'white', padding: '10px'}}> | ||
<Chip disabled={true}>Tag 2</Chip> | ||
</div> | ||
``` | ||
|
||
Chips can also be clicked, which will trigger the optional `onClick` callback: | ||
|
||
```javascript | ||
const handleClick = (value) => { | ||
alert('Clicked the chip with the value ' + value); | ||
}; | ||
|
||
<div style={{backgroundColor: 'white', padding: '10px'}}> | ||
<Chip onClick={handleClick} value={7}>Click me!</Chip> | ||
</div> | ||
``` | ||
|
||
They also accept a `onDelete` callback, which will render an `Icon` the user can click: | ||
|
||
```javascript | ||
const handleClick = (value) => { | ||
alert('Clicked the chip with the value ' + value); | ||
}; | ||
|
||
const handleDelete = (value) => { | ||
alert('Delete the chip with the value ' + value); | ||
}; | ||
|
||
<div style={{backgroundColor: 'white', padding: '10px'}}> | ||
<Chip onClick={handleClick} onDelete={handleDelete} value={9}>Remove me!</Chip> | ||
</div> | ||
``` |
30 changes: 30 additions & 0 deletions
30
src/Sulu/Bundle/AdminBundle/Resources/js/components/Chip/chip.scss
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,30 @@ | ||
@import '../../containers/Application/colors.scss'; | ||
|
||
$chipBackgroundColor: $wildSand; | ||
$chipDisabledBackgroundColor: $silver; | ||
|
||
.chip { | ||
background-color: $chipBackgroundColor; | ||
border: none; | ||
border-radius: 3px; | ||
display: inline-block; | ||
font-size: 12px; | ||
line-height: 18px; | ||
height: 18px; | ||
margin: 5px 10px 5px 0; | ||
padding: 0 10px; | ||
position: relative; | ||
white-space: nowrap; | ||
|
||
.icon { | ||
margin-left: 10px; | ||
} | ||
} | ||
|
||
.clickable { | ||
cursor: pointer; | ||
} | ||
|
||
.disabled { | ||
background-color: $chipDisabledBackgroundColor; | ||
} |
4 changes: 4 additions & 0 deletions
4
src/Sulu/Bundle/AdminBundle/Resources/js/components/Chip/index.js
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,4 @@ | ||
// @flow | ||
import Chip from './Chip'; | ||
|
||
export default Chip; |
40 changes: 40 additions & 0 deletions
40
src/Sulu/Bundle/AdminBundle/Resources/js/components/Chip/tests/Chip.test.js
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,40 @@ | ||
// @flow | ||
import React from 'react'; | ||
import {render, shallow} from 'enzyme'; | ||
import Chip from '../Chip'; | ||
|
||
test('Should render item with children', () => { | ||
expect(render(<Chip value={{}}>Name</Chip>)).toMatchSnapshot(); | ||
}); | ||
|
||
test('Should render item with delete icon', () => { | ||
expect(render(<Chip onDelete={jest.fn()} value={{}}>Name</Chip>)).toMatchSnapshot(); | ||
}); | ||
|
||
test('Should render item without delete icon in disabled state', () => { | ||
expect(render(<Chip disabled={true} onDelete={jest.fn()} value={{}}>Name</Chip>)).toMatchSnapshot(); | ||
}); | ||
|
||
test('Should render item as clickable', () => { | ||
expect(render(<Chip onClick={jest.fn()} value={{}}>Name</Chip>)).toMatchSnapshot(); | ||
}); | ||
|
||
test('Should call onClick callback when the button is clicked', () => { | ||
const clickSpy = jest.fn(); | ||
const value = {name: 'Test'}; | ||
const item = shallow(<Chip onClick={clickSpy} onDelete={jest.fn()} value={value}>Test</Chip>); | ||
|
||
item.find('button').simulate('click'); | ||
|
||
expect(clickSpy).toBeCalledWith(value); | ||
}); | ||
|
||
test('Should call onDelete callback when the times icon is clicked', () => { | ||
const deleteSpy = jest.fn(); | ||
const value = {name: 'Test'}; | ||
const item = shallow(<Chip onDelete={deleteSpy} value={value}>Test</Chip>); | ||
|
||
item.find('Icon').simulate('click'); | ||
|
||
expect(deleteSpy).toBeCalledWith(value); | ||
}); |
39 changes: 39 additions & 0 deletions
39
...ulu/Bundle/AdminBundle/Resources/js/components/Chip/tests/__snapshots__/Chip.test.js.snap
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 @@ | ||
// Jest Snapshot v1, https://goo.gl/fbAQLP | ||
|
||
exports[`Should render item as clickable 1`] = ` | ||
<button | ||
class="chip clickable" | ||
> | ||
Name | ||
</button> | ||
`; | ||
|
||
exports[`Should render item with children 1`] = ` | ||
<button | ||
class="chip" | ||
> | ||
Name | ||
</button> | ||
`; | ||
|
||
exports[`Should render item with delete icon 1`] = ` | ||
<button | ||
class="chip" | ||
> | ||
Name | ||
<span | ||
aria-label="su-times" | ||
class="su-times clickable icon" | ||
role="button" | ||
tabindex="0" | ||
/> | ||
</button> | ||
`; | ||
|
||
exports[`Should render item without delete icon in disabled state 1`] = ` | ||
<button | ||
class="chip disabled" | ||
> | ||
Name | ||
</button> | ||
`; |
41 changes: 0 additions & 41 deletions
41
src/Sulu/Bundle/AdminBundle/Resources/js/components/MultiAutoComplete/Item.js
This file was deleted.
Oops, something went wrong.
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
23 changes: 0 additions & 23 deletions
23
src/Sulu/Bundle/AdminBundle/Resources/js/components/MultiAutoComplete/item.scss
This file was deleted.
Oops, something went wrong.
22 changes: 0 additions & 22 deletions
22
src/Sulu/Bundle/AdminBundle/Resources/js/components/MultiAutoComplete/tests/Item.test.js
This file was deleted.
Oops, something went wrong.
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
23 changes: 0 additions & 23 deletions
23
...minBundle/Resources/js/components/MultiAutoComplete/tests/__snapshots__/Item.test.js.snap
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.