UNPKG

mobile-more

Version:

基于 antd-mobile v5 扩展移动端 UI 组件

162 lines (161 loc) 6.28 kB
import _extends from "@babel/runtime/helpers/esm/extends"; import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _defineProperty from "@babel/runtime/helpers/esm/defineProperty"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties"; var _excluded = ["visible", "onMaskClick", "destroyOnClose", "mask", "maskProps", "options", "onSelect", "bodyStyle", "getContainer", "className", "style"]; import React, { useCallback, useEffect, useRef, useState } from 'react'; import { isBrowser, throttle } from 'ut2'; import classNames from 'classnames'; import { useLatest, useSetState } from 'rc-hooks'; import { List, Mask } from 'antd-mobile'; import { prefixClass } from "../../../config"; import "./AutoComplete.css"; import getContainer from "../../../utils/getContainer"; import renderToContainer from "../../../utils/renderToContainer"; var prefixCls = "".concat(prefixClass, "-auto-complete"); var AutoCompletePopup = function AutoCompletePopup(_ref) { var visible = _ref.visible, onMaskClick = _ref.onMaskClick, _ref$destroyOnClose = _ref.destroyOnClose, destroyOnClose = _ref$destroyOnClose === void 0 ? true : _ref$destroyOnClose, _ref$mask = _ref.mask, mask = _ref$mask === void 0 ? true : _ref$mask, maskProps = _ref.maskProps, _ref$options = _ref.options, options = _ref$options === void 0 ? [] : _ref$options, onSelect = _ref.onSelect, bodyStyle = _ref.bodyStyle, customContainer = _ref.getContainer, className = _ref.className, style = _ref.style, restProps = _objectWithoutProperties(_ref, _excluded); var _useState = useState(true), _useState2 = _slicedToArray(_useState, 2), closed = _useState2[0], setClosed = _useState2[1]; useEffect(function () { if (visible) { setClosed(false); } }, [visible]); if (!visible && closed && destroyOnClose) { return null; } var node = /*#__PURE__*/React.createElement("div", _extends({ className: classNames("".concat(prefixCls, "-popup"), _defineProperty({}, "".concat(prefixCls, "-popup-empty"), options.length === 0), className), style: _objectSpread({ display: visible ? 'block' : 'none' }, style) }, restProps), /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-popup-body"), style: bodyStyle }, options.length > 0 && /*#__PURE__*/React.createElement(List, null, options.map(function (item) { return /*#__PURE__*/React.createElement(List.Item, { key: item, onClick: function onClick() { onSelect === null || onSelect === void 0 || onSelect(item); }, arrowIcon: false }, item); }))), mask && /*#__PURE__*/React.createElement(Mask, _extends({ visible: visible, onMaskClick: onMaskClick, afterClose: function afterClose() { setClosed(true); }, destroyOnClose: true }, maskProps))); return renderToContainer(node, getContainer(customContainer) || document.body); }; var AutoComplete = function AutoComplete(props) { var _props$options = props.options, options = _props$options === void 0 ? [] : _props$options, _props$mask = props.mask, mask = _props$mask === void 0 ? true : _props$mask, visible = props.visible, maskProps = props.maskProps, onSelect = props.onSelect, onMaskClick = props.onMaskClick, popupProps = props.popupProps, value = props.value, _props$hideMaskOnEmpt = props.hideMaskOnEmpty, hideMaskOnEmpty = _props$hideMaskOnEmpt === void 0 ? false : _props$hideMaskOnEmpt, _props$filterOption = props.filterOption, filterOption = _props$filterOption === void 0 ? true : _props$filterOption, pure = props.pure, children = props.children; var mainRef = useRef(null); var _useSetState = useSetState({ width: undefined, top: undefined }), _useSetState2 = _slicedToArray(_useSetState, 2), state = _useSetState2[0], setState = _useSetState2[1]; var visibleRef = useLatest(visible); var filterMethod = useCallback(function (inputValue, option) { if (typeof filterOption === 'function') { return filterOption(inputValue, option); } if (filterOption) { var trimVal = inputValue === null || inputValue === void 0 ? void 0 : inputValue.trim(); return !trimVal || option.indexOf(trimVal) > -1; } return true; }, [filterOption]); var opts = options.filter(function (item) { return filterMethod(value || '', item); }); var adjustSize = useCallback(function () { var rect = mainRef.current.getBoundingClientRect(); setState({ width: rect.width, top: rect.height }); }, [setState]); useEffect(function () { if (mainRef.current && visible) { adjustSize(); } }, [adjustSize, visible]); useEffect(function () { if (isBrowser && mainRef.current) { var throttleAdjustSize = throttle(function () { if (visibleRef.current) { adjustSize(); } }, 100); window.addEventListener('resize', throttleAdjustSize); return function () { window.removeEventListener('resize', throttleAdjustSize); }; } }, [adjustSize, visibleRef]); var popupDom = /*#__PURE__*/React.createElement(AutoCompletePopup, _extends({ visible: visible, onMaskClick: onMaskClick, mask: mask && (hideMaskOnEmpty ? opts.length > 0 : true), options: opts, onSelect: onSelect, maskProps: maskProps }, popupProps, { bodyStyle: _objectSpread({ width: state.width, top: state.top }, popupProps === null || popupProps === void 0 ? void 0 : popupProps.bodyStyle) })); // 通过 getContainer 将 popup 渲染至某个层级,需要手动设置 popupBody 宽度。 if (pure) { return /*#__PURE__*/React.createElement("div", { className: prefixCls }, children, popupDom); } return /*#__PURE__*/React.createElement("div", { className: classNames(prefixCls, _defineProperty({}, "".concat(prefixCls, "-visible"), visible)) }, /*#__PURE__*/React.createElement("div", { className: "".concat(prefixCls, "-main"), ref: mainRef }, children), popupDom); }; export default AutoComplete;