Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(comp:tree-select): maxLabel support responsive (#814) #823

Merged
merged 1 commit into from
Mar 25, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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