mirror of
https://github.com/tenrok/vue-select.git
synced 2026-06-16 09:10:33 +03:00
Merge branch 'master' into master
This commit is contained in:
@@ -51,7 +51,7 @@ You may now use the component in your markup
|
|||||||
Just include `vue` & `vue-select.js` - I recommend using [unpkg](https://unpkg.com/#/).
|
Just include `vue` & `vue-select.js` - I recommend using [unpkg](https://unpkg.com/#/).
|
||||||
|
|
||||||
```html
|
```html
|
||||||
<script scr="https://unpkg.com/vue@latest"></script>
|
<script src="https://unpkg.com/vue@latest"></script>
|
||||||
<!-- use the latest release -->
|
<!-- use the latest release -->
|
||||||
<script src="https://unpkg.com/vue-select@latest"></script>
|
<script src="https://unpkg.com/vue-select@latest"></script>
|
||||||
<!-- or point to a specific release -->
|
<!-- or point to a specific release -->
|
||||||
|
|||||||
@@ -40,6 +40,17 @@
|
|||||||
<v-select placeholder="multiple, closeOnSelect=false" multiple :close-on-select="false" :options="['cat', 'dog', 'bear']"></v-select>
|
<v-select placeholder="multiple, closeOnSelect=false" multiple :close-on-select="false" :options="['cat', 'dog', 'bear']"></v-select>
|
||||||
<v-select placeholder="unsearchable" :options="options" :searchable="false"></v-select>
|
<v-select placeholder="unsearchable" :options="options" :searchable="false"></v-select>
|
||||||
<v-select placeholder="search github.." label="full_name" @search="search" :options="ajaxRes"></v-select>
|
<v-select placeholder="search github.." label="full_name" @search="search" :options="ajaxRes"></v-select>
|
||||||
|
<v-select placeholder="custom option template" :options="options" multiple>
|
||||||
|
<template slot="selected-option" scope="option">
|
||||||
|
<img :src='"https://www.kidlink.org/icons/f0-" + option.value.toLowerCase() + ".gif"'/>
|
||||||
|
{{option.label}}
|
||||||
|
</template>
|
||||||
|
<template slot="option" scope="option">
|
||||||
|
<img :src='"https://www.kidlink.org/icons/f0-" + option.value.toLowerCase() + ".gif"'/>
|
||||||
|
{{option.label}} ({{option.value}})
|
||||||
|
</template>
|
||||||
|
</v-select>
|
||||||
|
<v-select disabled placeholder="disabled" value="Some Selected Value"></v-select>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
|
|||||||
Vendored
+2
-2
File diff suppressed because one or more lines are too long
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -7,6 +7,7 @@
|
|||||||
"main": "dist/vue-select.js",
|
"main": "dist/vue-select.js",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
"start": "npm run dev",
|
||||||
"dev": "node build/dev-server.js",
|
"dev": "node build/dev-server.js",
|
||||||
"dev:docs": "node build/dev-server.js --docs",
|
"dev:docs": "node build/dev-server.js --docs",
|
||||||
"build": "node build/build.js",
|
"build": "node build/build.js",
|
||||||
|
|||||||
+32
-12
@@ -3,6 +3,12 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
font-family: sans-serif;
|
font-family: sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.v-select .disabled {
|
||||||
|
cursor: not-allowed !important;
|
||||||
|
background-color: rgb(248, 248, 248) !important;
|
||||||
|
}
|
||||||
|
|
||||||
.v-select,
|
.v-select,
|
||||||
.v-select * {
|
.v-select * {
|
||||||
-webkit-box-sizing: border-box;
|
-webkit-box-sizing: border-box;
|
||||||
@@ -33,7 +39,6 @@
|
|||||||
transition: all 150ms cubic-bezier(1.000, -0.115, 0.975, 0.855);
|
transition: all 150ms cubic-bezier(1.000, -0.115, 0.975, 0.855);
|
||||||
transition-timing-function: cubic-bezier(1.000, -0.115, 0.975, 0.855);
|
transition-timing-function: cubic-bezier(1.000, -0.115, 0.975, 0.855);
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
transition: opacity .1s;
|
|
||||||
height: 20px; width: 10px;
|
height: 20px; width: 10px;
|
||||||
}
|
}
|
||||||
.v-select .open-indicator:before {
|
.v-select .open-indicator:before {
|
||||||
@@ -71,7 +76,6 @@
|
|||||||
border: 1px solid rgba(60, 60, 60, .26);
|
border: 1px solid rgba(60, 60, 60, .26);
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
transition: border-radius .25s;
|
|
||||||
}
|
}
|
||||||
.v-select .dropdown-toggle:after {
|
.v-select .dropdown-toggle:after {
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
@@ -280,10 +284,12 @@
|
|||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="dropdown v-select" :class="dropdownClasses">
|
<div class="dropdown v-select" :class="dropdownClasses">
|
||||||
<div ref="toggle" @mousedown.prevent="toggleDropdown" class="dropdown-toggle">
|
<div ref="toggle" @mousedown.prevent="toggleDropdown" :class="['dropdown-toggle', 'clearfix', {'disabled': disabled}]">
|
||||||
|
|
||||||
<span class="selected-tag" v-for="option in valueAsArray" v-bind:key="option.index">
|
<span class="selected-tag" v-for="option in valueAsArray" v-bind:key="option.index">
|
||||||
{{ getOptionLabel(option) }}
|
<slot name="selected-option" v-bind="option">
|
||||||
|
{{ getOptionLabel(option) }}
|
||||||
|
</slot>
|
||||||
<button v-if="multiple" @click="deselect(option)" type="button" class="close" aria-label="Remove option">
|
<button v-if="multiple" @click="deselect(option)" type="button" class="close" aria-label="Remove option">
|
||||||
<span aria-hidden="true">×</span>
|
<span aria-hidden="true">×</span>
|
||||||
</button>
|
</button>
|
||||||
@@ -300,7 +306,7 @@
|
|||||||
@blur="onSearchBlur"
|
@blur="onSearchBlur"
|
||||||
@focus="onSearchFocus"
|
@focus="onSearchFocus"
|
||||||
type="search"
|
type="search"
|
||||||
class="form-control"
|
:class="[{'disabled': disabled}, 'form-control']"
|
||||||
:placeholder="searchPlaceholder"
|
:placeholder="searchPlaceholder"
|
||||||
:readonly="!searchable"
|
:readonly="!searchable"
|
||||||
:style="{ width: isValueEmpty ? '100%' : 'auto' }"
|
:style="{ width: isValueEmpty ? '100%' : 'auto' }"
|
||||||
@@ -308,7 +314,7 @@
|
|||||||
aria-label="Search for option"
|
aria-label="Search for option"
|
||||||
>
|
>
|
||||||
|
|
||||||
<i v-if="!noDrop" ref="openIndicator" role="presentation" class="open-indicator"></i>
|
<i v-if="!noDrop" ref="openIndicator" role="presentation" :class="[{'disabled': disabled}, 'open-indicator']"></i>
|
||||||
|
|
||||||
<slot name="spinner">
|
<slot name="spinner">
|
||||||
<div class="spinner" v-show="mutableLoading">Loading...</div>
|
<div class="spinner" v-show="mutableLoading">Loading...</div>
|
||||||
@@ -319,7 +325,9 @@
|
|||||||
<ul ref="dropdownMenu" v-if="dropdownOpen" class="dropdown-menu" :style="{ 'max-height': maxHeight }">
|
<ul ref="dropdownMenu" v-if="dropdownOpen" class="dropdown-menu" :style="{ 'max-height': maxHeight }">
|
||||||
<li v-for="(option, index) in filteredOptions" v-bind:key="index" :class="{ active: isOptionSelected(option), highlight: index === typeAheadPointer }" @mouseover="typeAheadPointer = index">
|
<li v-for="(option, index) in filteredOptions" v-bind:key="index" :class="{ active: isOptionSelected(option), highlight: index === typeAheadPointer }" @mouseover="typeAheadPointer = index">
|
||||||
<a @mousedown.prevent="select(option)">
|
<a @mousedown.prevent="select(option)">
|
||||||
|
<slot name="option" v-bind="option">
|
||||||
{{ getOptionLabel(option) }}
|
{{ getOptionLabel(option) }}
|
||||||
|
</slot>
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
<li v-if="!filteredOptions.length" class="no-options">
|
<li v-if="!filteredOptions.length" class="no-options">
|
||||||
@@ -354,7 +362,7 @@
|
|||||||
* If you are using an array of objects, vue-select will look for
|
* If you are using an array of objects, vue-select will look for
|
||||||
* a `label` key (ex. [{label: 'This is Foo', value: 'foo'}]). A
|
* a `label` key (ex. [{label: 'This is Foo', value: 'foo'}]). A
|
||||||
* custom label key can be set with the `label` prop.
|
* custom label key can be set with the `label` prop.
|
||||||
* @type {Object}
|
* @type {Array}
|
||||||
*/
|
*/
|
||||||
options: {
|
options: {
|
||||||
type: Array,
|
type: Array,
|
||||||
@@ -363,6 +371,15 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Disable the entire component.
|
||||||
|
* @type {Boolean}
|
||||||
|
*/
|
||||||
|
disabled: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the max-height property on the dropdown list.
|
* Sets the max-height property on the dropdown list.
|
||||||
* @deprecated
|
* @deprecated
|
||||||
@@ -384,7 +401,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Equivalent to the `multiple` attribute on a `<select>` input.
|
* Equivalent to the `multiple` attribute on a `<select>` input.
|
||||||
* @type {Object}
|
* @type {Boolean}
|
||||||
*/
|
*/
|
||||||
multiple: {
|
multiple: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
@@ -393,7 +410,7 @@
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Equivalent to the `placeholder` attribute on an `<input>`.
|
* Equivalent to the `placeholder` attribute on an `<input>`.
|
||||||
* @type {Object}
|
* @type {String}
|
||||||
*/
|
*/
|
||||||
placeholder: {
|
placeholder: {
|
||||||
type: String,
|
type: String,
|
||||||
@@ -442,6 +459,7 @@
|
|||||||
/**
|
/**
|
||||||
* Callback to generate the label text. If {option}
|
* Callback to generate the label text. If {option}
|
||||||
* is an object, returns option[this.label] by default.
|
* is an object, returns option[this.label] by default.
|
||||||
|
* @type {Function}
|
||||||
* @param {Object || String} option
|
* @param {Object || String} option
|
||||||
* @return {String}
|
* @return {String}
|
||||||
*/
|
*/
|
||||||
@@ -462,7 +480,7 @@
|
|||||||
* value(s) change. When integrating with Vuex, use this callback to trigger
|
* value(s) change. When integrating with Vuex, use this callback to trigger
|
||||||
* an action, rather than using :value.sync to retreive the selected value.
|
* an action, rather than using :value.sync to retreive the selected value.
|
||||||
* @type {Function}
|
* @type {Function}
|
||||||
* @default {null}
|
* @param {Object || String} val
|
||||||
*/
|
*/
|
||||||
onChange: {
|
onChange: {
|
||||||
type: Function,
|
type: Function,
|
||||||
@@ -693,8 +711,10 @@
|
|||||||
if (this.open) {
|
if (this.open) {
|
||||||
this.$refs.search.blur() // dropdown will close on blur
|
this.$refs.search.blur() // dropdown will close on blur
|
||||||
} else {
|
} else {
|
||||||
this.open = true
|
if (!this.disabled) {
|
||||||
this.$refs.search.focus()
|
this.open = true
|
||||||
|
this.$refs.search.focus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -315,6 +315,25 @@ describe('Select.vue', () => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('Toggling Dropdown', () => {
|
describe('Toggling Dropdown', () => {
|
||||||
|
it('should not open the dropdown when the el is clicked but the component is disabled', (done) => {
|
||||||
|
const vm = new Vue({
|
||||||
|
template: '<div><v-select :options="options" :value="value" disabled></v-select></div>',
|
||||||
|
components: {vSelect},
|
||||||
|
data: {
|
||||||
|
value: [{label: 'one'}],
|
||||||
|
options: [{label: 'one'}]
|
||||||
|
}
|
||||||
|
}).$mount()
|
||||||
|
|
||||||
|
vm.$children[0].toggleDropdown({target: vm.$children[0].$refs.search})
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
Vue.nextTick(() => {
|
||||||
|
expect(vm.$children[0].open).toEqual(false)
|
||||||
|
done()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
it('should open the dropdown when the el is clicked', (done) => {
|
it('should open the dropdown when the el is clicked', (done) => {
|
||||||
const vm = new Vue({
|
const vm = new Vue({
|
||||||
template: '<div><v-select :options="options" :value="value"></v-select></div>',
|
template: '<div><v-select :options="options" :value="value"></v-select></div>',
|
||||||
|
|||||||
Reference in New Issue
Block a user