From b61ff9515e498966c4985c41575171d2cfa62c71 Mon Sep 17 00:00:00 2001 From: zcj <18137693952@163.com> Date: Sun, 30 Oct 2022 16:17:21 +0800 Subject: [PATCH 1/6] =?UTF-8?q?feat(tag-input):=20=E7=BB=84=E4=BB=B6=20cla?= =?UTF-8?q?ss=20=E4=BD=BF=E7=94=A8=20namespace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../tag-input/__tests__/tag-input.spec.ts | 39 +-- .../devui/tag-input/src/tag-input.scss | 244 +++++++++--------- .../devui/tag-input/src/tag-input.tsx | 43 ++- 3 files changed, 158 insertions(+), 168 deletions(-) diff --git a/packages/devui-vue/devui/tag-input/__tests__/tag-input.spec.ts b/packages/devui-vue/devui/tag-input/__tests__/tag-input.spec.ts index 6edb124071..2b00f7d98f 100644 --- a/packages/devui-vue/devui/tag-input/__tests__/tag-input.spec.ts +++ b/packages/devui-vue/devui/tag-input/__tests__/tag-input.spec.ts @@ -47,11 +47,10 @@ describe('DTagInput', () => { }); const wrapper = customMount(state); expect(wrapper.find(ns.b()).exists()).toBe(true); - expect(wrapper.find('.devui-tags').exists()).toBe(true); - expect(wrapper.find('.devui-tag-list').exists()).toBe(true); - expect(wrapper.find('.devui-input').exists()).toBe(true); + expect(wrapper.find(ns.e('tags')).exists()).toBe(true); + expect(wrapper.find(ns.e('input')).exists()).toBe(true); - const itemA = wrapper.find('.devui-tag-item'); + const itemA = wrapper.find(ns.e('tags__item')); expect(itemA.exists()).toBe(true); expect(itemA.text()).toBe('Y.Chen'); @@ -72,13 +71,13 @@ describe('DTagInput', () => { ], }); const wrapper = customMount(state); - const input = wrapper.find('input.devui-input'); + const input = wrapper.find(ns.e('input')); - expect(wrapper.find('.devui-suggestion-list').exists()).toBe(false); + expect(wrapper.find(ns.e('suggestion-list')).exists()).toBe(false); await input.trigger('focus'); // 是否存在 devui-suggestion-list - const suggestionList = !!document.querySelectorAll('.devui-suggestion-list')[0]; + const suggestionList = !!document.querySelectorAll(ns.e('suggestion-list'))[0]; expect(suggestionList).toBe(true); wrapper.unmount(); @@ -99,14 +98,16 @@ describe('DTagInput', () => { }, }); - expect(wrapper.find('.devui-disabled').exists()).toBe(false); - expect(wrapper.find('.devui-input').isVisible()).toBe(true); + expect(wrapper.find('.is-disabled').exists()).toBe(false); + expect(wrapper.find(ns.e('input')).isVisible()).toBe(true); await wrapper.setProps({ disabled: true, }); - expect(wrapper.find('.devui-disabled').exists()).toBe(true); - expect(wrapper.find('.devui-input').isVisible()).toBe(false); + + expect(wrapper.find('.is-disabled').exists()).toBe(true); + // 禁用状态下不显示input + expect(wrapper.find(ns.e('input_hide')).exists()).toBe(true); expect(wrapper.find('.remove-button').exists()).toBe(false); wrapper.unmount(); @@ -146,7 +147,7 @@ describe('DTagInput', () => { const wrapper = customMount(state); const removeSvg = wrapper.find('.remove-button'); await removeSvg.trigger('click'); - expect(wrapper.findAll('.devui-tag-item').length).toBe(1); + expect(wrapper.findAll(ns.e('tags__item')).length).toBe(1); expect(state.tags.length).toBe(1); expect(state.suggestionList.length).toBe(2); @@ -196,17 +197,17 @@ describe('DTagInput', () => { const input = wrapper.find('input'); await input.trigger('focus'); - let suggestionList = document.querySelectorAll('.devui-suggestion-item'); + let suggestionList = document.querySelectorAll(ns.e('suggestion-list__item')); expect(suggestionList.length).toBe(3); await input.setValue('xy'); await input.trigger('input'); - suggestionList = document.querySelectorAll('.devui-suggestion-item'); + suggestionList = document.querySelectorAll(ns.e('suggestion-list__item')); expect(suggestionList.length).toBe(2); await input.setValue('xxx'); await input.trigger('input'); - suggestionList = document.querySelectorAll('.devui-suggestion-item'); + suggestionList = document.querySelectorAll(ns.e('suggestion-list__item')); expect(suggestionList.length).toBe(1); wrapper.unmount(); @@ -226,7 +227,7 @@ describe('DTagInput', () => { }); const wrapper = customMount(state); await wrapper.find('input').trigger('focus'); - const suggestionList = document.querySelectorAll('.devui-suggestion-item'); + const suggestionList = document.querySelectorAll(ns.e('suggestion-list__item')); const yyy = suggestionList[1]; yyy.dispatchEvent(new Event('click')); @@ -252,18 +253,18 @@ describe('DTagInput', () => { const wrapper = customMount(state); const input = wrapper.find('input'); await input.trigger('focus'); - let suggestionList = document.querySelectorAll('.devui-suggestion-item'); + let suggestionList = document.querySelectorAll(ns.e('suggestion-list__item')); // 获取焦点默认第一个选中 expect(suggestionList[0].className).toContain('selected'); // 按下 下箭头,选中第二个数组第一个 await input.trigger('keydown', { key: 'ArrowDown' }); - suggestionList = document.querySelectorAll('.devui-suggestion-item'); + suggestionList = document.querySelectorAll(ns.e('suggestion-list__item')); expect(suggestionList[1].className).toContain('selected'); await input.trigger('keydown', { key: 'ArrowUp' }); await input.trigger('keydown', { key: 'ArrowUp' }); - suggestionList = document.querySelectorAll('.devui-suggestion-item'); + suggestionList = document.querySelectorAll(ns.e('suggestion-list__item')); expect(suggestionList[2].className).toContain('selected'); // 按下Enter选中数据 diff --git a/packages/devui-vue/devui/tag-input/src/tag-input.scss b/packages/devui-vue/devui/tag-input/src/tag-input.scss index b79c7edc30..8c9a2b6b94 100644 --- a/packages/devui-vue/devui/tag-input/src/tag-input.scss +++ b/packages/devui-vue/devui/tag-input/src/tag-input.scss @@ -13,131 +13,130 @@ &:active { outline: 0; } -} -.#{$devui-prefix}-form-control.#{$devui-prefix}-tags { - -moz-appearance: textfield; - -webkit-appearance: textfield; - padding: 2px 4px; - overflow: hidden; - word-wrap: break-word; - cursor: text; - background-color: $devui-base-bg; - border: 1px solid $devui-line; - border-radius: $devui-border-radius; - height: 100%; - transition: border-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); + .is-disabled { + border-color: $devui-disabled-line; + background-color: $devui-disabled-bg; + cursor: not-allowed; - &:hover { - border-color: $devui-list-item-hover-bg; - } + .#{$devui-prefix}-tag-input__tags { + min-height: 22px; - &.focused { - outline: 0; - } + &__item { + color: $devui-disabled-text; + background-color: $devui-disabled-bg; + border-color: $devui-disabled-line; - &.#{$devui-prefix}-dropdown-origin:focus-within { - border-color: $devui-brand; - } + span { + margin-right: 0; + } - .#{$devui-prefix}-tag-list { - margin: 0; - padding: 0; - list-style-type: none; + .remove-button { + background-color: $devui-disabled-line; + + svg path { + fill: $devui-light-text; + } + } + } + } } - .#{$devui-prefix}-tag-item { - margin: 1px; - padding: 0 10px; - display: inline-block; - min-height: 18px; - line-height: 18px; + // 已选择 + &__tags__wrapper { + -moz-appearance: textfield; + -webkit-appearance: textfield; + padding: 2px 4px; + overflow: hidden; + word-wrap: break-word; + cursor: text; + background-color: $devui-base-bg; + border: 1px solid $devui-line; border-radius: $devui-border-radius; - color: $devui-text; - background-color: $devui-label-bg; - position: relative; - border: 1px solid $devui-label-bg; + height: 100%; + transition: border-color 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); - span { - line-height: 1.5; - margin-right: 25px; + &:hover { + border-color: $devui-list-item-hover-bg; } - .remove-button { - margin: 0 0 0 12px; - padding: 0; - border: none; - vertical-align: top; - font-size: $devui-font-size-page-title; - border-radius: 50%; - background-color: $devui-line; - width: 12px; - height: 12px; - display: inline-block; - line-height: 12px; - text-align: center; - transform: translateY(-50%); - position: absolute; - top: 50%; - right: 10px; - - svg path { - fill: $devui-light-text; //TODO: Color-Question - } + &:focus-within { + border-color: $devui-brand; + } - &:hover { - text-decoration: none; - } + &.focused { + outline: 0; } } - &:not(.#{$devui-prefix}-disabled) { - .#{$devui-prefix}-tag-item { - cursor: pointer; + &__tags { + margin: 0; + padding: 0; + list-style-type: none; + + &__item { + margin: 1px; + padding: 0 10px; + display: inline-block; + min-height: 18px; + line-height: 18px; + border-radius: $devui-border-radius; + color: $devui-text; + background-color: $devui-label-bg; + position: relative; + border: 1px solid $devui-label-bg; span { - &:hover { - color: $devui-list-item-hover-text; - } + line-height: 1.5; + margin-right: 25px; } .remove-button { + margin: 0 0 0 12px; + padding: 0; + border: none; + vertical-align: top; + font-size: $devui-font-size-page-title; + border-radius: 50%; + background-color: $devui-line; + width: 12px; + height: 12px; + display: inline-block; + line-height: 12px; + text-align: center; + transform: translateY(-50%); + position: absolute; + top: 50%; + right: 10px; + + svg path { + fill: $devui-light-text; //TODO: Color-Question + } + &:hover { - background-color: $devui-list-item-hover-text; + text-decoration: none; } } - } - } - - &.#{$devui-prefix}-disabled { - border-color: $devui-disabled-line; - background-color: $devui-disabled-bg; - cursor: not-allowed; - .#{$devui-prefix}-tag-item { - color: $devui-disabled-text; - background-color: $devui-disabled-bg; - border-color: $devui-disabled-line; - - span { - margin-right: 0; - } + &:not(.is-disabled) { + cursor: pointer; - .remove-button { - background-color: $devui-disabled-line; + span { + &:hover { + color: $devui-list-item-hover-text; + } + } - svg path { - fill: $devui-light-text; + .remove-button { + &:hover { + background-color: $devui-list-item-hover-text; + } } } } - - .#{$devui-prefix}-tag-list { - min-height: 22px; - } } - input.#{$devui-prefix}-input { + &__input { border: 0; outline: 0; float: left; @@ -149,54 +148,51 @@ &::-ms-clear { display: none; } - } -} -.#{$devui-prefix}-tags-autocomplete { - width: 100%; - padding: 8px; - border-radius: $devui-border-radius; - background-color: $devui-connected-overlay-bg; - box-shadow: $devui-shadow-length-connected-overlay $devui-shadow; + &_hide { + display: none; + } + } - .#{$devui-prefix}-suggestion-list { + // 建议列表 + &__suggestion-list { + position: relative; + width: 100%; + max-height: 280px; + padding: 8px; margin: 0; - padding: 0; + border-radius: $devui-border-radius; + background-color: $devui-connected-overlay-bg; + box-shadow: $devui-shadow-length-connected-overlay $devui-shadow; list-style-type: none; - max-height: 280px; overflow-y: auto; - position: relative; - .#{$devui-prefix}-suggestion-item { + &__item { padding: 5px 10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; + color: $devui-text; font-size: $devui-font-size; line-height: 20px; border-radius: $devui-border-radius; + transition: color $devui-animation-duration-fast $devui-animation-ease-in-smooth, background-color $devui-animation-duration-fast $devui-animation-ease-in-smooth; + cursor: pointer; - &:not(.#{$devui-prefix}-disabled) { - cursor: pointer; - color: $devui-text; - // background-color: $devui-base-bg; - &:hover { - background-color: $devui-list-item-hover-bg; - } + &:hover { + background-color: $devui-list-item-hover-bg; + } - &.selected { - color: $devui-brand; - background-color: $devui-list-item-active-bg; - } + &.selected { + color: $devui-brand; + background-color: $devui-list-item-active-bg; } } - } -} -.#{$devui-prefix}-tags-autocomplete { - .#{$devui-prefix}-suggestion-list { - .#{$devui-prefix}-suggestion-item { - transition: color $devui-animation-duration-fast $devui-animation-ease-in-smooth, background-color $devui-animation-duration-fast $devui-animation-ease-in-smooth; + &__no-data { + color: var(--devui-disabled-text, #adb0b8); + background-color: var(--devui-disabled-bg, #f5f5f5); + cursor: not-allowed; } } } diff --git a/packages/devui-vue/devui/tag-input/src/tag-input.tsx b/packages/devui-vue/devui/tag-input/src/tag-input.tsx index c17e48da8f..a39c252042 100644 --- a/packages/devui-vue/devui/tag-input/src/tag-input.tsx +++ b/packages/devui-vue/devui/tag-input/src/tag-input.tsx @@ -151,10 +151,10 @@ export default defineComponent({ // 已选择 tags 列表 const chosenTags = () => { - return