@wix/design-system
Version:
@wix/design-system
161 lines • 6.28 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 === 'long') {
return dateTimeFormat.getLongDate(this._getLocale(), 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,
value: PropTypes.oneOfType([PropTypes.object, PropTypes.string]),
locale: PropTypes.oneOf(SupportedWixLocales),
dateStyle: PropTypes.oneOf(['short', 'medium', 'long']),
validate: PropTypes.bool,
onValidate: PropTypes.func,
excludePastDates: PropTypes.bool,
clearButtonTooltipContent: PropTypes.node,
clearButtonTooltipProps: PropTypes.node,
focusOnClearClick: PropTypes.bool,
};
export default DateInput;
//# sourceMappingURL=DateInput.js.map