feat(components): [select/select-v2] add tag-tooltip config object prop (#23556)

* feat(components): [select] add collapseTagsTooltipAppendTo & test

Add collapseTagsTooltipAppendTo prop to control where the collapse-tags tooltip is appended. Wire it
to the tag tooltip with fallback to appendTo. Add unit test to verify prop is passed correctly.

* docs(docs): add collapseTagsTooltipAppendTo doc

* refactor(components): [select]rename collapseTagsTooltipAppendTo prop

Rename collapseTagsTooltipAppendTo to tooltipAppendTo
Simplify the prop name by removing redundant context
Behavior remains unchanged

* docs(components): [select] add version tag for tooltipAppendTo prop

* Update packages/components/select/__tests__/select.test.ts

Co-authored-by: rzzf <cszhjh@gmail.com>

* feat(components): [select] add tagTooltip config object

Add TagTooltip to support appendTo, placement, fallbackPlacements, effect, popperClass, popperStyle,
teleported, popperOptions, showAfter, and offsetWire all tagTooltip properties to the collapse-tags
tooltip with fallback to existing select propsProvides more granular control over tooltip behavior
while maintaining backward compatibility

* docs(components): [select] add tag-tooltip config object doc

* docs(components): [select] add default value for fallback-placements

* docs(components): [select]  update tag-tooltip default value to {}

* docs(components): [select]remove string type from TagTooltipProps effect

* docs(components): [select] add fallback mechanism tip for tag-tooltip

* feat(components): [select] extend TagTooltipProps

Add transition, hideAfter, and autoClose properties to TagTooltipProps

Update popperStyle type to accept both string and CSSProperties

* docs(components): [select] enhance tag-tooltip documentation

Add transition, hide-after, and auto-close properties to TagTooltip API table

Clarify fallback mechanism with priority order explanation

Add custom container positioning tip for append-to usage

* docs(components): [select] refine tag-tooltip priority description

Co-authored-by: keeplearning66 <1256734885@qq.com>

* docs(components): [select] refine effect prop type in tag-tooltip

Co-authored-by: keeplearning66 <1256734885@qq.com>

* chore: format

* docs: apply rabbit comment

* feat(components): [select-v2] add TagTooltipProps interface

Add TagTooltipProps interface with popper configuration options

* feat(components): [select-v2] implement tagTooltip prop

* test(components): [select-v2] add tag-tooltip prop test case

Add test case to verify tagTooltip prop functionality with appendTo option

* docs(components): [select-v2] add tag-tooltip API documentation

Add tag-tooltip configuration object to Select V2 API table

Add comprehensive tag-tooltip properties section with fallback mechanism explanation and custom
container positioning tip

* docs(components): [select-v2] add version tag to tag-tooltip prop

* fix(components): [select-v2] Optional chain tagTooltip access

* fix(components): [select] optional chain tagTooltip access

* feat(components): [select-v2] Fix tooltip teleport timing

* docs(components): [select-v] add version tag for tag-tooltip

Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com>

* docs(components): [select] add version tag for tag-tooltip

Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com>

---------

Co-authored-by: rzzf <cszhjh@gmail.com>
Co-authored-by: keeplearning66 <1256734885@qq.com>
Co-authored-by: Noblet Ouways <91417411+Dsaquel@users.noreply.github.com>
This commit is contained in:
lostElk
2026-02-14 07:00:16 +08:00
committed by GitHub
parent 5a997a62c5
commit 2b1ab441e3
8 changed files with 342 additions and 132 deletions

View File

@@ -235,63 +235,64 @@ select-v2/custom-width
### Attributes
| Name | Description | Type | Default |
| ----------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| model-value / v-model | binding value | ^[string] / ^[number] / ^[boolean] / ^[object] / ^[array] | — |
| options | data of the options, the key of `value` and `label` can be customize by `props` | ^[array] | — |
| [props](#props) ^(2.4.2) | configuration options, see the following table | ^[object] | — |
| multiple | is multiple | ^[boolean] | false |
| disabled | is disabled | ^[boolean] | false |
| value-key | unique identity key name for value, required when value is an object | ^[string] | value |
| size | size of component | ^[enum]`'' \| 'large' \| 'default' \| 'small'` | '' |
| clearable | whether select can be cleared | ^[boolean] | false |
| clear-icon | custom clear icon | ^[string] / ^[object]`Component` | CircleClose |
| collapse-tags | whether to collapse tags to a text when multiple selecting | ^[boolean] | false |
| multiple-limit | maximum number of options user can select when multiple is true. No limit when set to 0 | ^[number] | 0 |
| id | native input id input | ^[string] | — |
| name | the name attribute of select input | ^[string] | — |
| effect | tooltip theme, built-in theme: `dark` / `light` | ^[enum]`'dark' \| 'light'` / ^[string] | light |
| autocomplete | autocomplete of select input | ^[string] | off |
| placeholder | placeholder | ^[string] | Please select |
| filterable | whether Select is filterable | ^[boolean] | false |
| allow-create | whether creating new items is allowed. To use this, `filterable` must be true | ^[boolean] | false |
| filter-method | custom filter method, the first parameter is the current input value. To use this, `filterable` must be true method | ^[Function]`(query: string) => void` | — |
| loading | whether Select is loading data from server | ^[boolean] | false |
| loading-text | displayed text while loading data from server, default is 'Loading' | ^[string] | — |
| reserve-keyword | whether reserve the keyword after select filtered option. | ^[boolean] | true |
| default-first-option | select first matching option on enter key. Use with `filterable` or `remote` | ^[boolean] | false |
| no-match-text | displayed text when no data matches the filtering query, you can also use slot `empty`, default is 'No matching data' | ^[string] | — |
| no-data-text | displayed text when there is no options, you can also use slot empty | ^[string] | No Data |
| popper-class | custom class name for Select's dropdown and tags' tooltip | ^[string] / ^[object] | '' |
| popper-style ^(2.11.0) | custom style for Select's dropdown and tags' tooltip | ^[string] / ^[object] | — |
| teleported | whether select dropdown is teleported, if `true` it will be teleported to where `append-to` sets | ^[boolean] | true |
| append-to ^(2.8.8) | which element the select dropdown appends to | ^[CSSSelector] / ^[HTMLElement] | — |
| persistent | when select dropdown is inactive and `persistent` is `false`, select dropdown will be destroyed | ^[boolean] | true |
| popper-options | [popper.js](https://popper.js.org/docs/v2/) parameters | ^[object]refer to [popper.js](https://popper.js.org/docs/v2/) doc | {} |
| automatic-dropdown | for non-filterable Select, this prop decides if the option menu pops up when the input is focused | ^[boolean] | false |
| fit-input-width ^(2.9.2) | whether the width of the dropdown is the same as the input, if the value is `number`, then the width is fixed | ^[boolean] / ^[number] | true |
| suffix-icon ^(2.9.8) | custom suffix icon component | ^[string] / ^[object]`Component` | ArrowDown |
| height | The height of the dropdown panel, 34px for each item | ^[number] | 274 |
| item-height | The height of the dropdown item | ^[number] | 34 |
| scrollbar-always-on | Controls whether the scrollbar is always displayed | ^[boolean] | false |
| remote | whether search data from server | ^[boolean] | false |
| debounce ^(2.11.7) | debounce delay during remote search, in milliseconds | ^[number] | 300 |
| remote-method | function that gets called when the input value changes. Its parameter is the current input value. To use this, `filterable` must be true | ^[Function]`(query: string) => void` | — |
| remote-show-suffix ^(2.11.9) | in remote search method show suffix icon | ^[boolean] | false |
| validate-event | whether to trigger form validation | ^[boolean] | true |
| offset ^(2.8.8) | offset of the dropdown | ^[number] | 12 |
| show-arrow ^(2.8.8) | whether the dropdown has an arrow | ^[boolean] | true |
| placement | position of dropdown | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | bottom-start |
| fallback-placements ^(2.5.6) | list of possible positions for dropdown [popper.js](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements) | ^[array]`Placement[]` | ['bottom-start', 'top-start', 'right', 'left'] |
| collapse-tags-tooltip ^(2.3.0) | whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true | ^[boolean] | false |
| max-collapse-tags ^(2.3.0) | The max tags number to be shown. To use this, `collapse-tags` must be true | ^[number] | 1 |
| tag-type ^(2.5.0) | tag type | ^[enum]`'' \| 'success' \| 'info' \| 'warning' \| 'danger'` | info |
| tag-effect ^(2.7.7) | tag effect | ^[enum]`'' \| 'light' \| 'dark' \| 'plain'` | light |
| aria-label ^(a11y) ^(2.5.0) | same as `aria-label` in native input | ^[string] | |
| empty-values ^(2.7.0) | empty values of component, [see config-provider](./config-provider.md#empty-values-configurations) | ^[array] | — |
| value-on-clear ^(2.7.0) | clear return value, [see config-provider](./config-provider.md#empty-values-configurations) | ^[string] / ^[number] / ^[boolean] / ^[Function] | — |
| popper-append-to-body ^(deprecated) | whether to append the popper menu to body. If the positioning of the popper is wrong, you can try to set this prop to false | ^[boolean] | false |
| tabindex ^(2.9.0) | tabindex for input | ^[string] / ^[number] | |
| Name | Description | Type | Default |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| model-value / v-model | binding value | ^[string] / ^[number] / ^[boolean] / ^[object] / ^[array] | — |
| options | data of the options, the key of `value` and `label` can be customize by `props` | ^[array] | — |
| [props](#props) ^(2.4.2) | configuration options, see the following table | ^[object] | — |
| multiple | is multiple | ^[boolean] | false |
| disabled | is disabled | ^[boolean] | false |
| value-key | unique identity key name for value, required when value is an object | ^[string] | value |
| size | size of component | ^[enum]`'' \| 'large' \| 'default' \| 'small'` | '' |
| clearable | whether select can be cleared | ^[boolean] | false |
| clear-icon | custom clear icon | ^[string] / ^[object]`Component` | CircleClose |
| collapse-tags | whether to collapse tags to a text when multiple selecting | ^[boolean] | false |
| multiple-limit | maximum number of options user can select when multiple is true. No limit when set to 0 | ^[number] | 0 |
| id | native input id input | ^[string] | — |
| name | the name attribute of select input | ^[string] | — |
| effect | tooltip theme, built-in theme: `dark` / `light` | ^[enum]`'dark' \| 'light'` / ^[string] | light |
| autocomplete | autocomplete of select input | ^[string] | off |
| placeholder | placeholder | ^[string] | Please select |
| filterable | whether Select is filterable | ^[boolean] | false |
| allow-create | whether creating new items is allowed. To use this, `filterable` must be true | ^[boolean] | false |
| filter-method | custom filter method, the first parameter is the current input value. To use this, `filterable` must be true method | ^[Function]`(query: string) => void` | — |
| loading | whether Select is loading data from server | ^[boolean] | false |
| loading-text | displayed text while loading data from server, default is 'Loading' | ^[string] | — |
| reserve-keyword | whether reserve the keyword after select filtered option. | ^[boolean] | true |
| default-first-option | select first matching option on enter key. Use with `filterable` or `remote` | ^[boolean] | false |
| no-match-text | displayed text when no data matches the filtering query, you can also use slot `empty`, default is 'No matching data' | ^[string] | — |
| no-data-text | displayed text when there is no options, you can also use slot empty | ^[string] | No Data |
| popper-class | custom class name for Select's dropdown and tags' tooltip | ^[string] / ^[object] | '' |
| popper-style ^(2.11.0) | custom style for Select's dropdown and tags' tooltip | ^[string] / ^[object] | — |
| teleported | whether select dropdown is teleported, if `true` it will be teleported to where `append-to` sets | ^[boolean] | true |
| append-to ^(2.8.8) | which element the select dropdown appends to | ^[CSSSelector] / ^[HTMLElement] | — |
| persistent | when select dropdown is inactive and `persistent` is `false`, select dropdown will be destroyed | ^[boolean] | true |
| popper-options | [popper.js](https://popper.js.org/docs/v2/) parameters | ^[object]refer to [popper.js](https://popper.js.org/docs/v2/) doc | {} |
| automatic-dropdown | for non-filterable Select, this prop decides if the option menu pops up when the input is focused | ^[boolean] | false |
| fit-input-width ^(2.9.2) | whether the width of the dropdown is the same as the input, if the value is `number`, then the width is fixed | ^[boolean] / ^[number] | true |
| suffix-icon ^(2.9.8) | custom suffix icon component | ^[string] / ^[object]`Component` | ArrowDown |
| height | The height of the dropdown panel, 34px for each item | ^[number] | 274 |
| item-height | The height of the dropdown item | ^[number] | 34 |
| scrollbar-always-on | Controls whether the scrollbar is always displayed | ^[boolean] | false |
| remote | whether search data from server | ^[boolean] | false |
| debounce ^(2.11.7) | debounce delay during remote search, in milliseconds | ^[number] | 300 |
| remote-method | function that gets called when the input value changes. Its parameter is the current input value. To use this, `filterable` must be true | ^[Function]`(query: string) => void` | — |
| remote-show-suffix ^(2.11.9) | in remote search method show suffix icon | ^[boolean] | false |
| validate-event | whether to trigger form validation | ^[boolean] | true |
| offset ^(2.8.8) | offset of the dropdown | ^[number] | 12 |
| show-arrow ^(2.8.8) | whether the dropdown has an arrow | ^[boolean] | true |
| placement | position of dropdown | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | bottom-start |
| fallback-placements ^(2.5.6) | list of possible positions for dropdown [popper.js](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements) | ^[array]`Placement[]` | ['bottom-start', 'top-start', 'right', 'left'] |
| collapse-tags-tooltip ^(2.3.0) | whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true | ^[boolean] | false |
| [tag-tooltip](#tag-tooltip) ^(2.13.3) | configuration object for the collapse-tags tooltip. To use this, `collapse-tags` and `collapse-tags-tooltip` must be true | ^[object]`TagTooltipProps` | {} |
| max-collapse-tags ^(2.3.0) | The max tags number to be shown. To use this, `collapse-tags` must be true | ^[number] | 1 |
| tag-type ^(2.5.0) | tag type | ^[enum]`'' \| 'success' \| 'info' \| 'warning' \| 'danger'` | info |
| tag-effect ^(2.7.7) | tag effect | ^[enum]`'' \| 'light' \| 'dark' \| 'plain'` | light |
| aria-label ^(a11y) ^(2.5.0) | same as `aria-label` in native input | ^[string] | — |
| empty-values ^(2.7.0) | empty values of component, [see config-provider](./config-provider.md#empty-values-configurations) | ^[array] | — |
| value-on-clear ^(2.7.0) | clear return value, [see config-provider](./config-provider.md#empty-values-configurations) | ^[string] / ^[number] / ^[boolean] / ^[Function] | — |
| popper-append-to-body ^(deprecated) | whether to append the popper menu to body. If the positioning of the popper is wrong, you can try to set this prop to false | ^[boolean] | false |
| tabindex ^(2.9.0) | tabindex for input | ^[string] / ^[number] | — |
### props
@@ -302,6 +303,41 @@ select-v2/custom-width
| options | specify which key of node object is used as the node's children | ^[string] | options |
| disabled | specify which key of node object is used as the node's disabled | ^[string] | disabled |
### tag-tooltip ^(2.13.3)
:::tip Fallback Mechanism
Properties in tag-tooltip follow this priority order:
1. Explicitly defined fields within the tag-tooltip object.
2. Shared props inherited from el-select-v2 (e.g. effect, popper-class, popper-style, teleported, append-to, popper-options).
3. Default values of the underlying el-tooltip component.
This allows you to override specific tooltip behaviors for tags while maintaining consistency with the Select dropdown by default.
:::
:::tip Custom Container Positioning
When appending the Tooltip to a custom container (via the `append-to` attribute), the container should be configured with `position: relative` or `position: absolute` to ensure accurate positioning. Additionally, you can apply `overflow: hidden` to the container if you need to prevent the Tooltip from overflowing its boundaries.
:::
| Attribute | Description | Type | Default |
| ------------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| append-to | which element the tooltip CONTENT appends to | ^[CSSSelector] / ^[HTMLElement] | — |
| placement | position of Tooltip | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | bottom |
| fallback-placements | list of possible positions for Tooltip [popper.js](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements) | ^[array]`Placement[]` | ['bottom', 'top', 'right', 'left'] |
| effect | Tooltip theme, built-in theme: `dark` / `light` | ^[enum]`'dark' \| 'light'` / ^[string] | — |
| popper-class | custom class name for Tooltip's popper | ^[string] | — |
| popper-style | custom style for Tooltip's popper | ^[string] / ^[object] | — |
| transition | animation name | ^[string] | — |
| teleported | whether tooltip content is teleported, if `true` it will be teleported to where `append-to` sets | ^[boolean] | — |
| popper-options | [popper.js](https://popper.js.org/docs/v2/) parameters | ^[object]refer to [popper.js](https://popper.js.org/docs/v2/) doc | — |
| show-after | delay of appearance, in millisecond | ^[number] | — |
| hide-after | delay of disappear, in millisecond | ^[number] | — |
| auto-close | timeout in milliseconds to hide tooltip | ^[number] | — |
| offset | offset of the Tooltip | ^[number] | — |
### Events
| Name | Description | Type |

View File

@@ -201,60 +201,61 @@ select/custom-label
### Select Attributes
| Name | Description | Type | Default |
| ------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| model-value / v-model | binding value | ^[string] / ^[number] / ^[boolean] / ^[object] / ^[array] | — |
| multiple | whether multiple-select is activated | ^[boolean] | false |
| options ^(2.10.5) | data of the options, the key of `value` and `label` and `disabled` can be customize by `props` | ^[array]`Array<{[key: string]: any}>` | — |
| [props](#props) ^(2.10.5) | configuration options | ^[object] | — |
| disabled | whether Select is disabled | ^[boolean] | false |
| value-key | unique identity key name for value, required when value is an object | ^[string] | value |
| size | size of Input | ^[enum]`'' \| 'large' \| 'default' \| 'small'` | — |
| clearable | whether select can be cleared | ^[boolean] | false |
| collapse-tags | whether to collapse tags to a text when multiple selecting | ^[boolean] | false |
| collapse-tags-tooltip ^(2.3.0) | whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true | ^[boolean] | false |
| multiple-limit | maximum number of options user can select when `multiple` is `true`. No limit when set to 0 | ^[number] | 0 |
| id | native input id input | ^[string] | |
| name | the name attribute of select input | ^[string] | — |
| effect | tooltip theme, built-in theme: `dark` / `light` | ^[enum]`'dark' \| 'light'` / ^[string] | light |
| autocomplete | the autocomplete attribute of select input | ^[string] | off |
| placeholder | placeholder, default is 'Select' | ^[string] | |
| filterable | whether Select is filterable | ^[boolean] | false |
| allow-create | whether creating new items is allowed. To use this, `filterable` must be true | ^[boolean] | false |
| filter-method | custom filter method, the first parameter is the current input value. To use this, `filterable` must be true | ^[Function]`(query: string) => void` | |
| remote | whether options are loaded from server | ^[boolean] | false |
| debounce ^(2.11.7) | debounce delay during remote search, in milliseconds | ^[number] | 300 |
| remote-method | function that gets called when the input value changes. Its parameter is the current input value. To use this, `filterable` must be true | ^[Function]`(query: string) => void` | |
| remote-show-suffix | in remote search method show suffix icon | ^[boolean] | false |
| loading | whether Select is loading data from server | ^[boolean] | false |
| loading-text | displayed text while loading data from server, default is 'Loading' | ^[string] | |
| no-match-text | displayed text when no data matches the filtering query, you can also use slot `empty`, default is 'No matching data' | ^[string] | — |
| no-data-text | displayed text when there is no options, you can also use slot `empty`, default is 'No data' | ^[string] | — |
| popper-class | custom class name for Select's dropdown and tags' tooltip | ^[string] | '' |
| popper-style ^(2.11.0) | custom style for Select's dropdown and tags' tooltip | ^[string] / ^[object] | |
| reserve-keyword | when `multiple` and `filterable` is true, whether to reserve current keyword after selecting an option | ^[boolean] | true |
| default-first-option | select first matching option on enter key. Use with `filterable` or `remote` | ^[boolean] | false |
| teleported | whether select dropdown is teleported, if `true` it will be teleported to where `append-to` sets | ^[boolean] | true |
| append-to ^(2.8.4) | which element the select dropdown appends to | ^[CSSSelector] / ^[HTMLElement] | |
| persistent | when select dropdown is inactive and `persistent` is `false`, select dropdown will be destroyed | ^[boolean] | true |
| automatic-dropdown | for non-filterable Select, this prop decides if the option menu pops up when the input is focused | ^[boolean] | false |
| clear-icon | custom clear icon component | ^[string] / ^[object]`Component` | CircleClose |
| fit-input-width | whether the width of the dropdown is the same as the input | ^[boolean] | false |
| suffix-icon | custom suffix icon component | ^[string] / ^[object]`Component` | ArrowDown |
| tag-type | tag type | ^[enum]`'' \| 'success' \| 'info' \| 'warning' \| 'danger'` | info |
| tag-effect ^(2.7.7) | tag effect | ^[enum]`'' \| 'light' \| 'dark' \| 'plain'` | light |
| validate-event | whether to trigger form validation | ^[boolean] | true |
| offset ^(2.8.8) | offset of the dropdown | ^[number] | 12 |
| show-arrow ^(2.8.8) | whether the dropdown has an arrow | ^[boolean] | true |
| placement ^(2.2.17) | position of dropdown | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | bottom-start |
| fallback-placements ^(2.5.6) | list of possible positions for dropdown [popper.js](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements) | ^[array]`Placement[]` | ['bottom-start', 'top-start', 'right', 'left'] |
| max-collapse-tags ^(2.3.0) | the max tags number to be shown. To use this, `collapse-tags` must be true | ^[number] | 1 |
| popper-options | [popper.js](https://popper.js.org/docs/v2/) parameters | ^[object]refer to [popper.js](https://popper.js.org/docs/v2/) doc | {} |
| aria-label ^(a11y) | same as `aria-label` in native input | ^[string] | |
| empty-values ^(2.7.0) | empty values of component, [see config-provider](./config-provider.md#empty-values-configurations) | ^[array] | — |
| value-on-clear ^(2.7.0) | clear return value, [see config-provider](./config-provider.md#empty-values-configurations) | ^[string] / ^[number] / ^[boolean] / ^[Function] | — |
| suffix-transition ^(deprecated) | animation when dropdown appears/disappears icon | ^[boolean] | true |
| tabindex ^(2.9.0) | tabindex for input | ^[string] / ^[number] | |
| Name | Description | Type | Default |
| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------- |
| model-value / v-model | binding value | ^[string] / ^[number] / ^[boolean] / ^[object] / ^[array] | — |
| multiple | whether multiple-select is activated | ^[boolean] | false |
| options ^(2.10.5) | data of the options, the key of `value` and `label` and `disabled` can be customize by `props` | ^[array]`Array<{[key: string]: any}>` | — |
| [props](#props) ^(2.10.5) | configuration options | ^[object] | — |
| disabled | whether Select is disabled | ^[boolean] | false |
| value-key | unique identity key name for value, required when value is an object | ^[string] | value |
| size | size of Input | ^[enum]`'' \| 'large' \| 'default' \| 'small'` | — |
| clearable | whether select can be cleared | ^[boolean] | false |
| collapse-tags | whether to collapse tags to a text when multiple selecting | ^[boolean] | false |
| collapse-tags-tooltip ^(2.3.0) | whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true | ^[boolean] | false |
| [tag-tooltip](#tag-tooltip) ^(2.13.3) | configuration object for the collapse-tags tooltip. To use this, `collapse-tags` and `collapse-tags-tooltip` must be true | ^[object]`TagTooltipProps` | {} |
| multiple-limit | maximum number of options user can select when `multiple` is `true`. No limit when set to 0 | ^[number] | 0 |
| id | native input id input | ^[string] | — |
| name | the name attribute of select input | ^[string] | — |
| effect | tooltip theme, built-in theme: `dark` / `light` | ^[enum]`'dark' \| 'light'` / ^[string] | light |
| autocomplete | the autocomplete attribute of select input | ^[string] | off |
| placeholder | placeholder, default is 'Select' | ^[string] | |
| filterable | whether Select is filterable | ^[boolean] | false |
| allow-create | whether creating new items is allowed. To use this, `filterable` must be true | ^[boolean] | false |
| filter-method | custom filter method, the first parameter is the current input value. To use this, `filterable` must be true | ^[Function]`(query: string) => void` | |
| remote | whether options are loaded from server | ^[boolean] | false |
| debounce ^(2.11.7) | debounce delay during remote search, in milliseconds | ^[number] | 300 |
| remote-method | function that gets called when the input value changes. Its parameter is the current input value. To use this, `filterable` must be true | ^[Function]`(query: string) => void` | |
| remote-show-suffix | in remote search method show suffix icon | ^[boolean] | false |
| loading | whether Select is loading data from server | ^[boolean] | false |
| loading-text | displayed text while loading data from server, default is 'Loading' | ^[string] | — |
| no-match-text | displayed text when no data matches the filtering query, you can also use slot `empty`, default is 'No matching data' | ^[string] | — |
| no-data-text | displayed text when there is no options, you can also use slot `empty`, default is 'No data' | ^[string] | |
| popper-class | custom class name for Select's dropdown and tags' tooltip | ^[string] | '' |
| popper-style ^(2.11.0) | custom style for Select's dropdown and tags' tooltip | ^[string] / ^[object] | |
| reserve-keyword | when `multiple` and `filterable` is true, whether to reserve current keyword after selecting an option | ^[boolean] | true |
| default-first-option | select first matching option on enter key. Use with `filterable` or `remote` | ^[boolean] | false |
| teleported | whether select dropdown is teleported, if `true` it will be teleported to where `append-to` sets | ^[boolean] | true |
| append-to ^(2.8.4) | which element the select dropdown appends to | ^[CSSSelector] / ^[HTMLElement] | |
| persistent | when select dropdown is inactive and `persistent` is `false`, select dropdown will be destroyed | ^[boolean] | true |
| automatic-dropdown | for non-filterable Select, this prop decides if the option menu pops up when the input is focused | ^[boolean] | false |
| clear-icon | custom clear icon component | ^[string] / ^[object]`Component` | CircleClose |
| fit-input-width | whether the width of the dropdown is the same as the input | ^[boolean] | false |
| suffix-icon | custom suffix icon component | ^[string] / ^[object]`Component` | ArrowDown |
| tag-type | tag type | ^[enum]`'' \| 'success' \| 'info' \| 'warning' \| 'danger'` | info |
| tag-effect ^(2.7.7) | tag effect | ^[enum]`'' \| 'light' \| 'dark' \| 'plain'` | light |
| validate-event | whether to trigger form validation | ^[boolean] | true |
| offset ^(2.8.8) | offset of the dropdown | ^[number] | 12 |
| show-arrow ^(2.8.8) | whether the dropdown has an arrow | ^[boolean] | true |
| placement ^(2.2.17) | position of dropdown | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | bottom-start |
| fallback-placements ^(2.5.6) | list of possible positions for dropdown [popper.js](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements) | ^[array]`Placement[]` | ['bottom-start', 'top-start', 'right', 'left'] |
| max-collapse-tags ^(2.3.0) | the max tags number to be shown. To use this, `collapse-tags` must be true | ^[number] | 1 |
| popper-options | [popper.js](https://popper.js.org/docs/v2/) parameters | ^[object]refer to [popper.js](https://popper.js.org/docs/v2/) doc | {} |
| aria-label ^(a11y) | same as `aria-label` in native input | ^[string] | — |
| empty-values ^(2.7.0) | empty values of component, [see config-provider](./config-provider.md#empty-values-configurations) | ^[array] | — |
| value-on-clear ^(2.7.0) | clear return value, [see config-provider](./config-provider.md#empty-values-configurations) | ^[string] / ^[number] / ^[boolean] / ^[Function] | |
| suffix-transition ^(deprecated) | animation when dropdown appears/disappears icon | ^[boolean] | true |
| tabindex ^(2.9.0) | tabindex for input | ^[string] / ^[number] | — |
:::warning
@@ -271,6 +272,41 @@ select/custom-label
| options ^(2.11.0) | specify which key of node object is used as the node's children | ^[string] | options |
| disabled | specify which key of node object is used as the node's disabled | ^[string] | disabled |
### tag-tooltip ^(2.13.3)
:::tip Fallback Mechanism
Properties in tag-tooltip follow this priority order:
1. Explicitly defined fields within the tag-tooltip object.
2. Shared props inherited from el-select (e.g. effect, popper-class, popper-style, teleported, append-to, popper-options).
3. Default values of the underlying el-tooltip component.
This allows you to override specific tooltip behaviors for tags while maintaining consistency with the Select dropdown by default.
:::
:::tip Custom Container Positioning
When appending the Tooltip to a custom container (via the `append-to` attribute), the container should be configured with `position: relative` or `position: absolute` to ensure accurate positioning. Additionally, you can apply `overflow: hidden` to the container if you need to prevent the Tooltip from overflowing its boundaries.
:::
| Attribute | Description | Type | Default |
| ------------------- | -------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
| append-to | which element the tooltip CONTENT appends to | ^[CSSSelector] / ^[HTMLElement] | — |
| placement | position of Tooltip | ^[enum]`'top' \| 'top-start' \| 'top-end' \| 'bottom' \| 'bottom-start' \| 'bottom-end' \| 'left' \| 'left-start' \| 'left-end' \| 'right' \| 'right-start' \| 'right-end'` | bottom |
| fallback-placements | list of possible positions for Tooltip [popper.js](https://popper.js.org/docs/v2/modifiers/flip/#fallbackplacements) | ^[array]`Placement[]` | ['bottom', 'top', 'right', 'left'] |
| effect | Tooltip theme, built-in theme: `dark` / `light` | ^[enum]`'dark' \| 'light'` / ^[string] | — |
| popper-class | custom class name for Tooltip's popper | ^[string] | — |
| popper-style | custom style for Tooltip's popper | ^[string] / ^[object] | — |
| transition | animation name | ^[string] | — |
| teleported | whether tooltip content is teleported, if `true` it will be teleported to where `append-to` sets | ^[boolean] | — |
| popper-options | [popper.js](https://popper.js.org/docs/v2/) parameters | ^[object]refer to [popper.js](https://popper.js.org/docs/v2/) doc | — |
| show-after | delay of appearance, in millisecond | ^[number] | — |
| hide-after | delay of disappear, in millisecond | ^[number] | — |
| auto-close | timeout in milliseconds to hide tooltip | ^[number] | — |
| offset | offset of the Tooltip | ^[number] | — |
### Select Events
| Name | Description | Type |

View File

@@ -68,6 +68,7 @@ interface SelectProps {
multiple?: boolean
collapseTags?: boolean
collapseTagsTooltip?: boolean
tagTooltip?: Record<string, any>
maxCollapseTags?: number
filterable?: boolean
remote?: boolean
@@ -136,6 +137,7 @@ const createSelect = (
:multiple="multiple"
:collapseTags="collapseTags"
:collapseTagsTooltip="collapseTagsTooltip"
:tag-tooltip="tagTooltip"
:max-collapse-tags="maxCollapseTags"
:filterable="filterable"
:multiple-limit="multipleLimit"
@@ -189,6 +191,7 @@ const createSelect = (
multiple: false,
collapseTags: false,
collapseTagsTooltip: false,
tagTooltip: undefined,
maxCollapseTags: 1,
remote: false,
filterable: false,
@@ -916,6 +919,43 @@ describe('Select', () => {
})
expect(tags.length).toBe(4)
})
it('use tag-tooltip', async () => {
const appendTarget = document.createElement('div')
appendTarget.className = 'append-target'
document.body.appendChild(appendTarget)
const wrapper = createSelect({
data: () => {
return {
multiple: true,
collapseTags: true,
collapseTagsTooltip: true,
tagTooltip: { appendTo: '.append-target' },
value: [],
}
},
})
await nextTick()
const options = getOptions()
options[0].click()
await nextTick()
options[1].click()
await nextTick()
options[2].click()
await nextTick()
const select = wrapper.findComponent(Select)
const tagTooltip = select.findComponent({ ref: 'tagTooltipRef' })
expect(tagTooltip.props('appendTo')).toBe('.append-target')
const triggerWrappers = wrapper.findAll('.el-tooltip__trigger')
expect(triggerWrappers[0]).toBeDefined()
const tags = wrapper.findAll('.el-tag').filter((item) => {
return !hasClass(item.element, 'in-tooltip')
})
expect(tags.length).toBe(2)
expect(tags[1].element.textContent.trim()).toBe('+ 2')
})
})
describe('manually set modelValue', () => {

View File

@@ -21,13 +21,36 @@ import type SelectV2 from './select.vue'
import type { Option, OptionType } from './select.types'
import type { Props } from './useProps'
import type { EmitFn } from '@element-plus/utils/vue/typescript'
import type { ExtractPropTypes, ExtractPublicPropTypes } from 'vue'
import type {
CSSProperties,
ExtractPropTypes,
ExtractPublicPropTypes,
} from 'vue'
import type {
Options,
Placement,
PopperEffect,
} from '@element-plus/components/popper'
/**
* @description Tag tooltip configuration interface
*/
export interface TagTooltipProps {
appendTo?: string | HTMLElement
placement?: Placement
fallbackPlacements?: Placement[]
effect?: PopperEffect
popperClass?: string
popperStyle?: string | CSSProperties
transition?: string
teleported?: boolean
popperOptions?: Partial<Options>
showAfter?: number
hideAfter?: number
autoClose?: number
offset?: number
}
export const selectV2Props = buildProps({
/**
* @description whether creating new items is allowed. To use this, `filterable` must be true
@@ -70,6 +93,13 @@ export const selectV2Props = buildProps({
* @description whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true
*/
collapseTagsTooltip: Boolean,
/**
* @description configuration object for the collapse-tags tooltip. To use this, `collapse-tags` and `collapse-tags-tooltip` must be true
*/
tagTooltip: {
type: definePropType<TagTooltipProps>(Object),
default: () => ({}),
},
/**
* @description The max tags number to be shown. To use this, `collapse-tags` must be true
*/

View File

@@ -92,16 +92,31 @@
</div>
<el-tooltip
v-if="collapseTags && modelValue.length > maxCollapseTags"
v-if="
collapseTags && states.cachedOptions.length > maxCollapseTags
"
ref="tagTooltipRef"
:disabled="dropdownMenuVisible || !collapseTagsTooltip"
:fallback-placements="['bottom', 'top', 'right', 'left']"
:effect="effect"
placement="bottom"
:popper-class="popperClass"
:popper-style="popperStyle"
:teleported="teleported"
:popper-options="popperOptions"
:fallback-placements="
tagTooltip?.fallbackPlacements ?? [
'bottom',
'top',
'right',
'left',
]
"
:effect="tagTooltip?.effect ?? effect"
:placement="tagTooltip?.placement ?? 'bottom'"
:popper-class="tagTooltip?.popperClass ?? popperClass"
:popper-style="tagTooltip?.popperStyle ?? popperStyle"
:teleported="tagTooltip?.teleported ?? teleported"
:append-to="tagTooltip?.appendTo ?? appendTo"
:popper-options="tagTooltip?.popperOptions ?? popperOptions"
:transition="tagTooltip?.transition"
:show-after="tagTooltip?.showAfter"
:hide-after="tagTooltip?.hideAfter"
:auto-close="tagTooltip?.autoClose"
:offset="tagTooltip?.offset"
>
<template #default>
<div
@@ -117,7 +132,7 @@
disable-transitions
>
<span :class="nsSelect.e('tags-text')">
+ {{ modelValue.length - maxCollapseTags }}
+ {{ states.cachedOptions.length - maxCollapseTags }}
</span>
</el-tag>
</div>

View File

@@ -1505,10 +1505,19 @@ describe('Select', () => {
wrapper = _mount(
`
<el-select v-model="selectedList" multiple collapseTags collapse-tags-tooltip placeholder="请选择">
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value">
</el-option>
</el-select>
<div>
<div class="append-target"></div>
<el-select
v-model="selectedList"
multiple
collapseTags
collapse-tags-tooltip
:tag-tooltip="{ appendTo: '.append-target' }"
placeholder="请选择"
>
<el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
</el-select>
</div>
`,
() => ({
options: [
@@ -1545,6 +1554,11 @@ describe('Select', () => {
await nextTick()
options[2].click()
await nextTick()
const select = wrapper.findComponent(Select)
const tagTooltip = select.findComponent({ ref: 'tagTooltipRef' })
expect(tagTooltip.props('appendTo')).toBe('.append-target')
const triggerWrappers = wrapper.findAll('.el-tooltip__trigger')
expect(triggerWrappers[0]).toBeDefined()
const tags = document.querySelectorAll('.el-select__tags-text')

View File

@@ -27,6 +27,25 @@ import type {
import type { OptionValue } from './type'
import type { Props } from '@element-plus/components/select-v2/src/useProps'
/**
* @description Tag tooltip configuration interface
*/
export interface TagTooltipProps {
appendTo?: string | HTMLElement
placement?: Placement
fallbackPlacements?: Placement[]
effect?: PopperEffect
popperClass?: string
popperStyle?: string | CSSProperties
transition?: string
teleported?: boolean
popperOptions?: Partial<Options>
showAfter?: number
hideAfter?: number
autoClose?: number
offset?: number
}
export const selectProps = buildProps({
/**
* @description the name attribute of select input
@@ -192,6 +211,13 @@ export const selectProps = buildProps({
* @description whether show all selected tags when mouse hover text of collapse-tags. To use this, `collapse-tags` must be true
*/
collapseTagsTooltip: Boolean,
/**
* @description configuration object for the collapse-tags tooltip. To use this, `collapse-tags` and `collapse-tags-tooltip` must be true
*/
tagTooltip: {
type: definePropType<TagTooltipProps>(Object),
default: () => ({}),
},
/**
* @description the max tags number to be shown. To use this, `collapse-tags` must be true
*/

View File

@@ -95,13 +95,26 @@
v-if="collapseTags && states.selected.length > maxCollapseTags"
ref="tagTooltipRef"
:disabled="dropdownMenuVisible || !collapseTagsTooltip"
:fallback-placements="['bottom', 'top', 'right', 'left']"
:effect="effect"
placement="bottom"
:popper-class="popperClass"
:popper-style="popperStyle"
:teleported="teleported"
:popper-options="popperOptions"
:fallback-placements="
tagTooltip?.fallbackPlacements ?? [
'bottom',
'top',
'right',
'left',
]
"
:effect="tagTooltip?.effect ?? effect"
:placement="tagTooltip?.placement ?? 'bottom'"
:popper-class="tagTooltip?.popperClass ?? popperClass"
:popper-style="tagTooltip?.popperStyle ?? popperStyle"
:teleported="tagTooltip?.teleported ?? teleported"
:append-to="tagTooltip?.appendTo ?? appendTo"
:popper-options="tagTooltip?.popperOptions ?? popperOptions"
:transition="tagTooltip?.transition"
:show-after="tagTooltip?.showAfter"
:hide-after="tagTooltip?.hideAfter"
:auto-close="tagTooltip?.autoClose"
:offset="tagTooltip?.offset"
>
<template #default>
<div