forked from carbon-design-system/carbon
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(Search): make search buttons configurable (carbon-design-system#817
) Fixes carbon-design-system#801.
- Loading branch information
Showing
10 changed files
with
236 additions
and
70 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
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
28 changes: 28 additions & 0 deletions
28
src/components/SearchFilterButton/SearchFilterButton-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,28 @@ | ||
import React from 'react'; | ||
import Icon from '../Icon'; | ||
import SearchFilterButton from '../SearchFilterButton'; | ||
import { mount } from 'enzyme'; | ||
|
||
describe('SearchFilterButton', () => { | ||
const wrapper = mount(<SearchFilterButton labelText="testlabel" />); | ||
|
||
describe('buttons', () => { | ||
const btn = wrapper.find('button'); | ||
|
||
it('should have type="button"', () => { | ||
const type = btn.instance().getAttribute('type'); | ||
expect(type).toEqual('button'); | ||
}); | ||
|
||
it('has expected class', () => { | ||
expect(btn.hasClass('bx--search-button')).toEqual(true); | ||
}); | ||
}); | ||
|
||
describe('icons', () => { | ||
it('should use "filter--glyph" icon', () => { | ||
const icon = wrapper.find(Icon); | ||
expect(icon.props().name).toEqual('filter--glyph'); | ||
}); | ||
}); | ||
}); |
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,29 @@ | ||
import React from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import Icon from '../Icon'; | ||
|
||
/** | ||
* The filter button for `<Search>`. | ||
*/ | ||
const SearchFilterButton = ({ labelText }) => ( | ||
<button className="bx--search-button" type="button" aria-label={labelText}> | ||
<Icon | ||
name="filter--glyph" | ||
description="filter" | ||
className="bx--search-filter" | ||
/> | ||
</button> | ||
); | ||
|
||
SearchFilterButton.propTypes = { | ||
/** | ||
* The a11y label text. | ||
*/ | ||
labelText: PropTypes.string, | ||
}; | ||
|
||
SearchFilterButton.defaultProps = { | ||
labelText: 'Search', | ||
}; | ||
|
||
export default SearchFilterButton; |
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 './SearchFilterButton'; |
56 changes: 56 additions & 0 deletions
56
src/components/SearchLayoutButton/SearchLayoutButton-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,56 @@ | ||
import React from 'react'; | ||
import Icon from '../Icon'; | ||
import SearchLayoutButton from '../SearchLayoutButton'; | ||
import { mount } from 'enzyme'; | ||
|
||
describe('SearchLayoutButton', () => { | ||
const wrapper = mount(<SearchLayoutButton labelText="testlabel" />); | ||
|
||
describe('buttons', () => { | ||
const btn = wrapper.find('button'); | ||
|
||
it('should have type="button"', () => { | ||
const type = btn.instance().getAttribute('type'); | ||
expect(type).toEqual('button'); | ||
}); | ||
|
||
it('has expected class for sort button', () => { | ||
expect(btn.hasClass('bx--search-button')).toEqual(true); | ||
}); | ||
}); | ||
|
||
describe('icons', () => { | ||
it('should use "list" icon for toggle button', () => { | ||
const icon = wrapper.find(Icon); | ||
expect(icon.props().name).toEqual('list'); | ||
}); | ||
|
||
it('should use "grid" icon when format state is not "list"', () => { | ||
wrapper.setState({ format: 'not-list' }); | ||
const icon = wrapper.find(Icon); | ||
expect(icon.props().name).toEqual('grid'); | ||
}); | ||
|
||
it('should support specifying the layout via props', () => { | ||
const wrapperWithFormatProps = mount( | ||
<SearchLayoutButton format="grid" /> | ||
); | ||
expect(wrapperWithFormatProps.find(Icon).props().name).toEqual('grid'); | ||
wrapperWithFormatProps.setProps({ format: 'list' }); | ||
expect(wrapperWithFormatProps.find(Icon).props().name).toEqual('list'); | ||
}); | ||
|
||
it('should support being notified of change in layout', () => { | ||
const onChangeFormat = jest.fn(); | ||
const wrapperWithFormatProps = mount( | ||
<SearchLayoutButton format="grid" onChangeFormat={onChangeFormat} /> | ||
); | ||
wrapperWithFormatProps.find('button').simulate('click'); | ||
wrapperWithFormatProps.find('button').simulate('click'); | ||
expect(onChangeFormat.mock.calls).toEqual([ | ||
[{ format: 'list' }], | ||
[{ format: 'grid' }], | ||
]); | ||
}); | ||
}); | ||
}); |
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,84 @@ | ||
import React, { Component } from 'react'; | ||
import PropTypes from 'prop-types'; | ||
import Icon from '../Icon'; | ||
|
||
/** | ||
* The layout button for `<Search>`. | ||
*/ | ||
class SearchLayoutButton extends Component { | ||
static propTypes = { | ||
/** | ||
* The layout. | ||
*/ | ||
format: PropTypes.oneOf(['list', 'grid']), | ||
|
||
/** | ||
* The a11y label text. | ||
*/ | ||
labelText: PropTypes.string, | ||
|
||
/** | ||
* The callback called when layout switches. | ||
*/ | ||
onChangeFormat: PropTypes.func, | ||
}; | ||
|
||
static defaultProps = { | ||
labelText: 'Filter', | ||
}; | ||
|
||
state = { | ||
/** | ||
* The current layout. | ||
* @type {string} | ||
*/ | ||
format: this.props.format || 'list', | ||
}; | ||
|
||
componentWillReceiveProps({ format }) { | ||
const { format: prevFormat } = this.props; | ||
if (prevFormat !== format) { | ||
this.setState({ format: format || 'list' }); | ||
} | ||
} | ||
|
||
/** | ||
* Toggles the button state upon user-initiated event. | ||
*/ | ||
toggleLayout = () => { | ||
const format = this.state.format === 'list' ? 'grid' : 'list'; | ||
this.setState({ format }, () => { | ||
const { onChangeFormat } = this.props; | ||
if (typeof onChangeFormat === 'function') { | ||
onChangeFormat({ format }); | ||
} | ||
}); | ||
}; | ||
|
||
render() { | ||
const { labelText } = this.props; | ||
return ( | ||
<button | ||
className="bx--search-button" | ||
type="button" | ||
onClick={this.toggleLayout} | ||
aria-label={labelText}> | ||
{this.state.format === 'list' ? ( | ||
<div className="bx--search__toggle-layout__container"> | ||
<Icon name="list" description="list" className="bx--search-view" /> | ||
</div> | ||
) : ( | ||
<div className="bx--search__toggle-layout__container"> | ||
<Icon | ||
name="grid" | ||
description="toggle-layout" | ||
className="bx--search-view" | ||
/> | ||
</div> | ||
)} | ||
</button> | ||
); | ||
} | ||
} | ||
|
||
export default SearchLayoutButton; |
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 './SearchLayoutButton'; |
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