UNPKG

@talend/react-components

Version:
260 lines (255 loc) 9.98 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _react = require("react"); var _isSameSecond = require("date-fns/isSameSecond"); var _propTypes = _interopRequireDefault(require("prop-types")); var _constants = require("../constants"); var _Context = require("../Context"); var _dateExtraction = require("../date-extraction"); var _jsxRuntime = require("react/jsx-runtime"); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; } function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == typeof i ? i : i + ""; } function _toPrimitive(t, r) { if ("object" != typeof t || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != typeof i) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); } class ContextualManager extends _react.Component { constructor(props) { super(props); (0, _dateExtraction.checkSupportedDateFormat)(props.dateFormat); this.inputErrorId = `${props.id}-input-error`; this.hoursErrorId = `${props.id}-hours-error`; this.minutesErrorId = `${props.id}-minutes-error`; this.secondsErrorId = `${props.id}-seconds-error`; this.initialState = (0, _dateExtraction.extractParts)(props.selectedDateTime, this.getDateOptions()); this.state = { ...this.initialState, previousErrors: [] }; this.onInputFocus = this.onInputFocus.bind(this); this.hasError = this.hasError.bind(this); this.onReset = this.onReset.bind(this); this.onSubmit = this.onSubmit.bind(this); this.onInputChange = this.onInputChange.bind(this); this.onPickerChange = this.onPickerChange.bind(this); } componentDidUpdate(prevProps, prevState) { const newSelectedDateTime = this.props.selectedDateTime; const needDateTimeStateUpdate = newSelectedDateTime !== prevProps.selectedDateTime && // selectedDateTime props updated newSelectedDateTime !== prevState.datetime && // not the same ref as state date time !(0, _isSameSecond.isSameSecond)(newSelectedDateTime, prevState.datetime); // not the same value as state if (prevProps.dateFormat !== this.props.dateFormat) { (0, _dateExtraction.checkSupportedDateFormat)(this.props.dateFormat); } if (needDateTimeStateUpdate) { const dateRelatedPartState = (0, _dateExtraction.extractParts)(newSelectedDateTime, this.getDateOptions()); this.setState(dateRelatedPartState); } } onChange(event, origin) { if (!this.props.onChange) { return; } const { errorMessage, datetime, textInput, errors } = this.state; // we need to update the initial state once it has been changed this.initialState = { ...this.state }; this.props.onChange(event, { errors, errorMessage, datetime, textInput, origin }); } onInputChange(event) { const textInput = event.target.value; const nextState = (0, _dateExtraction.extractPartsFromTextInput)(textInput, this.getDateOptions()); this.setState(oldState => ({ previousErrors: oldState.errors, ...nextState }), () => { if (!this.props.formMode) { this.onChange(event, 'INPUT'); } }); } onPickerChange(event, { date, time, field }) { const nextState = (0, _dateExtraction.extractPartsFromDateAndTime)(date, time, this.getDateOptions()); const isTimeUpdate = [_constants.FIELD_HOURS, _constants.FIELD_MINUTES, _constants.FIELD_SECONDS].includes(field); const isTimeEmpty = !nextState.time.hours && !nextState.time.minutes && !nextState.time.seconds; const isHybridMode = this.getDateOptions().hybridMode; // we need to retrieve the input error from nextState to add them to the current one // because, by changing the picker, we update the textInput so we need to update its errors let nextErrors = this.state.errors // remove old main input errors .filter(error => !_constants.INPUT_ERRORS.includes(error.code)) // add new main input errors .concat(nextState.errors.filter(error => _constants.INPUT_ERRORS.includes(error.code))); if (isTimeUpdate) { if (isHybridMode && isTimeEmpty) { nextErrors = nextErrors.filter(error => !_constants.HOUR_ERRORS.includes(error.code) && !_constants.MINUTES_ERRORS.includes(error.code) && !_constants.SECONDS_ERRORS.includes(error.code)); } else { // to avoid having errors on untouched time elements, we check only the updated part let newError; switch (field) { case _constants.FIELD_HOURS: newError = (0, _dateExtraction.checkHours)(time.hours, this.getDateOptions().hybridMode); break; case _constants.FIELD_MINUTES: newError = (0, _dateExtraction.checkMinutes)(time.minutes, this.getDateOptions().hybridMode); break; case _constants.FIELD_SECONDS: newError = (0, _dateExtraction.checkSeconds)(time.seconds, this.getDateOptions().hybridMode); break; default: break; } // remove old error on updated time part nextErrors = nextErrors.filter(error => field === _constants.FIELD_HOURS && !_constants.HOUR_ERRORS.includes(error.code) || field === _constants.FIELD_MINUTES && !_constants.MINUTES_ERRORS.includes(error.code) || field === _constants.FIELD_SECONDS && !_constants.SECONDS_ERRORS.includes(error.code)); // add the new error on updated time part if (newError) { nextErrors.push(newError); } } } this.setState({ previousErrors: this.state.errors, ...nextState, errors: nextErrors }, () => { if (!this.props.formMode) { this.onChange(event, 'PICKER'); } }); } onSubmit(event, origin) { event.preventDefault(); // validation // to avoid having error message change on invalid elements, // we don't replace the error on those elements let errors = (0, _dateExtraction.check)(this.state.date, this.state.time, this.getDateOptions()); errors = this.state.errors.filter(({ code }) => !errors.find(error => error.code === code)).concat(errors); this.setState({ errors, errorMessage: errors[0] ? errors[0].message : '' }, () => { if (!errors.length) { this.onChange(event, origin); } }); } onInputFocus(event, focusedId) { this.setState({ focusedInput: focusedId }); } onReset() { // in form mode user has to explicitly validate the persist the selected date // Otherwise, on picker close, the date is reset to the previous value if (this.props.formMode) { this.setState({ ...this.initialState }); } } getDateOptions() { return { dateFormat: this.props.dateFormat, useTime: this.props.useTime, useSeconds: this.props.useSeconds, useUTC: this.props.useUTC, required: this.props.required, hybridMode: this.props.hybridMode }; } hasError(errorCodes) { // no error management in component when not in formMode if (!this.props.formMode) { return false; } const errorCodesArray = Array.isArray(errorCodes) ? errorCodes : [errorCodes]; return !!this.state.errors.find(stateError => errorCodesArray.indexOf(stateError.code) > -1); } render() { return /*#__PURE__*/(0, _jsxRuntime.jsx)(_Context.DateTimeContext.Provider, { value: { datetime: { textInput: this.state.textInput, date: this.state.date, time: this.state.time }, errorManagement: { onInputFocus: this.onInputFocus, focusedInput: this.state.focusedInput, errors: this.state.errors, hasError: this.hasError, formMode: this.props.formMode, inputErrorId: this.inputErrorId, hoursErrorId: this.hoursErrorId, minutesErrorId: this.minutesErrorId, secondsErrorId: this.secondsErrorId }, inputManagement: { inputRef: ref => { this.inputRef = ref; }, onChange: this.onInputChange, placeholder: (0, _dateExtraction.getFullDateFormat)(this.getDateOptions()) }, pickerManagement: { onSubmit: this.onPickerChange, useTime: this.props.useTime, useSeconds: this.props.useSeconds, useUTC: this.props.useUTC }, formManagement: { onReset: this.onReset, onSubmit: this.onSubmit } }, children: this.props.children }); } } _defineProperty(ContextualManager, "displayName", 'DateTime.Manager'); _defineProperty(ContextualManager, "propTypes", { children: _propTypes.default.node, dateFormat: _propTypes.default.string, formMode: _propTypes.default.bool, id: _propTypes.default.string.isRequired, onChange: _propTypes.default.func, hybridMode: _propTypes.default.bool, required: _propTypes.default.bool, selectedDateTime: _propTypes.default.oneOfType([_propTypes.default.instanceOf(Date), _propTypes.default.number, _propTypes.default.string]), useSeconds: _propTypes.default.bool, useTime: _propTypes.default.bool, useUTC: _propTypes.default.bool }); _defineProperty(ContextualManager, "defaultProps", { dateFormat: 'YYYY-MM-DD', formMode: false, hybridMode: false, // default behaviour is to forbid empty values required: true, useSeconds: false, useTime: false, useUTC: false }); var _default = exports.default = ContextualManager; //# sourceMappingURL=Manager.component.js.map