From df82e5d4a61a3cd8bc064a448ea22502eb94967a Mon Sep 17 00:00:00 2001 From: hangboss1761 <1240123692@qq.com> Date: Fri, 25 Mar 2022 10:09:18 +0800 Subject: [PATCH] feat(comp:tree-select): maxLabel support responsive (#814) (#823) --- .../select/src/trigger/Selector.tsx | 2 +- .../components/tree-select/docs/Index.zh.md | 8 +- .../tree-select/src/trigger/Item.tsx | 6 +- .../tree-select/src/trigger/Selector.tsx | 86 +++++++++++++------ packages/components/tree-select/src/types.ts | 5 +- .../tree-select/style/multiple.less | 4 + 6 files changed, 77 insertions(+), 34 deletions(-) diff --git a/packages/components/select/src/trigger/Selector.tsx b/packages/components/select/src/trigger/Selector.tsx index 3f448578d..eb5dc3e05 100644 --- a/packages/components/select/src/trigger/Selector.tsx +++ b/packages/components/select/src/trigger/Selector.tsx @@ -90,7 +90,7 @@ export default defineComponent({ title: label, } - const selectedLabelSlot = slots.label ?? slots.selectedLabel + const selectedLabelSlot = slots.selectedLabel ?? slots.label const labelNode: VNodeChild | undefined = selectedLabelSlot ? selectedLabelSlot(rawOption) : renderOptionLabel(slots, rawOption, label) diff --git a/packages/components/tree-select/docs/Index.zh.md b/packages/components/tree-select/docs/Index.zh.md index 06778c018..63532203b 100644 --- a/packages/components/tree-select/docs/Index.zh.md +++ b/packages/components/tree-select/docs/Index.zh.md @@ -33,7 +33,7 @@ order: 0 | `droppable` | 是否允许放置节点,参见[TreeDroppable](/components/tree/zh#TreeDroppable) | `TreeDroppable` | - | - | - | | `empty` | 空数据时的内容 | `string \|` [EmptyProps](/components/empty/zh#EmptyProps) | - | - | - | | `expandIcon` | 树组件中的展开图标 | `string` | `right` | ✅ | - | -| `maxLabelCount` | 最多显示多少个标签 | `number` | - | - | - | +| `maxLabel` | 最多显示多少个标签,响应式模式会对性能产生损耗 | `number \| 'responsive'` | - | - | - | | `multiple` | 多选模式 | `boolean` | `false` | - | - | | `nodeKey` | 替代[TreeSelectNode](#TreeSelectNode)中的`key`字段 | `string \| (node: TreeSelectNode) => VKey` | `key` | ✅ | - | `labelKey` | 替代[TreeSelectNode](#TreeSelectNode)中的`label`字段 | `string` | `label` | ✅ | - @@ -89,9 +89,9 @@ order: 0 | --- | --- | --- | --- | | `empty` | 自定义当下拉列表为空时显示的内容 | - | - | | `expandIcon` | 节点展开图标 | `{key: VKey, expanded: boolean, node: TreeSelectNode}` | - | -| `label` | 自定义选中的标签 | `{node: RawNode}` | `RawNode`为用户传入的数据结构 | +| `selectedLabel` | 自定义选中的标签 | `{node: RawNode}` | `RawNode`为用户传入的数据结构 | | `leafLineIcon` | 叶子节点的图标,用于替换默认的连接线 | - | 仅在 `showLine 时生效` | -| `maxLabel` | 自定义超出最多显示多少个标签的内容 | `{nodes: RawNode[]}` | 参数为超出的数组 | +| `overflowedLabel` | 自定义超出最多显示多少个标签的内容 | `{nodes: RawNode[]}` | 参数为超出的数组 | | `suffix` | 后缀图标 | - | - | | `placeholder` | 选择框默认文本 | - | - | | `treeLabel` | 自定义节点的文本 | `{node: TreeSelectNode}` | - | @@ -169,4 +169,4 @@ order: 0 | `@tree-select-multiple-item-border-radius` | `@tree-select-border-radius` | - | - | | `@tree-select-multiple-item-label-margin-left` | `@spacing-xs` | - | - | | `@tree-select-multiple-item-remove-icon-font-size` | `@font-size-xs` | - | - | - \ No newline at end of file + diff --git a/packages/components/tree-select/src/trigger/Item.tsx b/packages/components/tree-select/src/trigger/Item.tsx index 1021b5466..6c2bc4eee 100644 --- a/packages/components/tree-select/src/trigger/Item.tsx +++ b/packages/components/tree-select/src/trigger/Item.tsx @@ -15,8 +15,8 @@ import { useKey } from '@idux/components/utils' interface ItemProps { disabled?: boolean prefixCls: string - removable: boolean - handleItemRemove: (key: any) => void + removable?: boolean + handleItemRemove?: (key: any) => void } const Item: FunctionalComponent = (props, { slots }) => { @@ -27,7 +27,7 @@ const Item: FunctionalComponent = (props, { slots }) => { const handleClick = (evt: Event) => { evt.stopPropagation() - handleItemRemove(key) + handleItemRemove?.(key) } return ( diff --git a/packages/components/tree-select/src/trigger/Selector.tsx b/packages/components/tree-select/src/trigger/Selector.tsx index 4779b0802..352f8c973 100644 --- a/packages/components/tree-select/src/trigger/Selector.tsx +++ b/packages/components/tree-select/src/trigger/Selector.tsx @@ -6,10 +6,12 @@ */ import type { MergedNode } from '../composables/useDataSource' -import type { VNodeTypes } from 'vue' +import type { VNodeChild } from 'vue' import { computed, defineComponent, inject } from 'vue' +import { Logger } from '@idux/cdk/utils' +import { ɵOverflow } from '@idux/components/_private/overflow' import { IxIcon } from '@idux/components/icon' import { treeSelectToken } from '../token' @@ -32,18 +34,6 @@ export default defineComponent({ searchValue, } = inject(treeSelectToken)! - const selectedItems = computed(() => { - const { maxLabelCount } = treeSelectProps - const nodes = selectedNodes.value - const items = nodes.slice(0, maxLabelCount) as Array - if (nodes.length > maxLabelCount) { - const label = `+ ${nodes.length - maxLabelCount} ...` - const key = nodes.slice(maxLabelCount).map(node => node.rawNode) - items.push({ isMax: true, key, label } as unknown as MergedNode & { isMax?: boolean }) - } - return items - }) - const showItems = computed(() => { return treeSelectProps.multiple || (selectedValue.value.length > 0 && !searchValue.value) }) @@ -59,10 +49,26 @@ export default defineComponent({ const prefixCls = `${mergedPrefixCls.value}-selector` const itemPrefixCls = `${prefixCls}-item` - const itemNodes = selectedItems.value.map(item => { - const { key, isMax, label } = item + + if (__DEV__ && treeSelectProps.maxLabelCount) { + Logger.warn('components/treeSelect', '`maxLabelCount` was deprecated, please use `maxLabel` instead') + } + + if (__DEV__ && slots.maxLabel) { + Logger.warn( + 'components/treeSelect', + 'slot `maxLabel` was deprecated, please use slot `overflowedLabel` instead', + ) + } + + if (__DEV__ && slots.label) { + Logger.warn('components/treeSelect', 'slots `label` was deprecated, please use slots `selectedLabel` instead') + } + + const renderItem = (item: MergedNode) => { + const { key, label, rawNode } = item const _disabled = disabled || item.selectDisabled - const removable = multiple && !_disabled && !readonly && !isMax + const removable = multiple && !_disabled && !readonly const itemProps = { key, @@ -72,19 +78,51 @@ export default defineComponent({ title: label, handleItemRemove, } - let labelNode: VNodeTypes | undefined - if (isMax) { - labelNode = slots.maxLabel?.(item.key) ?? label - } else { - labelNode = slots.label?.(item.rawNode) ?? label + + const selectedLabelSlot = slots.selectedLabel ?? slots.label + const labelNode: VNodeChild | undefined = selectedLabelSlot ? selectedLabelSlot(rawNode) : label + + return {labelNode} + } + const renderRest = (rest: MergedNode[]) => { + const key = 'IDUX_TREE_SELECT_MAX_ITEM' + + const itemProps = { + key, + prefixCls: itemPrefixCls, + removable: false, } + + const overflowedLabelSlot = slots.overflowedLabel ?? slots.maxLabel + const labelNode: VNodeChild | undefined = overflowedLabelSlot?.(rest) ?? `+ ${rest.length} ...` + return {labelNode} - }) + } + + const singleItem = treeSelectProps.multiple ? null : selectedNodes.value.map(item => renderItem(item)) + + const overflowSlot = { + item: renderItem, + rest: renderRest, + suffix: () => , + } return (