UNPKG

linkmore-design

Version:

🌈 🚀lm组件库。🚀

165 lines (157 loc) 6.76 kB
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;