2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-06-22 10:30:34 +03:00

Merge branch 'master' into customizable-text

This commit is contained in:
Jeff Sagal
2021-08-01 12:38:43 -07:00
9 changed files with 658 additions and 615 deletions
+1
View File
@@ -19,6 +19,7 @@ export default {
required: true, required: true,
}, },
height: { height: {
type: [String, Number],
default: 250, default: 250,
}, },
}, },
+4 -1
View File
@@ -1,6 +1,9 @@
<template> <template>
<ul> <ul>
<li v-for="{ login, avatar_url, html_url, contributions } in contributors"> <li
v-for="{ login, avatar_url, html_url, contributions } in contributors"
:key="login"
>
<img :src="`${avatar_url}&s=75`" :alt="`${login}'s Avatar`" /> <img :src="`${avatar_url}&s=75`" :alt="`${login}'s Avatar`" />
<div> <div>
<a :href="html_url">@{{ login }}</a> <a :href="html_url">@{{ login }}</a>
+1 -1
View File
@@ -4,7 +4,7 @@
<th>Name</th> <th>Name</th>
<th>Country</th> <th>Country</th>
</tr> </tr>
<tr v-for="person in people"> <tr v-for="person in people" :key="person.name">
<td>{{ person.name }}</td> <td>{{ person.name }}</td>
<td> <td>
<v-select <v-select
+4 -4
View File
@@ -188,11 +188,11 @@
v-bind="configuration" v-bind="configuration"
placeholder="country objects, using option scoped slots" placeholder="country objects, using option scoped slots"
> >
<template slot="selected-option" slot-scope="{ label, value }"> <template slot="selected-option" slot-scope="option">
{{ label }} -- {{ value }} {{ option.label }} -- {{ option.value }}
</template> </template>
<template slot="option" slot-scope="{ label, value }"> <template slot="option" slot-scope="option">
{{ label }} ({{ value }}) {{ option.label }} ({{ option.value }})
</template> </template>
</v-select> </v-select>
</div> </div>
@@ -1,5 +1,6 @@
<template> <template>
<v-select> <v-select>
<!-- eslint-disable-next-line vue/no-unused-vars -->
<template #no-options="{ search, searching, loading }"> <template #no-options="{ search, searching, loading }">
This is the no options slot. This is the no options slot.
</template> </template>
@@ -1,4 +1,5 @@
<template> <template>
<!-- eslint-disable vue/no-unused-vars -->
<v-select :options="books" label="title"> <v-select :options="books" label="title">
<template <template
#selected-option-container="{ option, deselect, multiple, disabled }" #selected-option-container="{ option, deselect, multiple, disabled }"
+1 -1
View File
@@ -1,6 +1,6 @@
<template> <template>
<ul> <ul>
<li v-for="{ createdAt, login, avatarUrl } in sponsors"> <li v-for="{ createdAt, login, avatarUrl } in sponsors" :key="login">
<img :src="avatarUrl + '&s=150'" :alt="`@${login}'s avatar`" /> <img :src="avatarUrl + '&s=150'" :alt="`@${login}'s avatar`" />
<p> <p>
<a :href="`https://github.com/${login}`">@{{ login }}</a> <br /> <a :href="`https://github.com/${login}`">@{{ login }}</a> <br />
+184 -149
View File
@@ -8,12 +8,12 @@
<div <div
:id="`vs${uid}__combobox`" :id="`vs${uid}__combobox`"
ref="toggle" ref="toggle"
@mousedown="toggleDropdown($event)"
class="vs__dropdown-toggle" class="vs__dropdown-toggle"
role="combobox" role="combobox"
:aria-expanded="dropdownOpen.toString()" :aria-expanded="dropdownOpen.toString()"
:aria-owns="`vs${uid}__listbox`" :aria-owns="`vs${uid}__listbox`"
:aria-label="i18n.search.ariaLabel" aria-label="Search for option"
@mousedown="toggleDropdown($event)"
> >
<div ref="selectedOptions" class="vs__selected-options"> <div ref="selectedOptions" class="vs__selected-options">
<slot <slot
@@ -33,15 +33,13 @@
</slot> </slot>
<button <button
v-if="multiple" v-if="multiple"
ref="deselectButtons"
:disabled="disabled" :disabled="disabled"
@click="deselect(option)"
type="button" type="button"
class="vs__deselect" class="vs__deselect"
:title="i18n.deselectButton.ariaLabel(getOptionLabel(option))" :title="`Deselect ${getOptionLabel(option)}`"
:aria-label=" :aria-label="`Deselect ${getOptionLabel(option)}`"
i18n.deselectButton.ariaLabel(getOptionLabel(option)) @click="deselect(option)"
"
ref="deselectButtons"
> >
<component :is="childComponents.Deselect" /> <component :is="childComponents.Deselect" />
</button> </button>
@@ -60,13 +58,13 @@
<div ref="actions" class="vs__actions"> <div ref="actions" class="vs__actions">
<button <button
v-show="showClearButton" v-show="showClearButton"
ref="clearButton"
:disabled="disabled" :disabled="disabled"
type="button" type="button"
@click="clearSelection"
class="vs__clear" class="vs__clear"
title="i18n.clearButton.ariaLabel" title="Clear Selected"
aria-label="i18n.clearButton.ariaLabel" aria-label="Clear Selected"
ref="clearButton" @click="clearSelection"
> >
<component :is="childComponents.Deselect" /> <component :is="childComponents.Deselect" />
</button> </button>
@@ -80,31 +78,29 @@
</slot> </slot>
<slot name="spinner" v-bind="scope.spinner"> <slot name="spinner" v-bind="scope.spinner">
<div v-show="mutableLoading" class="vs__spinner"> <div v-show="mutableLoading" class="vs__spinner">Loading...</div>
{{ i18n.spinner.text }}
</div>
</slot> </slot>
</div> </div>
</div> </div>
<transition :name="transition"> <transition :name="transition">
<ul <ul
ref="dropdownMenu"
v-if="dropdownOpen" v-if="dropdownOpen"
:id="`vs${uid}__listbox`" :id="`vs${uid}__listbox`"
ref="dropdownMenu"
:key="`vs${uid}__listbox`" :key="`vs${uid}__listbox`"
v-append-to-body
class="vs__dropdown-menu" class="vs__dropdown-menu"
role="listbox" role="listbox"
tabindex="-1"
@mousedown.prevent="onMousedown" @mousedown.prevent="onMousedown"
@mouseup="onMouseUp" @mouseup="onMouseUp"
tabindex="-1"
v-append-to-body
> >
<slot name="list-header" v-bind="scope.listHeader" /> <slot name="list-header" v-bind="scope.listHeader" />
<li <li
v-for="(option, index) in filteredOptions" v-for="(option, index) in filteredOptions"
role="option"
:key="getOptionKey(option)"
:id="`vs${uid}__option-${index}`" :id="`vs${uid}__option-${index}`"
:key="getOptionKey(option)"
role="option"
class="vs__dropdown-option" class="vs__dropdown-option"
:class="{ :class="{
'vs__dropdown-option--selected': isOptionSelected(option), 'vs__dropdown-option--selected': isOptionSelected(option),
@@ -120,9 +116,9 @@
</slot> </slot>
</li> </li>
<li v-if="filteredOptions.length === 0" class="vs__no-options"> <li v-if="filteredOptions.length === 0" class="vs__no-options">
<slot name="no-options" v-bind="scope.noOptions">{{ <slot name="no-options" v-bind="scope.noOptions"
i18n.noOptions.text >Sorry, no matching options.</slot
}}</slot> >
</li> </li>
<slot name="list-footer" v-bind="scope.listFooter" /> <slot name="list-footer" v-bind="scope.listFooter" />
</ul> </ul>
@@ -137,13 +133,10 @@
</div> </div>
</template> </template>
<script type="text/babel"> <script>
import { import pointerScroll from '../mixins/pointerScroll'
ajax, import typeAheadPointer from '../mixins/typeAheadPointer'
pointerScroll, import ajax from '../mixins/ajax'
i18n,
pointer as typeAheadPointer,
} from '../mixins'
import childComponents from './childComponents' import childComponents from './childComponents'
import appendToBody from '../directives/appendToBody' import appendToBody from '../directives/appendToBody'
import sortAndStringify from '../utility/sortAndStringify' import sortAndStringify from '../utility/sortAndStringify'
@@ -157,7 +150,7 @@ export default {
directives: { appendToBody }, directives: { appendToBody },
mixins: [pointerScroll, typeAheadPointer, ajax, i18n], mixins: [pointerScroll, typeAheadPointer, ajax],
props: { props: {
/** /**
@@ -166,6 +159,7 @@ export default {
* using 'change' event using v-on * using 'change' event using v-on
* @type {Object||String||null} * @type {Object||String||null}
*/ */
// eslint-disable-next-line vue/require-default-prop,vue/require-prop-types
value: {}, value: {},
/** /**
@@ -529,6 +523,7 @@ export default {
* @type {String} * @type {String}
* @default {null} * @default {null}
*/ */
// eslint-disable-next-line vue/require-default-prop
inputId: { inputId: {
type: String, type: String,
}, },
@@ -582,6 +577,7 @@ export default {
* for the search input. Can be used to implement * for the search input. Can be used to implement
* custom behaviour for key presses. * custom behaviour for key presses.
*/ */
mapKeydown: { mapKeydown: {
type: Function, type: Function,
/** /**
@@ -653,6 +649,7 @@ export default {
open: false, open: false,
isComposing: false, isComposing: false,
pushedTags: [], pushedTags: [],
// eslint-disable-next-line vue/no-reserved-keys
_value: [], // Internal value managed by Vue Select if no `value` prop is passed _value: [], // Internal value managed by Vue Select if no `value` prop is passed
} }
}, },
@@ -664,7 +661,10 @@ export default {
* @return {boolean} * @return {boolean}
*/ */
isTrackingValues() { isTrackingValues() {
return typeof this.value === 'undefined' || this.$options.propsData.hasOwnProperty('reduce'); return (
typeof this.value === 'undefined' ||
this.$options.propsData.hasOwnProperty('reduce')
)
}, },
/** /**
@@ -672,17 +672,17 @@ export default {
* @return {Array} * @return {Array}
*/ */
selectedValue() { selectedValue() {
let value = this.value; let value = this.value
if (this.isTrackingValues) { if (this.isTrackingValues) {
// Vue select has to manage value internally // Vue select has to manage value internally
value = this.$data._value; value = this.$data._value
} }
if (value) { if (value) {
return [].concat(value); return [].concat(value)
} }
return []; return []
}, },
/** /**
@@ -693,7 +693,7 @@ export default {
* @return {Array} * @return {Array}
*/ */
optionList() { optionList() {
return this.options.concat(this.pushTags ? this.pushedTags : []); return this.options.concat(this.pushTags ? this.pushedTags : [])
}, },
/** /**
@@ -702,8 +702,10 @@ export default {
*/ */
searchEl() { searchEl() {
return !!this.$scopedSlots['search'] return !!this.$scopedSlots['search']
? this.$refs.selectedOptions.querySelector(this.searchInputQuerySelector) ? this.$refs.selectedOptions.querySelector(
: this.$refs.search; this.searchInputQuerySelector
)
: this.$refs.search
}, },
/** /**
@@ -715,38 +717,40 @@ export default {
search: this.search, search: this.search,
loading: this.loading, loading: this.loading,
searching: this.searching, searching: this.searching,
filteredOptions: this.filteredOptions filteredOptions: this.filteredOptions,
}; }
return { return {
search: { search: {
attributes: { attributes: {
'disabled': this.disabled, disabled: this.disabled,
'placeholder': this.searchPlaceholder, placeholder: this.searchPlaceholder,
'tabindex': this.tabindex, tabindex: this.tabindex,
'readonly': !this.searchable, readonly: !this.searchable,
'id': this.inputId, id: this.inputId,
'aria-autocomplete': 'list', 'aria-autocomplete': 'list',
'aria-labelledby': `vs${this.uid}__combobox`, 'aria-labelledby': `vs${this.uid}__combobox`,
'aria-controls': `vs${this.uid}__listbox`, 'aria-controls': `vs${this.uid}__listbox`,
'ref': 'search', ref: 'search',
'type': 'search', type: 'search',
'autocomplete': this.autocomplete, autocomplete: this.autocomplete,
'value': this.search, value: this.search,
...(this.dropdownOpen && this.filteredOptions[this.typeAheadPointer] ? { ...(this.dropdownOpen && this.filteredOptions[this.typeAheadPointer]
'aria-activedescendant': `vs${this.uid}__option-${this.typeAheadPointer}` ? {
} : {}), 'aria-activedescendant': `vs${this.uid}__option-${this.typeAheadPointer}`,
}
: {}),
}, },
events: { events: {
'compositionstart': () => this.isComposing = true, compositionstart: () => (this.isComposing = true),
'compositionend': () => this.isComposing = false, compositionend: () => (this.isComposing = false),
'keydown': this.onSearchKeyDown, keydown: this.onSearchKeyDown,
'blur': this.onSearchBlur, blur: this.onSearchBlur,
'focus': this.onSearchFocus, focus: this.onSearchFocus,
'input': (e) => this.search = e.target.value, input: (e) => (this.search = e.target.value),
}, },
}, },
spinner: { spinner: {
loading: this.mutableLoading loading: this.mutableLoading,
}, },
noOptions: { noOptions: {
search: this.search, search: this.search,
@@ -755,16 +759,16 @@ export default {
}, },
openIndicator: { openIndicator: {
attributes: { attributes: {
'ref': 'openIndicator', ref: 'openIndicator',
'role': 'presentation', role: 'presentation',
'class': 'vs__open-indicator', class: 'vs__open-indicator',
}, },
}, },
listHeader: listSlot, listHeader: listSlot,
listFooter: listSlot, listFooter: listSlot,
header: { ...listSlot, deselect: this.deselect }, header: { ...listSlot, deselect: this.deselect },
footer: { ...listSlot, deselect: this.deselect } footer: { ...listSlot, deselect: this.deselect },
}; }
}, },
/** /**
@@ -777,8 +781,8 @@ export default {
childComponents() { childComponents() {
return { return {
...childComponents, ...childComponents,
...this.components ...this.components,
}; }
}, },
/** /**
@@ -793,7 +797,7 @@ export default {
'vs--searchable': this.searchable && !this.noDrop, 'vs--searchable': this.searchable && !this.noDrop,
'vs--unsearchable': !this.searchable, 'vs--unsearchable': !this.searchable,
'vs--loading': this.mutableLoading, 'vs--loading': this.mutableLoading,
'vs--disabled': this.disabled 'vs--disabled': this.disabled,
} }
}, },
@@ -812,7 +816,7 @@ export default {
* @return {Boolean} True if open * @return {Boolean} True if open
*/ */
dropdownOpen() { dropdownOpen() {
return this.dropdownShouldOpen(this); return this.dropdownShouldOpen(this)
}, },
/** /**
@@ -821,9 +825,9 @@ export default {
* @return {String} Placeholder text * @return {String} Placeholder text
*/ */
searchPlaceholder() { searchPlaceholder() {
if (this.isValueEmpty && this.placeholder) { return this.isValueEmpty && this.placeholder
return this.placeholder; ? this.placeholder
} : undefined
}, },
/** /**
@@ -835,20 +839,22 @@ export default {
* @return {array} * @return {array}
*/ */
filteredOptions() { filteredOptions() {
const optionList = [].concat(this.optionList); const optionList = [].concat(this.optionList)
if (!this.filterable && !this.taggable) { if (!this.filterable && !this.taggable) {
return optionList; return optionList
} }
let options = this.search.length ? this.filter(optionList, this.search, this) : optionList; let options = this.search.length
? this.filter(optionList, this.search, this)
: optionList
if (this.taggable && this.search.length) { if (this.taggable && this.search.length) {
const createdOption = this.createOption(this.search); const createdOption = this.createOption(this.search)
if (!this.optionExists(createdOption)) { if (!this.optionExists(createdOption)) {
options.unshift(createdOption); options.unshift(createdOption)
} }
} }
return options; return options
}, },
/** /**
@@ -856,7 +862,7 @@ export default {
* @return {Boolean} * @return {Boolean}
*/ */
isValueEmpty() { isValueEmpty() {
return this.selectedValue.length === 0; return this.selectedValue.length === 0
}, },
/** /**
@@ -864,7 +870,9 @@ export default {
* @return {Boolean} * @return {Boolean}
*/ */
showClearButton() { showClearButton() {
return !this.multiple && this.clearable && !this.open && !this.isValueEmpty return (
!this.multiple && this.clearable && !this.open && !this.isValueEmpty
)
}, },
}, },
@@ -877,16 +885,21 @@ export default {
* @return {[type]} [description] * @return {[type]} [description]
*/ */
options(newOptions, oldOptions) { options(newOptions, oldOptions) {
let shouldReset = () => typeof this.resetOnOptionsChange === 'function' let shouldReset = () =>
? this.resetOnOptionsChange(newOptions, oldOptions, this.selectedValue) typeof this.resetOnOptionsChange === 'function'
: this.resetOnOptionsChange; ? this.resetOnOptionsChange(
newOptions,
oldOptions,
this.selectedValue
)
: this.resetOnOptionsChange
if (!this.taggable && shouldReset()) { if (!this.taggable && shouldReset()) {
this.clearSelection(); this.clearSelection()
} }
if (this.value && this.isTrackingValues) { if (this.value && this.isTrackingValues) {
this.setInternalValueFromOptions(this.value); this.setInternalValueFromOptions(this.value)
} }
}, },
@@ -903,7 +916,6 @@ export default {
/** /**
* Always reset the value when * Always reset the value when
* the multiple prop changes. * the multiple prop changes.
* @param {Boolean} isMultiple
* @return {void} * @return {void}
*/ */
multiple() { multiple() {
@@ -911,14 +923,14 @@ export default {
}, },
open(isOpen) { open(isOpen) {
this.$emit(isOpen ? 'open' : 'close'); this.$emit(isOpen ? 'open' : 'close')
} },
}, },
created() { created() {
this.mutableLoading = this.loading; this.mutableLoading = this.loading
if (typeof this.value !== "undefined" && this.isTrackingValues) { if (typeof this.value !== 'undefined' && this.isTrackingValues) {
this.setInternalValueFromOptions(this.value) this.setInternalValueFromOptions(this.value)
} }
@@ -934,9 +946,11 @@ export default {
*/ */
setInternalValueFromOptions(value) { setInternalValueFromOptions(value) {
if (Array.isArray(value)) { if (Array.isArray(value)) {
this.$data._value = value.map(val => this.findOptionFromReducedValue(val)); this.$data._value = value.map((val) =>
this.findOptionFromReducedValue(val)
)
} else { } else {
this.$data._value = this.findOptionFromReducedValue(value); this.$data._value = this.findOptionFromReducedValue(value)
} }
}, },
@@ -946,16 +960,16 @@ export default {
* @return {void} * @return {void}
*/ */
select(option) { select(option) {
this.$emit('option:selecting', option); this.$emit('option:selecting', option)
if (!this.isOptionSelected(option)) { if (!this.isOptionSelected(option)) {
if (this.taggable && !this.optionExists(option)) { if (this.taggable && !this.optionExists(option)) {
this.$emit('option:created', option); this.$emit('option:created', option)
} }
if (this.multiple) { if (this.multiple) {
option = this.selectedValue.concat(option) option = this.selectedValue.concat(option)
} }
this.updateValue(option); this.updateValue(option)
this.$emit('option:selected', option); this.$emit('option:selected', option)
} }
this.onAfterSelect(option) this.onAfterSelect(option)
}, },
@@ -966,11 +980,13 @@ export default {
* @return {void} * @return {void}
*/ */
deselect(option) { deselect(option) {
this.$emit('option:deselecting', option); this.$emit('option:deselecting', option)
this.updateValue(this.selectedValue.filter(val => { this.updateValue(
return !this.optionComparator(val, option); this.selectedValue.filter((val) => {
})); return !this.optionComparator(val, option)
this.$emit('option:deselected', option); })
)
this.$emit('option:deselected', option)
}, },
/** /**
@@ -988,7 +1004,7 @@ export default {
*/ */
onAfterSelect(option) { onAfterSelect(option) {
if (this.closeOnSelect) { if (this.closeOnSelect) {
this.open = !this.open; this.open = !this.open
this.searchEl.blur() this.searchEl.blur()
} }
@@ -1008,18 +1024,18 @@ export default {
updateValue(value) { updateValue(value) {
if (typeof this.value === 'undefined') { if (typeof this.value === 'undefined') {
// Vue select has to manage value // Vue select has to manage value
this.$data._value = value; this.$data._value = value
} }
if (value !== null) { if (value !== null) {
if (Array.isArray(value)) { if (Array.isArray(value)) {
value = value.map(val => this.reduce(val)); value = value.map((val) => this.reduce(val))
} else { } else {
value = this.reduce(value); value = this.reduce(value)
} }
} }
this.$emit('input', value); this.$emit('input', value)
}, },
/** /**
@@ -1028,9 +1044,9 @@ export default {
* @return {void} * @return {void}
*/ */
toggleDropdown(event) { toggleDropdown(event) {
const targetIsNotSearch = event.target !== this.searchEl; const targetIsNotSearch = event.target !== this.searchEl
if (targetIsNotSearch) { if (targetIsNotSearch) {
event.preventDefault(); event.preventDefault()
} }
// don't react to click on deselect/clear buttons, // don't react to click on deselect/clear buttons,
@@ -1038,18 +1054,23 @@ export default {
const ignoredButtons = [ const ignoredButtons = [
...(this.$refs['deselectButtons'] || []), ...(this.$refs['deselectButtons'] || []),
...([this.$refs['clearButton']] || []), ...([this.$refs['clearButton']] || []),
]; ]
if (this.searchEl === undefined || ignoredButtons.filter(Boolean).some(ref => ref.contains(event.target) || ref === event.target)) { if (
event.preventDefault(); this.searchEl === undefined ||
return; ignoredButtons
.filter(Boolean)
.some((ref) => ref.contains(event.target) || ref === event.target)
) {
event.preventDefault()
return
} }
if (this.open && targetIsNotSearch) { if (this.open && targetIsNotSearch) {
this.searchEl.blur(); this.searchEl.blur()
} else if (!this.disabled) { } else if (!this.disabled) {
this.open = true; this.open = true
this.searchEl.focus(); this.searchEl.focus()
} }
}, },
@@ -1059,7 +1080,9 @@ export default {
* @return {Boolean} True when selected | False otherwise * @return {Boolean} True when selected | False otherwise
*/ */
isOptionSelected(option) { isOptionSelected(option) {
return this.selectedValue.some(value => this.optionComparator(value, option)) return this.selectedValue.some((value) =>
this.optionComparator(value, option)
)
}, },
/** /**
@@ -1070,7 +1093,7 @@ export default {
* @returns {boolean} * @returns {boolean}
*/ */
optionComparator(a, b) { optionComparator(a, b) {
return this.getOptionKey(a) === this.getOptionKey(b); return this.getOptionKey(a) === this.getOptionKey(b)
}, },
/** /**
@@ -1082,15 +1105,13 @@ export default {
* @returns {*} * @returns {*}
*/ */
findOptionFromReducedValue(value) { findOptionFromReducedValue(value) {
const predicate = option => JSON.stringify(this.reduce(option)) === JSON.stringify(value); const predicate = (option) =>
JSON.stringify(this.reduce(option)) === JSON.stringify(value)
const matches = [ const matches = [...this.options, ...this.pushedTags].filter(predicate)
...this.options,
...this.pushedTags,
].filter(predicate);
if (matches.length === 1) { if (matches.length === 1) {
return matches[0]; return matches[0]
} }
/** /**
@@ -1099,7 +1120,11 @@ export default {
* unique reduced value. * unique reduced value.
* @see https://github.com/sagalbot/vue-select/issues/1089#issuecomment-597238735 * @see https://github.com/sagalbot/vue-select/issues/1089#issuecomment-597238735
*/ */
return matches.find(match => this.optionComparator(match, this.$data._value)) || value; return (
matches.find((match) =>
this.optionComparator(match, this.$data._value)
) || value
)
}, },
/** /**
@@ -1118,10 +1143,17 @@ export default {
* @return {this.value} * @return {this.value}
*/ */
maybeDeleteValue() { maybeDeleteValue() {
if (!this.searchEl.value.length && this.selectedValue && this.selectedValue.length && this.clearable) { if (
let value = null; !this.searchEl.value.length &&
this.selectedValue &&
this.selectedValue.length &&
this.clearable
) {
let value = null
if (this.multiple) { if (this.multiple) {
value = [...this.selectedValue.slice(0, this.selectedValue.length - 1)] value = [
...this.selectedValue.slice(0, this.selectedValue.length - 1),
]
} }
this.updateValue(value) this.updateValue(value)
} }
@@ -1135,7 +1167,9 @@ export default {
* @return {boolean} * @return {boolean}
*/ */
optionExists(option) { optionExists(option) {
return this.optionList.some(_option => this.optionComparator(_option, option)) return this.optionList.some((_option) =>
this.optionComparator(_option, option)
)
}, },
/** /**
@@ -1145,7 +1179,7 @@ export default {
* @return {*} * @return {*}
*/ */
normalizeOptionForSlot(option) { normalizeOptionForSlot(option) {
return (typeof option === 'object') ? option : {[this.label]: option}; return typeof option === 'object' ? option : { [this.label]: option }
}, },
/** /**
@@ -1156,7 +1190,7 @@ export default {
* @return {void} * @return {void}
*/ */
pushTag(option) { pushTag(option) {
this.pushedTags.push(option); this.pushedTags.push(option)
}, },
/** /**
@@ -1181,7 +1215,7 @@ export default {
if (this.mousedown && !this.searching) { if (this.mousedown && !this.searching) {
this.mousedown = false this.mousedown = false
} else { } else {
const { clearSearchOnSelect, multiple } = this; const { clearSearchOnSelect, multiple } = this
if (this.clearSearchOnBlur({ clearSearchOnSelect, multiple })) { if (this.clearSearchOnBlur({ clearSearchOnSelect, multiple })) {
this.search = '' this.search = ''
} }
@@ -1232,37 +1266,38 @@ export default {
* @return {Function} * @return {Function}
*/ */
onSearchKeyDown(e) { onSearchKeyDown(e) {
const preventAndSelect = e => { const preventAndSelect = (e) => {
e.preventDefault(); e.preventDefault()
return !this.isComposing && this.typeAheadSelect(); return !this.isComposing && this.typeAheadSelect()
}; }
const defaults = { const defaults = {
// backspace // backspace
8: e => this.maybeDeleteValue(), 8: (e) => this.maybeDeleteValue(),
// tab // tab
9: e => this.onTab(), 9: (e) => this.onTab(),
// esc // esc
27: e => this.onEscape(), 27: (e) => this.onEscape(),
// up.prevent // up.prevent
38: e => { 38: (e) => {
e.preventDefault(); e.preventDefault()
return this.typeAheadUp(); return this.typeAheadUp()
}, },
// down.prevent // down.prevent
40: e => { 40: (e) => {
e.preventDefault(); e.preventDefault()
return this.typeAheadDown(); return this.typeAheadDown()
}, },
}; }
this.selectOnKeyCodes.forEach(keyCode => defaults[keyCode] = preventAndSelect); this.selectOnKeyCodes.forEach(
(keyCode) => (defaults[keyCode] = preventAndSelect)
)
const handlers = this.mapKeydown(defaults, this); const handlers = this.mapKeydown(defaults, this)
if (typeof handlers[e.keyCode] === 'function') { if (typeof handlers[e.keyCode] === 'function') {
return handlers[e.keyCode](e); return handlers[e.keyCode](e)
}
} }
}, },
}, },
+2
View File
@@ -7,8 +7,10 @@ export default {
left, left,
width, width,
} = context.$refs.toggle.getBoundingClientRect() } = context.$refs.toggle.getBoundingClientRect()
let scrollX = window.scrollX || window.pageXOffset let scrollX = window.scrollX || window.pageXOffset
let scrollY = window.scrollY || window.pageYOffset let scrollY = window.scrollY || window.pageYOffset
el.unbindPosition = context.calculatePosition(el, context, { el.unbindPosition = context.calculatePosition(el, context, {
width: width + 'px', width: width + 'px',
left: scrollX + left + 'px', left: scrollX + left + 'px',