UNPKG

@ozen-ui/kit

Version:

React component library

185 lines (184 loc) 11.3 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Select = void 0; var tslib_1 = require("tslib"); require("./Select.css"); var react_1 = tslib_1.__importStar(require("react")); var logger_1 = require("@ozen-ui/logger"); var react_is_1 = require("react-is"); var useControlled_1 = require("../../hooks/useControlled"); var useDevEffect_1 = require("../../hooks/useDevEffect"); var useMultiRef_1 = require("../../hooks/useMultiRef"); var useThemeProps_1 = require("../../hooks/useThemeProps"); var utils_1 = require("../../utils"); var isKeys_1 = require("../../utils/isKeys"); var isString_1 = require("../../utils/isString"); var DataList_1 = require("../DataList"); var components_1 = require("./components"); var constants_1 = require("./constants"); var helpers_1 = require("./helpers"); var SelectContext_1 = require("./SelectContext"); var SelectRender = function (inProps, ref) { var props = (0, useThemeProps_1.useThemeProps)({ props: inProps, name: 'Select', }); var _a = props.size, size = _a === void 0 ? constants_1.SELECT_DEFAULT_SIZE : _a, _b = props.autoFocus, autoFocus = _b === void 0 ? constants_1.SELECT_DEFAULT_AUTO_FOCUS : _b, _c = props.fullWidth, fullWidth = _c === void 0 ? constants_1.SELECT_DEFAULT_FULL_WIDTH : _c, _d = props.disabled, disabled = _d === void 0 ? constants_1.SELECT_DEFAULT_DISABLED : _d, _e = props.required, required = _e === void 0 ? constants_1.SELECT_DEFAULT_REQUIRED : _e, _f = props.multiline, multiline = _f === void 0 ? constants_1.SELECT_DEFAULT_MULTILINE : _f, _g = props.defaultOpen, defaultOpen = _g === void 0 ? constants_1.SELECT_DEFAULT_DEFAULT_OPEN : _g, _h = props.renderRightLayout, renderRightLayout = _h === void 0 ? constants_1.SELECT_DEFAULT_RENDER_RIGHT_LAYOUT : _h, valueProp = props.value, defaultValue = props.defaultValue, onChange = props.onChange, renderValueProp = props.renderValue, children = props.children, onClick = props.onClick, onKeyDown = props.onKeyDown, menuProps = props.menuProps, dataListPropsProp = props.dataListProps, bodyProps = props.bodyProps, bodyRefProp = props.bodyRef, onCloseProp = props.onClose, onOpenProp = props.onOpen, openProp = props.open, multiple = props.multiple, _j = props.showClearButton, showClearButton = _j === void 0 ? constants_1.SELECT_DEFAULT_SHOW_CLEAR_BUTTON : _j, renderLeft = props.renderLeft, renderRight = props.renderRight, onClearProp = props.onClear, clearText = props.clearText, _k = props.error, error = _k === void 0 ? constants_1.SELECT_DEFAULT_ERROR : _k, other = tslib_1.__rest(props, ["size", "autoFocus", "fullWidth", "disabled", "required", "multiline", "defaultOpen", "renderRightLayout", "value", "defaultValue", "onChange", "renderValue", "children", "onClick", "onKeyDown", "menuProps", "dataListProps", "bodyProps", "bodyRef", "onClose", "onOpen", "open", "multiple", "showClearButton", "renderLeft", "renderRight", "onClear", "clearText", "error"]); (0, useDevEffect_1.useDevEffect)(function () { if (renderRightLayout.length !== new Set(renderRightLayout).size) { logger_1.logger.error("\u0412 renderRightLayout [".concat(renderRightLayout.map(function (element) { return "\"".concat(element, "\""); }).join(', '), "] \u0435\u0441\u0442\u044C \u0434\u0443\u0431\u043B\u0438\u0440\u0443\u044E\u0449\u0438\u0435 \u044D\u043B\u0435\u043C\u0435\u043D\u0442\u044B, \u043F\u0435\u0440\u0435\u043F\u0440\u043E\u0432\u0435\u0440\u044C\u0442\u0435 \u043F\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0435\u043C\u044B\u0435 \u0434\u0430\u043D\u043D\u044B\u0435.")); } }, [renderRightLayout]); var bodyInnerRef = (0, react_1.useRef)(null); var bodyRef = (0, useMultiRef_1.useMultiRef)([(bodyProps === null || bodyProps === void 0 ? void 0 : bodyProps.ref) || bodyRefProp, bodyInnerRef]); var dataListProps = dataListPropsProp || menuProps; var _l = tslib_1.__read((0, useControlled_1.useControlled)({ value: valueProp, defaultValue: defaultValue, name: 'Select', state: 'value', }), 2), valueState = _l[0], setValueState = _l[1]; var _m = tslib_1.__read((0, useControlled_1.useControlled)({ value: openProp, defaultValue: defaultOpen, name: 'Select', state: 'open', }), 2), open = _m[0], setOpen = _m[1]; var currentLabel; var isNotSelectOption = function (child) { return !(0, react_1.isValidElement)(child) || child.type !== DataList_1.DataListOption; }; var resolvedChildren = (0, react_is_1.isFragment)(children) ? children.props.children : children; react_1.Children.forEach(resolvedChildren, function (child) { var _a, _b; if (!isNotSelectOption(child)) { var label = (0, isString_1.isString)(child.props.children) ? (_a = child.props.label) !== null && _a !== void 0 ? _a : child.props.children : child.props.label; var params = tslib_1.__assign(tslib_1.__assign({}, inProps), { multiple: multiple, value: valueState }); if ((0, helpers_1.isMultipleParams)(params) && (0, helpers_1.isMultipleLabel)(currentLabel, multiple)) { var selected = (_b = params.value) === null || _b === void 0 ? void 0 : _b.includes(child.props.value); if (selected) currentLabel = tslib_1.__spreadArray(tslib_1.__spreadArray([], tslib_1.__read((currentLabel || [])), false), [ label, ], false); } if ((0, helpers_1.isNotMultipleParams)(params) && (0, helpers_1.isNotMultipleLabel)(currentLabel, multiple)) { var selected = params.value === child.props.value; if (selected) currentLabel = label; } } }); var handleClose = function () { setOpen(false); onCloseProp === null || onCloseProp === void 0 ? void 0 : onCloseProp(); }; var handleOpen = function () { setOpen(true); onOpenProp === null || onOpenProp === void 0 ? void 0 : onOpenProp(); }; var handleToggle = function () { if (disabled) return; if (open) handleClose(); else handleOpen(); }; var handleClick = function (e) { onClick === null || onClick === void 0 ? void 0 : onClick(e); handleToggle(); }; /** Управление элементом контроля через клавиатуру */ var handleKeyDown = function (e) { if ((0, isKeys_1.isKeys)(e, ['Space', 'ArrowDown', 'ArrowUp']) && !open) { e.preventDefault(); handleToggle(); } onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(e); }; /** Событие выбора значения из раскрывающегося списка */ var handleChange = function (e, _a) { var value = _a.value; setValueState(value); onChange === null || onChange === void 0 ? void 0 : onChange(value, e); if (!multiple) handleClose(); }; /** Представление значение элемента контроля по умолчанию */ var renderDefaultValue = function (option) { var _a = option.label, label = _a === void 0 ? '' : _a, _b = option.value, value = _b === void 0 ? '' : _b; if (!value && value !== 0) return null; if ((0, helpers_1.isMultipleLabel)(label, multiple)) return react_1.default.createElement("span", null, tslib_1.__spreadArray([], tslib_1.__read(label), false).join(', ')); if ((0, helpers_1.isNotMultipleLabel)(label, multiple)) return react_1.default.createElement("span", null, label); return null; }; /** Значение для текстового поля компонента */ var inputValue = function () { var _a; var params = { multiple: multiple, value: valueState, }; if ((0, helpers_1.isMultipleParams)(params)) return ((_a = params.value) === null || _a === void 0 ? void 0 : _a.join(',')) || ''; if ((0, helpers_1.isNotMultipleParams)(params)) return (params === null || params === void 0 ? void 0 : params.value) || ''; return ''; }; var onClear = function (event) { setValueState(undefined); onChange === null || onChange === void 0 ? void 0 : onChange(undefined, event); onClearProp === null || onClearProp === void 0 ? void 0 : onClearProp(event); }; /** Представление значение элемента контроля */ var renderValue = renderValueProp || renderDefaultValue; var hasValue = (0, utils_1.isArray)(valueState) ? valueState.length > 0 : (0, utils_1.isNotNil)(valueState); (0, react_1.useEffect)(function () { var _a; /** Устанавливает фокус на элементе контроля * если компонент по умолчанию открыт — defaultOpen={true} * и является неконтролируемым */ if (defaultOpen) (_a = bodyInnerRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, []); (0, react_1.useEffect)(function () { var _a; /** Автофокус на элементе контроля */ if (autoFocus) (_a = bodyInnerRef.current) === null || _a === void 0 ? void 0 : _a.focus(); }, [autoFocus]); return (react_1.default.createElement(SelectContext_1.SelectContext.Provider, { value: { open: open !== null && open !== void 0 ? open : false, hasValue: hasValue, size: size, disabled: disabled, renderRightLayout: renderRightLayout, showClearButton: showClearButton, fullWidth: fullWidth, required: required, multiline: multiline, onClear: onClear, clearText: clearText !== null && clearText !== void 0 ? clearText : '', renderRight: renderRight, renderLeft: renderLeft, error: error, } }, react_1.default.createElement(components_1.SelectInput, tslib_1.__assign({}, other, { value: inputValue(), onClick: handleClick, onKeyDown: handleKeyDown, renderedValue: renderValue({ label: currentLabel, value: valueState, }), bodyProps: tslib_1.__assign(tslib_1.__assign({}, bodyProps), { ref: bodyRef }), ref: ref })), react_1.default.createElement(DataList_1.DataList, tslib_1.__assign({ equalAnchorWidth: true }, dataListProps, { listProps: tslib_1.__assign({ size: size, role: 'listbox' }, dataListProps === null || dataListProps === void 0 ? void 0 : dataListProps.listProps), open: open, multiple: multiple, onClose: handleClose, onSelect: handleChange, anchorRef: bodyInnerRef, // TODO: add `null` to `DataListSelected` selected: (valueState || null) }), children))); }; exports.Select = (0, react_1.forwardRef)(SelectRender); exports.Select.displayName = 'Select';