diff --git a/components/_util/props-util/initDefaultProps.ts b/components/_util/props-util/initDefaultProps.ts index 8c01271ce..99bc6366a 100644 --- a/components/_util/props-util/initDefaultProps.ts +++ b/components/_util/props-util/initDefaultProps.ts @@ -17,7 +17,13 @@ const initDefaultProps = <T>( Object.keys(defaultProps).forEach(k => { const prop = propTypes[k] as VueTypeValidableDef; if (prop) { - prop.default = defaultProps[k]; + if (prop.type || prop.default) { + prop.default = defaultProps[k]; + } else if (prop.def) { + prop.def(defaultProps[k]); + } else { + propTypes[k] = { type: prop, default: defaultProps[k] }; + } } else { throw new Error(`not have ${k} prop`); } diff --git a/components/tree-select/index.tsx b/components/tree-select/index.tsx index 8b4152eaf..e094e6db0 100644 --- a/components/tree-select/index.tsx +++ b/components/tree-select/index.tsx @@ -11,8 +11,6 @@ import VcTreeSelect, { import classNames from '../_util/classNames'; import initDefaultProps from '../_util/props-util/initDefaultProps'; import type { SizeType } from '../config-provider'; -import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined'; -import CaretDownOutlined from '@ant-design/icons-vue/CaretDownOutlined'; import type { DefaultValueType, FieldNames } from '../vc-tree-select/interface'; import omit from '../_util/omit'; import PropTypes from '../_util/vue-types'; @@ -237,78 +235,6 @@ const TreeSelect = defineComponent({ ); }; }, - - methods: { - saveTreeSelect(node: any) { - this.vcTreeSelect = node; - }, - focus() { - this.vcTreeSelect.focus(); - }, - - blur() { - this.vcTreeSelect.blur(); - }, - renderSwitcherIcon(prefixCls: string, { isLeaf, loading }) { - if (loading) { - return <LoadingOutlined class={`${prefixCls}-switcher-loading-icon`} />; - } - if (isLeaf) { - return null; - } - return <CaretDownOutlined class={`${prefixCls}-switcher-icon`} />; - }, - handleChange(...args: any[]) { - this.$emit('update:value', args[0]); - this.$emit('change', ...args); - }, - handleTreeExpand(...args: any[]) { - this.$emit('update:treeExpandedKeys', args[0]); - this.$emit('treeExpand', ...args); - }, - handleSearch(...args: any[]) { - this.$emit('update:searchValue', args[0]); - this.$emit('search', ...args); - }, - updateTreeData(treeData: any[]) { - const { $slots } = this; - const defaultFields = { - children: 'children', - title: 'title', - key: 'key', - label: 'label', - value: 'value', - }; - const replaceFields = { ...defaultFields, ...this.$props.replaceFields }; - return treeData.map(item => { - const { slots = {} } = item; - const label = item[replaceFields.label]; - const title = item[replaceFields.title]; - const value = item[replaceFields.value]; - const key = item[replaceFields.key]; - const children = item[replaceFields.children]; - let newLabel = typeof label === 'function' ? label() : label; - let newTitle = typeof title === 'function' ? title() : title; - if (!newLabel && slots.label && $slots[slots.label]) { - newLabel = <>{$slots[slots.label](item)}</>; - } - if (!newTitle && slots.title && $slots[slots.title]) { - newTitle = <>{$slots[slots.title](item)}</>; - } - const treeNodeProps = { - ...item, - title: newTitle || newLabel, - value, - dataRef: item, - key, - }; - if (children) { - return { ...treeNodeProps, children: this.updateTreeData(children) }; - } - return treeNodeProps; - }); - }, - }, }); /* istanbul ignore next */ diff --git a/components/tree/Tree.tsx b/components/tree/Tree.tsx index 7ad82b765..286e54361 100644 --- a/components/tree/Tree.tsx +++ b/components/tree/Tree.tsx @@ -8,6 +8,7 @@ import PropTypes from '../_util/vue-types'; import { filterEmpty } from '../_util/props-util'; import initDefaultProps from '../_util/props-util/initDefaultProps'; import type { DataNode, DragNodeEvent, FieldNames, Key } from '../vc-tree/interface'; +import type { TreeNodeProps } from '../vc-tree/props'; import { treeProps as vcTreeProps } from '../vc-tree/props'; import useConfigInject from '../_util/hooks/useConfigInject'; import renderSwitcherIcon from './utils/iconUtil'; @@ -35,7 +36,7 @@ export interface AntdTreeNodeAttribute { disableCheckbox: boolean; } -export type AntTreeNodeProps = DataNode; +export type AntTreeNodeProps = TreeNodeProps; // [Legacy] Compatible for v2 export type TreeDataItem = DataNode; diff --git a/components/tree/index.tsx b/components/tree/index.tsx index 9ace3d8b5..112ad28a3 100644 --- a/components/tree/index.tsx +++ b/components/tree/index.tsx @@ -11,7 +11,6 @@ export { AntTreeNodeCheckedEvent, AntTreeNodeSelectedEvent, AntdTreeNodeAttribute, - AntTreeNodeProps, TreeDataItem, } from './Tree'; diff --git a/components/tree/utils/dictUtil.ts b/components/tree/utils/dictUtil.ts index bd1f0a339..00b7285c6 100644 --- a/components/tree/utils/dictUtil.ts +++ b/components/tree/utils/dictUtil.ts @@ -1,4 +1,4 @@ -import type { DataNode, Key } from 'ant-design-vue/es/vc-tree/interface'; +import type { DataNode, Key } from '../../vc-tree/interface'; enum Record { None, diff --git a/components/tree/utils/iconUtil.tsx b/components/tree/utils/iconUtil.tsx index e14f6df63..e0d19abfc 100644 --- a/components/tree/utils/iconUtil.tsx +++ b/components/tree/utils/iconUtil.tsx @@ -4,7 +4,7 @@ import MinusSquareOutlined from '@ant-design/icons-vue/MinusSquareOutlined'; import PlusSquareOutlined from '@ant-design/icons-vue/PlusSquareOutlined'; import CaretDownFilled from '@ant-design/icons-vue/CaretDownFilled'; import type { AntTreeNodeProps } from '../Tree'; -import { isValidElement } from 'ant-design-vue/es/_util/props-util'; +import { isValidElement } from '../../_util/props-util'; import { cloneVNode } from 'vue'; diff --git a/components/vc-select/Selector/SingleSelector.tsx b/components/vc-select/Selector/SingleSelector.tsx index 269bc0b8e..ad99ebc28 100644 --- a/components/vc-select/Selector/SingleSelector.tsx +++ b/components/vc-select/Selector/SingleSelector.tsx @@ -5,7 +5,7 @@ import type { VNodeChild } from 'vue'; import { Fragment } from 'vue'; import { computed, defineComponent, ref, watch } from 'vue'; import PropTypes from '../../_util/vue-types'; -import { useInjectTreeSelectContext } from 'ant-design-vue/es/vc-tree-select/Context'; +import { useInjectTreeSelectContext } from '../../vc-tree-select/Context'; interface SelectorProps extends InnerSelectorProps { inputElement: VNodeChild; diff --git a/components/vc-select/generate.tsx b/components/vc-select/generate.tsx index 0bf2ac824..9c8b45a4e 100644 --- a/components/vc-select/generate.tsx +++ b/components/vc-select/generate.tsx @@ -1034,7 +1034,7 @@ export default function generateSelector< internalProps = {}, ...restProps - } = props; //as SelectProps<OptionType[], ValueType>; + } = { ...props, ...attrs }; //as SelectProps<OptionType[], ValueType>; // ============================= Input ============================== // Only works in `combobox` const customizeInputElement: VNodeChild | JSX.Element = @@ -1144,9 +1144,8 @@ export default function generateSelector< }); return ( <div - {...attrs} - class={mergedClassName} {...domProps} + class={mergedClassName} ref={containerRef} onMousedown={onInternalMouseDown} onKeydown={onInternalKeyDown} diff --git a/components/vc-tree-select/OptionList.tsx b/components/vc-tree-select/OptionList.tsx index bcbf0bc6c..5599754c7 100644 --- a/components/vc-tree-select/OptionList.tsx +++ b/components/vc-tree-select/OptionList.tsx @@ -143,7 +143,7 @@ export default defineComponent({ activeKey.value = key; }; expose({ - scrollTo: (...args: any[]) => treeRef.value.scrollTo?.(...args), + scrollTo: (...args: any[]) => treeRef.value?.scrollTo?.(...args), onKeydown: (event: KeyboardEvent) => { const { which } = event; switch (which) { diff --git a/components/vc-tree-select/generate.tsx b/components/vc-tree-select/generate.tsx index b1eca4003..a5fc4bf25 100644 --- a/components/vc-tree-select/generate.tsx +++ b/components/vc-tree-select/generate.tsx @@ -64,6 +64,7 @@ const OMIT_PROPS: (keyof TreeSelectProps)[] = [ 'treeDataSimpleMode', 'treeNodeLabelProp', 'treeDefaultExpandedKeys', + 'bordered', ]; export default function generate(config: { @@ -236,8 +237,9 @@ export default function generate(config: { ...checkedKeys.map(key => getEntityByKey(key).data.value), ]; rawHalfCheckedKeys.value = halfCheckedKeys; + } else { + [rawValues.value, rawHalfCheckedKeys.value] = [newRawValues, valueHalfCheckedKeys]; } - [rawValues.value, rawHalfCheckedKeys.value] = [newRawValues, valueHalfCheckedKeys]; }); const selectValues = useSelectValues(rawValues, { @@ -378,7 +380,7 @@ export default function generate(config: { option: DataNode, source: SelectSource, ) => { - const eventValue = mergedLabelInValue.value ? selectValue : selectValue; + const eventValue = selectValue; let newRawValues = removeValue(rawValues.value, selectValue); diff --git a/components/vc-tree-select/hooks/useTreeData.ts b/components/vc-tree-select/hooks/useTreeData.ts index b0969db67..22b8aaef0 100644 --- a/components/vc-tree-select/hooks/useTreeData.ts +++ b/components/vc-tree-select/hooks/useTreeData.ts @@ -1,4 +1,4 @@ -import { warning } from 'ant-design-vue/es/vc-util/warning'; +import { warning } from '../../vc-util/warning'; import type { ComputedRef, Ref } from 'vue'; import { computed } from 'vue'; import type { @@ -76,6 +76,7 @@ function formatTreeData( value: mergedValue, title: getLabelProp(node), node, + dataRef: node, }; if (node.slots) { diff --git a/components/vc-tree-select/interface.ts b/components/vc-tree-select/interface.ts index 747795c4b..1f659ddf3 100644 --- a/components/vc-tree-select/interface.ts +++ b/components/vc-tree-select/interface.ts @@ -39,6 +39,8 @@ export interface InternalDataEntity { /** Origin DataNode */ node: DataNode; + dataRef: DataNode; + slots?: Record<string, string>; // 兼容 V2 } diff --git a/components/vc-tree-select/utils/valueUtil.ts b/components/vc-tree-select/utils/valueUtil.ts index ba3a9757a..33f71a74f 100644 --- a/components/vc-tree-select/utils/valueUtil.ts +++ b/components/vc-tree-select/utils/valueUtil.ts @@ -11,9 +11,9 @@ import type { } from '../interface'; import { fillLegacyProps } from './legacyUtil'; import type { SkipType } from '../hooks/useKeyValueMapping'; -import type { FlattenNode } from 'ant-design-vue/es/vc-tree/interface'; -import { flattenTreeData } from 'ant-design-vue/es/vc-tree/utils/treeUtil'; -import type { FilterFunc } from 'ant-design-vue/es/vc-select/interface/generator'; +import type { FlattenNode } from '../../vc-tree/interface'; +import { flattenTreeData } from '../../vc-tree/utils/treeUtil'; +import type { FilterFunc } from '../../vc-select/interface/generator'; type CompatibleDataNode = Omit<FlattenDataNode, 'level'>; diff --git a/components/vc-tree-select/utils/warningPropsUtil.ts b/components/vc-tree-select/utils/warningPropsUtil.ts index d26534010..2b58b8936 100644 --- a/components/vc-tree-select/utils/warningPropsUtil.ts +++ b/components/vc-tree-select/utils/warningPropsUtil.ts @@ -1,12 +1,14 @@ import { warning } from '../../vc-util/warning'; -import type { TreeSelectProps } from '../TreeSelect'; import { toArray } from './valueUtil'; -function warningProps(props: TreeSelectProps) { +function warningProps(props: any) { const { searchPlaceholder, treeCheckStrictly, treeCheckable, labelInValue, value, multiple } = props; - warning(!searchPlaceholder, '`searchPlaceholder` has been removed.'); + warning( + !searchPlaceholder, + '`searchPlaceholder` has been removed, please use `placeholder` instead', + ); if (treeCheckStrictly && labelInValue === false) { warning(false, '`treeCheckStrictly` will force set `labelInValue` to `true`.'); diff --git a/components/vc-tree/Tree.tsx b/components/vc-tree/Tree.tsx index 95fd32a1b..a23622441 100644 --- a/components/vc-tree/Tree.tsx +++ b/components/vc-tree/Tree.tsx @@ -634,7 +634,7 @@ export default defineComponent({ checkedObj = newCheckedKeys; - // [Legacy] This is used for `rc-tree-select` + // [Legacy] This is used for vc-tree-select` eventObj.checkedNodes = []; eventObj.checkedNodesPositions = []; eventObj.halfCheckedKeys = newHalfCheckedKeys; @@ -997,7 +997,6 @@ export default defineComponent({ const { class: className, style } = attrs; const domProps = getDataAndAria({ ...props, ...attrs }); - return ( <TreeContext value={{ diff --git a/components/vc-tree/utils/treeUtil.ts b/components/vc-tree/utils/treeUtil.ts index f951ab9c7..6891c765c 100644 --- a/components/vc-tree/utils/treeUtil.ts +++ b/components/vc-tree/utils/treeUtil.ts @@ -402,8 +402,8 @@ export function convertNodePropsToEventData(props: TreeNodeProps): EventDataNode pos, active, } = props; - const eventData = { + dataRef: data, ...data, expanded, selected, @@ -416,7 +416,6 @@ export function convertNodePropsToEventData(props: TreeNodeProps): EventDataNode dragOverGapBottom, pos, active, - dataRef: data, eventKey: data.key, }; if (!('props' in eventData)) { diff --git a/examples/App.vue b/examples/App.vue index 6690b569d..2ba67e48d 100644 --- a/examples/App.vue +++ b/examples/App.vue @@ -1,40 +1,80 @@ <template> - <a-tree-select - v-model:value="value" - show-search - style="width: 100%" - :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" - placeholder="Please select" - allow-clear - multiple - tree-default-expand-all - > - <a-tree-select-node value="parent 1" title="parent 1"> - <a-tree-select-node value="parent 1-0" title="parent 1-0"> - <a-tree-select-node value="leaf1" title="my leaf" /> - <a-tree-select-node value="leaf2" title="your leaf" /> - </a-tree-select-node> - <a-tree-select-node value="parent 1-1" title="parent 1-1"> - <a-tree-select-node value="sss"> - <template #title><b style="color: #08c">sss</b></template> - </a-tree-select-node> - </a-tree-select-node> - </a-tree-select-node> - </a-tree-select> + <a-space direction="vertical" style="width: 100%"> + <a-tree-select + v-model:value="value" + show-search + style="width: 100%" + :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" + placeholder="Please select" + allow-clear + tree-default-expand-all + :tree-data="treeData" + > + <template #suffixIcon><SmileOutlined /></template> + </a-tree-select> + + <a-tree-select + v-model:value="value1" + show-search + style="width: 100%" + :dropdown-style="{ maxHeight: '400px', overflow: 'auto' }" + placeholder="Please select" + allow-clear + multiple + show-arrow + tree-default-expand-all + :tree-data="treeData" + > + <template #suffixIcon><SmileOutlined /></template> + </a-tree-select> + </a-space> </template> <script lang="ts"> +import { SmileOutlined } from '@ant-design/icons-vue'; +import { TreeSelectProps } from 'ant-design-vue'; import { defineComponent, ref, watch } from 'vue'; export default defineComponent({ + components: { + SmileOutlined, + }, setup() { const value = ref<string[]>([]); - + const value1 = ref<string[]>([]); + const treeData = ref<TreeSelectProps['treeData']>([ + { + title: 'parent 1', + value: 'parent 1', + children: [ + { + title: 'parent 1-0', + value: 'parent 1-0', + children: [ + { + title: 'my leaf', + value: 'leaf1', + }, + { + title: 'your leaf', + value: 'leaf2', + }, + ], + }, + { + title: 'parent 1-1', + value: 'parent 1-1', + }, + ], + }, + ]); watch(value, () => { console.log('select', value.value); }); return { value, + value1, + treeData, }; }, }); diff --git a/v2-doc b/v2-doc index 2e39bc81a..3f94a02d1 160000 --- a/v2-doc +++ b/v2-doc @@ -1 +1 @@ -Subproject commit 2e39bc81a84e2cfa90e8863e8f18d5a3d3ab1995 +Subproject commit 3f94a02d16bac2377d71e26948ffe45571dae49e