Skip to content

Commit

Permalink
feat(comp:tree-select): maxLabel support responsive (#814) (#823)
Browse files Browse the repository at this point in the history
  • Loading branch information
hangboss1761 committed Mar 25, 2022
1 parent 3b99839 commit df82e5d
Show file tree
Hide file tree
Showing 6 changed files with 77 additions and 34 deletions.
2 changes: 1 addition & 1 deletion packages/components/select/src/trigger/Selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
8 changes: 4 additions & 4 deletions packages/components/tree-select/docs/Index.zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -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` | ✅ | -
Expand Down Expand Up @@ -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}` | - |
Expand Down Expand Up @@ -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` | - | - |
<!--- insert less variable end --->
<!--- insert less variable end --->
6 changes: 3 additions & 3 deletions packages/components/tree-select/src/trigger/Item.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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<ItemProps> = (props, { slots }) => {
Expand All @@ -27,7 +27,7 @@ const Item: FunctionalComponent<ItemProps> = (props, { slots }) => {

const handleClick = (evt: Event) => {
evt.stopPropagation()
handleItemRemove(key)
handleItemRemove?.(key)
}

return (
Expand Down
86 changes: 62 additions & 24 deletions packages/components/tree-select/src/trigger/Selector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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<MergedNode & { isMax?: boolean }>
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)
})
Expand All @@ -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,
Expand All @@ -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 <Item {...itemProps}>{labelNode}</Item>
}
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 <Item {...itemProps}>{labelNode}</Item>
})
}

const singleItem = treeSelectProps.multiple ? null : selectedNodes.value.map(item => renderItem(item))

const overflowSlot = {
item: renderItem,
rest: renderRest,
suffix: () => <Input />,
}

return (
<label class={prefixCls}>
{showItems.value && itemNodes}
<Input></Input>
{treeSelectProps.multiple ? (
<ɵOverflow
v-slots={overflowSlot}
prefixCls={prefixCls}
dataSource={selectedNodes.value}
maxLabel={treeSelectProps.maxLabelCount ?? treeSelectProps.maxLabel}
getKey={(item: MergedNode) => item.key}
/>
) : (
<>
{showItems.value && singleItem}
<Input />
</>
)}
{showPlaceholder.value && (
<div class={`${prefixCls}-placeholder`}> {slots.placeholder?.() ?? treeSelectProps.placeholder}</div>
)}
Expand Down
5 changes: 3 additions & 2 deletions packages/components/tree-select/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ export const treeSelectProps = {
droppable: IxPropTypes.func<TreeDroppable>(),
empty: IxPropTypes.oneOfType([String, IxPropTypes.object<EmptyProps>()]),
expandIcon: IxPropTypes.string,
maxLabelCount: IxPropTypes.number.def(Number.MAX_SAFE_INTEGER),
maxLabelCount: IxPropTypes.oneOfType([IxPropTypes.number, IxPropTypes.oneOf(['responsive'])]),
maxLabel: IxPropTypes.oneOfType([IxPropTypes.number, IxPropTypes.oneOf(['responsive'])]).def(Number.MAX_SAFE_INTEGER),
multiple: IxPropTypes.bool.def(false),
labelKey: IxPropTypes.string,
leafLineIcon: IxPropTypes.string,
Expand All @@ -61,7 +62,7 @@ export const treeSelectProps = {
'onUpdate:expandedKeys': IxPropTypes.emit<(keys: VKey[]) => void>(),
'onUpdate:loadedKeys': IxPropTypes.emit<(keys: VKey[]) => void>(),
onCheck: IxPropTypes.emit<(checked: boolean, node: TreeSelectNode) => void>(),
onChange: IxPropTypes.emit<(value: any, oldValue: any, node: TreeSelectNode | TreeSelectNode[]) => void>(),
onChange: IxPropTypes.emit<(value: any, oldValue: any, node?: TreeSelectNode | TreeSelectNode[]) => void>(),
onClear: IxPropTypes.emit<(evt: Event) => void>(),
onDragstart: IxPropTypes.emit<(options: TreeDragDropOptions) => void>(),
onDragend: IxPropTypes.emit<(options: TreeDragDropOptions) => void>(),
Expand Down
4 changes: 4 additions & 0 deletions packages/components/tree-select/style/multiple.less
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@
line-height: @tree-select-item-line-height;
}
}

&-overflow {
line-height: @tree-select-item-height;
}
}

&.@{tree-select-prefix}-with-suffix .@{tree-select-prefix}-selector,
Expand Down

0 comments on commit df82e5d

Please sign in to comment.