UNPKG

wix-style-react

Version:
310 lines (251 loc) • 11.9 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports["default"] = exports.DEFAULT_TIME_STYLE = exports.DEFAULT_STEP = void 0; var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _Input = _interopRequireDefault(require("../Input")); var _DropdownBase = _interopRequireDefault(require("../DropdownBase")); var _constants = require("./constants"); var _TimeInputNextSt = require("./TimeInputNext.st.css"); var _wixDesignSystemsLocaleUtils = require("wix-design-systems-locale-utils"); var _context = require("../WixStyleReactEnvironmentProvider/context"); var _TimeInputNextUtils = require("./TimeInputNextUtils"); var _excluded = ["dataHook", "className", "size", "suffix", "prefix", "status", "statusMessage", "border", "disabled", "placeholder", "readOnly", "width", "value", "timeStyle", "onChange", "step", "noRightBorderRadius", "noLeftBorderRadius"]; function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || _typeof(obj) !== "object" && typeof obj !== "function") { return { "default": obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj["default"] = obj; if (cache) { cache.set(obj, newObj); } return newObj; } var DEFAULT_STEP = 15; exports.DEFAULT_STEP = DEFAULT_STEP; var DEFAULT_TIME_STYLE = 'short'; exports.DEFAULT_TIME_STYLE = DEFAULT_TIME_STYLE; var TimeInputNext = /*#__PURE__*/_react["default"].forwardRef(function (_ref, ref) { var dataHook = _ref.dataHook, className = _ref.className, size = _ref.size, suffix = _ref.suffix, prefix = _ref.prefix, status = _ref.status, statusMessage = _ref.statusMessage, border = _ref.border, disabled = _ref.disabled, placeholder = _ref.placeholder, readOnly = _ref.readOnly, width = _ref.width, value = _ref.value, timeStyle = _ref.timeStyle, onChange = _ref.onChange, step = _ref.step, noRightBorderRadius = _ref.noRightBorderRadius, noLeftBorderRadius = _ref.noLeftBorderRadius, rest = (0, _objectWithoutProperties2["default"])(_ref, _excluded); var inputRef = (0, _react.useRef)(); (0, _react.useImperativeHandle)(ref, function () { return { focus: function focus() { return inputRef.current.focus(); } }; }); var context = (0, _react.useContext)(_context.WixStyleReactEnvironmentContext); var locale = rest.locale || context.locale || 'en'; var timeSlots = (0, _react.useMemo)(function () { return (0, _TimeInputNextUtils.getTimeSlots)({ value: value, timeStyle: timeStyle, locale: locale, step: step }); }, [value, timeStyle, locale, step]); var _React$useState = _react["default"].useState(false), _React$useState2 = (0, _slicedToArray2["default"])(_React$useState, 2), isDropdownOpen = _React$useState2[0], setIsDropdownOpen = _React$useState2[1]; var _React$useState3 = _react["default"].useState(''), _React$useState4 = (0, _slicedToArray2["default"])(_React$useState3, 2), inputValue = _React$useState4[0], setInputValue = _React$useState4[1]; var _React$useState5 = _react["default"].useState(null), _React$useState6 = (0, _slicedToArray2["default"])(_React$useState5, 2), selectedId = _React$useState6[0], setSelectedId = _React$useState6[1]; var _React$useState7 = _react["default"].useState(null), _React$useState8 = (0, _slicedToArray2["default"])(_React$useState7, 2), highlightedOptionId = _React$useState8[0], setHighlightedOptionId = _React$useState8[1]; var _React$useState9 = _react["default"].useState(false), _React$useState10 = (0, _slicedToArray2["default"])(_React$useState9, 2), error = _React$useState10[0], setError = _React$useState10[1]; var validationError = error ? 'error' : undefined; var validationErrorMessage = error ? (0, _TimeInputNextUtils.getErorMessageByLocale)(locale) : undefined; (0, _react.useEffect)(function () { var timeSlot = value ? (0, _TimeInputNextUtils.getTimeSlot)({ value: value, timeStyle: timeStyle, locale: locale }) : (0, _TimeInputNextUtils.getClosestTimeSlot)({ value: value, timeSlots: timeSlots }); setInputValue(timeSlot.value); setSelectedId(timeSlot.id); }, [value, timeStyle, locale, timeSlots]); var onSelect = (0, _react.useCallback)(function (option) { setInputValue(option.value); setSelectedId(option.id); setIsDropdownOpen(false); onChange && onChange({ date: new Date(option.id) }); }, [onChange]); var _onKeyDown = (0, _react.useCallback)(function (e, delegateKeyDown) { if (e.key === ' ' || e.key === 'Spacebar') { return; } if (!isDropdownOpen && e.key === 'ArrowDown') { setIsDropdownOpen(true); return e.preventDefault(); } if (isDropdownOpen) { delegateKeyDown(e); if (e.key === 'Escape') { setIsDropdownOpen(false); return e.preventDefault(); } // should be handled by error validation if (!highlightedOptionId && e.key === 'Enter') { setIsDropdownOpen(false); return e.preventDefault(); } } }, [isDropdownOpen, highlightedOptionId]); var onInputChanged = function onInputChanged(e) { setInputValue(e.target.value); // validate input if ((0, _TimeInputNextUtils.isInputValid)(e.target.value)) { setError(false); } else { setError(true); setIsDropdownOpen(false); } // open dropdown when value is selected with keyboard and value is typed again if (!isDropdownOpen) { setIsDropdownOpen(true); } // stop selecting option when input value changes and doesn't match anymore if (e.target.value !== timeSlots[selectedId]) { setSelectedId(null); } var suggestedOption = (0, _TimeInputNextUtils.getSuggestedOption)(e.target.value, timeSlots); setHighlightedOptionId(suggestedOption ? suggestedOption.id : null); }; var onBlur = function onBlur() { var highlightedOption = timeSlots.find(function (slot) { return slot.id === highlightedOptionId; }); if (highlightedOption) { setInputValue(highlightedOption.value); setSelectedId(highlightedOption.id); } if (isDropdownOpen) { setIsDropdownOpen(false); } }; return /*#__PURE__*/_react["default"].createElement("div", { className: (0, _TimeInputNextSt.st)(_TimeInputNextSt.classes.root, className), style: { width: width }, "data-hook": dataHook, "data-value": selectedId, "data-locale": locale, "data-time-style": timeStyle }, /*#__PURE__*/_react["default"].createElement(_DropdownBase["default"], { dataHook: _constants.dataHooks.TimeInputNextDropdown, open: isDropdownOpen, onClickOutside: function onClickOutside() { return setIsDropdownOpen(false); }, options: timeSlots, onSelect: onSelect, selectedId: selectedId, maxHeight: "216px", markedOptionId: highlightedOptionId, focusOnOption: highlightedOptionId, focusOnSelectedOption: true, onMouseDown: function onMouseDown(e) { return e.preventDefault(); } }, function (_ref2) { var delegateKeyDown = _ref2.delegateKeyDown; return /*#__PURE__*/_react["default"].createElement(_Input["default"], { dataHook: _constants.dataHooks.TimeInputNextInput, size: size, status: status || validationError, statusMessage: statusMessage || validationErrorMessage, suffix: suffix && /*#__PURE__*/_react["default"].createElement(_Input["default"].Affix, null, suffix), prefix: prefix && /*#__PURE__*/_react["default"].createElement(_Input["default"].Affix, null, prefix), border: border, disabled: disabled, placeholder: placeholder, value: inputValue, onChange: onInputChanged, onInputClicked: function onInputClicked() { return !readOnly && setIsDropdownOpen(true); }, onKeyDown: function onKeyDown(e) { return _onKeyDown(e, delegateKeyDown); }, ref: inputRef, readOnly: readOnly, noLeftBorderRadius: noLeftBorderRadius, noRightBorderRadius: noRightBorderRadius, onBlur: onBlur }); })); }); TimeInputNext.displayName = 'TimeInputNext'; TimeInputNext.propTypes = { /** Control the border style of input */ border: _propTypes["default"].oneOf(['standard', 'round', 'bottomLine']), /** Specifies a CSS class name to be appended to the component’s root element */ className: _propTypes["default"].string, /** Applies a data-hook HTML attribute that can be used in the tests */ dataHook: _propTypes["default"].string, /** Specifies whether component is disabled */ disabled: _propTypes["default"].bool, /** Sets locale and formats time according to it */ locale: _propTypes["default"].oneOf(_wixDesignSystemsLocaleUtils.supportedWixlocales), /** Defines a callback function which is called on every time value changes */ onChange: _propTypes["default"].func, /** Sets a placeholder message to display */ placeholder: _propTypes["default"].string, /** Pass a component you want to show as the prefix of the input, e.g., text, icon */ prefix: _propTypes["default"].node, /** Specifies whether input is read only */ readOnly: _propTypes["default"].bool, /** Controls the size of the input */ size: _propTypes["default"].oneOf(['small', 'medium', 'large']), /** Specify the status of a field */ status: _propTypes["default"].oneOf(['error', 'warning', 'loading']), /** Defines the message to display on status icon hover. If not given or empty there will be no tooltip. */ statusMessage: _propTypes["default"].node, /** Specifies the interval between time values shown in dropdown */ step: _propTypes["default"].number, /** Pass a component you want to show as the suffix of the input, e.g., text, icon */ suffix: _propTypes["default"].node, /** Specifies what time formatting style to use when calling `format()` */ timeStyle: _propTypes["default"].string, /** Specifies the current value of the input */ value: _propTypes["default"].object, /** Controls the width of the component. `auto` will resize the input to match width of its contents, while `100%` will take up the full parent container width. */ width: _propTypes["default"].oneOf(['auto', '100%']) }; TimeInputNext.defaultProps = { width: 'auto', step: DEFAULT_STEP, timeStyle: DEFAULT_TIME_STYLE }; var _default = TimeInputNext; exports["default"] = _default;