acud
Version:
acg react 组件库
497 lines (496 loc) • 23.6 kB
JavaScript
;
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _typeof3 = require("@babel/runtime/helpers/typeof");
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var _toConsumableArray2 = _interopRequireDefault(require("@babel/runtime/helpers/toConsumableArray"));
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var React = _interopRequireWildcard(require("react"));
var _rcSelect = require("rc-select");
var _conductUtil = require("rc-tree/lib/utils/conductUtil");
var _useId = _interopRequireDefault(require("rc-select/lib/hooks/useId"));
var _useMergedState5 = _interopRequireDefault(require("rc-util/lib/hooks/useMergedState"));
var _OptionList = _interopRequireDefault(require("./OptionList"));
var _TreeNode = _interopRequireDefault(require("./TreeNode"));
var _strategyUtil = require("./utils/strategyUtil");
var _TreeSelectContext = _interopRequireDefault(require("./TreeSelectContext"));
var _LegacyContext = _interopRequireDefault(require("./LegacyContext"));
var _useTreeData = _interopRequireDefault(require("./hooks/useTreeData"));
var _valueUtil = require("./utils/valueUtil");
var _useCache3 = _interopRequireDefault(require("./hooks/useCache"));
var _useRefFunc = _interopRequireDefault(require("./hooks/useRefFunc"));
var _useDataEntities2 = _interopRequireDefault(require("./hooks/useDataEntities"));
var _legacyUtil = require("./utils/legacyUtil");
var _useCheckedKeys3 = _interopRequireDefault(require("./hooks/useCheckedKeys"));
var _useFilterTreeData = _interopRequireDefault(require("./hooks/useFilterTreeData"));
var _warningPropsUtil = _interopRequireDefault(require("./utils/warningPropsUtil"));
var _warning = _interopRequireDefault(require("rc-util/lib/warning"));
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof3(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
var __rest = void 0 && (void 0).__rest || function (s, e) {
var t = {};
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
}
return t;
};
function isRawValue(value) {
return !value || (0, _typeof2["default"])(value) !== 'object';
}
var TreeSelect = /*#__PURE__*/React.forwardRef(function (props, ref) {
var id = props.id,
_props$prefixCls = props.prefixCls,
prefixCls = _props$prefixCls === void 0 ? 'rc-tree-select' : _props$prefixCls,
value = props.value,
defaultValue = props.defaultValue,
onChange = props.onChange,
onSelect = props.onSelect,
onDeselect = props.onDeselect,
searchValue = props.searchValue,
inputValue = props.inputValue,
onSearch = props.onSearch,
_props$autoClearSearc = props.autoClearSearchValue,
autoClearSearchValue = _props$autoClearSearc === void 0 ? true : _props$autoClearSearc,
filterTreeNode = props.filterTreeNode,
_props$treeNodeFilter = props.treeNodeFilterProp,
treeNodeFilterProp = _props$treeNodeFilter === void 0 ? 'value' : _props$treeNodeFilter,
_props$showCheckedStr = props.showCheckedStrategy,
showCheckedStrategy = _props$showCheckedStr === void 0 ? _strategyUtil.SHOW_CHILD : _props$showCheckedStr,
treeNodeLabelProp = props.treeNodeLabelProp,
multiple = props.multiple,
treeCheckable = props.treeCheckable,
treeCheckStrictly = props.treeCheckStrictly,
labelInValue = props.labelInValue,
fieldNames = props.fieldNames,
treeDataSimpleMode = props.treeDataSimpleMode,
treeData = props.treeData,
children = props.children,
loadData = props.loadData,
treeLoadedKeys = props.treeLoadedKeys,
onTreeLoad = props.onTreeLoad,
treeDefaultExpandAll = props.treeDefaultExpandAll,
treeExpandedKeys = props.treeExpandedKeys,
treeDefaultExpandedKeys = props.treeDefaultExpandedKeys,
onTreeExpand = props.onTreeExpand,
treeExpandAction = props.treeExpandAction,
virtual = props.virtual,
_props$listHeight = props.listHeight,
listHeight = _props$listHeight === void 0 ? 200 : _props$listHeight,
_props$listItemHeight = props.listItemHeight,
listItemHeight = _props$listItemHeight === void 0 ? 20 : _props$listItemHeight,
onDropdownVisibleChange = props.onDropdownVisibleChange,
_props$dropdownMatchS = props.dropdownMatchSelectWidth,
dropdownMatchSelectWidth = _props$dropdownMatchS === void 0 ? true : _props$dropdownMatchS,
treeLine = props.treeLine,
treeIcon = props.treeIcon,
showTreeIcon = props.showTreeIcon,
switcherIcon = props.switcherIcon,
treeMotion = props.treeMotion,
_props$showSelectAll = props.showSelectAll,
showSelectAll = _props$showSelectAll === void 0 ? true : _props$showSelectAll,
restProps = __rest(props, ["id", "prefixCls", "value", "defaultValue", "onChange", "onSelect", "onDeselect", "searchValue", "inputValue", "onSearch", "autoClearSearchValue", "filterTreeNode", "treeNodeFilterProp", "showCheckedStrategy", "treeNodeLabelProp", "multiple", "treeCheckable", "treeCheckStrictly", "labelInValue", "fieldNames", "treeDataSimpleMode", "treeData", "children", "loadData", "treeLoadedKeys", "onTreeLoad", "treeDefaultExpandAll", "treeExpandedKeys", "treeDefaultExpandedKeys", "onTreeExpand", "treeExpandAction", "virtual", "listHeight", "listItemHeight", "onDropdownVisibleChange", "dropdownMatchSelectWidth", "treeLine", "treeIcon", "showTreeIcon", "switcherIcon", "treeMotion", "showSelectAll"]);
var mergedId = (0, _useId["default"])(id);
var treeConduction = treeCheckable && !treeCheckStrictly;
var mergedCheckable = treeCheckable || treeCheckStrictly;
var mergedLabelInValue = treeCheckStrictly || labelInValue;
var mergedMultiple = mergedCheckable || multiple;
// ========================== Warning ===========================
if (process.env.NODE_ENV !== 'production') {
(0, _warningPropsUtil["default"])(props);
}
// ========================= FieldNames =========================
var mergedFieldNames = React.useMemo(function () {
return (0, _valueUtil.fillFieldNames)(fieldNames);
}, /* eslint-disable react-hooks/exhaustive-deps */
[JSON.stringify(fieldNames)]);
// =========================== Search ===========================
var _useMergedState = (0, _useMergedState5["default"])('', {
value: searchValue !== undefined ? searchValue : inputValue,
postState: function postState(search) {
return search || '';
}
}),
_useMergedState2 = (0, _slicedToArray2["default"])(_useMergedState, 2),
mergedSearchValue = _useMergedState2[0],
setSearchValue = _useMergedState2[1];
var onInternalSearch = function onInternalSearch(searchText) {
setSearchValue(searchText);
onSearch === null || onSearch === void 0 ? void 0 : onSearch(searchText);
};
// ============================ Data ============================
// `useTreeData` only do convert of `children` or `simpleMode`.
// Else will return origin `treeData` for perf consideration.
// Do not do anything to loop the data.
var mergedTreeData = (0, _useTreeData["default"])(treeData, children, treeDataSimpleMode);
var _useDataEntities = (0, _useDataEntities2["default"])(mergedTreeData, mergedFieldNames),
keyEntities = _useDataEntities.keyEntities,
valueEntities = _useDataEntities.valueEntities;
/** Get `missingRawValues` which not exist in the tree yet */
var splitRawValues = React.useCallback(function (newRawValues) {
var missingRawValues = [];
var existRawValues = [];
// Keep missing value in the cache
newRawValues.forEach(function (val) {
if (valueEntities.has(val)) {
existRawValues.push(val);
} else {
missingRawValues.push(val);
}
});
return {
missingRawValues: missingRawValues,
existRawValues: existRawValues
};
}, [valueEntities]);
// Filtered Tree
var filteredTreeData = (0, _useFilterTreeData["default"])(mergedTreeData, mergedSearchValue, {
fieldNames: mergedFieldNames,
treeNodeFilterProp: treeNodeFilterProp,
filterTreeNode: filterTreeNode
});
// =========================== Label ============================
var getLabel = React.useCallback(function (item) {
if (item) {
if (treeNodeLabelProp) {
return item[treeNodeLabelProp];
}
// Loop from fieldNames
var titleList = mergedFieldNames._title;
for (var i = 0; i < titleList.length; i += 1) {
var title = item[titleList[i]];
if (title !== undefined) {
return title;
}
}
}
}, [mergedFieldNames, treeNodeLabelProp]);
// ========================= Wrap Value =========================
var toLabeledValues = React.useCallback(function (draftValues) {
var values = (0, _valueUtil.toArray)(draftValues);
return values.map(function (val) {
if (isRawValue(val)) {
return {
value: val
};
}
return val;
});
}, []);
var convert2LabelValues = React.useCallback(function (draftValues) {
var values = toLabeledValues(draftValues);
return values.map(function (item) {
var rawLabel = item.label;
var rawValue = item.value,
rawHalfChecked = item.halfChecked;
var rawDisabled;
var entity = valueEntities.get(rawValue);
// Fill missing label & status
if (entity) {
rawLabel = rawLabel !== null && rawLabel !== void 0 ? rawLabel : getLabel(entity.node);
rawDisabled = entity.node.disabled;
}
return {
label: rawLabel,
value: rawValue,
halfChecked: rawHalfChecked,
disabled: rawDisabled
};
});
}, [valueEntities, getLabel, toLabeledValues]);
// =========================== Values ===========================
var _useMergedState3 = (0, _useMergedState5["default"])(defaultValue, {
value: value
}),
_useMergedState4 = (0, _slicedToArray2["default"])(_useMergedState3, 2),
internalValue = _useMergedState4[0],
setInternalValue = _useMergedState4[1];
var rawMixedLabeledValues = React.useMemo(function () {
return toLabeledValues(internalValue);
}, [toLabeledValues, internalValue]);
// Split value into full check and half check
var _React$useMemo = React.useMemo(function () {
var fullCheckValues = [];
var halfCheckValues = [];
rawMixedLabeledValues.forEach(function (item) {
if (item.halfChecked) {
halfCheckValues.push(item);
} else {
fullCheckValues.push(item);
}
});
return [fullCheckValues, halfCheckValues];
}, [rawMixedLabeledValues]),
_React$useMemo2 = (0, _slicedToArray2["default"])(_React$useMemo, 2),
rawLabeledValues = _React$useMemo2[0],
rawHalfLabeledValues = _React$useMemo2[1];
// const [mergedValues] = useCache(rawLabeledValues);
var rawValues = React.useMemo(function () {
return rawLabeledValues.map(function (item) {
return item.value;
});
}, [rawLabeledValues]);
// Convert value to key. Will fill missed keys for conduct check.
var _useCheckedKeys = (0, _useCheckedKeys3["default"])(rawLabeledValues, rawHalfLabeledValues, treeConduction, keyEntities),
_useCheckedKeys2 = (0, _slicedToArray2["default"])(_useCheckedKeys, 2),
rawCheckedValues = _useCheckedKeys2[0],
rawHalfCheckedValues = _useCheckedKeys2[1];
// Convert rawCheckedKeys to check strategy related values
var displayValues = React.useMemo(function () {
// Collect keys which need to show
var displayKeys = (0, _strategyUtil.formatStrategyValues)(rawCheckedValues, showCheckedStrategy, keyEntities, mergedFieldNames);
// Convert to value and filled with label
var values = displayKeys.map(function (key) {
var _a, _b, _c;
return (_c = (_b = (_a = keyEntities[key]) === null || _a === void 0 ? void 0 : _a.node) === null || _b === void 0 ? void 0 : _b[mergedFieldNames.value]) !== null && _c !== void 0 ? _c : key;
});
// Back fill with origin label
var labeledValues = values.map(function (val) {
var targetItem = rawLabeledValues.find(function (item) {
return item.value === val;
});
return {
value: val,
label: targetItem === null || targetItem === void 0 ? void 0 : targetItem.label
};
});
var rawDisplayValues = convert2LabelValues(labeledValues);
var firstVal = rawDisplayValues[0];
if (!mergedMultiple && firstVal && (0, _valueUtil.isNil)(firstVal.value) && (0, _valueUtil.isNil)(firstVal.label)) {
return [];
}
return rawDisplayValues.map(function (item) {
var _a;
return (0, _extends2["default"])((0, _extends2["default"])({}, item), {
label: (_a = item.label) !== null && _a !== void 0 ? _a : item.value
});
});
}, [mergedFieldNames, mergedMultiple, rawCheckedValues, rawLabeledValues, convert2LabelValues, showCheckedStrategy, keyEntities]);
var _useCache = (0, _useCache3["default"])(displayValues),
_useCache2 = (0, _slicedToArray2["default"])(_useCache, 1),
cachedDisplayValues = _useCache2[0];
// =========================== Change ===========================
var triggerChange = (0, _useRefFunc["default"])(function (newRawValues, extra, source) {
var labeledValues = convert2LabelValues(newRawValues);
setInternalValue(labeledValues);
// Clean up if needed
if (autoClearSearchValue) {
setSearchValue('');
}
// Generate rest parameters is costly, so only do it when necessary
if (onChange) {
var eventValues = newRawValues;
if (treeConduction) {
var formattedKeyList = (0, _strategyUtil.formatStrategyValues)(newRawValues, showCheckedStrategy, keyEntities, mergedFieldNames);
eventValues = formattedKeyList.map(function (key) {
var entity = valueEntities.get(key);
return entity ? entity.node[mergedFieldNames.value] : key;
});
}
var _ref = extra || {
triggerValue: undefined,
selected: undefined
},
triggerValue = _ref.triggerValue,
selected = _ref.selected;
var returnRawValues = eventValues;
// We need fill half check back
if (treeCheckStrictly) {
var halfValues = rawHalfLabeledValues.filter(function (item) {
return !eventValues.includes(item.value);
});
returnRawValues = [].concat((0, _toConsumableArray2["default"])(returnRawValues), (0, _toConsumableArray2["default"])(halfValues));
}
var returnLabeledValues = convert2LabelValues(returnRawValues);
var additionalInfo = {
// [Legacy] Always return as array contains label & value
preValue: rawLabeledValues,
triggerValue: triggerValue
};
// [Legacy] Fill legacy data if user query.
// This is expansive that we only fill when user query
// https://github.com/react-component/tree-select/blob/fe33eb7c27830c9ac70cd1fdb1ebbe7bc679c16a/src/Select.jsx
var showPosition = true;
if (treeCheckStrictly || source === 'selection' && !selected) {
showPosition = false;
}
(0, _legacyUtil.fillAdditionalInfo)(additionalInfo, triggerValue, newRawValues, mergedTreeData, showPosition, mergedFieldNames);
if (mergedCheckable) {
additionalInfo.checked = selected;
} else {
additionalInfo.selected = selected;
}
var returnValues = mergedLabelInValue ? returnLabeledValues : returnLabeledValues.map(function (item) {
return item.value;
});
onChange(mergedMultiple ? returnValues : returnValues[0], mergedLabelInValue ? null : returnLabeledValues.map(function (item) {
return item.label;
}), additionalInfo);
}
});
// ========================== Options ===========================
/** Trigger by option list */
var onOptionSelect = React.useCallback(function (selectedKey, _ref2) {
var selected = _ref2.selected,
source = _ref2.source;
var _a;
var entity = keyEntities[selectedKey];
var node = entity === null || entity === void 0 ? void 0 : entity.node;
var selectedValue = (_a = node === null || node === void 0 ? void 0 : node[mergedFieldNames.value]) !== null && _a !== void 0 ? _a : selectedKey;
// Never be falsy but keep it safe
if (!mergedMultiple) {
// Single mode always set value
triggerChange([selectedValue], {
selected: true,
triggerValue: selectedValue
}, 'option');
} else {
var newRawValues = selected ? [].concat((0, _toConsumableArray2["default"])(rawValues), [selectedValue]) : rawCheckedValues.filter(function (v) {
return v !== selectedValue;
});
// Add keys if tree conduction
if (treeConduction) {
// Should keep missing values
var _splitRawValues = splitRawValues(newRawValues),
missingRawValues = _splitRawValues.missingRawValues,
existRawValues = _splitRawValues.existRawValues;
var keyList = existRawValues.map(function (val) {
return valueEntities.get(val).key;
});
// Conduction by selected or not
var checkedKeys;
if (selected) {
var _conductCheck = (0, _conductUtil.conductCheck)(keyList, true, keyEntities);
checkedKeys = _conductCheck.checkedKeys;
} else {
var _conductCheck2 = (0, _conductUtil.conductCheck)(keyList, {
checked: false,
halfCheckedKeys: rawHalfCheckedValues
}, keyEntities);
checkedKeys = _conductCheck2.checkedKeys;
}
// Fill back of keys
newRawValues = [].concat((0, _toConsumableArray2["default"])(missingRawValues), (0, _toConsumableArray2["default"])(checkedKeys.map(function (key) {
return keyEntities[key].node[mergedFieldNames.value];
})));
}
triggerChange(newRawValues, {
selected: selected,
triggerValue: selectedValue
}, source || 'option');
}
// Trigger select event
if (selected || !mergedMultiple) {
onSelect === null || onSelect === void 0 ? void 0 : onSelect(selectedValue, (0, _legacyUtil.fillLegacyProps)(node));
} else {
onDeselect === null || onDeselect === void 0 ? void 0 : onDeselect(selectedValue, (0, _legacyUtil.fillLegacyProps)(node));
}
}, [splitRawValues, valueEntities, keyEntities, mergedFieldNames, mergedMultiple, rawValues, triggerChange, treeConduction, onSelect, onDeselect, rawCheckedValues, rawHalfCheckedValues]);
// ========================== Dropdown ==========================
var onInternalDropdownVisibleChange = React.useCallback(function (open) {
if (onDropdownVisibleChange) {
var legacyParam = {};
Object.defineProperty(legacyParam, 'documentClickClose', {
get: function get() {
(0, _warning["default"])(false, 'Second param of `onDropdownVisibleChange` has been removed.');
return false;
}
});
onDropdownVisibleChange(open, legacyParam);
}
}, [onDropdownVisibleChange]);
// ====================== Display Change ========================
var onDisplayValuesChange = (0, _useRefFunc["default"])(function (newValues, info) {
var newRawValues = newValues.map(function (item) {
return item.value;
});
if (info.type === 'clear') {
triggerChange(newRawValues, {}, 'selection');
return;
}
// TreeSelect only have multiple mode which means display change only has remove
if (info.values.length) {
onOptionSelect(info.values[0].value, {
selected: false,
source: 'selection'
});
}
});
// ========================== Context ===========================
var treeSelectContext = React.useMemo(function () {
return {
virtual: virtual,
dropdownMatchSelectWidth: dropdownMatchSelectWidth,
listHeight: listHeight,
listItemHeight: listItemHeight,
treeData: filteredTreeData,
fieldNames: mergedFieldNames,
onSelect: onOptionSelect,
triggerChange: triggerChange,
treeExpandAction: treeExpandAction
};
}, [virtual, dropdownMatchSelectWidth, listHeight, listItemHeight, filteredTreeData, mergedFieldNames, onOptionSelect, treeExpandAction]);
// ======================= Legacy Context =======================
var legacyContext = React.useMemo(function () {
return {
checkable: mergedCheckable,
loadData: loadData,
treeLoadedKeys: treeLoadedKeys,
onTreeLoad: onTreeLoad,
checkedKeys: rawCheckedValues,
halfCheckedKeys: rawHalfCheckedValues,
treeDefaultExpandAll: treeDefaultExpandAll,
treeExpandedKeys: treeExpandedKeys,
treeDefaultExpandedKeys: treeDefaultExpandedKeys,
onTreeExpand: onTreeExpand,
treeIcon: treeIcon,
treeMotion: treeMotion,
showTreeIcon: showTreeIcon,
showSelectAll: showSelectAll,
switcherIcon: switcherIcon,
treeLine: treeLine,
treeNodeFilterProp: treeNodeFilterProp,
keyEntities: keyEntities
};
}, [mergedCheckable, loadData, treeLoadedKeys, onTreeLoad, rawCheckedValues, rawHalfCheckedValues, treeDefaultExpandAll, treeExpandedKeys, treeDefaultExpandedKeys, onTreeExpand, treeIcon, treeMotion, showTreeIcon, showSelectAll, switcherIcon, treeLine, treeNodeFilterProp, keyEntities]);
// =========================== Render ===========================
return /*#__PURE__*/React.createElement(_TreeSelectContext["default"].Provider, {
value: treeSelectContext
}, /*#__PURE__*/React.createElement(_LegacyContext["default"].Provider, {
value: legacyContext
}, /*#__PURE__*/React.createElement(_rcSelect.BaseSelect, (0, _extends2["default"])({
ref: ref
}, restProps, {
// >>> MISC
id: mergedId,
prefixCls: prefixCls,
mode: mergedMultiple ? 'multiple' : undefined
// >>> Display Value
,
displayValues: cachedDisplayValues,
onDisplayValuesChange: onDisplayValuesChange
// >>> Search
,
searchValue: mergedSearchValue,
onSearch: onInternalSearch
// >>> Options
,
OptionList: _OptionList["default"],
emptyOptions: !mergedTreeData.length,
onDropdownVisibleChange: onInternalDropdownVisibleChange,
dropdownMatchSelectWidth: dropdownMatchSelectWidth
}))));
});
// Assign name for Debug
if (process.env.NODE_ENV !== 'production') {
TreeSelect.displayName = 'TreeSelect';
}
var GenericTreeSelect = TreeSelect;
GenericTreeSelect.TreeNode = _TreeNode["default"];
GenericTreeSelect.SHOW_ALL = _strategyUtil.SHOW_ALL;
GenericTreeSelect.SHOW_PARENT = _strategyUtil.SHOW_PARENT;
GenericTreeSelect.SHOW_CHILD = _strategyUtil.SHOW_CHILD;
var _default = exports["default"] = GenericTreeSelect;