2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-05-17 02:29:37 +03:00

remove wrapper, start add tests

This commit is contained in:
Jeff Sagal
2016-05-31 10:18:55 -07:00
parent eb003ef987
commit cf87f838fd
2 changed files with 144 additions and 50 deletions
+70 -49
View File
@@ -119,8 +119,8 @@
</style>
<template>
<div class="dropdown v-select" :class="dropdownClasses">
<div v-el:toggle @mousedown.prevent="toggleDropdown" class="dropdown-toggle clearfix" type="button">
<div class="dropdown v-select" :class="dropdownClasses">
<div v-el:toggle @mousedown.prevent="toggleDropdown" class="dropdown-toggle clearfix" type="button">
<span class="form-control" v-if="!searchable && isValueEmpty">
{{ placeholder }}
</span>
@@ -132,40 +132,38 @@
</button>
</span>
<input
v-el:search
v-show="searchable"
v-model="search"
@keydown.delete="maybeDeleteValue"
@keyup.esc="onEscape"
@keyup.up.prevent="typeAheadUp"
@keyup.down.prevent="typeAheadDown"
@keyup.enter.prevent="typeAheadSelect"
@blur="open = false"
@focus="open = true"
type="search"
class="form-control"
:placeholder="searchPlaceholder"
:style="{ width: isValueEmpty ? '100%' : 'auto' }"
>
<input
v-el:search
v-show="searchable"
v-model="search"
@keydown.delete="maybeDeleteValue"
@keyup.esc="onEscape"
@keyup.up.prevent="typeAheadUp"
@keyup.down.prevent="typeAheadDown"
@keyup.enter.prevent="typeAheadSelect"
@blur="open = false"
@focus="open = true"
type="search"
class="form-control"
:placeholder="searchPlaceholder"
:style="{ width: isValueEmpty ? '100%' : 'auto' }"
>
<i v-el:open-indicator role="presentation" class="open-indicator"></i>
</div>
<i v-el:open-indicator role="presentation" class="open-indicator"></i>
</div>
<div v-el:dropdown-wrapper v-show="open" :transition="transition" class="dropdown-menu" :style="{ 'max-height': maxHeight }">
<ul class="options" v-el:dropdown-menu>
<li v-for="option in filteredOptions" track-by="$index" :class="{ active: isOptionSelected(option), highlight: $index === typeAheadPointer }" @mouseover="typeAheadPointer = $index">
<a @mousedown.prevent="select(option)">
{{ getOptionLabel(option) }}
</a>
</li>
<li transition="fade" v-if="!filteredOptions.length" class="divider"></li>
<li transition="fade" v-if="!filteredOptions.length" class="text-center">
<slot name="no-options">Sorry, no matching options.</slot>
</li>
</ul>
<ul v-el:dropdown-menu v-show="open" :transition="transition" class="dropdown-menu" :style="{ 'max-height': maxHeight }">
<li v-for="option in filteredOptions" track-by="$index" :class="{ active: isOptionSelected(option), highlight: $index === typeAheadPointer }" @mouseover="typeAheadPointer = $index">
<a @mousedown.prevent="select(option)">
{{ getOptionLabel(option) }}
</a>
</li>
<li transition="fade" v-if="!filteredOptions.length" class="divider"></li>
<li transition="fade" v-if="!filteredOptions.length" class="text-center">
<slot name="no-options">Sorry, no matching options.</slot>
</li>
</ul>
</div>
</div>
</template>
@@ -478,25 +476,52 @@
},
maybeAdjustScrollPosition() {
let pointerHeight = this.$els.dropdownMenu.children[this.typeAheadPointer].offsetHeight
let pixelsToPointerTop = 0
let bounds = this.viewport()
let pixelsToPointerTop = this.pixelsToPointerTop()
let pixelsToPointerBottom = this.pixelsToPointerBottom()
let pointerHeight = this.pointerHeight()
for ( let i = 0; i < this.typeAheadPointer; i++ ) {
if (pixelsToPointerTop <= bounds.top) {
return this.scrollTo(pixelsToPointerTop)
} else if (pixelsToPointerBottom >= bounds.bottom) {
// return this.scrollTo(( this.pixelsToPointerCenter() - this.$els.dropdownMenu.offsetHeight ) + ( pointerHeight / 2))
return this.scrollTo(( this.pixelsToPointerCenter() - this.$els.dropdownMenu.offsetHeight ) + pointerHeight)
}
},
pixelsToPointerTop() {
let pixelsToPointerTop = 0
for (let i = 0; i < this.typeAheadPointer; i++) {
pixelsToPointerTop += this.$els.dropdownMenu.children[i].offsetHeight
}
return pixelsToPointerTop
},
let pixelsToPointerBottom = pixelsToPointerTop + pointerHeight
pixelsToPointerBottom() {
return this.pixelsToPointerTop() + this.pointerHeight()
},
let bounds = {
top: this.$els.dropdownWrapper.scrollTop,
bottom: this.$els.dropdownWrapper.offsetHeight + this.$els.dropdownWrapper.scrollTop
pixelsToPointerCenter() {
return this.pixelsToPointerTop() + ( this.pointerHeight() / 2 )
},
pointerHeight() {
return this.$els.dropdownMenu.children[this.typeAheadPointer].offsetHeight
},
/**
* The viewport is the currently viewable
* portion of the dropdown menu
*/
viewport() {
return {
top: this.$els.dropdownMenu.scrollTop,
bottom: this.$els.dropdownMenu.offsetHeight + this.$els.dropdownMenu.scrollTop
}
},
if( pixelsToPointerTop <= bounds.top ) {
this.$els.dropdownWrapper.scrollTop = pixelsToPointerTop
} else if ( pixelsToPointerBottom >= bounds.bottom) {
this.$els.dropdownWrapper.scrollTop = ( pixelsToPointerBottom - this.$els.dropdownWrapper.offsetHeight ) + pointerHeight
}
scrollTo(position) {
return this.$els.dropdownMenu.scrollTop = position
},
/**
@@ -547,10 +572,6 @@
computed: {
scrollTop() {
return [this.$els.dropdownMenu.scrollTop,this.$el.scrollTop]
},
/**
* Classes to be output on .dropdown
* @return {Object}
+74 -1
View File
@@ -365,6 +365,79 @@ describe('Select.vue', () => {
vm.$children[0].typeAheadDown()
expect(vm.$children[0].typeAheadPointer).toEqual(2)
})
it('should check if the scroll position needs to be adjusted on up arrow keyup', () => {
const vm = new Vue({
template: '<div><v-select :options="options"></v-select></div>',
components: {vSelect},
data: {
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].typeAheadPointer = 1
spyOn(vm.$children[0], 'maybeAdjustScrollPosition')
trigger(vm.$children[0].$els.search, 'keyup', (e) => e.keyCode = 38)
expect(vm.$children[0].maybeAdjustScrollPosition).toHaveBeenCalled()
})
it('should check if the scroll position needs to be adjusted on down arrow keyup', () => {
const vm = new Vue({
template: '<div><v-select :options="options" max-height="10"></v-select></div>',
components: {vSelect},
data: {
options: ['one', 'two', 'three']
}
}).$mount()
spyOn(vm.$children[0], 'maybeAdjustScrollPosition')
vm.$children[0].$els.search.focus()
trigger(vm.$children[0].$els.search, 'keyup', (e) => e.keyCode = 40)
expect(vm.$children[0].maybeAdjustScrollPosition).toHaveBeenCalled()
})
it('should scroll up if the new pointer is above the current viewport bounds', () => {
})
describe('Measuring pixel distances', () => {
it('should calculate pixelsToPointerTop as the sum of the height all options above the pointer', () => {
const vm = new Vue({
template: '<div><v-select :options="options"></v-select></div>',
components: {vSelect},
data: {
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].typeAheadPointer = 1
let lineHeight = vm.$children[0].$els.dropdownMenu.children[0].offsetHeight
expect(vm.$children[0].pixelsToPointerTop()).toEqual( lineHeight * 2 )
})
it('should calculate pixelsToPointerBottom as the sum of the height all options above the pointer plus the height of the pointer', () => {
const vm = new Vue({
template: '<div><v-select :options="options"></v-select></div>',
components: {vSelect},
data: {
options: ['one', 'two', 'three']
}
}).$mount()
vm.$children[0].typeAheadPointer = 1
let lineHeight = vm.$children[0].$els.dropdownMenu.children[0].offsetHeight
console.log(lineHeight)
expect(vm.$children[0].pixelsToPointerTop()).toEqual( lineHeight * 10 + lineHeight)
})
it('should calculate pixelsToPointerCenter', () => {
})
it('should calculate pointerHeight', () => {
})
})
})
describe('Removing values', () => {
@@ -611,4 +684,4 @@ describe('Select.vue', () => {
})
// also see example testing a component with mocks at
// https://github.com/vuejs/vueify-example/blob/master/test/unit/a.spec.js#L22-L43
// http://vue-loader.vuejs.org/en/workflow/testing-with-mocks.html