linkmore-design
Version:
🌈 🚀lm组件库。🚀
408 lines (388 loc) • 15.1 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 _hooks = require("../hooks");
var _ahooks = require("ahooks");
var _cascader = _interopRequireDefault(require("../cascader"));
var _classnames = _interopRequireDefault(require("classnames"));
var _button = _interopRequireDefault(require("../button"));
var _checkbox = _interopRequireDefault(require("../checkbox"));
var _dropdown = _interopRequireDefault(require("../dropdown"));
var _input = _interopRequireDefault(require("../input"));
var _empty = _interopRequireDefault(require("../empty"));
var _react = _interopRequireWildcard(require("react"));
var _iconFont = _interopRequireDefault(require("../icon-font"));
var _virtualList = _interopRequireDefault(require("../virtual-list"));
var _utils = require("./utils");
const FilterEmpty = () => {
return /*#__PURE__*/_react.default.createElement("div", {
className: "filter_empty"
}, /*#__PURE__*/_react.default.createElement(_empty.default, {
title: "\u6682\u65E0\u6570\u636E"
}));
};
// 下拉单选过滤器
const SelectFilter = ({
filters = [],
getFilterValue,
setFilterValue
}) => {
const inputRef = (0, _react.useRef)(null);
// 搜索后的筛选项
const [options, setOptions] = (0, _react.useState)(filters);
// 是否存在搜索, 当数据大于8时存在搜索
const isSearch = (0, _react.useMemo)(() => filters.length > 8, [filters.length]);
// 搜索
const handleFilter = (0, _hooks.useEvent)(val => setOptions(filters.filter(v => (0, _utils.onStringSearch)(val, v.label))));
// 单选事件
const onChange = (e, item) => {
e.preventDefault();
setFilterValue(item.value);
};
return /*#__PURE__*/_react.default.createElement("div", {
className: "filter_dropdown"
}, isSearch && /*#__PURE__*/_react.default.createElement("div", {
className: "filter_header"
}, /*#__PURE__*/_react.default.createElement(_input.default.Search, {
ref: inputRef,
allowClear: true,
size: "small",
placeholder: "\u8BF7\u8F93\u5165",
onSearch: handleFilter,
onChange: e => handleFilter(e.target.value)
})), /*#__PURE__*/_react.default.createElement("div", {
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: item.value === getFilterValue
}),
onClick: e => onChange(e, item)
}), /*#__PURE__*/_react.default.createElement("div", {
className: "filter_item-content"
}, item.label));
}), !options.length && /*#__PURE__*/_react.default.createElement(FilterEmpty, null)));
};
// 下拉多选过滤器: 要过滤的数据, 当前选中项, 触发过滤, 过滤前的数据
const CheckboxFilter = ({
filters = [],
getFilterValue = [],
setFilterValue
}) => {
const onValuesChange = (0, _hooks.useEvent)(checkedValues => setFilterValue(checkedValues, false));
// 父组件和子组件同步checked状态
const [checkedValues, setCheckedValues] = (0, _ahooks.useControllableValue)({
value: getFilterValue,
onChange: onValuesChange
});
// 搜索后的筛选项:[{value: '', ... }, ...]
const [options, setOptions] = (0, _react.useState)(filters);
// 是否存在搜索, 当数据大于8时存在搜索
const isSearch = (0, _react.useMemo)(() => filters.length > 8, [filters.length]);
// 是否全选: 选中的数据大于等于筛选后的数据 && 筛选后的数据全部存在于选中的数据中
const checkAll = (0, _react.useMemo)(() => {
const isLen = checkedValues.length >= options.length;
return isLen && options.every(({
value
}) => checkedValues.includes(value));
}, [checkedValues.length, options]);
// 是否半选: 存在选中的数据 && 未全选
const indeterminate = (0, _react.useMemo)(() => checkedValues.length && !checkAll, [checkedValues.length, checkAll]);
// 全选事件
const onCheckAllChange = e => {
const nValue = checkAll ? checkedValues.filter(v => !options.some(({
value
}) => v === value)) : Array.from(new Set([...checkedValues, ...options.map(v => v.value)]));
setCheckedValues(nValue);
};
// 搜索
const handleFilter = (0, _hooks.useEvent)(val => setOptions(filters.filter(v => (0, _utils.onStringSearch)(val, v.label))));
// 单选事件
const onChange = (e, item) => {
e.preventDefault();
e.stopPropagation();
const arr = checkedValues.includes(item.value) ? checkedValues.filter(v => v !== item.value) : [...checkedValues, item.value];
setCheckedValues(arr || undefined);
};
return /*#__PURE__*/_react.default.createElement("div", {
className: "select_dropdown"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "filter_header"
}, isSearch && /*#__PURE__*/_react.default.createElement(_input.default.Search, {
allowClear: true,
size: "small",
placeholder: "\u8BF7\u8F93\u5165",
onSearch: handleFilter,
onChange: e => handleFilter(e?.target?.value)
}), /*#__PURE__*/_react.default.createElement("div", {
className: "filter_header_operate"
}, /*#__PURE__*/_react.default.createElement(_checkbox.default, {
indeterminate: indeterminate,
onChange: onCheckAllChange,
checked: checkAll,
className: "filter_tip"
}, "\u5168\u90E8"), /*#__PURE__*/_react.default.createElement("div", null, /*#__PURE__*/_react.default.createElement("span", {
className: "filter_tip"
}, "\u5DF2\u9009: ", 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.value)
}),
onClick: e => onChange(e, item)
}), /*#__PURE__*/_react.default.createElement(_checkbox.default, {
value: item.value,
className: "filter_item-content"
}, item.label));
}), !options.length && /*#__PURE__*/_react.default.createElement(FilterEmpty, null)));
};
// 级联选择器
const CascaderFilter = props => {
const {
title,
filters,
getFilterValue,
setFilterValue,
itemProps = {},
isFiltering
} = props;
const [visible, setVisible] = (0, _react.useState)(false);
const [options, setOptions] = (0, _react.useState)(filters);
const [text, setText] = (0, _react.useState)('全部');
const [checkedValues, setCheckedValues] = (0, _react.useState)(getFilterValue || itemProps.multiple ? [] : '');
// const isSearch = useMemo(() => filters.length > 8, [filters.length]);
const handleFilter = (0, _hooks.useEvent)(val => setOptions(filters.filter(v => (0, _utils.onStringSearch)(val, v.label))));
// 重置级联弹框
const dropdownRender = menus => {
const inputRef = (0, _react.useRef)(null);
// 确定
const handleSure = () => {
setFilterValue(itemProps.multiple ? checkedValues.map(v => v[v.length - 1]) : checkedValues);
setVisible(false);
};
// 取消
const handleReset = () => {
if (inputRef.current) {
inputRef.current.input.value = '';
}
setFilterValue(undefined);
setCheckedValues(itemProps.multiple ? [] : '');
};
return /*#__PURE__*/_react.default.createElement("div", {
className: "filter_cascader_container filter_dropdown"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "filter_header"
}, /*#__PURE__*/_react.default.createElement(_input.default.Search, {
ref: inputRef,
allowClear: true,
size: "small",
placeholder: "\u8BF7\u8F93\u5165",
onSearch: handleFilter,
onChange: e => handleFilter(e.target.value)
})), menus, itemProps.multiple && /*#__PURE__*/_react.default.createElement("div", {
className: "filter_footer"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "footer_clear",
onClick: handleReset
}, "\u53D6\u6D88"), /*#__PURE__*/_react.default.createElement(_button.default, {
type: "primary",
size: "small",
onClick: handleSure
}, "\u786E\u5B9A")));
};
const onChange = (item, selectedOptions) => {
if (!item.length) {
setText('全部');
setCheckedValues(itemProps.multiple ? [] : '');
setFilterValue(undefined);
return;
}
if (itemProps.multiple) {
const arr = [];
selectedOptions.map(vals => {
return vals.length > 1 ? arr.push(vals.map(v => v.label).join('/')) : vals[0].children.map(v => arr.push(`${vals[0].label}/${v.label}`));
});
const showLabel = arr.length < 3 ? arr.join('、') : `${arr[0]}、+${arr.length}`;
setText(showLabel);
setCheckedValues(item);
} else {
setText(selectedOptions.map(v => v.label).join('/'));
setFilterValue(item);
setCheckedValues(item);
}
};
const handleClear = e => {
if (isFiltering) {
e.stopPropagation();
setText('全部');
setCheckedValues(itemProps.multiple ? [] : '');
setFilterValue(undefined);
}
};
return /*#__PURE__*/_react.default.createElement(_react.default.Fragment, null, /*#__PURE__*/_react.default.createElement(_cascader.default, (0, _extends2.default)({}, itemProps, {
options: options,
value: checkedValues,
onChange: onChange,
open: visible
// showCheckedStrategy="Cascader.SHOW_CHILD"
,
dropdownRender: dropdownRender,
onDropdownVisibleChange: v => setVisible(v)
}), /*#__PURE__*/_react.default.createElement("div", {
className: (0, _classnames.default)('filter_item', {
isfiltering: isFiltering || visible,
active: !isFiltering && visible
})
}, /*#__PURE__*/_react.default.createElement("div", {
className: "filter_item_label"
}, title, ":"), /*#__PURE__*/_react.default.createElement("div", {
className: "filter_item_value"
}, /*#__PURE__*/_react.default.createElement("div", {
className: "checked"
}, isFiltering ? text : '全部'), /*#__PURE__*/_react.default.createElement(_iconFont.default, {
type: isFiltering ? 'lm-icon-close-circle-fill' : 'lmweb-down',
className: "addonAfter",
onClick: handleClear
})))));
};
const FilterComp = props => {
const {
type,
...resetProps
} = props;
switch (type) {
case 'select':
return /*#__PURE__*/_react.default.createElement(SelectFilter, resetProps);
case 'checkbox':
return /*#__PURE__*/_react.default.createElement(CheckboxFilter, resetProps);
case 'cascader':
return /*#__PURE__*/_react.default.createElement(CascaderFilter, resetProps);
default:
return /*#__PURE__*/_react.default.createElement(SelectFilter, resetProps);
}
};
const Index = props => {
const {
className,
dropdownClassName,
title,
type,
options,
children,
style,
props: comProps
} = props;
const [visible, setVisible] = (0, _react.useState)(false);
const [value, setValue] = (0, _react.useState)();
const data = (0, _react.useMemo)(() => {
if (options) return options;
return (0, _utils.getArray)(children).map(item => ({
label: item.props.children,
value: item.props.value
}));
}, [options, children]);
// 判断是否正在过滤,普通过滤 && 嵌套过滤
const isFiltering = (0, _react.useMemo)(() => (0, _utils.getIsHas)(value), [value]);
// 设置过滤的内容 filterType: 'single' 存在时 单个勾选时触发, 默认按钮触发
const setFilterValue = (0, _hooks.useEvent)((val, close = true) => {
setValue(val);
props?.onChange?.(val);
close && setVisible(false);
});
// 展示的内容
const checkedValue = (0, _react.useMemo)(() => {
if (!isFiltering) return '全部';
// select & checkbox
if (['select', 'checkbox'].includes(type)) {
const findItem = data.find(v => Array.isArray(value) ? value.includes(v.value) : value === v.value);
if (!findItem) {
setFilterValue(type === 'checkbox' ? [] : '');
return '全部';
}
const filterLabel = findItem.label;
if (Array.isArray(value)) {
if (value.length > 1) {
return `${filterLabel}、+${value.length - 1}...`;
}
return filterLabel;
}
return filterLabel;
}
return value;
}, [comProps, data, isFiltering, setFilterValue, type, value]);
// 下拉组件渲染
const FilterControl = () => {
const obj = {
filters: data,
getFilterValue: value,
setFilterValue
};
return (0, _utils.render)((() => /*#__PURE__*/_react.default.createElement(FilterComp, (0, _extends2.default)({
type: type
}, obj)))());
};
// 清除筛选项
const handleClear = e => {
if (isFiltering) {
e.stopPropagation();
setFilterValue(type === 'checkbox' ? [] : '');
}
};
if (['cascader'].includes(type)) {
return /*#__PURE__*/_react.default.createElement(FilterComp, (0, _extends2.default)({}, props, {
itemProps: comProps,
filters: data,
isFiltering: isFiltering,
getFilterValue: value,
setFilterValue: setFilterValue,
handleClear: handleClear
}));
}
return /*#__PURE__*/_react.default.createElement("div", {
className: (0, _classnames.default)('lm_select_dropdown_base', className),
style: style
}, /*#__PURE__*/_react.default.createElement(_dropdown.default, {
trigger: ['click'],
visible: visible,
placement: "bottomLeft",
overlay: FilterControl,
onVisibleChange: setVisible,
className: (0, _classnames.default)(dropdownClassName)
}, /*#__PURE__*/_react.default.createElement("div", {
className: (0, _classnames.default)('filter_item', {
isfiltering: isFiltering || visible,
active: !isFiltering && visible
})
}, /*#__PURE__*/_react.default.createElement("div", {
className: "filter_item_label"
}, title && `${title}:`), /*#__PURE__*/_react.default.createElement("div", {
className: "filter_item_value"
}, /*#__PURE__*/_react.default.createElement("span", {
className: "checked"
}, checkedValue), /*#__PURE__*/_react.default.createElement(_iconFont.default, {
type: isFiltering ? 'lm-icon-close-circle-fill' : 'lmweb-down',
className: "addonAfter",
onClick: handleClear
})))));
};
var _default = Index;
exports.default = _default;