mirror of
https://github.com/tenrok/vue-select.git
synced 2026-05-17 02:29:37 +03:00
wip
This commit is contained in:
+2
-2
@@ -6,8 +6,8 @@
|
||||
|
||||
<script>
|
||||
import vSelect from "../src/components/Select";
|
||||
import countries from "../docs/data/countryCodes";
|
||||
import books from "../docs/data/books";
|
||||
import countries from "../docs/assets/data/countryCodes";
|
||||
import books from "../docs/assets/data/books";
|
||||
|
||||
export default {
|
||||
components: { vSelect },
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor">
|
||||
<path d="M11 3a1 1 0 100 2h2.586l-6.293 6.293a1 1 0 101.414 1.414L15 6.414V9a1 1 0 102 0V4a1 1 0 00-1-1h-5z" />
|
||||
<path d="M5 5a2 2 0 00-2 2v8a2 2 0 002 2h8a2 2 0 002-2v-3a1 1 0 10-2 0v3H5V7h3a1 1 0 000-2H5z" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 306 B |
@@ -0,0 +1,45 @@
|
||||
<template>
|
||||
<div>
|
||||
<label for="search" class="block text-sm font-medium text-gray-700 sr-only">
|
||||
Quick search
|
||||
</label>
|
||||
<div class="mt-1 relative flex items-center">
|
||||
<input
|
||||
type="text"
|
||||
name="search"
|
||||
id="search"
|
||||
class="
|
||||
shadow-sm
|
||||
focus:ring-indigo-500 focus:border-indigo-500
|
||||
block
|
||||
w-full
|
||||
pr-12
|
||||
sm:text-sm
|
||||
border-gray-300
|
||||
rounded-md
|
||||
"
|
||||
/>
|
||||
<div class="absolute inset-y-0 right-0 flex py-1.5 pr-1.5">
|
||||
<kbd
|
||||
class="
|
||||
inline-flex
|
||||
items-center
|
||||
border border-gray-200
|
||||
rounded
|
||||
px-2
|
||||
text-sm
|
||||
font-sans font-medium
|
||||
text-gray-400
|
||||
"
|
||||
>
|
||||
⌘K
|
||||
</kbd>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script>
|
||||
export default {
|
||||
name: "ContentSearch",
|
||||
};
|
||||
</script>
|
||||
@@ -3,16 +3,14 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countryCodes from '../data/countryCodes.js';
|
||||
import countryCodes from "../assets/data/countryCodes.js";
|
||||
|
||||
export default {
|
||||
name: 'CountrySelect',
|
||||
name: "CountrySelect",
|
||||
data: () => ({
|
||||
options: countryCodes,
|
||||
}),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
</style>
|
||||
<style scoped></style>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<v-select :filter="fuseSearch" :options="books" :getOptionLabel="option => option.title">
|
||||
<v-select
|
||||
:filter="fuseSearch"
|
||||
:options="books"
|
||||
:getOptionLabel="(option) => option.title"
|
||||
>
|
||||
<template #option="{ author, title }">
|
||||
{{ title }}
|
||||
<br />
|
||||
@@ -10,22 +14,22 @@
|
||||
|
||||
<script>
|
||||
import Fuse from "fuse.js";
|
||||
import books from "../data/books.js";
|
||||
import books from "../assets/data/books.js";
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
books: () => books
|
||||
books: () => books,
|
||||
},
|
||||
methods: {
|
||||
fuseSearch(options, search) {
|
||||
const fuse = new Fuse(options, {
|
||||
keys: ["title", "author.firstName", "author.lastName"],
|
||||
shouldSort: true
|
||||
shouldSort: true,
|
||||
});
|
||||
return search.length
|
||||
? fuse.search(search).map(({ item }) => item)
|
||||
: fuse.list;
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
:filterable="false"
|
||||
@open="onOpen"
|
||||
@close="onClose"
|
||||
@search="query => search = query"
|
||||
@search="(query) => (search = query)"
|
||||
>
|
||||
<template #list-footer>
|
||||
<li ref="load" class="loader" v-show="hasNextPage">
|
||||
@@ -15,16 +15,16 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countries from '../data/countries.js';
|
||||
import countries from "../assets/data/countries.js";
|
||||
|
||||
export default {
|
||||
name: "InfiniteScroll",
|
||||
data: () => ({
|
||||
observer: null,
|
||||
limit: 10,
|
||||
search: ''
|
||||
search: "",
|
||||
}),
|
||||
mounted () {
|
||||
mounted() {
|
||||
/**
|
||||
* You could do this directly in data(), but since these docs
|
||||
* are server side rendered, IntersectionObserver doesn't exist
|
||||
@@ -33,27 +33,27 @@ export default {
|
||||
this.observer = new IntersectionObserver(this.infiniteScroll);
|
||||
},
|
||||
computed: {
|
||||
filtered () {
|
||||
return countries.filter(country => country.includes(this.search));
|
||||
filtered() {
|
||||
return countries.filter((country) => country.includes(this.search));
|
||||
},
|
||||
paginated () {
|
||||
paginated() {
|
||||
return this.filtered.slice(0, this.limit);
|
||||
},
|
||||
hasNextPage () {
|
||||
hasNextPage() {
|
||||
return this.paginated.length < this.filtered.length;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async onOpen () {
|
||||
async onOpen() {
|
||||
if (this.hasNextPage) {
|
||||
await this.$nextTick();
|
||||
this.observer.observe(this.$refs.load)
|
||||
this.observer.observe(this.$refs.load);
|
||||
}
|
||||
},
|
||||
onClose () {
|
||||
onClose() {
|
||||
this.observer.disconnect();
|
||||
},
|
||||
async infiniteScroll ([{isIntersecting, target}]) {
|
||||
async infiniteScroll([{ isIntersecting, target }]) {
|
||||
if (isIntersecting) {
|
||||
const ul = target.offsetParent;
|
||||
const scrollTop = target.offsetParent.scrollTop;
|
||||
@@ -61,14 +61,14 @@ export default {
|
||||
await this.$nextTick();
|
||||
ul.scrollTop = scrollTop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.loader {
|
||||
text-align: center;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
.loader {
|
||||
text-align: center;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -9,13 +9,13 @@
|
||||
/>
|
||||
</template>
|
||||
<script>
|
||||
import books from '../data/books.js';
|
||||
import books from "../assets/data/books.js";
|
||||
export default {
|
||||
data() {
|
||||
return { selected: [] }
|
||||
return { selected: [] };
|
||||
},
|
||||
computed: {
|
||||
books: () => books,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
<v-select
|
||||
:options="options"
|
||||
:value="person.country"
|
||||
@input="country => updateCountry(person, country)"
|
||||
@input="(country) => updateCountry(person, country)"
|
||||
/>
|
||||
</td>
|
||||
</tr>
|
||||
@@ -18,14 +18,17 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countries from '../data/countries.js';
|
||||
import countries from "../assets/data/countries.js";
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
people: [{name: 'John', country: ''}, {name: 'Jane', country: ''}],
|
||||
people: [
|
||||
{ name: "John", country: "" },
|
||||
{ name: "Jane", country: "" },
|
||||
],
|
||||
}),
|
||||
methods: {
|
||||
updateCountry (person, country) {
|
||||
updateCountry(person, country) {
|
||||
person.country = country;
|
||||
},
|
||||
},
|
||||
@@ -36,8 +39,8 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
table {
|
||||
display: table;
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<v-select :options="paginated" @search="query => search = query" :filterable="false">
|
||||
<v-select
|
||||
:options="paginated"
|
||||
@search="(query) => (search = query)"
|
||||
:filterable="false"
|
||||
>
|
||||
<li slot="list-footer" class="pagination">
|
||||
<button @click="offset -= 10" :disabled="!hasPrevPage">Prev</button>
|
||||
<button @click="offset += 10" :disabled="!hasNextPage">Next</button>
|
||||
@@ -8,42 +12,46 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countries from '../data/countries.js';
|
||||
import countries from "../assets/data/countries.js";
|
||||
export default {
|
||||
data: () => ({
|
||||
countries,
|
||||
search: '',
|
||||
search: "",
|
||||
offset: 0,
|
||||
limit: 10,
|
||||
}),
|
||||
computed: {
|
||||
filtered () {
|
||||
return this.countries.filter(country => country.includes(this.search));
|
||||
filtered() {
|
||||
return this.countries.filter((country) => country.includes(this.search));
|
||||
},
|
||||
paginated () {
|
||||
paginated() {
|
||||
return this.filtered.slice(this.offset, this.limit + this.offset);
|
||||
},
|
||||
hasNextPage () {
|
||||
hasNextPage() {
|
||||
const nextOffset = this.offset + 10;
|
||||
return Boolean(this.filtered.slice(nextOffset, this.limit + nextOffset).length);
|
||||
return Boolean(
|
||||
this.filtered.slice(nextOffset, this.limit + nextOffset).length
|
||||
);
|
||||
},
|
||||
hasPrevPage () {
|
||||
hasPrevPage() {
|
||||
const prevOffset = this.offset - 10;
|
||||
return Boolean(this.filtered.slice(prevOffset, this.limit + prevOffset).length);
|
||||
}
|
||||
return Boolean(
|
||||
this.filtered.slice(prevOffset, this.limit + prevOffset).length
|
||||
);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.pagination {
|
||||
display: flex;
|
||||
margin: .25rem .25rem 0;
|
||||
}
|
||||
.pagination button {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.pagination button:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
.pagination {
|
||||
display: flex;
|
||||
margin: 0.25rem 0.25rem 0;
|
||||
}
|
||||
.pagination button {
|
||||
flex-grow: 1;
|
||||
}
|
||||
.pagination button:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,28 +1,32 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-select :options="countries" append-to-body :calculate-position="withPopper" />
|
||||
<v-select
|
||||
:options="countries"
|
||||
append-to-body
|
||||
:calculate-position="withPopper"
|
||||
/>
|
||||
|
||||
<label for="position" style="display: block; margin: 1rem 0;">
|
||||
<label for="position" style="display: block; margin: 1rem 0">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="position"
|
||||
v-model="placement"
|
||||
true-value="top"
|
||||
false-value="bottom"
|
||||
>
|
||||
/>
|
||||
Position dropdown above
|
||||
</label>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countries from '../data/countries.js'
|
||||
import { createPopper } from '@popperjs/core';
|
||||
import countries from "../assets/data/countries.js";
|
||||
import { createPopper } from "@popperjs/core";
|
||||
|
||||
export default {
|
||||
data: () => ({countries, placement: 'top'}),
|
||||
data: () => ({ countries, placement: "top" }),
|
||||
methods: {
|
||||
withPopper (dropdownList, component, {width}) {
|
||||
withPopper(dropdownList, component, { width }) {
|
||||
/**
|
||||
* We need to explicitly define the dropdown width since
|
||||
* it is usually inherited from the parent with CSS.
|
||||
@@ -43,18 +47,23 @@ export default {
|
||||
placement: this.placement,
|
||||
modifiers: [
|
||||
{
|
||||
name: 'offset', options: {
|
||||
offset: [0, -1]
|
||||
}
|
||||
name: "offset",
|
||||
options: {
|
||||
offset: [0, -1],
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'toggleClass',
|
||||
name: "toggleClass",
|
||||
enabled: true,
|
||||
phase: 'write',
|
||||
fn ({state}) {
|
||||
component.$el.classList.toggle('drop-up', state.placement === 'top')
|
||||
phase: "write",
|
||||
fn({ state }) {
|
||||
component.$el.classList.toggle(
|
||||
"drop-up",
|
||||
state.placement === "top"
|
||||
);
|
||||
},
|
||||
}]
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -62,22 +71,22 @@ export default {
|
||||
* If you return function, it will be called just before dropdown is removed from DOM.
|
||||
*/
|
||||
return () => popper.destroy();
|
||||
}
|
||||
}
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.v-select.drop-up.vs--open .vs__dropdown-toggle {
|
||||
border-radius: 0 0 4px 4px;
|
||||
border-top-color: transparent;
|
||||
border-bottom-color: rgba(60, 60, 60, 0.26);
|
||||
}
|
||||
.v-select.drop-up.vs--open .vs__dropdown-toggle {
|
||||
border-radius: 0 0 4px 4px;
|
||||
border-top-color: transparent;
|
||||
border-bottom-color: rgba(60, 60, 60, 0.26);
|
||||
}
|
||||
|
||||
[data-popper-placement='top'] {
|
||||
border-radius: 4px 4px 0 0;
|
||||
border-top-style: solid;
|
||||
border-bottom-style: none;
|
||||
box-shadow: 0 -3px 6px rgba(0, 0, 0, 0.15)
|
||||
}
|
||||
[data-popper-placement="top"] {
|
||||
border-radius: 4px 4px 0 0;
|
||||
border-top-style: solid;
|
||||
border-bottom-style: none;
|
||||
box-shadow: 0 -3px 6px rgba(0, 0, 0, 0.15);
|
||||
}
|
||||
</style>
|
||||
|
||||
+191
-92
@@ -1,49 +1,85 @@
|
||||
<template>
|
||||
<div id="sandbox-wrap">
|
||||
<div id="config">
|
||||
|
||||
<div class="list-item" v-if="!hideHelp">
|
||||
<p>Use the controls below to adjust the props used
|
||||
by the vue-select components.</p>
|
||||
<p>The API provides
|
||||
more props than are shown here, these are some
|
||||
commonly adjusted settings.</p>
|
||||
<p>
|
||||
Use the controls below to adjust the props used by the vue-select
|
||||
components.
|
||||
</p>
|
||||
<p>
|
||||
The API provides more props than are shown here, these are some
|
||||
commonly adjusted settings.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<h5 class="list-item">Basic Features</h5>
|
||||
|
||||
<div class="list-item">
|
||||
<label for="multiple">
|
||||
<input id="multiple" type="checkbox" v-model="configuration.multiple">
|
||||
<code>:multiple="{{ configuration.multiple ? 'true' : 'false' }}"</code>
|
||||
<input
|
||||
id="multiple"
|
||||
type="checkbox"
|
||||
v-model="configuration.multiple"
|
||||
/>
|
||||
<code
|
||||
>:multiple="{{ configuration.multiple ? "true" : "false" }}"</code
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<label for="disabled">
|
||||
<input id="disabled" type="checkbox" v-model="configuration.disabled">
|
||||
<code>:disabled="{{ configuration.disabled ? 'true' : 'false' }}"</code>
|
||||
<input
|
||||
id="disabled"
|
||||
type="checkbox"
|
||||
v-model="configuration.disabled"
|
||||
/>
|
||||
<code
|
||||
>:disabled="{{ configuration.disabled ? "true" : "false" }}"</code
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<label for="clearable">
|
||||
<input id="clearable" type="checkbox" v-model="configuration.clearable">
|
||||
<code>:clearable="{{ configuration.clearable ? 'true' : 'false' }}"</code>
|
||||
<input
|
||||
id="clearable"
|
||||
type="checkbox"
|
||||
v-model="configuration.clearable"
|
||||
/>
|
||||
<code
|
||||
>:clearable="{{ configuration.clearable ? "true" : "false" }}"</code
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<label for="searchable">
|
||||
<input id="searchable" type="checkbox" v-model="configuration.searchable">
|
||||
<code>:searchable="{{ configuration.searchable ? 'true' : 'false' }}"</code>
|
||||
<input
|
||||
id="searchable"
|
||||
type="checkbox"
|
||||
v-model="configuration.searchable"
|
||||
/>
|
||||
<code
|
||||
>:searchable="{{
|
||||
configuration.searchable ? "true" : "false"
|
||||
}}"</code
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<label for="filterable">
|
||||
<input id="filterable" type="checkbox" v-model="configuration.filterable">
|
||||
<code>:filterable="{{ configuration.searchable ? 'true' : 'false' }}"</code>
|
||||
<input
|
||||
id="filterable"
|
||||
type="checkbox"
|
||||
v-model="configuration.filterable"
|
||||
/>
|
||||
<code
|
||||
>:filterable="{{
|
||||
configuration.searchable ? "true" : "false"
|
||||
}}"</code
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -51,22 +87,34 @@
|
||||
|
||||
<div class="list-item">
|
||||
<label for="taggable">
|
||||
<input id="taggable" type="checkbox" v-model="configuration.taggable">
|
||||
<code>:taggable="{{ configuration.taggable ? 'true' : 'false' }}"</code>
|
||||
<input
|
||||
id="taggable"
|
||||
type="checkbox"
|
||||
v-model="configuration.taggable"
|
||||
/>
|
||||
<code
|
||||
>:taggable="{{ configuration.taggable ? "true" : "false" }}"</code
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<label for="noDrop">
|
||||
<input id="noDrop" type="checkbox" v-model="configuration.noDrop">
|
||||
<code>:no-drop="{{ configuration.noDrop ? 'true' : 'false' }}"</code>
|
||||
<input id="noDrop" type="checkbox" v-model="configuration.noDrop" />
|
||||
<code>:no-drop="{{ configuration.noDrop ? "true" : "false" }}"</code>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<label for="pushTags">
|
||||
<input id="pushTags" type="checkbox" v-model="configuration.pushTags">
|
||||
<code>:push-tags="{{ configuration.pushTags ? 'true' : 'false' }}"</code>
|
||||
<input
|
||||
id="pushTags"
|
||||
type="checkbox"
|
||||
v-model="configuration.pushTags"
|
||||
/>
|
||||
<code
|
||||
>:push-tags="{{ configuration.pushTags ? "true" : "false" }}"</code
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -74,15 +122,31 @@
|
||||
|
||||
<div class="list-item">
|
||||
<label for="selectOnTab">
|
||||
<input id="selectOnTab" type="checkbox" v-model="configuration.selectOnTab">
|
||||
<code>:select-on-tab="{{ configuration.selectOnTab ? 'true' : 'false' }}"</code>
|
||||
<input
|
||||
id="selectOnTab"
|
||||
type="checkbox"
|
||||
v-model="configuration.selectOnTab"
|
||||
/>
|
||||
<code
|
||||
>:select-on-tab="{{
|
||||
configuration.selectOnTab ? "true" : "false"
|
||||
}}"</code
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="list-item">
|
||||
<label for="closeOnSelect">
|
||||
<input id="closeOnSelect" type="checkbox" v-model="configuration.closeOnSelect">
|
||||
<code>:close-on-select="{{ configuration.closeOnSelect ? 'true' : 'false' }}"</code>
|
||||
<input
|
||||
id="closeOnSelect"
|
||||
type="checkbox"
|
||||
v-model="configuration.closeOnSelect"
|
||||
/>
|
||||
<code
|
||||
>:close-on-select="{{
|
||||
configuration.closeOnSelect ? "true" : "false"
|
||||
}}"</code
|
||||
>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
@@ -90,11 +154,21 @@
|
||||
|
||||
<div class="list-item">
|
||||
<label for="rtl">
|
||||
<input id="rtl" type="radio" v-model="configuration.dir" value="rtl">
|
||||
<input
|
||||
id="rtl"
|
||||
type="radio"
|
||||
v-model="configuration.dir"
|
||||
value="rtl"
|
||||
/>
|
||||
<code>dir="rtl"</code>
|
||||
</label>
|
||||
<label for="ltr">
|
||||
<input id="ltr" type="radio" v-model="configuration.dir" value="ltr">
|
||||
<input
|
||||
id="ltr"
|
||||
type="radio"
|
||||
v-model="configuration.dir"
|
||||
value="ltr"
|
||||
/>
|
||||
<code>dir="ltr"</code>
|
||||
</label>
|
||||
</div>
|
||||
@@ -103,11 +177,17 @@
|
||||
<div id="sandbox">
|
||||
<slot v-bind="configuration">
|
||||
<div class="example">
|
||||
<v-select v-bind="configuration" placeholder="country objects"></v-select>
|
||||
<v-select
|
||||
v-bind="configuration"
|
||||
placeholder="country objects"
|
||||
></v-select>
|
||||
</div>
|
||||
|
||||
<div class="example">
|
||||
<v-select v-bind="configuration" placeholder="country objects, using option scoped slots">
|
||||
<v-select
|
||||
v-bind="configuration"
|
||||
placeholder="country objects, using option scoped slots"
|
||||
>
|
||||
<template slot="selected-option" slot-scope="{ label, value }">
|
||||
{{ label }} -- {{ value }}
|
||||
</template>
|
||||
@@ -118,7 +198,11 @@
|
||||
</div>
|
||||
|
||||
<div class="example">
|
||||
<v-select v-bind="configuration" :options="['cat', 'dog', 'bear']" placeholder="string options, option slots">
|
||||
<v-select
|
||||
v-bind="configuration"
|
||||
:options="['cat', 'dog', 'bear']"
|
||||
placeholder="string options, option slots"
|
||||
>
|
||||
<template slot="selected-option" slot-scope="{ label }">
|
||||
{{ label }}
|
||||
</template>
|
||||
@@ -129,32 +213,48 @@
|
||||
</div>
|
||||
|
||||
<div class="example">
|
||||
<v-select v-bind="configuration" :options="[1,5,10]" placeholder="options=[1,5,10]"></v-select>
|
||||
<v-select
|
||||
v-bind="configuration"
|
||||
:options="[1, 5, 10]"
|
||||
placeholder="options=[1,5,10]"
|
||||
></v-select>
|
||||
</div>
|
||||
|
||||
<div class="example">
|
||||
<v-select v-bind="configuration" label="title" :options="optionDataSets.books" :filter="fuseSearch"
|
||||
placeholder="advanced filtering w/ fuse.js + scoped slots">
|
||||
<v-select
|
||||
v-bind="configuration"
|
||||
label="title"
|
||||
:options="optionDataSets.books"
|
||||
:filter="fuseSearch"
|
||||
placeholder="advanced filtering w/ fuse.js + scoped slots"
|
||||
>
|
||||
<template slot="option" slot-scope="option">
|
||||
<strong>{{ option.title }}</strong><br>
|
||||
<em>{{ `${option.author.firstName} ${option.author.lastName}` }}</em>
|
||||
<strong>{{ option.title }}</strong
|
||||
><br />
|
||||
<em>{{
|
||||
`${option.author.firstName} ${option.author.lastName}`
|
||||
}}</em>
|
||||
</template>
|
||||
</v-select>
|
||||
</div>
|
||||
|
||||
<div class="example">
|
||||
<v-select
|
||||
v-bind="configuration"
|
||||
placeholder="search github repositories.."
|
||||
label="full_name"
|
||||
@search="search"
|
||||
:options="ajaxRes"
|
||||
v-bind="configuration"
|
||||
placeholder="search github repositories.."
|
||||
label="full_name"
|
||||
@search="search"
|
||||
:options="ajaxRes"
|
||||
>
|
||||
</v-select>
|
||||
</div>
|
||||
|
||||
<div class="example">
|
||||
<v-select v-bind="configuration" :options="[]" placeholder="options=[]"></v-select>
|
||||
<v-select
|
||||
v-bind="configuration"
|
||||
:options="[]"
|
||||
placeholder="options=[]"
|
||||
></v-select>
|
||||
</div>
|
||||
</slot>
|
||||
</div>
|
||||
@@ -162,16 +262,16 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Fuse from 'fuse.js';
|
||||
import debounce from 'lodash/debounce';
|
||||
import vSelect from '../../src/components/Select.vue';
|
||||
import countries from '../data/countryCodes.js';
|
||||
import books from '../data/books.js';
|
||||
import Fuse from "fuse.js";
|
||||
import debounce from "lodash/debounce";
|
||||
import vSelect from "../../src/components/Select.vue";
|
||||
import countries from "../assets/data/countryCodes.js";
|
||||
import books from "../assets/data/books.js";
|
||||
|
||||
const defaultConfig = () => ({
|
||||
options: countries,
|
||||
multiple: false,
|
||||
dir: 'ltr',
|
||||
dir: "ltr",
|
||||
clearable: true,
|
||||
searchable: true,
|
||||
filterable: true,
|
||||
@@ -179,7 +279,7 @@ const defaultConfig = () => ({
|
||||
closeOnSelect: true,
|
||||
disabled: false,
|
||||
selectOntab: false,
|
||||
placeholder: 'Select a Country...',
|
||||
placeholder: "Select a Country...",
|
||||
});
|
||||
|
||||
export default {
|
||||
@@ -189,14 +289,14 @@ export default {
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
components: {vSelect},
|
||||
data () {
|
||||
components: { vSelect },
|
||||
data() {
|
||||
return {
|
||||
configuration: defaultConfig(),
|
||||
value: null,
|
||||
ajaxRes: [],
|
||||
people: [],
|
||||
optionDataSet: 'countries',
|
||||
optionDataSet: "countries",
|
||||
optionDataSets: {
|
||||
countries,
|
||||
books,
|
||||
@@ -204,16 +304,16 @@ export default {
|
||||
};
|
||||
},
|
||||
methods: {
|
||||
search (search, loading) {
|
||||
search(search, loading) {
|
||||
loading(true);
|
||||
this.getRepositories(search, loading, this);
|
||||
},
|
||||
searchPeople (search, loading) {
|
||||
searchPeople(search, loading) {
|
||||
loading(true);
|
||||
this.getPeople(loading, this);
|
||||
},
|
||||
getPeople: debounce((loading, vm) => {
|
||||
vm.$http.get(`https://reqres.in/api/users?per_page=10`).then(res => {
|
||||
vm.$http.get(`https://reqres.in/api/users?per_page=10`).then((res) => {
|
||||
vm.people = res.data.data;
|
||||
loading(false);
|
||||
});
|
||||
@@ -221,7 +321,7 @@ export default {
|
||||
getRepositories: debounce((search, loading, vm) => {
|
||||
vm.$http
|
||||
.get(`https://api.github.com/search/repositories?q=${search}`)
|
||||
.then(res => {
|
||||
.then((res) => {
|
||||
vm.ajaxRes = res.data.items;
|
||||
loading(false);
|
||||
});
|
||||
@@ -231,46 +331,45 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#sandbox-wrap {
|
||||
min-height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: auto 75%;
|
||||
grid-template-rows: auto;
|
||||
grid-template-areas:
|
||||
"sidebar component"
|
||||
}
|
||||
#sandbox-wrap {
|
||||
min-height: 100%;
|
||||
display: grid;
|
||||
grid-template-columns: auto 75%;
|
||||
grid-template-rows: auto;
|
||||
grid-template-areas: "sidebar component";
|
||||
}
|
||||
|
||||
#config {
|
||||
grid-area: sidebar;
|
||||
border-right: 1px solid #eaecef;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
#config {
|
||||
grid-area: sidebar;
|
||||
border-right: 1px solid #eaecef;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
#sandbox {
|
||||
grid-area: component;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
#sandbox {
|
||||
grid-area: component;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.list-item {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
padding: 1rem 1rem 0;
|
||||
}
|
||||
.list-item {
|
||||
margin-top: 0;
|
||||
margin-bottom: 1rem;
|
||||
padding: 1rem 1rem 0;
|
||||
}
|
||||
|
||||
.list-item:not(:first-child) {
|
||||
border-top: 1px solid #eaecef;
|
||||
}
|
||||
.list-item:not(:first-child) {
|
||||
border-top: 1px solid #eaecef;
|
||||
}
|
||||
|
||||
.example {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.example {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.v-select {
|
||||
width: 25em;
|
||||
}
|
||||
.v-select {
|
||||
width: 25em;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
placeholder="Choose a book to read"
|
||||
label="title"
|
||||
:options="books"
|
||||
:selectable="option => ! option.author.lastName.includes('Woodhouse')"
|
||||
:selectable="(option) => !option.author.lastName.includes('Woodhouse')"
|
||||
/>
|
||||
</template>
|
||||
<script>
|
||||
import books from '../data/books.js';
|
||||
import books from "../assets/data/books.js";
|
||||
export default {
|
||||
computed: {
|
||||
books: () => books,
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<template>
|
||||
<form @submit.stop="onSubmit">
|
||||
<v-select :options="books" label="title" v-model="selected">
|
||||
<template #search="{attributes, events}">
|
||||
<template #search="{ attributes, events }">
|
||||
<input
|
||||
:required="!selected"
|
||||
class="vs__search"
|
||||
@@ -11,12 +11,12 @@
|
||||
</template>
|
||||
</v-select>
|
||||
|
||||
<input type="submit">
|
||||
<input type="submit" />
|
||||
</form>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import books from '../data/books.js'
|
||||
import books from "../assets/data/books.js";
|
||||
export default {
|
||||
data: () => ({
|
||||
books,
|
||||
@@ -24,28 +24,28 @@ export default {
|
||||
}),
|
||||
methods: {
|
||||
onSubmit() {
|
||||
alert('Submitted!');
|
||||
}
|
||||
}
|
||||
alert("Submitted!");
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
form {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
form {
|
||||
display: flex;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.v-select {
|
||||
width: 75%;
|
||||
}
|
||||
.v-select {
|
||||
width: 75%;
|
||||
}
|
||||
|
||||
input[type="submit"] {
|
||||
margin-left: 1rem;
|
||||
background: #44ae7d;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
width: 20%;
|
||||
}
|
||||
input[type="submit"] {
|
||||
margin-left: 1rem;
|
||||
background: #44ae7d;
|
||||
border: none;
|
||||
border-radius: 3px;
|
||||
color: #fff;
|
||||
width: 20%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<a :href="href" class="flex items-center">
|
||||
<slot></slot>
|
||||
<img
|
||||
src="~assets/svg/ExternalLink.svg?data"
|
||||
aria-hidden="true"
|
||||
class="w-5 h-5 opacity-50"
|
||||
alt="External Link Icon"
|
||||
/>
|
||||
</a>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: "ExternalLink",
|
||||
props: {
|
||||
href: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1 +1,35 @@
|
||||
<template></template>
|
||||
<template>
|
||||
<div>
|
||||
<header>
|
||||
<nav class="flex justify-between items-center px-5">
|
||||
<h1 class="font-bold text-xl text-gray-800">Vue Select</h1>
|
||||
|
||||
<ContentSearch />
|
||||
|
||||
<ul class="flex items-center space-x-4">
|
||||
<li>
|
||||
<NuxtLink to="/sandbox">Sandbox</NuxtLink>
|
||||
</li>
|
||||
<li>
|
||||
<ExternalLink href="https://github.com/sagalbot/vue-select">
|
||||
GitHub
|
||||
</ExternalLink>
|
||||
</li>
|
||||
</ul>
|
||||
</nav>
|
||||
</header>
|
||||
|
||||
<div>
|
||||
<nav></nav>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ContentSearch from "~/components/ContentSearch.vue";
|
||||
import ExternalLink from "~/layouts/ExternalLink.vue";
|
||||
|
||||
export default {
|
||||
components: { ExternalLink, ContentSearch },
|
||||
};
|
||||
</script>
|
||||
|
||||
+8
-2
@@ -1,4 +1,10 @@
|
||||
export default {
|
||||
import { resolve } from "path";
|
||||
import theme from "@nuxt/content-theme-docs";
|
||||
|
||||
export default theme({
|
||||
env: {},
|
||||
alias: {
|
||||
svg: resolve(__dirname, "./assets/svg"),
|
||||
},
|
||||
buildModules: ["@nuxtjs/tailwindcss"],
|
||||
};
|
||||
});
|
||||
|
||||
+3
-1
@@ -10,9 +10,12 @@
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nuxt/content": "^1.14.0",
|
||||
"@nuxt/content-theme-docs": "^0.10.2",
|
||||
"@nuxtjs/svg": "^0.1.12",
|
||||
"@nuxtjs/tailwindcss": "^4.2.1",
|
||||
"@octokit/graphql": "^4.6.4",
|
||||
"@popperjs/core": "^2.9.2",
|
||||
"@tailwindcss/forms": "^0.3.3",
|
||||
"autoprefixer": "^10.3.1",
|
||||
"axios": "^0.21.1",
|
||||
"date-fns": "^2.23.0",
|
||||
@@ -21,7 +24,6 @@
|
||||
"octonode": "^0.10.2",
|
||||
"postcss": "^8.3.6",
|
||||
"prettier": "^2.3.2",
|
||||
"tailwindcss": "^2.2.7",
|
||||
"vuex": "^3.6.2"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,5 +11,5 @@ module.exports = {
|
||||
theme: {
|
||||
extend: {},
|
||||
},
|
||||
plugins: [],
|
||||
plugins: [require("@tailwindcss/forms")],
|
||||
};
|
||||
|
||||
+746
-19
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user