UNPKG

@progress/kendo-react-dateinputs

Version:
528 lines • 21.5 kB
"use strict"; var __extends = (this && this.__extends) || (function () { var extendStatics = Object.setPrototypeOf || ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; return function (d, b) { extendStatics(d, b); function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; })(); var __assign = (this && this.__assign) || Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; Object.defineProperty(exports, "__esModule", { value: true }); var React = require("react"); var PropTypes = require("prop-types"); var kendo_date_math_1 = require("@progress/kendo-date-math"); var kendo_react_intl_1 = require("@progress/kendo-react-intl"); var models_1 = require("./models"); var kendo_react_common_1 = require("@progress/kendo-react-common"); var utils_1 = require("./utils"); var utils_2 = require("./../utils"); var messages_1 = require("./../messages"); var VALIDATION_MESSAGE = 'Please enter a valid value!'; // tslint:enable:max-line-length var DateInput = /** @class */ (function (_super) { __extends(DateInput, _super); function DateInput() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.kendoDate = null; _this._element = null; _this._inputId = kendo_react_common_1.guid(); /** * @hidden */ _this.setValidity = function () { if (_this.element && _this.element.setCustomValidity) { _this.element.setCustomValidity(_this.validity.valid ? '' : _this.props.validationMessage || DateInput.defaultProps.validationMessage); } }; /* Handlers */ _this.spinnersMouseDown = function (event) { /* do not steal focus from input when changing value with spinners */ event.preventDefault(); /* manually focus the input in case the user clicks the spinners first */ if (_this.element && document.activeElement !== _this.element) { _this.element.focus(); } }; _this.elementChange = function (event) { if (!_this.element || !_this.kendoDate) { return; } var _a = _this.kendoDate.getTextAndFormat(), text = _a.text, currentFormat = _a.format; _this.currentFormat = currentFormat; var dateBeforeChange = _this.value; var diff = utils_1.approximateStringMatching(text, _this.currentFormat, _this.element.value, _this.selection.start); var navigationOnly = (diff.length === 1 && diff[0][1] === '_'); var switchPart = false; if (!navigationOnly) { for (var i = 0; i < diff.length; i++) { switchPart = _this.kendoDate.parsePart(diff[i][0], diff[i][1]).switchToNext; } } if (diff.length && diff[0][0] !== '_') { _this.setSelection(_this.selectionBySymbol(diff[0][0])); } if (switchPart || navigationOnly) { _this.switchDateSegment(1); } _this.triggerChange(event, dateBeforeChange); }; _this.elementClick = function (_) { _this.setSelection(_this.selectionByIndex(_this.selection.start)); }; _this.wheel = function (event) { if (document.activeElement !== _this.element) { return; } if (event.nativeEvent.deltaY < 0) { event.preventDefault(); _this.increasePart(event); } if (event.nativeEvent.deltaY > 0) { event.preventDefault(); _this.decreasePart(event); } }; _this.increasePart = function (event) { _this.modifyDateSegmentValue(1, event); }; _this.decreasePart = function (event) { _this.modifyDateSegmentValue(-1, event); }; _this.elementKeyDown = function (event) { if (event.altKey) { return; } switch (event.keyCode) { case 37: /* * Key: `Left Arrow` * Action: Switches to previous logical* segment. * (*) https://www.w3.org/International/articles/inline-bidi-markup/uba-basics */ _this.switchDateSegment(-1); break; case (38): /* * Key: `Up Arrow` * Action: Increases the currently selected segment value. */ _this.modifyDateSegmentValue(1, event); break; case 39: /* * Key: `Right Arrow` * Action: Switches to the next logical segment. */ _this.switchDateSegment(1); break; case 40: /* * Key: `Down Arrow` * Action: Decreases the currently selected segment value. */ _this.modifyDateSegmentValue(-1, event); break; default: /* * Key: any * Action: Does not prevent the default behavior. */ return; } event.preventDefault(); }; return _this; } /** * @hidden */ DateInput.prototype.componentDidMount = function () { this.setValidity(); }; /** * @hidden */ DateInput.prototype.componentDidUpdate = function () { if (this._lastSelectedSymbol) { this.setSelection(this.selectionBySymbol(this._lastSelectedSymbol)); } this.setValidity(); }; /** * @hidden */ DateInput.prototype.render = function () { var _this = this; var localizationService = kendo_react_intl_1.provideLocalizationService(this); var props = __assign({}, DateInput.defaultProps, this.props); var formatPlaceholder = props.formatPlaceholder, format = props.format, value = props.value, min = props.min, max = props.max, name = props.name, label = props.label, id = props.id, defaultValue = props.defaultValue; if (this.kendoDate === null) { this.kendoDate = new models_1.KendoDate(this.intl.bind(this), formatPlaceholder, format); this.kendoDate.setValue(value || defaultValue); } else { this.kendoDate.format = format; this.kendoDate.formatPlaceholder = formatPlaceholder; } if (value !== undefined && this.value !== value) { this.kendoDate.setValue(value); } var _a = this.kendoDate.getTextAndFormat(), currentText = _a.text, currentFormat = _a.format; this.currentFormat = currentFormat; var inputId = id || this._inputId; var isValid = !this.validityStyles || this.validity.valid; var ariaProps = { 'aria-valuemin': min === null ? undefined : min.getTime(), 'aria-valuemax': max === null ? undefined : max.getTime(), 'aria-valuetext': currentText }; if (this.value !== null) { ariaProps['aria-valuenow'] = this.value.getTime(); } var wrapperClassesInstance = utils_1.wrapperClasses.slice(); if (this.props.className) { wrapperClassesInstance.push(this.props.className); } var dateinput = (React.createElement("span", { style: !label ? { width: this.props.width } : undefined, dir: this.props.dir, className: isValid ? wrapperClassesInstance.join(' ') : Array.prototype.concat([], wrapperClassesInstance, utils_1.invalidClasses).join(' ') }, React.createElement("span", { className: 'k-dateinput-wrap' + (this.props.disabled ? ' k-state-disabled' : '') }, React.createElement("input", __assign({ tabIndex: this.props.tabIndex, disabled: this.props.disabled, title: this.props.title || currentText, type: "text", spellCheck: false, autoComplete: "off", autoCorrect: "off", className: "k-input", id: inputId, onWheel: this.wheel, onClick: this.elementClick, onChange: this.elementChange, onKeyDown: this.elementKeyDown, value: currentText, name: name }, ariaProps, { ref: function (input) { return _this._element = input; } })), this.props.children, this.props.spinners && React.createElement("span", { className: "k-select", onMouseDown: this.spinnersMouseDown }, React.createElement("span", { className: "k-link k-link-increase", "aria-label": localizationService .toLanguageString(messages_1.increaseValue, messages_1.messages[messages_1.increaseValue]), title: localizationService .toLanguageString(messages_1.increaseValue, messages_1.messages[messages_1.increaseValue]), onClick: this.increasePart }, React.createElement("span", { className: "k-icon k-i-arrow-n" })), React.createElement("span", { className: "k-link k-link-decrease", "aria-label": localizationService .toLanguageString(messages_1.decreaseValue, messages_1.messages[messages_1.decreaseValue]), title: localizationService .toLanguageString(messages_1.decreaseValue, messages_1.messages[messages_1.decreaseValue]), onClick: this.decreasePart }, React.createElement("span", { className: "k-icon k-i-arrow-s" })))))); return label ? (React.createElement(kendo_react_common_1.FloatingLabel, { id: inputId, value: currentText, valid: isValid, label: label, children: dateinput, style: { width: this.props.width } })) : dateinput; }; Object.defineProperty(DateInput.prototype, "value", { /* Public Getters */ /** * Gets the value of the DateInput. */ get: function () { if (this.valueDuringOnChange !== undefined) { return this.valueDuringOnChange; } return this.kendoDate && this.kendoDate.getDateObject(); }, enumerable: true, configurable: true }); Object.defineProperty(DateInput.prototype, "name", { /** * Gets the `name` property of the DateInput. */ get: function () { return this.props.name; }, enumerable: true, configurable: true }); Object.defineProperty(DateInput.prototype, "min", { get: function () { return this.props.min !== undefined ? this.props.min : DateInput.defaultProps.min; }, enumerable: true, configurable: true }); Object.defineProperty(DateInput.prototype, "max", { get: function () { return this.props.max !== undefined ? this.props.max : DateInput.defaultProps.max; }, enumerable: true, configurable: true }); Object.defineProperty(DateInput.prototype, "validity", { /** * Represents the validity state into which the DateInput is set. */ get: function () { var inRange = utils_1.isInRange(this.value, this.min, this.max); var customError = this.props.validationMessage !== undefined; var isValid = (!this.required || this.value !== null) && inRange; var valid = this.props.valid !== undefined ? this.props.valid : isValid; return { customError: customError, rangeOverflow: (this.value && this.max.getTime() < this.value.getTime()) || false, rangeUnderflow: (this.value && this.value.getTime() < this.min.getTime()) || false, valid: valid, valueMissing: this.value === null }; }, enumerable: true, configurable: true }); Object.defineProperty(DateInput.prototype, "element", { /** * Gets the element of the DateInput. * * @return - An `HTMLInputElement`. * * @example * ```jsx * class App extends React.Component { * constructor(props) { * super(props); * } * element = null; * render() { * return ( * <div> * <DateInput * ref={(dateInput) => * this.element = dateInput ? dateInput.element : null} * /> * <button onClick={() => console.log(this.element)}>console.log the element</button> * </div> * ); * } * } * * ReactDOM.render( * <App />, * document.getElementsByTagName('my-app')[0] * ); * ``` */ get: function () { return this._element; }, enumerable: true, configurable: true }); Object.defineProperty(DateInput.prototype, "validityStyles", { /** * @hidden */ get: function () { return this.props.validityStyles !== undefined ? this.props.validityStyles : DateInput.defaultProps.validityStyles; }, enumerable: true, configurable: true }); Object.defineProperty(DateInput.prototype, "required", { /** * @hidden */ get: function () { return this.props.required !== undefined ? this.props.required : DateInput.defaultProps.required; }, enumerable: true, configurable: true }); /** * @hidden */ DateInput.prototype.intl = function () { return kendo_react_intl_1.provideIntlService(this); }; Object.defineProperty(DateInput.prototype, "selection", { /* end handlers */ get: function () { var returnValue = { start: 0, end: 0 }; if (this.element !== null && this.element.selectionStart !== undefined) { returnValue = { start: this.element.selectionStart, end: this.element.selectionEnd }; } return returnValue; }, enumerable: true, configurable: true }); DateInput.prototype.setSelection = function (selection) { var _this = this; this._lastSelectedSymbol = this.currentFormat[selection.start]; window.requestAnimationFrame(function () { if (_this.element && document.activeElement === _this.element) { _this.element.setSelectionRange(selection.start, selection.end); } }); }; DateInput.prototype.triggerChange = function (event, oldValue) { this.valueDuringOnChange = this.value; this.forceUpdate(); if (this.props.onChange && !kendo_date_math_1.isEqual(oldValue, this.value)) { // isEqual works with null this.props.onChange.call(undefined, { syntheticEvent: event, nativeEvent: event.nativeEvent, value: this.value, target: this // inRange: this.props.min && this.props.max ? isInRange(value, this.props.min, this.props.max) : true }); } this.valueDuringOnChange = undefined; }; DateInput.prototype.selectionBySymbol = function (symbol) { var start = -1; var end = 0; for (var i = 0; i < this.currentFormat.length; i++) { if (this.currentFormat[i] === symbol) { end = i + 1; if (start === -1) { start = i; } } } if (start < 0) { start = 0; } return { start: start, end: end }; }; DateInput.prototype.selectionByIndex = function (index) { var selection = { start: index, end: index }; for (var i = index, j = index - 1; i < this.currentFormat.length || j >= 0; i++, j--) { if (i < this.currentFormat.length && this.currentFormat[i] !== '_') { selection = this.selectionBySymbol(this.currentFormat[i]); break; } if (j >= 0 && this.currentFormat[j] !== '_') { selection = this.selectionBySymbol(this.currentFormat[j]); break; } } return selection; }; DateInput.prototype.switchDateSegment = function (offset) { var _a = this.selection, selectionStart = _a.start, selectionEnd = _a.end; if (selectionStart < selectionEnd && this.currentFormat[selectionStart] !== this.currentFormat[selectionEnd - 1]) { this.setSelection(this.selectionByIndex(offset > 0 ? selectionStart : selectionEnd - 1)); return; } var previousFormatSymbol = this.currentFormat[selectionStart]; var a = selectionStart + offset; while (a > 0 && a < this.currentFormat.length) { if (this.currentFormat[a] !== previousFormatSymbol && this.currentFormat[a] !== '_') { break; } a += offset; } if (this.currentFormat[a] === '_') { // no known symbol is found return; } var b = a; while (b >= 0 && b < this.currentFormat.length) { if (this.currentFormat[b] !== this.currentFormat[a]) { break; } b += offset; } if (a > b && (b + 1 !== selectionStart || a + 1 !== selectionEnd)) { this.setSelection({ start: b + 1, end: a + 1 }); } else if (a < b && (a !== selectionStart || b !== selectionEnd)) { this.setSelection({ start: a, end: b }); } }; DateInput.prototype.modifyDateSegmentValue = function (offset, event) { if (!this.kendoDate) { return; } var oldValue = this.value; var symbol = this.currentFormat[this.selection.start]; var currentStepSymbol = this.kendoDate.symbolMap(symbol); var step = ((this.props.steps || {})[currentStepSymbol] || 1) * offset; this.kendoDate.modifyPart(symbol, step); this.setSelection(this.selectionBySymbol(symbol)); this.triggerChange(event, oldValue); }; /** * @hidden */ DateInput.propTypes = { value: PropTypes.instanceOf(Date), format: PropTypes.string, formatPlaceholder: PropTypes.oneOfType([ PropTypes.oneOf(['wide', 'narrow', 'short', 'formatPattern']), PropTypes.shape({ year: PropTypes.string, month: PropTypes.string, day: PropTypes.string, hour: PropTypes.string, minute: PropTypes.string, second: PropTypes.string }) ]), width: PropTypes.oneOfType([ PropTypes.string, PropTypes.number ]), tabIndex: PropTypes.number, title: PropTypes.string, steps: PropTypes.shape({ year: PropTypes.number, month: PropTypes.number, day: PropTypes.number, hour: PropTypes.number, minute: PropTypes.number, second: PropTypes.number }), min: PropTypes.instanceOf(Date), max: PropTypes.instanceOf(Date), disabled: PropTypes.bool, spinners: PropTypes.bool, name: PropTypes.string, dir: PropTypes.string, label: PropTypes.string, id: PropTypes.string, onChange: PropTypes.func, validationMessage: PropTypes.string, required: PropTypes.bool, validate: PropTypes.bool, valid: PropTypes.bool }; /** * @hidden */ DateInput.defaultProps = { format: utils_1.defaultFormat, formatPlaceholder: utils_1.defaultFormatPlaceholder, defaultValue: null, spinners: false, disabled: false, max: kendo_date_math_1.cloneDate(utils_2.MAX_DATE), min: kendo_date_math_1.cloneDate(utils_2.MIN_DATE), required: false, validityStyles: true, validationMessage: VALIDATION_MESSAGE // the rest of the properties are undefined by default }; return DateInput; }(React.Component)); exports.DateInput = DateInput; kendo_react_intl_1.registerForIntl(DateInput); kendo_react_intl_1.registerForLocalization(DateInput); //# sourceMappingURL=DateInput.js.map