index.js 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288
  1. import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2";
  2. import _extends from "@babel/runtime/helpers/esm/extends";
  3. import { resolveDirective as _resolveDirective, createVNode as _createVNode } from "vue";
  4. var __rest = this && this.__rest || function (s, e) {
  5. var t = {};
  6. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  7. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  8. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  9. }
  10. return t;
  11. };
  12. import VcCascader, { cascaderProps as vcCascaderProps, SHOW_CHILD, SHOW_PARENT } from '../vc-cascader';
  13. import RightOutlined from "@ant-design/icons-vue/es/icons/RightOutlined";
  14. import LoadingOutlined from "@ant-design/icons-vue/es/icons/LoadingOutlined";
  15. import LeftOutlined from "@ant-design/icons-vue/es/icons/LeftOutlined";
  16. import getIcons from '../select/utils/iconUtil';
  17. import { withInstall } from '../_util/type';
  18. import omit from '../_util/omit';
  19. import { computed, defineComponent, ref, watchEffect } from 'vue';
  20. import PropTypes from '../_util/vue-types';
  21. import { initDefaultProps } from '../_util/props-util';
  22. import useConfigInject from '../config-provider/hooks/useConfigInject';
  23. import classNames from '../_util/classNames';
  24. import devWarning from '../vc-util/devWarning';
  25. import { getTransitionDirection, getTransitionName } from '../_util/transition';
  26. import { useInjectFormItemContext } from '../form';
  27. import { getStatusClassNames, getMergedStatus } from '../_util/statusUtils';
  28. import { FormItemInputContext } from '../form/FormItemContext';
  29. import { useCompactItemContext } from '../space/Compact';
  30. import useSelectStyle from '../select/style';
  31. import useStyle from './style';
  32. import { useInjectDisabled } from '../config-provider/DisabledContext';
  33. function highlightKeyword(str, lowerKeyword, prefixCls) {
  34. const cells = str.toLowerCase().split(lowerKeyword).reduce((list, cur, index) => index === 0 ? [cur] : [...list, lowerKeyword, cur], []);
  35. const fillCells = [];
  36. let start = 0;
  37. cells.forEach((cell, index) => {
  38. const end = start + cell.length;
  39. let originWorld = str.slice(start, end);
  40. start = end;
  41. if (index % 2 === 1) {
  42. const _originWorld = function () {
  43. return originWorld;
  44. }();
  45. originWorld = _createVNode("span", {
  46. "class": `${prefixCls}-menu-item-keyword`,
  47. "key": "seperator"
  48. }, [originWorld]);
  49. }
  50. fillCells.push(originWorld);
  51. });
  52. return fillCells;
  53. }
  54. const defaultSearchRender = _ref => {
  55. let {
  56. inputValue,
  57. path,
  58. prefixCls,
  59. fieldNames
  60. } = _ref;
  61. const optionList = [];
  62. // We do lower here to save perf
  63. const lower = inputValue.toLowerCase();
  64. path.forEach((node, index) => {
  65. if (index !== 0) {
  66. optionList.push(' / ');
  67. }
  68. let label = node[fieldNames.label];
  69. const type = typeof label;
  70. if (type === 'string' || type === 'number') {
  71. label = highlightKeyword(String(label), lower, prefixCls);
  72. }
  73. optionList.push(label);
  74. });
  75. return optionList;
  76. };
  77. export function cascaderProps() {
  78. return _extends(_extends({}, omit(vcCascaderProps(), ['customSlots', 'checkable', 'options'])), {
  79. multiple: {
  80. type: Boolean,
  81. default: undefined
  82. },
  83. size: String,
  84. bordered: {
  85. type: Boolean,
  86. default: undefined
  87. },
  88. placement: {
  89. type: String
  90. },
  91. suffixIcon: PropTypes.any,
  92. status: String,
  93. options: Array,
  94. popupClassName: String,
  95. /** @deprecated Please use `popupClassName` instead */
  96. dropdownClassName: String,
  97. 'onUpdate:value': Function
  98. });
  99. }
  100. const Cascader = defineComponent({
  101. compatConfig: {
  102. MODE: 3
  103. },
  104. name: 'ACascader',
  105. inheritAttrs: false,
  106. props: initDefaultProps(cascaderProps(), {
  107. bordered: true,
  108. choiceTransitionName: '',
  109. allowClear: true
  110. }),
  111. setup(props, _ref2) {
  112. let {
  113. attrs,
  114. expose,
  115. slots,
  116. emit
  117. } = _ref2;
  118. // ====================== Warning ======================
  119. if (process.env.NODE_ENV !== 'production') {
  120. devWarning(!props.dropdownClassName, 'Cascader', '`dropdownClassName` is deprecated. Please use `popupClassName` instead.');
  121. }
  122. const formItemContext = useInjectFormItemContext();
  123. const formItemInputContext = FormItemInputContext.useInject();
  124. const mergedStatus = computed(() => getMergedStatus(formItemInputContext.status, props.status));
  125. const {
  126. prefixCls: cascaderPrefixCls,
  127. rootPrefixCls,
  128. getPrefixCls,
  129. direction,
  130. getPopupContainer,
  131. renderEmpty,
  132. size: contextSize,
  133. disabled
  134. } = useConfigInject('cascader', props);
  135. const prefixCls = computed(() => getPrefixCls('select', props.prefixCls));
  136. const {
  137. compactSize,
  138. compactItemClassnames
  139. } = useCompactItemContext(prefixCls, direction);
  140. const mergedSize = computed(() => compactSize.value || contextSize.value);
  141. const contextDisabled = useInjectDisabled();
  142. const mergedDisabled = computed(() => {
  143. var _a;
  144. return (_a = disabled.value) !== null && _a !== void 0 ? _a : contextDisabled.value;
  145. });
  146. const [wrapSelectSSR, hashId] = useSelectStyle(prefixCls);
  147. const [wrapCascaderSSR] = useStyle(cascaderPrefixCls);
  148. const isRtl = computed(() => direction.value === 'rtl');
  149. // =================== Warning =====================
  150. if (process.env.NODE_ENV !== 'production') {
  151. watchEffect(() => {
  152. devWarning(!props.multiple || !props.displayRender || !slots.displayRender, 'Cascader', '`displayRender` not work on `multiple`. Please use `tagRender` instead.');
  153. });
  154. }
  155. // ==================== Search =====================
  156. const mergedShowSearch = computed(() => {
  157. if (!props.showSearch) {
  158. return props.showSearch;
  159. }
  160. let searchConfig = {
  161. render: defaultSearchRender
  162. };
  163. if (typeof props.showSearch === 'object') {
  164. searchConfig = _extends(_extends({}, searchConfig), props.showSearch);
  165. }
  166. return searchConfig;
  167. });
  168. // =================== Dropdown ====================
  169. const mergedDropdownClassName = computed(() => classNames(props.popupClassName || props.dropdownClassName, `${cascaderPrefixCls.value}-dropdown`, {
  170. [`${cascaderPrefixCls.value}-dropdown-rtl`]: isRtl.value
  171. }, hashId.value));
  172. const selectRef = ref();
  173. expose({
  174. focus() {
  175. var _a;
  176. (_a = selectRef.value) === null || _a === void 0 ? void 0 : _a.focus();
  177. },
  178. blur() {
  179. var _a;
  180. (_a = selectRef.value) === null || _a === void 0 ? void 0 : _a.blur();
  181. }
  182. });
  183. const handleChange = function () {
  184. for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
  185. args[_key] = arguments[_key];
  186. }
  187. emit('update:value', args[0]);
  188. emit('change', ...args);
  189. formItemContext.onFieldChange();
  190. };
  191. const handleBlur = function () {
  192. for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
  193. args[_key2] = arguments[_key2];
  194. }
  195. emit('blur', ...args);
  196. formItemContext.onFieldBlur();
  197. };
  198. const mergedShowArrow = computed(() => props.showArrow !== undefined ? props.showArrow : props.loading || !props.multiple);
  199. const placement = computed(() => {
  200. if (props.placement !== undefined) {
  201. return props.placement;
  202. }
  203. return direction.value === 'rtl' ? 'bottomRight' : 'bottomLeft';
  204. });
  205. return () => {
  206. var _a, _b;
  207. const {
  208. notFoundContent = (_a = slots.notFoundContent) === null || _a === void 0 ? void 0 : _a.call(slots),
  209. expandIcon = (_b = slots.expandIcon) === null || _b === void 0 ? void 0 : _b.call(slots),
  210. multiple,
  211. bordered,
  212. allowClear,
  213. choiceTransitionName,
  214. transitionName,
  215. id = formItemContext.id.value
  216. } = props,
  217. restProps = __rest(props, ["notFoundContent", "expandIcon", "multiple", "bordered", "allowClear", "choiceTransitionName", "transitionName", "id"]);
  218. // =================== No Found ====================
  219. const mergedNotFoundContent = notFoundContent || renderEmpty('Cascader');
  220. // ===================== Icon ======================
  221. let mergedExpandIcon = expandIcon;
  222. if (!expandIcon) {
  223. mergedExpandIcon = isRtl.value ? _createVNode(LeftOutlined, null, null) : _createVNode(RightOutlined, null, null);
  224. }
  225. const loadingIcon = _createVNode("span", {
  226. "class": `${prefixCls.value}-menu-item-loading-icon`
  227. }, [_createVNode(LoadingOutlined, {
  228. "spin": true
  229. }, null)]);
  230. // ===================== Icons =====================
  231. const {
  232. suffixIcon,
  233. removeIcon,
  234. clearIcon
  235. } = getIcons(_extends(_extends({}, props), {
  236. hasFeedback: formItemInputContext.hasFeedback,
  237. feedbackIcon: formItemInputContext.feedbackIcon,
  238. multiple,
  239. prefixCls: prefixCls.value,
  240. showArrow: mergedShowArrow.value
  241. }), slots);
  242. return wrapCascaderSSR(wrapSelectSSR(_createVNode(VcCascader, _objectSpread(_objectSpread(_objectSpread({}, restProps), attrs), {}, {
  243. "id": id,
  244. "prefixCls": prefixCls.value,
  245. "class": [cascaderPrefixCls.value, {
  246. [`${prefixCls.value}-lg`]: mergedSize.value === 'large',
  247. [`${prefixCls.value}-sm`]: mergedSize.value === 'small',
  248. [`${prefixCls.value}-rtl`]: isRtl.value,
  249. [`${prefixCls.value}-borderless`]: !bordered,
  250. [`${prefixCls.value}-in-form-item`]: formItemInputContext.isFormItemInput
  251. }, getStatusClassNames(prefixCls.value, mergedStatus.value, formItemInputContext.hasFeedback), compactItemClassnames.value, attrs.class, hashId.value],
  252. "disabled": mergedDisabled.value,
  253. "direction": direction.value,
  254. "placement": placement.value,
  255. "notFoundContent": mergedNotFoundContent,
  256. "allowClear": allowClear,
  257. "showSearch": mergedShowSearch.value,
  258. "expandIcon": mergedExpandIcon,
  259. "inputIcon": suffixIcon,
  260. "removeIcon": removeIcon,
  261. "clearIcon": clearIcon,
  262. "loadingIcon": loadingIcon,
  263. "checkable": !!multiple,
  264. "dropdownClassName": mergedDropdownClassName.value,
  265. "dropdownPrefixCls": cascaderPrefixCls.value,
  266. "choiceTransitionName": getTransitionName(rootPrefixCls.value, '', choiceTransitionName),
  267. "transitionName": getTransitionName(rootPrefixCls.value, getTransitionDirection(placement.value), transitionName),
  268. "getPopupContainer": getPopupContainer === null || getPopupContainer === void 0 ? void 0 : getPopupContainer.value,
  269. "customSlots": _extends(_extends({}, slots), {
  270. checkable: () => _createVNode("span", {
  271. "class": `${cascaderPrefixCls.value}-checkbox-inner`
  272. }, null)
  273. }),
  274. "tagRender": props.tagRender || slots.tagRender,
  275. "displayRender": props.displayRender || slots.displayRender,
  276. "maxTagPlaceholder": props.maxTagPlaceholder || slots.maxTagPlaceholder,
  277. "showArrow": formItemInputContext.hasFeedback || props.showArrow,
  278. "onChange": handleChange,
  279. "onBlur": handleBlur,
  280. "ref": selectRef
  281. }), slots)));
  282. };
  283. }
  284. });
  285. export default withInstall(_extends(Cascader, {
  286. SHOW_CHILD,
  287. SHOW_PARENT
  288. }));