gui-one-nutui-react-taro
Version:
京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序
673 lines (672 loc) • 25.7 kB
JavaScript
import _typeof from "@babel/runtime/helpers/typeof";
import _asyncToGenerator from "@babel/runtime/helpers/asyncToGenerator";
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _classCallCheck from "@babel/runtime/helpers/classCallCheck";
import _createClass from "@babel/runtime/helpers/createClass";
import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
import _regeneratorRuntime from "@babel/runtime/regenerator";
function _toPropertyKey(arg) { var key = _toPrimitive(arg, "string"); return _typeof(key) === "symbol" ? key : String(key); }
function _toPrimitive(input, hint) { if (_typeof(input) !== "object" || input === null) return input; var prim = input[Symbol.toPrimitive]; if (prim !== undefined) { var res = prim.call(input, hint || "default"); if (_typeof(res) !== "object") return res; throw new TypeError("@@toPrimitive must return a primitive value."); } return (hint === "string" ? String : Number)(input); }
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; }
import React__default, { useEffect, useState } from 'react';
import classNames from 'classnames';
import { P as Popup } from './popup.taro-33d0bbc8.js';
import { T as Tabs } from './tabs.taro-e71875fa.js';
import { T as TabPane } from './tabpane.taro-91cd6cf4.js';
import { I as Icon } from './icon.taro-1d0d4fb7.js';
import { c as cn } from './bem-893ad28d.js';
var defaultProps$1 = {
data: {
text: '',
value: '',
paneKey: '',
disabled: false,
loading: false,
children: []
},
checked: false,
chooseItem: function chooseItem() {}
};
var InternalCascaderItem = function InternalCascaderItem(props) {
var _defaultProps$1$props = _objectSpread(_objectSpread({}, defaultProps$1), props),
data = _defaultProps$1$props.data,
checked = _defaultProps$1$props.checked,
chooseItem = _defaultProps$1$props.chooseItem;
var b = cn('cascader-item');
var classes = classNames({
active: checked,
disabled: data.disabled
}, b(''));
var classesTitle = classNames(_defineProperty({}, "".concat(b(''), "__title"), true));
useEffect(function () {
initData();
}, [data]);
var initData = function initData() {
// console.log('------data', data)
};
return React__default.createElement("div", {
className: classes,
onClick: function onClick() {
chooseItem(data);
}
}, React__default.createElement("div", {
className: classesTitle
}, data.text), data.loading ? React__default.createElement(Icon, {
color: "#969799",
className: "nut-cascader-item__icon-loading",
name: "loading"
}) : React__default.createElement(Icon, {
className: "".concat(checked ? b('icon-check') : ''),
name: "checklist"
}));
};
var CascaderItem = React__default.forwardRef(InternalCascaderItem);
CascaderItem.defaultProps = defaultProps$1;
CascaderItem.displayName = 'NutCascaderItem';
var formatTree = function formatTree(tree, parent, config) {
return tree.map(function (node) {
var _config$value = config.value,
valueKey = _config$value === void 0 ? 'value' : _config$value,
_config$text = config.text,
textKey = _config$text === void 0 ? 'text' : _config$text,
_config$children = config.children,
childrenKey = _config$children === void 0 ? 'children' : _config$children;
var value = node[valueKey],
text = node[textKey],
children = node[childrenKey],
others = _objectWithoutProperties(node, [valueKey, textKey, childrenKey].map(_toPropertyKey));
var newNode = _objectSpread(_objectSpread({
loading: false
}, others), {}, {
level: parent ? (parent && parent.level || 0) + 1 : 0,
value: value,
text: text,
children: children,
_parent: parent
});
if (newNode.children && newNode.children.length) {
newNode.children = formatTree(newNode.children, newNode, config);
}
return newNode;
});
};
var eachTree = function eachTree(tree, cb) {
var i = 0;
var node;
while (node = tree[i++]) {
if (cb(node) === true) {
break;
}
if (node.children && node.children.length) {
eachTree(node.children, cb);
}
}
};
var defaultConvertConfig = {
topId: null,
idKey: 'id',
pidKey: 'pid',
sortKey: ''
};
var convertListToOptions = function convertListToOptions(list, options) {
var mergedOptions = _objectSpread(_objectSpread({}, defaultConvertConfig), options || {});
var topId = mergedOptions.topId,
idKey = mergedOptions.idKey,
pidKey = mergedOptions.pidKey,
sortKey = mergedOptions.sortKey;
var result = [];
var map = {};
list.forEach(function (node) {
node = _objectSpread({}, node);
var _node = node,
id = _node[idKey],
pid = _node[pidKey];
var children = map[pid] = map[pid] || [];
// const children = map[pid] || []
if (!result.length && pid === topId) {
result = children;
}
children.push(node);
node.children = map[id] || (map[id] = []);
});
if (sortKey) {
Object.keys(map).forEach(function (i) {
if (map[i].length > 1) {
map[i].sort(function (a, b) {
return a[sortKey] - b[sortKey];
});
}
});
}
map = null;
return result;
};
var Tree = /*#__PURE__*/function () {
function Tree(nodes, config) {
var _this = this;
_classCallCheck(this, Tree);
_defineProperty(this, "nodes", void 0);
_defineProperty(this, "config", void 0);
_defineProperty(this, "isLeaf", function (node, lazy) {
var leaf = node.leaf,
children = node.children;
var hasChildren = Array.isArray(children) && Boolean(children.length);
return leaf || !hasChildren && !lazy;
});
_defineProperty(this, "hasChildren", function (node, lazy) {
var isLeaf = _this.isLeaf(node, lazy);
if (isLeaf) {
return false;
}
var children = node.children;
return Array.isArray(children) && Boolean(children.length);
});
this.config = _objectSpread({
value: 'value',
text: 'text',
children: 'children'
}, config || {});
this.nodes = formatTree(nodes, null, this.config);
}
_createClass(Tree, [{
key: "updateChildren",
value: function updateChildren(nodes, parent) {
if (!parent) {
this.nodes = formatTree(nodes, null, this.config);
} else {
parent.children = formatTree(nodes, parent, this.config);
}
}
// for test
}, {
key: "getNodeByValue",
value: function getNodeByValue(value) {
var foundNode;
eachTree(this.nodes, function (node) {
if (node.value === value) {
foundNode = node;
return true;
}
return null;
});
return foundNode;
}
}, {
key: "getPathNodesByValue",
value: function getPathNodesByValue(value) {
if (!value.length) {
return [];
}
var pathNodes = [];
var currentNodes = this.nodes;
while (currentNodes && currentNodes.length) {
var foundNode = currentNodes.find(function (node) {
return node.value === value[node.level];
});
if (!foundNode) {
break;
}
pathNodes.push(foundNode);
currentNodes = foundNode.children;
}
return pathNodes;
}
}]);
return Tree;
}();
var defaultProps = _objectSpread({
className: '',
style: {},
poppable: true,
visible: false,
options: [],
value: [],
title: '',
textKey: 'text',
valueKey: 'value',
childrenKey: 'children',
convertConfig: {},
closeable: false,
closeIconPosition: 'top-right',
closeIcon: 'close',
lazy: false,
lazyLoad: function lazyLoad() {},
onClose: function onClose() {},
onChange: function onChange() {},
onPathChange: function onPathChange() {}
}, Popup.defaultProps);
var InternalCascader = function InternalCascader(props) {
var _defaultProps$props = _objectSpread(_objectSpread({}, defaultProps), props),
className = _defaultProps$props.className,
style = _defaultProps$props.style,
poppable = _defaultProps$props.poppable,
visible = _defaultProps$props.visible,
options = _defaultProps$props.options,
value = _defaultProps$props.value,
title = _defaultProps$props.title,
textKey = _defaultProps$props.textKey,
valueKey = _defaultProps$props.valueKey,
childrenKey = _defaultProps$props.childrenKey,
convertConfig = _defaultProps$props.convertConfig,
closeable = _defaultProps$props.closeable,
closeIconPosition = _defaultProps$props.closeIconPosition,
closeIcon = _defaultProps$props.closeIcon,
lazy = _defaultProps$props.lazy,
lazyLoad = _defaultProps$props.lazyLoad,
onClose = _defaultProps$props.onClose,
onChange = _defaultProps$props.onChange,
onPathChange = _defaultProps$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 isLazy = function isLazy() {
return state.configs.lazy && Boolean(state.configs.lazyLoad);
};
var _useState5 = useState({
optionsData: [],
panes: [{
nodes: [],
selectedNode: [],
paneKey: ''
}],
innerValue: value,
tree: new Tree([], {}),
tabsCursor: 0,
initLoading: false,
currentProcessNode: [],
configs: {
lazy: lazy,
lazyLoad: lazyLoad,
valueKey: valueKey,
textKey: textKey,
childrenKey: childrenKey,
convertConfig: convertConfig
},
lazyLoadMap: new Map()
}),
_useState6 = _slicedToArray(_useState5, 1),
state = _useState6[0];
var b = cn('cascader');
var classes = classNames(b(''));
var classesPane = classNames(_defineProperty({}, "".concat(b(''), "-pane"), true));
useEffect(function () {
initData();
}, []);
useEffect(function () {
if (value !== state.innerValue) {
state.innerValue = value;
}
}, [value]);
useEffect(function () {
initData();
}, [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 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 || !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() {
onClose && onClose();
};
var closePopup = function closePopup() {
close();
};
/* type: 是否是静默模式,是的话不触发事件
tabsCursor: tab的索引 */
var _chooseItem = /*#__PURE__*/function () {
var _ref5 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee5(node, type) {
var pathNodes, optionParams, level, _pathNodes, _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 (!state.tree.isLeaf(node, isLazy())) {
_context5.next = 10;
break;
}
node.leaf = true;
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(optionParams, pathNodes);
onPathChange(optionParams, pathNodes);
}
setOptiosData(state.panes);
close();
return _context5.abrupt("return");
case 10:
if (!state.tree.hasChildren(node, isLazy())) {
_context5.next = 20;
break;
}
level = node.level + 1;
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)
});
setTabvalue("c".concat(state.tabsCursor + 1));
setOptiosData(state.panes);
if (!type) {
_pathNodes = state.panes.map(function (item) {
return item.selectedNode;
});
_optionParams = _pathNodes.map(function (item) {
return item === null || item === void 0 ? void 0 : item.value;
});
onPathChange(_optionParams, _pathNodes);
}
return _context5.abrupt("return");
case 20:
state.currentProcessNode = node;
if (!node.loading) {
_context5.next = 23;
break;
}
return _context5.abrupt("return");
case 23:
_context5.next = 25;
return invokeLazyLoad(node);
case 25:
if (state.currentProcessNode === node) {
state.panes[state.tabsCursor].selectedNode = node;
_chooseItem(node, type);
}
setOptiosData(state.panes);
case 27:
case "end":
return _context5.stop();
}
}
}, _callee5);
}));
return function chooseItem(_x4, _x5) {
return _ref5.apply(this, arguments);
};
}();
var renderItem = function renderItem() {
return React__default.createElement("div", {
className: "".concat(classes, " ").concat(className),
style: style
}, poppable && React__default.createElement("div", {
className: b('title')
}, title), React__default.createElement(Tabs, {
value: tabvalue,
titleNode: function titleNode() {
return optiosData.map(function (pane, index) {
var _pane$selectedNode, _pane$selectedNode2;
return React__default.createElement("div", {
onClick: function onClick() {
setTabvalue(pane.paneKey);
state.tabsCursor = index;
},
className: "nut-tabs__titles-item ".concat(tabvalue === pane.paneKey ? 'active' : ''),
key: pane.paneKey
}, React__default.createElement("span", {
className: "nut-tabs__titles-item__text"
}, !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...'), React__default.createElement("span", {
className: "nut-tabs__titles-item__line"
}));
});
}
}, !state.initLoading && state.panes.length ? optiosData.map(function (pane) {
return React__default.createElement(TabPane, {
key: pane.paneKey,
paneKey: pane.paneKey
}, React__default.createElement("div", {
className: classesPane
}, pane.nodes && pane.nodes.map(function (node, index) {
var _pane$selectedNode3;
return React__default.createElement(CascaderItem, _objectSpread(_objectSpread({
key: index
}, 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);
}
}));
})));
}) : React__default.createElement(TabPane, null, React__default.createElement("div", {
className: classesPane
}))));
};
return React__default.createElement(React__default.Fragment, null, poppable ? React__default.createElement(Popup, {
popClass: "cascadar-popup",
visible: visible,
position: "bottom",
round: true,
closeable: closeable,
closeIconPosition: closeIconPosition,
closeIcon: closeIcon,
onClickOverlay: closePopup,
onClickCloseIcon: closePopup
}, renderItem()) : renderItem());
};
var Cascader = React__default.forwardRef(InternalCascader);
Cascader.defaultProps = defaultProps;
Cascader.displayName = 'NutCascader';
export { Cascader as C };