201 lines
12 KiB
JavaScript
201 lines
12 KiB
JavaScript
define(["require", "exports", "tslib", "react", "../../Utilities", "@fluentui/date-time-utilities", "../../ComboBox", "../../Utilities", "@fluentui/react-hooks"], function (require, exports, tslib_1, React, Utilities_1, date_time_utilities_1, ComboBox_1, Utilities_2, react_hooks_1) {
|
|
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.TimePicker = void 0;
|
|
var REGEX_SHOW_SECONDS_HOUR_12 = /^((1[0-2]|0?[1-9]):([0-5][0-9]):([0-5][0-9])\s([AaPp][Mm]))$/;
|
|
var REGEX_HIDE_SECONDS_HOUR_12 = /^((1[0-2]|0?[1-9]):[0-5][0-9]\s([AaPp][Mm]))$/;
|
|
var REGEX_SHOW_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]:[0-5][0-9]$/;
|
|
var REGEX_HIDE_SECONDS_HOUR_24 = /^([0-1]?[0-9]|2[0-3]):[0-5][0-9]$/;
|
|
var TIME_LOWER_BOUND = 0;
|
|
var TIME_UPPER_BOUND = 23;
|
|
var getDefaultStrings = function (useHour12, showSeconds) {
|
|
var hourUnits = useHour12 ? '12-hour' : '24-hour';
|
|
var timeFormat = "hh:mm".concat(showSeconds ? ':ss' : '').concat(useHour12 ? ' AP' : '');
|
|
var invalidInputErrorMessage = "Enter a valid time in the ".concat(hourUnits, " format: ").concat(timeFormat);
|
|
var timeOutOfBoundsErrorMessage = "Please enter a time within the range of {0} and {1}";
|
|
return {
|
|
invalidInputErrorMessage: invalidInputErrorMessage,
|
|
timeOutOfBoundsErrorMessage: timeOutOfBoundsErrorMessage,
|
|
};
|
|
};
|
|
/**
|
|
* {@docCategory TimePicker}
|
|
*/
|
|
var TimePicker = function (_a) {
|
|
var label = _a.label, _b = _a.increments, increments = _b === void 0 ? 30 : _b, _c = _a.showSeconds, showSeconds = _c === void 0 ? false : _c, _d = _a.allowFreeform, allowFreeform = _d === void 0 ? true : _d, _e = _a.useHour12, useHour12 = _e === void 0 ? false : _e, timeRange = _a.timeRange, _f = _a.strings, strings = _f === void 0 ? getDefaultStrings(useHour12, showSeconds) : _f, defaultValue = _a.defaultValue, value = _a.value, dateAnchor = _a.dateAnchor, onChange = _a.onChange, onFormatDate = _a.onFormatDate, onValidateUserInput = _a.onValidateUserInput, onValidationResult = _a.onValidationResult, rest = tslib_1.__rest(_a, ["label", "increments", "showSeconds", "allowFreeform", "useHour12", "timeRange", "strings", "defaultValue", "value", "dateAnchor", "onChange", "onFormatDate", "onValidateUserInput", "onValidationResult"]);
|
|
var _g = React.useState(''), comboBoxText = _g[0], setComboBoxText = _g[1];
|
|
var _h = React.useState(), selectedKey = _h[0], setSelectedKey = _h[1];
|
|
var _j = React.useState(''), errorMessage = _j[0], setErrorMessage = _j[1];
|
|
var fallbackDateAnchor = (0, react_hooks_1.useConst)(new Date());
|
|
var _k = (0, react_hooks_1.useControllableValue)(value, defaultValue), selectedTime = _k[0], setSelectedTime = _k[1];
|
|
var optionsCount = getDropdownOptionsCount(increments, timeRange);
|
|
var internalDateAnchor = dateAnchor || value || defaultValue || fallbackDateAnchor;
|
|
var dateStartAnchor = React.useMemo(function () { return getDateAnchor(internalDateAnchor, 'start', increments, timeRange); }, [internalDateAnchor, increments, timeRange]);
|
|
var dateEndAnchor = React.useMemo(function () { return getDateAnchor(internalDateAnchor, 'end', increments, timeRange); }, [internalDateAnchor, increments, timeRange]);
|
|
var timePickerOptions = React.useMemo(function () {
|
|
var optionsList = Array(optionsCount);
|
|
for (var i = 0; i < optionsCount; i++) {
|
|
optionsList[i] = 0;
|
|
}
|
|
return optionsList.map(function (_, index) {
|
|
var option = (0, date_time_utilities_1.addMinutes)(dateStartAnchor, increments * index);
|
|
option.setSeconds(0);
|
|
var formattedTimeString = (0, date_time_utilities_1.formatTimeString)(option, showSeconds, useHour12);
|
|
var optionText = onFormatDate ? onFormatDate(option) : formattedTimeString;
|
|
return {
|
|
key: formattedTimeString,
|
|
text: optionText,
|
|
data: option,
|
|
};
|
|
});
|
|
}, [dateStartAnchor, increments, optionsCount, showSeconds, onFormatDate, useHour12]);
|
|
React.useEffect(function () {
|
|
if (selectedTime && !isNaN(selectedTime.valueOf())) {
|
|
var formattedTimeString_1 = (0, date_time_utilities_1.formatTimeString)(selectedTime, showSeconds, useHour12);
|
|
var comboboxOption = timePickerOptions.find(function (option) { return option.key === formattedTimeString_1; });
|
|
setSelectedKey(comboboxOption === null || comboboxOption === void 0 ? void 0 : comboboxOption.key);
|
|
setComboBoxText(comboboxOption ? comboboxOption.text : formattedTimeString_1);
|
|
}
|
|
else {
|
|
setSelectedKey(null);
|
|
setComboBoxText('');
|
|
}
|
|
}, [selectedTime, timePickerOptions, onFormatDate, showSeconds, useHour12]);
|
|
var onInputChange = React.useCallback(function (ev, option, _index, input) {
|
|
var validateUserInput = function (userInput) {
|
|
var errorMessageToDisplay = '';
|
|
var regex;
|
|
if (useHour12) {
|
|
regex = showSeconds ? REGEX_SHOW_SECONDS_HOUR_12 : REGEX_HIDE_SECONDS_HOUR_12;
|
|
}
|
|
else {
|
|
regex = showSeconds ? REGEX_SHOW_SECONDS_HOUR_24 : REGEX_HIDE_SECONDS_HOUR_24;
|
|
}
|
|
if (!regex.test(userInput)) {
|
|
errorMessageToDisplay = strings.invalidInputErrorMessage;
|
|
}
|
|
else if (timeRange && strings.timeOutOfBoundsErrorMessage) {
|
|
var optionDate = (0, date_time_utilities_1.getDateFromTimeSelection)(useHour12, dateStartAnchor, userInput);
|
|
if (optionDate < dateStartAnchor || optionDate > dateEndAnchor) {
|
|
errorMessageToDisplay = (0, Utilities_2.format)(strings.timeOutOfBoundsErrorMessage, dateStartAnchor.toString(), dateEndAnchor.toString());
|
|
}
|
|
}
|
|
return errorMessageToDisplay;
|
|
};
|
|
var errorMessageToDisplay = '';
|
|
if (input) {
|
|
if (allowFreeform && !option) {
|
|
if (!onFormatDate) {
|
|
// Validate only if user did not add onFormatDate
|
|
errorMessageToDisplay = validateUserInput(input);
|
|
}
|
|
else {
|
|
// Use user provided validation if onFormatDate is provided
|
|
if (onValidateUserInput) {
|
|
errorMessageToDisplay = onValidateUserInput(input);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (onValidationResult && errorMessage !== errorMessageToDisplay) {
|
|
// only call onValidationResult if stored errorMessage state value is different from latest error message
|
|
onValidationResult(ev, { errorMessage: errorMessageToDisplay });
|
|
}
|
|
var changedTime;
|
|
if (errorMessageToDisplay || (input !== undefined && !input.length)) {
|
|
var timeSelection = input || (option === null || option === void 0 ? void 0 : option.text) || '';
|
|
setComboBoxText(timeSelection);
|
|
setSelectedTime(errorMessageToDisplay ? new Date('invalid') : undefined);
|
|
changedTime = new Date('invalid');
|
|
}
|
|
else {
|
|
var updatedTime = void 0;
|
|
if ((option === null || option === void 0 ? void 0 : option.data) instanceof Date) {
|
|
updatedTime = option.data;
|
|
}
|
|
else {
|
|
var timeSelection = (option === null || option === void 0 ? void 0 : option.key) || input || '';
|
|
updatedTime = (0, date_time_utilities_1.getDateFromTimeSelection)(useHour12, dateStartAnchor, timeSelection);
|
|
}
|
|
setSelectedTime(updatedTime);
|
|
changedTime = updatedTime;
|
|
}
|
|
onChange === null || onChange === void 0 ? void 0 : onChange(ev, changedTime);
|
|
setErrorMessage(errorMessageToDisplay);
|
|
}, [
|
|
timeRange,
|
|
dateStartAnchor,
|
|
dateEndAnchor,
|
|
allowFreeform,
|
|
onFormatDate,
|
|
onValidateUserInput,
|
|
showSeconds,
|
|
useHour12,
|
|
strings.invalidInputErrorMessage,
|
|
strings.timeOutOfBoundsErrorMessage,
|
|
setSelectedTime,
|
|
onValidationResult,
|
|
onChange,
|
|
errorMessage,
|
|
]);
|
|
var evaluatePressedKey = function (event) {
|
|
// eslint-disable-next-line @typescript-eslint/no-deprecated
|
|
var charCode = event.charCode;
|
|
if (!onFormatDate &&
|
|
// Only permit input of digits, space, colon, A/P/M characters
|
|
!((charCode >= Utilities_1.KeyCodes.zero && charCode <= Utilities_1.KeyCodes.colon) ||
|
|
charCode === Utilities_1.KeyCodes.space ||
|
|
charCode === Utilities_1.KeyCodes.a ||
|
|
charCode === Utilities_1.KeyCodes.m ||
|
|
charCode === Utilities_1.KeyCodes.p)) {
|
|
event.preventDefault();
|
|
}
|
|
};
|
|
return (React.createElement(ComboBox_1.ComboBox, tslib_1.__assign({}, rest, { allowFreeform: allowFreeform, selectedKey: selectedKey, label: label, errorMessage: errorMessage, options: timePickerOptions, onChange: onInputChange, text: comboBoxText,
|
|
//eslint-disable-next-line
|
|
onKeyPress: evaluatePressedKey, useComboBoxAsMenuWidth: true })));
|
|
};
|
|
exports.TimePicker = TimePicker;
|
|
exports.TimePicker.displayName = 'TimePicker';
|
|
var getDateAnchor = function (internalDateAnchor, startEnd, increments, timeRange) {
|
|
var clampedDateAnchor = new Date(internalDateAnchor.getTime());
|
|
if (timeRange) {
|
|
var clampedTimeRange = clampTimeRange(timeRange);
|
|
var timeRangeHours = startEnd === 'start' ? clampedTimeRange.start : clampedTimeRange.end;
|
|
if (clampedDateAnchor.getHours() !== timeRangeHours) {
|
|
clampedDateAnchor.setHours(timeRangeHours);
|
|
}
|
|
}
|
|
else if (startEnd === 'end') {
|
|
clampedDateAnchor.setDate(clampedDateAnchor.getDate() + 1);
|
|
}
|
|
clampedDateAnchor.setMinutes(0);
|
|
clampedDateAnchor.setSeconds(0);
|
|
clampedDateAnchor.setMilliseconds(0);
|
|
return (0, date_time_utilities_1.ceilMinuteToIncrement)(clampedDateAnchor, increments);
|
|
};
|
|
var clampTimeRange = function (timeRange) {
|
|
return {
|
|
start: Math.min(Math.max(timeRange.start, TIME_LOWER_BOUND), TIME_UPPER_BOUND),
|
|
end: Math.min(Math.max(timeRange.end, TIME_LOWER_BOUND), TIME_UPPER_BOUND),
|
|
};
|
|
};
|
|
var getHoursInRange = function (timeRange) {
|
|
var hoursInRange = date_time_utilities_1.TimeConstants.HoursInOneDay;
|
|
if (timeRange) {
|
|
var clampedTimeRange = clampTimeRange(timeRange);
|
|
if (clampedTimeRange.start > clampedTimeRange.end) {
|
|
hoursInRange = date_time_utilities_1.TimeConstants.HoursInOneDay - timeRange.start - timeRange.end;
|
|
}
|
|
else if (timeRange.end > timeRange.start) {
|
|
hoursInRange = timeRange.end - timeRange.start;
|
|
}
|
|
}
|
|
return hoursInRange;
|
|
};
|
|
var getDropdownOptionsCount = function (increments, timeRange) {
|
|
var hoursInRange = getHoursInRange(timeRange);
|
|
return Math.floor((date_time_utilities_1.TimeConstants.MinutesInOneHour * hoursInRange) / increments);
|
|
};
|
|
});
|
|
//# sourceMappingURL=TimePicker.js.map
|