UNPKG

@yandex/ui

Version:

Yandex UI components

81 lines (80 loc) 5.87 kB
"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;