linkmore-design
Version:
🌈 🚀lm组件库。🚀
485 lines (466 loc) • 17.2 kB
JavaScript
import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
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"],
_excluded2 = ["item"],
_excluded3 = ["type"];
import { useEvent } from "../hooks";
import { useControllableValue } from 'ahooks';
import Cascader from "../cascader";
import cn from 'classnames';
import Button from "../button";
import Checkbox from "../checkbox";
import Dropdown from "../dropdown";
import Input from "../input";
import Empty from "../empty";
import React, { useMemo, useRef, useState } from 'react';
import IconFont from "../icon-font";
import VirtualList from "../virtual-list";
import { getArray, getIsHas, onStringSearch, render } from "./utils";
var FilterEmpty = function FilterEmpty() {
return /*#__PURE__*/React.createElement("div", {
className: "filter_empty"
}, /*#__PURE__*/React.createElement(Empty, {
title: "\u6682\u65E0\u6570\u636E"
}));
};
// 下拉单选过滤器
var SelectFilter = function SelectFilter(_ref) {
var _ref$filters = _ref.filters,
filters = _ref$filters === void 0 ? [] : _ref$filters,
getFilterValue = _ref.getFilterValue,
setFilterValue = _ref.setFilterValue;
var inputRef = useRef(null);
// 搜索后的筛选项
var _useState = useState(filters),
_useState2 = _slicedToArray(_useState, 2),
options = _useState2[0],
setOptions = _useState2[1];
// 是否存在搜索, 当数据大于8时存在搜索
var isSearch = useMemo(function () {
return filters.length > 8;
}, [filters.length]);
// 搜索
var handleFilter = useEvent(function (val) {
return setOptions(filters.filter(function (v) {
return onStringSearch(val, v.label);
}));
});
// 单选事件
var onChange = function onChange(e, item) {
e.preventDefault();
setFilterValue(item.value);
};
return /*#__PURE__*/React.createElement("div", {
className: "filter_dropdown"
}, isSearch && /*#__PURE__*/React.createElement("div", {
className: "filter_header"
}, /*#__PURE__*/React.createElement(Input.Search, {
ref: inputRef,
allowClear: true,
size: "small",
placeholder: "\u8BF7\u8F93\u5165",
onSearch: handleFilter,
onChange: function onChange(e) {
return handleFilter(e.target.value);
}
})), /*#__PURE__*/React.createElement("div", {
className: "filter_body"
}, /*#__PURE__*/React.createElement(VirtualList, {
options: options,
className: "filter_list"
}, function (_ref2) {
var item = _ref2.item,
resetProps = _objectWithoutProperties(_ref2, _excluded);
return /*#__PURE__*/React.createElement("div", _extends({}, resetProps, {
className: cn('filter_item', {
checked: item.value === getFilterValue
}),
onClick: function onClick(e) {
return onChange(e, item);
}
}), /*#__PURE__*/React.createElement("div", {
className: "filter_item-content"
}, item.label));
}), !options.length && /*#__PURE__*/React.createElement(FilterEmpty, null)));
};
// 下拉多选过滤器: 要过滤的数据, 当前选中项, 触发过滤, 过滤前的数据
var CheckboxFilter = function CheckboxFilter(_ref3) {
var _ref3$filters = _ref3.filters,
filters = _ref3$filters === void 0 ? [] : _ref3$filters,
_ref3$getFilterValue = _ref3.getFilterValue,
getFilterValue = _ref3$getFilterValue === void 0 ? [] : _ref3$getFilterValue,
setFilterValue = _ref3.setFilterValue;
var onValuesChange = useEvent(function (checkedValues) {
return setFilterValue(checkedValues, false);
});
// 父组件和子组件同步checked状态
var _useControllableValue = useControllableValue({
value: getFilterValue,
onChange: onValuesChange
}),
_useControllableValue2 = _slicedToArray(_useControllableValue, 2),
checkedValues = _useControllableValue2[0],
setCheckedValues = _useControllableValue2[1];
// 搜索后的筛选项:[{value: '', ... }, ...]
var _useState3 = useState(filters),
_useState4 = _slicedToArray(_useState3, 2),
options = _useState4[0],
setOptions = _useState4[1];
// 是否存在搜索, 当数据大于8时存在搜索
var isSearch = useMemo(function () {
return filters.length > 8;
}, [filters.length]);
// 是否全选: 选中的数据大于等于筛选后的数据 && 筛选后的数据全部存在于选中的数据中
var checkAll = useMemo(function () {
var isLen = checkedValues.length >= options.length;
return isLen && options.every(function (_ref4) {
var value = _ref4.value;
return checkedValues.includes(value);
});
}, [checkedValues.length, options]);
// 是否半选: 存在选中的数据 && 未全选
var indeterminate = useMemo(function () {
return checkedValues.length && !checkAll;
}, [checkedValues.length, checkAll]);
// 全选事件
var onCheckAllChange = function onCheckAllChange(e) {
var nValue = checkAll ? checkedValues.filter(function (v) {
return !options.some(function (_ref5) {
var value = _ref5.value;
return v === value;
});
}) : Array.from(new Set([].concat(_toConsumableArray(checkedValues), _toConsumableArray(options.map(function (v) {
return v.value;
})))));
setCheckedValues(nValue);
};
// 搜索
var handleFilter = useEvent(function (val) {
return setOptions(filters.filter(function (v) {
return onStringSearch(val, v.label);
}));
});
// 单选事件
var onChange = function onChange(e, item) {
e.preventDefault();
e.stopPropagation();
var arr = checkedValues.includes(item.value) ? checkedValues.filter(function (v) {
return v !== item.value;
}) : [].concat(_toConsumableArray(checkedValues), [item.value]);
setCheckedValues(arr || undefined);
};
return /*#__PURE__*/React.createElement("div", {
className: "select_dropdown"
}, /*#__PURE__*/React.createElement("div", {
className: "filter_header"
}, isSearch && /*#__PURE__*/React.createElement(Input.Search, {
allowClear: true,
size: "small",
placeholder: "\u8BF7\u8F93\u5165",
onSearch: handleFilter,
onChange: function onChange(e) {
var _e$target;
return handleFilter(e === null || e === void 0 ? void 0 : (_e$target = e.target) === null || _e$target === void 0 ? void 0 : _e$target.value);
}
}), /*#__PURE__*/React.createElement("div", {
className: "filter_header_operate"
}, /*#__PURE__*/React.createElement(Checkbox, {
indeterminate: indeterminate,
onChange: onCheckAllChange,
checked: checkAll,
className: "filter_tip"
}, "\u5168\u90E8"), /*#__PURE__*/React.createElement("div", null, /*#__PURE__*/React.createElement("span", {
className: "filter_tip"
}, "\u5DF2\u9009: ", checkedValues.length)))), /*#__PURE__*/React.createElement(Checkbox.Group, {
value: checkedValues,
className: "filter_body"
}, /*#__PURE__*/React.createElement(VirtualList, {
options: options,
className: "filter_list"
}, function (_ref6) {
var item = _ref6.item,
resetProps = _objectWithoutProperties(_ref6, _excluded2);
return /*#__PURE__*/React.createElement("div", _extends({}, resetProps, {
className: cn('filter_item', {
checked: checkedValues.includes(item.value)
}),
onClick: function onClick(e) {
return onChange(e, item);
}
}), /*#__PURE__*/React.createElement(Checkbox, {
value: item.value,
className: "filter_item-content"
}, item.label));
}), !options.length && /*#__PURE__*/React.createElement(FilterEmpty, null)));
};
// 级联选择器
var CascaderFilter = function CascaderFilter(props) {
var title = props.title,
filters = props.filters,
getFilterValue = props.getFilterValue,
setFilterValue = props.setFilterValue,
_props$itemProps = props.itemProps,
itemProps = _props$itemProps === void 0 ? {} : _props$itemProps,
isFiltering = props.isFiltering;
var _useState5 = useState(false),
_useState6 = _slicedToArray(_useState5, 2),
visible = _useState6[0],
setVisible = _useState6[1];
var _useState7 = useState(filters),
_useState8 = _slicedToArray(_useState7, 2),
options = _useState8[0],
setOptions = _useState8[1];
var _useState9 = useState('全部'),
_useState10 = _slicedToArray(_useState9, 2),
text = _useState10[0],
setText = _useState10[1];
var _useState11 = useState(getFilterValue || itemProps.multiple ? [] : ''),
_useState12 = _slicedToArray(_useState11, 2),
checkedValues = _useState12[0],
setCheckedValues = _useState12[1];
// const isSearch = useMemo(() => filters.length > 8, [filters.length]);
var handleFilter = useEvent(function (val) {
return setOptions(filters.filter(function (v) {
return onStringSearch(val, v.label);
}));
});
// 重置级联弹框
var dropdownRender = function dropdownRender(menus) {
var inputRef = useRef(null);
// 确定
var handleSure = function handleSure() {
setFilterValue(itemProps.multiple ? checkedValues.map(function (v) {
return v[v.length - 1];
}) : checkedValues);
setVisible(false);
};
// 取消
var handleReset = function handleReset() {
if (inputRef.current) {
inputRef.current.input.value = '';
}
setFilterValue(undefined);
setCheckedValues(itemProps.multiple ? [] : '');
};
return /*#__PURE__*/React.createElement("div", {
className: "filter_cascader_container filter_dropdown"
}, /*#__PURE__*/React.createElement("div", {
className: "filter_header"
}, /*#__PURE__*/React.createElement(Input.Search, {
ref: inputRef,
allowClear: true,
size: "small",
placeholder: "\u8BF7\u8F93\u5165",
onSearch: handleFilter,
onChange: function onChange(e) {
return handleFilter(e.target.value);
}
})), menus, itemProps.multiple && /*#__PURE__*/React.createElement("div", {
className: "filter_footer"
}, /*#__PURE__*/React.createElement("div", {
className: "footer_clear",
onClick: handleReset
}, "\u53D6\u6D88"), /*#__PURE__*/React.createElement(Button, {
type: "primary",
size: "small",
onClick: handleSure
}, "\u786E\u5B9A")));
};
var onChange = function onChange(item, selectedOptions) {
if (!item.length) {
setText('全部');
setCheckedValues(itemProps.multiple ? [] : '');
setFilterValue(undefined);
return;
}
if (itemProps.multiple) {
var arr = [];
selectedOptions.map(function (vals) {
return vals.length > 1 ? arr.push(vals.map(function (v) {
return v.label;
}).join('/')) : vals[0].children.map(function (v) {
return arr.push("".concat(vals[0].label, "/").concat(v.label));
});
});
var showLabel = arr.length < 3 ? arr.join('、') : "".concat(arr[0], "\u3001+").concat(arr.length);
setText(showLabel);
setCheckedValues(item);
} else {
setText(selectedOptions.map(function (v) {
return v.label;
}).join('/'));
setFilterValue(item);
setCheckedValues(item);
}
};
var handleClear = function handleClear(e) {
if (isFiltering) {
e.stopPropagation();
setText('全部');
setCheckedValues(itemProps.multiple ? [] : '');
setFilterValue(undefined);
}
};
return /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(Cascader, _extends({}, itemProps, {
options: options,
value: checkedValues,
onChange: onChange,
open: visible
// showCheckedStrategy="Cascader.SHOW_CHILD"
,
dropdownRender: dropdownRender,
onDropdownVisibleChange: function onDropdownVisibleChange(v) {
return setVisible(v);
}
}), /*#__PURE__*/React.createElement("div", {
className: cn('filter_item', {
isfiltering: isFiltering || visible,
active: !isFiltering && visible
})
}, /*#__PURE__*/React.createElement("div", {
className: "filter_item_label"
}, title, ":"), /*#__PURE__*/React.createElement("div", {
className: "filter_item_value"
}, /*#__PURE__*/React.createElement("div", {
className: "checked"
}, isFiltering ? text : '全部'), /*#__PURE__*/React.createElement(IconFont, {
type: isFiltering ? 'lmweb-close-circle-fill' : 'lmweb-down',
className: "addonAfter",
onClick: handleClear
})))));
};
var FilterComp = function FilterComp(props) {
var type = props.type,
resetProps = _objectWithoutProperties(props, _excluded3);
switch (type) {
case 'select':
return /*#__PURE__*/React.createElement(SelectFilter, resetProps);
case 'checkbox':
return /*#__PURE__*/React.createElement(CheckboxFilter, resetProps);
case 'cascader':
return /*#__PURE__*/React.createElement(CascaderFilter, resetProps);
default:
return /*#__PURE__*/React.createElement(SelectFilter, resetProps);
}
};
var Index = function Index(props) {
var className = props.className,
dropdownClassName = props.dropdownClassName,
title = props.title,
type = props.type,
options = props.options,
children = props.children,
style = props.style,
comProps = props.props;
var _useState13 = useState(false),
_useState14 = _slicedToArray(_useState13, 2),
visible = _useState14[0],
setVisible = _useState14[1];
var _useState15 = useState(),
_useState16 = _slicedToArray(_useState15, 2),
value = _useState16[0],
setValue = _useState16[1];
var data = useMemo(function () {
if (options) return options;
return getArray(children).map(function (item) {
return {
label: item.props.children,
value: item.props.value
};
});
}, [options, children]);
// 判断是否正在过滤,普通过滤 && 嵌套过滤
var isFiltering = useMemo(function () {
return getIsHas(value);
}, [value]);
// 设置过滤的内容 filterType: 'single' 存在时 单个勾选时触发, 默认按钮触发
var setFilterValue = useEvent(function (val) {
var _props$onChange;
var close = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : true;
setValue(val);
props === null || props === void 0 ? void 0 : (_props$onChange = props.onChange) === null || _props$onChange === void 0 ? void 0 : _props$onChange.call(props, val);
close && setVisible(false);
});
// 展示的内容
var checkedValue = useMemo(function () {
if (!isFiltering) return '全部';
// select & checkbox
if (['select', 'checkbox'].includes(type)) {
var findItem = data.find(function (v) {
return Array.isArray(value) ? value.includes(v.value) : value === v.value;
});
if (!findItem) {
setFilterValue(type === 'checkbox' ? [] : '');
return '全部';
}
var filterLabel = findItem.label;
if (Array.isArray(value)) {
if (value.length > 1) {
return "".concat(filterLabel, "\u3001+").concat(value.length - 1, "...");
}
return filterLabel;
}
return filterLabel;
}
return value;
}, [comProps, data, isFiltering, setFilterValue, type, value]);
// 下拉组件渲染
var FilterControl = function FilterControl() {
var obj = {
filters: data,
getFilterValue: value,
setFilterValue: setFilterValue
};
return render(function () {
return /*#__PURE__*/React.createElement(FilterComp, _extends({
type: type
}, obj));
}());
};
// 清除筛选项
var handleClear = function handleClear(e) {
if (isFiltering) {
e.stopPropagation();
setFilterValue(type === 'checkbox' ? [] : '');
}
};
if (['cascader'].includes(type)) {
return /*#__PURE__*/React.createElement(FilterComp, _extends({}, props, {
itemProps: comProps,
filters: data,
isFiltering: isFiltering,
getFilterValue: value,
setFilterValue: setFilterValue,
handleClear: handleClear
}));
}
return /*#__PURE__*/React.createElement("div", {
className: cn('lm_select_dropdown_base', className),
style: style
}, /*#__PURE__*/React.createElement(Dropdown, {
trigger: ['click'],
visible: visible,
placement: "bottomLeft",
overlay: FilterControl,
onVisibleChange: setVisible,
className: cn(dropdownClassName)
}, /*#__PURE__*/React.createElement("div", {
className: cn('filter_item', {
isfiltering: isFiltering || visible,
active: !isFiltering && visible
})
}, /*#__PURE__*/React.createElement("div", {
className: "filter_item_label"
}, title && "".concat(title, ":")), /*#__PURE__*/React.createElement("div", {
className: "filter_item_value"
}, /*#__PURE__*/React.createElement("span", {
className: "checked"
}, checkedValue), /*#__PURE__*/React.createElement(IconFont, {
type: isFiltering ? 'lmweb-close-circle-fill' : 'lmweb-down',
className: "addonAfter",
onClick: handleClear
})))));
};
export default Index;