@progress/kendo-react-dateinputs
Version:
KendoReact Date Inputs package
528 lines • 21.5 kB
JavaScript
"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