UNPKG

wix-style-react

Version:
162 lines (143 loc) 4.46 kB
import React, { Children, PureComponent } from 'react'; import PropTypes from 'prop-types'; import FieldLabelAttributes from '../FieldLabelAttributes/FieldLabelAttributes'; import { DATA_HOOKS } from './constants'; import { st, classes } from './Range.st.css'; const ELEMENT_POSITION = { first: 'first', last: 'last', }; const getFocusedElementPosition = (hasFocusFirst, hasFocusLast) => { if (hasFocusFirst) { return ELEMENT_POSITION.first; } if (hasFocusLast) { return ELEMENT_POSITION.last; } }; class Range extends PureComponent { state = { hasFocusFirst: false, hasFocusLast: false, }; _doKeyDown(e) { const keys = { upArrow: 38, downArrow: 40, }; if (e.keyCode === keys.upArrow && !isNaN(e.target.value)) { e.preventDefault(); e.target.value++; } if (e.keyCode === keys.downArrow && !isNaN(e.target.value)) { e.preventDefault(); e.target.value--; } } _handleFocusFirst() { this.setState({ hasFocusFirst: true }); } _handleBlurFirst() { this.setState({ hasFocusFirst: false }); } _handleFocusLast() { this.setState({ hasFocusLast: true }); } _handleBlurLast() { this.setState({ hasFocusLast: false }); } render() { const { children, dataHook } = this.props; const { hasFocusFirst, hasFocusLast } = this.state; const childrenArr = Children.toArray(children); const rangeType = children[1].type.displayName; const label = children.length === 3 ? ( <div className={classes.label} data-hook={DATA_HOOKS.label}> {children[0]} {this.props.required || this.props.info || this.props.tooltip ? ( <FieldLabelAttributes dataHook="field-label-attributes" required={this.props.required} info={this.props.info} tooltip={this.props.tooltip} appendToParent={this.props.appendToParent} /> ) : null} </div> ) : null; const firstInput = childrenArr.length === 3 ? childrenArr[1] : childrenArr[0]; const lastInput = childrenArr.length === 3 ? childrenArr[2] : childrenArr[1]; const additionalFirstInputProps = { className: rangeType === 'DatePicker' ? classes.firstDate : classes.firstinput, noRightBorderRadius: true, onKeyDown: e => this._doKeyDown(e), onFocus: e => this._handleFocusFirst(e), onBlur: e => this._handleBlurFirst(e), ...(rangeType === 'DatePicker' && !!firstInput.props.inputProps && firstInput.props.inputProps), }; const additionalLastInputProps = { className: rangeType === 'DatePicker' ? classes.lastDate : classes.lastinput, noLeftBorderRadius: true, onKeyDown: e => this._doKeyDown(e), onFocus: e => this._handleFocusLast(e), onBlur: e => this._handleBlurLast(e), ...(rangeType === 'DatePicker' && !!lastInput.props.inputProps && lastInput.props.inputProps), }; return ( <div data-hook={dataHook} className={st(classes.root, { focusedElementPosition: getFocusedElementPosition( hasFocusFirst, hasFocusLast, ), })} > {label} <div className={classes.inputWrapper} data-hook={DATA_HOOKS.inputWrapper} > {React.cloneElement( firstInput, rangeType === 'DatePicker' ? { inputProps: additionalFirstInputProps } : additionalFirstInputProps, )} {React.cloneElement( lastInput, rangeType === 'DatePicker' ? { inputProps: additionalLastInputProps } : additionalLastInputProps, )} </div> </div> ); } } Range.displayName = 'Range'; Range.propTypes = { /** Applies a data-hook HTML attribute that can be used in the tests. */ dataHook: PropTypes.string, /** Accept any component as a child item. At the moment it is most commonly used with `<DatePicker/>` or `<Input/>`*/ children: PropTypes.any, /** @deprecated Do not use this prop */ required: PropTypes.bool, /** @deprecated Do not use this prop */ info: PropTypes.string, /** @deprecated Do not use this prop */ appendToParent: PropTypes.bool, }; Range.defaultProps = { appendToParent: false, }; export default Range;