UNPKG

@progress/kendo-react-dateinputs

Version:
268 lines • 11.5 kB
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; }; import * as React from 'react'; import * as PropTypes from 'prop-types'; import { cloneDate } from '@progress/kendo-date-math'; import { classNames, Keys } from '@progress/kendo-react-common'; import { provideIntlService, provideLocalizationService, registerForIntl, registerForLocalization } from '@progress/kendo-react-intl'; import { messages, now, selectNow } from '../messages'; import { TimeList } from './TimeList'; import { MIDNIGHT_DATE, MIN_TIME, MAX_TIME } from '../utils'; import { TIME_PART } from './models/TimePart'; import { generateSnappers, getNow, isInTimeRange, snapTime, timeInRange } from './utils'; var formatRegExp = new RegExp(TIME_PART.hour + "|" + TIME_PART.minute + "|" + TIME_PART.second + "|" + TIME_PART.dayperiod + "|literal"); /** * @hidden */ export var Direction; (function (Direction) { Direction[Direction["Left"] = 0] = "Left"; Direction[Direction["Right"] = 1] = "Right"; })(Direction || (Direction = {})); /** * @hidden */ var TimePart = /** @class */ (function (_super) { __extends(TimePart, _super); function TimePart(props) { var _this = _super.call(this, props) || this; _this.timeLists = []; _this.focus = function () { Promise.resolve().then(function () { var timeList = _this.timeLists[0]; if ((_this.state.activeListIndex === -1) && !_this.hasActiveButton() && timeList && timeList.element) { timeList.focus(); } }); }; _this.timeFormatReducer = function (acc, current) { return acc + current.pattern; }; // Filtering only the time part of the format. // Literal types are added if the previous part is // part of a time format. _this.timeFormatFilter = function (part, index, all) { var prevItem = index >= 1 && all[index - 1]; if (!prevItem) { return formatRegExp.test(part.type || ''); } if (prevItem && part.type === 'literal') { return formatRegExp.test(prevItem.type || ''); } return formatRegExp.test(part.type || ''); }; _this.focusList = function (dir) { if (!_this.timeLists.length) { return; } _this.timeLists.reduce(_this.listReducer, ([])) .map(function (state) { return dir === Direction.Right ? state.next : state.prev; }) .map(function (list) { return list && list.element && list.element.focus(); }); }; _this.listReducer = function (state, list, idx, all) { if (state.length || list.props.id !== _this.state.activeListIndex) { return state; } return [{ next: all[idx + 1] || list, prev: all[idx - 1] || list }]; }; _this.showNowButton = function () { return !_this.hasSteps() && _this.props.nowButton && isInTimeRange(getNow(), _this.min, _this.max); }; _this.handleKeyDown = function (event) { var keyCode = event.keyCode; switch (keyCode) { case Keys.left: event.preventDefault(); _this.focusList(Direction.Left); return; case Keys.right: event.preventDefault(); _this.focusList(Direction.Right); return; default: return; } }; _this.handleListBlur = function () { _this.nextTick(function () { _this.setState({ activeListIndex: -1 }); }); }; _this.handleListFocus = function (idx) { clearTimeout(_this.nextTickId); _this.setState({ activeListIndex: idx }); }; _this.handleChange = function (candidate) { var onChange = _this.props.onChange; if (onChange) { onChange.call(undefined, candidate); } }; _this.snapTime = snapTime(generateSnappers(_this.props.steps, _this.props.min || TimePart.defaultProps.min)); _this.state = { activeListIndex: -1 }; _this.hasActiveButton = _this.hasActiveButton.bind(_this); return _this; } Object.defineProperty(TimePart.prototype, "element", { /** * @hidden */ get: function () { return this._element; }, enumerable: true, configurable: true }); Object.defineProperty(TimePart.prototype, "intl", { get: function () { return provideIntlService(this); }, enumerable: true, configurable: true }); Object.defineProperty(TimePart.prototype, "value", { get: function () { return timeInRange(this.snapTime(cloneDate(this.props.value || MIDNIGHT_DATE)), this.min, this.max); }, enumerable: true, configurable: true }); Object.defineProperty(TimePart.prototype, "min", { get: function () { return this.snapTime(this.props.min || TimePart.defaultProps.min); }, enumerable: true, configurable: true }); Object.defineProperty(TimePart.prototype, "max", { get: function () { return this.snapTime(this.props.max || TimePart.defaultProps.max); }, enumerable: true, configurable: true }); Object.defineProperty(TimePart.prototype, "steps", { get: function () { return this.props.steps || TimePart.defaultProps.steps; }, enumerable: true, configurable: true }); Object.defineProperty(TimePart.prototype, "boundRange", { get: function () { return this.props.boundRange !== undefined ? this.props.boundRange : TimePart.defaultProps.boundRange; }, enumerable: true, configurable: true }); /** * @hidden */ TimePart.prototype.componentWillUnmount = function () { clearTimeout(this.nextTickId); }; /** * @hidden */ TimePart.prototype.render = function () { var _this = this; var _a = this.props, format = _a.format, smoothScroll = _a.smoothScroll, onNowClick = _a.onNowClick, className = _a.className, disabled = _a.disabled; this.snapTime = snapTime(generateSnappers(this.steps, this.min)); this.dateFormatParts = this.intl .splitDateFormat(format || TimePart.defaultProps.format) .filter(this.timeFormatFilter); var rootClassName = classNames({ 'k-state-disabled': disabled }, className, 'k-time-part'); this.timeLists = []; var localizationService = provideLocalizationService(this); var selectNowMessage = localizationService.toLanguageString(selectNow, messages[selectNow]); return (React.createElement("div", { className: rootClassName }, React.createElement("div", { className: "k-time-header" }, React.createElement("span", { className: "k-title" }, this.intl.formatDate(this.value, this.dateFormatParts.reduce(this.timeFormatReducer, ''))), this.showNowButton() && React.createElement("button", __assign({ ref: function (btn) { _this._nowButton = btn; }, className: "k-button k-bare k-time-now", title: selectNowMessage }, { 'aria-label': selectNowMessage }, { onClick: onNowClick, tabIndex: disabled ? -1 : 0 }), localizationService.toLanguageString(now, messages[now]))), React.createElement("div", { className: "k-time-list-container", onKeyDown: this.handleKeyDown }, React.createElement("span", { className: "k-time-highlight" }), this.dateFormatParts.map(function (part, idx) { return (part.type !== 'literal' ? React.createElement("div", { key: idx, className: classNames('k-time-list-wrapper', { 'k-state-focused': idx === _this.state.activeListIndex }), role: "presentation", tabIndex: -1 }, React.createElement("span", { className: "k-title", onMouseDown: function (e) { e.preventDefault(); } }, _this.intl.dateFieldName(part)), React.createElement(TimeList, { min: _this.min, max: _this.max, boundRange: _this.boundRange, part: part, step: part.type ? _this.steps[part.type] : 1, smoothScroll: smoothScroll, ref: function (el) { if (!el) { return; } _this.timeLists.push(el); }, id: idx, onFocus: function () { _this.handleListFocus(idx); }, onBlur: _this.handleListBlur, onChange: _this.handleChange, value: _this.value, disabled: disabled })) : React.createElement("div", { key: idx, className: "k-time-separator" }, part.pattern)); })))); }; TimePart.prototype.nextTick = function (f) { // XXX: use setTimeout due to async focus/blur events in IE, and missing relatedTarget prop. // XXX: https://github.com/facebook/react/issues/3751 clearTimeout(this.nextTickId); this.nextTickId = setTimeout(function () { return f(); }); }; TimePart.prototype.hasActiveButton = function () { return document.activeElement === this._nowButton; }; TimePart.prototype.hasSteps = function () { var _this = this; var keys = Object.keys(this.steps); return keys.length !== keys.reduce(function (acc, k) { return acc + _this.steps[k]; }, 0); }; TimePart.propTypes = { cancelButton: PropTypes.bool, disabled: PropTypes.bool, format: PropTypes.string, max: PropTypes.instanceOf(Date), min: PropTypes.instanceOf(Date), nowButton: PropTypes.bool, steps: PropTypes.shape({ hour: PropTypes.number, minute: PropTypes.number, second: PropTypes.number }), smoothScroll: PropTypes.bool, tabIndex: PropTypes.number, value: PropTypes.instanceOf(Date) }; TimePart.defaultProps = { value: null, disabled: false, nowButton: true, cancelButton: true, format: 'hh:mm a', min: MIN_TIME, max: MAX_TIME, steps: {}, boundRange: false }; return TimePart; }(React.Component)); export { TimePart }; registerForIntl(TimePart); registerForLocalization(TimePart); //# sourceMappingURL=TimePart.js.map