Refactor #1451 - For AutoComplete

pull/1453/head
mertsincan 2021-08-16 14:20:49 +03:00
parent 7167964920
commit 6d90f461a4
2 changed files with 41 additions and 19 deletions

View File

@ -1,4 +1,5 @@
import { VNode } from 'vue'; import { VNode } from 'vue';
import { VirtualScrollerProps } from '../virtualscroller';
interface AutoCompleteProps { interface AutoCompleteProps {
modelValue?: any; modelValue?: any;
@ -20,6 +21,7 @@ interface AutoCompleteProps {
class?: any; class?: any;
style?: any; style?: any;
panelClass?: string; panelClass?: string;
virtualScrollerOptions?: VirtualScrollerProps;
} }
declare class AutoComplete { declare class AutoComplete {

View File

@ -18,25 +18,29 @@
<Button ref="dropdownButton" type="button" icon="pi pi-chevron-down" class="p-autocomplete-dropdown" :disabled="$attrs.disabled" @click="onDropdownClick" v-if="dropdown"/> <Button ref="dropdownButton" type="button" icon="pi pi-chevron-down" class="p-autocomplete-dropdown" :disabled="$attrs.disabled" @click="onDropdownClick" v-if="dropdown"/>
<Teleport :to="appendTarget" :disabled="appendDisabled"> <Teleport :to="appendTarget" :disabled="appendDisabled">
<transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave"> <transition name="p-connected-overlay" @enter="onOverlayEnter" @leave="onOverlayLeave" @after-leave="onOverlayAfterLeave">
<div :ref="overlayRef" :class="panelStyleClass" :style="{'max-height': scrollHeight}" v-if="overlayVisible" @click="onOverlayClick"> <div :ref="overlayRef" :class="panelStyleClass" :style="{'max-height': virtualScrollerDisabled ? scrollHeight : ''}" v-if="overlayVisible" @click="onOverlayClick">
<slot name="header" :value="modelValue" :suggestions="suggestions"></slot> <slot name="header" :value="modelValue" :suggestions="suggestions"></slot>
<ul :id="listId" class="p-autocomplete-items" role="listbox"> <VirtualScroller :ref="virtualScrollerRef" v-bind="virtualScrollerOptions" :style="{'height': scrollHeight}" :items="suggestions" :disabled="virtualScrollerDisabled">
<template v-if="!optionGroupLabel"> <template v-slot:content="{ styleClass, contentRef, items, getItemOptions }">
<li v-for="(item, i) of suggestions" class="p-autocomplete-item" :key="i" @click="selectItem($event, item)" role="option" v-ripple> <ul :id="listId" :ref="contentRef" :class="['p-autocomplete-items', styleClass]" role="listbox">
<slot name="item" :item="item" :index="i">{{getItemContent(item)}}</slot> <template v-if="!optionGroupLabel">
</li> <li v-for="(item, i) of items" class="p-autocomplete-item" :key="i" @click="selectItem($event, item)" role="option" v-ripple>
<slot name="item" :item="item" :index="getOptionIndex(i, getItemOptions)">{{getItemContent(item)}}</slot>
</li>
</template>
<template v-else>
<template v-for="(optionGroup, i) of items" :key="getOptionGroupRenderKey(optionGroup)">
<li class="p-autocomplete-item-group">
<slot name="optiongroup" :item="optionGroup" :index="getOptionIndex(i, getItemOptions)">{{getOptionGroupLabel(optionGroup)}}</slot>
</li>
<li v-for="(item, j) of getOptionGroupChildren(optionGroup)" class="p-autocomplete-item" :key="j" @click="selectItem($event, item)" role="option" v-ripple :data-group="i" :data-index="j">
<slot name="item" :item="item" :index="getOptionIndex(j, getItemOptions)">{{getItemContent(item)}}</slot>
</li>
</template>
</template>
</ul>
</template> </template>
<template v-else> </VirtualScroller>
<template v-for="(optionGroup, i) of suggestions" :key="getOptionGroupRenderKey(optionGroup)">
<li class="p-autocomplete-item-group">
<slot name="optiongroup" :item="optionGroup" :index="i">{{getOptionGroupLabel(optionGroup)}}</slot>
</li>
<li v-for="(item, j) of getOptionGroupChildren(optionGroup)" class="p-autocomplete-item" :key="j" @click="selectItem($event, item)" role="option" v-ripple :data-group="i" :data-index="j">
<slot name="item" :item="item" :index="j">{{getItemContent(item)}}</slot>
</li>
</template>
</template>
</ul>
<slot name="footer" :value="modelValue" :suggestions="suggestions"></slot> <slot name="footer" :value="modelValue" :suggestions="suggestions"></slot>
</div> </div>
</transition> </transition>
@ -49,6 +53,7 @@ import {ConnectedOverlayScrollHandler,UniqueComponentId,ObjectUtils,DomHandler,Z
import OverlayEventBus from 'primevue/overlayeventbus'; import OverlayEventBus from 'primevue/overlayeventbus';
import Button from 'primevue/button'; import Button from 'primevue/button';
import Ripple from 'primevue/ripple'; import Ripple from 'primevue/ripple';
import VirtualScroller from 'primevue/virtualscroller';
export default { export default {
name: 'AutoComplete', name: 'AutoComplete',
@ -106,13 +111,18 @@ export default {
inputStyle: null, inputStyle: null,
class: null, class: null,
style: null, style: null,
panelClass: null panelClass: null,
virtualScrollerOptions: {
type: Object,
default: null
}
}, },
timeout: null, timeout: null,
outsideClickListener: null, outsideClickListener: null,
resizeListener: null, resizeListener: null,
scrollHandler: null, scrollHandler: null,
overlay: null, overlay: null,
virtualScroller: null,
data() { data() {
return { return {
searching: false, searching: false,
@ -154,6 +164,9 @@ export default {
} }
}, },
methods: { methods: {
getOptionIndex(index, fn) {
return this.virtualScrollerDisabled ? index : (fn && fn(index)['index']);
},
getOptionGroupRenderKey(optionGroup) { getOptionGroupRenderKey(optionGroup) {
return ObjectUtils.resolveFieldData(optionGroup, this.optionGroupLabel); return ObjectUtils.resolveFieldData(optionGroup, this.optionGroupLabel);
}, },
@ -529,6 +542,9 @@ export default {
overlayRef(el) { overlayRef(el) {
this.overlay = el; this.overlay = el;
}, },
virtualScrollerRef(el) {
this.virtualScroller = el;
},
onOverlayClick(event) { onOverlayClick(event) {
OverlayEventBus.emit('overlay-click', { OverlayEventBus.emit('overlay-click', {
originalEvent: event, originalEvent: event,
@ -585,10 +601,14 @@ export default {
}, },
appendTarget() { appendTarget() {
return this.appendDisabled ? null : this.appendTo; return this.appendDisabled ? null : this.appendTo;
},
virtualScrollerDisabled() {
return !this.virtualScrollerOptions;
} }
}, },
components: { components: {
'Button': Button 'Button': Button,
'VirtualScroller': VirtualScroller
}, },
directives: { directives: {
'ripple': Ripple 'ripple': Ripple