@seafile/seafile-calendar
Version:
React Calendar
184 lines (155 loc) • 5.29 kB
JavaScript
import _classCallCheck from 'babel-runtime/helpers/classCallCheck';
import _possibleConstructorReturn from 'babel-runtime/helpers/possibleConstructorReturn';
import _inherits from 'babel-runtime/helpers/inherits';
import React from 'react';
import PropTypes from 'prop-types';
import { polyfill } from 'react-lifecycles-compat';
import dayjs from 'dayjs';
var customParseFormat = require('dayjs/plugin/customParseFormat');
dayjs.extend(customParseFormat);
function formatTime(value, format) {
if (!value) return '';
var fmt = Array.isArray(format) ? format[0] : format || 'HH:mm';
return value.format(fmt);
}
// Convert a loose numeric/time string into HH:mm
// Rules (similar spirit to DateInput.initializeStr):
// - Strip non-digits
// - If len <= 2 => treat as hour
// - If len > 2 => last two digits are minutes; preceding are hours
// - Clamp hours to [0,23], minutes to [0,59]
// - Return formatted HH:mm or '' when input is empty
function initializeTime(str) {
if (typeof str !== 'string') return '';
var digits = str.replace(/\D/g, '');
if (!digits.length) return '';
var hDigits = '';
var mDigits = '';
if (digits.length <= 2) {
hDigits = digits;
} else {
hDigits = digits.slice(0, digits.length - 2);
mDigits = digits.slice(-2);
}
var hour = parseInt(hDigits || '0', 10);
var minute = parseInt(mDigits || '0', 10);
if (Number.isNaN(hour)) hour = 0;
if (Number.isNaN(minute)) minute = 0;
if (hour > 23) hour = 23;
if (minute > 59) minute = 59;
var HH = String(hour).padStart(2, '0');
var mm = String(minute).padStart(2, '0');
return HH + ':' + mm;
}
var timeInputInstance = void 0;
var TimeInput = function (_React$Component) {
_inherits(TimeInput, _React$Component);
function TimeInput(props) {
_classCallCheck(this, TimeInput);
var _this = _possibleConstructorReturn(this, _React$Component.call(this, props));
_this.onInputChange = function (event) {
var str = event.target.value;
var timeStr = initializeTime(str);
if (!str || !timeStr) {
_this.setState({ str: str });
return;
}
var base = _this.props.selectedValue || _this.props.value || dayjs();
var parsed = dayjs(timeStr, 'HH:mm');
var next = base.clone().hour(parsed.hour()).minute(parsed.minute());
_this.setState({ str: str });
if (_this.props.onChange) {
_this.props.onChange(next);
}
};
_this.onKeyDown = function (event) {
if (event.key === 'Enter' && _this.props.onSelect) {
var timeStr = initializeTime(_this.state.str);
if (!timeStr) return;
var base = _this.props.selectedValue || _this.props.value || dayjs();
var parsed = dayjs(timeStr, 'HH:mm');
var next = base.clone().hour(parsed.hour()).minute(parsed.minute());
_this.props.onSelect(next);
event.preventDefault();
}
};
_this.onFocus = function () {
_this.setState({ hasFocus: true });
};
_this.onBlur = function () {
var base = _this.props.selectedValue ? _this.props.selectedValue : _this.props.value || null;
_this.setState({
hasFocus: false,
str: base ? formatTime(base, _this.props.format) : ''
});
};
_this.saveRef = function (node) {
timeInputInstance = node;
};
_this.state = {
str: '',
hasFocus: false
};
return _this;
}
TimeInput.getDerivedStateFromProps = function getDerivedStateFromProps(nextProps, state) {
var newState = null;
if (!state.hasFocus) {
var base = nextProps.selectedValue || null;
newState = { str: base ? formatTime(base, nextProps.format) : '' };
}
return newState;
};
TimeInput.getInstance = function getInstance() {
return timeInputInstance;
};
TimeInput.prototype.render = function render() {
var _props = this.props,
prefixCls = _props.prefixCls,
placeholder = _props.placeholder,
inputMode = _props.inputMode,
disabled = _props.disabled,
className = _props.className;
var inputCls = className || prefixCls + '-input';
return React.createElement(
'div',
{ className: prefixCls + '-input-wrap' },
React.createElement(
'div',
{ className: prefixCls + '-time-input-wrap' },
React.createElement('input', {
id: 'time-input',
ref: this.saveRef,
className: inputCls,
value: this.state.str,
disabled: disabled,
placeholder: placeholder,
onChange: this.onInputChange,
onKeyDown: this.onKeyDown,
onFocus: this.onFocus,
onBlur: this.onBlur,
inputMode: inputMode
})
)
);
};
return TimeInput;
}(React.Component);
TimeInput.propTypes = {
prefixCls: PropTypes.string,
value: PropTypes.object,
selectedValue: PropTypes.object,
onChange: PropTypes.func,
onSelect: PropTypes.func,
placeholder: PropTypes.string,
inputMode: PropTypes.string,
format: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]),
disabled: PropTypes.bool,
className: PropTypes.string
};
TimeInput.defaultProps = {
format: 'HH:mm',
placeholder: 'HH:mm'
};
polyfill(TimeInput);
export default TimeInput;