2019-08-13 16:54:29 +01:00
|
|
|
import classNames from 'classnames';
|
2019-08-09 17:06:27 +01:00
|
|
|
import Overlay from 'react-overlays/lib/Overlay';
|
|
|
|
import Icon from '../icon';
|
|
|
|
import SearchPopout from '../search_popout';
|
|
|
|
|
2019-08-13 16:54:29 +01:00
|
|
|
import './search.scss';
|
|
|
|
|
2019-08-09 17:06:27 +01:00
|
|
|
export default class Search extends PureComponent {
|
|
|
|
|
|
|
|
static contextTypes = {
|
|
|
|
router: PropTypes.object.isRequired,
|
|
|
|
};
|
|
|
|
|
|
|
|
static propTypes = {
|
|
|
|
value: PropTypes.string.isRequired,
|
|
|
|
submitted: PropTypes.bool,
|
|
|
|
onShow: PropTypes.func.isRequired,
|
|
|
|
openInRoute: PropTypes.bool,
|
2019-08-13 16:54:29 +01:00
|
|
|
placeholder: PropTypes.string.isRequired,
|
|
|
|
className: PropTypes.string,
|
|
|
|
searchTitle: PropTypes.string,
|
|
|
|
onChange: PropTypes.func.isRequired,
|
|
|
|
onKeyUp: PropTypes.func.isRequired,
|
|
|
|
handleSubmit: PropTypes.func,
|
|
|
|
withOverlay: PropTypes.bool,
|
|
|
|
handleClear: PropTypes.func.isRequired,
|
2019-08-09 17:06:27 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
state = {
|
|
|
|
expanded: false,
|
|
|
|
};
|
|
|
|
|
|
|
|
handleFocus = () => {
|
|
|
|
this.setState({ expanded: true });
|
|
|
|
this.props.onShow();
|
|
|
|
}
|
|
|
|
|
|
|
|
handleBlur = () => {
|
|
|
|
this.setState({ expanded: false });
|
|
|
|
}
|
|
|
|
|
|
|
|
render() {
|
2019-08-13 16:54:29 +01:00
|
|
|
const { value, submitted, placeholder, className, searchTitle, onKeyUp, handleClear, handleSubmit, withOverlay, onChange } = this.props;
|
2019-08-09 17:06:27 +01:00
|
|
|
const { expanded } = this.state;
|
2019-08-13 16:54:29 +01:00
|
|
|
|
2019-08-09 17:06:27 +01:00
|
|
|
const hasValue = value.length > 0 || submitted;
|
2019-08-13 16:54:29 +01:00
|
|
|
const classes = classNames('search', className);
|
|
|
|
const iconClass = hasValue ? 'active' : '';
|
2019-08-09 17:06:27 +01:00
|
|
|
|
|
|
|
return (
|
2019-08-13 16:54:29 +01:00
|
|
|
<div className={classes}>
|
2019-08-09 17:06:27 +01:00
|
|
|
<label>
|
2019-08-13 16:54:29 +01:00
|
|
|
<span className='invisible'>{placeholder}</span>
|
2019-08-09 17:06:27 +01:00
|
|
|
<input
|
|
|
|
className='search__input'
|
|
|
|
type='text'
|
2019-08-13 16:54:29 +01:00
|
|
|
placeholder={placeholder}
|
2019-08-09 17:06:27 +01:00
|
|
|
value={value}
|
2019-08-13 16:54:29 +01:00
|
|
|
onChange={onChange}
|
|
|
|
onKeyUp={onKeyUp}
|
2019-08-09 17:06:27 +01:00
|
|
|
onFocus={this.handleFocus}
|
|
|
|
onBlur={this.handleBlur}
|
|
|
|
/>
|
|
|
|
</label>
|
2019-08-13 16:54:29 +01:00
|
|
|
|
|
|
|
<div role='button' tabIndex='0' className='search__icon' onClick={handleClear}>
|
|
|
|
<Icon id='search' className={iconClass} />
|
|
|
|
<Icon id='times-circle' className={iconClass} aria-label={placeholder} />
|
2019-08-09 17:06:27 +01:00
|
|
|
</div>
|
2019-08-13 16:54:29 +01:00
|
|
|
|
|
|
|
{
|
|
|
|
withOverlay &&
|
|
|
|
<Overlay show={expanded && !hasValue} placement='bottom' target={this}>
|
|
|
|
<SearchPopout />
|
|
|
|
</Overlay>
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
(searchTitle && handleSubmit) &&
|
|
|
|
<Button onClick={handleSubmit}>{intl.formatMessage(messages.searchTitle)}</Button>
|
|
|
|
}
|
|
|
|
|
2019-08-09 17:06:27 +01:00
|
|
|
</div>
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|