2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-06-13 08:32:26 +03:00

feat: add autoscroll boolean prop (#1160)

* feat: add autoscroll boolean prop

Fixes #449

* refactor: update autoscroll implementation

Closes #1028
Closes #910

* refactor: only call maybeAdjustScroll in the watcher

* docs: upgrade vuepress
This commit is contained in:
Jeff Sagal
2020-04-12 15:44:52 -07:00
committed by GitHub
parent e65258df97
commit 2eb39087fd
7 changed files with 2364 additions and 1971 deletions
+28 -60
View File
@@ -1,8 +1,17 @@
export default {
props: {
autoscroll: {
type: Boolean,
default: true
}
},
watch: {
typeAheadPointer() {
this.maybeAdjustScroll();
}
if (this.autoscroll) {
this.maybeAdjustScroll();
}
},
},
methods: {
@@ -13,75 +22,34 @@ export default {
* @returns {*}
*/
maybeAdjustScroll() {
let pixelsToPointerTop = this.pixelsToPointerTop();
let pixelsToPointerBottom = this.pixelsToPointerBottom();
const optionEl =
this.$refs.dropdownMenu?.children[this.typeAheadPointer] || false;
if (pixelsToPointerTop <= this.viewport().top) {
return this.scrollTo(pixelsToPointerTop);
} else if (pixelsToPointerBottom >= this.viewport().bottom) {
return this.scrollTo(this.viewport().top + this.pointerHeight());
}
},
if (optionEl) {
const bounds = this.getDropdownViewport();
const { top, bottom, height } = optionEl.getBoundingClientRect();
/**
* The distance in pixels from the top of the dropdown
* list to the top of the current pointer element.
* @returns {number}
*/
pixelsToPointerTop() {
let pixelsToPointerTop = 0;
if (this.$refs.dropdownMenu && this.dropdownOpen) {
for (let i = 0; i < this.typeAheadPointer; i++) {
pixelsToPointerTop += this.$refs.dropdownMenu.children[i]
.offsetHeight;
if (top < bounds.top) {
return (this.$refs.dropdownMenu.scrollTop = optionEl.offsetTop);
} else if (bottom > bounds.bottom) {
return (this.$refs.dropdownMenu.scrollTop =
optionEl.offsetTop - (bounds.height - height));
}
}
return pixelsToPointerTop;
},
/**
* The distance in pixels from the top of the dropdown
* list to the bottom of the current pointer element.
* @returns {*}
*/
pixelsToPointerBottom() {
return this.pixelsToPointerTop() + this.pointerHeight();
},
/**
* The offsetHeight of the current pointer element.
* @returns {number}
*/
pointerHeight() {
let element = this.$refs.dropdownMenu
? this.$refs.dropdownMenu.children[this.typeAheadPointer]
: false;
return element ? element.offsetHeight : 0;
},
/**
* The currently viewable portion of the dropdownMenu.
* @returns {{top: (string|*|number), bottom: *}}
*/
viewport() {
return {
top: this.$refs.dropdownMenu ? this.$refs.dropdownMenu.scrollTop : 0,
bottom: this.$refs.dropdownMenu
? this.$refs.dropdownMenu.offsetHeight +
this.$refs.dropdownMenu.scrollTop
: 0
};
},
/**
* Scroll the dropdownMenu to a given position.
* @param position
* @returns {*}
*/
scrollTo(position) {
getDropdownViewport() {
return this.$refs.dropdownMenu
? (this.$refs.dropdownMenu.scrollTop = position)
: null;
? this.$refs.dropdownMenu.getBoundingClientRect()
: {
height: 0,
top: 0,
bottom: 0
};
}
}
};