diff --git a/components/tree-select/index.tsx b/components/tree-select/index.tsx index d23b184d0..8255c533b 100644 --- a/components/tree-select/index.tsx +++ b/components/tree-select/index.tsx @@ -12,8 +12,9 @@ import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined'; import CaretDownOutlined from '@ant-design/icons-vue/CaretDownOutlined'; import DownOutlined from '@ant-design/icons-vue/DownOutlined'; import CloseOutlined from '@ant-design/icons-vue/CloseOutlined'; -import CloseCircleOutlined from '@ant-design/icons-vue/CloseCircleOutlined'; +import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; import omit from 'omit.js'; +import { convertChildrenToData } from './utils'; const TreeSelect = defineComponent({ TreeNode, @@ -41,7 +42,7 @@ const TreeSelect = defineComponent({ ); }, methods: { - saveTreeSelect(node) { + saveTreeSelect(node: any) { this.vcTreeSelect = node; }, focus() { @@ -51,7 +52,7 @@ const TreeSelect = defineComponent({ blur() { this.vcTreeSelect.blur(); }, - renderSwitcherIcon(prefixCls, { isLeaf, loading }) { + renderSwitcherIcon(prefixCls: string, { isLeaf, loading }) { if (loading) { return ; } @@ -60,19 +61,19 @@ const TreeSelect = defineComponent({ } return ; }, - handleChange(...args) { + handleChange(...args: any[]) { this.$emit('update:value', args[0]); this.$emit('change', ...args); }, - handleTreeExpand(...args) { + handleTreeExpand(...args: any[]) { this.$emit('update:treeExpandedKeys', args[0]); this.$emit('treeExpand', ...args); }, - handleSearch(...args) { + handleSearch(...args: any[]) { this.$emit('update:searchValue', args[0]); this.$emit('search', ...args); }, - updateTreeData(treeData) { + updateTreeData(treeData: any[]) { const { $slots } = this; const defaultFields = { children: 'children', @@ -164,9 +165,7 @@ const TreeSelect = defineComponent({ const finalRemoveIcon = removeIcon || ; - const finalClearIcon = clearIcon || ( - - ); + const finalClearIcon = clearIcon || ; const VcTreeSelectProps = { ...this.$attrs, switcherIcon: nodeProps => this.renderSwitcherIcon(prefixCls, nodeProps), @@ -181,13 +180,12 @@ const TreeSelect = defineComponent({ dropdownStyle: { maxHeight: '100vh', overflow: 'auto', ...dropdownStyle }, treeCheckable: checkable, notFoundContent: notFoundContent || renderEmpty('Select'), - ...(treeData ? { treeData } : {}), class: cls, onChange: this.handleChange, onSearch: this.handleSearch, onTreeExpand: this.handleTreeExpand, ref: this.saveTreeSelect, - children: getSlot(this), + treeData: treeData ? treeData : convertChildrenToData(getSlot(this)), }; return ( ({ labelInValue: PropTypes.looseBool, loadData: PropTypes.func, maxTagCount: PropTypes.number, - maxTagPlaceholder: PropTypes.any, + maxTagPlaceholder: PropTypes.VNodeChild, value: PropTypes.oneOfType([ PropTypes.string, PropTypes.object, @@ -33,11 +33,11 @@ export const TreeSelectProps = () => ({ PropTypes.number, ]), multiple: PropTypes.looseBool, - notFoundContent: PropTypes.any, + notFoundContent: PropTypes.VNodeChild, searchPlaceholder: PropTypes.string, searchValue: PropTypes.string, showCheckedStrategy: PropTypes.oneOf(tuple('SHOW_ALL', 'SHOW_PARENT', 'SHOW_CHILD')), - suffixIcon: PropTypes.any, + suffixIcon: PropTypes.VNodeChild, treeCheckable: PropTypes.looseBool, treeCheckStrictly: PropTypes.looseBool, treeData: PropTypes.arrayOf(Object), @@ -52,8 +52,8 @@ export const TreeSelectProps = () => ({ treeNodeFilterProp: PropTypes.string, treeNodeLabelProp: PropTypes.string, replaceFields: PropTypes.object.def({}), - clearIcon: PropTypes.any, - removeIcon: PropTypes.any, + clearIcon: PropTypes.VNodeChild, + removeIcon: PropTypes.VNodeChild, onSelect: PropTypes.func, onChange: PropTypes.func, diff --git a/components/tree-select/utils.tsx b/components/tree-select/utils.tsx new file mode 100644 index 000000000..f900cc6a2 --- /dev/null +++ b/components/tree-select/utils.tsx @@ -0,0 +1,34 @@ +import { flattenChildren, isValidElement } from '../_util/props-util'; + +export function convertChildrenToData(nodes: any[]): any[] { + return flattenChildren(nodes) + .map(node => { + if (!isValidElement(node) || !node.type) { + return null; + } + const { default: d, ...restSlot } = node.children || {}; + const children = d ? d() : []; + const { + key, + props: { value, ...restProps }, + } = node; + + const data = { + key, + value, + ...restProps, + }; + Object.keys(restSlot).forEach(p => { + if (typeof restSlot[p] === 'function') { + data[p] = restSlot[p](); + } + }); + const childData = convertChildrenToData(children); + if (childData.length) { + data.children = childData; + } + + return data; + }) + .filter(data => data); +} diff --git a/components/vc-tree-select/src/Select.jsx b/components/vc-tree-select/src/Select.jsx index 84cfc95c1..8389d561d 100644 --- a/components/vc-tree-select/src/Select.jsx +++ b/components/vc-tree-select/src/Select.jsx @@ -245,12 +245,11 @@ const Select = defineComponent({ raf(() => { const popupNode = findDOMNode(this.popup); const triggerContainer = findPopupContainer(popupNode, `${prefixCls}-dropdown`); - const searchNode = this.popup.searchRef.current; - if (domNode && triggerContainer && searchNode) { + if (domNode && triggerContainer) { scrollIntoView(domNode, triggerContainer, { onlyScrollIfNeeded: true, - offsetTop: searchNode.offsetHeight, + offsetTop: 0, }); } });