UNPKG

@activecollab/components

Version:

ActiveCollab Components

162 lines • 6.49 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _objectWithoutPropertiesLoose from "@babel/runtime/helpers/esm/objectWithoutPropertiesLoose"; const _excluded = ["mode", "selected", "min", "max", "onChange", "step", "size", "className", "placeholder", "triggerMode", "disabled", "invalid", "enableVirtualization", "addCustomTimeLabel"]; import React, { useCallback, useEffect, useMemo, useState } from "react"; import classNames from "classnames"; import nlp from "compromise"; import plg from "compromise-dates"; import moment from "moment"; import styled from "styled-components"; import { isValidTime } from "../../utils/timeUtils"; import { ComboBox } from "../ComboBox/ComboBox"; nlp.plugin(plg); export const StyledInputTimeWrapper = styled.div.withConfig({ displayName: "InputTime__StyledInputTimeWrapper", componentId: "sc-71akdh-0" })(["max-width:176px;flex:1;& .c-combo-box--list{min-width:176px;}"]); const renderOption = option => { return /*#__PURE__*/React.createElement("div", { id: option.id, "data-testid": "time-option-" + option.id }, option.name); }; export const InputTime = _ref => { let _ref$mode = _ref.mode, mode = _ref$mode === void 0 ? "24" : _ref$mode, defaultSelected = _ref.selected, _ref$min = _ref.min, min = _ref$min === void 0 ? "00:00" : _ref$min, _ref$max = _ref.max, max = _ref$max === void 0 ? "23:45" : _ref$max, onChange = _ref.onChange, _ref$step = _ref.step, step = _ref$step === void 0 ? 15 : _ref$step, size = _ref.size, className = _ref.className, placeholder = _ref.placeholder, triggerMode = _ref.triggerMode, disabled = _ref.disabled, invalid = _ref.invalid, _ref$enableVirtualiza = _ref.enableVirtualization, enableVirtualization = _ref$enableVirtualiza === void 0 ? false : _ref$enableVirtualiza, _ref$addCustomTimeLab = _ref.addCustomTimeLabel, addCustomTimeLabel = _ref$addCustomTimeLab === void 0 ? "Add" : _ref$addCustomTimeLab, rest = _objectWithoutPropertiesLoose(_ref, _excluded); const _useState = useState(false), isOpen = _useState[0], setIsOpen = _useState[1]; const _useState2 = useState(undefined), search = _useState2[0], setSearch = _useState2[1]; const generateTimeOptions = () => { const allOptions = []; const currentTime = moment("00:00", "HH:mm"); while (currentTime.isBefore(moment("24:00", "HH:mm"))) { allOptions.push({ id: currentTime.format("HH:mm"), name: currentTime.format(mode === "12" ? "hh:mm A" : "HH:mm") }); currentTime.add(step, "minutes"); } return allOptions; }; const timeOptionsFilter = (options, _min, _max) => { const minTime = moment(isValidTime(_min) ? _min : "00:00", "HH:mm"); const maxTime = moment(isValidTime(_max) ? _max : "23:45", "HH:mm"); return options.filter(option => moment(option.id, "HH:mm").isSameOrAfter(minTime) && moment(option.id, "HH:mm").isSameOrBefore(maxTime)); }; const _useState3 = useState(generateTimeOptions()), allTimeOptions = _useState3[0], setAllTimeOptions = _useState3[1]; const timeOptions = useMemo(() => timeOptionsFilter(allTimeOptions, min, max), [allTimeOptions, min, max]); const isInOptions = useCallback(option => timeOptions.some(opt => opt.id === option), [timeOptions]); const isValidDefaultSelected = defaultSelected ? isInOptions(defaultSelected) : false; const _useState4 = useState(isValidDefaultSelected ? defaultSelected : undefined), selected = _useState4[0], setSelected = _useState4[1]; const handleInputChange = useCallback(text => { setSearch(text); if (/\d{1,2}:\d{2}/.test(text.trim())) { return; } const doc = nlp(text); const parsed = doc.times().get()[0]; if (parsed && parsed["24h"] && parsed["24h"] !== selected) { const value = moment(parsed).format("HH:mm"); if (timeOptions.some(option => option.id === value)) { setSelected(value); onChange == null || onChange(value); setIsOpen(false); } } }, [onChange, selected, timeOptions]); const handleEmptyAction = newTime => { const time = String(newTime); if (isValidTime(time)) { const newOption = { id: time, name: mode === "12" ? moment(time, "HH:mm").format("hh:mm A") : time }; const newOptions = [...timeOptions]; const index = newOptions.findIndex(option => moment(option.id, "HH:mm") > moment(time, "HH:mm")); if (index === -1) { newOptions.push(newOption); } else { newOptions.splice(index, 0, newOption); } setAllTimeOptions(newOptions); onChange == null || onChange(time); setSelected(time); } }; const handleChange = e => { setSelected(e); onChange == null || onChange(e); }; const handleOpen = () => { setIsOpen(true); }; const handleClose = () => { setIsOpen(false); }; useEffect(() => { if (isOpen && selected) { var _document$getElementB; const selectedItem = (_document$getElementB = document.getElementById(selected)) == null ? void 0 : _document$getElementB.parentElement; selectedItem == null || selectedItem.scrollIntoView({ behavior: "smooth", block: "center" }); } }, [isOpen, selected]); useEffect(() => { if (defaultSelected !== selected && timeOptions.some(opt => opt.id === defaultSelected)) setSelected(defaultSelected); // eslint-disable-next-line react-hooks/exhaustive-deps }, [defaultSelected, timeOptions]); const isValid = time => !isInOptions(time) && isValidTime(time); return /*#__PURE__*/React.createElement(StyledInputTimeWrapper, { className: classNames("c-input-time", className) }, /*#__PURE__*/React.createElement(ComboBox, _extends({}, rest, { options: timeOptions, open: isOpen, disabledInternalSort: true, selected: selected, keepSameOptionsOrder: true, onInputChange: handleInputChange, onChange: handleChange, handleEmptyAction: handleEmptyAction, emptyValue: isValid(search) ? addCustomTimeLabel + " " + search : undefined, forceCloseMenu: true, placeholder: placeholder, renderOption: renderOption, autoHeightMax: 226, size: size, onClose: handleClose, onOpen: handleOpen, triggerMode: triggerMode, disabled: disabled, invalid: invalid, disableVirtualization: !enableVirtualization }))); }; //# sourceMappingURL=InputTime.js.map