UNPKG

@yandex/ui

Version:

Yandex UI components

77 lines (76 loc) 5.14 kB
import { __assign, __rest } from "tslib"; import React from 'react'; import { Registry, withRegistry } from '@bem-react/di'; import { compose } from '@bem-react/core'; import { cn } from '@bem-react/classname'; import { Select, cnSelect } from '../../Select.bundle/desktop'; import { withOutsideClick } from '../../../withOutsideClick/withOutsideClick'; import { withZIndex } from '../../../withZIndex/withZIndex'; import { Popup } from '../../../Popup/Popup.bundle/desktop'; import { Menu } from '../../../Menu/Menu.bundle/desktop'; import { Icon } from '../../../Icon/Icon.bundle/desktop'; import { Text } from '../../../Text/Text.bundle/desktop'; import { Button } from '../../../Button/Button.bundle/desktop'; import { ListTile } from '../../../ListTile/ListTile'; import { Textinput } from '../../../Textinput/Textinput.bundle/desktop'; import { Spin } from '../../../Spin/Spin.bundle/desktop'; import { Spacer } from '../../../Spacer/Spacer'; import { UserPic } from '../../../UserPic/UserPic@desktop'; import './index.css'; var c = cn('ComboBox'); var SelectedItemContext = React.createContext(undefined); var SearchTextContext = React.createContext(undefined); var Option = function (props) { return (React.createElement(ListTile, { leading: React.createElement(UserPic, { className: c('Avatar'), lodpiUrl: props.avatar }), leftSpace: "m", alignItems: "center", rightSpace: "m", trailing: React.createElement(Icon, { glyph: "type-check" }) }, React.createElement(Text, { as: "div", typography: "control-xl" }, props.title), React.createElement(Text, { as: "div", typography: "control-s", color: "secondary" }, props.subtitle))); }; var Trigger = function (_a) { var className = _a.className, props = __rest(_a, ["className"]); var item = React.useContext(SelectedItemContext); var pressKeys = React.useMemo(function () { return []; }, []); return (React.createElement(Button, __assign({}, props, { pressKeys: pressKeys, className: className + " " + c('Trigger'), iconRight: props.iconRight }), item ? React.createElement(Option, __assign({}, item)) : '-')); }; var MenuWithSearch = function (props) { var _a = React.useContext(SearchTextContext), searchText = _a.searchText, searchInProgress = _a.searchInProgress, onChangeSearchText = _a.onChangeSearchText; var inputRef = React.useRef(null); var initialActiveElement = React.useRef(null); // Фокусируемся на текстовом поле при открытии попапа, возвращаем фокус при закрытии React.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.createElement("div", { className: c('MenuWithSearch') }, React.createElement("div", { className: c('Search') }, React.createElement(Textinput, { controlRef: inputRef, view: "default", size: "m", value: searchText, onChange: function (e) { return onChangeSearchText(e.target.value); }, iconRight: searchInProgress ? React.createElement(Spacer, { all: "10px" }, React.createElement(Spin, { view: "default", size: "xxs", progress: true })) : undefined })), React.createElement(Menu, __assign({}, props)))); }; var registry = new Registry({ id: cnSelect() }) .set('Trigger', Trigger) .set('Popup', compose(withOutsideClick, withZIndex)(Popup)) .set('Menu', MenuWithSearch) .set('Icon', Icon); var CustomSelect = withRegistry(registry)(Select); export var ComboBox = function (_a) { var searchText = _a.searchText, searchInProgress = _a.searchInProgress, onChangeSearchText = _a.onChangeSearchText, value = _a.value, items = _a.options, onChange = _a.onChange, props = __rest(_a, ["searchText", "searchInProgress", "onChangeSearchText", "value", "options", "onChange"]); var options = React.useMemo(function () { return items.map(function (item) { return (__assign(__assign({}, item), { value: item.id, content: (React.createElement(Option, __assign({}, item))) })); }); }, [items]); var searchTextValue = React.useMemo(function () { return ({ searchText: searchText, searchInProgress: searchInProgress, onChangeSearchText: onChangeSearchText, }); }, [searchText, searchInProgress, onChangeSearchText]); var handleChange = React.useCallback(function (e) { onChange(items.find((function (item) { return item.id === e.target.value; }))); }, [onChange, items]); return (React.createElement(SelectedItemContext.Provider, { value: value }, React.createElement(SearchTextContext.Provider, { value: searchTextValue }, React.createElement(CustomSelect, __assign({ className: c(), view: "default", size: "m", value: value && value.id, onChange: handleChange, options: options }, props))))); };