wix-style-react
Version:
310 lines (251 loc) • 11.9 kB
JavaScript
"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;