TreeSelect.js 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. import _extends from "@babel/runtime/helpers/esm/extends";
  2. import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray";
  3. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  4. import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
  5. import _objectWithoutProperties from "@babel/runtime/helpers/esm/objectWithoutProperties";
  6. import _typeof from "@babel/runtime/helpers/esm/typeof";
  7. var _excluded = ["id", "prefixCls", "value", "defaultValue", "onChange", "onSelect", "onDeselect", "searchValue", "inputValue", "onSearch", "autoClearSearchValue", "filterTreeNode", "treeNodeFilterProp", "showCheckedStrategy", "treeNodeLabelProp", "multiple", "treeCheckable", "treeCheckStrictly", "labelInValue", "maxCount", "fieldNames", "treeDataSimpleMode", "treeData", "children", "loadData", "treeLoadedKeys", "onTreeLoad", "treeDefaultExpandAll", "treeExpandedKeys", "treeDefaultExpandedKeys", "onTreeExpand", "treeExpandAction", "virtual", "listHeight", "listItemHeight", "listItemScrollOffset", "onDropdownVisibleChange", "dropdownMatchSelectWidth", "treeLine", "treeIcon", "showTreeIcon", "switcherIcon", "treeMotion", "treeTitleRender", "onPopupScroll"];
  8. import { BaseSelect } from 'rc-select';
  9. import useId from "rc-select/es/hooks/useId";
  10. import { conductCheck } from "rc-tree/es/utils/conductUtil";
  11. import useMergedState from "rc-util/es/hooks/useMergedState";
  12. import warning from "rc-util/es/warning";
  13. import * as React from 'react';
  14. import useCache from "./hooks/useCache";
  15. import useCheckedKeys from "./hooks/useCheckedKeys";
  16. import useDataEntities from "./hooks/useDataEntities";
  17. import useFilterTreeData from "./hooks/useFilterTreeData";
  18. import useRefFunc from "./hooks/useRefFunc";
  19. import useTreeData from "./hooks/useTreeData";
  20. import LegacyContext from "./LegacyContext";
  21. import OptionList from "./OptionList";
  22. import TreeNode from "./TreeNode";
  23. import TreeSelectContext from "./TreeSelectContext";
  24. import { fillAdditionalInfo, fillLegacyProps } from "./utils/legacyUtil";
  25. import { formatStrategyValues, SHOW_ALL, SHOW_CHILD, SHOW_PARENT } from "./utils/strategyUtil";
  26. import { fillFieldNames, isNil, toArray } from "./utils/valueUtil";
  27. import warningProps from "./utils/warningPropsUtil";
  28. function isRawValue(value) {
  29. return !value || _typeof(value) !== 'object';
  30. }
  31. var TreeSelect = /*#__PURE__*/React.forwardRef(function (props, ref) {
  32. var id = props.id,
  33. _props$prefixCls = props.prefixCls,
  34. prefixCls = _props$prefixCls === void 0 ? 'rc-tree-select' : _props$prefixCls,
  35. value = props.value,
  36. defaultValue = props.defaultValue,
  37. onChange = props.onChange,
  38. onSelect = props.onSelect,
  39. onDeselect = props.onDeselect,
  40. searchValue = props.searchValue,
  41. inputValue = props.inputValue,
  42. onSearch = props.onSearch,
  43. _props$autoClearSearc = props.autoClearSearchValue,
  44. autoClearSearchValue = _props$autoClearSearc === void 0 ? true : _props$autoClearSearc,
  45. filterTreeNode = props.filterTreeNode,
  46. _props$treeNodeFilter = props.treeNodeFilterProp,
  47. treeNodeFilterProp = _props$treeNodeFilter === void 0 ? 'value' : _props$treeNodeFilter,
  48. showCheckedStrategy = props.showCheckedStrategy,
  49. treeNodeLabelProp = props.treeNodeLabelProp,
  50. multiple = props.multiple,
  51. treeCheckable = props.treeCheckable,
  52. treeCheckStrictly = props.treeCheckStrictly,
  53. labelInValue = props.labelInValue,
  54. maxCount = props.maxCount,
  55. fieldNames = props.fieldNames,
  56. treeDataSimpleMode = props.treeDataSimpleMode,
  57. treeData = props.treeData,
  58. children = props.children,
  59. loadData = props.loadData,
  60. treeLoadedKeys = props.treeLoadedKeys,
  61. onTreeLoad = props.onTreeLoad,
  62. treeDefaultExpandAll = props.treeDefaultExpandAll,
  63. treeExpandedKeys = props.treeExpandedKeys,
  64. treeDefaultExpandedKeys = props.treeDefaultExpandedKeys,
  65. onTreeExpand = props.onTreeExpand,
  66. treeExpandAction = props.treeExpandAction,
  67. virtual = props.virtual,
  68. _props$listHeight = props.listHeight,
  69. listHeight = _props$listHeight === void 0 ? 200 : _props$listHeight,
  70. _props$listItemHeight = props.listItemHeight,
  71. listItemHeight = _props$listItemHeight === void 0 ? 20 : _props$listItemHeight,
  72. _props$listItemScroll = props.listItemScrollOffset,
  73. listItemScrollOffset = _props$listItemScroll === void 0 ? 0 : _props$listItemScroll,
  74. onDropdownVisibleChange = props.onDropdownVisibleChange,
  75. _props$dropdownMatchS = props.dropdownMatchSelectWidth,
  76. dropdownMatchSelectWidth = _props$dropdownMatchS === void 0 ? true : _props$dropdownMatchS,
  77. treeLine = props.treeLine,
  78. treeIcon = props.treeIcon,
  79. showTreeIcon = props.showTreeIcon,
  80. switcherIcon = props.switcherIcon,
  81. treeMotion = props.treeMotion,
  82. treeTitleRender = props.treeTitleRender,
  83. onPopupScroll = props.onPopupScroll,
  84. restProps = _objectWithoutProperties(props, _excluded);
  85. var mergedId = useId(id);
  86. var treeConduction = treeCheckable && !treeCheckStrictly;
  87. var mergedCheckable = treeCheckable || treeCheckStrictly;
  88. var mergedLabelInValue = treeCheckStrictly || labelInValue;
  89. var mergedMultiple = mergedCheckable || multiple;
  90. var _useMergedState = useMergedState(defaultValue, {
  91. value: value
  92. }),
  93. _useMergedState2 = _slicedToArray(_useMergedState, 2),
  94. internalValue = _useMergedState2[0],
  95. setInternalValue = _useMergedState2[1];
  96. // `multiple` && `!treeCheckable` should be show all
  97. var mergedShowCheckedStrategy = React.useMemo(function () {
  98. if (!treeCheckable) {
  99. return SHOW_ALL;
  100. }
  101. return showCheckedStrategy || SHOW_CHILD;
  102. }, [showCheckedStrategy, treeCheckable]);
  103. // ========================== Warning ===========================
  104. if (process.env.NODE_ENV !== 'production') {
  105. warningProps(props);
  106. }
  107. // ========================= FieldNames =========================
  108. var mergedFieldNames = React.useMemo(function () {
  109. return fillFieldNames(fieldNames);
  110. }, /* eslint-disable react-hooks/exhaustive-deps */
  111. [JSON.stringify(fieldNames)]
  112. /* eslint-enable react-hooks/exhaustive-deps */);
  113. // =========================== Search ===========================
  114. var _useMergedState3 = useMergedState('', {
  115. value: searchValue !== undefined ? searchValue : inputValue,
  116. postState: function postState(search) {
  117. return search || '';
  118. }
  119. }),
  120. _useMergedState4 = _slicedToArray(_useMergedState3, 2),
  121. mergedSearchValue = _useMergedState4[0],
  122. setSearchValue = _useMergedState4[1];
  123. var onInternalSearch = function onInternalSearch(searchText) {
  124. setSearchValue(searchText);
  125. onSearch === null || onSearch === void 0 || onSearch(searchText);
  126. };
  127. // ============================ Data ============================
  128. // `useTreeData` only do convert of `children` or `simpleMode`.
  129. // Else will return origin `treeData` for perf consideration.
  130. // Do not do anything to loop the data.
  131. var mergedTreeData = useTreeData(treeData, children, treeDataSimpleMode);
  132. var _useDataEntities = useDataEntities(mergedTreeData, mergedFieldNames),
  133. keyEntities = _useDataEntities.keyEntities,
  134. valueEntities = _useDataEntities.valueEntities;
  135. /** Get `missingRawValues` which not exist in the tree yet */
  136. var splitRawValues = React.useCallback(function (newRawValues) {
  137. var missingRawValues = [];
  138. var existRawValues = [];
  139. // Keep missing value in the cache
  140. newRawValues.forEach(function (val) {
  141. if (valueEntities.has(val)) {
  142. existRawValues.push(val);
  143. } else {
  144. missingRawValues.push(val);
  145. }
  146. });
  147. return {
  148. missingRawValues: missingRawValues,
  149. existRawValues: existRawValues
  150. };
  151. }, [valueEntities]);
  152. // Filtered Tree
  153. var filteredTreeData = useFilterTreeData(mergedTreeData, mergedSearchValue, {
  154. fieldNames: mergedFieldNames,
  155. treeNodeFilterProp: treeNodeFilterProp,
  156. filterTreeNode: filterTreeNode
  157. });
  158. // =========================== Label ============================
  159. var getLabel = React.useCallback(function (item) {
  160. if (item) {
  161. if (treeNodeLabelProp) {
  162. return item[treeNodeLabelProp];
  163. }
  164. // Loop from fieldNames
  165. var titleList = mergedFieldNames._title;
  166. for (var i = 0; i < titleList.length; i += 1) {
  167. var title = item[titleList[i]];
  168. if (title !== undefined) {
  169. return title;
  170. }
  171. }
  172. }
  173. }, [mergedFieldNames, treeNodeLabelProp]);
  174. // ========================= Wrap Value =========================
  175. var toLabeledValues = React.useCallback(function (draftValues) {
  176. var values = toArray(draftValues);
  177. return values.map(function (val) {
  178. if (isRawValue(val)) {
  179. return {
  180. value: val
  181. };
  182. }
  183. return val;
  184. });
  185. }, []);
  186. var convert2LabelValues = React.useCallback(function (draftValues) {
  187. var values = toLabeledValues(draftValues);
  188. return values.map(function (item) {
  189. var rawLabel = item.label;
  190. var rawValue = item.value,
  191. rawHalfChecked = item.halfChecked;
  192. var rawDisabled;
  193. var entity = valueEntities.get(rawValue);
  194. // Fill missing label & status
  195. if (entity) {
  196. var _rawLabel;
  197. rawLabel = treeTitleRender ? treeTitleRender(entity.node) : (_rawLabel = rawLabel) !== null && _rawLabel !== void 0 ? _rawLabel : getLabel(entity.node);
  198. rawDisabled = entity.node.disabled;
  199. } else if (rawLabel === undefined) {
  200. // We try to find in current `labelInValue` value
  201. var labelInValueItem = toLabeledValues(internalValue).find(function (labeledItem) {
  202. return labeledItem.value === rawValue;
  203. });
  204. rawLabel = labelInValueItem.label;
  205. }
  206. return {
  207. label: rawLabel,
  208. value: rawValue,
  209. halfChecked: rawHalfChecked,
  210. disabled: rawDisabled
  211. };
  212. });
  213. }, [valueEntities, getLabel, toLabeledValues, internalValue]);
  214. // =========================== Values ===========================
  215. var rawMixedLabeledValues = React.useMemo(function () {
  216. return toLabeledValues(internalValue === null ? [] : internalValue);
  217. }, [toLabeledValues, internalValue]);
  218. // Split value into full check and half check
  219. var _React$useMemo = React.useMemo(function () {
  220. var fullCheckValues = [];
  221. var halfCheckValues = [];
  222. rawMixedLabeledValues.forEach(function (item) {
  223. if (item.halfChecked) {
  224. halfCheckValues.push(item);
  225. } else {
  226. fullCheckValues.push(item);
  227. }
  228. });
  229. return [fullCheckValues, halfCheckValues];
  230. }, [rawMixedLabeledValues]),
  231. _React$useMemo2 = _slicedToArray(_React$useMemo, 2),
  232. rawLabeledValues = _React$useMemo2[0],
  233. rawHalfLabeledValues = _React$useMemo2[1];
  234. // const [mergedValues] = useCache(rawLabeledValues);
  235. var rawValues = React.useMemo(function () {
  236. return rawLabeledValues.map(function (item) {
  237. return item.value;
  238. });
  239. }, [rawLabeledValues]);
  240. // Convert value to key. Will fill missed keys for conduct check.
  241. var _useCheckedKeys = useCheckedKeys(rawLabeledValues, rawHalfLabeledValues, treeConduction, keyEntities),
  242. _useCheckedKeys2 = _slicedToArray(_useCheckedKeys, 2),
  243. rawCheckedValues = _useCheckedKeys2[0],
  244. rawHalfCheckedValues = _useCheckedKeys2[1];
  245. // Convert rawCheckedKeys to check strategy related values
  246. var displayValues = React.useMemo(function () {
  247. // Collect keys which need to show
  248. var displayKeys = formatStrategyValues(rawCheckedValues, mergedShowCheckedStrategy, keyEntities, mergedFieldNames);
  249. // Convert to value and filled with label
  250. var values = displayKeys.map(function (key) {
  251. var _keyEntities$key$node, _keyEntities$key;
  252. return (_keyEntities$key$node = (_keyEntities$key = keyEntities[key]) === null || _keyEntities$key === void 0 || (_keyEntities$key = _keyEntities$key.node) === null || _keyEntities$key === void 0 ? void 0 : _keyEntities$key[mergedFieldNames.value]) !== null && _keyEntities$key$node !== void 0 ? _keyEntities$key$node : key;
  253. });
  254. // Back fill with origin label
  255. var labeledValues = values.map(function (val) {
  256. var targetItem = rawLabeledValues.find(function (item) {
  257. return item.value === val;
  258. });
  259. var label = labelInValue ? targetItem === null || targetItem === void 0 ? void 0 : targetItem.label : treeTitleRender === null || treeTitleRender === void 0 ? void 0 : treeTitleRender(targetItem);
  260. return {
  261. value: val,
  262. label: label
  263. };
  264. });
  265. var rawDisplayValues = convert2LabelValues(labeledValues);
  266. var firstVal = rawDisplayValues[0];
  267. if (!mergedMultiple && firstVal && isNil(firstVal.value) && isNil(firstVal.label)) {
  268. return [];
  269. }
  270. return rawDisplayValues.map(function (item) {
  271. var _item$label;
  272. return _objectSpread(_objectSpread({}, item), {}, {
  273. label: (_item$label = item.label) !== null && _item$label !== void 0 ? _item$label : item.value
  274. });
  275. });
  276. // eslint-disable-next-line react-hooks/exhaustive-deps
  277. }, [mergedFieldNames, mergedMultiple, rawCheckedValues, rawLabeledValues, convert2LabelValues, mergedShowCheckedStrategy, keyEntities]);
  278. var _useCache = useCache(displayValues),
  279. _useCache2 = _slicedToArray(_useCache, 1),
  280. cachedDisplayValues = _useCache2[0];
  281. // ========================== MaxCount ==========================
  282. var mergedMaxCount = React.useMemo(function () {
  283. if (mergedMultiple && (mergedShowCheckedStrategy === 'SHOW_CHILD' || treeCheckStrictly || !treeCheckable)) {
  284. return maxCount;
  285. }
  286. return null;
  287. }, [maxCount, mergedMultiple, treeCheckStrictly, mergedShowCheckedStrategy, treeCheckable]);
  288. // =========================== Change ===========================
  289. var triggerChange = useRefFunc(function (newRawValues, extra, source) {
  290. var formattedKeyList = formatStrategyValues(newRawValues, mergedShowCheckedStrategy, keyEntities, mergedFieldNames);
  291. // Not allow pass with `maxCount`
  292. if (mergedMaxCount && formattedKeyList.length > mergedMaxCount) {
  293. return;
  294. }
  295. var labeledValues = convert2LabelValues(newRawValues);
  296. setInternalValue(labeledValues);
  297. // Clean up if needed
  298. if (autoClearSearchValue) {
  299. setSearchValue('');
  300. }
  301. // Generate rest parameters is costly, so only do it when necessary
  302. if (onChange) {
  303. var eventValues = newRawValues;
  304. if (treeConduction) {
  305. eventValues = formattedKeyList.map(function (key) {
  306. var entity = valueEntities.get(key);
  307. return entity ? entity.node[mergedFieldNames.value] : key;
  308. });
  309. }
  310. var _ref = extra || {
  311. triggerValue: undefined,
  312. selected: undefined
  313. },
  314. triggerValue = _ref.triggerValue,
  315. selected = _ref.selected;
  316. var returnRawValues = eventValues;
  317. // We need fill half check back
  318. if (treeCheckStrictly) {
  319. var halfValues = rawHalfLabeledValues.filter(function (item) {
  320. return !eventValues.includes(item.value);
  321. });
  322. returnRawValues = [].concat(_toConsumableArray(returnRawValues), _toConsumableArray(halfValues));
  323. }
  324. var returnLabeledValues = convert2LabelValues(returnRawValues);
  325. var additionalInfo = {
  326. // [Legacy] Always return as array contains label & value
  327. preValue: rawLabeledValues,
  328. triggerValue: triggerValue
  329. };
  330. // [Legacy] Fill legacy data if user query.
  331. // This is expansive that we only fill when user query
  332. // https://github.com/react-component/tree-select/blob/fe33eb7c27830c9ac70cd1fdb1ebbe7bc679c16a/src/Select.jsx
  333. var showPosition = true;
  334. if (treeCheckStrictly || source === 'selection' && !selected) {
  335. showPosition = false;
  336. }
  337. fillAdditionalInfo(additionalInfo, triggerValue, newRawValues, mergedTreeData, showPosition, mergedFieldNames);
  338. if (mergedCheckable) {
  339. additionalInfo.checked = selected;
  340. } else {
  341. additionalInfo.selected = selected;
  342. }
  343. var returnValues = mergedLabelInValue ? returnLabeledValues : returnLabeledValues.map(function (item) {
  344. return item.value;
  345. });
  346. onChange(mergedMultiple ? returnValues : returnValues[0], mergedLabelInValue ? null : returnLabeledValues.map(function (item) {
  347. return item.label;
  348. }), additionalInfo);
  349. }
  350. });
  351. // ========================== Options ===========================
  352. /** Trigger by option list */
  353. var onOptionSelect = React.useCallback(function (selectedKey, _ref2) {
  354. var _node$mergedFieldName;
  355. var selected = _ref2.selected,
  356. source = _ref2.source;
  357. var entity = keyEntities[selectedKey];
  358. var node = entity === null || entity === void 0 ? void 0 : entity.node;
  359. var selectedValue = (_node$mergedFieldName = node === null || node === void 0 ? void 0 : node[mergedFieldNames.value]) !== null && _node$mergedFieldName !== void 0 ? _node$mergedFieldName : selectedKey;
  360. // Never be falsy but keep it safe
  361. if (!mergedMultiple) {
  362. // Single mode always set value
  363. triggerChange([selectedValue], {
  364. selected: true,
  365. triggerValue: selectedValue
  366. }, 'option');
  367. } else {
  368. var newRawValues = selected ? [].concat(_toConsumableArray(rawValues), [selectedValue]) : rawCheckedValues.filter(function (v) {
  369. return v !== selectedValue;
  370. });
  371. // Add keys if tree conduction
  372. if (treeConduction) {
  373. // Should keep missing values
  374. var _splitRawValues = splitRawValues(newRawValues),
  375. missingRawValues = _splitRawValues.missingRawValues,
  376. existRawValues = _splitRawValues.existRawValues;
  377. var keyList = existRawValues.map(function (val) {
  378. return valueEntities.get(val).key;
  379. });
  380. // Conduction by selected or not
  381. var checkedKeys;
  382. if (selected) {
  383. var _conductCheck = conductCheck(keyList, true, keyEntities);
  384. checkedKeys = _conductCheck.checkedKeys;
  385. } else {
  386. var _conductCheck2 = conductCheck(keyList, {
  387. checked: false,
  388. halfCheckedKeys: rawHalfCheckedValues
  389. }, keyEntities);
  390. checkedKeys = _conductCheck2.checkedKeys;
  391. }
  392. // Fill back of keys
  393. newRawValues = [].concat(_toConsumableArray(missingRawValues), _toConsumableArray(checkedKeys.map(function (key) {
  394. return keyEntities[key].node[mergedFieldNames.value];
  395. })));
  396. }
  397. triggerChange(newRawValues, {
  398. selected: selected,
  399. triggerValue: selectedValue
  400. }, source || 'option');
  401. }
  402. // Trigger select event
  403. if (selected || !mergedMultiple) {
  404. onSelect === null || onSelect === void 0 || onSelect(selectedValue, fillLegacyProps(node));
  405. } else {
  406. onDeselect === null || onDeselect === void 0 || onDeselect(selectedValue, fillLegacyProps(node));
  407. }
  408. }, [splitRawValues, valueEntities, keyEntities, mergedFieldNames, mergedMultiple, rawValues, triggerChange, treeConduction, onSelect, onDeselect, rawCheckedValues, rawHalfCheckedValues, maxCount]);
  409. // ========================== Dropdown ==========================
  410. var onInternalDropdownVisibleChange = React.useCallback(function (open) {
  411. if (onDropdownVisibleChange) {
  412. var legacyParam = {};
  413. Object.defineProperty(legacyParam, 'documentClickClose', {
  414. get: function get() {
  415. warning(false, 'Second param of `onDropdownVisibleChange` has been removed.');
  416. return false;
  417. }
  418. });
  419. onDropdownVisibleChange(open, legacyParam);
  420. }
  421. }, [onDropdownVisibleChange]);
  422. // ====================== Display Change ========================
  423. var onDisplayValuesChange = useRefFunc(function (newValues, info) {
  424. var newRawValues = newValues.map(function (item) {
  425. return item.value;
  426. });
  427. if (info.type === 'clear') {
  428. triggerChange(newRawValues, {}, 'selection');
  429. return;
  430. }
  431. // TreeSelect only have multiple mode which means display change only has remove
  432. if (info.values.length) {
  433. onOptionSelect(info.values[0].value, {
  434. selected: false,
  435. source: 'selection'
  436. });
  437. }
  438. });
  439. // ========================== Context ===========================
  440. var treeSelectContext = React.useMemo(function () {
  441. return {
  442. virtual: virtual,
  443. dropdownMatchSelectWidth: dropdownMatchSelectWidth,
  444. listHeight: listHeight,
  445. listItemHeight: listItemHeight,
  446. listItemScrollOffset: listItemScrollOffset,
  447. treeData: filteredTreeData,
  448. fieldNames: mergedFieldNames,
  449. onSelect: onOptionSelect,
  450. treeExpandAction: treeExpandAction,
  451. treeTitleRender: treeTitleRender,
  452. onPopupScroll: onPopupScroll,
  453. leftMaxCount: maxCount === undefined ? null : maxCount - cachedDisplayValues.length,
  454. leafCountOnly: mergedShowCheckedStrategy === 'SHOW_CHILD' && !treeCheckStrictly && !!treeCheckable,
  455. valueEntities: valueEntities
  456. };
  457. }, [virtual, dropdownMatchSelectWidth, listHeight, listItemHeight, listItemScrollOffset, filteredTreeData, mergedFieldNames, onOptionSelect, treeExpandAction, treeTitleRender, onPopupScroll, maxCount, cachedDisplayValues.length, mergedShowCheckedStrategy, treeCheckStrictly, treeCheckable, valueEntities]);
  458. // ======================= Legacy Context =======================
  459. var legacyContext = React.useMemo(function () {
  460. return {
  461. checkable: mergedCheckable,
  462. loadData: loadData,
  463. treeLoadedKeys: treeLoadedKeys,
  464. onTreeLoad: onTreeLoad,
  465. checkedKeys: rawCheckedValues,
  466. halfCheckedKeys: rawHalfCheckedValues,
  467. treeDefaultExpandAll: treeDefaultExpandAll,
  468. treeExpandedKeys: treeExpandedKeys,
  469. treeDefaultExpandedKeys: treeDefaultExpandedKeys,
  470. onTreeExpand: onTreeExpand,
  471. treeIcon: treeIcon,
  472. treeMotion: treeMotion,
  473. showTreeIcon: showTreeIcon,
  474. switcherIcon: switcherIcon,
  475. treeLine: treeLine,
  476. treeNodeFilterProp: treeNodeFilterProp,
  477. keyEntities: keyEntities
  478. };
  479. }, [mergedCheckable, loadData, treeLoadedKeys, onTreeLoad, rawCheckedValues, rawHalfCheckedValues, treeDefaultExpandAll, treeExpandedKeys, treeDefaultExpandedKeys, onTreeExpand, treeIcon, treeMotion, showTreeIcon, switcherIcon, treeLine, treeNodeFilterProp, keyEntities]);
  480. // =========================== Render ===========================
  481. return /*#__PURE__*/React.createElement(TreeSelectContext.Provider, {
  482. value: treeSelectContext
  483. }, /*#__PURE__*/React.createElement(LegacyContext.Provider, {
  484. value: legacyContext
  485. }, /*#__PURE__*/React.createElement(BaseSelect, _extends({
  486. ref: ref
  487. }, restProps, {
  488. // >>> MISC
  489. id: mergedId,
  490. prefixCls: prefixCls,
  491. mode: mergedMultiple ? 'multiple' : undefined
  492. // >>> Display Value
  493. ,
  494. displayValues: cachedDisplayValues,
  495. onDisplayValuesChange: onDisplayValuesChange
  496. // >>> Search
  497. ,
  498. searchValue: mergedSearchValue,
  499. onSearch: onInternalSearch
  500. // >>> Options
  501. ,
  502. OptionList: OptionList,
  503. emptyOptions: !mergedTreeData.length,
  504. onDropdownVisibleChange: onInternalDropdownVisibleChange,
  505. dropdownMatchSelectWidth: dropdownMatchSelectWidth
  506. }))));
  507. });
  508. // Assign name for Debug
  509. if (process.env.NODE_ENV !== 'production') {
  510. TreeSelect.displayName = 'TreeSelect';
  511. }
  512. var GenericTreeSelect = TreeSelect;
  513. GenericTreeSelect.TreeNode = TreeNode;
  514. GenericTreeSelect.SHOW_ALL = SHOW_ALL;
  515. GenericTreeSelect.SHOW_PARENT = SHOW_PARENT;
  516. GenericTreeSelect.SHOW_CHILD = SHOW_CHILD;
  517. export default GenericTreeSelect;