2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-06-19 09:50:33 +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> </style>
<template> <template>
<div class="dropdown v-select" :class="dropdownClasses"> <div class="dropdown v-select" :class="dropdownClasses">
<div v-el:toggle @mousedown.prevent="toggleDropdown" class="dropdown-toggle clearfix" type="button"> <div v-el:toggle @mousedown.prevent="toggleDropdown" class="dropdown-toggle clearfix" type="button">
<span class="form-control" v-if="!searchable && isValueEmpty"> <span class="form-control" v-if="!searchable && isValueEmpty">
{{ placeholder }} {{ placeholder }}
</span> </span>
@@ -132,40 +132,38 @@
</button> </button>
</span> </span>
<input <input
v-el:search v-el:search
v-show="searchable" v-show="searchable"
v-model="search" v-model="search"
@keydown.delete="maybeDeleteValue" @keydown.delete="maybeDeleteValue"
@keyup.esc="onEscape" @keyup.esc="onEscape"
@keyup.up.prevent="typeAheadUp" @keyup.up.prevent="typeAheadUp"
@keyup.down.prevent="typeAheadDown" @keyup.down.prevent="typeAheadDown"
@keyup.enter.prevent="typeAheadSelect" @keyup.enter.prevent="typeAheadSelect"
@blur="open = false" @blur="open = false"
@focus="open = true" @focus="open = true"
type="search" type="search"
class="form-control" class="form-control"
:placeholder="searchPlaceholder" :placeholder="searchPlaceholder"
:style="{ width: isValueEmpty ? '100%' : 'auto' }" :style="{ width: isValueEmpty ? '100%' : 'auto' }"
> >
<i v-el:open-indicator role="presentation" class="open-indicator"></i> <i v-el:open-indicator role="presentation" class="open-indicator"></i>
</div> </div>
<div v-el:dropdown-wrapper v-show="open" :transition="transition" class="dropdown-menu" :style="{ 'max-height': maxHeight }"> <ul v-el:dropdown-menu 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">
<li v-for="option in filteredOptions" track-by="$index" :class="{ active: isOptionSelected(option), highlight: $index === typeAheadPointer }" @mouseover="typeAheadPointer = $index"> <a @mousedown.prevent="select(option)">
<a @mousedown.prevent="select(option)"> {{ getOptionLabel(option) }}
{{ getOptionLabel(option) }} </a>
</a> </li>
</li> <li transition="fade" v-if="!filteredOptions.length" class="divider"></li>
<li transition="fade" v-if="!filteredOptions.length" class="divider"></li> <li transition="fade" v-if="!filteredOptions.length" class="text-center">
<li transition="fade" v-if="!filteredOptions.length" class="text-center"> <slot name="no-options">Sorry, no matching options.</slot>
<slot name="no-options">Sorry, no matching options.</slot> </li>
</li> </ul>
</ul>
</div> </div>
</div>
</template> </template>
@@ -478,25 +476,52 @@
}, },
maybeAdjustScrollPosition() { maybeAdjustScrollPosition() {
let pointerHeight = this.$els.dropdownMenu.children[this.typeAheadPointer].offsetHeight let bounds = this.viewport()
let pixelsToPointerTop = 0 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 pixelsToPointerTop += this.$els.dropdownMenu.children[i].offsetHeight
} }
return pixelsToPointerTop
},
let pixelsToPointerBottom = pixelsToPointerTop + pointerHeight pixelsToPointerBottom() {
return this.pixelsToPointerTop() + this.pointerHeight()
},
let bounds = { pixelsToPointerCenter() {
top: this.$els.dropdownWrapper.scrollTop, return this.pixelsToPointerTop() + ( this.pointerHeight() / 2 )
bottom: this.$els.dropdownWrapper.offsetHeight + this.$els.dropdownWrapper.scrollTop },
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 ) { scrollTo(position) {
this.$els.dropdownWrapper.scrollTop = pixelsToPointerTop return this.$els.dropdownMenu.scrollTop = position
} else if ( pixelsToPointerBottom >= bounds.bottom) {
this.$els.dropdownWrapper.scrollTop = ( pixelsToPointerBottom - this.$els.dropdownWrapper.offsetHeight ) + pointerHeight
}
}, },
/** /**
@@ -547,10 +572,6 @@
computed: { computed: {
scrollTop() {
return [this.$els.dropdownMenu.scrollTop,this.$el.scrollTop]
},
/** /**
* Classes to be output on .dropdown * Classes to be output on .dropdown
* @return {Object} * @return {Object}
+74 -1
View File
@@ -365,6 +365,79 @@ describe('Select.vue', () => {
vm.$children[0].typeAheadDown() vm.$children[0].typeAheadDown()
expect(vm.$children[0].typeAheadPointer).toEqual(2) 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', () => { describe('Removing values', () => {
@@ -611,4 +684,4 @@ describe('Select.vue', () => {
}) })
// also see example testing a component with mocks at // 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