linkmore-design
Version:
🌈 🚀lm组件库。🚀
165 lines (157 loc) • 6.76 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
var _excluded = ["item"];
import { useDebounceEffect } from 'ahooks';
import cn from 'classnames';
import difference from 'lodash/difference';
import sortBy from 'lodash/sortBy';
import union from 'lodash/union';
import React, { useMemo, useRef, useState } from 'react';
import Button from "../../button";
import Checkbox from "../../checkbox";
import VirtualList from "../../virtual-list";
import Empty from "../../empty";
import DelayInput from "./DelayInput";
var CheckboxFilter = function CheckboxFilter(props) {
var _props$value = props.value,
value = _props$value === void 0 ? [] : _props$value,
onChange = props.onChange,
onCancel = props.onCancel,
_props$options = props.options,
filters = _props$options === void 0 ? [] : _props$options,
_props$showSearch = props.showSearch,
showSearch = _props$showSearch === void 0 ? true : _props$showSearch,
_props$showAllChecked = props.showAllChecked,
showAllChecked = _props$showAllChecked === void 0 ? true : _props$showAllChecked,
fieldNames = props.fieldNames,
_props$locale = props.locale,
locale = _props$locale === void 0 ? {} : _props$locale;
var inputRef = useRef(null);
// 存在搜索时, 下拉数据取搜索后的, 反之实时取最新来源
var _useState = useState(false),
_useState2 = _slicedToArray(_useState, 2),
searched = _useState2[0],
setSearched = _useState2[1];
// 选中的数据项: [key, key, ...];
var _useState3 = useState(value),
_useState4 = _slicedToArray(_useState3, 2),
checkedValues = _useState4[0],
setCheckedValues = _useState4[1];
// 搜索后的筛选项
var _useState5 = useState(function () {
return filters;
}),
_useState6 = _slicedToArray(_useState5, 2),
optionals = _useState6[0],
setOptions = _useState6[1];
var options = sortBy(searched ? optionals : filters, function (a) {
return !(value !== null && value !== void 0 && value.includes(a[fieldNames.value]));
});
// 是否存在搜索, 当数据大于8时存在搜索
// const isSearch = useMemo(() => filters.length > 8 && !!showSearch, [filters.length, showSearch])
// 是否全选: 选中的数据大于等于筛选后的数据 && 筛选后的数据全部存在于选中的数据中
var checkAll = useMemo(function () {
var isAll = checkedValues.length >= options.length;
// 及早return以免后续的比对
if (!isAll) return false;
var optionsKeys = options.map(function (v) {
return v[fieldNames.value];
});
// 搜索后的值(options)排除选中的值(checkedValues)后的数据若不存在数据则全选
return !difference(optionsKeys, checkedValues).length;
}, [checkedValues, options]);
// 是否半选: 存在选中的数据 && 未全选
var indeterminate = useMemo(function () {
return !!checkedValues.length && !checkAll;
}, [checkedValues.length, checkAll]);
// 搜索
var handleFilter = function handleFilter() {
var val = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '';
setSearched(!!val);
var searchValues = filters.filter(function (v) {
return (v[fieldNames.label] || '').indexOf(val) > -1;
});
setOptions(searchValues);
};
// 单选事件
var handleOnClick = function handleOnClick(e, item) {
e.preventDefault();
var checkedMap = new Set(checkedValues);
checkedMap.has(item[fieldNames.value]) ? checkedMap.delete(item[fieldNames.value]) : checkedMap.add(item[fieldNames.value]);
setCheckedValues(Array.from(checkedMap));
};
// 全选事件, 判断触发前checkAll的值(此时的操作与checkAll相反)
var onCheckAllChange = function onCheckAllChange() {
var currentOptionsKey = options.map(function (v) {
return v[fieldNames.value];
});
// 若checkAll全选, 则返回与搜索后(options)不同的值, 反之联合两者
var nValue = checkAll ? difference(checkedValues, currentOptionsKey) : union(checkedValues, currentOptionsKey);
setCheckedValues(nValue);
};
// 确定 执行查询操作
var handleSure = function handleSure() {
var resetValue = checkedValues !== null && checkedValues !== void 0 && checkedValues.length ? checkedValues : undefined;
onChange === null || onChange === void 0 ? void 0 : onChange(resetValue);
};
// 展开下拉时触发: 赋值 && 聚焦 && 重置显示内容
useDebounceEffect(function () {
inputRef.current && inputRef.current.focus({
cursor: 'all'
});
}, [], {
wait: 200
});
return /*#__PURE__*/React.createElement("div", {
className: "filter_dropdown"
}, showSearch && /*#__PURE__*/React.createElement("div", {
className: "filter_header"
}, /*#__PURE__*/React.createElement(DelayInput, {
ref: inputRef,
onSearch: handleFilter,
onChange: handleFilter
}), !!showAllChecked && /*#__PURE__*/React.createElement("div", {
className: "filter_header_operate"
}, /*#__PURE__*/React.createElement(Checkbox, {
indeterminate: indeterminate,
onChange: onCheckAllChange,
checked: checkAll,
className: "filter_tip"
}, locale.all), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
className: "filter_tip"
}, locale.selected, ": ", checkedValues.length)))), /*#__PURE__*/React.createElement(Checkbox.Group, {
value: checkedValues,
className: "filter_body"
}, /*#__PURE__*/React.createElement(VirtualList, {
options: options,
className: "filter_list"
}, function (_ref) {
var _ref$item = _ref.item,
item = _ref$item === void 0 ? {} : _ref$item,
resetProps = _objectWithoutProperties(_ref, _excluded);
return /*#__PURE__*/React.createElement("div", _extends({}, resetProps, {
className: cn('filter_item', {
checked: checkedValues.includes(item[fieldNames.value])
}),
onClick: function onClick(e) {
return handleOnClick(e, item);
}
}), /*#__PURE__*/React.createElement(Checkbox, {
value: item[fieldNames.value],
className: "filter_item_content"
}, item[fieldNames.label]));
}), !options.length && /*#__PURE__*/React.createElement(Empty, {
title: ""
})), /*#__PURE__*/React.createElement("div", {
className: "filter_footer"
}, /*#__PURE__*/React.createElement("div", {
className: "footer_clear",
onClick: onCancel
}, locale.cancel), /*#__PURE__*/React.createElement(Button, {
type: "primary",
size: "small",
onClick: handleSure
}, locale.ok)));
};
export default CheckboxFilter;