acud
Version:
acg react 组件库
399 lines • 16.5 kB
JavaScript
import _defineProperty from "@babel/runtime/helpers/esm/defineProperty";
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
import * as React from 'react';
import classNames from 'classnames';
import isEqual from 'lodash/isEqual';
import OutlinedFunnel from "acud-icon/es/icons/OutlinedFunnel";
import cloneDeep from 'lodash/cloneDeep';
import Button from '../../../button';
import Tree from '../../../tree';
import Checkbox from '../../../checkbox';
import Dropdown from '../../../dropdown';
import Empty from '../../../empty';
import FilterDropdownMenuWrapper from './FilterWrapper';
import FilterSearch from './FilterSearch';
import { flattenKeys } from '.';
import useSyncState from '../../../_util/hooks/useSyncState';
import { ConfigContext } from '../../../config-provider/context';
var defaultFilterFun = function defaultFilterFun(searchValue, filterItem) {
var _a;
return ((_a = filterItem.text) === null || _a === void 0 ? void 0 : _a.toString().toLowerCase().indexOf(searchValue.trim().toLowerCase())) > -1;
};
function searchValueMatched(searchValue, text) {
if (typeof text === 'string' || typeof text === 'number') {
return text === null || text === void 0 ? void 0 : text.toString().toLowerCase().includes(searchValue.trim().toLowerCase());
}
return false;
}
var formatContent = function formatContent(content, searchValue, prefixCls) {
var lowerContent = content.toLowerCase();
var lowerSearch = searchValue.toLowerCase().trim();
var searchStartIndex = lowerContent.indexOf(lowerSearch);
var len = lowerSearch.length;
// 存在搜索值不在content的情况,比如key与children不一致时
if (searchStartIndex === -1) {
return /*#__PURE__*/React.createElement(React.Fragment, null, content);
}
return /*#__PURE__*/React.createElement(React.Fragment, null, content.slice(0, searchStartIndex), /*#__PURE__*/React.createElement("span", {
className: "".concat(prefixCls, "-dropdown-search-highlight")
}, content.slice(searchStartIndex, searchStartIndex + len)), content.slice(searchStartIndex + len));
};
function FilterDropdown(props) {
var _a;
var tablePrefixCls = props.tablePrefixCls,
prefixCls = props.prefixCls,
column = props.column,
dropdownPrefixCls = props.dropdownPrefixCls,
columnKey = props.columnKey,
filterMultiple = props.filterMultiple,
_props$filterMode = props.filterMode,
filterMode = _props$filterMode === void 0 ? 'menu' : _props$filterMode,
_props$filterSearch = props.filterSearch,
filterSearch = _props$filterSearch === void 0 ? false : _props$filterSearch,
filterState = props.filterState,
filterShowSelectAll = props.filterShowSelectAll,
triggerFilter = props.triggerFilter,
locale = props.locale,
children = props.children,
getPopupContainer = props.getPopupContainer;
var filterDropdownVisible = column.filterDropdownVisible,
filterPlaceholder = column.filterPlaceholder,
onFilterDropdownVisibleChange = column.onFilterDropdownVisibleChange;
var _React$useState = React.useState(false),
_React$useState2 = _slicedToArray(_React$useState, 2),
visible = _React$useState2[0],
setVisible = _React$useState2[1];
var filtered = !!(filterState && (((_a = filterState.filteredKeys) === null || _a === void 0 ? void 0 : _a.length) || filterState.forceFiltered));
var triggerVisible = function triggerVisible(newVisible) {
setVisible(newVisible);
onFilterDropdownVisibleChange === null || onFilterDropdownVisibleChange === void 0 ? void 0 : onFilterDropdownVisibleChange(newVisible);
};
var mergedVisible = typeof filterDropdownVisible === 'boolean' ? filterDropdownVisible : visible;
// ===================== Select Keys =====================
var propFilteredKeys = filterState === null || filterState === void 0 ? void 0 : filterState.filteredKeys;
// preKeys = propFilteredKeys;
var _useSyncState = useSyncState(propFilteredKeys || []),
_useSyncState2 = _slicedToArray(_useSyncState, 2),
getFilteredKeysSync = _useSyncState2[0],
setFilteredKeysSync = _useSyncState2[1];
// eslint-disable-next-line react-hooks/exhaustive-deps
var onSelectKeys = React.useCallback(function (_ref) {
var selectedKeys = _ref.selectedKeys;
setFilteredKeysSync(selectedKeys);
}, []);
var onCheck = function onCheck(keys, _ref2) {
var node = _ref2.node,
checked = _ref2.checked;
if (!filterMultiple) {
onSelectKeys({
selectedKeys: checked && node.key ? [node.key] : []
});
} else {
onSelectKeys({
selectedKeys: keys
});
}
};
var menuChange = function menuChange(e, value) {
var keys = new Set(getFilteredKeysSync());
var checked = e.target.checked;
checked ? keys.add(value) : keys["delete"](value);
onSelectKeys({
selectedKeys: _toConsumableArray(keys)
});
};
React.useEffect(function () {
if (!visible) {
return;
}
onSelectKeys({
selectedKeys: propFilteredKeys || []
});
}, [propFilteredKeys, visible]);
// search in tree mode column filter
var _React$useState3 = React.useState(''),
_React$useState4 = _slicedToArray(_React$useState3, 2),
searchValue = _React$useState4[0],
setSearchValue = _React$useState4[1];
var onSearch = function onSearch(e) {
var value = e.target.value;
setSearchValue(value);
};
// clear search value after close filter dropdown
React.useEffect(function () {
if (!visible) {
setSearchValue('');
}
}, [visible]);
var filteredArr = React.useMemo(function () {
if (searchValue === '' || searchValue === undefined) {
return column.filters;
}
if (filterMode === 'tree') {
var _loopTree = function loopTree(arr) {
var filteredArrTemp = [];
arr.forEach(function (filterItem) {
var _a;
if (defaultFilterFun(searchValue, filterItem)) {
filteredArrTemp.push(filterItem);
} else if (((_a = filterItem === null || filterItem === void 0 ? void 0 : filterItem.children) === null || _a === void 0 ? void 0 : _a.length) > 0) {
var tempArr = _loopTree(filterItem.children);
if (tempArr.length > 0) {
filterItem.children = tempArr;
filteredArrTemp.push(filterItem);
}
}
});
return filteredArrTemp;
};
return _loopTree(cloneDeep(column.filters));
}
return column.filters.filter(function (filterItem) {
return defaultFilterFun(searchValue, filterItem);
});
}, [filterMode, column.filters, searchValue]);
// ======================= Submit ========================
var internalTriggerFilter = function internalTriggerFilter(keys) {
var mergedKeys = keys && keys.length ? keys : null;
if (mergedKeys === null && (!filterState || !filterState.filteredKeys)) {
return null;
}
if (isEqual(mergedKeys, filterState === null || filterState === void 0 ? void 0 : filterState.filteredKeys)) {
return null;
}
triggerFilter({
column: column,
key: columnKey,
filteredKeys: mergedKeys
});
};
var onConfirm = function onConfirm() {
triggerVisible(false);
internalTriggerFilter(getFilteredKeysSync());
};
var onReset = function onReset() {
setSearchValue('');
setFilteredKeysSync([]);
// internalTriggerFilter([]);
// triggerVisible(false);
};
var doFilter = function doFilter() {
var _ref3 = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
closeDropdown: true
},
closeDropdown = _ref3.closeDropdown;
if (closeDropdown) {
triggerVisible(false);
}
internalTriggerFilter(getFilteredKeysSync());
};
var onVisibleChange = function onVisibleChange(newVisible) {
if (newVisible && propFilteredKeys !== undefined) {
// Sync filteredKeys on appear in controlled mode (propFilteredKeys !== undefiend)
setFilteredKeysSync(propFilteredKeys || []);
}
// Default will filter when closed
if (!newVisible && !column.filterDropdown) {
// onConfirm();
onReset();
}
triggerVisible(newVisible);
};
// ======================== Style ========================
var onCheckAll = function onCheckAll(e) {
var selectedKeys = getFilteredKeysSync() || [];
// const allFilterKeys = flattenKeys(filteredArr).map(key => String(key));
var allFilterKeys = flattenKeys(filteredArr);
if (e.target.checked) {
setFilteredKeysSync(_toConsumableArray(new Set([].concat(_toConsumableArray(selectedKeys), _toConsumableArray(allFilterKeys)))));
} else {
setFilteredKeysSync(selectedKeys.filter(function (key) {
return !allFilterKeys.includes(key);
}));
}
};
var onClearAll = function onClearAll() {
setFilteredKeysSync([]);
onConfirm();
};
var onSingleCheck = function onSingleCheck(value) {
setFilteredKeysSync([value]);
onConfirm();
};
var _getTreeChildrenData = function getTreeChildrenData(_ref4) {
var filters = _ref4.filters;
return (filters || []).map(function (filter, index) {
var key = String(filter.value);
var item = {
title: filter.text,
key: filter.value !== undefined ? key : index
};
if (filter.children) {
item.children = _getTreeChildrenData({
filters: filter.children
});
}
return item;
});
};
var getTreeData = function getTreeData(_ref5) {
var filters = _ref5.filters;
var treeDataArr = [];
var treeData = {
title: locale.filterCheckall,
key: 'checkall',
children: []
};
treeData.children = _getTreeChildrenData({
filters: filters
});
treeDataArr.push(treeData);
return treeDataArr;
};
var dropdownContent;
if (typeof column.filterDropdown === 'function') {
dropdownContent = column.filterDropdown({
prefixCls: "".concat(dropdownPrefixCls, "-custom"),
setSelectedKeys: function setSelectedKeys(selectedKeys) {
return onSelectKeys({
selectedKeys: selectedKeys
});
},
selectedKeys: getFilteredKeysSync(),
confirm: doFilter,
clearFilters: onReset,
filters: column.filters,
visible: mergedVisible
});
} else if (column.filterDropdown) {
dropdownContent = column.filterDropdown;
} else {
var selectedKeys = getFilteredKeysSync() || [];
var getFilterComponent = function getFilterComponent() {
if (filteredArr.length === 0) {
return /*#__PURE__*/React.createElement(Empty, {
className: "".concat(tablePrefixCls, "-filter-dropdown-empty"),
description: locale.filterEmptyText,
hasImage: false
});
}
if (filterMode === 'tree') {
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
className: "".concat(tablePrefixCls, "-filter-dropdown-tree")
}, /*#__PURE__*/React.createElement(Tree, {
checkable: true,
selectable: false,
multiple: filterMultiple,
checkStrictly: !filterMultiple,
className: "".concat(dropdownPrefixCls, "-menu"),
onCheck: onCheck,
checkedKeys: selectedKeys,
selectedKeys: selectedKeys,
searchable: filterSearch !== false,
showIcon: false,
treeData: getTreeData({
filters: filteredArr
}),
autoExpandParent: true,
defaultExpandAll: true,
filterTreeNode: searchValue.trim() ? function (node) {
return searchValueMatched(searchValue, node.title);
} : undefined
})));
}
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("div", {
className: "".concat(dropdownPrefixCls, "-menu")
}, filterMultiple && /*#__PURE__*/React.createElement(React.Fragment, null, filterShowSelectAll && /*#__PURE__*/React.createElement("div", {
className: "".concat(dropdownPrefixCls, "-menu-item ").concat(dropdownPrefixCls, "-menu-item-multiple")
}, /*#__PURE__*/React.createElement(Checkbox, {
checked: filteredArr.every(function (item) {
return selectedKeys.includes(item.value);
}),
indeterminate: !filteredArr.every(function (item) {
return selectedKeys.includes(item.value);
}) && filteredArr.some(function (item) {
return selectedKeys.includes(item.value);
}),
onChange: onCheckAll
}, locale.filterCheckall)), filteredArr.map(function (filter, index) {
return /*#__PURE__*/React.createElement("div", {
key: index
// eslint-disable-next-line max-len
,
className: "".concat(dropdownPrefixCls, "-menu-item ").concat(dropdownPrefixCls, "-menu-item-multiple")
}, /*#__PURE__*/React.createElement(Checkbox, {
checked: selectedKeys.includes(filter.value),
onChange: function onChange(e) {
return menuChange(e, filter.value);
}
}, searchValue ? formatContent(filter.text, searchValue, prefixCls) : filter.text));
})), !filterMultiple && /*#__PURE__*/React.createElement(React.Fragment, null, filterShowSelectAll && /*#__PURE__*/React.createElement("div", {
className: classNames("".concat(dropdownPrefixCls, "-menu-item"), "".concat(dropdownPrefixCls, "-menu-item-all")),
onClick: onClearAll
}, locale.filterAll), filteredArr.map(function (filter, index) {
return /*#__PURE__*/React.createElement("div", {
className: classNames("".concat(dropdownPrefixCls, "-menu-item"), // eslint-disable-next-line max-len
_defineProperty({}, "".concat(prefixCls, "-dropdown-menu-item-checked"), selectedKeys.includes(filter.value))),
key: index,
onClick: function onClick() {
return onSingleCheck(filter.value);
}
}, /*#__PURE__*/React.createElement("span", null, searchValue ? formatContent(filter.text, searchValue, prefixCls) : filter.text));
}))));
};
dropdownContent = /*#__PURE__*/React.createElement(React.Fragment, null, filterMode === 'menu' && /*#__PURE__*/React.createElement(FilterSearch, {
filterSearch: filterSearch,
filterPlaceholder: filterPlaceholder,
value: searchValue,
onChange: onSearch,
tablePrefixCls: tablePrefixCls,
locale: locale
}), getFilterComponent(), filterMultiple && /*#__PURE__*/React.createElement("div", {
className: "".concat(prefixCls, "-dropdown-btns")
}, /*#__PURE__*/React.createElement(Button, {
type: "primary",
size: "small",
onClick: onConfirm
}, locale.filterConfirm), /*#__PURE__*/React.createElement(Button, {
type: "default",
size: "small",
className: "".concat(prefixCls, "-dropdown-btns-reset"),
onClick: onReset
}, locale.filterReset)));
}
var menu = /*#__PURE__*/React.createElement(FilterDropdownMenuWrapper, {
className: "".concat(prefixCls, "-dropdown-box")
}, dropdownContent);
var filterIcon;
if (typeof column.filterIcon === 'function') {
filterIcon = column.filterIcon(filtered);
} else if (column.filterIcon) {
filterIcon = column.filterIcon;
} else {
filterIcon = /*#__PURE__*/React.createElement(OutlinedFunnel, null);
}
var _React$useContext = React.useContext(ConfigContext),
direction = _React$useContext.direction;
return /*#__PURE__*/React.createElement("div", {
className: "".concat(prefixCls, "-column")
}, /*#__PURE__*/React.createElement("span", {
className: "".concat(tablePrefixCls, "-column-title")
}, children), /*#__PURE__*/React.createElement(Dropdown, {
overlay: menu,
trigger: ['click'],
visible: mergedVisible,
onVisibleChange: onVisibleChange,
getPopupContainer: getPopupContainer,
overlayClassName: "".concat(prefixCls, "-dropdown"),
placement: direction === 'rtl' ? 'bottomRight' : 'bottomLeft',
onClick: function onClick(e) {
return e.stopPropagation();
}
}, /*#__PURE__*/React.createElement("span", {
role: "button",
tabIndex: -1,
className: classNames("".concat(prefixCls, "-trigger"), _defineProperty({}, "".concat(prefixCls, "-trigger-active"), filtered))
}, filterIcon)));
}
export default FilterDropdown;