UNPKG

react-jam-ui

Version:

React JAM UI components

176 lines (151 loc) 4.66 kB
import React from 'react' import classNames from 'classnames' import Input from '../Input' import './styles.styl' export default class Suggest extends React.Component { constructor(props) { super(props); this.state = { value: props.value ? props.value : '', showList: false, clickInProcess: false, focus: props.focus }; } componentWillReceiveProps(nextProps) { if (nextProps.value && (!this.state.value || nextProps.value !== this.state.value)) { this.setState({ value: nextProps.value }) } } onSuggestListMouseUp = el => { const template = this.props.inputLabel || this.props.label const str = this.parseTemplate(template, el) this.setState({ value: str, showList: false, clickInProcess: false, focus: false }); if (this.props.onSelect) this.props.onSelect(el); } onChangeCapture = e => { const value = e.target.value; this.setState({ value }); if (this.props.onChange) this.props.onChange(e); } onBlurCapture = () => { const template = this.props.inputLabel || this.props.label let value = this.state.value; const str = this.parseTemplate(template, this.props.data[0]) if ( this.props.onSelect && this.props.data.length == 1 && value && value.toLowerCase() == str.toLowerCase() ) { this.props.onSelect(this.props.data[0]); value = this.props.data[0]; } this.setState({ showList: false, focus: false }) if (this.props.onBlur && !this.state.clickInProcess) this.props.onBlur( value ) } onFocusCapture = () => { this.setState({ showList: true, focus: true }) } onSuggestListMouseDown = () => { this.setState({ clickInProcess: true }) } getObjectValueByString = (obj, path) => { return path.split('.').reduce( (prev, key) => { return prev ? prev[key] : undefined }, obj || self) } parseTemplate = (template, obj) => template.replace(/\$\{.+?\}/g, match => this.getObjectValueByString(obj, match.slice(2, -1).trim()) || match) render() { const { className, size, variant, value, onFocus, onChange, onBlur, onSelect, data, label, inputLabel, ...rest } = this.props; const classes = classNames( 'suggest', size, className, { 'suggest-default': !variant, [`suggest-${variant}`]: variant, 'value': this.state.value, 'focus': this.state.focus } ); return <div className={ classes } onBlur={ this.onBlurCapture } onFocus={ this.onFocusCapture } tabIndex='0' > <Input variant={ variant } size={ size } value={ this.state.value } onChange={ this.onChangeCapture } autoComplete='off' { ... rest } /> <div className={'suggest-list' + (data.length > 0 && this.state.showList ? '' : ' hide')}> { data.map( row => <div key={`suggest-${this.props.name}-${ this.getObjectValueByString(row, this.props.id) }`} onMouseDown={ this.onSuggestListMouseDown } onMouseUp={ () => { this.onSuggestListMouseUp(row) } } className='suggest-item' >{ this.parseTemplate(label, row) }</div>) } </div> </div> } } /** * TODO: Возможность HTML в template * TODO: Required field and validation */ /* <Suggest variant='material' name='INN' placeholder='ИНН' value={ formBasic.INN } data={ this.props.suggest } inputLabel='${data.inn}' label='${data.name.short_with_opf} (${data.inn}/${data.ogrn})' id='data.hid' onKeyUp={ this.onSuggestCompanies } onSelect={ this.onSelectSuggestCompany } onBlur={ this.onBlurSuggestCompany } mask={{ name: 'number' }} maxLength='12' /> */