UNPKG

@activecollab/components

Version:

ActiveCollab Components

148 lines 5.38 kB
import _extends from "@babel/runtime/helpers/esm/extends"; 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 { mode = "24", selected: defaultSelected, min = "00:00", max = "23:45", onChange, step = 15, size, className, placeholder, triggerMode, disabled, invalid, enableVirtualization = false, addCustomTimeLabel = "Add", ...rest } = _ref; const [isOpen, setIsOpen] = useState(false); const [search, setSearch] = useState(undefined); 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 [allTimeOptions, setAllTimeOptions] = useState(generateTimeOptions()); 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 [selected, setSelected] = useState(isValidDefaultSelected ? defaultSelected : undefined); 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