UNPKG

react-date-range-headless

Version:

A React component for choosing dates and date ranges. A fork of hypeserver/react-date-range in which the Headless UI Listbox (Select) uses instead html select and options

109 lines (90 loc) 2.71 kB
import React, { PureComponent } from 'react'; import PropTypes from 'prop-types'; import classnames from 'classnames'; import { format, parse, isValid, isEqual } from 'date-fns'; class DateInput extends PureComponent { constructor(props, context) { super(props, context); this.state = { invalid: false, changed: false, value: this.formatDate(props), }; } componentDidUpdate(prevProps) { const { value } = prevProps; if (!isEqual(value, this.props.value)) { this.setState({ value: this.formatDate(this.props) }); } } formatDate({ value, dateDisplayFormat, dateOptions }) { if (value && isValid(value)) { return format(value, dateDisplayFormat, dateOptions); } return ''; } update(value) { const { invalid, changed } = this.state; if (invalid || !changed || !value) { return; } const { onChange, dateDisplayFormat, dateOptions } = this.props; const parsed = parse(value, dateDisplayFormat, new Date(), dateOptions); if (isValid(parsed)) { this.setState({ changed: false }, () => onChange(parsed)); } else { this.setState({ invalid: true }); } } onKeyDown = e => { const { value } = this.state; if (e.key === 'Enter') { this.update(value); } }; onChange = e => { this.setState({ value: e.target.value, changed: true, invalid: false }); }; onBlur = () => { const { value } = this.state; this.update(value); }; render() { const { className, readOnly, placeholder, ariaLabel, disabled, onFocus } = this.props; const { value, invalid } = this.state; return ( <span className={classnames('rdrDateInput', className)}> <input readOnly={readOnly} disabled={disabled} value={value} placeholder={placeholder} aria-label={ariaLabel} onKeyDown={this.onKeyDown} onChange={this.onChange} onBlur={this.onBlur} onFocus={onFocus} /> {invalid && <span className="rdrWarning">&#9888;</span>} </span> ); } } DateInput.propTypes = { value: PropTypes.object, placeholder: PropTypes.string, disabled: PropTypes.bool, readOnly: PropTypes.bool, dateOptions: PropTypes.object, dateDisplayFormat: PropTypes.string, ariaLabel: PropTypes.string, className: PropTypes.string, onFocus: PropTypes.func.isRequired, onChange: PropTypes.func.isRequired, }; DateInput.defaultProps = { readOnly: true, disabled: false, dateDisplayFormat: 'MMM D, YYYY', }; export default DateInput;