mirror of
https://github.com/tenrok/vue-select.git
synced 2026-06-22 10:30:34 +03:00
Merge branch 'master' into umd
# Conflicts: # src/components/Select.vue
This commit is contained in:
@@ -1,6 +1,9 @@
|
|||||||
# vue-select [](https://travis-ci.org/sagalbot/vue-select) [](https://codeclimate.com/github/sagalbot/vue-select) [](https://codeclimate.com/github/sagalbot/vue-select) [](https://gemnasium.com/github.com/sagalbot/vue-select)  
|
# vue-select [](https://travis-ci.org/sagalbot/vue-select) [](https://codeclimate.com/github/sagalbot/vue-select) [](https://gemnasium.com/github.com/sagalbot/vue-select)  
|
||||||
|
|
||||||
|
> A native Vue.js component that provides similar functionality to Select2 without the overhead of jQuery.
|
||||||
|
|
||||||
|
Rather than bringing in jQuery just to use Select2 or Chosen, this Vue.js component provides similar functionality without the extra overhead of jQuery, while providing the same awesome data-binding features you expect from Vue. Vue-select has no JavaScript dependencies other than Vue, and is designed to mimic [Select2](https://github.com/select2/select2).
|
||||||
|
|
||||||
> Rather than bringing in jQuery just to use Select2 or Chosen, this Vue.js component provides similar functionality without the extra overhead of jQuery, while providing the same awesome data-binding features you expect from Vue. Vue-select has no JavaScript dependencies other than Vue, and is designed to mimic [Select2](https://github.com/select2/select2).
|
|
||||||
|
|
||||||
#### Features
|
#### Features
|
||||||
|
|
||||||
|
|||||||
+23
-12
@@ -6,13 +6,14 @@ var path = require('path')
|
|||||||
var config = require('../config')
|
var config = require('../config')
|
||||||
var ora = require('ora')
|
var ora = require('ora')
|
||||||
var webpack = require('webpack')
|
var webpack = require('webpack')
|
||||||
|
var ghpages = require('gh-pages')
|
||||||
var webpackConfig = require('./webpack.prod.conf')
|
var webpackConfig = require('./webpack.prod.conf')
|
||||||
var umdConfig = require('./webpack.umd.conf')
|
var umdConfig = require('./webpack.umd.conf')
|
||||||
|
|
||||||
console.log(
|
console.log(
|
||||||
' Tip:\n' +
|
' Tip:\n' +
|
||||||
' Built files are meant to be served over an HTTP server.\n' +
|
' Built files are meant to be served over an HTTP server.\n' +
|
||||||
' Opening index.html over file:// won\'t work.\n'
|
' Opening index.html over file:// won\'t work.\n'
|
||||||
)
|
)
|
||||||
|
|
||||||
var spinner = ora('building for production...')
|
var spinner = ora('building for production...')
|
||||||
@@ -27,15 +28,25 @@ cp('-R', 'static/', assetsPath)
|
|||||||
* Build the /dist/ folder (demo site)
|
* Build the /dist/ folder (demo site)
|
||||||
*/
|
*/
|
||||||
webpack(webpackConfig, function (err, stats) {
|
webpack(webpackConfig, function (err, stats) {
|
||||||
spinner.stop()
|
spinner.stop()
|
||||||
if (err) throw err
|
if (err) throw err
|
||||||
process.stdout.write(stats.toString({
|
process.stdout.write(stats.toString({
|
||||||
colors: true,
|
colors: true,
|
||||||
modules: false,
|
modules: false,
|
||||||
children: false,
|
children: false,
|
||||||
chunks: false,
|
chunks: false,
|
||||||
chunkModules: false
|
chunkModules: false
|
||||||
}) + '\n')
|
}) + '\n')
|
||||||
|
|
||||||
|
// $ npm run build publish
|
||||||
|
// This will publish /dist/ to the gh-pages
|
||||||
|
if (( process.argv.indexOf('publish') > 1 )) {
|
||||||
|
spinner = ora('Publishing to GitHub Pages...').start()
|
||||||
|
ghpages.publish(path.join(__dirname, '../dist'), function (err) {
|
||||||
|
spinner.stop()
|
||||||
|
if (err) throw err
|
||||||
|
});
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ var projectRoot = path.resolve(__dirname, '../')
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
entry: {
|
entry: {
|
||||||
app: './src/main.js'
|
app: './docs/main.js'
|
||||||
},
|
},
|
||||||
output: {
|
output: {
|
||||||
path: config.build.assetsRoot,
|
path: config.build.assetsRoot,
|
||||||
@@ -17,8 +17,9 @@ module.exports = {
|
|||||||
fallback: [path.join(__dirname, '../node_modules')],
|
fallback: [path.join(__dirname, '../node_modules')],
|
||||||
alias: {
|
alias: {
|
||||||
'src': path.resolve(__dirname, '../src'),
|
'src': path.resolve(__dirname, '../src'),
|
||||||
'assets': path.resolve(__dirname, '../src/assets'),
|
'assets': path.resolve(__dirname, '../docs/assets'),
|
||||||
'components': path.resolve(__dirname, '../src/components')
|
'mixins': path.resolve(__dirname, '../src/mixins'),
|
||||||
|
'components': path.resolve(__dirname, '../docs/components')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
resolveLoader: {
|
resolveLoader: {
|
||||||
@@ -45,7 +46,7 @@ module.exports = {
|
|||||||
loader: 'vue-html'
|
loader: 'vue-html'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
|
test: /\.(png|jpe?g|gif)(\?.*)?$/,
|
||||||
loader: 'url',
|
loader: 'url',
|
||||||
query: {
|
query: {
|
||||||
limit: 10000,
|
limit: 10000,
|
||||||
@@ -53,7 +54,7 @@ module.exports = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
|
test: /\.(woff2?|eot|ttf|otf|svg)(\?.*)?$/,
|
||||||
loader: 'url',
|
loader: 'url',
|
||||||
query: {
|
query: {
|
||||||
limit: 10000,
|
limit: 10000,
|
||||||
|
|||||||
+2
-2
@@ -6,8 +6,8 @@ module.exports = {
|
|||||||
env: require('./prod.env'),
|
env: require('./prod.env'),
|
||||||
index: path.resolve(__dirname, '../dist/index.html'),
|
index: path.resolve(__dirname, '../dist/index.html'),
|
||||||
assetsRoot: path.resolve(__dirname, '../dist'),
|
assetsRoot: path.resolve(__dirname, '../dist'),
|
||||||
assetsSubDirectory: 'static',
|
assetsSubDirectory: '',
|
||||||
assetsPublicPath: '/',
|
assetsPublicPath: ( process.argv.indexOf('publish') > 1 ) ? 'http://sagalbot.github.io/vue-select/' : '/',
|
||||||
productionSourceMap: true
|
productionSourceMap: true
|
||||||
},
|
},
|
||||||
dev: {
|
dev: {
|
||||||
|
|||||||
@@ -0,0 +1,32 @@
|
|||||||
|
<style lang="scss">
|
||||||
|
@import 'assets/scss/_demo.scss';
|
||||||
|
@import 'assets/scss/_cyan_theme.scss';
|
||||||
|
@import 'assets/scss/_prism.scss';
|
||||||
|
@import 'assets/scss/_octicons.scss';
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="container">
|
||||||
|
<div class="col-md-10 col-md-offset-1">
|
||||||
|
<examples></examples>
|
||||||
|
<params></params>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note that this file (and anything other than src/components/Select.vue)
|
||||||
|
* has nothing to do with how you use vue-select. These files are used
|
||||||
|
* for the demo site at http://sagalbot.github.io/vue-select/.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import Examples from './components/Examples.vue'
|
||||||
|
import Params from './components/Params.vue'
|
||||||
|
import Ajax from './components/snippets/Ajax.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: { Params, Examples, Ajax }
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
@@ -49,13 +49,15 @@ p.lead {
|
|||||||
|
|
||||||
.btn-outline {
|
.btn-outline {
|
||||||
background: none;
|
background: none;
|
||||||
padding: 10px 16px;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 1.3333333;
|
line-height: 1.3333333;
|
||||||
border-radius: 6px;
|
border-radius: 6px;
|
||||||
border: 3px solid #91ddec;
|
border: 2px solid #91ddec;
|
||||||
color: #147688;
|
color: #147688;
|
||||||
|
|
||||||
|
&.btn-lg {
|
||||||
|
border-width: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
border-color: rgb(65, 184, 131);
|
border-color: rgb(65, 184, 131);
|
||||||
background-color: rgba(65, 184, 131, 0.67);
|
background-color: rgba(65, 184, 131, 0.67);
|
||||||
@@ -83,4 +85,13 @@ p.lead {
|
|||||||
.selected-tag .close {
|
.selected-tag .close {
|
||||||
font-family: "Helvetica Neue", "Helvetica";
|
font-family: "Helvetica Neue", "Helvetica";
|
||||||
font-weight: 400;
|
font-weight: 400;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accolades a {
|
||||||
|
margin-left: 0;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.doc-row {
|
||||||
|
padding: 2em 0;
|
||||||
}
|
}
|
||||||
@@ -1,9 +1,9 @@
|
|||||||
@font-face {
|
@font-face {
|
||||||
font-family: 'octicons';
|
font-family: 'octicons';
|
||||||
src: url('./assets/fonts/octicons.eot?#iefix') format('embedded-opentype'),
|
src: url('~assets/fonts/octicons.eot?#iefix') format('embedded-opentype'),
|
||||||
url('./assets/fonts/octicons.woff') format('woff'),
|
url('~assets/fonts/octicons.woff') format('woff'),
|
||||||
url('./assets/fonts/octicons.ttf') format('truetype'),
|
url('~assets/fonts/octicons.ttf') format('truetype'),
|
||||||
url('./assets/fonts/octicons.svg#octicons') format('svg');
|
url('~assets/fonts/octicons.svg#octicons') format('svg');
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
@@ -14,48 +14,52 @@
|
|||||||
|
|
||||||
<h2 class="page-header" id="examples">Examples</h2>
|
<h2 class="page-header" id="examples">Examples</h2>
|
||||||
|
|
||||||
<h3 class="page-header">Single/Multiple Selection</h3>
|
<article class="doc-row" id="ex-multiple">
|
||||||
<div class="row">
|
<h3 class="page-header">Single/Multiple Selection</h3>
|
||||||
<div class="col-md-6">
|
<div class="row">
|
||||||
<h4>Single Option Select</h4>
|
<div class="col-md-6">
|
||||||
<pre><v-code lang="markup"><v-select :options="countries"></v-select></v-code></pre>
|
<h4>Single Option Select</h4>
|
||||||
<v-select :options="countries"></v-select>
|
<pre><v-code lang="markup"><v-select :options="countries"></v-select></v-code></pre>
|
||||||
</div>
|
<v-select :options="countries"></v-select>
|
||||||
|
|
||||||
<div class="col-md-6">
|
|
||||||
<h4>Multiple Option Select</h4>
|
|
||||||
<pre><v-code lang="markup"><v-select multiple :options="countries"></v-select></v-code></pre>
|
|
||||||
<v-select multiple :options="countries"></v-select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<h3 class="page-header">Reactive Options</h3>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-6">
|
|
||||||
<p>When the list of options provided by the parent changes, vue-select will react as you'd expect.</p>
|
|
||||||
<div style="margin-top:0;" class="radio">
|
|
||||||
<label>
|
|
||||||
<input type="radio" name="reactive-options" v-model="reactive" :value="countries">
|
|
||||||
<v-code lang="markup"><v-select :options="countries"></v-select></v-code>
|
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="radio">
|
<div class="col-md-6">
|
||||||
<label>
|
<h4>Multiple Option Select</h4>
|
||||||
<input type="radio" name="reactive-options" v-model="reactive" :value="['foo','bar','baz']">
|
<pre><v-code lang="markup"><v-select multiple :options="countries"></v-select></v-code></pre>
|
||||||
<v-code lang="markup"><v-select options="['foo','bar','baz']"></v-select></v-code>
|
<v-select multiple :options="countries"></v-select>
|
||||||
</label>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
<div class="col-md-6">
|
<article class="doc-row" id="ex-reactive">
|
||||||
<v-select :options="reactive"></v-select>
|
<h3 class="page-header">Reactive Options</h3>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<p>When the list of options provided by the parent changes, vue-select will react as you'd expect.</p>
|
||||||
|
<div style="margin-top:0;" class="radio">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="reactive-options" v-model="reactive" :value="countries">
|
||||||
|
<v-code lang="markup"><v-select :options="countries"></v-select></v-code>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="radio">
|
||||||
|
<label>
|
||||||
|
<input type="radio" name="reactive-options" v-model="reactive" :value="['foo','bar','baz']">
|
||||||
|
<v-code lang="markup"><v-select options="['foo','bar','baz']"></v-select></v-code>
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<v-select :options="reactive"></v-select>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</article>
|
||||||
|
|
||||||
<h3 class="page-header">Two-Way Value Syncing</h3>
|
<article class="doc-row" id="ex-syncing">
|
||||||
<div class="row">
|
<h3 class="page-header">Two-Way Value Syncing</h3>
|
||||||
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<p>The most common use case for vue-select is being able to sync the components value with a parent component. The <code>value</code> property supports two-way data binding to accomplish this.</p>
|
<p>The most common use case for vue-select is being able to sync the components value with a parent component. The <code>value</code> property supports two-way data binding to accomplish this.</p>
|
||||||
<p>The <code>.sync</code> data-binding modifier is completely optional. You may use <code>value</code> without a two-way binding to preselect options.</p>
|
<p>The <code>.sync</code> data-binding modifier is completely optional. You may use <code>value</code> without a two-way binding to preselect options.</p>
|
||||||
@@ -78,9 +82,11 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
<h3 class="page-header">Custom Labels</h3>
|
<article class="doc-row" id="ex-labels">
|
||||||
<div class="row">
|
<h3 class="page-header">Custom Labels</h3>
|
||||||
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<p>By default when the <code>options</code> array contains objects, <code>vue-select</code> looks for the <code>label</code> key for display. If your data source doesn't contain that key, you can set your own using the <code>label</code> prop.</p>
|
<p>By default when the <code>options</code> array contains objects, <code>vue-select</code> looks for the <code>label</code> key for display. If your data source doesn't contain that key, you can set your own using the <code>label</code> prop.</p>
|
||||||
<p>On this page, the list of countries used in the examples contains <code>value</code> and <code>label</code> properties: <v-code lang="json">{value: "CA", label: "Canada"}</v-code>. In this example, we'll display the country code instead of the label.</p>
|
<p>On this page, the list of countries used in the examples contains <code>value</code> and <code>label</code> properties: <v-code lang="json">{value: "CA", label: "Canada"}</v-code>. In this example, we'll display the country code instead of the label.</p>
|
||||||
@@ -91,9 +97,11 @@
|
|||||||
<v-select :options="countries" label="value"></v-select>
|
<v-select :options="countries" label="value"></v-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
<h3 class="page-header">On-Change Callback <small>Vuex Compatibility</small></h3>
|
<article class="doc-row" id="ex-vuex">
|
||||||
<div class="row">
|
<h3 class="page-header">On-Change Callback <small>Vuex Compatibility</small></h3>
|
||||||
|
<div class="row">
|
||||||
<div class="col-md-6">
|
<div class="col-md-6">
|
||||||
<p>vue-select provides an <code>onChange</code> property that accepts a callback function. This function is passed the currently selected value(s) as it's only parameter.</p>
|
<p>vue-select provides an <code>onChange</code> property that accepts a callback function. This function is passed the currently selected value(s) as it's only parameter.</p>
|
||||||
<p>This is very useful when integrating with Vuex, as it will allow your to trigger an action to update your vuex state object. Choose a callback and see it in action.</p>
|
<p>This is very useful when integrating with Vuex, as it will allow your to trigger an action to update your vuex state object. Choose a callback and see it in action.</p>
|
||||||
@@ -127,13 +135,12 @@
|
|||||||
<v-select :options="countries" :on-change="getCallback"></v-select>
|
<v-select :options="countries" :on-change="getCallback"></v-select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</article>
|
||||||
|
|
||||||
|
<ajax></ajax>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style type="scss">
|
|
||||||
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
/**
|
/**
|
||||||
* Note that this file (and anything other than src/components/Select.vue)
|
* Note that this file (and anything other than src/components/Select.vue)
|
||||||
@@ -141,13 +148,15 @@
|
|||||||
* for the demo site at http://sagalbot.github.io/vue-select/. They'll
|
* for the demo site at http://sagalbot.github.io/vue-select/. They'll
|
||||||
* be moved out of this repo in the very near future to avoid confusion.
|
* be moved out of this repo in the very near future to avoid confusion.
|
||||||
*/
|
*/
|
||||||
import countries from '../countries/advanced'
|
import countries from '../data/advanced'
|
||||||
import simple from '../countries/simple'
|
import simple from '../data/simple'
|
||||||
import vSelect from './Select.vue'
|
import vSelect from 'src/components/Select.vue'
|
||||||
import vCode from './Code.vue'
|
import vCode from './Code.vue'
|
||||||
|
import Ajax from './snippets/Ajax.vue'
|
||||||
import InstallSnippet from './snippets/InstallSnippet.vue'
|
import InstallSnippet from './snippets/InstallSnippet.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
components: {vSelect,vCode,InstallSnippet},
|
components: {vSelect,vCode,InstallSnippet,Ajax},
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
countries,
|
countries,
|
||||||
@@ -0,0 +1,122 @@
|
|||||||
|
<style lang="scss">
|
||||||
|
.github-search {
|
||||||
|
&.panel-default {
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-heading,
|
||||||
|
.panel-footer {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-heading {
|
||||||
|
padding: 0;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-body {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
border-left: 1px solid #ddd;
|
||||||
|
border-right: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
.panel-footer {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-select .dropdown-toggle {
|
||||||
|
border-color: #ddd;
|
||||||
|
border-bottom-left-radius: 0;
|
||||||
|
border-bottom-right-radius: 0;
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-select .dropdown-toggle .open-indicator {
|
||||||
|
top: 15px;
|
||||||
|
right: 15px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-select .selected-tag {
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.gravatar {
|
||||||
|
max-width: 25px;
|
||||||
|
float: left;
|
||||||
|
margin-right: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
background: #7BC8A4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.list-inline {
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<div class="github-search panel panel-default">
|
||||||
|
<div class="panel-heading">
|
||||||
|
<v-select :debounce="250" :value.sync="repo" :options="options" :on-search="getOptions" placeholder="Search GitHub Repositories..." label="full_name"></v-select>
|
||||||
|
</div>
|
||||||
|
<div class="panel-body" v-if="repo">
|
||||||
|
<img :src="repo.owner.avatar_url" alt="{{ repo.owner.login }}" class="gravatar">
|
||||||
|
<p>{{ repo.description }}</p>
|
||||||
|
</div>
|
||||||
|
<div class="panel-footer" v-if="repo">
|
||||||
|
<ul class="list-inline" role="tablist">
|
||||||
|
<li><a href="{{ repo.url }}">Stars <span class="badge">{{ repo.stargazers_count }}</span></a>
|
||||||
|
</li>
|
||||||
|
<li><a href="{{ repo.url }}">Forks <span class="badge">{{ repo.forks }}</span></a></li>
|
||||||
|
<li><a href="{{ repo.url }}">Open Issues
|
||||||
|
<span class="badge">{{ repo.open_issues_count }}</span></a></li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div v-if="error" class="alert alert-warning" role="alert">
|
||||||
|
<button type="button" class="close" @click="error = null">
|
||||||
|
<span aria-hidden="true">×</span></button>
|
||||||
|
{{ error.message }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
repo: null,
|
||||||
|
error: null,
|
||||||
|
options: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getOptions(search, loading) {
|
||||||
|
loading(true)
|
||||||
|
this.$http.get('https://api.github.com/search/repositories', {q: search})
|
||||||
|
.then(resp => {
|
||||||
|
this.options = resp.data.items
|
||||||
|
loading(false)
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
this.error = err.data
|
||||||
|
loading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<p><v-select :debounce="250" :options="options" :on-search="getOptions" placeholder="Search GitHub Repositories..." label="full_name"></v-select></p>
|
||||||
|
|
||||||
|
<div v-if="error" class="alert alert-warning" role="alert">
|
||||||
|
<button type="button" class="close" @click="error = null">
|
||||||
|
<span aria-hidden="true">×</span></button>
|
||||||
|
{{ error.message }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
repo: null,
|
||||||
|
error: null,
|
||||||
|
options: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getOptions(search, loading) {
|
||||||
|
loading(true)
|
||||||
|
this.$http.get('https://api.github.com/search/repositories', {q: search})
|
||||||
|
.then(resp => {
|
||||||
|
this.options = resp.data.items
|
||||||
|
loading(false)
|
||||||
|
})
|
||||||
|
.catch(err => {
|
||||||
|
this.error = err.data
|
||||||
|
loading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,130 @@
|
|||||||
|
<template>
|
||||||
|
<article class="example" id="ex-ajax">
|
||||||
|
<h3 id="ajax" class="page-header">AJAX Remote Option Loading</h3>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<p>
|
||||||
|
The <code>onSearch</code> prop allows you to load options via ajax in a parent component
|
||||||
|
when the search text is updated. It is invoked with two parameters, <code>search</code> & <code>loading</code>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4>onSearch Callback Parameters <small>search, loading</small></h4>
|
||||||
|
<p>
|
||||||
|
<code>search</code> is a string containing the current search text.
|
||||||
|
<code>loading</code> is a function that accepts a boolean value,
|
||||||
|
and is used to toggle the 'loading' class on the top-level vue-select wrapper.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4>Loading Spinner</h4>
|
||||||
|
<p>
|
||||||
|
Vue Select includes a default loading spinner that appears when the loading class is present.
|
||||||
|
The <code>spinner</code> slot allows you to implement your own spinner.
|
||||||
|
|
||||||
|
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<div id="spinner-example" :class="{loading:spinner}">
|
||||||
|
<button class="btn btn-sm btn-default" @click="spinner = !spinner">Toggle Spinner</button>
|
||||||
|
<div class="spinner" v-show="spinner">Loading...</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<h4>Debounce Input</h4>
|
||||||
|
<p>
|
||||||
|
Vue Select also accepts a <code>debounce</code> prop that can be used to prevent
|
||||||
|
<code>onSearch</code> from being called until input has completed.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<h4>Library Agnostic</h4>
|
||||||
|
<p>
|
||||||
|
Since Vue.js does not ship with ajax functionality as part of the core library,
|
||||||
|
it's up to you to process the ajax requests in your parent component.
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-6">
|
||||||
|
<h4>Example <small>GitHub API</small></h4>
|
||||||
|
<p>In this example,
|
||||||
|
<a href="https://github.com/vuejs/vue-resource">Vue Resource</a> is used to access the
|
||||||
|
<a href="https://developer.github.com/v3/">GitHub API</a>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<git-hub-search-basic></git-hub-search-basic>
|
||||||
|
<ajax-example></ajax-example>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</article>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style>
|
||||||
|
#spinner-example {
|
||||||
|
max-width: 10em;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#spinner-example .spinner {
|
||||||
|
display: none;
|
||||||
|
display: inline-block;
|
||||||
|
float: right;
|
||||||
|
opacity: 0;
|
||||||
|
font-size: 5px;
|
||||||
|
text-indent: -9999em;
|
||||||
|
border-top: .9em solid rgba(100,100,100,.1);
|
||||||
|
border-right: .9em solid rgba(100,100,100,.1);
|
||||||
|
border-bottom: .9em solid rgba(100,100,100,.1);
|
||||||
|
border-left: .9em solid rgba(60,60,60,.45);
|
||||||
|
transform: translateZ(0);
|
||||||
|
animation: vSelectSpinner 1.1s infinite linear;
|
||||||
|
transition: opacity .1s;
|
||||||
|
}
|
||||||
|
#spinner-example.loading .spinner {
|
||||||
|
opacity: 1;
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
#spinner-example .spinner,
|
||||||
|
#spinner-example .spinner:after {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 5em;
|
||||||
|
height: 5em;
|
||||||
|
}
|
||||||
|
@-webkit-keyframes vSelectSpinner {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes vSelectSpinner {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
import GitHubSearchBasic from 'components/GitHubSearchBasic.vue'
|
||||||
|
import GitHubSearch from 'components/GitHubSearch.vue'
|
||||||
|
import AjaxProps from './AjaxProps.vue'
|
||||||
|
import AjaxExample from './AjaxExample.vue'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {GitHubSearchBasic, GitHubSearch, AjaxProps, AjaxExample},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
basicSource: false,
|
||||||
|
spinner: false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,31 @@
|
|||||||
|
<template>
|
||||||
|
<pre><v-code lang="markup"><v-select
|
||||||
|
:debounce="250"
|
||||||
|
:on-search="getOptions"
|
||||||
|
:options="options"
|
||||||
|
placeholder="Search GitHub Repositories..."
|
||||||
|
label="full_name"
|
||||||
|
>
|
||||||
|
</v-select></v-code></pre>
|
||||||
|
<pre><v-code lang="javascript">data() {
|
||||||
|
return {
|
||||||
|
options: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getOptions(search, loading) {
|
||||||
|
loading(true)
|
||||||
|
this.$http.get('https://api.github.com/search/repositories', {
|
||||||
|
q: search
|
||||||
|
}).then(resp => {
|
||||||
|
this.options = resp.data.items
|
||||||
|
loading(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</v-code></pre>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
export default {}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
<template>
|
||||||
|
<pre><v-code lang="javascript">/**
|
||||||
|
* Accept a callback function that will be run
|
||||||
|
* when the search text changes. The callback
|
||||||
|
* will be invoked with these parameters:
|
||||||
|
|
||||||
|
* @param {search} String Current search text
|
||||||
|
* @param {loading} Function(bool) Toggle loading class
|
||||||
|
*/
|
||||||
|
onSearch: {
|
||||||
|
type: Function,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Milliseconds to wait before invoking this.onSearch().
|
||||||
|
* Used to prevent sending an AJAX request until input
|
||||||
|
* has completed.
|
||||||
|
*/
|
||||||
|
debounce: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}</v-code></pre>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script type="text/babel">
|
||||||
|
export default {}
|
||||||
|
</script>
|
||||||
@@ -0,0 +1,49 @@
|
|||||||
|
import 'prismjs'
|
||||||
|
import Vue from 'vue'
|
||||||
|
import App from './Docs.vue'
|
||||||
|
import store from './vuex/store'
|
||||||
|
import Resource from 'vue-resource'
|
||||||
|
import vSelect from '../src/components/Select.vue'
|
||||||
|
import vCode from './components/Code.vue'
|
||||||
|
|
||||||
|
Vue.use(Resource)
|
||||||
|
|
||||||
|
Vue.component('v-select', vSelect)
|
||||||
|
Vue.component('v-code', vCode)
|
||||||
|
|
||||||
|
Vue.filter('score', function (value) {
|
||||||
|
return Math.round(value)
|
||||||
|
})
|
||||||
|
|
||||||
|
Vue.config.debug = true
|
||||||
|
Vue.config.devtools = true
|
||||||
|
|
||||||
|
import { setSelected, toggleMultiple, setPlaceholder, toggleOptionType } from './vuex/actions'
|
||||||
|
|
||||||
|
|
||||||
|
/* eslint-disable no-new */
|
||||||
|
new Vue({
|
||||||
|
el: 'body',
|
||||||
|
store,
|
||||||
|
components: { App },
|
||||||
|
vuex: {
|
||||||
|
getters: {
|
||||||
|
placeholder (store) {
|
||||||
|
return store.placeholder
|
||||||
|
},
|
||||||
|
selected (store) {
|
||||||
|
return store.selected
|
||||||
|
},
|
||||||
|
type (store) {
|
||||||
|
return store.optionType
|
||||||
|
},
|
||||||
|
options (store) {
|
||||||
|
return store.options[store.optionType]
|
||||||
|
},
|
||||||
|
multiple (store) {
|
||||||
|
return store.multiple
|
||||||
|
}
|
||||||
|
},
|
||||||
|
actions: { setSelected, toggleMultiple, setPlaceholder, toggleOptionType }
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -10,8 +10,8 @@ const state = {
|
|||||||
multiple: true,
|
multiple: true,
|
||||||
maxHeight: '400px',
|
maxHeight: '400px',
|
||||||
options: {
|
options: {
|
||||||
advanced: require('../countries/advanced.js'),
|
advanced: require('../data/advanced.js'),
|
||||||
simple: require('../countries/simple.js'),
|
simple: require('../data/simple.js'),
|
||||||
},
|
},
|
||||||
optionType: 'advanced'
|
optionType: 'advanced'
|
||||||
}
|
}
|
||||||
+64
-9
@@ -2,7 +2,7 @@
|
|||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<title>Vue Select | VueJS Select2/Chosen Component</title>
|
<title>Vue Select | VueJS Select2 Component</title>
|
||||||
|
|
||||||
<link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600|Roboto Mono" rel="stylesheet" type="text/css">
|
<link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600|Roboto Mono" rel="stylesheet" type="text/css">
|
||||||
<link href="//fonts.googleapis.com/css?family=Dosis:300&text=Vue Select" rel="stylesheet" type="text/css">
|
<link href="//fonts.googleapis.com/css?family=Dosis:300&text=Vue Select" rel="stylesheet" type="text/css">
|
||||||
@@ -11,19 +11,74 @@
|
|||||||
<meta name="title" content="Vue Select | VueJS Select2/Chosen Component">
|
<meta name="title" content="Vue Select | VueJS Select2/Chosen Component">
|
||||||
<meta name="description" content="A well-tested, native Vue.js component that provides similar functionality to Select2/Chosen without the overhead of jQuery.">
|
<meta name="description" content="A well-tested, native Vue.js component that provides similar functionality to Select2/Chosen without the overhead of jQuery.">
|
||||||
|
|
||||||
<link rel="icon" href="static/static/vue-logo.png" type="image/png">
|
<link rel="icon" href="static/vue-logo.png" type="image/png">
|
||||||
|
<meta property="og:image" content="static/vue-logo.png">
|
||||||
|
<meta property="twitter:image" content="static/vue-logo.png">
|
||||||
|
|
||||||
<meta name="description" content="A well-tested, native Vue.js component that provides similar functionality to Select2/Chosen without the overhead of jQuery.">
|
<meta name="description" content="A native Vue.js component that provides similar functionality to Select2/Chosen without the overhead of jQuery.">
|
||||||
|
<meta property="og:description" content="A native Vue.js component that provides similar functionality to Select2/Chosen without the overhead of jQuery.">
|
||||||
|
<meta property="twitter:description" content="A native Vue.js component that provides similar functionality to Select2/Chosen without the overhead of jQuery.">
|
||||||
|
|
||||||
|
<meta property="twitter:title" content="Vue Select | VueJS Select2/Chosen Component">
|
||||||
<meta property="og:title" content="Vue Select | VueJS Select2/Chosen Component">
|
<meta property="og:title" content="Vue Select | VueJS Select2/Chosen Component">
|
||||||
<meta property="og:site_name" content="Vue Select | VueJS Select2/Chosen Component">
|
<meta property="og:site_name" content="Vue Select | VueJS Select2/Chosen Component">
|
||||||
<meta property="og:url" content="http://sagalbot.github.io/vue-select">
|
<meta property="og:url" content="http://sagalbot.github.io/vue-select/">
|
||||||
<meta property="og:description" content="A well-tested, native Vue.js component that provides similar functionality to Select2/Chosen without the overhead of jQuery.">
|
|
||||||
<meta property="og:image" content="http://sagalbot.github.io/vue-select/static/vue-logo.png">
|
|
||||||
<meta property="twitter:image" content="http://sagalbot.github.io/vue-select/static/vue-logo.png">
|
|
||||||
<meta property="twitter:title" content="Vue Select | VueJS Select2/Chosen Component">
|
|
||||||
<meta property="twitter:description" content="A well-tested, native Vue.js component that provides similar functionality to Select2/Chosen without the overhead of jQuery.">
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div class="jumbotron jumbotron-top">
|
||||||
|
<div class="container">
|
||||||
|
<div class="col-md-8 col-md-offset-2">
|
||||||
|
|
||||||
|
<h1>Vue Select</h1>
|
||||||
|
|
||||||
|
<p class="accolades lead">
|
||||||
|
<a href="https://travis-ci.org/sagalbot/vue-select"><img src="https://img.shields.io/travis/sagalbot/vue-select.svg?style=flat-square" alt="Build Status"></a>
|
||||||
|
<a href="https://codeclimate.com/github/sagalbot/vue-select"><img src="https://img.shields.io/codeclimate/coverage/github/sagalbot/vue-select.svg?style=flat-square" alt="Code Coverage"></a>
|
||||||
|
<a href="https://gemnasium.com/github.com/sagalbot/vue-select"><img src="https://img.shields.io/gemnasium/sagalbot/vue-select.svg?style=flat-square" alt="No Dependencies"></a>
|
||||||
|
<img src="https://img.shields.io/github/license/sagalbot/vue-select.svg?style=flat-square" alt="MIT License">
|
||||||
|
<img src="https://img.shields.io/github/release/sagalbot/vue-select.svg?style=flat-square" alt="Current Release">
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<p class="lead">A native Vue.js select component that provides similar functionality to Select2/Chosen without the overhead of jQuery.</p>
|
||||||
|
|
||||||
|
<v-select
|
||||||
|
id="v-select"
|
||||||
|
taggable
|
||||||
|
:placeholder="placeholder"
|
||||||
|
:value="selected"
|
||||||
|
:options="options"
|
||||||
|
:multiple="multiple"
|
||||||
|
:on-change="setSelected"
|
||||||
|
>
|
||||||
|
</v-select>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-3 col-md-offset-3">
|
||||||
|
<ul class="list-vue">
|
||||||
|
<li>Fully Reactive</li>
|
||||||
|
<li>Tagging Support <small>v1.1.0</small></li>
|
||||||
|
<li>Works with Vuex</li>
|
||||||
|
<li>Zero dependencies</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="col-md-3">
|
||||||
|
<ul class="list-vue">
|
||||||
|
<li>+95% Test Coverage</li>
|
||||||
|
<li>Select Single/Multiple</li>
|
||||||
|
<li>Typeahead Suggestions</li>
|
||||||
|
<li>Bootstrap Friendly Markup</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a class="btn btn-primary btn-outline btn-lg" href="https://github.com/sagalbot/vue-select"><span class="octicon octicon-mark-github"></span> View on GitHub</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<a href="#install" class="down-arrow">
|
||||||
|
Install, Examples & Documentation
|
||||||
|
<i role="presentation" class="glyphicon glyphicon-chevron-down"></i>
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
<app></app>
|
<app></app>
|
||||||
<script>
|
<script>
|
||||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||||
|
|||||||
@@ -37,6 +37,7 @@
|
|||||||
"extract-text-webpack-plugin": "^1.0.1",
|
"extract-text-webpack-plugin": "^1.0.1",
|
||||||
"file-loader": "^0.8.4",
|
"file-loader": "^0.8.4",
|
||||||
"function-bind": "^1.0.2",
|
"function-bind": "^1.0.2",
|
||||||
|
"gh-pages": "^0.11.0",
|
||||||
"html-webpack-plugin": "^2.8.1",
|
"html-webpack-plugin": "^2.8.1",
|
||||||
"http-proxy-middleware": "^0.15.2",
|
"http-proxy-middleware": "^0.15.2",
|
||||||
"inject-loader": "^2.0.1",
|
"inject-loader": "^2.0.1",
|
||||||
@@ -62,6 +63,7 @@
|
|||||||
"vue-hot-reload-api": "^1.2.0",
|
"vue-hot-reload-api": "^1.2.0",
|
||||||
"vue-html-loader": "^1.0.0",
|
"vue-html-loader": "^1.0.0",
|
||||||
"vue-loader": "^8.3.0",
|
"vue-loader": "^8.3.0",
|
||||||
|
"vue-resource": "^0.8.0",
|
||||||
"vue-style-loader": "^1.0.0",
|
"vue-style-loader": "^1.0.0",
|
||||||
"vuex": "^0.6.3",
|
"vuex": "^0.6.3",
|
||||||
"webpack": "^1.12.2",
|
"webpack": "^1.12.2",
|
||||||
|
|||||||
-116
@@ -1,116 +0,0 @@
|
|||||||
<style lang="scss">
|
|
||||||
@import 'assets/scss/_demo.scss';
|
|
||||||
@import 'assets/scss/_cyan_theme.scss';
|
|
||||||
@import 'assets/scss/_prism.scss';
|
|
||||||
@import 'assets/scss/_octicons.scss';
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<template>
|
|
||||||
<div class="jumbotron jumbotron-top">
|
|
||||||
<div class="container">
|
|
||||||
<div class="col-md-8 col-md-offset-2">
|
|
||||||
|
|
||||||
<h1>Vue Select</h1>
|
|
||||||
|
|
||||||
<p class="accolades lead">
|
|
||||||
<a href="https://travis-ci.org/sagalbot/vue-select"><img src="https://img.shields.io/travis/sagalbot/vue-select.svg?style=flat-square" alt="Build Status"></a>
|
|
||||||
<a href="https://codeclimate.com/github/sagalbot/vue-select"><img src="https://img.shields.io/codeclimate/github/sagalbot/vue-select.svg?style=flat-square" alt="Code Climate Rating"></a>
|
|
||||||
<a href="https://codeclimate.com/github/sagalbot/vue-select"><img src="https://img.shields.io/codeclimate/coverage/github/sagalbot/vue-select.svg?style=flat-square" alt="Code Coverage"></a>
|
|
||||||
<a href="https://gemnasium.com/github.com/sagalbot/vue-select"><img src="https://img.shields.io/gemnasium/sagalbot/vue-select.svg?style=flat-square" alt="No Dependencies"></a>
|
|
||||||
<img src="https://img.shields.io/github/license/sagalbot/vue-select.svg?style=flat-square" alt="MIT License">
|
|
||||||
<img src="https://img.shields.io/github/release/sagalbot/vue-select.svg?style=flat-square" alt="Current Release">
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<p class="lead">A well-tested, native Vue.js select component that provides similar functionality to Select2/Chosen without the overhead of jQuery.</p>
|
|
||||||
|
|
||||||
<v-select
|
|
||||||
id="v-select"
|
|
||||||
taggable
|
|
||||||
:placeholder="placeholder"
|
|
||||||
:value="selected"
|
|
||||||
:options="options"
|
|
||||||
:multiple="multiple"
|
|
||||||
:on-change="setSelected"
|
|
||||||
>
|
|
||||||
</v-select>
|
|
||||||
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-md-3 col-md-offset-3">
|
|
||||||
<ul class="list-vue">
|
|
||||||
<li>Fully Reactive</li>
|
|
||||||
<li>Tagging Support <small>v1.1.0</small></li>
|
|
||||||
<li>Works with Vuex</li>
|
|
||||||
<li>Zero dependencies</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="col-md-3">
|
|
||||||
<ul class="list-vue">
|
|
||||||
<li>+90% Test Coverage</li>
|
|
||||||
<li>Select Single/Multiple</li>
|
|
||||||
<li>Typeahead Suggestions</li>
|
|
||||||
<li>Bootstrap Friendly Markup</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<a class="btn btn-primary btn-outline" href="https://github.com/sagalbot/vue-select"><span class="octicon octicon-mark-github"></span> View on GitHub</a>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<a href="#install" class="down-arrow">
|
|
||||||
Install, Examples & Documentation
|
|
||||||
<i role="presentation" class="glyphicon glyphicon-chevron-down"></i>
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="container">
|
|
||||||
<div class="col-md-10 col-md-offset-1">
|
|
||||||
<install></install>
|
|
||||||
<params></params>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script type="text/babel">
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Note that this file (and anything other than src/components/Select.vue)
|
|
||||||
* has nothing to do with how you use vue-select. These files are used
|
|
||||||
* for the demo site at http://sagalbot.github.io/vue-select/. They'll
|
|
||||||
* be moved out of this repo in the very near future to avoid confusion.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import Install from './components/Install.vue'
|
|
||||||
import Params from './components/Params.vue'
|
|
||||||
import vSelect from './components/Select.vue'
|
|
||||||
import { setSelected, toggleMultiple, setPlaceholder, toggleOptionType } from './vuex/actions'
|
|
||||||
|
|
||||||
export default {
|
|
||||||
components: { Params, Install, vSelect },
|
|
||||||
|
|
||||||
vuex: {
|
|
||||||
getters: {
|
|
||||||
placeholder (store) {
|
|
||||||
return store.placeholder
|
|
||||||
},
|
|
||||||
selected (store) {
|
|
||||||
return store.selected
|
|
||||||
},
|
|
||||||
type (store) {
|
|
||||||
return store.optionType
|
|
||||||
},
|
|
||||||
options (store) {
|
|
||||||
return store.options[store.optionType]
|
|
||||||
},
|
|
||||||
multiple (store) {
|
|
||||||
return store.multiple
|
|
||||||
}
|
|
||||||
},
|
|
||||||
actions: { setSelected, toggleMultiple, setPlaceholder, toggleOptionType }
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onPlaceholderChange ( e ) {
|
|
||||||
this.setPlaceholder( e.target.value )
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
Binary file not shown.
@@ -1,5 +1,5 @@
|
|||||||
<style>
|
<style>
|
||||||
.v-select.dropdown {
|
.v-select {
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,6 +12,12 @@
|
|||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
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;
|
||||||
|
transition: opacity .1s;
|
||||||
|
}
|
||||||
|
|
||||||
|
.v-select.loading .open-indicator {
|
||||||
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.v-select .open-indicator:before {
|
.v-select .open-indicator:before {
|
||||||
@@ -116,6 +122,47 @@
|
|||||||
background: #f0f0f0;
|
background: #f0f0f0;
|
||||||
color: #333;
|
color: #333;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.v-select .spinner {
|
||||||
|
opacity: 0;
|
||||||
|
position: absolute;
|
||||||
|
top: 5px;
|
||||||
|
right: 10px;
|
||||||
|
font-size: 5px;
|
||||||
|
text-indent: -9999em;
|
||||||
|
border-top: .9em solid rgba(100,100,100,.1);
|
||||||
|
border-right: .9em solid rgba(100,100,100,.1);
|
||||||
|
border-bottom: .9em solid rgba(100,100,100,.1);
|
||||||
|
border-left: .9em solid rgba(60,60,60,.45);
|
||||||
|
transform: translateZ(0);
|
||||||
|
animation: vSelectSpinner 1.1s infinite linear;
|
||||||
|
transition: opacity .1s;
|
||||||
|
}
|
||||||
|
.v-select.loading .spinner {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
.v-select .spinner,
|
||||||
|
.v-select .spinner:after {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 5em;
|
||||||
|
height: 5em;
|
||||||
|
}
|
||||||
|
@-webkit-keyframes vSelectSpinner {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@keyframes vSelectSpinner {
|
||||||
|
0% {
|
||||||
|
transform: rotate(0deg);
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
transform: rotate(360deg);
|
||||||
|
}
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
@@ -134,8 +181,9 @@
|
|||||||
|
|
||||||
<input
|
<input
|
||||||
v-el:search
|
v-el:search
|
||||||
v-show="searchable"
|
:debounce="debounce"
|
||||||
v-model="search"
|
v-model="search"
|
||||||
|
v-show="searchable"
|
||||||
@keydown.delete="maybeDeleteValue"
|
@keydown.delete="maybeDeleteValue"
|
||||||
@keyup.esc="onEscape"
|
@keyup.esc="onEscape"
|
||||||
@keydown.up.prevent="typeAheadUp"
|
@keydown.up.prevent="typeAheadUp"
|
||||||
@@ -150,6 +198,10 @@
|
|||||||
>
|
>
|
||||||
|
|
||||||
<i v-el:open-indicator role="presentation" class="open-indicator"></i>
|
<i v-el:open-indicator role="presentation" class="open-indicator"></i>
|
||||||
|
|
||||||
|
<slot name="spinner">
|
||||||
|
<div class="spinner" v-show="onSearch && loading">Loading...</div>
|
||||||
|
</slot>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<ul v-el:dropdown-menu 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 }">
|
||||||
@@ -170,9 +222,10 @@
|
|||||||
<script type="text/babel">
|
<script type="text/babel">
|
||||||
import pointerScroll from '../mixins/pointerScroll'
|
import pointerScroll from '../mixins/pointerScroll'
|
||||||
import typeAheadPointer from '../mixins/typeAheadPointer'
|
import typeAheadPointer from '../mixins/typeAheadPointer'
|
||||||
|
import ajax from '../mixins/ajax'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
mixins: [pointerScroll, typeAheadPointer],
|
mixins: [pointerScroll, typeAheadPointer, ajax],
|
||||||
|
|
||||||
props: {
|
props: {
|
||||||
/**
|
/**
|
||||||
@@ -492,7 +545,8 @@
|
|||||||
dropdownClasses() {
|
dropdownClasses() {
|
||||||
return {
|
return {
|
||||||
open: this.open,
|
open: this.open,
|
||||||
searchable: this.searchable
|
searchable: this.searchable,
|
||||||
|
loading: this.loading
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
-14
@@ -1,14 +0,0 @@
|
|||||||
import Vue from 'vue'
|
|
||||||
import App from './App.vue'
|
|
||||||
import store from './vuex/store'
|
|
||||||
import 'prismjs'
|
|
||||||
|
|
||||||
// Vue.config.debug = true
|
|
||||||
Vue.config.devtools = true
|
|
||||||
|
|
||||||
/* eslint-disable no-new */
|
|
||||||
new Vue({
|
|
||||||
el: 'body',
|
|
||||||
store,
|
|
||||||
components: { App }
|
|
||||||
})
|
|
||||||
@@ -0,0 +1,67 @@
|
|||||||
|
module.exports = {
|
||||||
|
props: {
|
||||||
|
/**
|
||||||
|
* Toggles the adding of a 'loading' class to the main
|
||||||
|
* .v-select wrapper. Useful to control UI state when
|
||||||
|
* results are being processed through AJAX.
|
||||||
|
*/
|
||||||
|
loading: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accept a callback function that will be
|
||||||
|
* run when the search text changes.
|
||||||
|
*
|
||||||
|
* loading() accepts a boolean value, and can
|
||||||
|
* be used to toggle a loading class from
|
||||||
|
* the onSearch callback.
|
||||||
|
*
|
||||||
|
* @param {search} String Current search text
|
||||||
|
* @param {loading} Function(bool) Toggle loading class
|
||||||
|
*/
|
||||||
|
onSearch: {
|
||||||
|
type: Function,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of milliseconds to wait before
|
||||||
|
* invoking this.onSearch(). Used to prevent
|
||||||
|
* sending an AJAX request until input is complete.
|
||||||
|
*/
|
||||||
|
debounce: {
|
||||||
|
type: Number,
|
||||||
|
default: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
/**
|
||||||
|
* If a callback & search text has been provided,
|
||||||
|
* invoke the onSearch callback.
|
||||||
|
*/
|
||||||
|
search() {
|
||||||
|
if (this.search.length > 0 && this.onSearch) {
|
||||||
|
this.onSearch(this.search, this.toggleLoading)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
/**
|
||||||
|
* Toggle this.loading. Optionally pass a boolean
|
||||||
|
* value. If no value is provided, this.loading
|
||||||
|
* will be set to the opposite of it's current value.
|
||||||
|
* @param toggle Boolean
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
toggleLoading(toggle = null) {
|
||||||
|
if (toggle == null) {
|
||||||
|
return this.loading = !this.loading
|
||||||
|
}
|
||||||
|
return this.loading = toggle
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+780
-692
File diff suppressed because it is too large
Load Diff
+1
-1
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user