linkmore-design
Version:
🌈 🚀lm组件库。🚀
144 lines (135 loc) • 6.17 kB
JavaScript
"use strict";
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _ahooks = require("ahooks");
var _classnames = _interopRequireDefault(require("classnames"));
var _difference = _interopRequireDefault(require("lodash/difference"));
var _sortBy = _interopRequireDefault(require("lodash/sortBy"));
var _union = _interopRequireDefault(require("lodash/union"));
var _react = _interopRequireWildcard(require("react"));
var _button = _interopRequireDefault(require("../../button"));
var _checkbox = _interopRequireDefault(require("../../checkbox"));
var _virtualList = _interopRequireDefault(require("../../virtual-list"));
var _empty = _interopRequireDefault(require("../../empty"));
var _DelayInput = _interopRequireDefault(require("./DelayInput"));
const CheckboxFilter = props => {
const {
value = [],
onChange,
onCancel,
options: filters = [],
showSearch = true,
showAllChecked = true,
fieldNames,
locale = {}
} = props;
const inputRef = (0, _react.useRef)(null);
// 存在搜索时, 下拉数据取搜索后的, 反之实时取最新来源
const [searched, setSearched] = (0, _react.useState)(false);
// 选中的数据项: [key, key, ...];
const [checkedValues, setCheckedValues] = (0, _react.useState)(value);
// 搜索后的筛选项
const [optionals, setOptions] = (0, _react.useState)(() => filters);
const options = (0, _sortBy.default)(searched ? optionals : filters, a => !value?.includes(a[fieldNames.value]));
// 是否存在搜索, 当数据大于8时存在搜索
// const isSearch = useMemo(() => filters.length > 8 && !!showSearch, [filters.length, showSearch])
// 是否全选: 选中的数据大于等于筛选后的数据 && 筛选后的数据全部存在于选中的数据中
const checkAll = (0, _react.useMemo)(() => {
const isAll = checkedValues.length >= options.length;
// 及早return以免后续的比对
if (!isAll) return false;
const optionsKeys = options.map(v => v[fieldNames.value]);
// 搜索后的值(options)排除选中的值(checkedValues)后的数据若不存在数据则全选
return !(0, _difference.default)(optionsKeys, checkedValues).length;
}, [checkedValues, options]);
// 是否半选: 存在选中的数据 && 未全选
const indeterminate = (0, _react.useMemo)(() => !!checkedValues.length && !checkAll, [checkedValues.length, checkAll]);
// 搜索
const handleFilter = (val = '') => {
setSearched(!!val);
const searchValues = filters.filter(v => (v[fieldNames.label] || '').indexOf(val) > -1);
setOptions(searchValues);
};
// 单选事件
const handleOnClick = (e, item) => {
e.preventDefault();
const 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相反)
const onCheckAllChange = () => {
const currentOptionsKey = options.map(v => v[fieldNames.value]);
// 若checkAll全选, 则返回与搜索后(options)不同的值, 反之联合两者
const nValue = checkAll ? (0, _difference.default)(checkedValues, currentOptionsKey) : (0, _union.default)(checkedValues, currentOptionsKey);
setCheckedValues(nValue);
};
// 确定 执行查询操作
const handleSure = () => {
const resetValue = checkedValues?.length ? checkedValues : undefined;
onChange?.(resetValue);
};
// 展开下拉时触发: 赋值 && 聚焦 && 重置显示内容
(0, _ahooks.useDebounceEffect)(() => {
inputRef.current && inputRef.current.focus({
cursor: 'all'
});
}, [], {
wait: 200
});
return /*#__PURE__*/_react.default.createElement("div", {
className: "filter_dropdown"
}, showSearch && /*#__PURE__*/_react.default.createElement("div", {
className: "filter_header"
}, /*#__PURE__*/_react.default.createElement(_DelayInput.default, {
ref: inputRef,
onSearch: handleFilter,
onChange: handleFilter
}), !!showAllChecked && /*#__PURE__*/_react.default.createElement("div", {
className: "filter_header_operate"
}, /*#__PURE__*/_react.default.createElement(_checkbox.default, {
indeterminate: indeterminate,
onChange: onCheckAllChange,
checked: checkAll,
className: "filter_tip"
}, locale.all), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("span", {
className: "filter_tip"
}, locale.selected, ": ", checkedValues.length)))), /*#__PURE__*/_react.default.createElement(_checkbox.default.Group, {
value: checkedValues,
className: "filter_body"
}, /*#__PURE__*/_react.default.createElement(_virtualList.default, {
options: options,
className: "filter_list"
}, ({
item = {},
...resetProps
}) => {
return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({}, resetProps, {
className: (0, _classnames.default)('filter_item', {
checked: checkedValues.includes(item[fieldNames.value])
}),
onClick: e => handleOnClick(e, item)
}), /*#__PURE__*/_react.default.createElement(_checkbox.default, {
value: item[fieldNames.value],
className: "filter_item_content"
}, item[fieldNames.label]));
}), !options.length && /*#__PURE__*/_react.default.createElement(_empty.default, {
title: ""
})), /*#__PURE__*/_react.default.createElement("div", {
className: "filter_footer"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "footer_clear",
onClick: onCancel
}, locale.cancel), /*#__PURE__*/_react.default.createElement(_button.default, {
type: "primary",
size: "small",
onClick: handleSure
}, locale.ok)));
};
var _default = CheckboxFilter;
exports.default = _default;