Repository URL to install this package:
|
Version:
7.11.3 ▾
|
import React, { Component } from 'react';
import Autocomplete from 'react-autocomplete';
import { renderToStaticMarkup } from 'react-dom/server';
import PropTypes from 'prop-types';
import Back from '../../../components/visuals/Icon/svg/ic_arrow_back.svg';
import Cancel from '../../../components/visuals/Icon/svg/ic_cancel.svg';
import ArrowDown from '../../../components/visuals/Icon/svg/ic_keyboard_arrow_down-grey.svg';
import Icon from '../../visuals/Icon/Icon';
import InputFeedback from '../Input/InputFeedback';
class AutoSelect extends Component {
static propTypes = {
items: PropTypes.arrayOf(
PropTypes.shape({
id: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
key: PropTypes.string,
})
).isRequired,
value: PropTypes.any,
errorMessage: PropTypes.string,
valid: PropTypes.bool,
label: PropTypes.any,
placeholder: PropTypes.string,
onCancel: PropTypes.func,
onClear: PropTypes.func,
menuTop: PropTypes.bool,
};
static defaultProps = {
errorMessage: '',
valid: true,
label: null,
value: null,
placeholder: '',
onCancel: () => {},
onClear: () => {},
menuTop: false,
};
constructor(props) {
super(props);
this.state = {
open: false,
};
this.selectRef = null;
}
componentDidUpdate() {
const $menu = this.selectRef.querySelector('.Autocomplete-menu');
const smallDevices = window.outerWidth < 826;
if (this.props.menuTop && this.state.open && $menu) {
const { height: menuHeight } = $menu.getBoundingClientRect();
$menu.style.top = smallDevices ? '' : `-${menuHeight + 6}px`;
}
}
changeMenuVisibility(open) {
const smallDevices = window.outerWidth < 826;
this.setState({ open });
if (smallDevices) {
window.scrollTo(0, 0);
}
}
clear() {
this.props.onClear();
}
cancel() {
this.props.onCancel();
this.input.blur();
}
render() {
const { items, placeholder, label, valid, errorMessage, ...rest } = this.props;
const { open } = this.state;
const svgString = encodeURIComponent(renderToStaticMarkup(<ArrowDown />));
const correctIconUrl = `url("data:image/svg+xml,${svgString}")`;
return (
<div className={open ? 'Autocomplete Autocomplete--open' : 'Autocomplete Autocomplete--close'}>
{label && <div className="Input-label">{label}</div>}
{open && <Icon icon={Back} className="Autocomplete-mobileIcon Autocomplete-backIcon" />}
<Autocomplete
ref={el => {
this.input = el;
}}
className="Input-field"
inputProps={{
placeholder,
className: open ? 'Autocomplete-input Input-field' : 'Button Button--white',
style: { backgroundImage: correctIconUrl },
}}
getItemValue={item => item.label}
items={items}
shouldItemRender={(item, value) => item.label.toLowerCase().indexOf(value.toLowerCase()) > -1}
renderItem={(item, isHighlighted) => (
<div
key={item.key || item.id}
style={{
background: isHighlighted ? '#e2f1f9' : 'white',
padding: '16px 24px',
borderRadius: '0px',
minHeight: '44px',
width: '100%',
}}
>
{item.label}
</div>
)}
onMenuVisibilityChange={o => this.changeMenuVisibility(o)}
renderMenu={menuItems => (
<div style={{}} className="Autocomplete-menu">
{menuItems}
</div>
)}
wrapperProps={{
ref: ref => {
this.selectRef = ref;
},
className: valid ? 'Autocomplete-wrapper' : 'Autocomplete-wrapper Autocomplete-wrapper--invalid',
}}
{...rest}
/>
<Icon
icon={Cancel}
className="Autocomplete-mobileIcon Autocomplete-closeIcon"
onMouseDown={e => e.preventDefault()}
onClick={() => this.clear()}
/>
{!valid && <InputFeedback type="error">{errorMessage}</InputFeedback>}
</div>
);
}
}
export default AutoSelect;