UNPKG

@nutui/nutui-react

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

409 lines (408 loc) 18.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); Object.defineProperty(exports, "Cascader", { enumerable: true, get: function() { return Cascader; } }); var _interop_require_default = require("@swc/helpers/_/_interop_require_default"); var _interop_require_wildcard = require("@swc/helpers/_/_interop_require_wildcard"); var _async_to_generator = require("@swc/helpers/_/_async_to_generator"); var _define_property = require("@swc/helpers/_/_define_property"); var _object_spread = require("@swc/helpers/_/_object_spread"); var _object_spread_props = require("@swc/helpers/_/_object_spread_props"); var _sliced_to_array = require("@swc/helpers/_/_sliced_to_array"); var _ts_generator = require("@swc/helpers/_/_ts_generator"); var _react = /*#__PURE__*/ _interop_require_wildcard._(require("react")); var _iconsreact = require("@nutui/icons-react"); var _classnames = /*#__PURE__*/ _interop_require_default._(require("classnames")); var _tabs = /*#__PURE__*/ _interop_require_default._(require("../tabs")); var _popup = /*#__PURE__*/ _interop_require_default._(require("../popup")); var _utils = require("./utils"); var _typings = require("../../utils/typings"); var _mergeprops = require("../../utils/merge-props"); var _usepropsvalue = require("../../hooks/use-props-value"); var _isempty = require("../../utils/is-empty"); var _userefstate = require("../../hooks/use-ref-state"); var _configprovider = require("../configprovider"); var defaultProps = (0, _object_spread_props._)((0, _object_spread._)({}, _typings.ComponentDefaults), { activeColor: '', activeIcon: 'checklist', popup: true, options: [], optionKey: {}, format: {}, closeable: false, closeIconPosition: 'top-right', closeIcon: 'close', lazy: false, onClose: function onClose() {}, onChange: function onChange() {}, onPathChange: function onPathChange() {} }); var Cascader = /*#__PURE__*/ (0, _react.forwardRef)(function(props, ref) { var classPrefix = 'nut-cascader'; var classPane = "".concat(classPrefix, "-pane"); var _mergeProps = (0, _mergeprops.mergeProps)(defaultProps, props), activeColor = _mergeProps.activeColor, activeIcon = _mergeProps.activeIcon, popup = _mergeProps.popup, _mergeProps_popupProps = _mergeProps.popupProps, popupProps = _mergeProps_popupProps === void 0 ? {} : _mergeProps_popupProps, outerVisible = _mergeProps.visible, outerOptions = _mergeProps.options, outerValue = _mergeProps.value, outerDefaultValue = _mergeProps.defaultValue, optionKey = _mergeProps.optionKey, format = _mergeProps.format, closeable = _mergeProps.closeable, closeIconPosition = _mergeProps.closeIconPosition, closeIcon = _mergeProps.closeIcon, lazy = _mergeProps.lazy, onLoad = _mergeProps.onLoad; var locale = (0, _configprovider.useConfig)().locale; var _useState = (0, _sliced_to_array._)((0, _react.useState)(0), 2), tabActiveIndex = _useState[0], setTabActiveIndex = _useState[1]; var _useRefState = (0, _sliced_to_array._)((0, _userefstate.useRefState)(outerOptions), 2), optionsRef = _useRefState[0], setInnerOptions = _useRefState[1]; var innerOptions = (0, _userefstate.getRefValue)(optionsRef); var _useState1 = (0, _sliced_to_array._)((0, _react.useState)({}), 2), loading = _useState1[0], setLoading = _useState1[1]; var _usePropsValue = (0, _sliced_to_array._)((0, _usepropsvalue.usePropsValue)({ value: outerValue, defaultValue: outerDefaultValue, finalValue: [], onChange: function onChange(value) { var _props_onChange, _props_onPathChange; (_props_onChange = props.onChange) === null || _props_onChange === void 0 ? void 0 : _props_onChange.call(props, value, pathNodes.current); (_props_onPathChange = props.onPathChange) === null || _props_onPathChange === void 0 ? void 0 : _props_onPathChange.call(props, value, pathNodes.current); } }), 2), value = _usePropsValue[0], setValue = _usePropsValue[1]; var _useState2 = (0, _sliced_to_array._)((0, _react.useState)(value), 2), innerValue = _useState2[0], setInnerValue = _useState2[1]; var options = (0, _react.useMemo)(function() { if (!(0, _isempty.isEmpty)(format)) { return (0, _utils.normalizeListOptions)(innerOptions, format); } if (!(0, _isempty.isEmpty)(optionKey)) { return (0, _utils.normalizeOptions)(innerOptions, optionKey); } return innerOptions; }, [ innerOptions, optionKey, format, innerValue ]); var pathNodes = (0, _react.useRef)([]); var levels = (0, _react.useMemo)(function() { var next = []; var end = false; var currentOptions = options; var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined; try { var _loop = function _loop() { var _step_value = (0, _sliced_to_array._)(_step.value, 2), index = _step_value[0], val = _step_value[1]; var opt = currentOptions === null || currentOptions === void 0 ? void 0 : currentOptions.find(function(o) { return o.value === val; }); next.push({ selected: val, pane: currentOptions }); pathNodes.current[index] = opt; if (opt === null || opt === void 0 ? void 0 : opt.children) { currentOptions = opt.children; } else { end = true; return "break"; } }; for(var _iterator = innerValue.entries()[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){ var _ret = _loop(); if (_ret === "break") break; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally{ try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally{ if (_didIteratorError) { throw _iteratorError; } } } if (!end) { next.push({ selected: null, pane: currentOptions }); } return next; }, [ innerValue, options, innerOptions ]); var _usePropsValue1 = (0, _sliced_to_array._)((0, _usepropsvalue.usePropsValue)({ value: outerVisible, defaultValue: undefined, onChange: function onChange(value) { if (value === false) { var _props_onClose; (_props_onClose = props.onClose) === null || _props_onClose === void 0 ? void 0 : _props_onClose.call(props); } } }), 2), visible = _usePropsValue1[0], setVisible = _usePropsValue1[1]; var actions = { open: function open() { setVisible(true); }, close: function close() { setVisible(false); } }; (0, _react.useImperativeHandle)(ref, function() { return actions; }); (0, _react.useEffect)(function() { if (!visible) { setInnerValue(value); } }, [ visible, value ]); (0, _react.useEffect)(function() { setInnerOptions(outerOptions); }, [ outerOptions ]); (0, _react.useEffect)(function() { setTabActiveIndex(levels.length - 1); }, [ innerValue, innerOptions, outerOptions ]); (0, _react.useEffect)(function() { var max = levels.length - 1; if (tabActiveIndex > max) { setTabActiveIndex(max); } }, [ tabActiveIndex, levels, innerOptions, outerOptions ]); (0, _react.useEffect)(function() { var load = /*#__PURE__*/ function() { var _ref = (0, _async_to_generator._)(function() { var parent, error; return (0, _ts_generator._)(this, function(_state) { switch(_state.label){ case 0: parent = { children: [] }; _state.label = 1; case 1: _state.trys.push([ 1, 3, , 4 ]); return [ 4, innerValue.reduce(/*#__PURE__*/ function() { var _ref = (0, _async_to_generator._)(function(promise, val, key) { var pane, parent, node; return (0, _ts_generator._)(this, function(_state) { switch(_state.label){ case 0: return [ 4, onLoad({ value: val }, key) ]; case 1: pane = _state.sent(); return [ 4, promise ]; case 2: parent = _state.sent(); parent.children = pane; if (key === innerValue.length - 1) { return [ 2, Promise.resolve(parent) ]; } if (pane) { node = pane.find(function(p) { return p.value === val; }); return [ 2, Promise.resolve(node) ]; } return [ 2 ]; } }); }); return function(promise, val, key) { return _ref.apply(this, arguments); }; }(), Promise.resolve(parent)) ]; case 2: _state.sent(); // 如果需要处理最终结果,可以在这里使用 last setInnerOptions(parent.children); return [ 3, 4 ]; case 3: error = _state.sent(); console.error('Error loading data:', error); return [ 3, 4 ]; case 4: return [ 2 ]; } }); }); return function load() { return _ref.apply(this, arguments); }; }(); if (lazy) load(); }, [ lazy ]); var chooseItem = /*#__PURE__*/ function() { var _ref = (0, _async_to_generator._)(function(pane, levelIndex) { var nextValue, nextPathNodes, _props_onPathChange, asyncOptions; return (0, _ts_generator._)(this, function(_state) { switch(_state.label){ case 0: if (pane.disabled) return [ 2 ]; nextValue = innerValue.slice(0, levelIndex); nextPathNodes = pathNodes.current.slice(0, levelIndex); if (pane.value) { ; setLoading(!!onLoad && (0, _define_property._)({}, levelIndex, pane.value)); nextValue[levelIndex] = pane.value; nextPathNodes[levelIndex] = pane; pathNodes.current = nextPathNodes; props === null || props === void 0 ? void 0 : (_props_onPathChange = props.onPathChange) === null || _props_onPathChange === void 0 ? void 0 : _props_onPathChange.call(props, nextValue, pathNodes.current); } if (!onLoad) return [ 3, 3 ]; if (!!pane.leaf) return [ 3, 2 ]; return [ 4, onLoad(pane, levelIndex) ]; case 1: asyncOptions = _state.sent(); // 修改 options 触发渲染逻辑 if (asyncOptions) pane.children = asyncOptions; return [ 3, 3 ]; case 2: setVisible(false); setValue(nextValue); _state.label = 3; case 3: if (!pane.children && !onLoad) { setVisible(false); setValue(nextValue); } setInnerValue(nextValue); setLoading({}); return [ 2 ]; } }); }); return function chooseItem(pane, levelIndex) { return _ref.apply(this, arguments); }; }(); var renderCascaderItem = function renderCascaderItem(item, levelIndex) { var _item_pane; return (_item_pane = item.pane) === null || _item_pane === void 0 ? void 0 : _item_pane.map(function(pane, index) { var active = item.selected === pane.value; var classes = (0, _classnames.default)({ active: active, disabled: pane.disabled }, 'nut-cascader-item'); var showLoadingIcon = loading[levelIndex] === pane.value; return /*#__PURE__*/ _react.default.createElement("div", { className: classes, style: { color: active ? activeColor : '' }, key: pane.value, onClick: function onClick() { chooseItem(pane, levelIndex); } }, /*#__PURE__*/ _react.default.createElement("div", { className: "nut-cascader-item-title" }, pane.text), showLoadingIcon && /*#__PURE__*/ _react.default.createElement(_iconsreact.Loading, { color: "#969799", className: "nut-cascader-item-icon-loading" }), active && /*#__PURE__*/ /*#__PURE__*/ ((0, _react.isValidElement)(activeIcon) ? activeIcon : /*#__PURE__*/ _react.default.createElement(_iconsreact.Check, { className: "".concat(classPrefix, "-icon-check") }))); }); }; var renderTab = function renderTab() { return /*#__PURE__*/ _react.default.createElement("div", { className: (0, _classnames.default)(classPrefix, props.className), style: props.style }, /*#__PURE__*/ _react.default.createElement(_tabs.default, { value: tabActiveIndex, onChange: function onChange(index) { var _props_onTabsChange; (_props_onTabsChange = props.onTabsChange) === null || _props_onTabsChange === void 0 ? void 0 : _props_onTabsChange.call(props, Number(index)); setTabActiveIndex(Number(index)); } }, levels.map(function(pane, index) { return /*#__PURE__*/ _react.default.createElement(_tabs.default.TabPane, { title: pane.selected || locale.select, key: index }, /*#__PURE__*/ _react.default.createElement("div", { className: classPane }, renderCascaderItem(pane, index))); }))); }; return popup ? /*#__PURE__*/ _react.default.createElement(_popup.default, (0, _object_spread_props._)((0, _object_spread._)({}, popupProps), { visible: visible, position: "bottom", round: true, closeIcon: closeIcon, closeable: closeable, closeIconPosition: closeIconPosition, title: props.title, left: props.left, onOverlayClick: function onOverlayClick() { return setVisible(false); }, onCloseIconClick: function onCloseIconClick() { return setVisible(false); } }), renderTab()) : renderTab(); }); Cascader.displayName = 'NutCascader';