UNPKG

react-keyboard-time-input

Version:
267 lines (239 loc) 7.96 kB
'use strict'; exports.__esModule = true; var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _createReactClass = require('create-react-class'); var _createReactClass2 = _interopRequireDefault(_createReactClass); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _isTwelveHourTime = require('./lib/is-twelve-hour-time'); var _isTwelveHourTime2 = _interopRequireDefault(_isTwelveHourTime); var _replaceCharAt = require('./lib/replace-char-at'); var _replaceCharAt2 = _interopRequireDefault(_replaceCharAt); var _getGroupId = require('./lib/get-group-id'); var _getGroupId2 = _interopRequireDefault(_getGroupId); var _getGroups = require('./lib/get-groups'); var _getGroups2 = _interopRequireDefault(_getGroups); var _timeStringAdder = require('./lib/time-string-adder'); var _timeStringAdder2 = _interopRequireDefault(_timeStringAdder); var _caret = require('./lib/caret'); var _caret2 = _interopRequireDefault(_caret); var _validate = require('./lib/validate'); var _validate2 = _interopRequireDefault(_validate); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var SILHOUETTE = '00:00:00:000 AM'; // isSeparator :: Char -> Bool var isSeparator = function isSeparator(char) { return (/[:\s]/.test(char) ); }; var TimeInput = (0, _createReactClass2.default)({ getInitialState: function getInitialState() { return {}; }, getDefaultProps: function getDefaultProps() { return { value: '12:00 AM' }; }, propTypes: { className: _propTypes2.default.string, value: _propTypes2.default.string, onChange: _propTypes2.default.func }, render: function render() { var _this = this; var className = 'TimeInput'; if (this.props.className) { className += ' ' + this.props.className; } return _react2.default.createElement( 'div', { className: className }, _react2.default.createElement('input', { className: 'TimeInput-input', ref: function ref(input) { _this.input = input; }, type: 'text', value: this.format(this.props.value), onChange: this.handleChange, onBlur: this.handleBlur, onKeyDown: this.handleKeyDown }) ); }, format: function format(val) { if ((0, _isTwelveHourTime2.default)(val)) val = val.replace(/^00/, '12'); return val.toUpperCase(); }, componentDidMount: function componentDidMount() { this.mounted = true; }, componentWillUnmount: function componentWillUnmount() { this.mounted = false; }, componentDidUpdate: function componentDidUpdate() { var index = this.state.caretIndex; if (index || index === 0) _caret2.default.set(this.input, index); }, handleBlur: function handleBlur() { if (this.mounted) this.setState({ caretIndex: null }); }, handleEscape: function handleEscape() { if (this.mounted) this.input.blur(); }, handleTab: function handleTab(event) { var start = _caret2.default.start(this.input); var value = this.props.value; var groups = (0, _getGroups2.default)(value); var groupId = (0, _getGroupId2.default)(start); if (event.shiftKey) { if (!groupId) return; groupId--; } else { if (groupId >= groups.length - 1) return; groupId++; } event.preventDefault(); var index = groupId * 3; if (this.props.value.charAt(index) === ' ') index++; if (this.mounted) this.setState({ caretIndex: index }); }, handleArrows: function handleArrows(event) { event.preventDefault(); var start = _caret2.default.start(this.input); var value = this.props.value; var amount = event.which === 38 ? 1 : -1; if (event.shiftKey) { amount *= 2; if (event.metaKey) amount *= 2; } value = (0, _timeStringAdder2.default)(value, (0, _getGroupId2.default)(start), amount); this.onChange(value, start); }, silhouette: function silhouette() { return this.props.value.replace(/\d/g, function (val, i) { return SILHOUETTE.charAt(i); }); }, handleBackspace: function handleBackspace(event) { event.preventDefault(); var start = _caret2.default.start(this.input); var value = this.props.value; var end = _caret2.default.end(this.input); if (!start && !end) return; var diff = end - start; var silhouette = this.silhouette(); if (!diff) { if (value[start - 1] === ':') start--; value = (0, _replaceCharAt2.default)(value, start - 1, silhouette.charAt(start - 1)); start--; } else { while (diff--) { if (value[end - 1] !== ':') { value = (0, _replaceCharAt2.default)(value, end - 1, silhouette.charAt(end - 1)); } end--; } } if (value.charAt(start - 1) === ':') start--; this.onChange(value, start); }, handleForwardSpace: function handleForwardSpace(event) { event.preventDefault(); var start = _caret2.default.start(this.input); var value = this.props.value; var end = _caret2.default.end(this.input); if (start === end === value.length - 1) return; var diff = end - start; var silhouette = this.silhouette(); if (!diff) { if (value[start] === ':') start++; value = (0, _replaceCharAt2.default)(value, start, silhouette.charAt(start)); start++; } else { while (diff--) { if (value[end - 1] !== ':') { value = (0, _replaceCharAt2.default)(value, start, silhouette.charAt(start)); } start++; } } if (value.charAt(start) === ':') start++; this.onChange(value, start); }, handleKeyDown: function handleKeyDown(event) { switch (event.which) { case 9: // Tab return this.handleTab(event); case 8: // Backspace return this.handleBackspace(event); case 46: // Forward return this.handleForwardSpace(event); case 27: // Esc return this.handleEscape(event); case 38: // Left case 40: // Right return this.handleArrows(event); default: break; } }, handleChange: function handleChange(event) { var value = this.props.value; var newValue = this.input.value; var diff = newValue.length - value.length; var end = _caret2.default.start(this.input); var insertion = void 0; var start = end - Math.abs(diff); event.preventDefault(); if (diff > 0) { insertion = newValue.slice(end - diff, end); while (diff--) { var oldChar = value.charAt(start); var newChar = insertion.charAt(0); if (isSeparator(oldChar)) { if (isSeparator(newChar)) { insertion = insertion.slice(1); start++; } else { start++; diff++; end++; } } else { value = (0, _replaceCharAt2.default)(value, start, newChar); insertion = insertion.slice(1); start++; } } newValue = value; } else { if (newValue.charAt(start) === ':') start++; // apply default to selection var result = value; for (var i = start; i < end; i++) { result = (0, _replaceCharAt2.default)(result, i, newValue.charAt(i)); } newValue = result; } if ((0, _validate2.default)(newValue)) { if (newValue.charAt(end) === ':') end++; this.onChange(newValue, end); } else { var caretIndex = this.props.value.length - (newValue.length - end); if (this.mounted) this.setState({ caretIndex: caretIndex }); } }, onChange: function onChange(str, caretIndex) { if (this.props.onChange) this.props.onChange(this.format(str)); if (this.mounted && typeof caretIndex === 'number') this.setState({ caretIndex: caretIndex }); } }); exports.default = TimeInput;