@fluentui/react
Version:
Reusable React components for building web experiences.
149 lines • 7.24 kB
JavaScript
import { __assign, __rest } from "tslib";
import * as React from 'react';
import { useConst } from '@fluentui/react-hooks';
import { KeyCodes } from '../../Utilities';
import { TimeConstants, addMinutes, formatTimeString, ceilMinuteToIncrement, getDateFromTimeSelection, } from '@fluentui/date-time-utilities';
import { ComboBox } from '../../ComboBox';
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" + (showSeconds ? ':ss' : '') + (useHour12 ? ' AP' : '');
var errorMessageToDisplay = "Enter a valid time in the " + hourUnits + " format: " + timeFormat;
return {
invalidInputErrorMessage: errorMessageToDisplay,
};
};
/**
* {@docCategory TimePicker}
*/
export 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, onChange = _a.onChange, onFormatDate = _a.onFormatDate, onValidateUserInput = _a.onValidateUserInput, rest = __rest(_a, ["label", "increments", "showSeconds", "allowFreeform", "useHour12", "timeRange", "strings", "defaultValue", "onChange", "onFormatDate", "onValidateUserInput"]);
var _g = React.useState(''), userText = _g[0], setUserText = _g[1];
var _h = React.useState(''), errorMessage = _h[0], setErrorMessage = _h[1];
var optionsCount = getDropdownOptionsCount(increments, timeRange);
var initialValue = useConst(defaultValue || new Date());
var baseDate = React.useMemo(function () { return generateBaseDate(increments, timeRange, initialValue); }, [
increments,
timeRange,
initialValue,
]);
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 = addMinutes(baseDate, increments * index);
option.setSeconds(0);
var optionText = onFormatDate ? onFormatDate(option) : formatTimeString(option, showSeconds, useHour12);
return {
key: optionText,
text: optionText,
};
});
}, [baseDate, increments, optionsCount, showSeconds, onFormatDate, useHour12]);
var _j = React.useState(timePickerOptions[0].key), selectedKey = _j[0], setSelectedKey = _j[1];
var onInputChange = React.useCallback(function (event, option, index, value) {
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;
}
return errorMessageToDisplay;
};
var key = option === null || option === void 0 ? void 0 : option.key;
var updatedUserText = '';
var errorMessageToDisplay = '';
if (value) {
if (allowFreeform && !option) {
if (!onFormatDate) {
// Validate only if user did not add onFormatDate
errorMessageToDisplay = validateUserInput(value);
}
else {
// Use user provided validation if onFormatDate is provided
if (onValidateUserInput) {
errorMessageToDisplay = onValidateUserInput(value);
}
}
}
updatedUserText = value;
}
else if (option) {
updatedUserText = option.text;
}
if (onChange && !errorMessageToDisplay) {
var selectedTime = value || (option === null || option === void 0 ? void 0 : option.text) || '';
var date = getDateFromTimeSelection(useHour12, baseDate, selectedTime);
onChange(event, date);
}
setErrorMessage(errorMessageToDisplay);
setUserText(updatedUserText);
setSelectedKey(key);
}, [
baseDate,
allowFreeform,
onChange,
onFormatDate,
onValidateUserInput,
showSeconds,
useHour12,
strings.invalidInputErrorMessage,
]);
var evaluatePressedKey = function (event) {
// eslint-disable-next-line deprecation/deprecation
var charCode = event.charCode;
if (!onFormatDate &&
// Only permit input of digits, space, colon, A/P/M characters
!((charCode >= KeyCodes.zero && charCode <= KeyCodes.colon) ||
charCode === KeyCodes.space ||
charCode === KeyCodes.a ||
charCode === KeyCodes.m ||
charCode === KeyCodes.p)) {
event.preventDefault();
}
};
return (React.createElement(ComboBox, __assign({}, rest, { allowFreeform: allowFreeform, selectedKey: selectedKey, label: label, errorMessage: errorMessage, options: timePickerOptions, onChange: onInputChange, text: userText,
//eslint-disable-next-line
onKeyPress: evaluatePressedKey })));
};
TimePicker.displayName = 'TimePicker';
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 generateBaseDate = function (increments, timeRange, baseDate) {
if (timeRange) {
var clampedTimeRange = clampTimeRange(timeRange);
baseDate.setHours(clampedTimeRange.start);
}
return ceilMinuteToIncrement(baseDate, increments);
};
var getDropdownOptionsCount = function (increments, timeRange) {
var hoursInRange = TimeConstants.HoursInOneDay;
if (timeRange) {
var clampedTimeRange = clampTimeRange(timeRange);
if (clampedTimeRange.start > clampedTimeRange.end) {
hoursInRange = TimeConstants.HoursInOneDay - timeRange.start - timeRange.end;
}
else if (timeRange.end > timeRange.start) {
hoursInRange = timeRange.end - timeRange.start;
}
}
return Math.floor((TimeConstants.MinutesInOneHour * hoursInRange) / increments);
};
//# sourceMappingURL=TimePicker.js.map