mobile-more
Version:
基于 antd-mobile v5 扩展移动端 UI 组件
168 lines (167 loc) • 7.16 kB
JavaScript
"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault").default;
var _interopRequireWildcard = require("@babel/runtime/helpers/interopRequireWildcard").default;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
var _objectSpread2 = _interopRequireDefault(require("@babel/runtime/helpers/objectSpread2"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
var _react = _interopRequireWildcard(require("react"));
var _ut = require("ut2");
var _classnames = _interopRequireDefault(require("classnames"));
var _rcHooks = require("rc-hooks");
var _antdMobile = require("antd-mobile");
var _config = require("../../../config");
require("./AutoComplete.css");
var _getContainer = _interopRequireDefault(require("../../../utils/getContainer"));
var _renderToContainer = _interopRequireDefault(require("../../../utils/renderToContainer"));
var _excluded = ["visible", "onMaskClick", "destroyOnClose", "mask", "maskProps", "options", "onSelect", "bodyStyle", "getContainer", "className", "style"];
var prefixCls = "".concat(_config.prefixClass, "-autocomplete");
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 = (0, _objectWithoutProperties2.default)(_ref, _excluded);
var _useState = (0, _react.useState)(true),
_useState2 = (0, _slicedToArray2.default)(_useState, 2),
closed = _useState2[0],
setClosed = _useState2[1];
(0, _react.useEffect)(function () {
if (visible) {
setClosed(false);
}
}, [visible]);
if (!visible && closed && destroyOnClose) {
return null;
}
var node = /*#__PURE__*/_react.default.createElement("div", (0, _objectSpread2.default)({
className: (0, _classnames.default)("".concat(prefixCls, "-popup"), (0, _defineProperty2.default)({}, "".concat(prefixCls, "-popup-empty"), options.length === 0), className),
style: (0, _objectSpread2.default)({
display: visible ? 'block' : 'none'
}, style)
}, restProps), /*#__PURE__*/_react.default.createElement("div", {
className: "".concat(prefixCls, "-popup-body"),
style: bodyStyle
}, options.length > 0 && (/*#__PURE__*/_react.default.createElement(_antdMobile.List, null, options.map(function (item) {
return /*#__PURE__*/_react.default.createElement(_antdMobile.List.Item, {
key: item,
onClick: function onClick() {
onSelect === null || onSelect === void 0 ? void 0 : onSelect(item);
},
arrowIcon: false
}, item);
})))), mask && (/*#__PURE__*/_react.default.createElement(_antdMobile.Mask, (0, _objectSpread2.default)({
visible: visible,
onMaskClick: onMaskClick,
afterClose: function afterClose() {
setClosed(true);
},
destroyOnClose: true
}, maskProps))));
return (0, _renderToContainer.default)(node, (0, _getContainer.default)(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 = (0, _react.useRef)(null);
var _useSetState = (0, _rcHooks.useSetState)({
width: undefined,
top: undefined
}),
_useSetState2 = (0, _slicedToArray2.default)(_useSetState, 2),
state = _useSetState2[0],
setState = _useSetState2[1];
var visibleRef = (0, _rcHooks.useLatest)(visible);
var filterMethod = (0, _react.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 = (0, _react.useCallback)(function () {
var rect = mainRef.current.getBoundingClientRect();
setState({
width: rect.width,
top: rect.height
});
}, [setState]);
(0, _react.useEffect)(function () {
if (mainRef.current && visible) {
adjustSize();
}
}, [adjustSize, visible]);
(0, _react.useEffect)(function () {
if (_ut.isBrowser && mainRef.current) {
var throttleAdjustSize = (0, _ut.throttle)(function () {
if (visibleRef.current) {
adjustSize();
}
}, 100);
window.addEventListener('resize', throttleAdjustSize);
return function () {
window.removeEventListener('resize', throttleAdjustSize);
};
}
}, [adjustSize, visibleRef]);
var popupDom = /*#__PURE__*/_react.default.createElement(AutoCompletePopup, (0, _objectSpread2.default)((0, _objectSpread2.default)({
visible: visible,
onMaskClick: onMaskClick,
mask: mask && (hideMaskOnEmpty ? opts.length > 0 : true),
options: opts,
onSelect: onSelect,
maskProps: maskProps
}, popupProps), {}, {
bodyStyle: (0, _objectSpread2.default)({
width: state.width,
top: state.top
}, popupProps === null || popupProps === void 0 ? void 0 : popupProps.bodyStyle)
}));
// 通过 getContainer 将 popup 渲染至某个层级,需要手动设置 popupBody 宽度。
if (pure) {
return /*#__PURE__*/_react.default.createElement("div", {
className: prefixCls
}, children, popupDom);
}
return /*#__PURE__*/_react.default.createElement("div", {
className: (0, _classnames.default)(prefixCls, (0, _defineProperty2.default)({}, "".concat(prefixCls, "-visible"), visible))
}, /*#__PURE__*/_react.default.createElement("div", {
className: "".concat(prefixCls, "-main"),
ref: mainRef
}, children), popupDom);
};
var _default = exports.default = AutoComplete;