diff --git a/packages/components/select-v2/__tests__/select.spec.ts b/packages/components/select-v2/__tests__/select.spec.ts index f5ae97890d..22a7306261 100644 --- a/packages/components/select-v2/__tests__/select.spec.ts +++ b/packages/components/select-v2/__tests__/select.spec.ts @@ -979,4 +979,54 @@ describe('Select', () => { await nextTick() expect(vm.value).toEqual([6]) }) + + it('multiple select when content overflow', async () => { + const wrapper = createSelect({ + data () { + return { + options: [{ + value: '选项1', + label: '黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕黄金糕', + }, { + value: '选项2', + label: '双皮奶双皮奶双皮奶双皮奶双皮奶双皮奶双皮奶双皮奶双皮奶双皮奶双皮奶双皮奶双皮奶', + }, { + value: '选项3', + label: '蚵仔煎蚵仔煎蚵仔煎蚵仔煎蚵仔煎蚵仔煎', + }, { + value: '选项4', + label: '龙须面', + }, { + value: '选项5', + label: '北京烤鸭', + }], + } + }, + }) + const select = wrapper.findComponent(Select) + const selectVm = select.vm as any + const selectDom = wrapper.find('.el-select-v2__wrapper').element + const selectRect = { + height: 40, + width: 221, + x:44, + y:8, + top:8, + } + const mockSelectWidth = jest.spyOn(selectDom, 'getBoundingClientRect').mockReturnValue(selectRect as DOMRect) + selectVm.handleResize() + const options = getOptions() + options[0].click() + await nextTick() + options[1].click() + await nextTick() + options[2].click() + await nextTick() + const tagWrappers = wrapper.findAll('.el-select-v2__tags-text') + for(let i = 0;i < tagWrappers.length;i++) { + const tagWrapperDom = tagWrappers[i].element + expect(parseInt(tagWrapperDom.style.maxWidth) === selectRect.width - 42).toBe(true) + } + mockSelectWidth.mockRestore() + }) }) diff --git a/packages/components/select-v2/src/select.vue b/packages/components/select-v2/src/select.vue index 24fa407bd7..3a50f22c34 100644 --- a/packages/components/select-v2/src/select.vue +++ b/packages/components/select-v2/src/select.vue @@ -52,7 +52,9 @@ > {{ states.cachedOptions[0].label }} - + {{ modelValue.length - 1 }} + + {{ modelValue.length - 1 }} @@ -81,7 +88,12 @@ disable-transitions @close="deleteTag($event, selected)" > - {{ getLabel(selected) }} + {{ getLabel(selected) }} diff --git a/packages/components/select-v2/src/useSelect.ts b/packages/components/select-v2/src/useSelect.ts index cc7476d4d4..a56e4fd30b 100644 --- a/packages/components/select-v2/src/useSelect.ts +++ b/packages/components/select-v2/src/useSelect.ts @@ -38,6 +38,10 @@ import { useInput } from './useInput' const DEFAULT_INPUT_PLACEHOLDER = '' const MINIMUM_INPUT_WIDTH = 11 +const TAG_BASE_WIDTH = { + small: 42, + mini: 33, +} const useSelect = (props: ExtractPropTypes, emit) => { @@ -63,7 +67,7 @@ const useSelect = (props: ExtractPropTypes, emit) => { isSilentBlur: false, isComposing: false, inputLength: 20, - inputWidth: 240, + selectWidth: 200, initialInputHeight: 0, previousQuery: null, previousValue: '', @@ -165,6 +169,14 @@ const useSelect = (props: ExtractPropTypes, emit) => { const collapseTagSize = computed(() => ['small', 'mini'].indexOf(selectSize.value) > -1 ? 'mini' : 'small') + const tagMaxWidth = computed(() => { + const select = selectionRef.value + const size = collapseTagSize.value + const paddingLeft = select ? parseInt(getComputedStyle(select).paddingLeft) : 0 + const paddingRight = select ? parseInt(getComputedStyle(select).paddingRight) : 0 + return states.selectWidth - paddingRight - paddingLeft - TAG_BASE_WIDTH[size] + }) + const calculatePopperSize = () => { popperSize.value = selectRef.value?.getBoundingClientRect?.()?.width || 200 } @@ -203,8 +215,9 @@ const useSelect = (props: ExtractPropTypes, emit) => { // the index with current value in options const indexRef = computed(() => { if (props.multiple) { + const len = (props.modelValue as []).length if ((props.modelValue as Array).length > 0) { - return filteredOptions.value.findIndex(o => o.value === props.modelValue[0]) + return filteredOptions.value.findIndex(o => o.value === props.modelValue[len - 1]) } } else { if (props.modelValue) { @@ -324,12 +337,15 @@ const useSelect = (props: ExtractPropTypes, emit) => { resetInputWidth() calculatePopperSize() popper.value?.update?.() - if (props.multiple) resetInputHeight() + if (props.multiple) { + return resetInputHeight() + } } const resetInputWidth = () => { - if (inputRef.value) { - states.inputWidth = inputRef.value.getBoundingClientRect().width + const select = selectionRef.value + if (select) { + states.selectWidth = select.getBoundingClientRect().width } } @@ -678,6 +694,7 @@ const useSelect = (props: ExtractPropTypes, emit) => { selectSize, showClearBtn, states, + tagMaxWidth, // refs items exports calculatorRef, @@ -704,6 +721,7 @@ const useSelect = (props: ExtractPropTypes, emit) => { handleEsc, handleFocus, handleMenuEnter, + handleResize, toggleMenu, scrollTo: scrollToItem, onInput, diff --git a/packages/theme-chalk/src/common/var.scss b/packages/theme-chalk/src/common/var.scss index 945c7ab7fb..3496259aeb 100644 --- a/packages/theme-chalk/src/common/var.scss +++ b/packages/theme-chalk/src/common/var.scss @@ -775,6 +775,17 @@ $--tag: map.merge( $--tag-color: () !default; +$--tag-height: () !default; +$--tag-height: map.merge( + ( + 'default': 32px, + 'medium': 28px, + 'small': 24px, + 'mini': 20px, + ), + $--tag-height +); + @each $type in $--types { $--tag-color: map.merge( ( diff --git a/packages/theme-chalk/src/select-v2.scss b/packages/theme-chalk/src/select-v2.scss index 4323aa8724..c3ead22904 100644 --- a/packages/theme-chalk/src/select-v2.scss +++ b/packages/theme-chalk/src/select-v2.scss @@ -52,7 +52,7 @@ $--input-inline-start: 15px !default; border-color: var(--el-select-disabled-border); &:hover { - border-color: inherit; + border-color: var(--el-select-disabled-border); } &.is-focus { @@ -98,6 +98,13 @@ $--input-inline-start: 15px !default; } } + .#{$namespace}-select-v2__tags-text { + text-overflow: ellipsis; + display: inline-block; + overflow-x: hidden; + vertical-align: bottom; + } + @include e(empty) { padding: 10px 0; margin: 0; @@ -314,7 +321,6 @@ $--input-inline-start: 15px !default; .#{$namespace}-icon-close { background-color: var(--el-text-color-placeholder); right: -7px; - top: 0; color: var(--el-color-white); &:hover { diff --git a/packages/theme-chalk/src/tag.scss b/packages/theme-chalk/src/tag.scss index 377c2f57bd..c39125e3d0 100644 --- a/packages/theme-chalk/src/tag.scss +++ b/packages/theme-chalk/src/tag.scss @@ -84,9 +84,9 @@ @include b(tag) { @include genTheme(10%, 20%, 100%, 100%); display: inline-block; - height: 32px; + height: map.get($--tag-height, 'default'); padding: var(--el-tag-padding); - line-height: 30px; + line-height: map.get($--tag-height, 'default') - 2px; font-size: var(--el-tag-font-size); border-width: 1px; border-style: solid; @@ -120,30 +120,28 @@ @include genTheme(0, 40%, 100%, 100%); } - @include m(medium) { - height: 28px; - line-height: 26px; + @each $size in (medium, small, mini) { + @include m($size) { + height: map.get($--tag-height, $size); + line-height: map.get($--tag-height, $size) - 2px; + } + } + @include m(medium) { .#{$namespace}-icon-close { transform: scale(0.8); } } @include m(small) { - height: 24px; padding: 0 8px; - line-height: 22px; - .#{$namespace}-icon-close { transform: scale(0.8); } } @include m(mini) { - height: 20px; padding: 0 5px; - line-height: 19px; - .#{$namespace}-icon-close { margin-left: -3px; transform: scale(0.7); diff --git a/website/docs/en-US/select-v2.md b/website/docs/en-US/select-v2.md index 2492f052bd..601e71d7ae 100644 --- a/website/docs/en-US/select-v2.md +++ b/website/docs/en-US/select-v2.md @@ -20,7 +20,7 @@ The simplest selector v-model="value" :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" /> @@ -53,7 +53,7 @@ The basic multi-select selector with tags v-model="value" :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -86,7 +86,7 @@ The basic multi-select selector with tags v-model="value" :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple collapse-tags /> @@ -122,7 +122,7 @@ When the options are overwhelmingly too many, you can use `filterable` option to filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -157,7 +157,7 @@ You can choose to disable selector itself or the option. filterable :options="options" placeholder="Please select" - style="width: 200px; margin-right: 16px; vertical-align: middle;" + style="width: 240px; margin-right: 16px; vertical-align: middle;" multiple /> @@ -203,7 +203,7 @@ We can group option as we wanted, as long as the data satisfies the pattern. filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -245,7 +245,7 @@ We can define our own template for rendering the option in the popup. filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple > @@ -328,7 +328,7 @@ Create and select new items that are not included in select options v-model="value1" :options="options" placeholder="Please select" - style="width: 200px; margin-right: 16px; vertical-align: middle;" + style="width: 240px; margin-right: 16px; vertical-align: middle;" allow-create filterable multiple @@ -338,7 +338,7 @@ Create and select new items that are not included in select options v-model="value2" :options="options" placeholder="Please select" - style="width: 200px; vertical-align: middle;" + style="width: 240px; vertical-align: middle;" allow-create filterable clearable @@ -372,7 +372,7 @@ Enter keywords and search data from server. @@ -53,7 +53,7 @@ The basic multi-select selector with tags v-model="value" :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -86,7 +86,7 @@ The basic multi-select selector with tags v-model="value" :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple collapse-tags /> @@ -122,7 +122,7 @@ When the options are overwhelmingly too many, you can use `filterable` option to filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -157,7 +157,7 @@ You can choose to disable selector itself or the option. filterable :options="options" placeholder="Please select" - style="width: 200px; margin-right: 16px; vertical-align: middle;" + style="width: 240px; margin-right: 16px; vertical-align: middle;" multiple /> @@ -203,7 +203,7 @@ We can group option as we wanted, as long as the data satisfies the pattern. filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -245,7 +245,7 @@ We can define our own template for rendering the option in the popup. filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple > @@ -329,7 +329,7 @@ Crear y seleccionar nuevos items que no están incluidas en las opciones de sele v-model="value1" :options="options" placeholder="Please select" - style="width: 200px; margin-right: 16px; vertical-align: middle;" + style="width: 240px; margin-right: 16px; vertical-align: middle;" allow-create filterable multiple @@ -339,7 +339,7 @@ Crear y seleccionar nuevos items que no están incluidas en las opciones de sele v-model="value2" :options="options" placeholder="Please select" - style="width: 200px; vertical-align: middle;" + style="width: 240px; vertical-align: middle;" allow-create filterable clearable @@ -373,7 +373,7 @@ Introduzca palabras y datos para buscar desde el servidor. @@ -53,7 +53,7 @@ The basic multi-select selector with tags v-model="value" :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -86,7 +86,7 @@ The basic multi-select selector with tags v-model="value" :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple collapse-tags /> @@ -122,7 +122,7 @@ When the options are overwhelmingly too many, you can use `filterable` option to filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -157,7 +157,7 @@ You can choose to disable selector itself or the option. filterable :options="options" placeholder="Please select" - style="width: 200px; margin-right: 16px; vertical-align: middle;" + style="width: 240px; margin-right: 16px; vertical-align: middle;" multiple /> @@ -203,7 +203,7 @@ We can group option as we wanted, as long as the data satisfies the pattern. filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -245,7 +245,7 @@ We can define our own template for rendering the option in the popup. filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple > @@ -330,7 +330,7 @@ Vous pouvez entrer des choix dans le champ de sélection qui ne sont pas incluse v-model="value1" :options="options" placeholder="Please select" - style="width: 200px; margin-right: 16px; vertical-align: middle;" + style="width: 240px; margin-right: 16px; vertical-align: middle;" allow-create filterable multiple @@ -340,7 +340,7 @@ Vous pouvez entrer des choix dans le champ de sélection qui ne sont pas incluse v-model="value2" :options="options" placeholder="Please select" - style="width: 200px; vertical-align: middle;" + style="width: 240px; vertical-align: middle;" allow-create filterable clearable @@ -374,7 +374,7 @@ Vous pouvez aller chercher les options sur le serveur de manière dynamique. @@ -53,7 +53,7 @@ The basic multi-select selector with tags v-model="value" :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -86,7 +86,7 @@ The basic multi-select selector with tags v-model="value" :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple collapse-tags /> @@ -122,7 +122,7 @@ When the options are overwhelmingly too many, you can use `filterable` option to filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -157,7 +157,7 @@ You can choose to disable selector itself or the option. filterable :options="options" placeholder="Please select" - style="width: 200px; margin-right: 16px; vertical-align: middle;" + style="width: 240px; margin-right: 16px; vertical-align: middle;" multiple /> @@ -203,7 +203,7 @@ We can group option as we wanted, as long as the data satisfies the pattern. filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -245,7 +245,7 @@ We can define our own template for rendering the option in the popup. filterable :options="options" placeholder="Please select" - style="width: 200px;" + style="width: 240px;" multiple > @@ -328,7 +328,7 @@ We can clear all the selected options at once, also applicable for single select v-model="value1" :options="options" placeholder="Please select" - style="width: 200px; margin-right: 16px; vertical-align: middle;" + style="width: 240px; margin-right: 16px; vertical-align: middle;" allow-create filterable multiple @@ -338,7 +338,7 @@ We can clear all the selected options at once, also applicable for single select v-model="value2" :options="options" placeholder="Please select" - style="width: 200px; vertical-align: middle;" + style="width: 240px; vertical-align: middle;" allow-create filterable clearable @@ -372,7 +372,7 @@ We can clear all the selected options at once, also applicable for single select @@ -53,7 +53,7 @@ v-model="value" :options="options" placeholder="请选择" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -86,7 +86,7 @@ v-model="value" :options="options" placeholder="请选择" - style="width: 200px;" + style="width: 240px;" multiple collapse-tags /> @@ -122,7 +122,7 @@ filterable :options="options" placeholder="请选择" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -157,7 +157,7 @@ filterable :options="options" placeholder="请选择" - style="width: 200px; margin-right: 16px; vertical-align: middle;" + style="width: 240px; margin-right: 16px; vertical-align: middle;" multiple /> @@ -203,7 +203,7 @@ filterable :options="options" placeholder="请选择" - style="width: 200px;" + style="width: 240px;" multiple /> @@ -246,7 +246,7 @@ filterable :options="options" placeholder="请选择" - style="width: 200px;" + style="width: 240px;" multiple > @@ -329,7 +329,7 @@ v-model="value1" :options="options" placeholder="请选择" - style="width: 200px; margin-right: 16px; vertical-align: middle;" + style="width: 240px; margin-right: 16px; vertical-align: middle;" allow-create filterable multiple @@ -339,7 +339,7 @@ v-model="value2" :options="options" placeholder="请选择" - style="width: 200px; vertical-align: middle;" + style="width: 240px; vertical-align: middle;" allow-create filterable clearable @@ -372,7 +372,7 @@