index.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. "use client";
  2. var __rest = this && this.__rest || function (s, e) {
  3. var t = {};
  4. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  5. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  6. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  7. }
  8. return t;
  9. };
  10. import * as React from 'react';
  11. import cls from 'classnames';
  12. import RcTreeSelect, { SHOW_ALL, SHOW_CHILD, SHOW_PARENT, TreeNode } from 'rc-tree-select';
  13. import omit from "rc-util/es/omit";
  14. import { useZIndex } from '../_util/hooks/useZIndex';
  15. import { getTransitionName } from '../_util/motion';
  16. import genPurePanel from '../_util/PurePanel';
  17. import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';
  18. import { devUseWarning } from '../_util/warning';
  19. import { ConfigContext } from '../config-provider';
  20. import { useComponentConfig } from '../config-provider/context';
  21. import DefaultRenderEmpty from '../config-provider/defaultRenderEmpty';
  22. import DisabledContext from '../config-provider/DisabledContext';
  23. import useCSSVarCls from '../config-provider/hooks/useCSSVarCls';
  24. import useSize from '../config-provider/hooks/useSize';
  25. import { FormItemInputContext } from '../form/context';
  26. import useVariant from '../form/hooks/useVariants';
  27. import mergedBuiltinPlacements from '../select/mergedBuiltinPlacements';
  28. import useSelectStyle from '../select/style';
  29. import useIcons from '../select/useIcons';
  30. import usePopupRender from '../select/usePopupRender';
  31. import useShowArrow from '../select/useShowArrow';
  32. import { useCompactItemContext } from '../space/Compact';
  33. import { useToken } from '../theme/internal';
  34. import SwitcherIconCom from '../tree/utils/iconUtil';
  35. import useStyle from './style';
  36. const InternalTreeSelect = (props, ref) => {
  37. var _a, _b, _c, _d, _e;
  38. const {
  39. prefixCls: customizePrefixCls,
  40. size: customizeSize,
  41. disabled: customDisabled,
  42. bordered = true,
  43. style,
  44. className,
  45. rootClassName,
  46. treeCheckable,
  47. multiple,
  48. listHeight = 256,
  49. listItemHeight: customListItemHeight,
  50. placement,
  51. notFoundContent,
  52. switcherIcon,
  53. treeLine,
  54. getPopupContainer,
  55. popupClassName,
  56. dropdownClassName,
  57. treeIcon = false,
  58. transitionName,
  59. choiceTransitionName = '',
  60. status: customStatus,
  61. treeExpandAction,
  62. builtinPlacements,
  63. dropdownMatchSelectWidth,
  64. popupMatchSelectWidth,
  65. allowClear,
  66. variant: customVariant,
  67. dropdownStyle,
  68. dropdownRender,
  69. popupRender,
  70. onDropdownVisibleChange,
  71. onOpenChange,
  72. tagRender,
  73. maxCount,
  74. showCheckedStrategy,
  75. treeCheckStrictly,
  76. styles,
  77. classNames
  78. } = props,
  79. restProps = __rest(props, ["prefixCls", "size", "disabled", "bordered", "style", "className", "rootClassName", "treeCheckable", "multiple", "listHeight", "listItemHeight", "placement", "notFoundContent", "switcherIcon", "treeLine", "getPopupContainer", "popupClassName", "dropdownClassName", "treeIcon", "transitionName", "choiceTransitionName", "status", "treeExpandAction", "builtinPlacements", "dropdownMatchSelectWidth", "popupMatchSelectWidth", "allowClear", "variant", "dropdownStyle", "dropdownRender", "popupRender", "onDropdownVisibleChange", "onOpenChange", "tagRender", "maxCount", "showCheckedStrategy", "treeCheckStrictly", "styles", "classNames"]);
  80. const {
  81. getPopupContainer: getContextPopupContainer,
  82. getPrefixCls,
  83. renderEmpty,
  84. direction,
  85. virtual,
  86. popupMatchSelectWidth: contextPopupMatchSelectWidth,
  87. popupOverflow
  88. } = React.useContext(ConfigContext);
  89. const {
  90. styles: contextStyles,
  91. classNames: contextClassNames
  92. } = useComponentConfig('treeSelect');
  93. const [, token] = useToken();
  94. const listItemHeight = customListItemHeight !== null && customListItemHeight !== void 0 ? customListItemHeight : (token === null || token === void 0 ? void 0 : token.controlHeightSM) + (token === null || token === void 0 ? void 0 : token.paddingXXS);
  95. if (process.env.NODE_ENV !== 'production') {
  96. const warning = devUseWarning('TreeSelect');
  97. const deprecatedProps = {
  98. dropdownMatchSelectWidth: 'popupMatchSelectWidth',
  99. dropdownStyle: 'styles.popup.root',
  100. dropdownClassName: 'classNames.popup.root',
  101. popupClassName: 'classNames.popup.root',
  102. dropdownRender: 'popupRender',
  103. onDropdownVisibleChange: 'onOpenChange',
  104. bordered: 'variant'
  105. };
  106. Object.entries(deprecatedProps).forEach(([oldProp, newProp]) => {
  107. warning.deprecated(!(oldProp in props), oldProp, newProp);
  108. });
  109. process.env.NODE_ENV !== "production" ? warning(multiple !== false || !treeCheckable, 'usage', '`multiple` will always be `true` when `treeCheckable` is true') : void 0;
  110. process.env.NODE_ENV !== "production" ? warning(!('showArrow' in props), 'deprecated', '`showArrow` is deprecated which will be removed in next major version. It will be a default behavior, you can hide it by setting `suffixIcon` to null.') : void 0;
  111. }
  112. const rootPrefixCls = getPrefixCls();
  113. const prefixCls = getPrefixCls('select', customizePrefixCls);
  114. const treePrefixCls = getPrefixCls('select-tree', customizePrefixCls);
  115. const treeSelectPrefixCls = getPrefixCls('tree-select', customizePrefixCls);
  116. const {
  117. compactSize,
  118. compactItemClassnames
  119. } = useCompactItemContext(prefixCls, direction);
  120. const rootCls = useCSSVarCls(prefixCls);
  121. const treeSelectRootCls = useCSSVarCls(treeSelectPrefixCls);
  122. const [wrapCSSVar, hashId, cssVarCls] = useSelectStyle(prefixCls, rootCls);
  123. const [treeSelectWrapCSSVar] = useStyle(treeSelectPrefixCls, treePrefixCls, treeSelectRootCls);
  124. const [variant, enableVariantCls] = useVariant('treeSelect', customVariant, bordered);
  125. const mergedPopupClassName = cls(((_a = classNames === null || classNames === void 0 ? void 0 : classNames.popup) === null || _a === void 0 ? void 0 : _a.root) || ((_b = contextClassNames === null || contextClassNames === void 0 ? void 0 : contextClassNames.popup) === null || _b === void 0 ? void 0 : _b.root) || popupClassName || dropdownClassName, `${treeSelectPrefixCls}-dropdown`, {
  126. [`${treeSelectPrefixCls}-dropdown-rtl`]: direction === 'rtl'
  127. }, rootClassName, contextClassNames.root, classNames === null || classNames === void 0 ? void 0 : classNames.root, cssVarCls, rootCls, treeSelectRootCls, hashId);
  128. const mergedPopupStyle = ((_c = styles === null || styles === void 0 ? void 0 : styles.popup) === null || _c === void 0 ? void 0 : _c.root) || ((_d = contextStyles === null || contextStyles === void 0 ? void 0 : contextStyles.popup) === null || _d === void 0 ? void 0 : _d.root) || dropdownStyle;
  129. const mergedPopupRender = usePopupRender(popupRender || dropdownRender);
  130. const mergedOnOpenChange = onOpenChange || onDropdownVisibleChange;
  131. const isMultiple = !!(treeCheckable || multiple);
  132. const mergedMaxCount = React.useMemo(() => {
  133. if (maxCount && (showCheckedStrategy === 'SHOW_ALL' && !treeCheckStrictly || showCheckedStrategy === 'SHOW_PARENT')) {
  134. return undefined;
  135. }
  136. return maxCount;
  137. }, [maxCount, showCheckedStrategy, treeCheckStrictly]);
  138. const showSuffixIcon = useShowArrow(props.suffixIcon, props.showArrow);
  139. const mergedPopupMatchSelectWidth = (_e = popupMatchSelectWidth !== null && popupMatchSelectWidth !== void 0 ? popupMatchSelectWidth : dropdownMatchSelectWidth) !== null && _e !== void 0 ? _e : contextPopupMatchSelectWidth;
  140. // ===================== Form =====================
  141. const {
  142. status: contextStatus,
  143. hasFeedback,
  144. isFormItemInput,
  145. feedbackIcon
  146. } = React.useContext(FormItemInputContext);
  147. const mergedStatus = getMergedStatus(contextStatus, customStatus);
  148. // ===================== Icons =====================
  149. const {
  150. suffixIcon,
  151. removeIcon,
  152. clearIcon
  153. } = useIcons(Object.assign(Object.assign({}, restProps), {
  154. multiple: isMultiple,
  155. showSuffixIcon,
  156. hasFeedback,
  157. feedbackIcon,
  158. prefixCls,
  159. componentName: 'TreeSelect'
  160. }));
  161. const mergedAllowClear = allowClear === true ? {
  162. clearIcon
  163. } : allowClear;
  164. // ===================== Empty =====================
  165. let mergedNotFound;
  166. if (notFoundContent !== undefined) {
  167. mergedNotFound = notFoundContent;
  168. } else {
  169. mergedNotFound = (renderEmpty === null || renderEmpty === void 0 ? void 0 : renderEmpty('Select')) || /*#__PURE__*/React.createElement(DefaultRenderEmpty, {
  170. componentName: "Select"
  171. });
  172. }
  173. // ==================== Render =====================
  174. const selectProps = omit(restProps, ['suffixIcon', 'removeIcon', 'clearIcon', 'itemIcon', 'switcherIcon', 'style']);
  175. // ===================== Placement =====================
  176. const memoizedPlacement = React.useMemo(() => {
  177. if (placement !== undefined) {
  178. return placement;
  179. }
  180. return direction === 'rtl' ? 'bottomRight' : 'bottomLeft';
  181. }, [placement, direction]);
  182. const mergedSize = useSize(ctx => {
  183. var _a;
  184. return (_a = customizeSize !== null && customizeSize !== void 0 ? customizeSize : compactSize) !== null && _a !== void 0 ? _a : ctx;
  185. });
  186. // ===================== Disabled =====================
  187. const disabled = React.useContext(DisabledContext);
  188. const mergedDisabled = customDisabled !== null && customDisabled !== void 0 ? customDisabled : disabled;
  189. const mergedClassName = cls(!customizePrefixCls && treeSelectPrefixCls, {
  190. [`${prefixCls}-lg`]: mergedSize === 'large',
  191. [`${prefixCls}-sm`]: mergedSize === 'small',
  192. [`${prefixCls}-rtl`]: direction === 'rtl',
  193. [`${prefixCls}-${variant}`]: enableVariantCls,
  194. [`${prefixCls}-in-form-item`]: isFormItemInput
  195. }, getStatusClassNames(prefixCls, mergedStatus, hasFeedback), compactItemClassnames, className, rootClassName, contextClassNames.root, classNames === null || classNames === void 0 ? void 0 : classNames.root, cssVarCls, rootCls, treeSelectRootCls, hashId);
  196. const renderSwitcherIcon = nodeProps => (/*#__PURE__*/React.createElement(SwitcherIconCom, {
  197. prefixCls: treePrefixCls,
  198. switcherIcon: switcherIcon,
  199. treeNodeProps: nodeProps,
  200. showLine: treeLine
  201. }));
  202. // ============================ zIndex ============================
  203. const [zIndex] = useZIndex('SelectLike', mergedPopupStyle === null || mergedPopupStyle === void 0 ? void 0 : mergedPopupStyle.zIndex);
  204. const returnNode = /*#__PURE__*/React.createElement(RcTreeSelect, Object.assign({
  205. virtual: virtual,
  206. disabled: mergedDisabled
  207. }, selectProps, {
  208. dropdownMatchSelectWidth: mergedPopupMatchSelectWidth,
  209. builtinPlacements: mergedBuiltinPlacements(builtinPlacements, popupOverflow),
  210. ref: ref,
  211. prefixCls: prefixCls,
  212. className: mergedClassName,
  213. style: Object.assign(Object.assign({}, styles === null || styles === void 0 ? void 0 : styles.root), style),
  214. listHeight: listHeight,
  215. listItemHeight: listItemHeight,
  216. treeCheckable: treeCheckable ? /*#__PURE__*/React.createElement("span", {
  217. className: `${prefixCls}-tree-checkbox-inner`
  218. }) : treeCheckable,
  219. treeLine: !!treeLine,
  220. suffixIcon: suffixIcon,
  221. multiple: isMultiple,
  222. placement: memoizedPlacement,
  223. removeIcon: removeIcon,
  224. allowClear: mergedAllowClear,
  225. switcherIcon: renderSwitcherIcon,
  226. showTreeIcon: treeIcon,
  227. notFoundContent: mergedNotFound,
  228. getPopupContainer: getPopupContainer || getContextPopupContainer,
  229. treeMotion: null,
  230. dropdownClassName: mergedPopupClassName,
  231. dropdownStyle: Object.assign(Object.assign({}, mergedPopupStyle), {
  232. zIndex
  233. }),
  234. dropdownRender: mergedPopupRender,
  235. onDropdownVisibleChange: mergedOnOpenChange,
  236. choiceTransitionName: getTransitionName(rootPrefixCls, '', choiceTransitionName),
  237. transitionName: getTransitionName(rootPrefixCls, 'slide-up', transitionName),
  238. treeExpandAction: treeExpandAction,
  239. tagRender: isMultiple ? tagRender : undefined,
  240. maxCount: mergedMaxCount,
  241. showCheckedStrategy: showCheckedStrategy,
  242. treeCheckStrictly: treeCheckStrictly
  243. }));
  244. return wrapCSSVar(treeSelectWrapCSSVar(returnNode));
  245. };
  246. const TreeSelectRef = /*#__PURE__*/React.forwardRef(InternalTreeSelect);
  247. const TreeSelect = TreeSelectRef;
  248. // We don't care debug panel
  249. /* istanbul ignore next */
  250. const PurePanel = genPurePanel(TreeSelect, 'dropdownAlign', props => omit(props, ['visible']));
  251. TreeSelect.TreeNode = TreeNode;
  252. TreeSelect.SHOW_ALL = SHOW_ALL;
  253. TreeSelect.SHOW_PARENT = SHOW_PARENT;
  254. TreeSelect.SHOW_CHILD = SHOW_CHILD;
  255. TreeSelect._InternalPanelDoNotUseOrYouWillBeFired = PurePanel;
  256. if (process.env.NODE_ENV !== 'production') {
  257. TreeSelect.displayName = 'TreeSelect';
  258. }
  259. export { TreeNode };
  260. export default TreeSelect;