fastlion-amis
Version:
一种MIS页面生成工具
488 lines (487 loc) • 24.7 kB
JavaScript
"use strict";
/**
* @file Cascader
* @author fex
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.Cascader = void 0;
var tslib_1 = require("tslib");
var react_1 = (0, tslib_1.__importDefault)(require("react"));
var helper_1 = require("../utils/helper");
var theme_1 = require("../theme");
var Select_1 = require("./Select");
var intersectionBy_1 = (0, tslib_1.__importDefault)(require("lodash/intersectionBy"));
var compact_1 = (0, tslib_1.__importDefault)(require("lodash/compact"));
var find_1 = (0, tslib_1.__importDefault)(require("lodash/find"));
var uniqBy_1 = (0, tslib_1.__importDefault)(require("lodash/uniqBy"));
var Button_1 = (0, tslib_1.__importDefault)(require("./Button"));
var helper_2 = require("../utils/helper");
var Cascader = /** @class */ (function (_super) {
(0, tslib_1.__extends)(Cascader, _super);
function Cascader(props) {
var _this = _super.call(this, props) || this;
_this.tabsRef = react_1.default.createRef();
_this.tabRef = react_1.default.createRef();
_this.getParentTree = function (option, arr) {
var parentOption = _this.getOptionParent(option);
if (parentOption) {
arr.push(parentOption);
return _this.getParentTree(parentOption, arr);
}
return arr;
};
_this.state = {
selectedOptions: _this.props.selectedOptions || [],
activeTab: 0,
tabs: [
{
options: _this.props.options.slice() || []
}
]
};
return _this;
}
Cascader.prototype.componentDidMount = function () {
var _a = this.props, multiple = _a.multiple, options = _a.options, _b = _a.valueField, valueField = _b === void 0 ? 'value' : _b, cascade = _a.cascade;
var selectedOptions = this.props.selectedOptions.slice();
var parentsCount = 0;
var parentTree = [];
selectedOptions.forEach(function (item) {
var parents = (0, helper_1.getTreeAncestors)(options, item);
// 获取最长路径
if (parents && (parents === null || parents === void 0 ? void 0 : parents.length) > parentsCount) {
parentTree = parents;
parentsCount = parentTree.length;
}
});
var selectedValues = selectedOptions.map(function (option) { return option[valueField]; });
var tabs = parentTree.map(function (option) {
var _a;
if (multiple && !cascade) {
if (selectedValues.includes(option[valueField]) &&
((_a = option === null || option === void 0 ? void 0 : option.children) === null || _a === void 0 ? void 0 : _a.length)) {
option.children.forEach(function (option) { return (option.disabled = true); });
}
}
return multiple
? {
options: (0, tslib_1.__spreadArray)([
(0, tslib_1.__assign)((0, tslib_1.__assign)({}, option), { isCheckAll: true })
], (option.children ? option.children : []), true)
}
: {
options: option.children ? option.children : []
};
});
this.setState({
selectedOptions: selectedOptions,
tabs: (0, tslib_1.__spreadArray)((0, tslib_1.__spreadArray)([], this.state.tabs, true), tabs, true)
});
};
Cascader.prototype.handleTabSelect = function (index) {
var tabs = this.state.tabs.slice(0, index + 1);
this.setState({
activeTab: index,
tabs: tabs
});
};
Cascader.prototype.getOptionParent = function (option) {
var _a = this.props, options = _a.options, _b = _a.valueField, valueField = _b === void 0 ? 'value' : _b;
var ancestors = [];
(0, helper_2.findTree)(options, function (item, index, level, paths) {
if (item[valueField] === option[valueField]) {
ancestors = paths;
return true;
}
return false;
});
return ancestors.length ? ancestors[ancestors.length - 1] : null;
};
Cascader.prototype.dealParentSelect = function (option, selectedOptions) {
var _a;
var _b = this.props.valueField, valueField = _b === void 0 ? 'value' : _b;
var parentOption = this.getOptionParent(option);
if (parentOption) {
var parentChildren = parentOption === null || parentOption === void 0 ? void 0 : parentOption.children;
var equalOption = (0, intersectionBy_1.default)(selectedOptions, parentChildren, valueField);
// 包含则选中父节点
var isParentSelected = (0, find_1.default)(selectedOptions, (_a = {},
_a[valueField] = parentOption[valueField],
_a));
if (equalOption.length === (parentChildren === null || parentChildren === void 0 ? void 0 : parentChildren.length) && !isParentSelected) {
selectedOptions.push(parentOption);
}
if (equalOption.length !== (parentChildren === null || parentChildren === void 0 ? void 0 : parentChildren.length) && isParentSelected) {
var index = selectedOptions.findIndex(function (item) { return item[valueField] === parentOption[valueField]; });
selectedOptions.splice(index, 1);
}
return this.dealParentSelect(parentOption, selectedOptions);
}
else {
return selectedOptions;
}
};
Cascader.prototype.flattenTreeWithLeafNodes = function (option) {
return (0, compact_1.default)((0, helper_2.flattenTree)(Array.isArray(option) ? option : [option], function (node) { return node; }));
};
Cascader.prototype.adjustOptionSelect = function (option) {
var _a = this.props.valueField, valueField = _a === void 0 ? 'value' : _a;
var selectedOptions = this.state.selectedOptions;
function loop(arr) {
if (!arr.length) {
return false;
}
return arr.some(function (item) { return item[valueField] === option[valueField]; });
}
return loop(selectedOptions);
};
Cascader.prototype.getSelectedChildNum = function (option) {
var _this = this;
var count = 0;
var loop = function (arr) {
if (!arr || !arr.length) {
return;
}
for (var _i = 0, arr_1 = arr; _i < arr_1.length; _i++) {
var item = arr_1[_i];
if (item.children) {
loop(item.children || []);
}
else {
if (_this.adjustOptionSelect(item)) {
count++;
}
}
}
};
loop(option.children || []);
return count;
};
Cascader.prototype.dealOptionDisable = function (selectedOptions) {
var _a = this.props, _b = _a.valueField, valueField = _b === void 0 ? 'value' : _b, options = _a.options, cascade = _a.cascade, multiple = _a.multiple, onlyChildren = _a.onlyChildren // 子节点可点击
;
if (!multiple || cascade || onlyChildren) {
return;
}
var selectedValues = selectedOptions.map(function (option) { return option[valueField]; });
var loop = function (option) {
if (!option.children) {
return;
}
option.children &&
option.children.forEach(function (childOption) {
if (!selectedValues.includes(option[valueField]) &&
!option.disabled) {
childOption.disabled = false;
}
if (selectedValues.includes(option[valueField]) || option.disabled) {
childOption.disabled = true;
}
loop(childOption);
});
};
options.forEach(function (option) { return loop(option); });
};
Cascader.prototype.dealChildrenSelect = function (option, selectedOptions) {
var _a = this.props.valueField, valueField = _a === void 0 ? 'value' : _a;
var index = selectedOptions.findIndex(function (item) { return item[valueField] === option[valueField]; });
if (index !== -1) {
selectedOptions.splice(index, 1);
}
else {
selectedOptions.push(option);
}
function loop(option) {
if (!option.children) {
return;
}
option.children.forEach(function (item) {
if (index !== -1) {
// 删除选中节点及其子节点
selectedOptions = selectedOptions.filter(function (sItem) { return sItem[valueField] !== item[valueField]; });
}
else {
// 添加节点及其子节点
selectedOptions.push(item);
}
loop(item);
});
}
loop(option);
return selectedOptions;
};
Cascader.prototype.onSelect = function (option, tabIndex) {
var _this = this;
var _a = this.props, multiple = _a.multiple, _b = _a.valueField, valueField = _b === void 0 ? 'value' : _b, cascade = _a.cascade;
var tabs = this.state.tabs.slice();
var activeTab = this.state.activeTab;
var selectedOptions = this.state.selectedOptions;
var isDisable = option.disabled;
if (!isDisable) {
if (multiple) {
// 父子级分离
if (cascade) {
if (option.isCheckAll ||
!option.children ||
!option.children.length) {
var index = selectedOptions.findIndex(function (item) { return item[valueField] === option[valueField]; });
if (index !== -1) {
selectedOptions.splice(index, 1);
}
else {
selectedOptions.push(option);
}
}
}
else {
if (option.isCheckAll ||
!option.children ||
!option.children.length) {
selectedOptions = this.dealChildrenSelect(option, selectedOptions);
selectedOptions = this.dealParentSelect(option, selectedOptions);
}
}
}
else {
// 单选
selectedOptions = this.getParentTree(option, [option]);
}
}
this.dealOptionDisable(selectedOptions);
if (tabs.length > tabIndex + 1) {
tabs = tabs.slice(0, tabIndex + 1);
}
requestAnimationFrame(function () {
var _a;
var tabWidth = ((_a = _this.tabRef.current) === null || _a === void 0 ? void 0 : _a.offsetWidth) || 1;
var parentTree = _this.getParentTree(option, [option]);
var scrollLeft = (parentTree.length - 2) * tabWidth;
if (scrollLeft !== 0) {
_this.tabsRef.current.scrollTo(scrollLeft, 0);
}
});
if ((option === null || option === void 0 ? void 0 : option.children) && !option.isCheckAll) {
var nextTab = multiple
? {
options: (0, tslib_1.__spreadArray)([
(0, tslib_1.__assign)((0, tslib_1.__assign)({}, option), { isCheckAll: true })
], option.children, true)
}
: {
options: option.children
};
if (tabs[tabIndex + 1]) {
tabs[tabIndex + 1] = nextTab;
}
else {
tabs.push(nextTab);
}
activeTab += 1;
}
this.setState({
tabs: tabs,
activeTab: activeTab,
selectedOptions: selectedOptions
});
};
Cascader.prototype.onNextClick = function (option, tabIndex) {
var activeTab = this.state.activeTab;
var tabs = this.state.tabs.slice();
if (option.c)
if (option === null || option === void 0 ? void 0 : option.children) {
var nextTab = {
options: option.children
};
if (tabs[tabIndex + 1]) {
tabs[tabIndex + 1] = nextTab;
}
else {
tabs.push(nextTab);
}
activeTab += 1;
}
this.setState({
tabs: tabs,
activeTab: activeTab
});
};
Cascader.prototype.getSubmitOptions = function (selectedOptions) {
var _selectedOptions = [];
var _a = this.props, multiple = _a.multiple, options = _a.options, _b = _a.valueField, valueField = _b === void 0 ? 'value' : _b, cascade = _a.cascade, onlyChildren = _a.onlyChildren, withChildren = _a.withChildren;
if (cascade || onlyChildren || withChildren || !multiple) {
return selectedOptions;
}
var selectedValues = selectedOptions.map(function (option) { return option[valueField]; });
function loop(options) {
if (!options || !options.length) {
return;
}
options.forEach(function (option) {
if (selectedValues.includes(option[valueField])) {
_selectedOptions.push(option);
}
else {
loop(option.children ? option.children : []);
}
});
}
loop(options);
return _selectedOptions;
};
Cascader.prototype.confirm = function () {
var _a = this.props, onChange = _a.onChange, joinValues = _a.joinValues, delimiter = _a.delimiter, extractValue = _a.extractValue, valueField = _a.valueField, onClose = _a.onClose;
var selectedOptions = this.state.selectedOptions;
var _selectedOptions = this.getSubmitOptions(selectedOptions);
_selectedOptions = (0, uniqBy_1.default)(_selectedOptions, valueField);
onChange(joinValues
? _selectedOptions
.map(function (item) { return item[valueField]; })
.join(delimiter)
: extractValue
? _selectedOptions.map(function (item) { return item[valueField]; })
: _selectedOptions);
onClose && onClose();
};
Cascader.prototype.renderOption = function (option, tabIndex) {
var _this = this;
var _a = this.props, activeColor = _a.activeColor, optionRender = _a.optionRender, labelField = _a.labelField, _b = _a.valueField, valueField = _b === void 0 ? 'value' : _b, cx = _a.classnames, cascade = _a.cascade, multiple = _a.multiple;
var selectedOptions = this.state.selectedOptions;
var selectedValueArr = selectedOptions.map(function (item) { return item[valueField]; });
var selfChecked = selectedValueArr.includes(option[valueField]);
var color = option.color || (selfChecked ? activeColor : undefined);
var Text = optionRender ? (optionRender({ option: option, selected: selfChecked })) : (react_1.default.createElement("span", null, option[labelField]));
return (react_1.default.createElement("li", { className: cx('Cascader-option', {
selected: selfChecked,
disabled: option.disabled
}, option.className), style: { color: color }, onClick: function () { return _this.onSelect(option, tabIndex); }, key: tabIndex + '-' + option[valueField] },
react_1.default.createElement("span", { className: cx('Cascader-option--text') }, Text)));
};
Cascader.prototype.renderOptions = function (options, tabIndex) {
var _this = this;
var cx = this.props.classnames;
return (react_1.default.createElement("ul", { key: tabIndex, className: cx('Cascader-options') }, options.map(function (option) { return _this.renderOption(option, tabIndex); })));
};
Cascader.prototype.renderTabs = function () {
var _this = this;
var _a = this.props, cx = _a.classnames, options = _a.options;
var tabs = this.state.tabs;
var depth = (0, helper_2.getTreeDepth)(options);
return (react_1.default.createElement("div", { className: cx("Cascader-tabs", depth > 3 ? 'scrollable' : ''), ref: this.tabsRef },
tabs.map(function (tab, tabIndex) {
var options = tab.options;
return (react_1.default.createElement("div", { className: cx("Cascader-tab"), ref: _this.tabRef, key: tabIndex }, _this.renderOptions(options, tabIndex)));
}),
depth <= 3 && options.length
? Array((0, helper_2.getTreeDepth)(options) - tabs.length)
.fill(1)
.map(function (item, index) { return (react_1.default.createElement("div", { className: cx("Cascader-tab"), key: index })); })
: null));
};
Cascader.prototype.render = function () {
var _a = this.props, ns = _a.classPrefix, cx = _a.classnames, className = _a.className, onClose = _a.onClose, __ = _a.translate;
return (react_1.default.createElement("div", { className: cx("Cascader", className) },
react_1.default.createElement("div", { className: cx("Cascader-btnGroup") },
react_1.default.createElement(Button_1.default, { className: cx("Cascader-btnCancel"), level: "text", onClick: onClose }, __('cancel')),
react_1.default.createElement(Button_1.default, { className: cx("Cascader-btnConfirm"), level: "text", onClick: this.confirm }, __('confirm'))),
this.renderTabs()));
};
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
Cascader.defaultProps = {
labelField: 'label',
valueField: 'value'
};
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [Number]),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "handleTabSelect", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [typeof (_a = typeof Select_1.Option !== "undefined" && Select_1.Option) === "function" ? _a : Object]),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "getOptionParent", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [typeof (_b = typeof Select_1.Option !== "undefined" && Select_1.Option) === "function" ? _b : Object, typeof (_c = typeof Select_1.Options !== "undefined" && Select_1.Options) === "function" ? _c : Object]),
(0, tslib_1.__metadata)("design:returntype", typeof (_d = typeof Select_1.Options !== "undefined" && Select_1.Options) === "function" ? _d : Object)
], Cascader.prototype, "dealParentSelect", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [typeof (_e = typeof Select_1.Option !== "undefined" && Select_1.Option) === "function" ? _e : Object]),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "flattenTreeWithLeafNodes", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [typeof (_f = typeof Select_1.Option !== "undefined" && Select_1.Option) === "function" ? _f : Object]),
(0, tslib_1.__metadata)("design:returntype", Boolean)
], Cascader.prototype, "adjustOptionSelect", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [typeof (_g = typeof Select_1.Option !== "undefined" && Select_1.Option) === "function" ? _g : Object]),
(0, tslib_1.__metadata)("design:returntype", Number)
], Cascader.prototype, "getSelectedChildNum", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [typeof (_h = typeof Select_1.Options !== "undefined" && Select_1.Options) === "function" ? _h : Object]),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "dealOptionDisable", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [typeof (_j = typeof Select_1.Option !== "undefined" && Select_1.Option) === "function" ? _j : Object, typeof (_k = typeof Select_1.Options !== "undefined" && Select_1.Options) === "function" ? _k : Object]),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "dealChildrenSelect", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [Object, Number]),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "onSelect", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [Object, Number]),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "onNextClick", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [typeof (_l = typeof Select_1.Options !== "undefined" && Select_1.Options) === "function" ? _l : Object]),
(0, tslib_1.__metadata)("design:returntype", typeof (_m = typeof Select_1.Options !== "undefined" && Select_1.Options) === "function" ? _m : Object)
], Cascader.prototype, "getSubmitOptions", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", []),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "confirm", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [Object, Number]),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "renderOption", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", [typeof (_o = typeof Select_1.Options !== "undefined" && Select_1.Options) === "function" ? _o : Object, Number]),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "renderOptions", null);
(0, tslib_1.__decorate)([
helper_1.autobind,
(0, tslib_1.__metadata)("design:type", Function),
(0, tslib_1.__metadata)("design:paramtypes", []),
(0, tslib_1.__metadata)("design:returntype", void 0)
], Cascader.prototype, "renderTabs", null);
return Cascader;
}(react_1.default.Component));
exports.Cascader = Cascader;
exports.default = (0, theme_1.themeable)(Cascader);
//# sourceMappingURL=./components/Cascader.js.map