UNPKG

qt-public-ui

Version:

新设计规范下业务组件库

356 lines (355 loc) 15.1 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import React, { Children, useState, useEffect, useCallback, useRef } from 'react'; import classnames from 'classnames'; import { useDropdownClickAway, useUpdateEffect } from 'qt-public-hooks'; import { Dropdown, Tag, Checkbox, Popover, Button } from 'antd'; import { isFunction } from 'lodash'; // import { ConfigConsumer } from 'antd/lib/config-provider'; import { IconSlim as Icon, Input, VirtualList, Default } from '..'; export default (function (props) { var children = props.children, _props$defaultValue = props.defaultValue, defaultValue = _props$defaultValue === void 0 ? [] : _props$defaultValue, _props$value = props.value, value = _props$value === void 0 ? [] : _props$value, onChange = props.onChange, _props$seperator = props.seperator, seperator = _props$seperator === void 0 ? false : _props$seperator, suffixIcon = props.suffixIcon, renderSelectedContent = props.renderSelectedContent, _props$useAllSelectio = props.useAllSelection, useAllSelection = _props$useAllSelectio === void 0 ? false : _props$useAllSelectio, _props$optionFilterPr = props.optionFilterProp, optionFilterProp = _props$optionFilterPr === void 0 ? 'value' : _props$optionFilterPr, _props$style = props.style, style = _props$style === void 0 ? {} : _props$style, _props$disabled = props.disabled, disabled = _props$disabled === void 0 ? false : _props$disabled, _props$vHeight = props.vHeight, vHeight = _props$vHeight === void 0 ? Children.count(children) < 7 ? Children.count(children) * 36 : 250 : _props$vHeight, _props$styleType = props.styleType, styleType = _props$styleType === void 0 ? '' : _props$styleType, _props$placeholder = props.placeholder, placeholder = _props$placeholder === void 0 ? '请选择...' : _props$placeholder, notFoundContent = props.notFoundContent, getPopupContainer = props.getPopupContainer, _props$overlayClassNa = props.overlayClassName, overlayClassName = _props$overlayClassNa === void 0 ? '' : _props$overlayClassNa, _props$extendDropdown = props.extendDropdownRender, extendDropdownRender = _props$extendDropdown === void 0 ? null : _props$extendDropdown, _props$addOkBtn = props.addOkBtn, addOkBtn = _props$addOkBtn === void 0 ? false : _props$addOkBtn, onOkChange = props.onOkChange; var isControlled = ('value' in props); var isOpenControlled = ('visible' in props); var _useState = useState(false), open = _useState[0], setOpen = _useState[1]; var _useState2 = useState('全部'), allSelection = _useState2[0], setAllSelection = _useState2[1]; var _useState3 = useState([]), filterChildren = _useState3[0], setFilterChildren = _useState3[1]; var _useState4 = useState(isControlled ? value : defaultValue), multiSelectValue = _useState4[0], setMultiSelectValue = _useState4[1]; var _useState5 = useState(false), showPopover = _useState5[0], setShowPopover = _useState5[1]; var childrenCount = Children.count(children); var selectedContainerRef = useRef(null); var dropDownCls = useDropdownClickAway(function () { if (isOpenControlled) { props.onVisibleChange && props.onVisibleChange(false); } else { setOpen(false); } }, []); var _useState6 = useState(), search = _useState6[0], setSearch = _useState6[1]; var getSearchValue = function getSearchValue(child) { if (typeof child.props[optionFilterProp] === 'string') { return child.props[optionFilterProp]; } else { return getSearchValue(child.props[optionFilterProp]); } }; var traverseChildren = function traverseChildren(_value) { if (!_value) return; if (typeof _value === 'string') { return _value; } else { return traverseChildren(_value.props.children || _value.props.tooltipProps.title); } }; var getMultipSelectedOptions = useCallback(function (values) { var childrenArray = Children.toArray(children); if (values.length === 0) { return []; } else { var _values = []; childrenArray.forEach(function (item) { var _props = item.props; if (values.includes(_props.value)) { var newValue = traverseChildren(_props.children); _values.push(newValue); } }); return _values; } }, [children, traverseChildren]); useEffect(function () { if (!search) { setFilterChildren(children); return; } var filtered = []; React.Children.map(children, function (child) { var searchValue = getSearchValue(child); if (String(searchValue).toLowerCase().includes(search.toLowerCase())) { filtered.push(child); } }); setFilterChildren(filtered); }, [search, children]); useEffect(function () { if (typeof useAllSelection === 'string') { setAllSelection(useAllSelection); } }, [useAllSelection]); useEffect(function () { if (seperator) { var _selectedContainerRef; var selectedWrapperWidth = selectedContainerRef === null || selectedContainerRef === void 0 ? void 0 : (_selectedContainerRef = selectedContainerRef.current) === null || _selectedContainerRef === void 0 ? void 0 : _selectedContainerRef.clientWidth; var selectedList = getMultipSelectedOptions(multiSelectValue) || []; var _getTextWidthAndHeigh = getTextWidthAndHeight(selectedList === null || selectedList === void 0 ? void 0 : selectedList.join('、')), selectedListWidth = _getTextWidthAndHeigh.width; selectedListWidth + 2 >= selectedWrapperWidth ? setShowPopover(true) : setShowPopover(false); } }, [seperator, multiSelectValue.length, getMultipSelectedOptions, multiSelectValue]); // 计算字符串宽度和高度 var getTextWidthAndHeight = function getTextWidthAndHeight(text, fontSize, fontFamily) { var text_span = document.createElement('span'); var result = { width: 0, height: 0 }; result.width = text_span.offsetWidth; result.height = text_span.offsetHeight; text_span.style.visibility = 'hidden'; text_span.style.fontSize = fontSize || '12px'; text_span.style.fontFamily = fontFamily || 'Alibaba-PuHuiTi-Regular'; text_span.style.display = 'inline-block'; document.body.appendChild(text_span); if (typeof text_span.textContent !== 'undefined') { text_span.textContent = text; } else { text_span.innerText = text; } result.width = parseFloat(window.getComputedStyle(text_span).width) - result.width; result.height = parseFloat(window.getComputedStyle(text_span).height) - result.height; document.body.removeChild(text_span); return result; }; useUpdateEffect(function () { isControlled && setMultiSelectValue(props.value); }, [props.value]); var renderOptions = function renderOptions(opt) { var _ref = opt || {}, _value = _ref.value, index = _ref.index; var _filterChildren = Children.toArray(filterChildren); var child = _filterChildren[index]; return child && /*#__PURE__*/React.createElement("li", { key: _value }, React.cloneElement(child, { selectValue: multiSelectValue, optionChange: function optionChange(selectedValue) { !isControlled && setMultiSelectValue(selectedValue); onChange && onChange(selectedValue); } })); }; var footerOkClick = function footerOkClick(e) { if (e) { e.stopPropagation(); } if (isOpenControlled) { props.onVisibleChange && props.onVisibleChange(false); } else { setOpen(false); } onOkChange && onOkChange(multiSelectValue); }; var dropdownRender = function dropdownRender() { var showSearch = props.showSearch, _props$searchPlacehol = props.searchPlaceholder, searchPlaceholder = _props$searchPlacehol === void 0 ? '搜索...' : _props$searchPlacehol; var _filterChildren = Children.toArray(filterChildren); var _filterChildrenMap = (Array.isArray(_filterChildren) ? _filterChildren : []).map(function (item, index) { var _item$props; return { value: item === null || item === void 0 ? void 0 : (_item$props = item.props) === null || _item$props === void 0 ? void 0 : _item$props.value, index: index }; }); var renderDom = /*#__PURE__*/React.createElement("div", { className: "umui-multi-select-dropdown" }, showSearch && /*#__PURE__*/React.createElement("div", { className: "search-box" }, /*#__PURE__*/React.createElement(Input.Search, { value: search, placeholder: searchPlaceholder, styleType: "underline", onChange: function onChange(_ref2) { var target = _ref2.target; setSearch(target.value); } })), useAllSelection && /*#__PURE__*/React.createElement("div", { className: classnames('use-all-selection', { 'use-all-selection-checked': !!multiSelectValue.length && multiSelectValue.length < childrenCount || childrenCount === multiSelectValue.length }), onClick: function onClick() { handleCheckAll(); } }, /*#__PURE__*/React.createElement(Checkbox, { indeterminate: !!multiSelectValue.length && multiSelectValue.length < childrenCount, checked: childrenCount === multiSelectValue.length }), /*#__PURE__*/React.createElement("span", null, allSelection)), /*#__PURE__*/React.createElement("ul", { className: "umui-multi-options-wrapper" }, (_filterChildren === null || _filterChildren === void 0 ? void 0 : _filterChildren.length) > 0 ? /*#__PURE__*/React.createElement(VirtualList, { data: _filterChildrenMap, height: vHeight, itemHeight: 28, itemKey: "value" }, renderOptions) : notFoundContent || /*#__PURE__*/React.createElement(Default, { type: "nothing" })), !!addOkBtn && /*#__PURE__*/React.createElement("div", { className: "umui-multi-footer" }, /*#__PURE__*/React.createElement("p", null, "\u5DF2\u9009\u4E2D", (multiSelectValue === null || multiSelectValue === void 0 ? void 0 : multiSelectValue.length) || 0, "\u4E2A"), /*#__PURE__*/React.createElement(Button, { type: "primary", onClick: footerOkClick }, "\u786E\u5B9A"))); return extendDropdownRender ? extendDropdownRender(renderDom) : renderDom; }; var handleCheckAll = function handleCheckAll() { var childrenArray = Children.toArray(children); if (childrenArray.length !== multiSelectValue.length) { var allValues = childrenArray.map(function (_ref3) { var _props = _ref3.props; return _props.value; }); !isControlled && setMultiSelectValue(allValues); onChange && onChange(allValues, true); } else { !isControlled && setMultiSelectValue([]); onChange && onChange([], false); } }; var onDeselect = function onDeselect(option) { var childrenArray = Children.toArray(children); var _multiSelectValue = [].concat(multiSelectValue); childrenArray.forEach(function (item) { var _props = item.props; if (option === _props.children) { var _index = _multiSelectValue.findIndex(function (v) { return v === _props.value; }); _multiSelectValue.splice(_index, 1); } }); !isControlled && setMultiSelectValue(_multiSelectValue); onChange && onChange(_multiSelectValue); }; var isShowClosable = function isShowClosable(option) { var childrenArray = Children.toArray(children); return !childrenArray.some(function (_ref4) { var _props = _ref4.props; return _props.children === option && _props.disabled === true; }); }; var _suffixIcon = suffixIcon ? React.cloneElement(suffixIcon, { className: classnames('um-icon-filter', { 'umui-multi-select-active-color': open, 'umui-multi-select-active-transform': open }) }) : /*#__PURE__*/React.createElement(Icon, { type: "umicon-filter", className: classnames('um-icon-filter', { 'umui-multi-select-active-color': open, 'umui-multi-select-active-transform': open }) }); var renderSelected = useCallback(function () { var selectedList = getMultipSelectedOptions(multiSelectValue) || []; if (renderSelectedContent && isFunction(renderSelectedContent)) { return renderSelectedContent(selectedList); } else { return seperator ? showPopover ? /*#__PURE__*/React.createElement(Popover, { content: selectedList.join('、') }, /*#__PURE__*/React.createElement("div", { className: "options-seperator" }, selectedList.join('、'))) : /*#__PURE__*/React.createElement("div", { className: "options-seperator" }, selectedList.join('、')) : selectedList.map(function (option) { return /*#__PURE__*/React.createElement(Tag, { closable: isShowClosable(option), key: option, onClose: function onClose() { return onDeselect(option); }, visible: true }, /*#__PURE__*/React.createElement("span", { className: "multi-select-option-text" }, option)); }); } }, [getMultipSelectedOptions, multiSelectValue, renderSelectedContent, seperator, showPopover, isShowClosable, onDeselect]); var onVisibleChange = function onVisibleChange(isOpen) { if (isOpenControlled) { props.onVisibleChange && props.onVisibleChange(isOpen); } else if (addOkBtn && !isOpen) { footerOkClick(); } }; useEffect(function () { if (isOpenControlled) { setOpen(props.visible); } }, [props.visible, isOpenControlled]); return /*#__PURE__*/React.createElement("div", { className: classnames('umui-multi-select', { 'umui-multi-select-disabled': disabled }, { 'umui-multi-select-underline': styleType === 'underline' }), style: _extends({ minWidth: style.width || style.minWidth, width: 'unset' }, style), onClick: function onClick(e) { e.stopPropagation(); !props.disabled && (isOpenControlled ? props.onVisibleChange && props.onVisibleChange(true) : setOpen(true)); } }, /*#__PURE__*/React.createElement(Dropdown, { trigger: ['click'], overlay: dropdownRender, visible: open, onVisibleChange: onVisibleChange, overlayStyle: style, overlayClassName: classnames("umui-category-popup " + overlayClassName, dropDownCls), getPopupContainer: getPopupContainer }, /*#__PURE__*/React.createElement("div", { className: classnames('umui-multi-selected-options', { 'umui-multi-select-active': open, 'umui-multi-selected-options-seperator': seperator }) }, (multiSelectValue === null || multiSelectValue === void 0 ? void 0 : multiSelectValue.length) > 0 ? /*#__PURE__*/React.createElement("div", { className: "umui-multi-selected-options-wrapper", ref: selectedContainerRef }, renderSelected()) : /*#__PURE__*/React.createElement("div", { className: "umui-multi-select-placeholder" }, placeholder), _suffixIcon))); });