@heycar-uikit/core
Version:
The React UI library from HeyCar
113 lines (108 loc) • 6.87 kB
JavaScript
var components_DropdownOption = require('./DropdownOption-245a1217.js');
var React = require('react');
var cn = require('classnames');
var icons = require('../../icons/cssm');
var Input = require('../../input/cssm');
var styles = require('./styles/default.module.css');
require('./components/option.module.css');
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
var React__default = /*#__PURE__*/_interopDefaultLegacy(React);
var cn__default = /*#__PURE__*/_interopDefaultLegacy(cn);
var Input__default = /*#__PURE__*/_interopDefaultLegacy(Input);
var styles__default = /*#__PURE__*/_interopDefaultLegacy(styles);
function Dropdown(_a) {
var _b = _a.Component, Component = _b === void 0 ? 'div' : _b, value = _a.value, onChange = _a.onChange, options = _a.options, disabled = _a.disabled, dataTestId = _a.dataTestId, onBlur = _a.onBlur, onClick = _a.onClick, label = _a.label, hint = _a.hint, inputRef = _a.inputRef, fullWidth = _a.fullWidth, placeholder = _a.placeholder, error = _a.error, onKeyDown = _a.onKeyDown, restProps = components_DropdownOption.__rest(_a, ["Component", "value", "onChange", "options", "disabled", "dataTestId", "onBlur", "onClick", "label", "hint", "inputRef", "fullWidth", "placeholder", "error", "onKeyDown"]);
var _c = React.useState(value), stateValue = _c[0], setStateValue = _c[1];
var _d = React.useState(false), isOpen = _d[0], setIsOpen = _d[1];
var _e = React.useState(0), highlightedIndex = _e[0], setHighlightedIndex = _e[1];
var containerRef = React.useRef(null);
var isValueIncludedInOptions = React.useCallback(function (option) {
return !!options.find(function (o) { return Object.entries(o).every(function (_a) {
var key = _a[0], val = _a[1];
return val === option[key];
}); });
}, [options]);
React.useEffect(function () {
if (options.length === 0)
setStateValue(undefined);
if (value && !isValueIncludedInOptions(value))
setStateValue(undefined);
if (stateValue && !isValueIncludedInOptions(stateValue))
setStateValue(undefined);
if (!stateValue && value && isValueIncludedInOptions(value))
setStateValue(value);
}, [value, options, stateValue, isValueIncludedInOptions]);
var selectOption = React.useCallback(function (option) {
if (onChange) {
if (option !== stateValue)
onChange(option);
}
setStateValue(option);
}, [onChange, stateValue]);
var onClickHandler = React.useCallback(function () {
onClick === null || onClick === void 0 ? void 0 : onClick();
if (!disabled)
setIsOpen(function (nextState) { return !nextState; });
}, [onClick, disabled, setIsOpen]);
React.useEffect(function () {
if (isOpen)
setHighlightedIndex(0);
}, [isOpen]);
React.useEffect(function () {
var _a;
var handler = function (e) {
if (e.target != containerRef.current)
return;
switch (e.code) {
case 'Enter':
case 'Space':
setIsOpen(function (prev) { return !prev; });
if (isOpen)
selectOption(options[highlightedIndex]);
break;
case 'ArrowUp':
case 'ArrowDown': {
if (!isOpen) {
setIsOpen(true);
break;
}
var newValue = highlightedIndex + (e.code === 'ArrowDown' ? 1 : -1);
if (newValue >= 0 && newValue < options.length) {
setHighlightedIndex(newValue);
}
break;
}
case 'Escape':
setIsOpen(false);
break;
}
};
(_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.addEventListener('keydown', handler);
return function () {
var _a;
// eslint-disable-next-line react-hooks/exhaustive-deps
(_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.removeEventListener('keydown', handler);
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [highlightedIndex, options, selectOption]);
var isOptionSelection = function (option) {
return (option === null || option === void 0 ? void 0 : option.value) === (stateValue === null || stateValue === void 0 ? void 0 : stateValue.value);
};
var onBlurHandler = React.useCallback(function () {
onBlur === null || onBlur === void 0 ? void 0 : onBlur();
setIsOpen(false);
}, [onBlur, setIsOpen]);
var classNames = cn__default["default"](styles__default["default"].container, disabled && styles__default["default"].disabled, fullWidth && styles__default["default"].fullWidth);
var valueClassNames = cn__default["default"](disabled && 'disabled', styles__default["default"].value);
return (React__default["default"].createElement(Component, { className: classNames, onBlur: onBlurHandler, onClick: onClickHandler, ref: containerRef, tabIndex: 0 },
React__default["default"].createElement(Input__default["default"], components_DropdownOption.__assign({ "aria-disabled": true, className: valueClassNames, disabled: disabled, error: error, fullWidth: true, hint: hint, label: label, onChange: function () {
setStateValue(options[highlightedIndex]);
}, onKeyDown: onKeyDown, placeholder: placeholder, ref: inputRef, rightIcon: isOpen ? React__default["default"].createElement(icons.ChevronTop, null) : React__default["default"].createElement(icons.ChevronDown, null), value: stateValue === null || stateValue === void 0 ? void 0 : stateValue.label }, restProps)),
React__default["default"].createElement("ul", { className: styles__default["default"].options + " " + (isOpen ? styles__default["default"].show : ''), "data-test-id": dataTestId }, options.map(function (option, index) { return (React__default["default"].createElement("li", { className: styles__default["default"].option + " " + (isOptionSelection(option) ? styles__default["default"].selected : '') + " " + (index === highlightedIndex ? styles__default["default"].highlighted : ''), key: option.value, onMouseDown: function (e) {
selectOption(option);
e.stopPropagation();
setIsOpen(false);
}, onMouseEnter: function () { return setHighlightedIndex(index); } },
React__default["default"].createElement(components_DropdownOption.DropdownOption, components_DropdownOption.__assign({}, option)))); }))));
}
module.exports = Dropdown;