diff --git a/rollup.config.js b/rollup.config.js
index a4ed61d4d..dcc8492f2 100644
--- a/rollup.config.js
+++ b/rollup.config.js
@@ -14,6 +14,7 @@ let globalDependencies = {
'primevue/utils': 'primevue.utils',
'primevue/button': 'primevue.button',
'primevue/inputtext': 'primevue.inputtext',
+ 'primevue/virtualscroller': 'primevue.virtualscroller',
'primevue/dialog': 'primevue.dialog',
'primevue/paginator': 'primevue.paginator',
'primevue/confirmationeventbus': 'primevue.confirmationeventbus',
@@ -129,4 +130,4 @@ addUtils();
addApi();
addServices();
-export default entries;
\ No newline at end of file
+export default entries;
diff --git a/src/components/dropdown/Dropdown.vue b/src/components/dropdown/Dropdown.vue
index 3dd33a5c2..2c77effbf 100755
--- a/src/components/dropdown/Dropdown.vue
+++ b/src/components/dropdown/Dropdown.vue
@@ -23,32 +23,36 @@
-
-
-
- -
- {{getOptionLabel(option)}}
-
-
-
-
- -
- {{getOptionGroupLabel(optionGroup)}}
+
+
+
+
+
+ -
+ {{getOptionLabel(option)}}
+
+
+
+
+ -
+ {{getOptionGroupLabel(optionGroup)}}
+
+ -
+ {{getOptionLabel(option)}}
+
+
+
+ -
+ {{emptyFilterMessageText}}
- -
- {{getOptionLabel(option)}}
+
-
+ {{emptyMessageText}}
-
+
- -
- {{emptyFilterMessageText}}
-
- -
- {{emptyMessageText}}
-
-
+
@@ -62,6 +66,7 @@ import {ConnectedOverlayScrollHandler,ObjectUtils,DomHandler,ZIndexUtils} from '
import OverlayEventBus from 'primevue/overlayeventbus';
import {FilterService} from 'primevue/api';
import Ripple from 'primevue/ripple';
+import VirtualScroller from 'primevue/virtualscroller';
export default {
name: 'Dropdown',
@@ -117,6 +122,10 @@ export default {
loadingIcon: {
type: String,
default: 'pi pi-spinner pi-spin'
+ },
+ virtualScrollerOptions: {
+ type: Object,
+ default: null
}
},
data() {
@@ -135,6 +144,7 @@ export default {
searchValue: null,
overlay: null,
itemsWrapper: null,
+ virtualScroller: null,
beforeUnmount() {
this.unbindOutsideClickListener();
this.unbindResizeListener();
@@ -152,6 +162,12 @@ export default {
}
},
methods: {
+ getVisibleOptions(items) {
+ return items || this.visibleOptions;
+ },
+ getOptionIndex(index, fn) {
+ return this.virtualScrollerDisabled ? index : (fn && fn(index)['index']);
+ },
getOptionLabel(option) {
return this.optionLabel ? ObjectUtils.resolveFieldData(option, this.optionLabel) : option;
},
@@ -415,6 +431,13 @@ export default {
this.$refs.filterInput.focus();
}
+ if (!this.virtualScrollerDisabled) {
+ const selectedIndex = this.getSelectedOptionIndex();
+ if (selectedIndex !== -1) {
+ this.virtualScroller.scrollToIndex(selectedIndex);
+ }
+ }
+
this.$emit('show');
},
onOverlayLeave() {
@@ -581,6 +604,9 @@ export default {
itemsWrapperRef(el) {
this.itemsWrapper = el;
},
+ virtualScrollerRef(el) {
+ this.virtualScroller = el;
+ },
scrollValueInView() {
if (this.overlay) {
let selectedItem = DomHandler.findSingle(this.overlay, 'li.p-highlight');
@@ -675,6 +701,9 @@ export default {
appendDisabled() {
return this.appendTo === 'self';
},
+ virtualScrollerDisabled() {
+ return !this.virtualScrollerOptions;
+ },
appendTarget() {
return this.appendDisabled ? null : this.appendTo;
},
@@ -684,6 +713,9 @@ export default {
},
directives: {
'ripple': Ripple
+ },
+ components: {
+ 'VirtualScroller': VirtualScroller
}
}
diff --git a/src/views/dropdown/DropdownDemo.vue b/src/views/dropdown/DropdownDemo.vue
index b63e97daa..230fc521c 100755
--- a/src/views/dropdown/DropdownDemo.vue
+++ b/src/views/dropdown/DropdownDemo.vue
@@ -47,6 +47,9 @@
Loading State
+
+ Virtual Scroll (100000 Items)
+
@@ -64,6 +67,7 @@ export default {
selectedCity2: null,
selectedCountry: null,
selectedGroupedCity: null,
+ selectedItem: null,
cities: [
{name: 'New York', code: 'NY'},
{name: 'Rome', code: 'RM'},
@@ -84,7 +88,7 @@ export default {
{name: 'United States', code: 'US'}
],
groupedCities: [{
- label: 'Germany', code: 'DE',
+ label: 'Germany', code: 'DE',
items: [
{label: 'Berlin', value: 'Berlin'},
{label: 'Frankfurt', value: 'Frankfurt'},
@@ -93,7 +97,7 @@ export default {
]
},
{
- label: 'USA', code: 'US',
+ label: 'USA', code: 'US',
items: [
{label: 'Chicago', value: 'Chicago'},
{label: 'Los Angeles', value: 'Los Angeles'},
@@ -102,14 +106,15 @@ export default {
]
},
{
- label: 'Japan', code: 'JP',
+ label: 'Japan', code: 'JP',
items: [
{label: 'Kyoto', value: 'Kyoto'},
{label: 'Osaka', value: 'Osaka'},
{label: 'Tokyo', value: 'Tokyo'},
{label: 'Yokohama', value: 'Yokohama'}
]
- }]
+ }],
+ items: Array.from({ length: 100000 }, (_, i) => ({ label: `Item #${i}`, value: i }))
}
},
components: {
diff --git a/vue.config.js b/vue.config.js
index 8a01def02..a30740808 100644
--- a/vue.config.js
+++ b/vue.config.js
@@ -1,4 +1,4 @@
-const path = require('path');
+const path = require('path');
module.exports = {
publicPath: process.env.NODE_ENV === 'production' ? '/primevue/showcase/' : '/',
@@ -24,7 +24,8 @@ module.exports = {
'primevue/confirmationeventbus': path.resolve(__dirname, 'src/components/confirmationeventbus/ConfirmationEventBus.js'),
'primevue/toasteventbus': path.resolve(__dirname, 'src/components/toasteventbus/ToastEventBus.js'),
'primevue/overlayeventbus': path.resolve(__dirname, 'src/components/overlayeventbus/OverlayEventBus.js'),
- 'primevue/terminalservice': path.resolve(__dirname, 'src/components/terminalservice/TerminalService.js')
+ 'primevue/terminalservice': path.resolve(__dirname, 'src/components/terminalservice/TerminalService.js'),
+ 'primevue/virtualscroller': path.resolve(__dirname, 'src/components/virtualscroller/VirtualScroller.vue')
},
},
output: {
@@ -34,4 +35,4 @@ module.exports = {
css: {
extract: false
}
-}
\ No newline at end of file
+}