xy-select
Version:
基于React的下拉列表组件
64 lines • 4.69 kB
JavaScript
import classNames from "classnames";
import React, { useLayoutEffect, useRef, useState } from "react";
import { useUpdateEffect } from "utils-hooks";
import Trigger from "xy-trigger";
import { OptionsContext, OptionStateContext, ValueContext } from "./Context";
import Dropdown from "./Dropdown";
import useNnavigate from "./Hooks/useNnavigate";
import useOptions from "./Hooks/useOptions";
import useValue from "./Hooks/useValue";
import useVisible from "./Hooks/useVisible";
import SelectBox from "./SelectInner/SelectBox";
import SelectSearch from "./SelectInner/SelectSearch";
var ACTION = ["click"];
var POPUPALIGN = { overflow: { adjust: false, flip: true } };
export var Select = React.forwardRef(function (props, innerRef) {
var _a;
var _b = props.prefixCls, prefixCls = _b === void 0 ? "xy-select" : _b, className = props.className, style = props.style, children = props.children, multiple = props.multiple, _c = props.stretch, stretch = _c === void 0 ? true : _c, popupClassName = props.popupClassName, _d = props.searchMode, searchMode = _d === void 0 ? false : _d, filter = props.filter, _e = props.disabled, disabled = _e === void 0 ? false : _e, placeholder = props.placeholder, empyPlaceholder = props.empyPlaceholder, onBlur = props.onBlur, renderSelectItem = props.renderSelectItem, _f = props.searchFilterDisabled, searchFilterDisabled = _f === void 0 ? false : _f;
if (!innerRef) {
innerRef = useRef(null);
}
var align = useRef(null);
// 由于 Trigger 的实现是用监听原生dom, 所以触发事件后, 事件处理函数所处的prop都是原来的
var disabledRef = useRef(disabled);
disabledRef.current = disabled;
var _g = useVisible(innerRef, disabledRef), visible = _g[0], setVisible = _g[1];
var _h = useValue(props, setVisible, align), value = _h[0], onSelect = _h[1], onUnSelect = _h[2], search = _h[3], searchHandle = _h[4];
var _j = useOptions(multiple, children), options = _j[0], optionsContextRef = _j[1], getOptionCfg = _j[2];
var _k = useNnavigate(options, value, onSelect, setVisible, searchMode, multiple), focusValue = _k[0], handleKeyPress = _k[1], scrollwrapRef = _k[2];
var classString = classNames(prefixCls, className, prefixCls + "-" + (multiple ? "multiple" : "single"), (_a = {},
_a[prefixCls + "-disabled"] = disabled,
_a[prefixCls + "-visible"] = visible,
_a[prefixCls + "-searchMode"] = searchMode,
_a[prefixCls + "-hide-item"] = search !== "",
_a[prefixCls + "-has-value"] = multiple ? value && value.length > 0 : !!value,
_a));
var selectedCfg = getOptionCfg(value);
var _l = useState(false), empty = _l[0], setEmpty = _l[1];
useUpdateEffect(function () {
var _empty = options.current.filter(function (x) { return !x.disabled && !x.filtered; }).length === 0 && search !== "" && searchFilterDisabled === false;
if (!searchMode && options.current.length === 0) {
_empty = true;
}
setEmpty(_empty);
});
// TODO: #1 上一次没有合适的 label 中文显示, 当childer的options改变后, 如果有合适的,就强制更新
// 搜索改变后也要重新对齐
useLayoutEffect(function () {
if (align.current) {
align.current(false);
}
}, [search]);
function renderDropdown() {
return (React.createElement(OptionStateContext.Provider, { value: { focusValue: focusValue, filter: filter, search: search, searchFilterDisabled: searchFilterDisabled } },
React.createElement(OptionsContext.Provider, { value: optionsContextRef.current },
React.createElement(Dropdown, { prefixCls: prefixCls, empty: empty, placeholder: empyPlaceholder, scrollwrapRef: scrollwrapRef }, children)),
" "));
}
return (React.createElement(ValueContext.Provider, { value: { value: value, onSelect: onSelect, onUnSelect: onUnSelect } },
React.createElement(Trigger, { prefixCls: prefixCls + "-transition", visible: visible, onChange: setVisible, alignRef: align, action: ACTION, popupAlign: POPUPALIGN, popupClassName: popupClassName, stretch: stretch, popup: renderDropdown() },
React.createElement("div", { className: classString, style: style },
React.createElement(SelectBox, { multiple: multiple, selectedCfg: selectedCfg, placeholder: placeholder, onKeyDown: handleKeyPress, onBlur: onBlur, ref: innerRef, renderSelectItem: renderSelectItem }, searchMode && React.createElement(SelectSearch, { prefixCls: prefixCls, visible: visible, search: search, onSearchChange: searchHandle }))))));
});
export default Select;
//# sourceMappingURL=Select.js.map