Skip to content

Commit 423e3cd

Browse files
vaebekagol
authored andcommitted
feat(tag-input): suggestion-list 使用 FlexibleOverlay
1 parent 7447c50 commit 423e3cd

File tree

3 files changed

+40
-39
lines changed

3 files changed

+40
-39
lines changed

packages/devui-vue/devui/tag-input/src/tag-input.scss

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -153,18 +153,10 @@
153153
}
154154

155155
.#{$devui-prefix}-tags-autocomplete {
156-
position: absolute;
157-
padding-bottom: 5px;
158-
z-index: $devui-z-index-dropdown;
159156
width: 100%;
160157
background-color: $devui-connected-overlay-bg;
161158
box-shadow: $devui-shadow-length-connected-overlay $devui-shadow;
162159

163-
&.#{$devui-prefix}-dropdown-menu {
164-
display: block;
165-
margin: 4px 0;
166-
}
167-
168160
.#{$devui-prefix}-suggestion-list {
169161
margin: 0;
170162
padding: 0;
@@ -191,7 +183,7 @@
191183

192184
&.selected {
193185
color: $devui-brand;
194-
background-color: $devui-list-item-hover-bg;
186+
background-color: $devui-list-item-active-bg;
195187
}
196188
}
197189
}

packages/devui-vue/devui/tag-input/src/tag-input.tsx

Lines changed: 39 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import { defineComponent, ref, computed, nextTick, watch, SetupContext, getCurrentInstance } from 'vue';
1+
import { defineComponent, ref, computed, nextTick, watch, SetupContext, getCurrentInstance, Teleport, Transition } from 'vue';
22
import { createI18nTranslate } from '../../locale/create';
3-
import clickoutsideDirective from '../../shared/devui-directive/clickoutside';
4-
import removeBtnSvg from './icon-remove';
3+
import ClickOutside from '../../shared/devui-directive/clickoutside';
4+
import { FlexibleOverlay } from '../../overlay/src/flexible-overlay';
5+
import removeBtnSvg from './components/icon-remove';
56
import { Suggestion, TagInputProps, tagInputProps } from './tag-input-types';
67
import './tag-input.scss';
78

@@ -16,7 +17,7 @@ const KEYS_MAP = {
1617
export default defineComponent({
1718
name: 'DTagInput',
1819
directives: {
19-
clickoutside: clickoutsideDirective,
20+
ClickOutside,
2021
},
2122
props: tagInputProps,
2223
emits: ['update:tags', 'update:suggestionList', 'valueChange'],
@@ -67,14 +68,11 @@ export default defineComponent({
6768
selectIndex.value > 0 ? selectIndex.value-- : (selectIndex.value = mergedSuggestions.value.length - 1);
6869
};
6970

70-
const tagInputRef = ref<HTMLInputElement | null>(null);
71+
const tagInputRef = ref();
7172
const isInputBoxFocus = ref(false);
7273
const onInputFocus = () => {
7374
isInputBoxFocus.value = true;
7475
};
75-
const onInputBlur = () => {
76-
// isInputBoxFocus.value = false;
77-
};
7876

7977
// 点击元素外部区域关闭Suggestion选择
8078
const closeSuggestion = () => {
@@ -173,7 +171,9 @@ export default defineComponent({
173171

174172
const noDataTpl = <li class="devui-suggestion-item devui-disabled">{props.noData}</li>;
175173

176-
return () => (<div class="devui-tags-host" tabIndex="-1" v-clickoutside={closeSuggestion}>
174+
const origin = ref();
175+
176+
return () => (<div class="devui-tags-host" ref={origin} v-click-outside={closeSuggestion}>
177177
<div class={inputBoxCls} style={['box-shadow: none;']}>
178178
<ul class="devui-tag-list" title={props.disabled ? props.disabledText : ''}>
179179
{props.tags.map((tag, tagIdx) => {
@@ -197,33 +197,42 @@ export default defineComponent({
197197
style={tagInputStyle}
198198
onKeyDown={onInputKeydown}
199199
onFocus={onInputFocus}
200-
onBlur={onInputBlur}
201200
onInput={($event: InputEvent) => onInput($event)}
202201
placeholder={isTagsLimit.value ? `${props.maxTagsText || t('maxTagsText')} ${props.maxTags}` : props.placeholder}
203202
spellCheck={props.spellcheck}
204203
disabled={isTagsLimit.value}
205204
/>
206205
</div>
207-
{isShowSuggestion.value && (
208-
<div class="devui-tags-autocomplete devui-dropdown-menu">
209-
<ul class="devui-suggestion-list">
210-
{mergedSuggestions.value.length === 0
211-
? noDataTpl
212-
: mergedSuggestions.value.map((item: Suggestion, index: number) => {
213-
return (
214-
<li
215-
class={{ 'devui-suggestion-item': true, selected: index === selectIndex.value }}
216-
onClick={($event: Event) => {
217-
onSuggestionItemClick($event, index);
218-
}}
219-
>
220-
{item[props.displayProperty]}
221-
</li>
222-
);
223-
})}
224-
</ul>
225-
</div>
226-
)}
206+
207+
<Teleport to="body">
208+
<Transition name="fade">
209+
<FlexibleOverlay
210+
origin={origin.value}
211+
v-model={isShowSuggestion.value}
212+
style={{ zIndex: 'var(--devui-z-index-dropdown, 1052)', width: '100%' }}
213+
>
214+
<div class="devui-tags-autocomplete devui-dropdown-menu" style={{ width: '100%' }}>
215+
<ul class="devui-suggestion-list">
216+
{mergedSuggestions.value.length === 0
217+
? noDataTpl
218+
: mergedSuggestions.value.map((item: Suggestion, index: number) => {
219+
return (
220+
<li
221+
class={{ 'devui-suggestion-item': true, selected: index === selectIndex.value }}
222+
onClick={($event: Event) => {
223+
$event.stopPropagation();
224+
onSuggestionItemClick($event, index);
225+
}}
226+
>
227+
{item[props.displayProperty]}
228+
</li>
229+
);
230+
})}
231+
</ul>
232+
</div>
233+
</FlexibleOverlay>
234+
</Transition>
235+
</Teleport>
227236
</div>);
228237
},
229238
});

0 commit comments

Comments
 (0)