UNPKG

@ozen-ui/kit

Version:

React component library

151 lines (150 loc) 8.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DataList = exports.cnDataList = void 0; var tslib_1 = require("tslib"); require("./DataList.css"); var react_1 = tslib_1.__importStar(require("react")); var react_is_1 = require("react-is"); var useControlled_1 = require("../../hooks/useControlled"); var useEventListener_1 = require("../../hooks/useEventListener"); var useMultiRef_1 = require("../../hooks/useMultiRef"); var usePrevious_1 = require("../../hooks/usePrevious"); var useThemeProps_1 = require("../../hooks/useThemeProps"); var classname_1 = require("../../utils/classname"); var getPaperSizeToFormElement_1 = require("../../utils/getPaperSizeToFormElement"); var isKey_1 = require("../../utils/isKey"); var polymorphicComponentWithRef_1 = require("../../utils/polymorphicComponentWithRef"); var scrollContainerToElement_1 = require("../../utils/scrollContainerToElement"); var List_1 = require("../List"); var Popover_1 = require("../Popover"); var constants_1 = require("./constants"); var helpers_1 = require("./helpers"); var index_1 = require("./index"); var utils_1 = require("./utils"); exports.cnDataList = (0, classname_1.cn)('DataList'); var DataListRender = function (inProps, ref) { var _a = (0, useThemeProps_1.useThemeProps)({ props: inProps, name: 'DataList' }), _b = _a.as, as = _b === void 0 ? constants_1.DATA_LIST_DEFAULT_TAG : _b, _c = _a.open, open = _c === void 0 ? constants_1.DATA_LIST_DEFAULT_OPEN : _c, _d = _a.size, size = _d === void 0 ? constants_1.DATA_LIST_DEFAULT_SIZE : _d, name = _a.name, onClose = _a.onClose, children = _a.children, listProps = _a.listProps, anchorRef = _a.anchorRef, className = _a.className, defaultSelected = _a.defaultSelected, onSelectProp = _a.onSelect, selectedProp = _a.selected, other = tslib_1.__rest(_a, ["as", "open", "size", "name", "onClose", "children", "listProps", "anchorRef", "className", "defaultSelected", "onSelect", "selected"]); var dataListRef = (0, react_1.useRef)(null); var listRef = (0, react_1.useRef)(null); var radius = (0, getPaperSizeToFormElement_1.getPaperSizeToFormElement)(size); var _e = tslib_1.__read((0, useControlled_1.useControlled)({ name: 'DataList', defaultValue: defaultSelected, value: selectedProp, state: 'selected', }), 2), selectedState = _e[0], setSelected = _e[1]; var nodes = (0, react_1.useMemo)(function () { return new Map(); }, [children]); var items = (0, react_1.useMemo)(function () { return new Array(); }, [children]); var resolvedChildren = (0, react_is_1.isFragment)(children) ? children.props.children : children; var isNotSelectOption = function (child) { return !(0, react_1.isValidElement)(child) || child.type !== index_1.DataListOption || !!child.props.disabled; }; (0, react_1.useEffect)(function () { react_1.Children.forEach(resolvedChildren, function (child, idx) { if (!isNotSelectOption(child)) { items.push(child.props.value); nodes.set(child.props.value, idx); } }); }, [children]); var handleSelect = function (event, value) { var onSelect = function (e, payload) { setSelected(payload.value); onSelectProp === null || onSelectProp === void 0 ? void 0 : onSelectProp(e, payload); }; var params = tslib_1.__assign(tslib_1.__assign({}, inProps), { onSelect: onSelect, selected: selectedState }); if ((0, helpers_1.isNotMultipleParams)(params)) { var onSelect_1 = params.onSelect; onSelect_1 === null || onSelect_1 === void 0 ? void 0 : onSelect_1(event, { name: name, value: value }); } if ((0, helpers_1.isMultipleParams)(params)) { var selected = params.selected, onSelect_2 = params.onSelect; var res = (selected === null || selected === void 0 ? void 0 : selected.includes(value || '')) ? selected.filter(function (item) { return item !== value; }) : tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read((selected || [])), false), [value], false); onSelect_2 === null || onSelect_2 === void 0 ? void 0 : onSelect_2(event, { name: name, value: res }); } }; var handleOnMouseDownList = function (e) { var _a; e.preventDefault(); (_a = listProps === null || listProps === void 0 ? void 0 : listProps.onMouseDown) === null || _a === void 0 ? void 0 : _a.call(listProps, e); }; // Навигация по списку var _f = (0, utils_1.useDataListNavigation)({ items: items, active: open, selected: (0, utils_1.lastSelectedValue)(selectedState), onSelect: function (event, item) { handleSelect(event, item !== null && item !== void 0 ? item : ''); }, }), current = _f.current, focused = _f.focused, onKeyDown = _f.onKeyDown, onClick = _f.onClick; var previousCurrent = (0, usePrevious_1.usePrevious)(current); (0, react_1.useEffect)(function () { var _a, _b; var firstCurrent = (previousCurrent === null || previousCurrent === undefined) && current !== null && current !== undefined ? current : undefined; var selected = focused !== null && focused !== void 0 ? focused : firstCurrent; // Находит элемент по ключу var idx = selected !== undefined && selected !== null ? nodes.get(selected) : undefined; if (idx !== undefined) { // Прокрутка списка (0, scrollContainerToElement_1.scrollContainerToElement)({ container: dataListRef.current, element: (_b = (_a = listRef.current) === null || _a === void 0 ? void 0 : _a.children) === null || _b === void 0 ? void 0 : _b[idx], behavior: focused !== undefined && focused !== null ? 'smooth' : 'instant', }); } }, [focused, current, previousCurrent]); // Назначает элементу контроля событие управления списком с клавиатуры (0, useEventListener_1.useEventListener)({ eventName: 'keydown', element: anchorRef, handler: function (event) { return onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event); }, }); // Закрывает список по нажатию на клавишу {Tab} (0, useEventListener_1.useEventListener)({ active: open, eventName: 'keydown', element: anchorRef, handler: function (event) { if ((0, isKey_1.isKey)(event, 'Tab')) onClose === null || onClose === void 0 ? void 0 : onClose(); }, }); // Представление раскрывающегося списка var renderChildren = (0, react_1.useMemo)(function () { return react_1.Children.map(resolvedChildren, function (child) { if (isNotSelectOption(child)) { return child; } var key = child.props.value; var elementChild = child; var props = { onClick: function (event) { var _a, _b; onClick === null || onClick === void 0 ? void 0 : onClick(event, key); (_b = (_a = child.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, event); }, focused: key === focused, selected: Array.isArray(selectedState) ? selectedState.includes(key) : selectedState === key, }; return (0, react_1.cloneElement)(elementChild, props); }); }, [resolvedChildren, selectedState, focused, onClick]); return (react_1.default.createElement(Popover_1.Popover, tslib_1.__assign({ open: open, offset: [0, 4], radius: radius, onClose: onClose, strategy: "absolute", anchorRef: anchorRef, as: as, placement: "bottom-start", transitionProps: { classNames: 'DataList-animation' }, className: (0, exports.cnDataList)('', [className]), disableReturnFocus: true, disableEnforceFocus: true }, other, { ref: (0, useMultiRef_1.useMultiRef)([ref, dataListRef]) }), react_1.default.createElement(List_1.List, tslib_1.__assign({ as: "ul", size: size }, listProps, { onMouseDown: handleOnMouseDownList, ref: (0, useMultiRef_1.useMultiRef)([listRef, listProps === null || listProps === void 0 ? void 0 : listProps.ref]) }), renderChildren))); }; exports.DataList = (0, polymorphicComponentWithRef_1.polymorphicComponentWithRef)(DataListRender); exports.DataList.displayName = 'DataList';