UNPKG

@fluentui/react

Version:

Reusable React components for building web experiences.

149 lines 7.24 kB
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