wix-style-react
Version:
wix-style-react
166 lines • 6.64 kB
JavaScript
import React from 'react';
import PropTypes from 'prop-types';
import { Date as CalendarIcon } from '@wix/wix-ui-icons-common';
import { dateTimeFormat, SupportedWixLocales, } from 'wix-design-systems-locale-utils';
import Input from '../../Input';
import { WixStyleReactEnvironmentContext } from '../../WixStyleReactEnvironmentProvider/context';
import { parseStrictInputValue, parseDate } from './utils';
import { dataHooks } from './constants';
class DateInput extends React.PureComponent {
constructor(props) {
super(props);
this._getFormattedDate = value => {
const { dateStyle } = this.props;
if (!value) {
return '';
}
if (typeof value === 'string') {
return value;
}
if (dateStyle === 'medium') {
return dateTimeFormat.getMediumDate(this._getLocale(), value);
}
return dateTimeFormat.getShortDate(this._getLocale(), value);
};
this._handleBlur = () => {
const date = parseStrictInputValue(this.state.inputValue, this.props.dateStyle, this._getLocale());
if (date.parsedDate) {
this.setState({
inputValue: this._getFormattedDate(date.parsedDate),
});
}
if (this.props.validate || this.props.onValidate) {
this._handleValidation(date);
}
if (this.props.onBlur) {
this.props.onBlur();
}
};
this._handleChange = event => {
this.setState({
inputValue: event.target.value,
});
const date = parseDate(event.target.value, this.props.dateStyle, this._getLocale());
if (date) {
if (this.props.onChange) {
this.props.onChange({ dateVal: date });
}
}
};
this._handleValidation = date => {
let validationType = 'valid';
if (!date.parsedDate) {
validationType = 'formatError';
this.setState({
validationType,
statusMessage: `Invalid date. Please match "${date.dateFormat}" format`,
});
}
else if (this.props.excludePastDates &&
date.parsedDate &&
date.parsedDate.setHours(0, 0, 0, 0) < new Date().setHours(0, 0, 0, 0)) {
validationType = 'outOfBoundsError';
this.setState({
validationType,
statusMessage: 'Only today and future dates are allowed',
});
}
else {
this.setState({
validationType,
statusMessage: undefined,
});
}
if (this.props.onValidate) {
this.props.onValidate({
validationType,
format: validationType !== 'valid' ? date.dateFormat : undefined,
value: this.state.inputValue,
});
}
};
this._handleClear = event => {
this.setState({ inputValue: '' });
if (this.props.onClear) {
this.props.onClear(event);
}
};
this._handleKeyDown = event => {
const date = parseDate(this.state.inputValue, this.props.dateStyle, this._getLocale());
this.props.onKeyDown(event, date);
};
this.state = {
validationType: 'valid',
inputValue: '',
statusMessage: undefined,
};
}
componentDidMount() {
this.setState({
inputValue: this._getFormattedDate(this.props.value),
});
}
componentDidUpdate(prevProps) {
if (prevProps.value !== this.props.value) {
this.setState({
inputValue: this._getFormattedDate(this.props.value),
});
if (this.state.validationType !== 'valid') {
this.setState({
validationType: 'valid',
statusMessage: undefined,
});
}
}
}
_getLocale() {
return this.props.locale || this.context.locale || 'en';
}
render() {
const { customInput, focusOnClearClick, onChange, status, statusMessage, validate, ...rest } = this.props;
const inputProps = {
focusOnClearClick: !!focusOnClearClick,
autoSelect: false,
prefix: (React.createElement(Input.IconAffix, { dataHook: dataHooks.icon },
React.createElement(CalendarIcon, null))),
status: validate && this.state.validationType !== 'valid' && !status
? 'error'
: status,
statusMessage: validate && !statusMessage ? this.state.statusMessage : statusMessage,
...rest,
value: this.state.inputValue,
onBlur: this._handleBlur,
onChange: this._handleChange,
onClear: this.props.onClear ? this._handleClear : undefined,
onKeyDown: this._handleKeyDown,
ariaLabel: this.state.inputValue || this.props.placeholder,
...(customInput ? customInput.props : {}),
};
return React.cloneElement(customInput || React.createElement(Input, null), inputProps);
}
}
DateInput.displayName = 'DateInput';
DateInput.contextType = WixStyleReactEnvironmentContext;
DateInput.propTypes = {
...Input.propTypes,
/** The selected date */
value: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
/** Instance locale */
locale: PropTypes.oneOf(SupportedWixLocales),
/** Sets date format of locale */
dateStyle: PropTypes.oneOf(['short', 'medium']),
/** Specifies whether to validate the input */
validate: PropTypes.bool,
/** Defines a callback function which is called on cases when date is validated. */
onValidate: PropTypes.func,
/** Specifies whether past dates should show validation error. Validate prop must be true to use this feature */
excludePastDates: PropTypes.bool,
/** When provided, hover will display a tooltip over clear button */
clearButtonTooltipContent: PropTypes.node,
/** Tooltip props for clear buttons */
clearButtonTooltipProps: PropTypes.node,
/** Specifies whether focus input after clear click */
focusOnClearClick: PropTypes.bool,
};
export default DateInput;
//# sourceMappingURL=DateInput.js.map