UNPKG

@antmjs/vantui

Version:

一套适用于Taro3及React的vantui组件库

528 lines (527 loc) 21.1 kB
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator"; import _slicedToArray from "@babel/runtime/helpers/slicedToArray"; import _defineProperty from "@babel/runtime/helpers/defineProperty"; import _regeneratorRuntime from "@babel/runtime/regenerator"; function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } /* eslint-disable import/no-named-as-default */ import { useState, useEffect } from 'react'; import { View, Text } from '@tarojs/components'; import Tab from '../tab'; import Tabs from '../tabs'; import Button from '../button'; import Popup from '../popup'; import { get } from '../default-props'; import { CascaderItem } from './cascaderItem'; import { convertListToOptions } from './helper'; import ScrollViewTimeout from './scrollViewTimeout'; import Tree from './tree'; import { jsx as _jsx } from "react/jsx-runtime"; import { jsxs as _jsxs } from "react/jsx-runtime"; var d = get().Cascader || {}; var defaultProps = { className: '', style: {}, visible: false, options: [], value: [], title: '', textKey: 'text', valueKey: 'value', childrenKey: 'children', convertConfig: {}, closeable: false, closeIconPosition: 'top-right', closeIcon: 'close', checkStrictly: false, okText: '确定', lazy: false, lazyLoad: function lazyLoad() {}, onClose: function onClose() {}, onChange: function onChange() {}, onPathChange: function onPathChange() {} }; var InternalCascader = function InternalCascader(props) { var _defaultProps$d$props = _objectSpread(_objectSpread(_objectSpread({}, defaultProps), d), props), className = _defaultProps$d$props.className, style = _defaultProps$d$props.style, visible = _defaultProps$d$props.visible, options = _defaultProps$d$props.options, value = _defaultProps$d$props.value, title = _defaultProps$d$props.title, textKey = _defaultProps$d$props.textKey, valueKey = _defaultProps$d$props.valueKey, childrenKey = _defaultProps$d$props.childrenKey, convertConfig = _defaultProps$d$props.convertConfig, closeable = _defaultProps$d$props.closeable, closeIconPosition = _defaultProps$d$props.closeIconPosition, closeIcon = _defaultProps$d$props.closeIcon, lazy = _defaultProps$d$props.lazy, checkStrictly = _defaultProps$d$props.checkStrictly, okText = _defaultProps$d$props.okText, lazyLoad = _defaultProps$d$props.lazyLoad, onClose = _defaultProps$d$props.onClose, onChange = _defaultProps$d$props.onChange, scrollIntoView = _defaultProps$d$props.scrollIntoView, onPathChange = _defaultProps$d$props.onPathChange; var _useState = useState('c1'), _useState2 = _slicedToArray(_useState, 2), tabvalue = _useState2[0], setTabvalue = _useState2[1]; var _useState3 = useState([]), _useState4 = _slicedToArray(_useState3, 2), optiosData = _useState4[0], setOptiosData = _useState4[1]; var _useState5 = useState(false), _useState6 = _slicedToArray(_useState5, 2), tabAnimate = _useState6[0], settabAnimate = _useState6[1]; var isLazy = function isLazy() { return !!state.configs.lazy && Boolean(state.configs.lazyLoad); }; var _useState7 = useState({ optionsData: [], panes: [{ nodes: [], selectedNode: [], paneKey: '' }], innerValue: value, tree: new Tree([], {}), tabsCursor: 0, // 选中的tab项 initLoading: false, currentProcessNode: [], configs: { lazy: lazy, lazyLoad: lazyLoad, valueKey: valueKey, textKey: textKey, childrenKey: childrenKey, convertConfig: convertConfig }, lazyLoadMap: new Map() }), _useState8 = _slicedToArray(_useState7, 1), state = _useState8[0]; useEffect(function () { if (value !== state.innerValue) { state.innerValue = value; } // eslint-disable-next-line react-hooks/exhaustive-deps }, [value]); useEffect(function () { initData(); // eslint-disable-next-line react-hooks/exhaustive-deps }, [options]); var initData = /*#__PURE__*/function () { var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() { return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: // 初始化开始处理数据 state.lazyLoadMap.clear(); if (convertConfig && Object.keys(convertConfig).length > 0) { state.optionsData = convertListToOptions(options, convertConfig); } else { state.optionsData = options; } state.tree = new Tree(state.optionsData, { value: state.configs.valueKey, text: state.configs.textKey, children: state.configs.childrenKey }); if (!(isLazy() && !state.tree.nodes.length)) { _context.next = 6; break; } _context.next = 6; return invokeLazyLoad({ root: true, loading: true, text: '', value: '' }); case 6: state.panes = [{ nodes: state.tree.nodes, selectedNode: null, paneKey: 'c1' }]; syncValue(); setOptiosData(state.panes); case 9: case "end": return _context.stop(); } }, _callee); })); return function initData() { return _ref.apply(this, arguments); }; }(); // 处理有默认值时的数据 var syncValue = /*#__PURE__*/function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() { var _state$tree, _state$tree$nodes; var currentValue, needToSync, parent, last, pathNodes; return _regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: currentValue = state.innerValue; if (!(currentValue === undefined || currentValue === null || !((_state$tree = state.tree) !== null && _state$tree !== void 0 && (_state$tree$nodes = _state$tree.nodes) !== null && _state$tree$nodes !== void 0 && _state$tree$nodes.length))) { _context3.next = 3; break; } return _context3.abrupt("return"); case 3: if (!(currentValue.length === 0)) { _context3.next = 6; break; } state.tabsCursor = 0; // state.panes = [{ nodes: state.tree.nodes, selectedNode: null }]; return _context3.abrupt("return"); case 6: needToSync = currentValue; if (!(isLazy() && Array.isArray(currentValue) && currentValue.length)) { _context3.next = 19; break; } needToSync = []; parent = state.tree.nodes.find(function (node) { return node.value === currentValue[0]; }); if (!parent) { _context3.next = 19; break; } needToSync = [parent.value]; state.initLoading = true; _context3.next = 15; return currentValue.slice(1).reduce( /*#__PURE__*/function () { var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2(p, value) { var _parent$children; var parent, node; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: _context2.next = 2; return p; case 2: parent = _context2.sent; _context2.next = 5; return invokeLazyLoad(parent); case 5: node = parent === null || parent === void 0 ? void 0 : (_parent$children = parent.children) === null || _parent$children === void 0 ? void 0 : _parent$children.find(function (item) { return item.value === value; }); if (node) { needToSync.push(value); } return _context2.abrupt("return", Promise.resolve(node)); case 8: case "end": return _context2.stop(); } }, _callee2); })); return function (_x, _x2) { return _ref3.apply(this, arguments); }; }(), Promise.resolve(parent)); case 15: last = _context3.sent; _context3.next = 18; return invokeLazyLoad(last); case 18: state.initLoading = false; case 19: if (needToSync.length && currentValue === value) { pathNodes = state.tree.getPathNodesByValue(needToSync); pathNodes.forEach(function (node, index) { state.tabsCursor = index; // 当有默认值时,不触发 chooseItem 里的 emit 事件 _chooseItem(node, true); }); } case 20: case "end": return _context3.stop(); } }, _callee3); })); return function syncValue() { return _ref2.apply(this, arguments); }; }(); var invokeLazyLoad = /*#__PURE__*/function () { var _ref4 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4(node) { var parent, lazyLoadPromise, nodes; return _regeneratorRuntime.wrap(function _callee4$(_context4) { while (1) switch (_context4.prev = _context4.next) { case 0: if (node) { _context4.next = 2; break; } return _context4.abrupt("return"); case 2: if (state.configs.lazyLoad) { _context4.next = 5; break; } node.leaf = true; return _context4.abrupt("return"); case 5: if (!(state.tree.isLeaf(node, isLazy()) || state.tree.hasChildren(node, isLazy()))) { _context4.next = 7; break; } return _context4.abrupt("return"); case 7: node.loading = true; parent = node.root ? null : node; lazyLoadPromise = state.lazyLoadMap.get(node); if (!lazyLoadPromise) { lazyLoadPromise = new Promise(function (resolve) { var _state$configs$lazyLo, _state$configs; // 外部必须resolve (_state$configs$lazyLo = (_state$configs = state.configs).lazyLoad) === null || _state$configs$lazyLo === void 0 ? void 0 : _state$configs$lazyLo.call(_state$configs, node, resolve); }); state.lazyLoadMap.set(node, lazyLoadPromise); } _context4.next = 13; return lazyLoadPromise; case 13: nodes = _context4.sent; if (Array.isArray(nodes) && nodes.length > 0) { state.tree.updateChildren(nodes, parent); } else { // 如果加载完成后没有提供子节点,作为叶子节点处理 node.leaf = true; } node.loading = false; state.lazyLoadMap.delete(node); case 17: case "end": return _context4.stop(); } }, _callee4); })); return function invokeLazyLoad(_x3) { return _ref4.apply(this, arguments); }; }(); var close = function close() { settabAnimate(false); onClose && onClose(); }; var closePopup = function closePopup() { close(); settabAnimate(false); }; var onOk = function onOk() { var pathNodes = state.panes.map(function (item) { return item.selectedNode; }); var optionParams = pathNodes.reduce(function (pre, cur) { if (cur) { pre.push(cur.value); } return pre; }, []); onChange === null || onChange === void 0 ? void 0 : onChange(optionParams, pathNodes); closePopup(); }; /* type: 是否是静默模式,是的话不触发事件 tabsCursor: tab的索引 */ var _chooseItem = /*#__PURE__*/function () { var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(node, type) { var pathNodes, _pathNodes, optionParams, level, _pathNodes2, _optionParams; return _regeneratorRuntime.wrap(function _callee5$(_context5) { while (1) switch (_context5.prev = _context5.next) { case 0: if (!(!type && node.disabled || !state.panes[state.tabsCursor])) { _context5.next = 2; break; } return _context5.abrupt("return"); case 2: if (!checkStrictly) { _context5.next = 9; break; } pathNodes = state.panes.map(function (item) { return item.selectedNode; }); if (!pathNodes.includes(node)) { _context5.next = 9; break; } // 取消选中状态 state.panes = state.panes.slice(0, node.level + 1); // @ts-ignore state.panes[node.level].selectedNode = null; setOptiosData(state.panes); return _context5.abrupt("return"); case 9: if (!state.tree.isLeaf(node, isLazy())) { _context5.next = 16; break; } node.leaf = true; // @ts-ignore state.panes[state.tabsCursor].selectedNode = node; state.panes = state.panes.slice(0, node.level + 1); if (!type) { _pathNodes = state.panes.map(function (item) { return item.selectedNode; }); optionParams = _pathNodes.map(function (item) { return item.value; }); onChange === null || onChange === void 0 ? void 0 : onChange(optionParams, _pathNodes); onPathChange === null || onPathChange === void 0 ? void 0 : onPathChange(optionParams, _pathNodes); close(); } setOptiosData(state.panes); return _context5.abrupt("return"); case 16: if (!state.tree.hasChildren(node, isLazy())) { _context5.next = 26; break; } level = node.level + 1; // @ts-ignore state.panes[state.tabsCursor].selectedNode = node; state.panes = state.panes.slice(0, level); state.tabsCursor = level; state.panes.push({ nodes: node.children || [], selectedNode: null, paneKey: "c".concat(state.tabsCursor + 1) }); setOptiosData(state.panes); // 延时触发优化交互 setTabvalue("c".concat(state.tabsCursor + 1)); if (!type) { _pathNodes2 = state.panes.map(function (item) { return item.selectedNode; }); _optionParams = _pathNodes2.map(function (item) { return item === null || item === void 0 ? void 0 : item.value; }); onPathChange === null || onPathChange === void 0 ? void 0 : onPathChange(_optionParams, _pathNodes2); } return _context5.abrupt("return"); case 26: state.currentProcessNode = node; if (!node.loading) { _context5.next = 29; break; } return _context5.abrupt("return"); case 29: _context5.next = 31; return invokeLazyLoad(node); case 31: if (state.currentProcessNode === node) { // @ts-ignore state.panes[state.tabsCursor].selectedNode = node; _chooseItem(node, type); } setOptiosData(state.panes); case 33: case "end": return _context5.stop(); } }, _callee5); })); return function chooseItem(_x4, _x5) { return _ref5.apply(this, arguments); }; }(); return /*#__PURE__*/_jsx(View, { className: "van-cascader ".concat(className), style: style, children: /*#__PURE__*/_jsxs(Popup, { className: "van-cascadar-popup", show: visible, position: "bottom", round: true, closeable: closeable && !checkStrictly, closeIconPosition: closeIconPosition, closeIcon: closeIcon, onClickOverlay: closePopup, onClose: closePopup, children: [/*#__PURE__*/_jsxs(View, { className: 'van-cascader__title', children: [title, checkStrictly && /*#__PURE__*/_jsx(Button, { onClick: onOk, plain: true, type: "default", className: "van-cascader__ok-btn", children: okText })] }), /*#__PURE__*/_jsx(Tabs, { active: tabvalue, animated: tabAnimate, renderNavLeft: /*#__PURE__*/_jsx(View, { className: "van-cascader-tab-box", children: optiosData.map(function (pane, index) { var _pane$selectedNode, _pane$selectedNode2; return /*#__PURE__*/_jsx(View, { onClick: function onClick() { if (!tabAnimate) settabAnimate(true); setTabvalue(pane.paneKey); state.tabsCursor = index; }, className: "van-tabs__titles-item ".concat(tabvalue === pane.paneKey ? 'active' : ''), children: /*#__PURE__*/_jsxs(Text, { className: "van-tabs__titles-item__text", children: [!state.initLoading && state.panes.length && (pane === null || pane === void 0 ? void 0 : (_pane$selectedNode = pane.selectedNode) === null || _pane$selectedNode === void 0 ? void 0 : _pane$selectedNode.text), !state.initLoading && state.panes.length && !(pane !== null && pane !== void 0 && (_pane$selectedNode2 = pane.selectedNode) !== null && _pane$selectedNode2 !== void 0 && _pane$selectedNode2.text) && '请选择', !(!state.initLoading && state.panes.length) && 'Loading...'] }) }, pane.paneKey); }) }), children: !state.initLoading && state.panes.length ? optiosData.map(function (pane, index) { return /*#__PURE__*/_jsx(Tab, { active: tabvalue === pane.paneKey, name: pane.paneKey, lazyRender: true, lazyTimeout: 200, onClick: function onClick() { if (!tabAnimate && index !== optiosData.length - 1) settabAnimate(true); }, children: /*#__PURE__*/_jsx(ScrollViewTimeout, { timeout: 400, optiosData: optiosData, tabvalue: tabvalue, value: value, scrollIntoView: scrollIntoView, children: pane.nodes && pane.nodes.map(function (node, index) { var _pane$selectedNode3; return /*#__PURE__*/_jsx(CascaderItem, _objectSpread(_objectSpread({}, props), {}, { data: node, checked: ((_pane$selectedNode3 = pane.selectedNode) === null || _pane$selectedNode3 === void 0 ? void 0 : _pane$selectedNode3.value) === node.value, chooseItem: function chooseItem(node) { return _chooseItem(node, false); }, id: "vant-cascader-item".concat(node.value) }), index); }) }) }, pane.paneKey); }) : /*#__PURE__*/_jsx(Tab, { active: true, name: "-999", lazyRender: true, children: /*#__PURE__*/_jsx(View, { className: "van-cascader-tab" }) }, "-999") })] }) }); }; export var Cascader = InternalCascader;