UNPKG

linkmore-design

Version:

🌈 🚀lm组件库。🚀

485 lines (466 loc) 17.2 kB
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;