UNPKG

@heycar-uikit/core

Version:
113 lines (107 loc) 6.89 kB
var components_DropdownOption = require('./DropdownOption-32ed4ed1.js'); var React = require('react'); var cn = require('classnames'); var icons = require('../icons'); var Input = require('../input'); 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 = {"container":"dropdown__container_5a833","disabled":"dropdown__disabled_5a833","value":"dropdown__value_5a833","options":"dropdown__options_5a833","show":"dropdown__show_5a833","option":"dropdown__option_5a833","selected":"dropdown__selected_5a833","highlighted":"dropdown__highlighted_5a833","fullWidth":"dropdown__fullWidth_5a833"}; require('./styles/default.css'); 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.container, disabled && styles.disabled, fullWidth && styles.fullWidth); var valueClassNames = cn__default["default"](disabled && 'disabled', styles.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.options + " " + (isOpen ? styles.show : ''), "data-test-id": dataTestId }, options.map(function (option, index) { return (React__default["default"].createElement("li", { className: styles.option + " " + (isOptionSelection(option) ? styles.selected : '') + " " + (index === highlightedIndex ? styles.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;