@i-novus/ui-core
Version:
Базовые UI компоненты
108 lines (107 loc) • 4.64 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { forwardRef, useCallback, useEffect, useState } from 'react';
import classNames from 'classnames';
import { useConfigProvider } from '../../core';
import { OptionList } from './components';
import { defaultOptions, noOption } from './constants';
import { DropdownInput } from './DropdownInput';
import { MultipleSelector } from './MultipleSelector';
// eslint-disable-next-line sonarjs/cognitive-complexity
export const Select = forwardRef((props, ref) => {
const { prefix, className, value, options = defaultOptions, onChange, onSearch, onScroll, onOpen, style, visible = true, multiple = false, disabled = false, type, emptyText, loading, ...restProps } = props;
const [dropdownOptions, setDropdownOptions] = useState(defaultOptions);
const [selectedOptions, setSelectedOptions] = useState(defaultOptions);
const [inputValue, setInputValue] = useState('');
const { getPrefix } = useConfigProvider();
const prefixCls = getPrefix(prefix);
const onOptionClick = useCallback((newValue, event) => {
setSelectedOptions(newValue);
if (multiple) {
// @ts-ignore
onChange(newValue, event);
}
else {
const [selectedOption] = newValue;
if (selectedOption) {
// @ts-ignore
onChange(selectedOption, event);
setInputValue(selectedOption.label);
}
}
}, [multiple, onChange]);
const onInputValueChange = useCallback((newValue, event) => {
if (!multiple) {
setInputValue('');
setSelectedOptions([]);
}
// @ts-ignore
onChange?.(null, event);
}, [multiple, onChange]);
const onCloseTag = useCallback((id, evt) => {
setSelectedOptions((prev) => {
const newSelectedOptions = prev.filter(item => item.id !== id);
// @ts-ignore
onChange?.(newSelectedOptions, evt);
return newSelectedOptions;
});
}, [onChange]);
const handleOpen = useCallback((event) => {
if (onOpen) {
onOpen(event);
}
setDropdownOptions(() => {
if (loading) {
return [];
}
if (options.length) {
return options;
}
return [{ ...noOption, label: emptyText || noOption.label }];
});
}, [emptyText, options, onOpen, loading]);
useEffect(() => {
if (Array.isArray(value)) {
setSelectedOptions(value);
}
else if (value && typeof value === 'object' && 'label' in value) {
setSelectedOptions([value]);
setInputValue(value.label);
}
else {
setSelectedOptions([]);
setInputValue('');
}
}, [value]);
useEffect(() => { setDropdownOptions(options); }, [options, loading]);
const handleClearAllSelectedOptions = useCallback((event) => {
event.stopPropagation();
onInputValueChange('');
setSelectedOptions(defaultOptions);
// @ts-ignore
onChange?.(defaultOptions, event);
}, [onInputValueChange, onChange]);
if (!visible) {
return null;
}
if (multiple) {
return (_jsx("div", { className: classNames(className, `${prefixCls}-multiple-selector`), style: style, children: _jsx(MultipleSelector, { ...restProps, disableInput: true, disabled: disabled, ref: ref, prefixCls: prefixCls, value: inputValue, onChange: onInputValueChange, onOpen: handleOpen, dropdownInnerComponent: OptionList, dropdownInnerComponentProps: {
options: dropdownOptions,
selected: selectedOptions,
onOptionClick,
multiple,
onScroll,
}, tagListProps: {
selectedOptions,
onCloseTag,
handleClearAllSelectedOptions,
} }) }));
}
return (_jsx("div", { className: classNames(className, `${prefixCls}-select`), style: style, children: _jsx(DropdownInput, { ...restProps, disableInput: true, loading: loading, ref: ref, prefixCls: prefixCls, value: inputValue, onChange: onInputValueChange, dropdownInnerComponent: OptionList, disabled: disabled, type: type, onOpen: handleOpen, dropdownInnerComponentProps: {
options: dropdownOptions,
selected: selectedOptions,
onOptionClick,
multiple,
onScroll,
} }) }));
});
Select.displayName = 'Select';