@yandex/ui
Version:
Yandex UI components
81 lines (80 loc) • 5.87 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ComboBox = void 0;
var tslib_1 = require("tslib");
var react_1 = tslib_1.__importDefault(require("react"));
var di_1 = require("@bem-react/di");
var core_1 = require("@bem-react/core");
var classname_1 = require("@bem-react/classname");
var desktop_1 = require("../../Select.bundle/desktop");
var withOutsideClick_1 = require("../../../withOutsideClick/withOutsideClick");
var withZIndex_1 = require("../../../withZIndex/withZIndex");
var desktop_2 = require("../../../Popup/Popup.bundle/desktop");
var desktop_3 = require("../../../Menu/Menu.bundle/desktop");
var desktop_4 = require("../../../Icon/Icon.bundle/desktop");
var desktop_5 = require("../../../Text/Text.bundle/desktop");
var desktop_6 = require("../../../Button/Button.bundle/desktop");
var ListTile_1 = require("../../../ListTile/ListTile");
var desktop_7 = require("../../../Textinput/Textinput.bundle/desktop");
var desktop_8 = require("../../../Spin/Spin.bundle/desktop");
var Spacer_1 = require("../../../Spacer/Spacer");
var UserPic_desktop_1 = require("../../../UserPic/UserPic@desktop");
require("./index.css");
var c = classname_1.cn('ComboBox');
var SelectedItemContext = react_1.default.createContext(undefined);
var SearchTextContext = react_1.default.createContext(undefined);
var Option = function (props) {
return (react_1.default.createElement(ListTile_1.ListTile, { leading: react_1.default.createElement(UserPic_desktop_1.UserPic, { className: c('Avatar'), lodpiUrl: props.avatar }), leftSpace: "m", alignItems: "center", rightSpace: "m", trailing: react_1.default.createElement(desktop_4.Icon, { glyph: "type-check" }) },
react_1.default.createElement(desktop_5.Text, { as: "div", typography: "control-xl" }, props.title),
react_1.default.createElement(desktop_5.Text, { as: "div", typography: "control-s", color: "secondary" }, props.subtitle)));
};
var Trigger = function (_a) {
var className = _a.className, props = tslib_1.__rest(_a, ["className"]);
var item = react_1.default.useContext(SelectedItemContext);
var pressKeys = react_1.default.useMemo(function () { return []; }, []);
return (react_1.default.createElement(desktop_6.Button, tslib_1.__assign({}, props, { pressKeys: pressKeys, className: className + " " + c('Trigger'), iconRight: props.iconRight }), item ? react_1.default.createElement(Option, tslib_1.__assign({}, item)) : '-'));
};
var MenuWithSearch = function (props) {
var _a = react_1.default.useContext(SearchTextContext), searchText = _a.searchText, searchInProgress = _a.searchInProgress, onChangeSearchText = _a.onChangeSearchText;
var inputRef = react_1.default.useRef(null);
var initialActiveElement = react_1.default.useRef(null);
// Фокусируемся на текстовом поле при открытии попапа, возвращаем фокус при закрытии
react_1.default.useLayoutEffect(function () {
var input = inputRef.current;
if (props.focused) {
initialActiveElement.current = document.activeElement;
input.focus();
input.setSelectionRange(0, Number.MAX_SAFE_INTEGER);
}
else if (input === document.activeElement && initialActiveElement.current) {
initialActiveElement.current.focus();
}
}, [props.focused]);
return (react_1.default.createElement("div", { className: c('MenuWithSearch') },
react_1.default.createElement("div", { className: c('Search') },
react_1.default.createElement(desktop_7.Textinput, { controlRef: inputRef, view: "default", size: "m", value: searchText, onChange: function (e) { return onChangeSearchText(e.target.value); }, iconRight: searchInProgress ? react_1.default.createElement(Spacer_1.Spacer, { all: "10px" },
react_1.default.createElement(desktop_8.Spin, { view: "default", size: "xxs", progress: true })) : undefined })),
react_1.default.createElement(desktop_3.Menu, tslib_1.__assign({}, props))));
};
var registry = new di_1.Registry({ id: desktop_1.cnSelect() })
.set('Trigger', Trigger)
.set('Popup', core_1.compose(withOutsideClick_1.withOutsideClick, withZIndex_1.withZIndex)(desktop_2.Popup))
.set('Menu', MenuWithSearch)
.set('Icon', desktop_4.Icon);
var CustomSelect = di_1.withRegistry(registry)(desktop_1.Select);
var ComboBox = function (_a) {
var searchText = _a.searchText, searchInProgress = _a.searchInProgress, onChangeSearchText = _a.onChangeSearchText, value = _a.value, items = _a.options, onChange = _a.onChange, props = tslib_1.__rest(_a, ["searchText", "searchInProgress", "onChangeSearchText", "value", "options", "onChange"]);
var options = react_1.default.useMemo(function () { return items.map(function (item) { return (tslib_1.__assign(tslib_1.__assign({}, item), { value: item.id, content: (react_1.default.createElement(Option, tslib_1.__assign({}, item))) })); }); }, [items]);
var searchTextValue = react_1.default.useMemo(function () { return ({
searchText: searchText,
searchInProgress: searchInProgress,
onChangeSearchText: onChangeSearchText,
}); }, [searchText, searchInProgress, onChangeSearchText]);
var handleChange = react_1.default.useCallback(function (e) {
onChange(items.find((function (item) { return item.id === e.target.value; })));
}, [onChange, items]);
return (react_1.default.createElement(SelectedItemContext.Provider, { value: value },
react_1.default.createElement(SearchTextContext.Provider, { value: searchTextValue },
react_1.default.createElement(CustomSelect, tslib_1.__assign({ className: c(), view: "default", size: "m", value: value && value.id, onChange: handleChange, options: options }, props)))));
};
exports.ComboBox = ComboBox;