xy-select
Version:
基于React的下拉列表组件
80 lines • 3.31 kB
JavaScript
import classNames from "classnames";
import React, { useContext, useRef } from "react";
import { useMount, useUnmount } from "utils-hooks";
import { OptionsContext, OptionStateContext, ValueContext } from "../Context";
/**
* 判断是否过滤
* @param cfg option配置
* @param searchFilterDisabled 搜索过滤禁用
* @param filter 是否过滤/过滤函数
* @param search 当前搜索内容
* @returns 返回true则过滤, 返回false不过滤
*/
function useHasFiltered(cfg, searchFilterDisabled, filter, search) {
if (searchFilterDisabled) {
return false;
}
if (search) {
var _search = search.toLowerCase();
var value = String(cfg.value).toLowerCase();
var label = String(cfg.label).toLowerCase();
return value.indexOf(_search) === -1 && label.indexOf(_search) === -1;
}
else if (filter) {
return filter(cfg, search);
}
}
/**
* Option组件
* @description 必须配合SelectContext使用
*/
export function Option(props) {
var _a;
var _b = props.prefixCls, prefixCls = _b === void 0 ? "xy-option" : _b, className = props.className, style = props.style, _c = props.disabled, disabled = _c === void 0 ? false : _c, divided = props.divided, data = props.data, children = props.children;
var content = typeof children === "string" ? children : null;
var value = "value" in props ? props.value : content;
var label = props.label || content;
var optionsContext = useContext(OptionsContext);
var stateContext = useContext(OptionStateContext);
var valueContext = useContext(ValueContext);
var classString = classNames(prefixCls, className, (_a = {},
_a[prefixCls + "-checked"] = getContextChecked(),
_a[prefixCls + "-disabled"] = disabled,
_a[prefixCls + "-divided"] = divided,
_a[prefixCls + "-focus"] = stateContext && stateContext.focusValue === value,
_a));
var cfg = useRef({ value: value, label: label, disabled: disabled, filtered: false });
var filtered = stateContext ? useHasFiltered(cfg.current, stateContext.searchFilterDisabled, stateContext.filter, stateContext.search) : false;
// Option更新后, 也要更新这些值
cfg.current.filtered = filtered;
cfg.current.label = label;
cfg.current.value = value;
cfg.current.data = data;
useMount(function () {
if (optionsContext) {
optionsContext.onOptionAdd(cfg.current);
}
});
useUnmount(function () {
if (optionsContext) {
optionsContext.onOptionRemove(value);
}
});
function getContextChecked() {
if (valueContext && valueContext.value) {
return valueContext.value instanceof Array ? valueContext.value.some(function (x) { return x === value; }) : valueContext.value === value;
}
else {
return false;
}
}
function clickHandle(e) {
if (!disabled && valueContext) {
valueContext.onSelect(value);
}
e.stopPropagation();
}
return (React.createElement("li", { className: classNames(classString, { filtered: filtered }), style: style, title: label, "data-value": value, onClick: clickHandle }, children));
}
export default React.memo(Option);
//# sourceMappingURL=Option.js.map