UNPKG

zp-bee

Version:

zp-bee,是一款基于 Dumi,由 React + TypeScript 开发的组件库 🎉。

246 lines (223 loc) 8.16 kB
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; var __rest = this && this.__rest || function (s, e) { var t = {}; for (var p in s) { if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; } if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; import Select from '../bee-select/select'; import React, { useCallback, useRef, useState, forwardRef, useImperativeHandle, useEffect } from 'react'; import { createPortal } from 'react-dom'; import { getPopContainer } from '../_utils'; import { ConfigContext } from '../bee-config'; var Option = Select.Option; var BeeMultiSelect = /*#__PURE__*/forwardRef(function (props, ref) { var label = props.label, _props$maxTagTextSize = props.maxTagTextSize, maxTagTextSize = _props$maxTagTextSize === void 0 ? 3 : _props$maxTagTextSize, _props$required = props.required, required = _props$required === void 0 ? false : _props$required, onChange = props.onChange, onFocus = props.onFocus, onBlur = props.onBlur, value = props.value, others = __rest(props, ["label", "maxTagTextSize", "required", "onChange", "onFocus", "onBlur", "value"]); var _useState = useState(maxTagTextSize), _useState2 = _slicedToArray(_useState, 2), maxTagTextLength = _useState2[0], setMaxTagTextLength = _useState2[1]; var _useState3 = useState(1), _useState4 = _slicedToArray(_useState3, 2), maxTagCount = _useState4[0], setMaxTagCount = _useState4[1]; var _useState5 = useState(false), _useState6 = _slicedToArray(_useState5, 2), showLabelPop = _useState6[0], setShowLabelPop = _useState6[1]; var container = useRef(null); var selectRef = useRef({}); var positionRef = useRef({}); var wrapperRef = useRef(); var injectRef = useRef(null); var isFocusRef = useRef(false); // 是否激活Focus; useImperativeHandle(ref, function () { return { onChange: onSelfChange, onFocus: onSelfFocus, onBlur: onSelfBlur, onChangeNoPenetrate: onChangeNoPenetrate //仅调用内部onChange方法 不调用外部透传的onChange }; }); var _React$useContext = React.useContext(ConfigContext), getPrefixCls = _React$useContext.getPrefixCls; var prefixCls = getPrefixCls('select'); useEffect(function () { var _a; // https://developer.mozilla.org/zh-CN/docs/Web/API/Intersection_Observer_API var options = { rootMargin: '0px', threshold: 1.0 }; var parent = (_a = container.current) === null || _a === void 0 ? void 0 : _a.previousSibling; var target = parent.querySelector(".".concat(prefixCls, "-selector")); var observerInter = new IntersectionObserver(function (entries, observer) { entries.forEach(function (entry) { // 可见状态下设置宽度 if (entry.isIntersecting) { var dom = parent.querySelector(".".concat(prefixCls, "-selector")); var span = document.createElement('span'); span.innerHTML = label; span.classList.add("".concat(prefixCls, "-label")); // 是否必填 if (required) { var must = document.createElement('span'); must.innerHTML = '*'; span.prepend(must); } dom.prepend(span); //此处使用getBoundingClientRect().width 在动画过程中会计算错误 var _left = "".concat(span.offsetWidth + 16, "px"); dom.style.paddingLeft = _left; var _entry$boundingClient = entry.boundingClientRect, x = _entry$boundingClient.x, y = _entry$boundingClient.y, _width = _entry$boundingClient.width, height = _entry$boundingClient.height, _top = _entry$boundingClient.top, domLeft = _entry$boundingClient.left; var domRect = { x: x, y: y, width: _width, height: height, top: _top, left: domLeft }; if (_width) { positionRef.current = domRect; } else { positionRef.current = Object.assign({}, domRect, { width: positionRef.current.width }); } // 停止监听 observerInter.unobserve(target); } }); }, options); var observer = new ResizeObserver(function (entries, observer) { entries.forEach(function (entry) { var _entry$contentRect = entry.contentRect, width = _entry$contentRect.width, top = _entry$contentRect.top; if (width) { positionRef.current = Object.assign({}, positionRef.current, { width: width }); observer.unobserve(target); observerInter.observe(target); } }); }); observer.observe(target); return function () { observer.disconnect(); observerInter.disconnect(); }; }, []); var onSelfFocus = useCallback(function (e) { isFocusRef.current = true; setMaxTagCount(undefined); setMaxTagTextLength(undefined); setShowLabelPop(false); onFocus && onFocus(e); }, []); var onSelfBlur = useCallback(function (e) { isFocusRef.current = false; setMaxTagCount(1); setMaxTagTextLength(maxTagTextSize); onBlur && onBlur(e); }, []); var onMouseEnter = useCallback(function () { if (!isFocusRef.current) { setShowLabelPop(true); } }, []); var onMouseLeave = useCallback(function () { setShowLabelPop(false); }, []); useEffect(function () { // labelInValue 直接从value中取label拼接 if (others.labelInValue) { if (Array.isArray(value)) { selectRef.current = value.map(function (i) { return { children: "".concat(i.label) }; }); } else { selectRef.current = []; } } // else { // selectRef.current = option; // } }, [value]); var onSelfChange = useCallback(function (value, option) { onChange === null || onChange === void 0 ? void 0 : onChange(value, option); onChangeNoPenetrate(value, option); }, []); var onChangeNoPenetrate = useCallback(function (value, option) { if (others.labelInValue) { if (Array.isArray(value)) { selectRef.current = value.map(function (i) { return { children: "".concat(i.label) }; }); } else { selectRef.current = []; } } else { selectRef.current = option; } }, []); var _positionRef$current = positionRef.current, top = _positionRef$current.top, left = _positionRef$current.left, width = _positionRef$current.width; return /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-wrapper"), ref: wrapperRef, style: others.style }, /*#__PURE__*/React.createElement(Select, Object.assign({ ref: injectRef, mode: "multiple", allowClear: true, maxTagCount: maxTagCount, maxTagTextLength: maxTagTextLength, onChange: onSelfChange, onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave, value: value }, others, { onFocus: onSelfFocus, onBlur: onSelfBlur })), /*#__PURE__*/React.createElement("noscript", { ref: container }), showLabelPop && selectRef.current && selectRef.current.length > 0 && /*#__PURE__*/createPortal( /*#__PURE__*/React.createElement("div", { className: "bee-hover", style: { top: "".concat(top + 36, "px"), left: "".concat(left + 40, "px"), width: width, maxHeight: "calc(100vh - ".concat(top + 36, "px)"), overflow: 'hidden' } }, selectRef.current.map(function (item) { return /*#__PURE__*/React.createElement("span", { className: "bee-span" }, item.children, ";"); })), getPopContainer())); }); BeeMultiSelect.Option = Option; export default BeeMultiSelect;