mirror of
https://github.com/tenrok/vue-select.git
synced 2026-06-07 07:12:23 +03:00
Merge branch 'master' into ft/prettier
This commit is contained in:
@@ -29,10 +29,16 @@ jobs:
|
||||
node-version: 12
|
||||
|
||||
- name: Install dependencies
|
||||
run: yarn install --frozen-lockfile
|
||||
run: |
|
||||
yarn install --frozen-lockfile
|
||||
cd docs
|
||||
yarn install --frozen-lockfile
|
||||
|
||||
- name: Build
|
||||
- name: Build Dist
|
||||
run: yarn build
|
||||
|
||||
- name: Bundlewatch
|
||||
run: npx bundlewatch
|
||||
|
||||
- name: Build Docs
|
||||
run: yarn build:docs
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
node_modules
|
||||
|
||||
# local env files
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
|
||||
@@ -1,18 +1,22 @@
|
||||
# vue-select      
|
||||
# vue-select     [](https://coveralls.io/github/sagalbot/vue-select?branch=master) 
|
||||
|
||||
> **Everything you wish the HTML `<select>` element could do, wrapped up into a lightweight, zero
|
||||
dependency, extensible Vue component.**
|
||||
> **Everything you wish the HTML `<select>` element could do, wrapped up into a lightweight, zero
|
||||
> dependency, extensible Vue component.**
|
||||
|
||||
Vue Select is a feature rich select/dropdown/typeahead component. It provides a default
|
||||
template that fits most use cases for a filterable select dropdown. The component is designed to be as
|
||||
lightweight as possible, while maintaining high standards for accessibility,
|
||||
developer experience, and customization.
|
||||
|
||||
- Tagging
|
||||
- Filtering / Searching
|
||||
- Vuex Support
|
||||
- AJAX Support
|
||||
- SSR Support
|
||||
- Accessible
|
||||
- ~20kb Total / ~5kb CSS / ~15kb JS
|
||||
- Select Single/Multiple Options
|
||||
- Customizable with slots and SCSS variables
|
||||
- Tested with Bootstrap 3/4, Bulma, Foundation
|
||||
- +95% Test Coverage
|
||||
- Zero dependencies
|
||||
|
||||
## Documentation
|
||||
@@ -20,32 +24,47 @@ dependency, extensible Vue component.**
|
||||
Complete documentation and examples available at https://vue-select.org.
|
||||
|
||||
- **[API Documentation](https://vue-select.org)**
|
||||
- **[Sandbox Demo](https://vue-select.org/sandbox.html)**
|
||||
- **[CodePen Template](http://codepen.io/sagalbot/pen/NpwrQO)**
|
||||
- **[GitHub Projects](https://github.com/sagalbot/vue-select/projects)**
|
||||
|
||||
## Sponsors :tada:
|
||||
|
||||
It takes a lot of effort to maintain this project. If it has saved you development time, please consider [sponsoring the project](https://github.com/sponsors/sagalbot)
|
||||
with GitHub sponsors!
|
||||
|
||||
Huge thanks to the [sponsors](https://github.com/sponsors/sagalbot) and [contributors](https://github.com/sagalbot/vue-select/graphs/contributors) that make Vue Select possible!
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
$ npm install vue-select
|
||||
yarn add vue-select
|
||||
|
||||
# or use npm
|
||||
|
||||
npm install vue-select
|
||||
```
|
||||
|
||||
Register the component
|
||||
Then, import and register the component:
|
||||
|
||||
```js
|
||||
import Vue from 'vue'
|
||||
import vSelect from 'vue-select'
|
||||
import Vue from "vue";
|
||||
import vSelect from "vue-select";
|
||||
|
||||
Vue.component('v-select', vSelect)
|
||||
Vue.component("v-select", vSelect);
|
||||
```
|
||||
|
||||
You may now use the component in your markup
|
||||
The component itself does not include any CSS. You'll need to include it separately:
|
||||
|
||||
```html
|
||||
<v-select v-model="selected" :options="['Vue.js','React']"></v-select>
|
||||
```js
|
||||
import "vue-select/dist/vue-select.css";
|
||||
```
|
||||
|
||||
You can also include vue-select directly in the browser. Check out the
|
||||
Alternatively, you can import the scss for complete control of the component styles:
|
||||
|
||||
```scss
|
||||
@import "vue-select/src/scss/vue-select.scss";
|
||||
```
|
||||
|
||||
You can also include vue-select directly in the browser. Check out the
|
||||
[documentation for loading from CDN.](https://vue-select.org/guide/install.html#in-the-browser).
|
||||
|
||||
## License
|
||||
|
||||
+29
-24
@@ -1,39 +1,44 @@
|
||||
<template>
|
||||
<div id="app">
|
||||
<sandbox hide-help v-slot="config">
|
||||
<v-select v-bind="config"/>
|
||||
</sandbox>
|
||||
<v-select v-model="selected" v-bind="config" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import vSelect from '../src/components/Select';
|
||||
import Sandbox from '../docs/.vuepress/components/Sandbox';
|
||||
// import countries from '../docs/.vuepress/data/countryCodes';
|
||||
// import books from '../docs/.vuepress/data/books';
|
||||
import vSelect from "../src/components/Select";
|
||||
import countries from "../docs/.vuepress/data/countryCodes";
|
||||
import books from "../docs/.vuepress/data/books";
|
||||
|
||||
export default {
|
||||
components: {Sandbox, vSelect},
|
||||
components: { vSelect },
|
||||
data: () => ({
|
||||
selected: null,
|
||||
config: {
|
||||
options: countries
|
||||
}
|
||||
})
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
font-family: -apple-system, sans-serif;
|
||||
}
|
||||
html,
|
||||
body {
|
||||
margin: 0;
|
||||
height: 100%;
|
||||
font-family: -apple-system, sans-serif;
|
||||
}
|
||||
|
||||
#app {
|
||||
height: 100%;
|
||||
}
|
||||
#app {
|
||||
height: 100%;
|
||||
max-width: 20rem;
|
||||
margin: 10rem auto 0;
|
||||
}
|
||||
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid #cacaca;
|
||||
margin-bottom: 1em;
|
||||
padding-top: 1em;
|
||||
width: 90%;
|
||||
}
|
||||
hr {
|
||||
border: none;
|
||||
border-bottom: 1px solid #cacaca;
|
||||
margin-bottom: 1em;
|
||||
padding-top: 1em;
|
||||
width: 90%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Vue Select Dev</title>
|
||||
<link href="https://unpkg.com/tailwindcss@^2/dist/tailwind.min.css" rel="stylesheet">
|
||||
<!--<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/foundation/6.5.3/css/foundation.min.css">-->
|
||||
<!--<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/bulma/0.7.4/css/bulma.min.css">-->
|
||||
<!--<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">-->
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# personal access token used to fetch
|
||||
# sponsor listings when working locally
|
||||
GITHUB_TOKEN=
|
||||
@@ -1,9 +1,10 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-select
|
||||
placeholder="choose a country"
|
||||
v-model="selected"
|
||||
:options="['Canada', 'United States']"
|
||||
:components="{Deselect}"
|
||||
:options="['Canada', 'United States']"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,63 @@
|
||||
<template>
|
||||
<ul>
|
||||
<li v-for="{ login, avatar_url, html_url, contributions } in contributors">
|
||||
<img :src="`${avatar_url}&s=75`" :alt="`${login}'s Avatar`" />
|
||||
<div>
|
||||
<a :href="html_url">@{{ login }}</a>
|
||||
<br /><a
|
||||
class="contributions-link"
|
||||
:href="
|
||||
`https://github.com/sagalbot/vue-select/commits?author=${login}`
|
||||
"
|
||||
>{{ contributions }} contributions</a
|
||||
>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { CONTRIBUTORS } from "@dynamic/constants";
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
contributors: CONTRIBUTORS.filter(
|
||||
({ login }) => login !== "semantic-release-bot"
|
||||
)
|
||||
})
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
max-width: 100%;
|
||||
margin-top: 2rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
img {
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
margin-right: 1rem;
|
||||
border-radius: 100%;
|
||||
}
|
||||
li {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
margin-right: 1rem;
|
||||
}
|
||||
a {
|
||||
display: inline-block;
|
||||
max-width: 150px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.contributions-link {
|
||||
color: #2c5282;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,31 @@
|
||||
<template>
|
||||
<v-select :filter="fuseSearch" :options="books" :getOptionLabel="option => option.title">
|
||||
<template #option="{ author, title }">
|
||||
{{ title }}
|
||||
<br />
|
||||
<cite>{{ author.firstName }} {{ author.lastName }}</cite>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Fuse from "fuse.js";
|
||||
import books from "../data/books";
|
||||
|
||||
export default {
|
||||
computed: {
|
||||
books: () => books
|
||||
},
|
||||
methods: {
|
||||
fuseSearch(options, search) {
|
||||
const fuse = new Fuse(options, {
|
||||
keys: ["title", "author.firstName", "author.lastName"],
|
||||
shouldSort: true
|
||||
});
|
||||
return search.length
|
||||
? fuse.search(search).map(({ item }) => item)
|
||||
: fuse.list;
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,74 @@
|
||||
<template>
|
||||
<v-select
|
||||
:options="paginated"
|
||||
:filterable="false"
|
||||
@open="onOpen"
|
||||
@close="onClose"
|
||||
@search="query => search = query"
|
||||
>
|
||||
<template #list-footer>
|
||||
<li ref="load" class="loader" v-show="hasNextPage">
|
||||
Loading more options...
|
||||
</li>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countries from '../data/countries';
|
||||
|
||||
export default {
|
||||
name: "InfiniteScroll",
|
||||
data: () => ({
|
||||
observer: null,
|
||||
limit: 10,
|
||||
search: ''
|
||||
}),
|
||||
mounted () {
|
||||
/**
|
||||
* You could do this directly in data(), but since these docs
|
||||
* are server side rendered, IntersectionObserver doesn't exist
|
||||
* in that environment, so we need to do it in mounted() instead.
|
||||
*/
|
||||
this.observer = new IntersectionObserver(this.infiniteScroll);
|
||||
},
|
||||
computed: {
|
||||
filtered () {
|
||||
return countries.filter(country => country.includes(this.search));
|
||||
},
|
||||
paginated () {
|
||||
return this.filtered.slice(0, this.limit);
|
||||
},
|
||||
hasNextPage () {
|
||||
return this.paginated.length < this.filtered.length;
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
async onOpen () {
|
||||
if (this.hasNextPage) {
|
||||
await this.$nextTick();
|
||||
this.observer.observe(this.$refs.load)
|
||||
}
|
||||
},
|
||||
onClose () {
|
||||
this.observer.disconnect();
|
||||
},
|
||||
async infiniteScroll ([{isIntersecting, target}]) {
|
||||
if (isIntersecting) {
|
||||
const ul = target.offsetParent;
|
||||
const scrollTop = target.offsetParent.scrollTop;
|
||||
this.limit += 10;
|
||||
await this.$nextTick();
|
||||
ul.scrollTop = scrollTop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.loader {
|
||||
text-align: center;
|
||||
color: #bbbbbb;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,49 @@
|
||||
<template>
|
||||
<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>
|
||||
</li>
|
||||
</v-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import countries from '../data/countries';
|
||||
export default {
|
||||
data: () => ({
|
||||
countries,
|
||||
search: '',
|
||||
offset: 0,
|
||||
limit: 10,
|
||||
}),
|
||||
computed: {
|
||||
filtered () {
|
||||
return this.countries.filter(country => country.includes(this.search));
|
||||
},
|
||||
paginated () {
|
||||
return this.filtered.slice(this.offset, this.limit + this.offset);
|
||||
},
|
||||
hasNextPage () {
|
||||
const nextOffset = this.offset + 10;
|
||||
return Boolean(this.filtered.slice(nextOffset, this.limit + nextOffset).length);
|
||||
},
|
||||
hasPrevPage () {
|
||||
const prevOffset = this.offset - 10;
|
||||
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;
|
||||
}
|
||||
</style>
|
||||
@@ -22,7 +22,7 @@ import { createPopper } from '@popperjs/core';
|
||||
export default {
|
||||
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.
|
||||
@@ -39,7 +39,7 @@ export default {
|
||||
* wrapper so that we can set some styles for when the dropdown is placed
|
||||
* above.
|
||||
*/
|
||||
createPopper(component.$refs.toggle, dropdownList, {
|
||||
const popper = createPopper(component.$refs.toggle, dropdownList, {
|
||||
placement: this.placement,
|
||||
modifiers: [
|
||||
{
|
||||
@@ -56,6 +56,12 @@ export default {
|
||||
},
|
||||
}]
|
||||
});
|
||||
|
||||
/**
|
||||
* To prevent memory leaks Popper needs to be destroyed.
|
||||
* If you return function, it will be called just before dropdown is removed from DOM.
|
||||
*/
|
||||
return () => popper.destroy();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -226,11 +226,6 @@ export default {
|
||||
loading(false);
|
||||
});
|
||||
}, 250),
|
||||
fuseSearch (options, search) {
|
||||
return new Fuse(options, {
|
||||
keys: ['title', 'author.firstName', 'author.lastName'],
|
||||
}).search(search);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<v-select append-to-body>
|
||||
<template #footer>
|
||||
<div style="opacity: .8">Bottom of the component, in the footer slot!</div>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<v-select>
|
||||
<template #header>
|
||||
<div style="opacity: .8">Top of the component, in the header slot!</div>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<v-select>
|
||||
<template #list-footer>
|
||||
<li style="text-align: center">Bottom of the list!</li>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<v-select>
|
||||
<template #list-header>
|
||||
<li style="text-align: center">Top of the list!</li>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<v-select>
|
||||
<template #no-options="{ search, searching, loading }">
|
||||
This is the no options slot.
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
@@ -0,0 +1,7 @@
|
||||
<template>
|
||||
<v-select>
|
||||
<template #open-indicator="{ attributes }">
|
||||
<span v-bind="attributes">🔽</span>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
@@ -0,0 +1,24 @@
|
||||
<template>
|
||||
<v-select :options="books" label="title">
|
||||
<template #option="{ title, author }">
|
||||
<h3 style="margin: 0">{{ title }}</h3>
|
||||
<em>{{ author.firstName }} {{ author.lastName }}</em>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: () => ({
|
||||
books: [
|
||||
{
|
||||
title: "Old Man's War",
|
||||
author: {
|
||||
firstName: "John",
|
||||
lastName: "Scalzi"
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,12 @@
|
||||
<template>
|
||||
<v-select>
|
||||
<template #search="{ attributes, events }">
|
||||
<input
|
||||
maxlength="1"
|
||||
class="vs__search"
|
||||
v-bind="attributes"
|
||||
v-on="events"
|
||||
>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
@@ -0,0 +1,26 @@
|
||||
<template>
|
||||
<v-select v-model="selected" :options="books" label="title">
|
||||
<template #selected-option="{ title, author }">
|
||||
<div style="display: flex; align-items: baseline;">
|
||||
<strong>{{ title }}</strong>
|
||||
<em style="margin-left: .5rem;">by {{ author.firstName }} {{ author.lastName }}</em>
|
||||
</div>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
const book = {
|
||||
title: "Old Man's War",
|
||||
author: {
|
||||
firstName: "John",
|
||||
lastName: "Scalzi"
|
||||
}
|
||||
};
|
||||
export default {
|
||||
data: () => ({
|
||||
books: [book],
|
||||
selected: book
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,23 @@
|
||||
<template>
|
||||
<v-select :options="books" label="title">
|
||||
<template #selected-option-container="{ option, deselect, multiple, disabled }">
|
||||
<div class="vs__selected">{{ option.title }}</div>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
data: () => ({
|
||||
books: [
|
||||
{
|
||||
title: "Old Man's War",
|
||||
author: {
|
||||
firstName: "John",
|
||||
lastName: "Scalzi"
|
||||
}
|
||||
}
|
||||
]
|
||||
})
|
||||
}
|
||||
</script>
|
||||
@@ -0,0 +1,9 @@
|
||||
<template>
|
||||
<v-select :loading="true">
|
||||
<template #spinner="{ loading }">
|
||||
<div v-if="loading" style="border-left-color: rgba(88,151,251,0.71)" class="vs__spinner">
|
||||
The .vs__spinner class will hide the text for me.
|
||||
</div>
|
||||
</template>
|
||||
</v-select>
|
||||
</template>
|
||||
@@ -0,0 +1,25 @@
|
||||
<template>
|
||||
<p class="sponsor">
|
||||
Are you using Vue Select on a lot of projects? Please consider
|
||||
<a href="https://github.com/sponsors/sagalbot" target="_blank">
|
||||
sponsoring @sagalbot!
|
||||
</a>
|
||||
</p>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.sponsor {
|
||||
display: block;
|
||||
border: 2px solid #e2e8f0;
|
||||
background: #f7fafc;
|
||||
border-radius: 10px;
|
||||
padding: 0.25rem;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
color: #8492a4;
|
||||
}
|
||||
p a {
|
||||
color: #48BB78;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,146 @@
|
||||
<template>
|
||||
<div class="sponsor-me">
|
||||
<div class="avatar">
|
||||
<a href="https://github.com/sponsors/sagalbot">
|
||||
<img
|
||||
src="https://avatars2.githubusercontent.com/u/692538?s=400&u=a5ab0d164266bd2d59ce1a514835627b4cc4f24f&v=4"
|
||||
alt="Jeff Sagal's Avatar"
|
||||
/>
|
||||
</a>
|
||||
</div>
|
||||
<div class="cta">
|
||||
<p style="font-size: 1.2rem; font-weight: 600;">
|
||||
Hi! I'm Jeff Sagal, the author of Vue Select.
|
||||
</p>
|
||||
<p>
|
||||
I've spent hundreds of hours working alongside contributors to make Vue
|
||||
Select the best it can be. I've researched UX and accessibility
|
||||
patterns, squashed bugs, reviewed code, tested-cross browser, and spent
|
||||
many evenings and weekends working on these docs.
|
||||
</p>
|
||||
<p>
|
||||
If it's saved you time on your projects, please consider supporting me
|
||||
on GitHub sponsors.
|
||||
</p>
|
||||
<div class="links">
|
||||
<a
|
||||
href="https://github.com/sponsors/sagalbot"
|
||||
class="button"
|
||||
target="_blank"
|
||||
>
|
||||
<svg viewBox="0 0 20 20">
|
||||
<path
|
||||
d="M10 0a10 10 0 00-3.16 19.49c.5.1.68-.22.68-.48l-.01-1.7c-2.78.6-3.37-1.34-3.37-1.34-.46-1.16-1.11-1.47-1.11-1.47-.9-.62.07-.6.07-.6 1 .07 1.53 1.03 1.53 1.03.9 1.52 2.34 1.08 2.91.83.1-.65.35-1.09.63-1.34-2.22-.25-4.55-1.11-4.55-4.94 0-1.1.39-1.99 1.03-2.69a3.6 3.6 0 01.1-2.64s.84-.27 2.75 1.02a9.58 9.58 0 015 0c1.91-1.3 2.75-1.02 2.75-1.02.55 1.37.2 2.4.1 2.64.64.7 1.03 1.6 1.03 2.69 0 3.84-2.34 4.68-4.57 4.93.36.31.68.92.68 1.85l-.01 2.75c0 .26.18.58.69.48A10 10 0 0010 0"
|
||||
/>
|
||||
</svg>
|
||||
Sponsor Vue Select!
|
||||
</a>
|
||||
<a href="https://twitter.com/sagalbot" target="_blank" class="social-link">
|
||||
<svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M23.954 4.569a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.691 8.094 4.066 6.13 1.64 3.161a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.061a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.937 4.937 0 004.604 3.417 9.868 9.868 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63a9.936 9.936 0 002.46-2.548l-.047-.02z"
|
||||
/>
|
||||
</svg>
|
||||
Follow @sagalbot
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.sponsor-me {
|
||||
display: flex;
|
||||
border: 2px solid #c3dafe;
|
||||
background: #ebf4ff;
|
||||
border-radius: 10px;
|
||||
/*align-items: top;*/
|
||||
padding: 2rem 1rem;
|
||||
margin: 3rem 0;
|
||||
flex-direction: column;
|
||||
}
|
||||
.avatar {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-evenly;
|
||||
padding: 1rem;
|
||||
}
|
||||
.cta {
|
||||
/*text-align: center;*/
|
||||
}
|
||||
@media (min-width: 1150px) {
|
||||
.sponsor-me {
|
||||
flex-direction: row;
|
||||
}
|
||||
.avatar {
|
||||
display: flex;
|
||||
justify-content: flex-start;
|
||||
flex-direction: column;
|
||||
margin: 0 2rem;
|
||||
}
|
||||
.cta {
|
||||
text-align: left;
|
||||
}
|
||||
}
|
||||
p {
|
||||
margin-top: 0;
|
||||
}
|
||||
.avatar img {
|
||||
max-width: 150px;
|
||||
border-radius: 100%;
|
||||
}
|
||||
.button {
|
||||
display: inline-flex;
|
||||
text-align: center;
|
||||
align-items: center;
|
||||
padding: 0.75rem 1rem;
|
||||
background: #63b3ed;
|
||||
color: #fff;
|
||||
font-weight: 600;
|
||||
border-radius: 5px;
|
||||
margin-top: 0.5rem;
|
||||
transition: background-color 0.25s, box-shadow 0.25s;
|
||||
}
|
||||
.button svg {
|
||||
max-width: 25px;
|
||||
fill: currentColor;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
a.button:hover {
|
||||
box-shadow: inset 0px 0px 3px #3182ce;
|
||||
background: #90cdf4;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 1px 1px #63b3ed;
|
||||
}
|
||||
.links {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
}
|
||||
.links a {
|
||||
margin: 1rem;
|
||||
}
|
||||
@media (min-width: 1150px) {
|
||||
.links {
|
||||
flex-direction: row;
|
||||
justify-content: flex-start;
|
||||
}
|
||||
.links a {
|
||||
margin: 0 2rem 0 0;
|
||||
}
|
||||
}
|
||||
.social-link {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
color: #3182ce;
|
||||
}
|
||||
.social-link svg {
|
||||
fill: currentColor;
|
||||
width: 20px;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
.social-link:hover {
|
||||
color: #2c5282;
|
||||
text-decoration: none;
|
||||
}
|
||||
</style>
|
||||
@@ -0,0 +1,56 @@
|
||||
<template>
|
||||
<ul>
|
||||
<li v-for="{ createdAt, login, avatarUrl } in sponsors">
|
||||
<img :src="avatarUrl + '&s=150'" :alt="`@${login}'s avatar`" />
|
||||
<p>
|
||||
<a :href="`https://github.com/${login}`">@{{ login }}</a> <br />
|
||||
Sponsor since {{ createdAt }}
|
||||
</p>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { SPONSORS } from "@dynamic/constants";
|
||||
import { format } from "date-fns";
|
||||
|
||||
export default {
|
||||
data: () => ({
|
||||
sponsors: SPONSORS.map(({ createdAt, sponsorEntity }) => ({
|
||||
createdAt: format(new Date(createdAt), "LLL yyyy"),
|
||||
...sponsorEntity
|
||||
}))
|
||||
}),
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
ul {
|
||||
list-style: none;
|
||||
padding: 0;
|
||||
max-width: 100%;
|
||||
margin-top: 2rem;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: space-between;
|
||||
}
|
||||
img {
|
||||
width: 75px;
|
||||
height: 75px;
|
||||
margin-right: 1rem;
|
||||
border-radius: 100%;
|
||||
}
|
||||
li {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
/*max-width: 220px;*/
|
||||
}
|
||||
a {
|
||||
display: inline-block;
|
||||
max-width: 150px;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
</style>
|
||||
+8
-142
@@ -1,147 +1,13 @@
|
||||
const isDeployPreview = process.env.hasOwnProperty('DEPLOY_PREVIEW');
|
||||
|
||||
const meta = {
|
||||
title: 'Vue Select | VueJS Select2/Chosen Component',
|
||||
description: 'Everything you wish the HTML select element could do, wrapped up into a lightweight, extensible Vue component.',
|
||||
url: 'https://vue-select.org',
|
||||
};
|
||||
|
||||
let head = [
|
||||
[
|
||||
'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', {rel: 'icon', href: `/vue-logo.png`}],
|
||||
['meta', {name: 'theme-color', content: '#3eaf7c'}],
|
||||
['meta', {name: 'apple-mobile-web-app-capable', content: 'yes'}],
|
||||
['meta', {name: 'apple-mobile-web-app-status-bar-style', content: 'black'}],
|
||||
[
|
||||
'link',
|
||||
{rel: 'apple-touch-icon', href: `/icons/apple-touch-icon-152x152.png`}],
|
||||
[
|
||||
'link',
|
||||
{rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c'}],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
name: 'msapplication-TileImage',
|
||||
content: '/icons/msapplication-icon-144x144.png',
|
||||
}],
|
||||
['meta', {name: 'msapplication-TileColor', content: '#000000'}],
|
||||
['meta', {name: 'title', content: meta.title}],
|
||||
['meta', {name: 'description', content: meta.description}],
|
||||
['link', {rel: 'icon', href: meta.icon, type: 'image/png'}],
|
||||
['meta', {property: 'og:image', content: meta.icon}],
|
||||
['meta', {property: 'twitter:image', content: meta.icon}],
|
||||
['meta', {name: 'description', content: meta.description}],
|
||||
['meta', {property: 'og:description', content: ''}],
|
||||
['meta', {property: 'twitter:description', content: meta.description}],
|
||||
['meta', {property: 'twitter:title', content: meta.title}],
|
||||
['meta', {property: 'og:title', content: meta.title}],
|
||||
['meta', {property: 'og:site_name', content: meta.title}],
|
||||
['meta', {property: 'og:url', content: meta.url}],
|
||||
];
|
||||
|
||||
if (isDeployPreview) {
|
||||
head.push(
|
||||
['meta', {name: 'robots', content: 'noindex'}],
|
||||
['meta', {name: 'googlebot', content: 'noindex'}],
|
||||
);
|
||||
}
|
||||
const {description} = require('./config/meta');
|
||||
const head = require('./config/head');
|
||||
const plugins = require('./config/plugins');
|
||||
const themeConfig = require('./config/themeConfig');
|
||||
|
||||
module.exports = {
|
||||
title: 'Vue Select',
|
||||
description: meta.description,
|
||||
description,
|
||||
head,
|
||||
plugins: {
|
||||
'@vuepress/google-analytics': {
|
||||
ga: isDeployPreview ? '' : 'UA-12818324-8',
|
||||
},
|
||||
'@vuepress/pwa': {
|
||||
serviceWorker: false,
|
||||
updatePopup: true,
|
||||
},
|
||||
'@vuepress/plugin-register-components': {},
|
||||
'@vuepress/plugin-active-header-links': {},
|
||||
'@vuepress/plugin-search': {},
|
||||
'@vuepress/plugin-nprogress': {},
|
||||
},
|
||||
themeConfig: {
|
||||
repo: 'sagalbot/vue-select',
|
||||
editLinks: true,
|
||||
docsDir: 'docs',
|
||||
nav: [
|
||||
{text: 'Home', link: '/'},
|
||||
{text: 'Sandbox', link: '/sandbox'},
|
||||
],
|
||||
sidebar: {
|
||||
'/': [
|
||||
{
|
||||
title: 'Getting Started',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['guide/install', 'Installation'],
|
||||
['guide/options', 'Dropdown Options'],
|
||||
['guide/values', 'Selecting Values'],
|
||||
['guide/upgrading', 'Upgrading 2.x to 3.x'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Templating & Styling',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['guide/components', 'Child Components'],
|
||||
['guide/css', 'CSS & Selectors'],
|
||||
['guide/slots', 'Slots'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Accessibility',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['guide/accessibility', 'WAI-ARIA Spec'],
|
||||
['guide/localization', 'Localization'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Use Cases',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['guide/validation', 'Validation'],
|
||||
['guide/selectable', 'Limiting Selections'],
|
||||
['guide/vuex', 'Vuex'],
|
||||
['guide/ajax', 'AJAX'],
|
||||
['guide/loops', 'Using in Loops'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Customizing',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['guide/keydown', 'Keydown Events'],
|
||||
['guide/positioning', 'Dropdown Position']
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'API',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['api/props', 'Props'],
|
||||
['api/slots', 'Slots'],
|
||||
['api/events', 'Events'],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
plugins,
|
||||
themeConfig,
|
||||
};
|
||||
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
const isDeployPreview = require('./isDeployPreview');
|
||||
const meta = require('./meta');
|
||||
|
||||
const head = [
|
||||
[
|
||||
'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', {rel: 'icon', href: `/vue-logo.png`}],
|
||||
['meta', {name: 'theme-color', content: '#3eaf7c'}],
|
||||
['meta', {name: 'apple-mobile-web-app-capable', content: 'yes'}],
|
||||
['meta', {name: 'apple-mobile-web-app-status-bar-style', content: 'black'}],
|
||||
[
|
||||
'link',
|
||||
{rel: 'apple-touch-icon', href: `/icons/apple-touch-icon-152x152.png`}],
|
||||
[
|
||||
'link',
|
||||
{rel: 'mask-icon', href: '/icons/safari-pinned-tab.svg', color: '#3eaf7c'}],
|
||||
[
|
||||
'meta',
|
||||
{
|
||||
name: 'msapplication-TileImage',
|
||||
content: '/icons/msapplication-icon-144x144.png',
|
||||
}],
|
||||
['meta', {name: 'msapplication-TileColor', content: '#000000'}],
|
||||
['meta', {name: 'title', content: meta.title}],
|
||||
['meta', {name: 'description', content: meta.description}],
|
||||
['link', {rel: 'icon', href: meta.icon, type: 'image/png'}],
|
||||
['meta', {property: 'og:image', content: meta.icon}],
|
||||
['meta', {property: 'twitter:image', content: meta.icon}],
|
||||
['meta', {name: 'description', content: meta.description}],
|
||||
['meta', {property: 'og:description', content: ''}],
|
||||
['meta', {property: 'twitter:description', content: meta.description}],
|
||||
['meta', {property: 'twitter:title', content: meta.title}],
|
||||
['meta', {property: 'og:title', content: meta.title}],
|
||||
['meta', {property: 'og:site_name', content: meta.title}],
|
||||
['meta', {property: 'og:url', content: meta.url}],
|
||||
];
|
||||
|
||||
if (isDeployPreview) {
|
||||
head.push(
|
||||
['meta', {name: 'robots', content: 'noindex'}],
|
||||
['meta', {name: 'googlebot', content: 'noindex'}],
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = head;
|
||||
@@ -0,0 +1 @@
|
||||
module.exports = process.env.hasOwnProperty('DEPLOY_PREVIEW');
|
||||
@@ -0,0 +1,6 @@
|
||||
module.exports = {
|
||||
title: 'Vue Select | VueJS Select2/Chosen Component',
|
||||
description: 'Everything you wish the HTML select element could do, wrapped up into a lightweight, extensible Vue component.',
|
||||
url: 'https://vue-select.org',
|
||||
icon: '/vue-logo.png'
|
||||
};
|
||||
@@ -0,0 +1,22 @@
|
||||
const isDeployPreview = require("./isDeployPreview");
|
||||
|
||||
module.exports = [
|
||||
[
|
||||
"@vuepress/google-analytics",
|
||||
{
|
||||
ga: isDeployPreview ? "" : "UA-12818324-8"
|
||||
}
|
||||
],
|
||||
[
|
||||
"@vuepress/pwa",
|
||||
{
|
||||
serviceWorker: false,
|
||||
updatePopup: true
|
||||
}
|
||||
],
|
||||
"@vuepress/plugin-register-components",
|
||||
"@vuepress/plugin-active-header-links",
|
||||
"@vuepress/plugin-search",
|
||||
"@vuepress/plugin-nprogress",
|
||||
require('../github/index')
|
||||
];
|
||||
@@ -0,0 +1,78 @@
|
||||
module.exports = {
|
||||
repo: 'sagalbot/vue-select',
|
||||
editLinks: true,
|
||||
docsDir: 'docs',
|
||||
nav: [
|
||||
{text: 'Sandbox', link: '/sandbox'},
|
||||
],
|
||||
sidebar: {
|
||||
'/': [
|
||||
{
|
||||
title: 'Community',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['sponsors', 'Sponsors 🎉'],
|
||||
['contributors', 'Contributors'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Getting Started',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['guide/install', 'Installation'],
|
||||
['guide/options', 'Dropdown Options'],
|
||||
['guide/values', 'Selecting Values'],
|
||||
['guide/upgrading', 'Upgrading 2.x to 3.x'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Templating & Styling',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['guide/components', 'Child Components'],
|
||||
['guide/css', 'CSS & Selectors'],
|
||||
['guide/slots', 'Slots'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Accessibility',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['guide/accessibility', 'WAI-ARIA Spec'],
|
||||
['guide/localization', 'Localization'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Use Cases',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['guide/validation', 'Validation'],
|
||||
['guide/selectable', 'Limiting Selections'],
|
||||
['guide/pagination', 'Pagination'],
|
||||
['guide/infinite-scroll', 'Infinite Scroll'],
|
||||
['guide/vuex', 'Vuex'],
|
||||
['guide/ajax', 'AJAX'],
|
||||
['guide/loops', 'Using in Loops'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Customizing',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['guide/keydown', 'Keydown Events'],
|
||||
['guide/positioning', 'Dropdown Position'],
|
||||
['guide/filtering', 'Option Filtering'],
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'API',
|
||||
collapsable: false,
|
||||
children: [
|
||||
['api/props', 'Props'],
|
||||
['api/slots', 'Slots'],
|
||||
['api/events', 'Events'],
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -0,0 +1,65 @@
|
||||
require("dotenv").config();
|
||||
const axios = require("axios");
|
||||
const { graphql } = require("@octokit/graphql");
|
||||
|
||||
module.exports = async () => ({
|
||||
name: "constants.js",
|
||||
content: `
|
||||
export const SPONSORS = ${JSON.stringify(await getSponsors())};
|
||||
export const CONTRIBUTORS = ${JSON.stringify(await getContributors())};
|
||||
`
|
||||
});
|
||||
|
||||
/**
|
||||
* Get a list of vue select contributors.
|
||||
* @return {Promise<T>}
|
||||
*/
|
||||
async function getContributors() {
|
||||
const { data } = await axios.get(
|
||||
"https://api.github.com/repos/sagalbot/vue-select/contributors?per_page=100"
|
||||
);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of the current sponsors. Requires GITHUB_TOKEN to be set.
|
||||
* @return {Promise<*[]|ProfileNode[]|postcss.ChildNode[]|Array<parser.Node>|[]>}
|
||||
*/
|
||||
async function getSponsors() {
|
||||
const query = `
|
||||
{
|
||||
user(login: "sagalbot") {
|
||||
sponsorshipsAsMaintainer(first: 100) {
|
||||
nodes {
|
||||
sponsorEntity {
|
||||
... on User {
|
||||
id
|
||||
avatarUrl
|
||||
login
|
||||
}
|
||||
... on Organization {
|
||||
id
|
||||
avatarUrl
|
||||
login
|
||||
}
|
||||
}
|
||||
createdAt
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`;
|
||||
|
||||
try {
|
||||
const { user } = await graphql(query, {
|
||||
headers: {
|
||||
authorization: `token ${process.env.GITHUB_TOKEN || ""}`
|
||||
}
|
||||
});
|
||||
return user.sponsorshipsAsMaintainer.nodes;
|
||||
} catch (e) {
|
||||
console.log(`${e.status} ${e.name} - Couldn't fetch sponsor data.`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
const clientDynamicModules = require('./clientDynamicModules');
|
||||
|
||||
module.exports = {
|
||||
clientDynamicModules: async () => await clientDynamicModules(),
|
||||
};
|
||||
@@ -1,43 +0,0 @@
|
||||
<script>
|
||||
export default {
|
||||
render (h) {
|
||||
return h('div', {attrs: {id: 'codefund'}});
|
||||
},
|
||||
mounted () {
|
||||
this.load();
|
||||
},
|
||||
watch: {
|
||||
'$route' (to, from) {
|
||||
if (
|
||||
to.path !== from.path
|
||||
// Only reload if the ad has been loaded
|
||||
// otherwise it's possible that the script is appended but
|
||||
// the ads are not loaded yet. This would result in duplicated ads.
|
||||
&& this.$el.querySelector('#cf')
|
||||
) {
|
||||
this.$el.innerHTML = '';
|
||||
this.load();
|
||||
}
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
load () {
|
||||
|
||||
// const template = 'default';
|
||||
// const template = 'vertical';
|
||||
// const template = 'float-with-close';
|
||||
// const template = 'image-only';
|
||||
// const template = 'image-centered';
|
||||
// const template = 'square';
|
||||
const template = 'centered';
|
||||
// const template = 'bottom-bar';
|
||||
|
||||
const s = document.createElement('script');
|
||||
s.id = '_codefund_js';
|
||||
s.src = `//codefund.app/properties/193/funder.js?template=${template}`;
|
||||
s.async = 'async';
|
||||
this.$el.appendChild(s);
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -0,0 +1,54 @@
|
||||
<script>
|
||||
/**
|
||||
* @see https://ethical-ad-client.readthedocs.io/en/latest/
|
||||
*/
|
||||
export default {
|
||||
render(h) {
|
||||
return h("div", {
|
||||
attrs: {
|
||||
id: "ads",
|
||||
"data-ea-publisher": "vue-select",
|
||||
"data-ea-type": "image"
|
||||
},
|
||||
class: "flat horizontal"
|
||||
});
|
||||
},
|
||||
mounted() {
|
||||
this.load();
|
||||
},
|
||||
watch: {
|
||||
$route(to, from) {
|
||||
if (
|
||||
to.path !== from.path &&
|
||||
// Only reload if the ad has been loaded
|
||||
// otherwise it's possible that the script is appended but
|
||||
// the ads are not loaded yet. This would result in duplicated ads.
|
||||
[...this.$el.classList].includes("loaded")
|
||||
) {
|
||||
this.$el.innerHTML = "";
|
||||
this.$el.classList.remove("loaded");
|
||||
this.load();
|
||||
}
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
load() {
|
||||
const s = document.createElement("script");
|
||||
s.id = "_ads_js";
|
||||
s.src = `https://media.ethicalads.io/media/client/ethicalads.min.js`;
|
||||
s.async = "async";
|
||||
this.$el.appendChild(s);
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
#ads {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
width: 100%;
|
||||
min-height: 264px;
|
||||
}
|
||||
</style>
|
||||
@@ -1,27 +1,22 @@
|
||||
<template>
|
||||
<ParentLayout>
|
||||
<CodeFund slot="sidebar-top"/>
|
||||
</ParentLayout>
|
||||
<ParentLayout></ParentLayout>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ParentLayout from '@parent-theme/layouts/Layout.vue'
|
||||
import CodeFund from '../components/CodeFund.vue'
|
||||
import ParentLayout from "@parent-theme/layouts/Layout.vue";
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ParentLayout,
|
||||
CodeFund
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#codefund {
|
||||
border-bottom: 1px solid #eaecef;
|
||||
min-height: 115px;
|
||||
}
|
||||
#codefund + .sidebar-links {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
#ads {
|
||||
border-bottom: 1px solid #eaecef;
|
||||
}
|
||||
#ads + .sidebar-links {
|
||||
padding-top: 1rem;
|
||||
}
|
||||
</style>
|
||||
|
||||
+24
-18
@@ -1,38 +1,44 @@
|
||||
<SponsorBanner />
|
||||
|
||||
# Vue Select
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
> Everything you wish the HTML `<select>` element could do, wrapped
|
||||
up into a lightweight, extensible Vue component.
|
||||
> Everything you wish the HTML `<select>` element could do, wrapped
|
||||
> up into a lightweight, extensible Vue component.
|
||||
|
||||
Vue Select is a feature rich select/dropdown/typeahead component. It provides a default
|
||||
template that fits the 80% use case for a select dropdown. Here it is by default:
|
||||
template that fits most use cases for a filterable select dropdown. The component is designed to be as
|
||||
lightweight as possible, while maintaining high standards for accessibility,
|
||||
developer experience, and customization.
|
||||
|
||||
<div style="max-width:25rem; margin: 0 auto; padding: 1rem 0;">
|
||||
<country-select />
|
||||
</div>
|
||||
|
||||
If you want to get a quick sense of what vue-select can do, check out
|
||||
[the sandbox](sandbox.md).
|
||||
Vue Select aims to be as lightweight as possible, while maintaining high standards for accessibility,
|
||||
developer experience, and customization. Huge thanks to the [sponsors](sponsors.md) and
|
||||
[contributors](contributors.md) that make Vue Select possible!
|
||||
|
||||
## Features
|
||||
|
||||
#### Features
|
||||
- Tagging
|
||||
- Filtering/Searching
|
||||
- Filtering / Searching
|
||||
- Vuex Support
|
||||
- AJAX Support
|
||||
- SSR Support
|
||||
- Select Single/Multiple Options
|
||||
- Tested with Bootstrap 3/4, Bulma, Foundation
|
||||
- +95% Test Coverage
|
||||
- Accessible
|
||||
- ~20kb Total / ~5kb CSS / ~15kb JS
|
||||
- Select Single/Multiple Options
|
||||
- Customizable with slots and SCSS variables
|
||||
- Zero dependencies
|
||||
|
||||
#### Resources
|
||||
- **[CodePen Template](http://codepen.io/sagalbot/pen/NpwrQO)**
|
||||
## Resources
|
||||
|
||||
- **[GitHub](https://github.com/sagalbot/vue-select)**
|
||||
- **[Projects](https://github.com/sagalbot/vue-select/projects)**
|
||||
- **[CodePen Template](http://codepen.io/sagalbot/pen/NpwrQO)**
|
||||
|
||||
+97
-2
@@ -4,22 +4,99 @@ Triggered when the selected value changes. Used internally for `v-model`.
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param val {Object|String}` - selected option.
|
||||
* @param {Object|String} val - selected option.
|
||||
*/
|
||||
this.$emit("input", val);
|
||||
```
|
||||
|
||||
## `open`
|
||||
|
||||
Triggered when the dropdown is open.
|
||||
|
||||
```js
|
||||
this.$emit("open");
|
||||
```
|
||||
|
||||
## `close`
|
||||
|
||||
Triggered when the dropdown is closed.
|
||||
|
||||
```js
|
||||
this.$emit("close");
|
||||
```
|
||||
|
||||
## `option:selecting` <Badge text="v3.11.0+" />
|
||||
|
||||
Triggered after an option has been selected, <strong>before</strong> updating internal state.
|
||||
|
||||
```js
|
||||
this.$emit("option:selecting", selectedOption);
|
||||
```
|
||||
|
||||
## `option:selected` <Badge text="v3.11.0+" />
|
||||
|
||||
Triggered when an option has been selected, <strong>after</strong> updating internal state.
|
||||
|
||||
```js
|
||||
this.$emit("option:selected", selectedOption);
|
||||
```
|
||||
|
||||
## `option:deselecting` <Badge text="v3.11.0+" />
|
||||
|
||||
Triggered when an option has been deselected, <strong>before</strong> updating internal state.
|
||||
|
||||
```js
|
||||
this.$emit("option:deselecting", selectedOption);
|
||||
```
|
||||
|
||||
## `option:deselected` <Badge text="v3.11.0+" />
|
||||
|
||||
Triggered when an option has been deselected, <strong>after</strong> updating internal state.
|
||||
|
||||
```js
|
||||
this.$emit("option:deselected", deselectedOption);
|
||||
```
|
||||
|
||||
## `option:created`
|
||||
|
||||
Triggered when `taggable` is `true` and a new option has been created.
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param newOption {Object} - created option
|
||||
* @param {Object} newOption - created option
|
||||
*/
|
||||
this.$emit("option:created", newOption);
|
||||
```
|
||||
|
||||
## `search`
|
||||
|
||||
Anytime the search string changes, emit the
|
||||
'search' event. The event is passed with two
|
||||
parameters: the search string, and a function
|
||||
that accepts a boolean parameter to toggle the
|
||||
loading state.
|
||||
|
||||
See the [AJAX Guide](/guide/ajax.html#loading-options-with-ajax)
|
||||
for a complete example.
|
||||
|
||||
```js
|
||||
/**
|
||||
* @param {String} searchString - the search string
|
||||
* @param {Function} toggleLoading - function to toggle loading state, accepts true or false boolean
|
||||
*/
|
||||
this.$emit('search', this.search, this.toggleLoading);
|
||||
```
|
||||
|
||||
```vue
|
||||
<!-- example usage -->
|
||||
<v-select
|
||||
@search="(search, loading) => {
|
||||
loading(true)
|
||||
fetchOptions(search).then(() => loading(false))
|
||||
}"
|
||||
/>
|
||||
```
|
||||
|
||||
## `search:blur`
|
||||
|
||||
Triggered when the text input loses focus. The dropdown will close immediately before this
|
||||
@@ -37,3 +114,21 @@ event is triggered.
|
||||
```js
|
||||
this.$emit("search:focus");
|
||||
```
|
||||
|
||||
## `search`
|
||||
|
||||
Triggered when the search text changes.
|
||||
|
||||
```js
|
||||
/**
|
||||
* Anytime the search string changes, emit the
|
||||
* 'search' event. The event is passed with two
|
||||
* parameters: the search string, and a function
|
||||
* that accepts a boolean parameter to toggle the
|
||||
* loading state.
|
||||
*
|
||||
* @emits search
|
||||
*/
|
||||
this.$emit('search', newSearchString, toggleLoading);
|
||||
```
|
||||
|
||||
|
||||
+356
-238
@@ -13,121 +13,42 @@ appendToBody: {
|
||||
},
|
||||
```
|
||||
|
||||
## value
|
||||
|
||||
Contains the currently selected value. Very similar to a
|
||||
`value` attribute on an `<input>`. You can listen for changes
|
||||
using 'change' event using v-on.
|
||||
## autocomplete
|
||||
|
||||
The value provided here will be bound to the [autocomplete
|
||||
HTML attribute](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete)
|
||||
on the search input. Defaults to `off`.
|
||||
|
||||
```js
|
||||
value: {
|
||||
default: null
|
||||
autocomplete: {
|
||||
type: String,
|
||||
default: 'off'
|
||||
},
|
||||
```
|
||||
|
||||
## options
|
||||
|
||||
An array of strings or objects to be used as dropdown choices.
|
||||
If you are using an array of objects, vue-select will look for
|
||||
a `label` key (ex. `[{label: 'Canada', value: 'CA'}]`). A
|
||||
custom label key can be set with the `label` prop.
|
||||
## autoscroll <Badge text="v3.10.0+" />
|
||||
|
||||
When true, the dropdown will automatically scroll to ensure
|
||||
that the option highlighted is fully within the dropdown viewport
|
||||
when navigating with keyboard arrows.
|
||||
|
||||
```js
|
||||
options: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
autoscroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
```
|
||||
|
||||
## disabled
|
||||
|
||||
Disable the entire component.
|
||||
|
||||
```js
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
```
|
||||
|
||||
## clearable
|
||||
|
||||
Can the user clear the selected property?
|
||||
|
||||
```js
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
```
|
||||
|
||||
## maxHeight
|
||||
|
||||
::: warning Deprecated in `v2.x` & Removed in `v3.0`
|
||||
This prop was removed in `v3.0`. You can use the `$vs-dropdown-max-height`
|
||||
SCSS variable to adjust this setting in `v3.x`.
|
||||
:::
|
||||
|
||||
Sets the max-height property on the dropdown list.
|
||||
|
||||
```js
|
||||
maxHeight: {
|
||||
type: String,
|
||||
default: "400px"
|
||||
},
|
||||
```
|
||||
|
||||
## searchable
|
||||
|
||||
Enable/disable filtering the options.
|
||||
|
||||
```js
|
||||
searchable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
```
|
||||
|
||||
## multiple
|
||||
|
||||
Equivalent to the `multiple` attribute on a `<select>` input.
|
||||
|
||||
```js
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
```
|
||||
|
||||
## placeholder
|
||||
|
||||
Equivalent to the `placeholder` attribute on an `<input>`.
|
||||
|
||||
```js
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
```
|
||||
|
||||
## transition
|
||||
|
||||
Sets a Vue transition property on the `.dropdown-menu`. vue-select
|
||||
does not include CSS for transitions, you'll need to add them yourself.
|
||||
|
||||
```js
|
||||
transition: {
|
||||
type: String,
|
||||
default: "fade"
|
||||
},
|
||||
```
|
||||
|
||||
## calculatePosition <Badge text="v3.7.0+" />
|
||||
|
||||
When `appendToBody` is true, this function is responsible for positioning the drop down list.
|
||||
|
||||
If a function is returned from `calculatePosition`, it will be called when the drop down list
|
||||
is removed from the DOM. This allows for any garbage collection you may need to do.
|
||||
|
||||
See [Dropdown Position](../guide/positioning.md) for more details.
|
||||
|
||||
```js
|
||||
@@ -139,6 +60,7 @@ calculatePosition: {
|
||||
* @param width {string} calculated width in pixels of the dropdown menu
|
||||
* @param top {string} absolute position top value in pixels relative to the document
|
||||
* @param left {string} absolute position left value in pixels relative to the document
|
||||
* @return {function|void}
|
||||
*/
|
||||
default(dropdownList, component, {width, top, left}) {
|
||||
dropdownList.style.top = top;
|
||||
@@ -148,17 +70,19 @@ calculatePosition: {
|
||||
}
|
||||
```
|
||||
|
||||
## clearSearchOnSelect
|
||||
|
||||
Enables/disables clearing the search text when an option is selected.
|
||||
## clearable
|
||||
|
||||
Can the user clear the selected property?
|
||||
|
||||
```js
|
||||
clearSearchOnSelect: {
|
||||
clearable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## clearSearchOnBlur
|
||||
|
||||
Enables/disables clearing the search text when the search input is blurred.
|
||||
@@ -172,6 +96,19 @@ clearSearchOnBlur: {
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## clearSearchOnSelect
|
||||
|
||||
Enables/disables clearing the search text when an option is selected.
|
||||
|
||||
```js
|
||||
clearSearchOnSelect: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## closeOnSelect
|
||||
|
||||
Close a dropdown when an option is chosen. Set to false to keep the dropdown
|
||||
@@ -184,62 +121,141 @@ closeOnSelect: {
|
||||
},
|
||||
```
|
||||
|
||||
## label
|
||||
## components <Badge text="v3.1.0+" />
|
||||
|
||||
Tells vue-select what key to use when generating option
|
||||
labels when each `option` is an object.
|
||||
API to overwrite default vue-select components with your own. This can be used to change the clear button or select chevron with your own markup.
|
||||
|
||||
The object provided to the components prop will be merged with Vue Select's default components.
|
||||
|
||||
See [Components guide](../guide/components.md) for more details.
|
||||
|
||||
```js
|
||||
label: {
|
||||
type: String,
|
||||
default: "label"
|
||||
},
|
||||
```
|
||||
import Deselect from './Deselect';
|
||||
import OpenIndicator from './OpenIndicator';
|
||||
|
||||
## reduce
|
||||
// ...
|
||||
|
||||
When working with objects, the reduce
|
||||
prop allows you to transform a given
|
||||
object to only the information you
|
||||
want passed to a v-model binding
|
||||
or @input event.
|
||||
|
||||
```js
|
||||
reduce: {
|
||||
type: Function,
|
||||
default: option => option,
|
||||
},
|
||||
```
|
||||
|
||||
## getOptionLabel
|
||||
|
||||
Callback to generate the label text. If `{option}`
|
||||
is an object, returns `option[this.label]` by default.
|
||||
|
||||
Label text is used for filtering comparison and
|
||||
displaying. If you only need to adjust the
|
||||
display, you should use the `option` and
|
||||
`selected-option` slots.
|
||||
|
||||
```js
|
||||
getOptionLabel: {
|
||||
type: Function,
|
||||
default(option) {
|
||||
if (typeof option === 'object') {
|
||||
if (!option.hasOwnProperty(this.label)) {
|
||||
return console.warn(
|
||||
`[vue-select warn]: Label key "option.${this.label}" does not` +
|
||||
` exist in options object ${JSON.stringify(option)}.\n` +
|
||||
'https://vue-select.org/api/props.html#getoptionlabel'
|
||||
)
|
||||
}
|
||||
return option[this.label]
|
||||
}
|
||||
return option;
|
||||
components: {
|
||||
type: Object,
|
||||
default: function () {
|
||||
Deselect,
|
||||
OpenIndicator
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## createOption
|
||||
|
||||
User defined function for adding Options
|
||||
|
||||
```js
|
||||
createOption: {
|
||||
type: Function,
|
||||
default(newOption) {
|
||||
if (typeof this.optionList[0] === 'object') {
|
||||
newOption = {[this.label]: newOption}
|
||||
}
|
||||
|
||||
this.$emit('option:created', newOption)
|
||||
return newOption
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## dir
|
||||
|
||||
Sets RTL support. Accepts `ltr`, `rtl`, `auto`.
|
||||
|
||||
```js
|
||||
dir: {
|
||||
type: String,
|
||||
default: "auto"
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## disabled
|
||||
|
||||
Disable the entire component.
|
||||
|
||||
```js
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
```
|
||||
|
||||
## dropdownShouldOpen <Badge text="v3.12.0+" />
|
||||
|
||||
Determines whether the dropdown should open. Used
|
||||
for overriding the default dropdown behaviour. Receives
|
||||
the vue-select instance as the single argument to the function.
|
||||
|
||||
```js
|
||||
dropdownShouldOpen: {
|
||||
type: Function,
|
||||
default({noDrop, open, mutableLoading}) {
|
||||
return noDrop ? false : open && !mutableLoading;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## filter
|
||||
|
||||
Callback to filter results when search text
|
||||
is provided. Default implementation loops
|
||||
each option, and returns the result of
|
||||
this.filterBy.
|
||||
|
||||
```js
|
||||
filter: {
|
||||
type: Function,
|
||||
default(options, search) {
|
||||
return options.filter(option => {
|
||||
let label = this.getOptionLabel(option);
|
||||
if (typeof label === "number") {
|
||||
label = label.toString();
|
||||
}
|
||||
return this.filterBy(option, label, search);
|
||||
});
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## filterable
|
||||
|
||||
When true, existing options will be filtered
|
||||
by the search text. Should not be used in conjunction
|
||||
with taggable.
|
||||
|
||||
```js
|
||||
filterable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## filterBy
|
||||
|
||||
Callback to determine if the provided option should
|
||||
match the current search text. Used to determine
|
||||
if the option should be displayed.
|
||||
|
||||
```js
|
||||
filterBy: {
|
||||
type: Function,
|
||||
default(option, label, search) {
|
||||
return (label || '').toLowerCase().indexOf(search.toLowerCase()) > -1
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## getOptionKey
|
||||
|
||||
Callback to get an option key. If `option`
|
||||
@@ -272,6 +288,102 @@ getOptionKey: {
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## getOptionLabel
|
||||
|
||||
Callback to generate the label text. If `{option}`
|
||||
is an object, returns `option[this.label]` by default.
|
||||
|
||||
Label text is used for filtering comparison and
|
||||
displaying. If you only need to adjust the
|
||||
display, you should use the `option` and
|
||||
`selected-option` slots.
|
||||
|
||||
```js
|
||||
getOptionLabel: {
|
||||
type: Function,
|
||||
default(option) {
|
||||
if (typeof option === 'object') {
|
||||
if (!option.hasOwnProperty(this.label)) {
|
||||
return console.warn(
|
||||
`[vue-select warn]: Label key "option.${this.label}" does not` +
|
||||
` exist in options object ${JSON.stringify(option)}.\n` +
|
||||
'https://vue-select.org/api/props.html#getoptionlabel'
|
||||
)
|
||||
}
|
||||
return option[this.label]
|
||||
}
|
||||
return option;
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## inputId
|
||||
|
||||
Sets the id of the input element.
|
||||
|
||||
```js
|
||||
inputId: {
|
||||
type: String
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## label
|
||||
|
||||
Tells vue-select what key to use when generating option
|
||||
labels when each `option` is an object.
|
||||
|
||||
```js
|
||||
label: {
|
||||
type: String,
|
||||
default: "label"
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## maxHeight
|
||||
|
||||
::: warning Deprecated in `v2.x` & Removed in `v3.0`
|
||||
This prop was removed in `v3.0`. You can use the `$vs-dropdown-max-height`
|
||||
SCSS variable to adjust this setting in `v3.x`.
|
||||
:::
|
||||
|
||||
Sets the max-height property on the dropdown list.
|
||||
|
||||
```js
|
||||
maxHeight: {
|
||||
type: String,
|
||||
default: "400px"
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## multiple
|
||||
|
||||
Equivalent to the `multiple` attribute on a `<select>` input.
|
||||
|
||||
```js
|
||||
multiple: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## noDrop
|
||||
|
||||
Disable the dropdown entirely.
|
||||
|
||||
```js
|
||||
noDrop: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## onTab
|
||||
|
||||
Select the current value if `selectOnTab` is enabled
|
||||
@@ -287,28 +399,36 @@ onTab: {
|
||||
},
|
||||
```
|
||||
|
||||
## taggable
|
||||
|
||||
Enable/disable creating options from searchInput.
|
||||
## options
|
||||
|
||||
An array of strings or objects to be used as dropdown choices.
|
||||
If you are using an array of objects, vue-select will look for
|
||||
a `label` key (ex. `[{label: 'Canada', value: 'CA'}]`). A
|
||||
custom label key can be set with the `label` prop.
|
||||
|
||||
```js
|
||||
taggable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
options: {
|
||||
type: Array,
|
||||
default() {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
## tabindex
|
||||
|
||||
Set the tabindex for the input field.
|
||||
## placeholder
|
||||
|
||||
Equivalent to the `placeholder` attribute on an `<input>`.
|
||||
|
||||
```js
|
||||
tabindex: {
|
||||
type: Number,
|
||||
default: null
|
||||
placeholder: {
|
||||
type: String,
|
||||
default: ""
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## pushTags
|
||||
|
||||
When true, newly created tags will be added to
|
||||
@@ -321,74 +441,23 @@ pushTags: {
|
||||
},
|
||||
```
|
||||
|
||||
## filterable
|
||||
|
||||
When true, existing options will be filtered
|
||||
by the search text. Should not be used in conjunction
|
||||
with taggable.
|
||||
## reduce
|
||||
|
||||
When working with objects, the reduce
|
||||
prop allows you to transform a given
|
||||
object to only the information you
|
||||
want passed to a v-model binding
|
||||
or @input event.
|
||||
|
||||
```js
|
||||
filterable: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
},
|
||||
```
|
||||
|
||||
## filterBy
|
||||
|
||||
Callback to determine if the provided option should
|
||||
match the current search text. Used to determine
|
||||
if the option should be displayed.
|
||||
|
||||
```js
|
||||
filterBy: {
|
||||
type: Function,
|
||||
default(option, label, search) {
|
||||
return (label | "").toLowerCase().indexOf(search.toLowerCase()) > -1;
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
## filter
|
||||
|
||||
Callback to filter results when search text
|
||||
is provided. Default implementation loops
|
||||
each option, and returns the result of
|
||||
this.filterBy.
|
||||
|
||||
```js
|
||||
filter: {
|
||||
type: Function,
|
||||
default(options, search) {
|
||||
return options.filter(option => {
|
||||
let label = this.getOptionLabel(option);
|
||||
if (typeof label === "number") {
|
||||
label = label.toString();
|
||||
}
|
||||
return this.filterBy(option, label, search);
|
||||
});
|
||||
}
|
||||
},
|
||||
```
|
||||
|
||||
## createOption
|
||||
|
||||
User defined function for adding Options
|
||||
|
||||
```js
|
||||
createOption: {
|
||||
reduce: {
|
||||
type: Function,
|
||||
default(newOption) {
|
||||
if (typeof this.optionList[0] === 'object') {
|
||||
newOption = {[this.label]: newOption}
|
||||
}
|
||||
|
||||
this.$emit('option:created', newOption)
|
||||
return newOption
|
||||
}
|
||||
default: option => option,
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## resetOnOptionsChange
|
||||
|
||||
When false, updating the options will not reset the selected value.
|
||||
@@ -410,37 +479,36 @@ resetOnOptionsChange: {
|
||||
},
|
||||
```
|
||||
|
||||
## noDrop
|
||||
|
||||
Disable the dropdown entirely.
|
||||
## searchable
|
||||
|
||||
Enable/disable filtering the options.
|
||||
|
||||
```js
|
||||
noDrop: {
|
||||
searchable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
default: true
|
||||
},
|
||||
```
|
||||
|
||||
## inputId
|
||||
|
||||
Sets the id of the input element.
|
||||
## selectable <Badge text="v3.3.0+" />
|
||||
|
||||
The `selectable` prop determines if an option is selectable or not. If `selectable` returns false
|
||||
for a given option, it will be displayed with a `vs__dropdown-option--disabled` class. The option
|
||||
will be disabled and unable to be selected.
|
||||
|
||||
```js
|
||||
inputId: {
|
||||
type: String
|
||||
selectable: {
|
||||
type: Function,
|
||||
/**
|
||||
* @param {Object|String} option
|
||||
* @return {boolean}
|
||||
*/
|
||||
default: option => true,
|
||||
},
|
||||
```
|
||||
|
||||
## dir
|
||||
|
||||
Sets RTL support. Accepts `ltr`, `rtl`, `auto`.
|
||||
|
||||
```js
|
||||
dir: {
|
||||
type: String,
|
||||
default: "auto"
|
||||
},
|
||||
```
|
||||
|
||||
## selectOnTab
|
||||
|
||||
@@ -452,3 +520,53 @@ selectOnTab: {
|
||||
default: false
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
## tabindex
|
||||
|
||||
Set the tabindex for the input field.
|
||||
|
||||
```js
|
||||
tabindex: {
|
||||
type: Number,
|
||||
default: null
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## taggable
|
||||
|
||||
Enable/disable creating options from searchInput.
|
||||
|
||||
```js
|
||||
taggable: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## transition
|
||||
|
||||
Sets a Vue transition property on the `.dropdown-menu`. vue-select
|
||||
does not include CSS for transitions, you'll need to add them yourself.
|
||||
|
||||
```js
|
||||
transition: {
|
||||
type: String,
|
||||
default: "fade"
|
||||
},
|
||||
```
|
||||
|
||||
|
||||
## value
|
||||
|
||||
Contains the currently selected value. Very similar to a
|
||||
`value` attribute on an `<input>`. You can listen for changes
|
||||
using 'change' event using v-on.
|
||||
|
||||
```js
|
||||
value: {
|
||||
default: null
|
||||
},
|
||||
```
|
||||
|
||||
+151
-81
@@ -3,116 +3,186 @@ Vue Select leverages scoped slots to allow for total customization of the presen
|
||||
Slots can be used to change the look and feel of the UI, or to simply swap out text.
|
||||
:::
|
||||
|
||||
## Selected Option(s)
|
||||
<style>
|
||||
.slot-docs h2 {
|
||||
border-top: 1px solid #f0f0f0;
|
||||
border-bottom: none;
|
||||
margin-top: 2rem;
|
||||
padding-top: 2rem;
|
||||
}
|
||||
.slot-docs h2:first-child {
|
||||
border-top: none;
|
||||
margin-top: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
### `selected-option`
|
||||
<div class="slot-docs">
|
||||
|
||||
#### Scope:
|
||||
## `footer` <Badge text="3.8.0+" />
|
||||
|
||||
- `option {Object}` - A selected option
|
||||
Displayed at the bottom of the component, below `.vs__dropdown-toggle`.
|
||||
|
||||
```html
|
||||
<slot
|
||||
name="selected-option"
|
||||
v-bind="(typeof option === 'object')?option:{[label]: option}"
|
||||
>
|
||||
{{ getOptionLabel(option) }}
|
||||
</slot>
|
||||
```
|
||||
When implementing this slot, you'll likely need to use `appendToBody` to position the dropdown.
|
||||
Otherwise content in this slot will affect it's positioning.
|
||||
|
||||
### `selected-option-container`
|
||||
- `search {string}` - the current search query
|
||||
- `loading {boolean}` - is the component loading
|
||||
- `searching {boolean}` - is the component searching
|
||||
- `filteredOptions {array}` - options filtered by the search text
|
||||
- `deselect {function}` - function to deselect an option
|
||||
|
||||
#### Scope:
|
||||
<SlotFooter />
|
||||
<<< @/.vuepress/components/SlotFooter.vue
|
||||
|
||||
- `option {Object}` - A selected option
|
||||
- `deselect {Function}` - Method used to deselect a given option when `multiple` is true
|
||||
- `disabled {Boolean}` - Determine if the component is disabled
|
||||
- `multiple {Boolean}` - If the component supports the selection of multiple values
|
||||
## `header` <Badge text="3.8.0+" />
|
||||
|
||||
```html
|
||||
<slot
|
||||
v-for="option in valueAsArray"
|
||||
name="selected-option-container"
|
||||
:option="(typeof option === 'object')?option:{[label]: option}"
|
||||
:deselect="deselect"
|
||||
:multiple="multiple"
|
||||
:disabled="disabled"
|
||||
>
|
||||
<span class="selected-tag" v-bind:key="option.index">
|
||||
<slot
|
||||
name="selected-option"
|
||||
v-bind="(typeof option === 'object')?option:{[label]: option}"
|
||||
>
|
||||
{{ getOptionLabel(option) }}
|
||||
</slot>
|
||||
<button
|
||||
v-if="multiple"
|
||||
:disabled="disabled"
|
||||
@click="deselect(option)"
|
||||
type="button"
|
||||
class="close"
|
||||
aria-label="Remove option"
|
||||
>
|
||||
<span aria-hidden="true">×</span>
|
||||
</button>
|
||||
</span>
|
||||
</slot>
|
||||
```
|
||||
Displayed at the top of the component, above `.vs__dropdown-toggle`.
|
||||
|
||||
## Component Actions
|
||||
- `search {string}` - the current search query
|
||||
- `loading {boolean}` - is the component loading
|
||||
- `searching {boolean}` - is the component searching
|
||||
- `filteredOptions {array}` - options filtered by the search text
|
||||
- `deselect {function}` - function to deselect an option
|
||||
|
||||
### `spinner`
|
||||
<SlotHeader />
|
||||
<<< @/.vuepress/components/SlotHeader.vue
|
||||
|
||||
#### Scope:
|
||||
## `list-footer` <Badge text="3.8.0+" />
|
||||
|
||||
- `loading {Boolean}` - if the component is in a loading state
|
||||
Displayed as the last item in the dropdown. No content by default. Parent element is the `<ul>`,
|
||||
so this slot should contain a root `<li>`.
|
||||
|
||||
```html
|
||||
<slot name="spinner" v-bind="scope.spinner">
|
||||
<div class="vs__spinner" v-show="mutableLoading">Loading...</div>
|
||||
</slot>
|
||||
```
|
||||
- `search {string}` - the current search query
|
||||
- `loading {boolean}` - is the component loading
|
||||
- `searching {boolean}` - is the component searching
|
||||
- `filteredOptions {array}` - options filtered by the search text
|
||||
|
||||
### `open-indicator`
|
||||
<SlotListFooter />
|
||||
<<< @/.vuepress/components/SlotListFooter.vue
|
||||
|
||||
## `list-header` <Badge text="3.8.0+" />
|
||||
|
||||
Displayed as the first item in the dropdown. No content by default. Parent element is the `<ul>`,
|
||||
so this slot should contain a root `<li>`.
|
||||
|
||||
- `search {string}` - the current search query
|
||||
- `loading {boolean}` - is the component loading
|
||||
- `searching {boolean}` - is the component searching
|
||||
- `filteredOptions {array}` - options filtered by the search text
|
||||
|
||||
<SlotListHeader />
|
||||
<<< @/.vuepress/components/SlotListHeader.vue
|
||||
|
||||
## `no-options`
|
||||
|
||||
The no options slot is displayed above `list-footer` in the dropdown when
|
||||
`filteredOptions.length === 0`.
|
||||
|
||||
- `search {string}` - the current search query
|
||||
- `loading {boolean}` - is the component loading
|
||||
- `searching {boolean}` - is the component searching
|
||||
|
||||
<SlotNoOptions />
|
||||
<<< @/.vuepress/components/SlotNoOptions.vue
|
||||
|
||||
## `open-indicator`
|
||||
|
||||
The open indicator is the caret icon on the component used to indicate dropdown status.
|
||||
|
||||
```js
|
||||
attributes : {
|
||||
attributes: {
|
||||
'ref': 'openIndicator',
|
||||
'role': 'presentation',
|
||||
'class': 'vs__open-indicator',
|
||||
}
|
||||
```
|
||||
|
||||
```vue
|
||||
<slot name="open-indicator" v-bind="scope.openIndicator">
|
||||
<component :is="childComponents.OpenIndicator" v-if="!noDrop" v-bind="scope.openIndicator.attributes"/>
|
||||
</slot>
|
||||
```
|
||||
<SlotOpenIndicator />
|
||||
<<< @/.vuepress/components/SlotOpenIndicator.vue
|
||||
|
||||
## Dropdown
|
||||
## `option`
|
||||
|
||||
### `option`
|
||||
The current option within the dropdown, contained within `<li>`.
|
||||
|
||||
- `option {Object}` - The currently iterated option from `filteredOptions`
|
||||
|
||||
```html
|
||||
<slot
|
||||
name="option"
|
||||
v-bind="(typeof option === 'object')?option:{[label]: option}"
|
||||
>
|
||||
{{ getOptionLabel(option) }}
|
||||
</slot>
|
||||
<SlotOption />
|
||||
<<< @/.vuepress/components/SlotOption.vue
|
||||
|
||||
## `search`
|
||||
|
||||
The search input has a lot of bindings, but they're grouped into `attributes` and `events`. Most
|
||||
of the time, you will just be binding those two with `v-on="events"` and `v-bind="attributes"`.
|
||||
|
||||
If you want the default styling, you'll need to add `.vs__search` to the input you provide.
|
||||
|
||||
```js
|
||||
/**
|
||||
* Attributes to be bound to a search input.
|
||||
*/
|
||||
attributes: {
|
||||
'disabled': this.disabled,
|
||||
'placeholder': this.searchPlaceholder,
|
||||
'tabindex': this.tabindex,
|
||||
'readonly': !this.searchable,
|
||||
'id': this.inputId,
|
||||
'aria-autocomplete': 'list',
|
||||
'aria-labelledby': `vs${this.uid}__combobox`,
|
||||
'aria-controls': `vs${this.uid}__listbox`,
|
||||
'aria-activedescendant': this.typeAheadPointer > -1
|
||||
? `vs${this.uid}__option-${this.typeAheadPointer}`
|
||||
: '',
|
||||
'ref': 'search',
|
||||
'type': 'search',
|
||||
'autocomplete': this.autocomplete,
|
||||
'value': this.search,
|
||||
},
|
||||
/**
|
||||
* Events that this element should handle.
|
||||
*/
|
||||
events: {
|
||||
'compositionstart': () => this.isComposing = true,
|
||||
'compositionend': () => this.isComposing = false,
|
||||
'keydown': this.onSearchKeyDown,
|
||||
'blur': this.onSearchBlur,
|
||||
'focus': this.onSearchFocus,
|
||||
'input': (e) => this.search = e.target.value,
|
||||
}
|
||||
```
|
||||
|
||||
### `no-options`
|
||||
<SlotSearch />
|
||||
<<< @/.vuepress/components/SlotSearch.vue{5-6}
|
||||
|
||||
The no options slot is displayed in the dropdown when `filteredOptions.length === 0`.
|
||||
## `selected-option`
|
||||
|
||||
- `search {String}` - the current search text
|
||||
- `searching {Boolean}` - if the component has search text
|
||||
The text displayed within `selected-option-container`.
|
||||
|
||||
```vue
|
||||
<slot name="no-options" v-bind="scope.noOptions">
|
||||
Sorry, no matching options.
|
||||
</slot>
|
||||
```
|
||||
This slot doesn't exist if `selected-option-container` is implemented.
|
||||
|
||||
- `option {Object}` - A selected option
|
||||
|
||||
<SlotSelectedOption />
|
||||
<<< @/.vuepress/components/SlotSelectedOption.vue
|
||||
|
||||
## `selected-option-container`
|
||||
|
||||
This is the root element where `v-for="option in selectedValue"`. Most of the time you'll want to
|
||||
use `selected-option`, but this container is useful if you want to disable the deselect button,
|
||||
or have fine grain control over the markup.
|
||||
|
||||
- `option {Object}` - Currently iterated selected option
|
||||
- `deselect {Function}` - Method used to deselect a given option when `multiple` is true
|
||||
- `disabled {Boolean}` - Determine if the component is disabled
|
||||
- `multiple {Boolean}` - If the component supports the selection of multiple values
|
||||
|
||||
<SlotSelectedOptionContainer />
|
||||
<<< @/.vuepress/components/SlotSelectedOptionContainer.vue
|
||||
|
||||
## `spinner`
|
||||
|
||||
- `loading {Boolean}` - if the component is in a loading state
|
||||
|
||||
<SlotSpinner />
|
||||
<<< @/.vuepress/components/SlotSpinner.vue
|
||||
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
sidebarDepth: 0
|
||||
---
|
||||
|
||||
# Contributors
|
||||
|
||||
Vue Select is supported by a community of awesome contributors! Without their contributions,
|
||||
the package would not be what it is today.
|
||||
|
||||
<Contributors />
|
||||
@@ -58,7 +58,7 @@ export default {
|
||||
|
||||
## Setting Globally at Registration
|
||||
|
||||
If you want to all instances of Vue Select to use your custom components throughout your app, while
|
||||
If you want all instances of Vue Select to use your custom components throughout your app, while
|
||||
only having to set the implementation once, you can do so when registering Vue Select as a component.
|
||||
|
||||
```js
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
Vue Select provides two props accepting `functions` that can be used to implement custom filtering
|
||||
algorithms.
|
||||
|
||||
- `filter` <Badge text="v2.5.0+" />
|
||||
- `filterBy` <Badge text="v2.5.0+" />
|
||||
|
||||
By default, the component will perform a very basic check to see if an options label includes
|
||||
the current search text. If you're using scoped slots, you might have information within the
|
||||
option templates that should be searchable. Or maybe you just want a better search algorithm that
|
||||
can do fuzzy search matching.
|
||||
|
||||
## Filtering with Fuse.js
|
||||
|
||||
You can use the `filter` and `filterBy` props to hook right into something like
|
||||
[Fuse.js](https://fusejs.io/) that can handle searching multiple object keys with fuzzy matchings.
|
||||
|
||||
<FuseFilter />
|
||||
|
||||
<<< @/.vuepress/components/FuseFilter.vue
|
||||
@@ -0,0 +1,23 @@
|
||||
Vue Select doesn't ship with first party support for infinite scroll, but it's possible to implement
|
||||
by hooking into the `open`, `close`, and `search` events, along with the `filterable` prop, and the
|
||||
`list-footer` slot.
|
||||
|
||||
Let's break down the example below, starting with the `data`.
|
||||
|
||||
- `observer` - a new `IntersectionObserver` with `infiniteScroll` set as the callback
|
||||
- `limit` - the number of options to display
|
||||
- `search` - since we've disabled Vue Selects filtering, we'll need to filter options ourselves
|
||||
|
||||
When Vue Select opens, the `open` event is emitted and `onOpen` will be called. We wait for
|
||||
`$nextTick()` so that the `$ref` we need will exist, then begin observing it for intersection.
|
||||
|
||||
The observer is set to call `infiniteScroll` when the `<li>` is completely visible within the list.
|
||||
Some fancy destructuring is done here to get the first `ObservedEntry`, and specifically the
|
||||
`isIntersecting` & `target` properties. If the `<li>` is intersecting, we increase the `limit`, and
|
||||
ensure that the scroll position remains where it was before the list size changed. Again, it's
|
||||
important to wait for `$nextTick` here so that the DOM elements have been inserted before setting
|
||||
the scroll position.
|
||||
|
||||
<InfiniteScroll />
|
||||
|
||||
<<< @/.vuepress/components/InfiniteScroll.vue
|
||||
@@ -0,0 +1,18 @@
|
||||
::: tip <Badge text="3.8.0+" />
|
||||
Pagination is supported using slots available with Vue Select 3.8 and above.
|
||||
:::
|
||||
|
||||
Pagination can be a super helpful tool when working with large sets of data. If you have 1,000
|
||||
options, the component is going to render 1,000 DOM nodes. That's a lot of nodes to insert/remove,
|
||||
and chances are your user is only interested in a few of them anyways.
|
||||
|
||||
To implement pagination with Vue Select, you can take advantage of the `list-footer` slot. It
|
||||
appears below all other options in the drop down list.
|
||||
|
||||
To make pagination work properly with filtering, you'll have to handle it yourself in the parent.
|
||||
You can use the `filterable` boolean to turn off Vue Select's filtering, and then hook into the
|
||||
`search` event to use the current search query in the parent component.
|
||||
|
||||
<Paginated />
|
||||
|
||||
<<< @/.vuepress/components/Paginated.vue
|
||||
+17
-12
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@vue-select/docs",
|
||||
"version": "1.0",
|
||||
"version": "1.0.0",
|
||||
"license": "MIT",
|
||||
"scripts": {
|
||||
"serve": "vuepress dev",
|
||||
@@ -8,20 +8,25 @@
|
||||
"build:preview": "cross-env DEPLOY_PREVIEW=true vuepress build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@octokit/graphql": "^4.3.1",
|
||||
"@popperjs/core": "^2.1.0",
|
||||
"@vuepress/plugin-active-header-links": "^1.0.0-alpha.47",
|
||||
"@vuepress/plugin-google-analytics": "^1.0.0-alpha.47",
|
||||
"@vuepress/plugin-nprogress": "^1.0.0-alpha.47",
|
||||
"@vuepress/plugin-pwa": "^1.0.0-alpha.47",
|
||||
"@vuepress/plugin-register-components": "^1.0.0-alpha.47",
|
||||
"@vuepress/plugin-search": "^1.0.0-alpha.47",
|
||||
"cross-env": "^5.2.0",
|
||||
"fuse.js": "^3.4.4",
|
||||
"gh-pages": "^0.11.0",
|
||||
"@vuepress/plugin-active-header-links": "^1.4.0",
|
||||
"@vuepress/plugin-google-analytics": "^1.4.0",
|
||||
"@vuepress/plugin-nprogress": "^1.4.0",
|
||||
"@vuepress/plugin-pwa": "^1.4.0",
|
||||
"@vuepress/plugin-register-components": "^1.4.0",
|
||||
"@vuepress/plugin-search": "^1.4.0",
|
||||
"axios": "^0.19.2",
|
||||
"cross-env": "^7.0.2",
|
||||
"date-fns": "^2.11.0",
|
||||
"dotenv": "^8.2.0",
|
||||
"fuse.js": "^6.4.0",
|
||||
"gh-pages": "^2.2.0",
|
||||
"node-sass": "^4.12.0",
|
||||
"sass-loader": "^7.1.0",
|
||||
"octonode": "^0.9.5",
|
||||
"sass-loader": "^8.0.2",
|
||||
"vue": "^2.6.10",
|
||||
"vuepress": "^1.0.0-alpha.47",
|
||||
"vuepress": "^1.4.0",
|
||||
"vuex": "^3.1.0"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
sidebarDepth: 0
|
||||
---
|
||||
|
||||
<SponsorMe />
|
||||
|
||||
## Sponsors
|
||||
|
||||
<Sponsors />
|
||||
+2397
-1730
File diff suppressed because it is too large
Load Diff
+1
-1
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "vue-select",
|
||||
"version": "3.7.0",
|
||||
"version": "3.12.2",
|
||||
"description": "Everything you wish the HTML <select> element could do, wrapped up into a lightweight, extensible Vue component.",
|
||||
"author": "Jeff Sagal <sagalbot@gmail.com>",
|
||||
"homepage": "https://vue-select.org",
|
||||
|
||||
+6
-3
@@ -6,9 +6,12 @@ module.exports = {
|
||||
"@semantic-release/npm",
|
||||
"@semantic-release/commit-analyzer",
|
||||
"@semantic-release/release-notes-generator",
|
||||
["@semantic-release/github", {
|
||||
"assets": ["dist/**"]
|
||||
}],
|
||||
[
|
||||
"@semantic-release/github",
|
||||
{
|
||||
assets: ["dist/**"]
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/git",
|
||||
{
|
||||
|
||||
+128
-87
@@ -4,7 +4,8 @@
|
||||
|
||||
<template>
|
||||
<div :dir="dir" class="v-select" :class="stateClasses">
|
||||
<div :id="`vs${uid}__combobox`" ref="toggle" @mousedown.prevent="toggleDropdown" class="vs__dropdown-toggle" role="combobox" :aria-expanded="dropdownOpen.toString()" :aria-owns="`vs${uid}__listbox`" aria-label="Search for option">
|
||||
<slot name="header" v-bind="scope.header" />
|
||||
<div :id="`vs${uid}__combobox`" ref="toggle" @mousedown="toggleDropdown($event)" class="vs__dropdown-toggle" role="combobox" :aria-expanded="dropdownOpen.toString()" :aria-owns="`vs${uid}__listbox`" aria-label="Search for option">
|
||||
|
||||
<div class="vs__selected-options" ref="selectedOptions">
|
||||
<slot v-for="option in selectedValue"
|
||||
@@ -51,9 +52,9 @@
|
||||
</slot>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<transition :name="transition">
|
||||
<ul ref="dropdownMenu" v-if="dropdownOpen" :id="`vs${uid}__listbox`" class="vs__dropdown-menu" role="listbox" @mousedown.prevent="onMousedown" @mouseup="onMouseUp" v-append-to-body>
|
||||
<ul ref="dropdownMenu" v-if="dropdownOpen" :id="`vs${uid}__listbox`" :key="`vs${uid}__listbox`" class="vs__dropdown-menu" role="listbox" @mousedown.prevent="onMousedown" @mouseup="onMouseUp" tabindex="-1" v-append-to-body>
|
||||
<slot name="list-header" v-bind="scope.listHeader" />
|
||||
<li
|
||||
role="option"
|
||||
v-for="(option, index) in filteredOptions"
|
||||
@@ -69,12 +70,14 @@
|
||||
{{ getOptionLabel(option) }}
|
||||
</slot>
|
||||
</li>
|
||||
<li v-if="filteredOptions.length === 0" class="vs__no-options" @mousedown.stop="">
|
||||
<li v-if="filteredOptions.length === 0" class="vs__no-options">
|
||||
<slot name="no-options" v-bind="scope.noOptions">Sorry, no matching options.</slot>
|
||||
</li>
|
||||
<slot name="list-footer" v-bind="scope.listFooter" />
|
||||
</ul>
|
||||
<ul v-else :id="`vs${uid}__listbox`" role="listbox" style="display: none; visibility: hidden;"></ul>
|
||||
</transition>
|
||||
<slot name="footer" v-bind="scope.footer" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -84,6 +87,7 @@
|
||||
import ajax from '../mixins/ajax'
|
||||
import childComponents from './childComponents';
|
||||
import appendToBody from '../directives/appendToBody';
|
||||
import sortAndStringify from '../utility/sortAndStringify'
|
||||
import uniqueId from '../utility/uniqueId';
|
||||
|
||||
/**
|
||||
@@ -281,12 +285,16 @@
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback to get an option key. If {option}
|
||||
* is an object and has an {id}, returns {option.id}
|
||||
* by default, otherwise tries to serialize {option}
|
||||
* to JSON.
|
||||
* Generate a unique identifier for each option. If `option`
|
||||
* is an object and `option.hasOwnProperty('id')` exists,
|
||||
* `option.id` is used by default, otherwise the option
|
||||
* will be serialized to JSON.
|
||||
*
|
||||
* The key must be unique for an option.
|
||||
* If you are supplying a lot of options, you should
|
||||
* provide your own keys, as JSON.stringify can be
|
||||
* slow with lots of objects.
|
||||
*
|
||||
* The result of this function *must* be unique.
|
||||
*
|
||||
* @type {Function}
|
||||
* @param {Object || String} option
|
||||
@@ -294,22 +302,21 @@
|
||||
*/
|
||||
getOptionKey: {
|
||||
type: Function,
|
||||
default(option) {
|
||||
if (typeof option === 'object' && option.id) {
|
||||
return option.id
|
||||
} else {
|
||||
try {
|
||||
return JSON.stringify(option)
|
||||
} catch(e) {
|
||||
return console.warn(
|
||||
`[vue-select warn]: Could not stringify option ` +
|
||||
`to generate unique key. Please provide'getOptionKey' prop ` +
|
||||
`to return a unique key for each option.\n` +
|
||||
'https://vue-select.org/api/props.html#getoptionkey'
|
||||
);
|
||||
}
|
||||
default (option) {
|
||||
if (typeof option !== 'object') {
|
||||
return option;
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
return option.hasOwnProperty('id') ? option.id : sortAndStringify(option);
|
||||
} catch (e) {
|
||||
const warning = `[vue-select warn]: Could not stringify this option ` +
|
||||
`to generate unique key. Please provide'getOptionKey' prop ` +
|
||||
`to return a unique key for each option.\n` +
|
||||
'https://vue-select.org/api/props.html#getoptionkey';
|
||||
return console.warn(warning, option, e);
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -393,7 +400,7 @@
|
||||
* @return {Boolean}
|
||||
*/
|
||||
filter: {
|
||||
"type": Function,
|
||||
type: Function,
|
||||
default(options, search) {
|
||||
return options.filter((option) => {
|
||||
let label = this.getOptionLabel(option)
|
||||
@@ -533,9 +540,13 @@
|
||||
},
|
||||
|
||||
/**
|
||||
* When `appendToBody` is true, this function
|
||||
* is responsible for positioning the drop
|
||||
* down list.
|
||||
* When `appendToBody` is true, this function is responsible for
|
||||
* positioning the drop down list.
|
||||
*
|
||||
* If a function is returned from `calculatePosition`, it will
|
||||
* be called when the drop down list is removed from the DOM.
|
||||
* This allows for any garbage collection you may need to do.
|
||||
*
|
||||
* @since v3.7.0
|
||||
* @see http://vue-select.org/guide/positioning.html
|
||||
*/
|
||||
@@ -547,12 +558,27 @@
|
||||
* @param width {string} calculated width in pixels of the dropdown menu
|
||||
* @param top {string} absolute position top value in pixels relative to the document
|
||||
* @param left {string} absolute position left value in pixels relative to the document
|
||||
* @return {function|void}
|
||||
*/
|
||||
default(dropdownList, component, {width, top, left}) {
|
||||
dropdownList.style.top = top;
|
||||
dropdownList.style.left = left;
|
||||
dropdownList.style.width = width;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Determines whether the dropdown should be open.
|
||||
* Receives the component instance as the only argument.
|
||||
*
|
||||
* @since v3.12.0
|
||||
* @return boolean
|
||||
*/
|
||||
dropdownShouldOpen: {
|
||||
type: Function,
|
||||
default({noDrop, open, mutableLoading}) {
|
||||
return noDrop ? false : open && !mutableLoading;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -607,6 +633,10 @@
|
||||
*/
|
||||
multiple() {
|
||||
this.clearSelection()
|
||||
},
|
||||
|
||||
open(isOpen) {
|
||||
this.$emit(isOpen ? 'open' : 'close');
|
||||
}
|
||||
},
|
||||
|
||||
@@ -617,7 +647,7 @@
|
||||
this.setInternalValueFromOptions(this.value)
|
||||
}
|
||||
|
||||
this.$on('option:created', this.maybePushTag)
|
||||
this.$on('option:created', this.pushTag)
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -641,17 +671,17 @@
|
||||
* @return {void}
|
||||
*/
|
||||
select(option) {
|
||||
this.$emit('option:selecting', option);
|
||||
if (!this.isOptionSelected(option)) {
|
||||
if (this.taggable && !this.optionExists(option)) {
|
||||
option = this.createOption(option);
|
||||
this.$emit('option:created', option);
|
||||
}
|
||||
if (this.multiple) {
|
||||
option = this.selectedValue.concat(option)
|
||||
}
|
||||
this.updateValue(option);
|
||||
this.$emit('option:selected', option);
|
||||
}
|
||||
|
||||
this.onAfterSelect(option)
|
||||
},
|
||||
|
||||
@@ -661,9 +691,11 @@
|
||||
* @return {void}
|
||||
*/
|
||||
deselect (option) {
|
||||
this.$emit('option:deselecting', option);
|
||||
this.updateValue(this.selectedValue.filter(val => {
|
||||
return !this.optionComparator(val, option);
|
||||
}));
|
||||
this.$emit('option:deselected', option);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -681,7 +713,7 @@
|
||||
*/
|
||||
onAfterSelect(option) {
|
||||
if (this.closeOnSelect) {
|
||||
this.open = !this.open
|
||||
this.open = !this.open;
|
||||
this.searchEl.blur()
|
||||
}
|
||||
|
||||
@@ -699,7 +731,7 @@
|
||||
* @param value
|
||||
*/
|
||||
updateValue (value) {
|
||||
if (this.isTrackingValues) {
|
||||
if (typeof this.value === 'undefined') {
|
||||
// Vue select has to manage value
|
||||
this.$data._value = value;
|
||||
}
|
||||
@@ -717,22 +749,28 @@
|
||||
|
||||
/**
|
||||
* Toggle the visibility of the dropdown menu.
|
||||
* @param {Event} e
|
||||
* @param {Event} event
|
||||
* @return {void}
|
||||
*/
|
||||
toggleDropdown ({target}) {
|
||||
toggleDropdown (event) {
|
||||
const targetIsNotSearch = event.target !== this.searchEl;
|
||||
if (targetIsNotSearch) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
||||
// don't react to click on deselect/clear buttons,
|
||||
// they dropdown state will be set in their click handlers
|
||||
const ignoredButtons = [
|
||||
...(this.$refs['deselectButtons'] || []),
|
||||
...([this.$refs['clearButton']] || [])
|
||||
...([this.$refs['clearButton']] || []),
|
||||
];
|
||||
|
||||
if (ignoredButtons.some(ref => ref.contains(target) || ref === target)) {
|
||||
if (this.searchEl === undefined || ignoredButtons.filter(Boolean).some(ref => ref.contains(event.target) || ref === event.target)) {
|
||||
event.preventDefault();
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.open) {
|
||||
if (this.open && targetIsNotSearch) {
|
||||
this.searchEl.blur();
|
||||
} else if (!this.disabled) {
|
||||
this.open = true;
|
||||
@@ -746,42 +784,22 @@
|
||||
* @return {Boolean} True when selected | False otherwise
|
||||
*/
|
||||
isOptionSelected(option) {
|
||||
return this.selectedValue.some(value => {
|
||||
return this.optionComparator(value, option)
|
||||
})
|
||||
return this.selectedValue.some(value => this.optionComparator(value, option))
|
||||
},
|
||||
|
||||
/**
|
||||
* Determine if two option objects are matching.
|
||||
*
|
||||
* @param value {Object}
|
||||
* @param option {Object}
|
||||
* @param a {Object}
|
||||
* @param b {Object}
|
||||
* @returns {boolean}
|
||||
*/
|
||||
optionComparator(value, option) {
|
||||
if (typeof value !== 'object' && typeof option !== 'object') {
|
||||
// Comparing primitives
|
||||
if (value === option) {
|
||||
return true
|
||||
}
|
||||
} else {
|
||||
// Comparing objects
|
||||
if (value === this.reduce(option)) {
|
||||
return true
|
||||
}
|
||||
if ((this.getOptionLabel(value) === this.getOptionLabel(option)) || (this.getOptionLabel(value) === option)) {
|
||||
return true
|
||||
}
|
||||
if (this.reduce(value) === this.reduce(option)) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
optionComparator(a, b) {
|
||||
return this.getOptionKey(a) === this.getOptionKey(b);
|
||||
},
|
||||
|
||||
/**
|
||||
* Finds an option from this.options
|
||||
* Finds an option from the options
|
||||
* where a reduced value matches
|
||||
* the passed in value.
|
||||
*
|
||||
@@ -789,7 +807,24 @@
|
||||
* @returns {*}
|
||||
*/
|
||||
findOptionFromReducedValue (value) {
|
||||
return this.options.find(option => JSON.stringify(this.reduce(option)) === JSON.stringify(value)) || value;
|
||||
const predicate = option => JSON.stringify(this.reduce(option)) === JSON.stringify(value);
|
||||
|
||||
const matches = [
|
||||
...this.options,
|
||||
...this.pushedTags,
|
||||
].filter(predicate);
|
||||
|
||||
if (matches.length === 1) {
|
||||
return matches[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* This second loop is needed to cover an edge case where `taggable` + `reduce`
|
||||
* were used in conjunction with a `create-option` that doesn't create a
|
||||
* unique reduced value.
|
||||
* @see https://github.com/sagalbot/vue-select/issues/1089#issuecomment-597238735
|
||||
*/
|
||||
return matches.find(match => this.optionComparator(match, this.$data._value)) || value;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -808,7 +843,7 @@
|
||||
* @return {this.value}
|
||||
*/
|
||||
maybeDeleteValue() {
|
||||
if (!this.searchEl.value.length && this.selectedValue && this.clearable) {
|
||||
if (!this.searchEl.value.length && this.selectedValue && this.selectedValue.length && this.clearable) {
|
||||
let value = null;
|
||||
if (this.multiple) {
|
||||
value = [...this.selectedValue.slice(0, this.selectedValue.length - 1)]
|
||||
@@ -825,14 +860,7 @@
|
||||
* @return {boolean}
|
||||
*/
|
||||
optionExists(option) {
|
||||
return this.optionList.some(opt => {
|
||||
if (typeof opt === 'object' && this.getOptionLabel(opt) === option) {
|
||||
return true
|
||||
} else if (opt === option) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
})
|
||||
return this.optionList.some(_option => this.optionComparator(_option, option))
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -852,10 +880,8 @@
|
||||
* @param {Object || String} option
|
||||
* @return {void}
|
||||
*/
|
||||
maybePushTag(option) {
|
||||
if (this.pushTags) {
|
||||
this.pushedTags.push(option)
|
||||
}
|
||||
pushTag (option) {
|
||||
this.pushedTags.push(option);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -937,7 +963,7 @@
|
||||
};
|
||||
|
||||
const defaults = {
|
||||
// delete
|
||||
// backspace
|
||||
8: e => this.maybeDeleteValue(),
|
||||
// tab
|
||||
9: e => this.onTab(),
|
||||
@@ -981,7 +1007,6 @@
|
||||
*/
|
||||
selectedValue () {
|
||||
let value = this.value;
|
||||
|
||||
if (this.isTrackingValues) {
|
||||
// Vue select has to manage value internally
|
||||
value = this.$data._value;
|
||||
@@ -1002,7 +1027,7 @@
|
||||
* @return {Array}
|
||||
*/
|
||||
optionList () {
|
||||
return this.options.concat(this.pushedTags);
|
||||
return this.options.concat(this.pushTags ? this.pushedTags : []);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1020,6 +1045,12 @@
|
||||
* @returns {Object}
|
||||
*/
|
||||
scope () {
|
||||
const listSlot = {
|
||||
search: this.search,
|
||||
loading: this.loading,
|
||||
searching: this.searching,
|
||||
filteredOptions: this.filteredOptions
|
||||
};
|
||||
return {
|
||||
search: {
|
||||
attributes: {
|
||||
@@ -1031,11 +1062,13 @@
|
||||
'aria-autocomplete': 'list',
|
||||
'aria-labelledby': `vs${this.uid}__combobox`,
|
||||
'aria-controls': `vs${this.uid}__listbox`,
|
||||
'aria-activedescendant': this.typeAheadPointer > -1 ? `vs${this.uid}__option-${this.typeAheadPointer}` : '',
|
||||
'ref': 'search',
|
||||
'type': 'search',
|
||||
'autocomplete': this.autocomplete,
|
||||
'value': this.search,
|
||||
...(this.dropdownOpen && this.filteredOptions[this.typeAheadPointer] ? {
|
||||
'aria-activedescendant': `vs${this.uid}__option-${this.typeAheadPointer}`
|
||||
} : {}),
|
||||
},
|
||||
events: {
|
||||
'compositionstart': () => this.isComposing = true,
|
||||
@@ -1051,6 +1084,7 @@
|
||||
},
|
||||
noOptions: {
|
||||
search: this.search,
|
||||
loading: this.mutableLoading,
|
||||
searching: this.searching,
|
||||
},
|
||||
openIndicator: {
|
||||
@@ -1060,6 +1094,10 @@
|
||||
'class': 'vs__open-indicator',
|
||||
},
|
||||
},
|
||||
listHeader: listSlot,
|
||||
listFooter: listSlot,
|
||||
header: { ...listSlot, deselect: this.deselect },
|
||||
footer: { ...listSlot, deselect: this.deselect }
|
||||
};
|
||||
},
|
||||
|
||||
@@ -1108,7 +1146,7 @@
|
||||
* @return {Boolean} True if open
|
||||
*/
|
||||
dropdownOpen() {
|
||||
return this.noDrop ? false : this.open && !this.mutableLoading
|
||||
return this.dropdownShouldOpen(this);
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1138,10 +1176,13 @@
|
||||
}
|
||||
|
||||
let options = this.search.length ? this.filter(optionList, this.search, this) : optionList;
|
||||
if (this.taggable && this.search.length && !this.optionExists(this.search)) {
|
||||
options.unshift(this.search)
|
||||
if (this.taggable && this.search.length) {
|
||||
const createdOption = this.createOption(this.search);
|
||||
if (!this.optionExists(createdOption)) {
|
||||
options.unshift(createdOption);
|
||||
}
|
||||
}
|
||||
return options
|
||||
return options;
|
||||
},
|
||||
|
||||
/**
|
||||
@@ -1158,7 +1199,7 @@
|
||||
*/
|
||||
showClearButton() {
|
||||
return !this.multiple && this.clearable && !this.open && !this.isValueEmpty
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
@@ -1,21 +1,27 @@
|
||||
export default {
|
||||
inserted (el, bindings, {context}) {
|
||||
if (context.appendToBody) {
|
||||
const {height, top, left} = context.$refs.toggle.getBoundingClientRect();
|
||||
|
||||
context.calculatePosition(el, context, {
|
||||
width: context.$refs.toggle.clientWidth + 'px',
|
||||
top: (window.scrollY + top + height) + 'px',
|
||||
left: (window.scrollX + left) + 'px',
|
||||
const {height, top, left, width} = context.$refs.toggle.getBoundingClientRect();
|
||||
let scrollX = window.scrollX || window.pageXOffset;
|
||||
let scrollY = window.scrollY || window.pageYOffset;
|
||||
el.unbindPosition = context.calculatePosition(el, context, {
|
||||
width: width + 'px',
|
||||
left: (scrollX + left) + 'px',
|
||||
top: (scrollY + top + height) + 'px',
|
||||
});
|
||||
|
||||
|
||||
document.body.appendChild(el);
|
||||
}
|
||||
},
|
||||
|
||||
unbind (el, bindings, vnode) {
|
||||
if (vnode.context.appendToBody && el.parentNode) {
|
||||
el.parentNode.removeChild(el);
|
||||
unbind (el, bindings, {context}) {
|
||||
if (context.appendToBody) {
|
||||
if (el.unbindPosition && typeof el.unbindPosition === 'function') {
|
||||
el.unbindPosition();
|
||||
}
|
||||
if (el.parentNode) {
|
||||
el.parentNode.removeChild(el);
|
||||
}
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
+28
-60
@@ -1,8 +1,17 @@
|
||||
export default {
|
||||
props: {
|
||||
autoscroll: {
|
||||
type: Boolean,
|
||||
default: true
|
||||
}
|
||||
},
|
||||
|
||||
watch: {
|
||||
typeAheadPointer() {
|
||||
this.maybeAdjustScroll();
|
||||
}
|
||||
if (this.autoscroll) {
|
||||
this.maybeAdjustScroll();
|
||||
}
|
||||
},
|
||||
},
|
||||
|
||||
methods: {
|
||||
@@ -13,75 +22,34 @@ export default {
|
||||
* @returns {*}
|
||||
*/
|
||||
maybeAdjustScroll() {
|
||||
let pixelsToPointerTop = this.pixelsToPointerTop();
|
||||
let pixelsToPointerBottom = this.pixelsToPointerBottom();
|
||||
const optionEl =
|
||||
this.$refs.dropdownMenu?.children[this.typeAheadPointer] || false;
|
||||
|
||||
if (pixelsToPointerTop <= this.viewport().top) {
|
||||
return this.scrollTo(pixelsToPointerTop);
|
||||
} else if (pixelsToPointerBottom >= this.viewport().bottom) {
|
||||
return this.scrollTo(this.viewport().top + this.pointerHeight());
|
||||
}
|
||||
},
|
||||
if (optionEl) {
|
||||
const bounds = this.getDropdownViewport();
|
||||
const { top, bottom, height } = optionEl.getBoundingClientRect();
|
||||
|
||||
/**
|
||||
* The distance in pixels from the top of the dropdown
|
||||
* list to the top of the current pointer element.
|
||||
* @returns {number}
|
||||
*/
|
||||
pixelsToPointerTop() {
|
||||
let pixelsToPointerTop = 0;
|
||||
if (this.$refs.dropdownMenu && this.dropdownOpen) {
|
||||
for (let i = 0; i < this.typeAheadPointer; i++) {
|
||||
pixelsToPointerTop += this.$refs.dropdownMenu.children[i]
|
||||
.offsetHeight;
|
||||
if (top < bounds.top) {
|
||||
return (this.$refs.dropdownMenu.scrollTop = optionEl.offsetTop);
|
||||
} else if (bottom > bounds.bottom) {
|
||||
return (this.$refs.dropdownMenu.scrollTop =
|
||||
optionEl.offsetTop - (bounds.height - height));
|
||||
}
|
||||
}
|
||||
return pixelsToPointerTop;
|
||||
},
|
||||
|
||||
/**
|
||||
* The distance in pixels from the top of the dropdown
|
||||
* list to the bottom of the current pointer element.
|
||||
* @returns {*}
|
||||
*/
|
||||
pixelsToPointerBottom() {
|
||||
return this.pixelsToPointerTop() + this.pointerHeight();
|
||||
},
|
||||
|
||||
/**
|
||||
* The offsetHeight of the current pointer element.
|
||||
* @returns {number}
|
||||
*/
|
||||
pointerHeight() {
|
||||
let element = this.$refs.dropdownMenu
|
||||
? this.$refs.dropdownMenu.children[this.typeAheadPointer]
|
||||
: false;
|
||||
return element ? element.offsetHeight : 0;
|
||||
},
|
||||
|
||||
/**
|
||||
* The currently viewable portion of the dropdownMenu.
|
||||
* @returns {{top: (string|*|number), bottom: *}}
|
||||
*/
|
||||
viewport() {
|
||||
return {
|
||||
top: this.$refs.dropdownMenu ? this.$refs.dropdownMenu.scrollTop : 0,
|
||||
bottom: this.$refs.dropdownMenu
|
||||
? this.$refs.dropdownMenu.offsetHeight +
|
||||
this.$refs.dropdownMenu.scrollTop
|
||||
: 0
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
* Scroll the dropdownMenu to a given position.
|
||||
* @param position
|
||||
* @returns {*}
|
||||
*/
|
||||
scrollTo(position) {
|
||||
getDropdownViewport() {
|
||||
return this.$refs.dropdownMenu
|
||||
? (this.$refs.dropdownMenu.scrollTop = position)
|
||||
: null;
|
||||
? this.$refs.dropdownMenu.getBoundingClientRect()
|
||||
: {
|
||||
height: 0,
|
||||
top: 0,
|
||||
bottom: 0
|
||||
};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -26,9 +26,6 @@ export default {
|
||||
for (let i = this.typeAheadPointer - 1; i >= 0; i--) {
|
||||
if (this.selectable(this.filteredOptions[i])) {
|
||||
this.typeAheadPointer = i;
|
||||
if( this.maybeAdjustScroll ) {
|
||||
this.maybeAdjustScroll()
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -43,9 +40,6 @@ export default {
|
||||
for (let i = this.typeAheadPointer + 1; i < this.filteredOptions.length; i++) {
|
||||
if (this.selectable(this.filteredOptions[i])) {
|
||||
this.typeAheadPointer = i;
|
||||
if( this.maybeAdjustScroll ) {
|
||||
this.maybeAdjustScroll()
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -57,15 +51,11 @@ export default {
|
||||
* @return {void}
|
||||
*/
|
||||
typeAheadSelect() {
|
||||
if( this.filteredOptions[ this.typeAheadPointer ] ) {
|
||||
this.select( this.filteredOptions[ this.typeAheadPointer ] );
|
||||
} else if (this.taggable && this.search.length){
|
||||
this.select(this.search)
|
||||
}
|
||||
const typeAheadOption = this.filteredOptions[this.typeAheadPointer];
|
||||
|
||||
if( this.clearSearchOnSelect ) {
|
||||
this.search = "";
|
||||
if (typeAheadOption) {
|
||||
this.select(typeAheadOption);
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ $vs-border-color: map_get($vs-colors, 'lightest') !default;
|
||||
// Component Controls: Clear, Open Indicator
|
||||
$vs-controls-color: map_get($vs-colors, 'light') !default;
|
||||
$vs-controls-size: 1 !default;
|
||||
$vs-controls-deselect-text-shadow: 0 1px 0 #fff;
|
||||
$vs-controls-deselect-text-shadow: 0 1px 0 #fff !default;
|
||||
|
||||
// Selected
|
||||
$vs-selected-bg: #f0f0f0 !default;
|
||||
|
||||
@@ -13,6 +13,7 @@ $max-height: $vs-dropdown-max-height;
|
||||
|
||||
.vs__dropdown-menu {
|
||||
display: block;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
top: calc(100% - #{$border-width}); // -{#$border-width} here ensures the left and right borders of the dropdown appear flush with the toggle.
|
||||
left: 0;
|
||||
|
||||
@@ -34,6 +34,7 @@ $font-size: 1em;
|
||||
width: 0;
|
||||
max-width: 100%;
|
||||
flex-grow: 1;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.vs__search::placeholder {
|
||||
@@ -48,10 +49,9 @@ $font-size: 1em;
|
||||
.vs--unsearchable {
|
||||
.vs__search {
|
||||
opacity: 1;
|
||||
|
||||
&:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
&:not(.vs--disabled) .vs__search:hover {
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
// Single, when searching but not loading or open
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
line-height: $vs-component-line-height;
|
||||
margin: 4px 2px 0px 2px;
|
||||
padding: 0 0.25em;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.vs__deselect {
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
/**
|
||||
* @param sortable {object}
|
||||
* @return {string}
|
||||
*/
|
||||
function sortAndStringify(sortable) {
|
||||
const ordered = {};
|
||||
|
||||
Object.keys(sortable).sort().forEach(key => {
|
||||
ordered[key] = sortable[key];
|
||||
});
|
||||
|
||||
return JSON.stringify(ordered);
|
||||
}
|
||||
|
||||
export default sortAndStringify;
|
||||
@@ -16,6 +16,23 @@ export const searchSubmit = (Wrapper, searchText = false) => {
|
||||
Wrapper.find({ ref: "search" }).trigger("keydown.enter")
|
||||
};
|
||||
|
||||
/**
|
||||
* Focus the input, enter some search text, hit return.
|
||||
* @param Wrapper {Wrapper<Vue>}
|
||||
* @param searchText
|
||||
* @return {Promise<void>}
|
||||
*/
|
||||
export const selectTag = async (Wrapper, searchText) => {
|
||||
Wrapper.vm.$refs.search.focus();
|
||||
await Wrapper.vm.$nextTick();
|
||||
|
||||
Wrapper.vm.search = searchText;
|
||||
await Wrapper.vm.$nextTick();
|
||||
|
||||
Wrapper.find({ ref: "search" }).trigger("keydown.enter");
|
||||
await Wrapper.vm.$nextTick();
|
||||
};
|
||||
|
||||
/**
|
||||
* Create a new VueSelect instance with
|
||||
* a provided set of props.
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
import { mountDefault } from "../helpers";
|
||||
|
||||
describe("Search Slot Scope", () => {
|
||||
/**
|
||||
* @see https://www.w3.org/WAI/PF/aria/states_and_properties#aria-activedescendant
|
||||
*/
|
||||
describe("aria-activedescendant", () => {
|
||||
it("adds the active descendant attribute only when the dropdown is open and there is a typeAheadPointer value", async () => {
|
||||
const Select = mountDefault();
|
||||
|
||||
expect(
|
||||
Select.vm.scope.search.attributes["aria-activedescendant"]
|
||||
).toEqual(undefined);
|
||||
|
||||
Select.vm.open = true;
|
||||
await Select.vm.$nextTick();
|
||||
|
||||
expect(
|
||||
Select.vm.scope.search.attributes["aria-activedescendant"]
|
||||
).toEqual(undefined);
|
||||
});
|
||||
|
||||
it("adds the active descendant attribute when there's a typeahead value and an open dropdown", async () => {
|
||||
const Select = mountDefault();
|
||||
|
||||
Select.vm.open = true;
|
||||
Select.vm.typeAheadPointer = 1;
|
||||
await Select.vm.$nextTick();
|
||||
|
||||
expect(
|
||||
Select.vm.scope.search.attributes["aria-activedescendant"]
|
||||
).toEqual(`vs${Select.vm.uid}__option-1`);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,61 @@
|
||||
import { mountDefault } from "../helpers";
|
||||
|
||||
describe("Automatic Scrolling", () => {
|
||||
it("should check if the scroll position needs to be adjusted on up arrow keyUp", async () => {
|
||||
// Given
|
||||
const Select = mountDefault();
|
||||
const spy = jest.spyOn(Select.vm, "maybeAdjustScroll");
|
||||
Select.vm.typeAheadPointer = 1;
|
||||
|
||||
// When
|
||||
Select.find({ ref: "search" }).trigger("keydown.up");
|
||||
await Select.vm.$nextTick();
|
||||
|
||||
// Then
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should check if the scroll position needs to be adjusted on down arrow keyUp", async () => {
|
||||
// Given
|
||||
const Select = mountDefault();
|
||||
const spy = jest.spyOn(Select.vm, "maybeAdjustScroll");
|
||||
Select.vm.typeAheadPointer = 1;
|
||||
|
||||
// When
|
||||
Select.find({ ref: "search" }).trigger("keydown.down");
|
||||
await Select.vm.$nextTick();
|
||||
|
||||
// Then
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should check if the scroll position needs to be adjusted when filtered options changes", async () => {
|
||||
// Given
|
||||
const Select = mountDefault();
|
||||
const spy = jest.spyOn(Select.vm, "maybeAdjustScroll");
|
||||
Select.vm.typeAheadPointer = 1;
|
||||
|
||||
// When
|
||||
Select.vm.search = "two";
|
||||
await Select.vm.$nextTick();
|
||||
|
||||
// Then
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should not adjust scroll position when autoscroll is false", async () => {
|
||||
// Given
|
||||
const Select = mountDefault({
|
||||
autoscroll: false
|
||||
});
|
||||
const spy = jest.spyOn(Select.vm, "maybeAdjustScroll");
|
||||
Select.vm.typeAheadPointer = 1;
|
||||
|
||||
// When
|
||||
Select.vm.search = "two";
|
||||
await Select.vm.$nextTick();
|
||||
|
||||
// Then
|
||||
expect(spy).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,30 @@
|
||||
import { searchSubmit, selectTag, selectWithProps } from "../helpers";
|
||||
|
||||
describe("CreateOption When Tagging Is Enabled", () => {
|
||||
it("can select the current search text as a string", async () => {
|
||||
const Select = selectWithProps({
|
||||
taggable: true,
|
||||
multiple: true,
|
||||
options: ["one", "two"],
|
||||
createOption: option => "four"
|
||||
});
|
||||
|
||||
await selectTag(Select, "three");
|
||||
expect(Select.vm.selectedValue).toEqual(["four"]);
|
||||
});
|
||||
|
||||
it("can select the current search text as an object", async () => {
|
||||
const Select = selectWithProps({
|
||||
taggable: true,
|
||||
multiple: false,
|
||||
value: null,
|
||||
options: [],
|
||||
label: "name",
|
||||
createOption: title => ({ name: title })
|
||||
});
|
||||
|
||||
await selectTag(Select, "two");
|
||||
|
||||
expect(Select.emitted("input")[0]).toEqual([{ name: "two" }]);
|
||||
});
|
||||
});
|
||||
@@ -1,4 +1,4 @@
|
||||
import { selectWithProps } from "../helpers";
|
||||
import { mountDefault, selectWithProps } from '../helpers';
|
||||
|
||||
describe("Removing values", () => {
|
||||
it("can remove the given tag when its close icon is clicked", async () => {
|
||||
@@ -48,6 +48,17 @@ describe("Removing values", () => {
|
||||
expect(Select.vm.selectedValue).toEqual([]);
|
||||
});
|
||||
|
||||
it('will not emit input event if value has not changed with backspace', () => {
|
||||
const Select = mountDefault();
|
||||
Select.vm.$data._value = 'one';
|
||||
Select.find({ ref: 'search' }).trigger('keydown.backspace');
|
||||
expect(Select.emitted().input.length).toBe(1);
|
||||
|
||||
Select.find({ ref: 'search' }).trigger('keydown.backspace');
|
||||
Select.find({ ref: 'search' }).trigger('keydown.backspace');
|
||||
expect(Select.emitted().input.length).toBe(1);
|
||||
});
|
||||
|
||||
describe("Clear button", () => {
|
||||
it("should be displayed on single select when value is selected", () => {
|
||||
const Select = selectWithProps({
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
import { selectWithProps } from "../helpers";
|
||||
import OpenIndicator from "../../src/components/OpenIndicator";
|
||||
|
||||
const preventDefault = jest.fn()
|
||||
|
||||
function clickEvent (currentTarget) {
|
||||
return { currentTarget, preventDefault }
|
||||
}
|
||||
|
||||
describe("Toggling Dropdown", () => {
|
||||
it("should not open the dropdown when the el is clicked but the component is disabled", () => {
|
||||
const Select = selectWithProps({ disabled: true });
|
||||
Select.vm.toggleDropdown({ target: Select.vm.$refs.search });
|
||||
Select.vm.toggleDropdown(clickEvent(Select.vm.$refs.search));
|
||||
expect(Select.vm.open).toEqual(false);
|
||||
});
|
||||
|
||||
@@ -14,10 +20,23 @@ describe("Toggling Dropdown", () => {
|
||||
options: [{ label: "one" }]
|
||||
});
|
||||
|
||||
Select.vm.toggleDropdown({ target: Select.vm.$refs.search });
|
||||
Select.vm.toggleDropdown(clickEvent(Select.vm.$refs.search));
|
||||
expect(Select.vm.open).toEqual(true);
|
||||
});
|
||||
|
||||
it("should not close the dropdown when the el is clicked and enableMouseInputSearch is set to true", () => {
|
||||
const Select = selectWithProps({
|
||||
value: [{ label: "one" }],
|
||||
options: [{ label: "one" }],
|
||||
enableMouseSearchInput: true
|
||||
});
|
||||
|
||||
Select.vm.toggleDropdown(clickEvent(Select.vm.$refs.search));
|
||||
expect(Select.vm.open).toEqual(true);
|
||||
Select.vm.toggleDropdown(clickEvent(Select.vm.$el));
|
||||
expect(Select.vm.open).toEqual(false)
|
||||
});
|
||||
|
||||
it("should open the dropdown when the selected tag is clicked", () => {
|
||||
const Select = selectWithProps({
|
||||
value: [{ label: "one" }],
|
||||
@@ -26,7 +45,7 @@ describe("Toggling Dropdown", () => {
|
||||
|
||||
const selectedTag = Select.find(".vs__selected").element;
|
||||
|
||||
Select.vm.toggleDropdown({ target: selectedTag });
|
||||
Select.vm.toggleDropdown(clickEvent(selectedTag));
|
||||
expect(Select.vm.open).toEqual(true);
|
||||
});
|
||||
|
||||
@@ -35,7 +54,7 @@ describe("Toggling Dropdown", () => {
|
||||
const spy = jest.spyOn(Select.vm.$refs.search, "blur");
|
||||
|
||||
Select.vm.open = true;
|
||||
Select.vm.toggleDropdown({ target: Select.vm.$el });
|
||||
Select.vm.toggleDropdown(clickEvent(Select.vm.$el));
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
@@ -133,7 +152,9 @@ describe("Toggling Dropdown", () => {
|
||||
const Select = selectWithProps({
|
||||
noDrop: true,
|
||||
});
|
||||
Select.vm.toggleDropdown({ target: Select.vm.$refs.search });
|
||||
|
||||
Select.vm.toggleDropdown(clickEvent(Select.vm.$refs.search));
|
||||
|
||||
expect(Select.vm.open).toEqual(true);
|
||||
await Select.vm.$nextTick();
|
||||
|
||||
@@ -167,4 +188,14 @@ describe("Toggling Dropdown", () => {
|
||||
expect(Select.classes('vs--searching')).toBeFalsy();
|
||||
});
|
||||
|
||||
it("can be opened with dropdownShouldOpen", () => {
|
||||
const Select = selectWithProps({
|
||||
noDrop: true,
|
||||
dropdownShouldOpen: () => true,
|
||||
options: ['one']
|
||||
});
|
||||
|
||||
expect(Select.classes('vs--open')).toBeTruthy();
|
||||
expect(Select.find('.vs__dropdown-menu li')).toBeTruthy();
|
||||
})
|
||||
});
|
||||
|
||||
+15
-15
@@ -5,10 +5,10 @@ describe('Custom Keydown Handlers', () => {
|
||||
it('can use the map-keydown prop to trigger custom behaviour', () => {
|
||||
const onKeyDown = jest.fn();
|
||||
const Select = mountDefault({
|
||||
mapKeydown: (defaults, vm) => ({...defaults, 32: onKeyDown}),
|
||||
mapKeydown: (defaults, vm) => ({ ...defaults, 32: onKeyDown }),
|
||||
});
|
||||
|
||||
Select.find({ref: 'search'}).trigger('keydown.space');
|
||||
Select.find({ ref: 'search' }).trigger('keydown.space');
|
||||
|
||||
expect(onKeyDown.mock.calls.length).toBe(1);
|
||||
});
|
||||
@@ -20,7 +20,7 @@ describe('Custom Keydown Handlers', () => {
|
||||
|
||||
const spy = jest.spyOn(Select.vm, 'typeAheadSelect');
|
||||
|
||||
Select.find({ref: 'search'}).trigger('keydown.space');
|
||||
Select.find({ ref: 'search' }).trigger('keydown.space');
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
@@ -28,16 +28,16 @@ describe('Custom Keydown Handlers', () => {
|
||||
it('even works when combining selectOnKeyCodes with map-keydown', () => {
|
||||
const onKeyDown = jest.fn();
|
||||
const Select = mountDefault({
|
||||
mapKeydown: (defaults, vm) => ({...defaults, 32: onKeyDown}),
|
||||
mapKeydown: (defaults, vm) => ({ ...defaults, 32: onKeyDown }),
|
||||
selectOnKeyCodes: [9],
|
||||
});
|
||||
|
||||
const spy = jest.spyOn(Select.vm, 'typeAheadSelect');
|
||||
|
||||
Select.find({ref: 'search'}).trigger('keydown.space');
|
||||
Select.find({ ref: 'search' }).trigger('keydown.space');
|
||||
expect(onKeyDown.mock.calls.length).toBe(1);
|
||||
|
||||
Select.find({ref: 'search'}).trigger('keydown.tab');
|
||||
Select.find({ ref: 'search' }).trigger('keydown.tab');
|
||||
expect(spy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
@@ -47,25 +47,25 @@ describe('Custom Keydown Handlers', () => {
|
||||
const Select = mountDefault();
|
||||
const spy = jest.spyOn(Select.vm, 'typeAheadSelect');
|
||||
|
||||
Select.find({ref: 'search'}).trigger('compositionstart');
|
||||
Select.find({ref: 'search'}).trigger('keydown.enter');
|
||||
Select.find({ ref: 'search' }).trigger('compositionstart');
|
||||
Select.find({ ref: 'search' }).trigger('keydown.enter');
|
||||
expect(spy).toHaveBeenCalledTimes(0);
|
||||
|
||||
Select.find({ref: 'search'}).trigger('compositionend');
|
||||
Select.find({ref: 'search'}).trigger('keydown.enter');
|
||||
Select.find({ ref: 'search' }).trigger('compositionend');
|
||||
Select.find({ ref: 'search' }).trigger('keydown.enter');
|
||||
expect(spy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it('will not select a value with tab if the user is composing', () => {
|
||||
const Select = mountDefault({selectOnTab: true});
|
||||
const Select = mountDefault({ selectOnTab: true });
|
||||
const spy = jest.spyOn(Select.vm, 'typeAheadSelect');
|
||||
|
||||
Select.find({ref: 'search'}).trigger('compositionstart');
|
||||
Select.find({ref: 'search'}).trigger('keydown.tab');
|
||||
Select.find({ ref: 'search' }).trigger('compositionstart');
|
||||
Select.find({ ref: 'search' }).trigger('keydown.tab');
|
||||
expect(spy).toHaveBeenCalledTimes(0);
|
||||
|
||||
Select.find({ref: 'search'}).trigger('compositionend');
|
||||
Select.find({ref: 'search'}).trigger('keydown.tab');
|
||||
Select.find({ ref: 'search' }).trigger('compositionend');
|
||||
Select.find({ ref: 'search' }).trigger('keydown.tab');
|
||||
expect(spy).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
|
||||
@@ -41,4 +41,41 @@ describe("Labels", () => {
|
||||
Select.vm.$data._value = "one";
|
||||
expect(Select.vm.searchPlaceholder).not.toBeDefined();
|
||||
});
|
||||
|
||||
describe('getOptionLabel', () => {
|
||||
it('will return undefined if the option lacks the label key', () => {
|
||||
const getOptionLabel = VueSelect.props.getOptionLabel.default.bind({ label: 'label' });
|
||||
expect(getOptionLabel({name: 'vue'})).toEqual(undefined);
|
||||
});
|
||||
|
||||
it('will return a string value for a valid key', () => {
|
||||
const getOptionLabel = VueSelect.props.getOptionLabel.default.bind({ label: 'label' });
|
||||
expect(getOptionLabel({label: 'vue'})).toEqual('vue');
|
||||
});
|
||||
|
||||
/**
|
||||
* this test fails because of a bug where Vue executes the default contents
|
||||
* of a slot, even if it is implemented by the consumer.
|
||||
* @see https://github.com/vuejs/vue/issues/10224
|
||||
* @see https://github.com/vuejs/vue/pull/10229
|
||||
*/
|
||||
xit('will not call getOptionLabel if both scoped option slots are used and a filter is provided', () => {
|
||||
const spy = spyOn(VueSelect.props.getOptionLabel, 'default');
|
||||
const Select = shallowMount(VueSelect, {
|
||||
propsData: {
|
||||
options: [{name: 'one'}],
|
||||
filter: () => {},
|
||||
},
|
||||
scopedSlots: {
|
||||
'option': '<span class="option">{{ props.name }}</span>',
|
||||
'selected-option': '<span class="selected">{{ props.name }}</span>',
|
||||
},
|
||||
});
|
||||
|
||||
Select.vm.select({name: 'one'});
|
||||
|
||||
expect(spy).toHaveBeenCalledTimes(0);
|
||||
expect(Select.find('.selected').exists()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
import Select from '../../src/components/Select';
|
||||
|
||||
describe('Comparing Options', () => {
|
||||
|
||||
const comparator = Select.methods.optionComparator.bind({
|
||||
getOptionKey: Select.props.getOptionKey.default,
|
||||
});
|
||||
|
||||
it('can compare numbers', () => {
|
||||
expect(comparator(1, 2)).toBeFalsy();
|
||||
expect(comparator(1, 1)).toBeTruthy();
|
||||
});
|
||||
|
||||
it('can compare strings', () => {
|
||||
expect(comparator('one', 'one')).toBeTruthy();
|
||||
expect(comparator('one', 'two')).toBeFalsy();
|
||||
});
|
||||
|
||||
it('can compare objects', () => {
|
||||
// compare ID keys
|
||||
expect(comparator({label: 'halo', id: 1}, {label: 'halo', id: 2}))
|
||||
.toBeFalsy();
|
||||
// compare objects
|
||||
expect(comparator({label: 'halo', value: 1}, {label: 'halo', value: 1}))
|
||||
.toBeTruthy();
|
||||
// compare objects with different orders
|
||||
expect(comparator({value: 1, label: 'halo'}, {label: 'halo', value: 1}))
|
||||
.toBeTruthy();
|
||||
});
|
||||
|
||||
});
|
||||
@@ -5,11 +5,11 @@ describe('Serializing Option Keys', () => {
|
||||
const getOptionKey = Select.props.getOptionKey.default;
|
||||
|
||||
it('can serialize strings to a key', () => {
|
||||
expect(getOptionKey('vue')).toBe('"vue"');
|
||||
expect(getOptionKey('vue')).toBe('vue');
|
||||
});
|
||||
|
||||
it('can serialize integers to a key', () => {
|
||||
expect(getOptionKey(1)).toBe('1');
|
||||
expect(getOptionKey(1)).toBe(1);
|
||||
});
|
||||
|
||||
it('can serialize objects to a key', () => {
|
||||
|
||||
@@ -100,19 +100,36 @@ describe("When reduce prop is defined", () => {
|
||||
expect(Select.vm.selectedValue).toEqual([]);
|
||||
});
|
||||
|
||||
it("can use v-model syntax for a two way binding to a parent component", () => {
|
||||
it("can use v-model syntax for a two way binding to a parent component", async () => {
|
||||
const Parent = mount({
|
||||
data: () => ({
|
||||
reduce: option => option.value,
|
||||
value: "foo",
|
||||
current: "foo",
|
||||
options: [
|
||||
{ label: "This is Foo", value: "foo" },
|
||||
{ label: "This is Bar", value: "bar" },
|
||||
{ label: "This is Baz", value: "baz" }
|
||||
]
|
||||
}),
|
||||
template: `<div><v-select :reduce="option => option.value" :options="options" v-model="value"></v-select></div>`,
|
||||
components: { "v-select": VueSelect }
|
||||
components: { "v-select": VueSelect },
|
||||
computed: {
|
||||
value: {
|
||||
get() {
|
||||
return this.current;
|
||||
},
|
||||
set(value) {
|
||||
if (value == 'baz') return;
|
||||
this.current = value;
|
||||
}
|
||||
}
|
||||
},
|
||||
template: `
|
||||
<v-select
|
||||
v-model="value"
|
||||
:reduce="option => option.value"
|
||||
:options="options"
|
||||
/>
|
||||
`
|
||||
});
|
||||
const Select = Parent.vm.$children[0];
|
||||
|
||||
@@ -120,7 +137,15 @@ describe("When reduce prop is defined", () => {
|
||||
expect(Select.selectedValue).toEqual([{ label: "This is Foo", value: "foo" }]);
|
||||
|
||||
Select.select({ label: "This is Bar", value: "bar" });
|
||||
await Select.$nextTick();
|
||||
expect(Parent.vm.value).toEqual("bar");
|
||||
expect(Select.selectedValue).toEqual([{ label: "This is Bar", value: "bar" }]);
|
||||
|
||||
// Parent denies to set baz
|
||||
Select.select({ label: "This is Baz", value: "baz" });
|
||||
await Select.$nextTick();
|
||||
expect(Select.selectedValue).toEqual([{ label: "This is Bar", value: "bar" }]);
|
||||
expect(Parent.vm.value).toEqual('bar');
|
||||
});
|
||||
|
||||
it("can generate labels using a custom label key", () => {
|
||||
@@ -226,4 +251,38 @@ describe("When reduce prop is defined", () => {
|
||||
|
||||
expect(Select.vm.selectedValue).toEqual([optionToChangeTo]);
|
||||
});
|
||||
|
||||
describe('Reducing Tags', () => {
|
||||
it('tracks values that have been created by the user', async () => {
|
||||
const Parent = mount({
|
||||
data: () => ({selected: null, options: []}),
|
||||
template: `
|
||||
<v-select
|
||||
v-model="selected"
|
||||
:options="options"
|
||||
taggable
|
||||
:reduce="name => name.value"
|
||||
:create-option="label => ({ label, value: -1 })"
|
||||
/>
|
||||
`,
|
||||
components: {'v-select': VueSelect},
|
||||
});
|
||||
const Select = Parent.vm.$children[0];
|
||||
|
||||
// When
|
||||
Select.$refs.search.focus();
|
||||
await Select.$nextTick();
|
||||
|
||||
Select.search = 'hello';
|
||||
await Select.$nextTick();
|
||||
|
||||
Select.typeAheadSelect();
|
||||
await Select.$nextTick();
|
||||
|
||||
// Then
|
||||
expect(Select.selectedValue).toEqual([{label: 'hello', value: -1}]);
|
||||
expect(Select.$refs.selectedOptions.textContent.trim()).toEqual('hello');
|
||||
expect(Parent.vm.selected).toEqual(-1);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { mount, shallowMount } from "@vue/test-utils";
|
||||
import VueSelect from "../../src/components/Select.vue";
|
||||
import { mountDefault } from '../helpers';
|
||||
|
||||
describe("VS - Selecting Values", () => {
|
||||
let defaultProps;
|
||||
@@ -192,10 +193,20 @@ describe("VS - Selecting Values", () => {
|
||||
value: [{ label: "foo", value: "bar" }]
|
||||
}
|
||||
});
|
||||
expect(Select.vm.isOptionSelected("foo")).toEqual(true);
|
||||
expect(Select.vm.isOptionSelected({ label: "foo", value: "bar" })).toEqual(true);
|
||||
});
|
||||
|
||||
describe("change Event", () => {
|
||||
it('can select two options with the same label', () => {
|
||||
const options = [{label: 'one', id: 1}, {label: 'one', id: 2}];
|
||||
const Select = mountDefault({options, multiple: true});
|
||||
|
||||
Select.vm.select({label: 'one', id: 1});
|
||||
Select.vm.select({label: 'one', id: 2});
|
||||
|
||||
expect(Select.vm.selectedValue).toEqual(options);
|
||||
});
|
||||
|
||||
describe("input Event", () => {
|
||||
it("will trigger the input event when the selection changes", () => {
|
||||
const Select = shallowMount(VueSelect);
|
||||
Select.vm.select("bar");
|
||||
@@ -209,5 +220,84 @@ describe("VS - Selecting Values", () => {
|
||||
Select.vm.select("bar");
|
||||
expect(Select.emitted("input")[0]).toEqual([["foo", "bar"]]);
|
||||
});
|
||||
|
||||
it("will not trigger the input event when multiple is true and selection is repeated", () => {
|
||||
const Select = shallowMount(VueSelect, {
|
||||
propsData: { multiple: true, value: ["foo ", "bar"], options: ["foo", "bar", "baz"] }
|
||||
});
|
||||
|
||||
Select.vm.select("bar");
|
||||
expect(Select.emitted("input")).toBeFalsy();
|
||||
});
|
||||
});
|
||||
|
||||
describe("option:selecting Event", () => {
|
||||
it("will trigger the option:selecting event when an option is selected", () => {
|
||||
const Select = shallowMount(VueSelect);
|
||||
Select.vm.select("bar");
|
||||
expect(Select.emitted("option:selecting")[0]).toEqual(["bar"]);
|
||||
});
|
||||
|
||||
it("will trigger the option:selecting event regardless of current value", () => {
|
||||
const Select = shallowMount(VueSelect, {
|
||||
propsData: { value: ["foo"], options: ["foo", "bar"] }
|
||||
});
|
||||
Select.vm.select("foo");
|
||||
Select.vm.select("bar");
|
||||
expect(Select.emitted("option:selecting")).toEqual([["foo"], ["bar"]]);
|
||||
});
|
||||
|
||||
it("will trigger the option:selecting event with current selected item when multiple is true", () => {
|
||||
const Select = shallowMount(VueSelect, {
|
||||
propsData: { multiple: true, value: ["foo"], options: ["foo", "bar"] }
|
||||
});
|
||||
Select.vm.select("bar");
|
||||
expect(Select.emitted("option:selecting")[0]).toEqual(["bar"]);
|
||||
});
|
||||
|
||||
it("will trigger the option:selecting event regardless of current value when multiple is true", () => {
|
||||
const Select = shallowMount(VueSelect, {
|
||||
propsData: { multiple: true, value: ["foo", "bar"], options: ["foo", "bar"] }
|
||||
});
|
||||
Select.vm.select("bar");
|
||||
Select.vm.select("bar");
|
||||
expect(Select.emitted("option:selecting")).toEqual([["bar"], ["bar"]]);
|
||||
});
|
||||
});
|
||||
|
||||
describe("option:deselected Event", () => {
|
||||
it("will trigger the option:deselected event when an option is deselected", () => {
|
||||
const Select = shallowMount(VueSelect, {
|
||||
propsData: { value: ["foo"], options: ["foo", "bar"] }
|
||||
});
|
||||
Select.vm.deselect("foo");
|
||||
expect(Select.emitted("option:deselected")[0]).toEqual(["foo"]);
|
||||
});
|
||||
|
||||
it("will trigger the option:deselected event regardless of current value", () => {
|
||||
const Select = shallowMount(VueSelect, {
|
||||
propsData: { value: ["foo"], options: ["foo", "bar"] }
|
||||
});
|
||||
Select.vm.deselect("foo");
|
||||
Select.vm.deselect("bar");
|
||||
expect(Select.emitted("option:deselected")).toEqual([["foo"], ["bar"]]);
|
||||
});
|
||||
|
||||
it("will trigger the option:selected event with current selected item when multiple is true", () => {
|
||||
const Select = shallowMount(VueSelect, {
|
||||
propsData: { multiple: true, value: ["foo"], options: ["foo", "bar"] }
|
||||
});
|
||||
Select.vm.deselect("bar");
|
||||
expect(Select.emitted("option:deselected")[0]).toEqual(["bar"]);
|
||||
});
|
||||
|
||||
it("will trigger the option:selected event regardless of current value when multiple is true", () => {
|
||||
const Select = shallowMount(VueSelect, {
|
||||
propsData: { multiple: true, value: ["foo", "bar"], options: ["foo", "bar"] }
|
||||
});
|
||||
Select.vm.deselect("bar");
|
||||
Select.vm.deselect("bar");
|
||||
expect(Select.emitted("option:deselected")).toEqual([["bar"], ["bar"]]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -68,8 +68,55 @@ describe('Scoped Slots', () => {
|
||||
await Select.vm.$nextTick();
|
||||
|
||||
expect(noOptions).toHaveBeenCalledWith({
|
||||
loading: false,
|
||||
search: 'something not there',
|
||||
searching: true,
|
||||
})
|
||||
});
|
||||
|
||||
test('header slot props', async () => {
|
||||
const header = jest.fn();
|
||||
const Select = mountDefault({}, {
|
||||
scopedSlots: {header: header},
|
||||
});
|
||||
await Select.vm.$nextTick();
|
||||
expect(Object.keys(header.mock.calls[0][0])).toEqual([
|
||||
'search', 'loading', 'searching', 'filteredOptions', 'deselect',
|
||||
]);
|
||||
});
|
||||
|
||||
test('footer slot props', async () => {
|
||||
const footer = jest.fn();
|
||||
const Select = mountDefault({}, {
|
||||
scopedSlots: {footer: footer},
|
||||
});
|
||||
await Select.vm.$nextTick();
|
||||
expect(Object.keys(footer.mock.calls[0][0])).toEqual([
|
||||
'search', 'loading', 'searching', 'filteredOptions', 'deselect',
|
||||
]);
|
||||
});
|
||||
|
||||
test('list-header slot props', async () => {
|
||||
const header = jest.fn();
|
||||
const Select = mountDefault({}, {
|
||||
scopedSlots: {'list-header': header},
|
||||
});
|
||||
Select.vm.open = true;
|
||||
await Select.vm.$nextTick();
|
||||
expect(Object.keys(header.mock.calls[0][0])).toEqual([
|
||||
'search', 'loading', 'searching', 'filteredOptions',
|
||||
]);
|
||||
});
|
||||
|
||||
test('list-footer slot props', async () => {
|
||||
const footer = jest.fn();
|
||||
const Select = mountDefault({}, {
|
||||
scopedSlots: {'list-footer': footer},
|
||||
});
|
||||
Select.vm.open = true;
|
||||
await Select.vm.$nextTick();
|
||||
expect(Object.keys(footer.mock.calls[0][0])).toEqual([
|
||||
'search', 'loading', 'searching', 'filteredOptions',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
+52
-29
@@ -1,6 +1,13 @@
|
||||
import { searchSubmit, selectWithProps } from "../helpers";
|
||||
import {
|
||||
mountDefault,
|
||||
searchSubmit,
|
||||
selectTag,
|
||||
selectWithProps,
|
||||
} from '../helpers';
|
||||
import Select from '../../src/components/Select';
|
||||
|
||||
describe("When Tagging Is Enabled", () => {
|
||||
|
||||
it("can determine if a given option string already exists", () => {
|
||||
const Select = selectWithProps({ taggable: true, options: ["one", "two"] });
|
||||
expect(Select.vm.optionExists("one")).toEqual(true);
|
||||
@@ -13,8 +20,8 @@ describe("When Tagging Is Enabled", () => {
|
||||
options: [{ label: "one" }, { label: "two" }]
|
||||
});
|
||||
|
||||
expect(Select.vm.optionExists("one")).toEqual(true);
|
||||
expect(Select.vm.optionExists("three")).toEqual(false);
|
||||
expect(Select.vm.optionExists({label: "one"})).toEqual(true);
|
||||
expect(Select.vm.optionExists({label: "three"})).toEqual(false);
|
||||
});
|
||||
|
||||
it("can determine if a given option object already exists when using custom labels", () => {
|
||||
@@ -24,11 +31,13 @@ describe("When Tagging Is Enabled", () => {
|
||||
label: "foo"
|
||||
});
|
||||
|
||||
expect(Select.vm.optionExists("one")).toEqual(true);
|
||||
expect(Select.vm.optionExists("three")).toEqual(false);
|
||||
const createOption = (text) => Select.vm.createOption(text);
|
||||
|
||||
expect(Select.vm.optionExists(createOption("one"))).toEqual(true);
|
||||
expect(Select.vm.optionExists(createOption("three"))).toEqual(false);
|
||||
});
|
||||
|
||||
it("can add the current search text as the first item in the options list", () => {
|
||||
it("can add the current search text as the first item in the options list", async () => {
|
||||
const Select = selectWithProps({
|
||||
taggable: true,
|
||||
multiple: true,
|
||||
@@ -37,36 +46,37 @@ describe("When Tagging Is Enabled", () => {
|
||||
});
|
||||
|
||||
Select.vm.search = "three";
|
||||
await Select.vm.$nextTick();
|
||||
expect(Select.vm.filteredOptions).toEqual(["three"]);
|
||||
});
|
||||
|
||||
it("can select the current search text as a string", () => {
|
||||
it("can select the current search text as a string", async () => {
|
||||
const Select = selectWithProps({
|
||||
taggable: true,
|
||||
multiple: true,
|
||||
options: ["one", "two"]
|
||||
});
|
||||
|
||||
searchSubmit(Select, "three");
|
||||
await selectTag(Select, "three");
|
||||
|
||||
expect(Select.vm.selectedValue).toEqual(["three"]);
|
||||
});
|
||||
|
||||
it("can select the current search text as an object", () => {
|
||||
it("can select the current search text as an object", async () => {
|
||||
const Select = selectWithProps({
|
||||
taggable: true,
|
||||
multiple: true,
|
||||
options: [{ label: "one" }]
|
||||
});
|
||||
|
||||
searchSubmit(Select, "two");
|
||||
await selectTag(Select, "two");
|
||||
|
||||
expect(Select.vm.selectedValue).toEqual([
|
||||
{ label: "two" }
|
||||
]);
|
||||
});
|
||||
|
||||
it("should add a freshly created option/tag to the options list when pushTags is true", () => {
|
||||
it("should add a freshly created option/tag to the options list when pushTags is true", async () => {
|
||||
const Select = selectWithProps({
|
||||
pushTags: true,
|
||||
taggable: true,
|
||||
@@ -75,12 +85,12 @@ describe("When Tagging Is Enabled", () => {
|
||||
options: ["one", "two"]
|
||||
});
|
||||
|
||||
searchSubmit(Select, "three");
|
||||
await selectTag(Select, "three");
|
||||
expect(Select.vm.pushedTags).toEqual(["three"]);
|
||||
expect(Select.vm.optionList).toEqual(["one", "two", "three"]);
|
||||
});
|
||||
|
||||
it("should pushTags even if the consumer has defined a createOption callback", () => {
|
||||
it("should pushTags even if the consumer has defined a createOption callback", async () => {
|
||||
const Select = selectWithProps({
|
||||
pushTags: true,
|
||||
taggable: true,
|
||||
@@ -88,13 +98,13 @@ describe("When Tagging Is Enabled", () => {
|
||||
options: ["one", "two"]
|
||||
});
|
||||
|
||||
searchSubmit(Select, "three");
|
||||
await selectTag(Select, "three");
|
||||
|
||||
expect(Select.vm.pushedTags).toEqual(["three"]);
|
||||
expect(Select.vm.optionList).toEqual(["one", "two", "three"]);
|
||||
});
|
||||
|
||||
it("should add a freshly created option/tag to the options list when pushTags is true and filterable is false", () => {
|
||||
it("should add a freshly created option/tag to the options list when pushTags is true and filterable is false", async () => {
|
||||
const Select = selectWithProps({
|
||||
filterable: false,
|
||||
pushTags: true,
|
||||
@@ -104,13 +114,13 @@ describe("When Tagging Is Enabled", () => {
|
||||
options: ["one", "two"]
|
||||
});
|
||||
|
||||
searchSubmit(Select, "three");
|
||||
await selectTag(Select, "three");
|
||||
expect(Select.vm.pushedTags).toEqual(["three"]);
|
||||
expect(Select.vm.optionList).toEqual(["one", "two", "three"]);
|
||||
expect(Select.vm.filteredOptions).toEqual(["one", "two", "three"]);
|
||||
});
|
||||
|
||||
it("wont add a freshly created option/tag to the options list when pushTags is false", () => {
|
||||
it("wont add a freshly created option/tag to the options list when pushTags is false", async () => {
|
||||
const Select = selectWithProps({
|
||||
pushTags: false,
|
||||
taggable: true,
|
||||
@@ -119,11 +129,11 @@ describe("When Tagging Is Enabled", () => {
|
||||
options: ["one", "two"]
|
||||
});
|
||||
|
||||
searchSubmit(Select, "three");
|
||||
await selectTag(Select, "three");
|
||||
expect(Select.vm.optionList).toEqual(["one", "two"]);
|
||||
});
|
||||
|
||||
it("wont add a freshly created option/tag to the options list when pushTags is false and filterable is false", () => {
|
||||
it("wont add a freshly created option/tag to the options list when pushTags is false and filterable is false", async () => {
|
||||
const Select = selectWithProps({
|
||||
filterable: false,
|
||||
pushTags: false,
|
||||
@@ -133,7 +143,7 @@ describe("When Tagging Is Enabled", () => {
|
||||
options: ["one", "two"]
|
||||
});
|
||||
|
||||
searchSubmit(Select, "three");
|
||||
await selectTag(Select, "three");
|
||||
expect(Select.vm.optionList).toEqual(["one", "two"]);
|
||||
expect(Select.vm.filteredOptions).toEqual(["one", "two"]);
|
||||
});
|
||||
@@ -146,9 +156,7 @@ describe("When Tagging Is Enabled", () => {
|
||||
options: ["one", two]
|
||||
});
|
||||
|
||||
Select.vm.search = "two";
|
||||
|
||||
searchSubmit(Select);
|
||||
await selectTag(Select, "two");
|
||||
|
||||
expect(Select.vm.selectedValue).toEqual([two]);
|
||||
});
|
||||
@@ -207,34 +215,49 @@ describe("When Tagging Is Enabled", () => {
|
||||
expect(Select.vm.selectedValue).toEqual([{ label: "one" }]);
|
||||
});
|
||||
|
||||
it("should not allow duplicate tags when using string options", () => {
|
||||
it("should not allow duplicate tags when using string options", async () => {
|
||||
const Select = selectWithProps({
|
||||
taggable: true,
|
||||
multiple: true
|
||||
});
|
||||
|
||||
searchSubmit(Select, "one");
|
||||
await selectTag(Select, "one");
|
||||
expect(Select.vm.selectedValue).toEqual(["one"]);
|
||||
expect(Select.vm.search).toEqual("");
|
||||
|
||||
searchSubmit(Select, "one");
|
||||
await selectTag(Select, "one");
|
||||
expect(Select.vm.selectedValue).toEqual(["one"]);
|
||||
expect(Select.vm.search).toEqual("");
|
||||
});
|
||||
|
||||
it("should not allow duplicate tags when using object options", () => {
|
||||
it("should not allow duplicate tags when using object options", async () => {
|
||||
const Select = selectWithProps({
|
||||
taggable: true,
|
||||
multiple: true,
|
||||
options: [{ label: "two" }]
|
||||
});
|
||||
const spy = jest.spyOn(Select.vm, 'select');
|
||||
|
||||
searchSubmit(Select, "one");
|
||||
await selectTag(Select, "one");
|
||||
expect(Select.vm.selectedValue).toEqual([{ label: "one" }]);
|
||||
expect(spy).lastCalledWith({label: 'one'});
|
||||
expect(Select.vm.search).toEqual("");
|
||||
|
||||
searchSubmit(Select, "one");
|
||||
await selectTag(Select, "one");
|
||||
expect(Select.vm.selectedValue).toEqual([{ label: "one" }]);
|
||||
expect(Select.vm.search).toEqual("");
|
||||
});
|
||||
|
||||
it("will select an existing option on tab", async () => {
|
||||
const Select = mountDefault({
|
||||
taggable: true,
|
||||
selectOnTab: true
|
||||
});
|
||||
|
||||
Select.vm.typeAheadPointer = 0;
|
||||
Select.find({ ref: "search" }).trigger("keydown.tab");
|
||||
|
||||
await Select.vm.$nextTick();
|
||||
expect(Select.vm.selectedValue).toEqual(['one']);
|
||||
})
|
||||
});
|
||||
|
||||
@@ -1,18 +1,17 @@
|
||||
import { shallowMount } from '@vue/test-utils';
|
||||
import { shallowMount } from "@vue/test-utils";
|
||||
import VueSelect from "../../src/components/Select";
|
||||
import { mountDefault, mountWithoutTestUtils } from '../helpers';
|
||||
import typeAheadMixin from '../../src/mixins/typeAheadPointer';
|
||||
import Vue from 'vue';
|
||||
import { mountDefault, mountWithoutTestUtils } from "../helpers";
|
||||
import typeAheadMixin from "../../src/mixins/typeAheadPointer";
|
||||
import Vue from "vue";
|
||||
|
||||
describe("Moving the Typeahead Pointer", () => {
|
||||
|
||||
it('should set the pointer to zero when the filteredOptions watcher is called', async () => {
|
||||
it("should set the pointer to zero when the filteredOptions watcher is called", async () => {
|
||||
const Select = shallowMount(VueSelect, {
|
||||
propsData: { options: ['one', 'two', 'three'] },
|
||||
propsData: { options: ["one", "two", "three"] },
|
||||
sync: false
|
||||
});
|
||||
|
||||
Select.vm.search = 'one';
|
||||
Select.vm.search = "one";
|
||||
|
||||
await Select.vm.$nextTick();
|
||||
expect(Select.vm.typeAheadPointer).toEqual(0);
|
||||
@@ -45,114 +44,4 @@ describe("Moving the Typeahead Pointer", () => {
|
||||
Select.vm.typeAheadDown();
|
||||
expect(Select.vm.typeAheadPointer).toEqual(2);
|
||||
});
|
||||
|
||||
describe("Automatic Scrolling", () => {
|
||||
it("should check if the scroll position needs to be adjusted on up arrow keyUp", () => {
|
||||
const Select = mountDefault();
|
||||
const spy = jest.spyOn(Select.vm, "maybeAdjustScroll");
|
||||
|
||||
Select.vm.typeAheadPointer = 1;
|
||||
|
||||
Select.find({ ref: "search" }).trigger("keydown.up");
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should check if the scroll position needs to be adjusted on down arrow keyUp", () => {
|
||||
const Select = mountDefault();
|
||||
const spy = jest.spyOn(Select.vm, "maybeAdjustScroll");
|
||||
|
||||
Select.vm.typeAheadPointer = 1;
|
||||
|
||||
Select.find({ ref: "search" }).trigger("keydown.down");
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
/**
|
||||
* This test fails despite working in the browser.
|
||||
* After many attempts to get it to pass, it's been
|
||||
* rewritten below.
|
||||
*/
|
||||
it.skip("should check if the scroll position needs to be adjusted when filtered options changes", () => {
|
||||
const Select = mountDefault();
|
||||
const spy = jest.spyOn(Select.vm, "maybeAdjustScroll");
|
||||
|
||||
Select.vm.search = "two";
|
||||
|
||||
expect(spy).toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("should scroll up if the pointer is above the current viewport bounds", () => {
|
||||
const Select = mountDefault();
|
||||
const spy = jest.spyOn(Select.vm, "scrollTo");
|
||||
|
||||
Select.setMethods({
|
||||
pixelsToPointerTop() {
|
||||
return 1;
|
||||
},
|
||||
viewport() {
|
||||
return { top: 2, bottom: 0 };
|
||||
}
|
||||
});
|
||||
|
||||
Select.vm.maybeAdjustScroll();
|
||||
|
||||
expect(spy).toHaveBeenCalledWith(1);
|
||||
});
|
||||
|
||||
it("should scroll down if the pointer is below the current viewport bounds", () => {
|
||||
const Select = mountDefault();
|
||||
const spy = jest.spyOn(Select.vm, "scrollTo");
|
||||
|
||||
Select.setMethods({
|
||||
pixelsToPointerBottom() {
|
||||
return 2;
|
||||
},
|
||||
viewport() {
|
||||
return { top: 0, bottom: 1 };
|
||||
}
|
||||
});
|
||||
|
||||
Select.vm.maybeAdjustScroll();
|
||||
expect(spy).toHaveBeenCalledWith(
|
||||
Select.vm.viewport().top + Select.vm.pointerHeight()
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Measuring pixel distances", () => {
|
||||
it("should calculate pointerHeight as the offsetHeight of the pointer element if it exists", async () => {
|
||||
const Select = mountDefault();
|
||||
|
||||
// Drop down must be open for $refs to exist
|
||||
Select.vm.open = true;
|
||||
await Select.vm.$nextTick();
|
||||
|
||||
/**
|
||||
* Since JSDom doesn't render layouts, set the offsetHeight explicitly
|
||||
* to 25px for each list item.
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty
|
||||
*/
|
||||
let i = 0;
|
||||
for (let option of Select.vm.$refs.dropdownMenu.children) {
|
||||
Object.defineProperty(option, "offsetHeight", {
|
||||
value: 1 + i
|
||||
});
|
||||
i++;
|
||||
}
|
||||
|
||||
// Fresh instances start with the pointer at -1
|
||||
Select.vm.typeAheadPointer = -1;
|
||||
expect(Select.vm.pointerHeight()).toEqual(0);
|
||||
|
||||
Select.vm.typeAheadPointer = 0;
|
||||
expect(Select.vm.pointerHeight()).toEqual(1);
|
||||
|
||||
Select.vm.typeAheadPointer = 1;
|
||||
expect(Select.vm.pointerHeight()).toEqual(2);
|
||||
|
||||
Select.vm.typeAheadPointer = 2;
|
||||
expect(Select.vm.pointerHeight()).toEqual(3);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,14 @@
|
||||
import sortAndStringify from '../../../src/utility/sortAndStringify';
|
||||
|
||||
test('it will stringify an object', () => {
|
||||
expect(sortAndStringify({hello: 'world'})).toEqual('{"hello":"world"}');
|
||||
});
|
||||
|
||||
test('it will sort attributes alphabetically', () => {
|
||||
expect(sortAndStringify({b: 'b', a: 'a'})).toEqual('{"a":"a","b":"b"}');
|
||||
});
|
||||
|
||||
test('comparing two objects with unsorted keys', () => {
|
||||
expect(sortAndStringify({b: 'b', a: 'a'}))
|
||||
.toEqual(sortAndStringify({a: 'a', b: 'b'}))
|
||||
});
|
||||
@@ -1489,9 +1489,9 @@ acorn-walk@^6.0.1:
|
||||
integrity sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==
|
||||
|
||||
acorn@^5.5.3:
|
||||
version "5.7.3"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279"
|
||||
integrity sha512-T/zvzYRfbVojPWahDsE5evJdHb3oJoQfFbsrKM7w5Zcs++Tr257tia3BmMP8XYVjp1S9RZXQMh7gao96BlqZOw==
|
||||
version "5.7.4"
|
||||
resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.4.tgz#3e8d8a9947d0599a1796d10225d7432f4a4acf5e"
|
||||
integrity sha512-1D++VG7BhrtvQpNbBzovKNc1FLGGEE/oGe7b9xJm/RFHMBeUaUGpluV9RLjZa47YFdPcDAenEYuq9pQPcMdLJg==
|
||||
|
||||
acorn@^6.0.1, acorn@^6.2.1:
|
||||
version "6.4.0"
|
||||
@@ -1879,9 +1879,9 @@ aws-sign2@~0.7.0:
|
||||
integrity sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=
|
||||
|
||||
aws4@^1.8.0:
|
||||
version "1.9.1"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.9.1.tgz#7e33d8f7d449b3f673cd72deb9abdc552dbe528e"
|
||||
integrity sha512-wMHVg2EOHaMRxbzgFJ9gtjOOCrI80OHLG14rxi28XwOW8ux6IiEbRCGGGqCtdAIg4FQCbW20k9RsT4y3gJlFug==
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.10.0.tgz#a17b3a8ea811060e74d47d306122400ad4497ae2"
|
||||
integrity sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==
|
||||
|
||||
axios@^0.19.0:
|
||||
version "0.19.2"
|
||||
@@ -2096,9 +2096,9 @@ big.js@^5.2.2:
|
||||
integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ==
|
||||
|
||||
bin-links@^1.1.2, bin-links@^1.1.7:
|
||||
version "1.1.7"
|
||||
resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.7.tgz#34b79ea9d0e575d7308afeff0c6b2fc24c793359"
|
||||
integrity sha512-/eaLaTu7G7/o7PV04QPy1HRT65zf+1tFkPGv0sPTV0tRwufooYBQO3zrcyGgm+ja+ZtBf2GEuKjDRJ2pPG+yqA==
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/bin-links/-/bin-links-1.1.8.tgz#bd39aadab5dc4bdac222a07df5baf1af745b2228"
|
||||
integrity sha512-KgmVfx+QqggqP9dA3iIc5pA4T1qEEEL+hOhOhNPaUm77OTrJoOXE/C05SJLNJe6m/2wUK7F1tDSou7n5TfCDzQ==
|
||||
dependencies:
|
||||
bluebird "^3.5.3"
|
||||
cmd-shim "^3.0.0"
|
||||
@@ -2380,9 +2380,9 @@ bytes@3.1.0, bytes@^3.0.0:
|
||||
integrity sha512-zauLjrfCG+xvoyaqLoV8bLVXXNGC4JqlxFCutSDWA6fJrTo2ZuvLYTqZ7aHBLZSMOopbzwv8f+wZcVzfVTI2Dg==
|
||||
|
||||
cacache@^12.0.0, cacache@^12.0.2, cacache@^12.0.3:
|
||||
version "12.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.3.tgz#be99abba4e1bf5df461cd5a2c1071fc432573390"
|
||||
integrity sha512-kqdmfXEGFepesTuROHMs3MpFLWrPkSSpRqOw80RCflZXy/khxaArvFrQ7uJxSUduzAufc6G0g1VUCOZXxWavPw==
|
||||
version "12.0.4"
|
||||
resolved "https://registry.yarnpkg.com/cacache/-/cacache-12.0.4.tgz#668bcbd105aeb5f1d92fe25570ec9525c8faa40c"
|
||||
integrity sha512-a0tMB40oefvuInr4Cwb3GerbL9xTj1D5yg0T5xrjGCGyfvbxseIXX7BAO/u/hIXdafzOI5JC3wDwHyf24buOAQ==
|
||||
dependencies:
|
||||
bluebird "^3.5.5"
|
||||
chownr "^1.1.1"
|
||||
@@ -2623,12 +2623,7 @@ chokidar@^2.0.2, chokidar@^2.1.5, chokidar@^2.1.8:
|
||||
optionalDependencies:
|
||||
fsevents "^1.2.7"
|
||||
|
||||
chownr@^1.1.1:
|
||||
version "1.1.3"
|
||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.3.tgz#42d837d5239688d55f303003a508230fa6727142"
|
||||
integrity sha512-i70fVHhmV3DtTl6nqvZOnIjbY0Pe4kAUjwHj8z0zAdgBtYrJyYwLKCCuRBQ5ppkyL0AkN7HKRnETdmdp1zqNXw==
|
||||
|
||||
chownr@^1.1.2, chownr@^1.1.4:
|
||||
chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.4:
|
||||
version "1.1.4"
|
||||
resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b"
|
||||
integrity sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==
|
||||
@@ -3608,14 +3603,14 @@ debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^3.0.0, debug@^3.1.0, debug@^3.1.1, debug@^3.2.5:
|
||||
debug@^3.1.0, debug@^3.1.1, debug@^3.2.5:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debuglog@^1.0.1:
|
||||
debuglog@*, debuglog@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
||||
integrity sha1-qiT/uaw9+aI1GDfPstJ5NgzXhJI=
|
||||
@@ -4094,7 +4089,24 @@ error-ex@^1.2.0, error-ex@^1.3.1:
|
||||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
es-abstract@^1.17.0-next.1, es-abstract@^1.17.2:
|
||||
es-abstract@^1.17.0-next.1, es-abstract@^1.17.5:
|
||||
version "1.17.6"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a"
|
||||
integrity sha512-Fr89bON3WFyUi5EvAeI48QTWX0AyekGgLA8H+c+7fbfCkJwRWRMLd8CQedNEyJuoYYhmtEqY92pgte1FAhBlhw==
|
||||
dependencies:
|
||||
es-to-primitive "^1.2.1"
|
||||
function-bind "^1.1.1"
|
||||
has "^1.0.3"
|
||||
has-symbols "^1.0.1"
|
||||
is-callable "^1.2.0"
|
||||
is-regex "^1.1.0"
|
||||
object-inspect "^1.7.0"
|
||||
object-keys "^1.1.1"
|
||||
object.assign "^4.1.0"
|
||||
string.prototype.trimend "^1.0.1"
|
||||
string.prototype.trimstart "^1.0.1"
|
||||
|
||||
es-abstract@^1.17.2:
|
||||
version "1.17.4"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.4.tgz#e3aedf19706b20e7c2594c35fc0d57605a79e184"
|
||||
integrity sha512-Ae3um/gb8F0mui/jPL+QiqmglkUsaQf7FwBEHYIFkztkneosu9imhqHpBzQ3h1vit8t5iQ74t6PEVvphBZiuiQ==
|
||||
@@ -4316,9 +4328,9 @@ etag@~1.8.1:
|
||||
integrity sha1-Qa4u62XvpiJorr/qg6x9eSmbCIc=
|
||||
|
||||
eventemitter3@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.0.tgz#d65176163887ee59f386d64c82610b696a4a74eb"
|
||||
integrity sha512-qerSRB0p+UDEssxTtm6EDKcE7W4OaoisfIMl4CngyEhjpYglocpNg6UEqCvemdGhosAsg4sO2dXJOdyBifPGCg==
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==
|
||||
|
||||
events@^3.0.0:
|
||||
version "3.1.0"
|
||||
@@ -4585,9 +4597,9 @@ fb-watchman@^2.0.0:
|
||||
bser "2.1.1"
|
||||
|
||||
figgy-pudding@^3.4.1, figgy-pudding@^3.5.1:
|
||||
version "3.5.1"
|
||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.1.tgz#862470112901c727a0e495a80744bd5baa1d6790"
|
||||
integrity sha512-vNKxJHTEKNThjfrdJwHc7brvM6eVevuO5nTj6ez8ZQ1qbXTvGthucRF7S4vf2cr71QVnT70V34v0S1DyQsti0w==
|
||||
version "3.5.2"
|
||||
resolved "https://registry.yarnpkg.com/figgy-pudding/-/figgy-pudding-3.5.2.tgz#b4eee8148abb01dcf1d1ac34367d59e12fa61d6e"
|
||||
integrity sha512-0btnI/H8f2pavGMN8w40mlSKOfTK2SVJmBfBeVIj3kNw0swwgzyRq0d5TJVOwodFmtvpPeWPN/MCcfuWF0Ezbw==
|
||||
|
||||
figures@^2.0.0:
|
||||
version "2.0.0"
|
||||
@@ -4766,11 +4778,9 @@ follow-redirects@1.5.10:
|
||||
debug "=3.1.0"
|
||||
|
||||
follow-redirects@^1.0.0:
|
||||
version "1.10.0"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.10.0.tgz#01f5263aee921c6a54fb91667f08f4155ce169eb"
|
||||
integrity sha512-4eyLK6s6lH32nOvLLwlIOnr9zrL8Sm+OvW4pVTJNoXeGzYIkHVf+pADQi+OJ0E67hiuSLezPVPyBcIZO50TmmQ==
|
||||
dependencies:
|
||||
debug "^3.0.0"
|
||||
version "1.13.0"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.13.0.tgz#b42e8d93a2a7eea5ed88633676d6597bc8e384db"
|
||||
integrity sha512-aq6gF1BEKje4a9i9+5jimNFIpq4Q1WiwBToeRK5NvZBd/TRsmW8BsJfOEGkr76TbOyPVD3OVDN910EcUNtRYEA==
|
||||
|
||||
for-in@^1.0.2:
|
||||
version "1.0.2"
|
||||
@@ -4924,9 +4934,9 @@ gensync@^1.0.0-beta.1:
|
||||
integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg==
|
||||
|
||||
gentle-fs@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.3.0.tgz#13538db5029400f98684be4894e8a7d8f0d1ea7f"
|
||||
integrity sha512-3k2CgAmPxuz7S6nKK+AqFE2AdM1QuwqKLPKzIET3VRwK++3q96MsNFobScDjlCrq97ZJ8y5R725MOlm6ffUCjg==
|
||||
version "2.3.1"
|
||||
resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.3.1.tgz#11201bf66c18f930ddca72cf69460bdfa05727b1"
|
||||
integrity sha512-OlwBBwqCFPcjm33rF2BjW+Pr6/ll2741l+xooiwTCeaX2CA1ZuclavyMBe0/KlR21/XGsgY6hzEQZ15BdNa13Q==
|
||||
dependencies:
|
||||
aproba "^1.1.2"
|
||||
chownr "^1.1.2"
|
||||
@@ -5030,7 +5040,7 @@ glob@7.1.4:
|
||||
once "^1.3.0"
|
||||
path-is-absolute "^1.0.0"
|
||||
|
||||
glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@~7.1.1:
|
||||
glob@^7.0.0, glob@^7.0.3, glob@^7.1.1, glob@^7.1.2, glob@^7.1.3, glob@^7.1.4, glob@^7.1.6, glob@~7.1.1:
|
||||
version "7.1.6"
|
||||
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6"
|
||||
integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==
|
||||
@@ -5151,10 +5161,10 @@ got@^6.7.1:
|
||||
unzip-response "^2.0.1"
|
||||
url-parse-lax "^1.0.0"
|
||||
|
||||
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.3:
|
||||
version "4.2.3"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.3.tgz#4a12ff1b60376ef09862c2093edd908328be8423"
|
||||
integrity sha512-a30VEBm4PEdx1dRB7MFK7BejejvCvBronbLjht+sHuGYj8PHs7M/5Z+rt5lw551vZ7yfTCj4Vuyy3mSJytDWRQ==
|
||||
graceful-fs@^4.1.11, graceful-fs@^4.1.15, graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.2, graceful-fs@^4.2.4:
|
||||
version "4.2.4"
|
||||
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb"
|
||||
integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw==
|
||||
|
||||
"graceful-readlink@>= 1.0.0":
|
||||
version "1.0.1"
|
||||
@@ -5195,7 +5205,7 @@ har-schema@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
|
||||
integrity sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=
|
||||
|
||||
har-validator@~5.1.0:
|
||||
har-validator@~5.1.3:
|
||||
version "5.1.3"
|
||||
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.3.tgz#1ef89ebd3e4996557675eed9893110dc350fa080"
|
||||
integrity sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==
|
||||
@@ -5333,12 +5343,7 @@ hook-std@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/hook-std/-/hook-std-2.0.0.tgz#ff9aafdebb6a989a354f729bb6445cf4a3a7077c"
|
||||
integrity sha512-zZ6T5WcuBMIUVh49iPQS9t977t7C0l7OtHrpeMb5uk48JdflRX0NSFvCekfYNmGQETnLq9W/isMyHl69kxGi8g==
|
||||
|
||||
hosted-git-info@^2.1.4:
|
||||
version "2.8.5"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.5.tgz#759cfcf2c4d156ade59b0b2dfabddc42a6b9c70c"
|
||||
integrity sha512-kssjab8CvdXfcXMXVcvsXum4Hwdq9XGtRD3TteMEvEbq0LXyiNQr6AprqKqfeaDXze7SxWvRxdpwE6ku7ikLkg==
|
||||
|
||||
hosted-git-info@^2.7.1, hosted-git-info@^2.8.7:
|
||||
hosted-git-info@^2.1.4, hosted-git-info@^2.7.1, hosted-git-info@^2.8.8:
|
||||
version "2.8.8"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
|
||||
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
|
||||
@@ -5529,9 +5534,9 @@ http-proxy-middleware@0.19.1:
|
||||
micromatch "^3.1.10"
|
||||
|
||||
http-proxy@^1.17.0:
|
||||
version "1.18.0"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.0.tgz#dbe55f63e75a347db7f3d99974f2692a314a6a3a"
|
||||
integrity sha512-84I2iJM/n1d4Hdgc6y2+qY5mDaz2PUVjlg9znE9byl+q0uC3DeByqBGReQu5tpLK0TAqTIXScRUV+dg7+bUPpQ==
|
||||
version "1.18.1"
|
||||
resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.18.1.tgz#401541f0534884bbf95260334e72f88ee3976549"
|
||||
integrity sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==
|
||||
dependencies:
|
||||
eventemitter3 "^4.0.0"
|
||||
follow-redirects "^1.0.0"
|
||||
@@ -5680,7 +5685,7 @@ import-local@2.0.0, import-local@^2.0.0:
|
||||
pkg-dir "^3.0.0"
|
||||
resolve-cwd "^2.0.0"
|
||||
|
||||
imurmurhash@^0.1.4:
|
||||
imurmurhash@*, imurmurhash@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea"
|
||||
integrity sha1-khi5srkoojixPcT7a21XbyMUU+o=
|
||||
@@ -5741,9 +5746,9 @@ inherits@2.0.3:
|
||||
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
|
||||
|
||||
ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
|
||||
version "1.3.5"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
||||
version "1.3.7"
|
||||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.7.tgz#a09363e1911972ea16d7a8851005d84cf09a9a84"
|
||||
integrity sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==
|
||||
|
||||
init-package-json@^1.10.3:
|
||||
version "1.10.3"
|
||||
@@ -5906,7 +5911,12 @@ is-buffer@^1.1.5:
|
||||
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
|
||||
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
|
||||
|
||||
is-callable@^1.1.4, is-callable@^1.1.5:
|
||||
is-callable@^1.1.4, is-callable@^1.2.0:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.2.0.tgz#83336560b54a38e35e3a2df7afd0454d691468bb"
|
||||
integrity sha512-pyVD9AaGLxtg6srb2Ng6ynWJqkHU9bEM087AKck0w8QwDarTfNcpIYoU8x8Hv2Icm8u6kFJM18Dag8lyqGkviw==
|
||||
|
||||
is-callable@^1.1.5:
|
||||
version "1.1.5"
|
||||
resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.5.tgz#f7e46b596890456db74e7f6e976cb3273d06faab"
|
||||
integrity sha512-ESKv5sMCJB2jnHTWZ3O5itG+O128Hsus4K4Qh1h2/cgn2vbgnLSVqfV46AeJA9D5EeeLa9w81KUXMtn34zhX+Q==
|
||||
@@ -5926,9 +5936,9 @@ is-ci@^2.0.0:
|
||||
ci-info "^2.0.0"
|
||||
|
||||
is-cidr@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-3.1.0.tgz#72e233d8e1c4cd1d3f11713fcce3eba7b0e3476f"
|
||||
integrity sha512-3kxTForpuj8O4iHn0ocsn1jxRm5VYm60GDghK6HXmpn4IyZOoRy9/GmdjFA2yEMqw91TB1/K3bFTuI7FlFNR1g==
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/is-cidr/-/is-cidr-3.1.1.tgz#e92ef121bdec2782271a77ce487a8b8df3718ab7"
|
||||
integrity sha512-Gx+oErgq1j2jAKCR2Kbq0b3wbH0vQKqZ0wOlHxm0o56nq51Cs/DZA8oz9dMDhbHyHEGgJ86eTeVudtgMMOx3Mw==
|
||||
dependencies:
|
||||
cidr-regex "^2.0.10"
|
||||
|
||||
@@ -6143,6 +6153,13 @@ is-regex@^1.0.4, is-regex@^1.0.5:
|
||||
dependencies:
|
||||
has "^1.0.3"
|
||||
|
||||
is-regex@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.0.tgz#ece38e389e490df0dc21caea2bd596f987f767ff"
|
||||
integrity sha512-iI97M8KTWID2la5uYXlkbSDQIg4F6o1sYboZKKTDpnDQMLtUL86zxhgDet3Q2SriaYsyGqZ6Mn2SjbRKeLHdqw==
|
||||
dependencies:
|
||||
has-symbols "^1.0.1"
|
||||
|
||||
is-resolvable@^1.0.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88"
|
||||
@@ -6933,9 +6950,9 @@ levn@^0.3.0, levn@~0.3.0:
|
||||
type-check "~0.3.2"
|
||||
|
||||
libcipm@^4.0.7:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-4.0.7.tgz#76cd675c98bdaae64db88b782b01b804b6d02c8a"
|
||||
integrity sha512-fTq33otU3PNXxxCTCYCYe7V96o59v/o7bvtspmbORXpgFk+wcWrGf5x6tBgui5gCed/45/wtPomBsZBYm5KbIw==
|
||||
version "4.0.8"
|
||||
resolved "https://registry.yarnpkg.com/libcipm/-/libcipm-4.0.8.tgz#dcea4919e10dfbce420327e63901613b9141bc89"
|
||||
integrity sha512-IN3hh2yDJQtZZ5paSV4fbvJg4aHxCCg5tcZID/dSVlTuUiWktsgaldVljJv6Z5OUlYspx6xQkbR0efNodnIrOA==
|
||||
dependencies:
|
||||
bin-links "^1.1.2"
|
||||
bluebird "^3.5.1"
|
||||
@@ -6943,7 +6960,7 @@ libcipm@^4.0.7:
|
||||
find-npm-prefix "^1.0.2"
|
||||
graceful-fs "^4.1.11"
|
||||
ini "^1.3.5"
|
||||
lock-verify "^2.0.2"
|
||||
lock-verify "^2.1.0"
|
||||
mkdirp "^0.5.1"
|
||||
npm-lifecycle "^3.0.0"
|
||||
npm-logical-tree "^1.2.1"
|
||||
@@ -7053,9 +7070,9 @@ libnpmteam@^1.0.2:
|
||||
npm-registry-fetch "^4.0.0"
|
||||
|
||||
libnpx@^10.2.2:
|
||||
version "10.2.2"
|
||||
resolved "https://registry.yarnpkg.com/libnpx/-/libnpx-10.2.2.tgz#5a4171b9b92dd031463ef66a4af9f5cbd6b09572"
|
||||
integrity sha512-ujaYToga1SAX5r7FU5ShMFi88CWpY75meNZtr6RtEyv4l2ZK3+Wgvxq2IqlwWBiDZOqhumdeiocPS1aKrCMe3A==
|
||||
version "10.2.3"
|
||||
resolved "https://registry.yarnpkg.com/libnpx/-/libnpx-10.2.3.tgz#d5e01f12d383ffca9a947807ca6a8f587d38fe2c"
|
||||
integrity sha512-bCvdARu55fLQBhMfcYGF0GznF1kB2sqxq/9zKZ3652M8DDFWpVpCnpgzjzn0yWMDMez5ZGMBiX24yR11uEYZVQ==
|
||||
dependencies:
|
||||
dotenv "^5.0.1"
|
||||
npm-package-arg "^6.0.0"
|
||||
@@ -7173,6 +7190,11 @@ lockfile@^1.0.4:
|
||||
dependencies:
|
||||
signal-exit "^3.0.2"
|
||||
|
||||
lodash._baseindexof@*:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._baseindexof/-/lodash._baseindexof-3.1.0.tgz#fe52b53a1c6761e42618d654e4a25789ed61822c"
|
||||
integrity sha1-/lK1OhxnYeQmGNZU5KJXie1hgiw=
|
||||
|
||||
lodash._baseuniq@~4.6.0:
|
||||
version "4.6.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._baseuniq/-/lodash._baseuniq-4.6.0.tgz#0ebb44e456814af7905c6212fa2c9b2d51b841e8"
|
||||
@@ -7181,11 +7203,33 @@ lodash._baseuniq@~4.6.0:
|
||||
lodash._createset "~4.0.0"
|
||||
lodash._root "~3.0.0"
|
||||
|
||||
lodash._bindcallback@*:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e"
|
||||
integrity sha1-5THCdkTPi1epnhftlbNcdIeJOS4=
|
||||
|
||||
lodash._cacheindexof@*:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash._cacheindexof/-/lodash._cacheindexof-3.0.2.tgz#3dc69ac82498d2ee5e3ce56091bafd2adc7bde92"
|
||||
integrity sha1-PcaayCSY0u5ePOVgkbr9Ktx73pI=
|
||||
|
||||
lodash._createcache@*:
|
||||
version "3.1.2"
|
||||
resolved "https://registry.yarnpkg.com/lodash._createcache/-/lodash._createcache-3.1.2.tgz#56d6a064017625e79ebca6b8018e17440bdcf093"
|
||||
integrity sha1-VtagZAF2JeeevKa4AY4XRAvc8JM=
|
||||
dependencies:
|
||||
lodash._getnative "^3.0.0"
|
||||
|
||||
lodash._createset@~4.0.0:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/lodash._createset/-/lodash._createset-4.0.3.tgz#0f4659fbb09d75194fa9e2b88a6644d363c9fe26"
|
||||
integrity sha1-D0ZZ+7CddRlPqeK4imZE02PJ/iY=
|
||||
|
||||
lodash._getnative@*, lodash._getnative@^3.0.0:
|
||||
version "3.9.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
|
||||
integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=
|
||||
|
||||
lodash._reinterpolate@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz#0ccf2d89166af03b3663c796538b75ac6e114d9d"
|
||||
@@ -7241,6 +7285,11 @@ lodash.merge@^4.6.1:
|
||||
resolved "https://registry.yarnpkg.com/lodash.merge/-/lodash.merge-4.6.2.tgz#558aa53b43b661e1925a0afdfa36a9a1085fe57a"
|
||||
integrity sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==
|
||||
|
||||
lodash.restparam@*:
|
||||
version "3.6.1"
|
||||
resolved "https://registry.yarnpkg.com/lodash.restparam/-/lodash.restparam-3.6.1.tgz#936a4e309ef330a7645ed4145986c85ae5b20805"
|
||||
integrity sha1-k2pOMJ7zMKdkXtQUWYbIWuWyCAU=
|
||||
|
||||
lodash.sortby@^4.7.0:
|
||||
version "4.7.0"
|
||||
resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438"
|
||||
@@ -7448,10 +7497,10 @@ marked-terminal@^4.0.0:
|
||||
node-emoji "^1.10.0"
|
||||
supports-hyperlinks "^2.0.0"
|
||||
|
||||
marked@^0.8.0:
|
||||
version "0.8.0"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.0.tgz#ec5c0c9b93878dc52dd54be8d0e524097bd81a99"
|
||||
integrity sha512-MyUe+T/Pw4TZufHkzAfDj6HarCBWia2y27/bhuYkTaiUnfDYFnCP3KUN+9oM7Wi6JA2rymtVYbQu3spE0GCmxQ==
|
||||
marked@^1.0.0:
|
||||
version "1.2.4"
|
||||
resolved "https://registry.yarnpkg.com/marked/-/marked-1.2.4.tgz#94e99230b03496c9383b1322ac51bc17dd388a1d"
|
||||
integrity sha512-6x5TFGCTKSQBLTZtOburGxCxFEBJEGYVLwCMTBCxzvyuisGcC20UNzDSJhCr/cJ/Kmh6ulfJm10g6WWEAJ3kvg==
|
||||
|
||||
md5.js@^1.3.4:
|
||||
version "1.3.5"
|
||||
@@ -7612,7 +7661,19 @@ mime-db@1.43.0, "mime-db@>= 1.43.0 < 2":
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.43.0.tgz#0a12e0502650e473d735535050e7c8f4eb4fae58"
|
||||
integrity sha512-+5dsGEEovYbT8UY9yD7eE4XTc4UwJ1jBYlgaQQF38ENsKR3wj/8q8RFZrF9WIZpB2V1ArTVFUva8sAul1NzRzQ==
|
||||
|
||||
mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24:
|
||||
mime-db@1.44.0:
|
||||
version "1.44.0"
|
||||
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92"
|
||||
integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg==
|
||||
|
||||
mime-types@^2.1.12, mime-types@~2.1.19:
|
||||
version "2.1.27"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f"
|
||||
integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w==
|
||||
dependencies:
|
||||
mime-db "1.44.0"
|
||||
|
||||
mime-types@~2.1.17, mime-types@~2.1.24:
|
||||
version "2.1.26"
|
||||
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.26.tgz#9c921fc09b7e149a65dfdc0da4d20997200b0a06"
|
||||
integrity sha512-01paPWYgLrkqAyrlDorC1uDwl2p3qZT7yl806vW7DvDoxwXi46jsjFbg+WdwotBIk6/MbEhO/dh5aZ5sNj/dWQ==
|
||||
@@ -7673,16 +7734,16 @@ minimist-options@^3.0.1:
|
||||
arrify "^1.0.1"
|
||||
is-plain-obj "^1.1.0"
|
||||
|
||||
minimist@0.0.8:
|
||||
version "0.0.8"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
|
||||
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
|
||||
|
||||
minimist@1.2.0, minimist@^1.1.1, minimist@^1.1.3, minimist@^1.2.0:
|
||||
minimist@1.2.0, minimist@^1.1.1, minimist@^1.1.3:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284"
|
||||
integrity sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=
|
||||
|
||||
minimist@^1.2.0, minimist@^1.2.5:
|
||||
version "1.2.5"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.5.tgz#67d66014b66a6a8aaa0c083c5fd58df4e4e97602"
|
||||
integrity sha512-FM9nNUYrRBAELZQT3xeZQ7fmMOBg6nWNmJKTcgsJeaLstP/UODVpGsr5OhXhhXg6f+qtJ8uiZ+PUxkDWcgIXLw==
|
||||
|
||||
minimist@~0.0.1:
|
||||
version "0.0.10"
|
||||
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.10.tgz#de3f98543dbf96082be48ad1a0c7cda836301dcf"
|
||||
@@ -7727,13 +7788,20 @@ mixin-deep@^1.2.0:
|
||||
for-in "^1.0.2"
|
||||
is-extendable "^1.0.1"
|
||||
|
||||
mkdirp@0.5.1, "mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1:
|
||||
mkdirp@0.5.1:
|
||||
version "0.5.1"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
|
||||
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
|
||||
dependencies:
|
||||
minimist "0.0.8"
|
||||
|
||||
"mkdirp@>=0.5 0", mkdirp@^0.5.0, mkdirp@^0.5.1, mkdirp@^0.5.5, mkdirp@~0.5.0, mkdirp@~0.5.1:
|
||||
version "0.5.5"
|
||||
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.5.tgz#d91cefd62d1436ca0f41620e251288d420099def"
|
||||
integrity sha512-NKmAlESf6jMGym1++R0Ra7wvhV+wFW63FaSOFPwRahvea0gMUcGUhVeAg/0BC0wiv9ih5NYPB1Wn1UEI1/L+xQ==
|
||||
dependencies:
|
||||
minimist "^1.2.5"
|
||||
|
||||
modify-values@^1.0.0:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
|
||||
@@ -7866,18 +7934,18 @@ node-emoji@^1.10.0:
|
||||
lodash.toarray "^4.4.0"
|
||||
|
||||
node-fetch-npm@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.2.tgz#7258c9046182dca345b4208eda918daf33697ff7"
|
||||
integrity sha512-nJIxm1QmAj4v3nfCvEeCrYSoVwXyxLnaPBK5W1W5DGEJwjlKuC2VEUycGw5oxk+4zZahRrB84PUJJgEmhFTDFw==
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch-npm/-/node-fetch-npm-2.0.4.tgz#6507d0e17a9ec0be3bec516958a497cec54bf5a4"
|
||||
integrity sha512-iOuIQDWDyjhv9qSDrj9aq/klt6F9z1p2otB3AV7v3zBDcL/x+OfGsvGQZZCcMZbUf4Ujw1xGNQkjvGnVT22cKg==
|
||||
dependencies:
|
||||
encoding "^0.1.11"
|
||||
json-parse-better-errors "^1.0.0"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
node-fetch@^2.3.0:
|
||||
version "2.6.0"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.0.tgz#e633456386d4aa55863f676a7ab0daa8fdecb0fd"
|
||||
integrity sha512-8dG4H5ujfvFiqDmVu9fQ5bOHUC15JMjMY/Zumv26oOvvVJjM67KF8koCWIabKQ1GJIa9r2mMZscBq/TbdOcmNA==
|
||||
version "2.6.1"
|
||||
resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052"
|
||||
integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw==
|
||||
|
||||
node-forge@0.9.0:
|
||||
version "0.9.0"
|
||||
@@ -7902,10 +7970,10 @@ node-gyp@^3.8.0:
|
||||
tar "^2.0.0"
|
||||
which "1"
|
||||
|
||||
node-gyp@^5.0.2, node-gyp@^5.0.7:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.0.tgz#8e31260a7af4a2e2f994b0673d4e0b3866156332"
|
||||
integrity sha512-OUTryc5bt/P8zVgNUmC6xdXiDJxLMAW8cF5tLQOT9E5sOQj+UeQxnnPy74K3CLCa/SOjjBlbuzDLR8ANwA+wmw==
|
||||
node-gyp@^5.0.2, node-gyp@^5.1.0:
|
||||
version "5.1.1"
|
||||
resolved "https://registry.yarnpkg.com/node-gyp/-/node-gyp-5.1.1.tgz#eb915f7b631c937d282e33aed44cb7a025f62a3e"
|
||||
integrity sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==
|
||||
dependencies:
|
||||
env-paths "^2.2.0"
|
||||
glob "^7.1.4"
|
||||
@@ -8006,10 +8074,10 @@ node-sass@^4.12.0:
|
||||
dependencies:
|
||||
abbrev "1"
|
||||
|
||||
nopt@^4.0.1, nopt@~4.0.1:
|
||||
version "4.0.1"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.1.tgz#d0d4685afd5415193c8c7505602d0d17cd64474d"
|
||||
integrity sha1-0NRoWv1UFRk8jHUFYC0NF81kR00=
|
||||
nopt@^4.0.1, nopt@^4.0.3, nopt@~4.0.1:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/nopt/-/nopt-4.0.3.tgz#a375cad9d02fd921278d954c2254d5aa57e15e48"
|
||||
integrity sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==
|
||||
dependencies:
|
||||
abbrev "1"
|
||||
osenv "^0.1.4"
|
||||
@@ -8052,9 +8120,9 @@ normalize-url@^5.0.0:
|
||||
integrity sha512-bAEm2fx8Dq/a35Z6PIRkkBBJvR56BbEJvhpNtvCZ4W9FyORSna77fn+xtYFjqk5JpBS+fMnAOG/wFgkQBmB7hw==
|
||||
|
||||
npm-audit-report@^1.3.2:
|
||||
version "1.3.2"
|
||||
resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-1.3.2.tgz#303bc78cd9e4c226415076a4f7e528c89fc77018"
|
||||
integrity sha512-abeqS5ONyXNaZJPGAf6TOUMNdSe1Y6cpc9MLBRn+CuUoYbfdca6AxOyXVlfIv9OgKX+cacblbG5w7A6ccwoTPw==
|
||||
version "1.3.3"
|
||||
resolved "https://registry.yarnpkg.com/npm-audit-report/-/npm-audit-report-1.3.3.tgz#8226deeb253b55176ed147592a3995442f2179ed"
|
||||
integrity sha512-8nH/JjsFfAWMvn474HB9mpmMjrnKb1Hx/oTAdjv4PT9iZBvBxiZ+wtDUapHCJwLqYGQVPaAfs+vL5+5k9QndXw==
|
||||
dependencies:
|
||||
cli-table3 "^0.5.0"
|
||||
console-control-strings "^1.1.0"
|
||||
@@ -8079,9 +8147,9 @@ npm-install-checks@^3.0.2:
|
||||
semver "^2.3.0 || 3.x || 4 || 5"
|
||||
|
||||
npm-lifecycle@^3.0.0, npm-lifecycle@^3.1.4:
|
||||
version "3.1.4"
|
||||
resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.4.tgz#de6975c7d8df65f5150db110b57cce498b0b604c"
|
||||
integrity sha512-tgs1PaucZwkxECGKhC/stbEgFyc3TGh2TJcg2CDr6jbvQRdteHNhmMeljRzpe4wgFAXQADoy1cSqqi7mtiAa5A==
|
||||
version "3.1.5"
|
||||
resolved "https://registry.yarnpkg.com/npm-lifecycle/-/npm-lifecycle-3.1.5.tgz#9882d3642b8c82c815782a12e6a1bfeed0026309"
|
||||
integrity sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g==
|
||||
dependencies:
|
||||
byline "^5.0.0"
|
||||
graceful-fs "^4.1.15"
|
||||
@@ -8130,7 +8198,7 @@ npm-pick-manifest@^3.0.0, npm-pick-manifest@^3.0.2:
|
||||
npm-package-arg "^6.0.0"
|
||||
semver "^5.4.1"
|
||||
|
||||
npm-profile@^4.0.2:
|
||||
npm-profile@^4.0.2, npm-profile@^4.0.4:
|
||||
version "4.0.4"
|
||||
resolved "https://registry.yarnpkg.com/npm-profile/-/npm-profile-4.0.4.tgz#28ee94390e936df6d084263ee2061336a6a1581b"
|
||||
integrity sha512-Ta8xq8TLMpqssF0H60BXS1A90iMoM6GeKwsmravJ6wYjWwSzcYBTdyWa3DZCYqPutacBMEm7cxiOkiIeCUAHDQ==
|
||||
@@ -8139,10 +8207,10 @@ npm-profile@^4.0.2:
|
||||
figgy-pudding "^3.4.1"
|
||||
npm-registry-fetch "^4.0.0"
|
||||
|
||||
npm-registry-fetch@^4.0.0, npm-registry-fetch@^4.0.3:
|
||||
version "4.0.3"
|
||||
resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.3.tgz#3c2179e39e04f9348b1c2979545951d36bee8766"
|
||||
integrity sha512-WGvUx0lkKFhu9MbiGFuT9nG2NpfQ+4dCJwRwwtK2HK5izJEvwDxMeUyqbuMS7N/OkpVCqDorV6rO5E4V9F8lJw==
|
||||
npm-registry-fetch@^4.0.0, npm-registry-fetch@^4.0.5:
|
||||
version "4.0.5"
|
||||
resolved "https://registry.yarnpkg.com/npm-registry-fetch/-/npm-registry-fetch-4.0.5.tgz#cb87cf7f25bfb048d6c3ee19d115bebf93ea5bfa"
|
||||
integrity sha512-yQ0/U4fYpCCqmueB2g8sc+89ckQ3eXpmU4+Yi2j5o/r0WkKvE2+Y0tK3DEILAtn2UaQTkjTHxIXe2/CSdit+/Q==
|
||||
dependencies:
|
||||
JSONStream "^1.3.4"
|
||||
bluebird "^3.5.1"
|
||||
@@ -8167,14 +8235,14 @@ npm-run-path@^4.0.0:
|
||||
path-key "^3.0.0"
|
||||
|
||||
npm-user-validate@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.0.tgz#8ceca0f5cea04d4e93519ef72d0557a75122e951"
|
||||
integrity sha1-jOyg9c6gTU6TUZ73LQVXp1Ei6VE=
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/npm-user-validate/-/npm-user-validate-1.0.1.tgz#31428fc5475fe8416023f178c0ab47935ad8c561"
|
||||
integrity sha512-uQwcd/tY+h1jnEaze6cdX/LrhWhoBxfSknxentoqmIuStxUExxjWd3ULMLFPiFUrZKbOVMowH6Jq2FRWfmhcEw==
|
||||
|
||||
npm@^6.10.3:
|
||||
version "6.14.1"
|
||||
resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.1.tgz#3b80f6f1aa11a9868860dcf897665f80ab38a204"
|
||||
integrity sha512-2hi3UF7g5VL8VKm46Bx5GAW28DPb8BJZbj2uONMBMhY8XkJ56lSmHJNFcjTQr7KHZqWqiBT5BugaQEy+Y/4T2g==
|
||||
version "6.14.6"
|
||||
resolved "https://registry.yarnpkg.com/npm/-/npm-6.14.6.tgz#1a81ce1fac2bf5457dbf6342ceed503627ff228f"
|
||||
integrity sha512-axnz6iHFK6WPE0js/+mRp+4IOwpHn5tJEw5KB6FiCU764zmffrhsYHbSHi2kKqNkRBt53XasXjngZfBD3FQzrQ==
|
||||
dependencies:
|
||||
JSONStream "^1.3.5"
|
||||
abbrev "~1.1.1"
|
||||
@@ -8203,10 +8271,10 @@ npm@^6.10.3:
|
||||
fs-vacuum "~1.2.10"
|
||||
fs-write-stream-atomic "~1.0.10"
|
||||
gentle-fs "^2.3.0"
|
||||
glob "^7.1.4"
|
||||
graceful-fs "^4.2.3"
|
||||
glob "^7.1.6"
|
||||
graceful-fs "^4.2.4"
|
||||
has-unicode "~2.0.1"
|
||||
hosted-git-info "^2.8.7"
|
||||
hosted-git-info "^2.8.8"
|
||||
iferr "^1.0.2"
|
||||
infer-owner "^1.0.4"
|
||||
inflight "~1.0.6"
|
||||
@@ -8234,10 +8302,10 @@ npm@^6.10.3:
|
||||
lru-cache "^5.1.1"
|
||||
meant "~1.0.1"
|
||||
mississippi "^3.0.0"
|
||||
mkdirp "~0.5.1"
|
||||
mkdirp "^0.5.5"
|
||||
move-concurrently "^1.0.1"
|
||||
node-gyp "^5.0.7"
|
||||
nopt "~4.0.1"
|
||||
node-gyp "^5.1.0"
|
||||
nopt "^4.0.3"
|
||||
normalize-package-data "^2.5.0"
|
||||
npm-audit-report "^1.3.2"
|
||||
npm-cache-filename "~1.0.2"
|
||||
@@ -8246,8 +8314,8 @@ npm@^6.10.3:
|
||||
npm-package-arg "^6.1.1"
|
||||
npm-packlist "^1.4.8"
|
||||
npm-pick-manifest "^3.0.2"
|
||||
npm-profile "^4.0.2"
|
||||
npm-registry-fetch "^4.0.3"
|
||||
npm-profile "^4.0.4"
|
||||
npm-registry-fetch "^4.0.5"
|
||||
npm-user-validate "~1.0.0"
|
||||
npmlog "~4.1.2"
|
||||
once "~1.4.0"
|
||||
@@ -8268,7 +8336,7 @@ npm@^6.10.3:
|
||||
readdir-scoped-modules "^1.1.0"
|
||||
request "^2.88.0"
|
||||
retry "^0.12.0"
|
||||
rimraf "^2.6.3"
|
||||
rimraf "^2.7.1"
|
||||
safe-buffer "^5.1.2"
|
||||
semver "^5.7.1"
|
||||
sha "^3.0.0"
|
||||
@@ -8349,9 +8417,9 @@ object-hash@^2.0.1:
|
||||
integrity sha512-b+2AKjAf6uQlxxv8ChHdM+VT4eeX+ZSwv+pk2xIXZWbo+yxn4/En1iC+GHe/OFYa9on0AhFF2PvuAcFHoiiHaA==
|
||||
|
||||
object-inspect@^1.7.0:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.7.0.tgz#f4f6bd181ad77f006b5ece60bd0b6f398ff74a67"
|
||||
integrity sha512-a7pEHdh1xKIAgTySUGgLMx/xwDZskN1Ud6egYYN3EdRW4ZMPNEDUTF+hwy2LUC+Bl+SyLXANnwz/jyh/qutKUw==
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0"
|
||||
integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==
|
||||
|
||||
object-is@^1.0.1:
|
||||
version "1.0.2"
|
||||
@@ -8584,7 +8652,14 @@ p-limit@^1.1.0:
|
||||
dependencies:
|
||||
p-try "^1.0.0"
|
||||
|
||||
p-limit@^2.0.0, p-limit@^2.2.0:
|
||||
p-limit@^2.0.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.3.0.tgz#3dd33c647a214fdfffd835933eb086da0dc21db1"
|
||||
integrity sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==
|
||||
dependencies:
|
||||
p-try "^2.0.0"
|
||||
|
||||
p-limit@^2.2.0:
|
||||
version "2.2.2"
|
||||
resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-2.2.2.tgz#61279b67721f5287aa1c13a9a7fbbc48c9291b1e"
|
||||
integrity sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==
|
||||
@@ -9457,10 +9532,10 @@ pseudomap@^1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3"
|
||||
integrity sha1-8FKijacOYYkX7wqKw0wa5aaChrM=
|
||||
|
||||
psl@^1.1.24, psl@^1.1.28:
|
||||
version "1.7.0"
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.7.0.tgz#f1c4c47a8ef97167dea5d6bbf4816d736e884a3c"
|
||||
integrity sha512-5NsSEDv8zY70ScRnOTn7bK7eanl2MvFrOrS/R6x+dBt5g1ghnj9Zv90kO8GwT8gxcu2ANyFprnFYB85IogIJOQ==
|
||||
psl@^1.1.28:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24"
|
||||
integrity sha512-RIdOzyoavK+hA18OGGWDqUTsCLhtA7IcZ/6NCs4fFJaHBDab+pDDmDIByWFRQJq2Cd7r1OoQxBGKOaztq+hjIQ==
|
||||
|
||||
public-encrypt@^4.0.0:
|
||||
version "4.0.3"
|
||||
@@ -9504,7 +9579,7 @@ punycode@1.3.2:
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d"
|
||||
integrity sha1-llOgNvt8HuQjQvIyXM7v6jkmxI0=
|
||||
|
||||
punycode@^1.2.4, punycode@^1.4.1:
|
||||
punycode@^1.2.4:
|
||||
version "1.4.1"
|
||||
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
|
||||
integrity sha1-wNWmOycYgArY4esPpSachN1BhF4=
|
||||
@@ -9535,9 +9610,9 @@ qs@~6.5.2:
|
||||
integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==
|
||||
|
||||
query-string@^6.8.2:
|
||||
version "6.11.0"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.11.0.tgz#dc27a05733d1be66f16d0f83dfa957270f45f66d"
|
||||
integrity sha512-jS+me8X3OEGFTsF6kF+vUUMFG/d3WUCvD7bHhfZP5784nOq1pjj8yau/u86nfOncmcN6ZkSWKWkKAvv/MGxzLA==
|
||||
version "6.13.1"
|
||||
resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.1.tgz#d913ccfce3b4b3a713989fe6d39466d92e71ccad"
|
||||
integrity sha512-RfoButmcK+yCta1+FuU8REvisx1oEzhMKwhLUNcepQTPGcNMp1sIqjnfCtfnvGSQZQEhaBHvccujtWoUV3TTbA==
|
||||
dependencies:
|
||||
decode-uri-component "^0.2.0"
|
||||
split-on-first "^1.0.0"
|
||||
@@ -9753,7 +9828,7 @@ read@1, read@~1.0.1, read@~1.0.7:
|
||||
string_decoder "~1.1.1"
|
||||
util-deprecate "~1.0.1"
|
||||
|
||||
"readable-stream@2 || 3", readable-stream@^3.6.0:
|
||||
"readable-stream@2 || 3", readable-stream@^3.0.6, readable-stream@^3.1.1, readable-stream@^3.6.0:
|
||||
version "3.6.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
|
||||
integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
|
||||
@@ -9762,15 +9837,6 @@ read@1, read@~1.0.1, read@~1.0.7:
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-stream@^3.0.6, readable-stream@^3.1.1:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.5.0.tgz#465d70e6d1087f6162d079cd0b5db7fbebfd1606"
|
||||
integrity sha512-gSz026xs2LfxBPudDuI41V1lka8cxg64E66SGe78zJlsUofOg/yqwezdIcdfwik6B4h8LFmWPA9ef9X3FiNFLA==
|
||||
dependencies:
|
||||
inherits "^2.0.3"
|
||||
string_decoder "^1.1.1"
|
||||
util-deprecate "^1.0.1"
|
||||
|
||||
readable-stream@~1.1.10:
|
||||
version "1.1.14"
|
||||
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9"
|
||||
@@ -9998,9 +10064,9 @@ request-promise-native@^1.0.5:
|
||||
tough-cookie "^2.3.3"
|
||||
|
||||
request@^2.87.0, request@^2.88.0:
|
||||
version "2.88.0"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef"
|
||||
integrity sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==
|
||||
version "2.88.2"
|
||||
resolved "https://registry.yarnpkg.com/request/-/request-2.88.2.tgz#d73c918731cb5a87da047e207234146f664d12b3"
|
||||
integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==
|
||||
dependencies:
|
||||
aws-sign2 "~0.7.0"
|
||||
aws4 "^1.8.0"
|
||||
@@ -10009,7 +10075,7 @@ request@^2.87.0, request@^2.88.0:
|
||||
extend "~3.0.2"
|
||||
forever-agent "~0.6.1"
|
||||
form-data "~2.3.2"
|
||||
har-validator "~5.1.0"
|
||||
har-validator "~5.1.3"
|
||||
http-signature "~1.2.0"
|
||||
is-typedarray "~1.0.0"
|
||||
isstream "~0.1.2"
|
||||
@@ -10019,7 +10085,7 @@ request@^2.87.0, request@^2.88.0:
|
||||
performance-now "^2.1.0"
|
||||
qs "~6.5.2"
|
||||
safe-buffer "^5.1.2"
|
||||
tough-cookie "~2.4.3"
|
||||
tough-cookie "~2.5.0"
|
||||
tunnel-agent "^0.6.0"
|
||||
uuid "^3.3.2"
|
||||
|
||||
@@ -10090,13 +10156,20 @@ resolve@1.1.7:
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b"
|
||||
integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs=
|
||||
|
||||
resolve@^1.1.6, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.2.0, resolve@^1.3.2, resolve@^1.8.1:
|
||||
resolve@^1.1.6, resolve@^1.12.0, resolve@^1.2.0, resolve@^1.3.2, resolve@^1.8.1:
|
||||
version "1.15.1"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
|
||||
integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==
|
||||
dependencies:
|
||||
path-parse "^1.0.6"
|
||||
|
||||
resolve@^1.10.0:
|
||||
version "1.17.0"
|
||||
resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444"
|
||||
integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w==
|
||||
dependencies:
|
||||
path-parse "^1.0.6"
|
||||
|
||||
restore-cursor@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"
|
||||
@@ -10155,7 +10228,7 @@ right-pad@^1.0.1:
|
||||
resolved "https://registry.yarnpkg.com/right-pad/-/right-pad-1.0.1.tgz#8ca08c2cbb5b55e74dafa96bf7fd1a27d568c8d0"
|
||||
integrity sha1-jKCMLLtbVedNr6lr9/0aJ9VoyNA=
|
||||
|
||||
rimraf@2, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3:
|
||||
rimraf@2, rimraf@^2.5.2, rimraf@^2.5.4, rimraf@^2.6.2, rimraf@^2.6.3, rimraf@^2.7.1:
|
||||
version "2.7.1"
|
||||
resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.7.1.tgz#35797f13a7fdadc566142c29d4f07ccad483e3ec"
|
||||
integrity sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==
|
||||
@@ -10214,9 +10287,9 @@ safe-buffer@5.1.2, safe-buffer@~5.1.0, safe-buffer@~5.1.1:
|
||||
integrity sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==
|
||||
|
||||
safe-buffer@>=5.1.0, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, safe-buffer@^5.1.2, safe-buffer@^5.2.0, safe-buffer@~5.2.0:
|
||||
version "5.2.0"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
|
||||
integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
|
||||
version "5.2.1"
|
||||
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
|
||||
integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
|
||||
|
||||
safe-regex@^1.1.0:
|
||||
version "1.1.0"
|
||||
@@ -10309,9 +10382,9 @@ selfsigned@^1.10.7:
|
||||
node-forge "0.9.0"
|
||||
|
||||
semantic-release@^17.0.4:
|
||||
version "17.0.4"
|
||||
resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-17.0.4.tgz#4ca739b2bf80f8ce5e49b05f12c15f49ca233d6d"
|
||||
integrity sha512-5y9QRSrZtdvACmlpX5DvEVsvFuKRDUVn7JVJFxPVLGrGofDf1d0M/+hA1wFmCjiJZ+VCY8bYaSqVqF14KCF9rw==
|
||||
version "17.2.3"
|
||||
resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-17.2.3.tgz#11f10b851d4e75b1015b17515c433049b3df994c"
|
||||
integrity sha512-MY1MlowGQrkOR7+leOD8ICkVOC6i1szbwDODdbJ0UdshtMx8Ms0bhpRQmEEliqYKEb5PLv/dqs6zKKuHT7UxTg==
|
||||
dependencies:
|
||||
"@semantic-release/commit-analyzer" "^8.0.0"
|
||||
"@semantic-release/error" "^2.2.0"
|
||||
@@ -10330,14 +10403,14 @@ semantic-release@^17.0.4:
|
||||
hook-std "^2.0.0"
|
||||
hosted-git-info "^3.0.0"
|
||||
lodash "^4.17.15"
|
||||
marked "^0.8.0"
|
||||
marked "^1.0.0"
|
||||
marked-terminal "^4.0.0"
|
||||
micromatch "^4.0.2"
|
||||
p-each-series "^2.1.0"
|
||||
p-reduce "^2.0.0"
|
||||
read-pkg-up "^7.0.0"
|
||||
resolve-from "^5.0.0"
|
||||
semver "^7.1.1"
|
||||
semver "^7.3.2"
|
||||
semver-diff "^3.1.1"
|
||||
signale "^1.2.1"
|
||||
yargs "^15.0.1"
|
||||
@@ -10376,10 +10449,10 @@ semver@^6.0.0, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
|
||||
semver@^7.1.1, semver@^7.1.2:
|
||||
version "7.1.3"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.1.3.tgz#e4345ce73071c53f336445cfc19efb1c311df2a6"
|
||||
integrity sha512-ekM0zfiA9SCBlsKa2X1hxyxiI4L3B6EbVJkkdgQXnSEEaHlGdvyodMruTiulSRWMMB4NeIuYNMC9rTKTz97GxA==
|
||||
semver@^7.1.2, semver@^7.3.2:
|
||||
version "7.3.2"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
||||
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
|
||||
|
||||
semver@~5.3.0:
|
||||
version "5.3.0"
|
||||
@@ -10537,9 +10610,9 @@ sigmund@^1.0.1:
|
||||
integrity sha1-P/IfGYytIXX587eBhT/ZTQ0ZtZA=
|
||||
|
||||
signal-exit@^3.0.0, signal-exit@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d"
|
||||
integrity sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=
|
||||
version "3.0.3"
|
||||
resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.3.tgz#a1410c2edd8f077b08b4e253c8eacfcaf057461c"
|
||||
integrity sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==
|
||||
|
||||
signale@^1.2.1:
|
||||
version "1.4.0"
|
||||
@@ -10734,22 +10807,22 @@ spawn-error-forwarder@~1.0.0:
|
||||
integrity sha1-Gv2Uc46ZmwNG17n8NzvlXgdXcCk=
|
||||
|
||||
spdx-correct@^3.0.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.0.tgz#fb83e504445268f154b074e218c87c003cd31df4"
|
||||
integrity sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==
|
||||
version "3.1.1"
|
||||
resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-3.1.1.tgz#dece81ac9c1e6713e5f7d1b6f17d468fa53d89a9"
|
||||
integrity sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==
|
||||
dependencies:
|
||||
spdx-expression-parse "^3.0.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
|
||||
spdx-exceptions@^2.1.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz#2ea450aee74f2a89bfb94519c07fcd6f41322977"
|
||||
integrity sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz#3f28ce1a77a00372683eade4a433183527a2163d"
|
||||
integrity sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==
|
||||
|
||||
spdx-expression-parse@^3.0.0:
|
||||
version "3.0.0"
|
||||
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz#99e119b7a5da00e05491c9fa338b7904823b41d0"
|
||||
integrity sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz#cf70f50482eefdc98e3ce0a6833e4a53ceeba679"
|
||||
integrity sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==
|
||||
dependencies:
|
||||
spdx-exceptions "^2.1.0"
|
||||
spdx-license-ids "^3.0.0"
|
||||
@@ -10973,6 +11046,14 @@ string-width@^4.1.0, string-width@^4.2.0:
|
||||
is-fullwidth-code-point "^3.0.0"
|
||||
strip-ansi "^6.0.0"
|
||||
|
||||
string.prototype.trimend@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimend/-/string.prototype.trimend-1.0.1.tgz#85812a6b847ac002270f5808146064c995fb6913"
|
||||
integrity sha512-LRPxFUaTtpqYsTeNKaFOw3R4bxIzWOnbQ837QfBylo8jIxtcbK/A/sMV7Q+OAV/vWo+7s25pOE10KYSjaSO06g==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.17.5"
|
||||
|
||||
string.prototype.trimleft@^2.1.1:
|
||||
version "2.1.1"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimleft/-/string.prototype.trimleft-2.1.1.tgz#9bdb8ac6abd6d602b17a4ed321870d2f8dcefc74"
|
||||
@@ -10989,6 +11070,14 @@ string.prototype.trimright@^2.1.1:
|
||||
define-properties "^1.1.3"
|
||||
function-bind "^1.1.1"
|
||||
|
||||
string.prototype.trimstart@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/string.prototype.trimstart/-/string.prototype.trimstart-1.0.1.tgz#14af6d9f34b053f7cfc89b72f8f2ee14b9039a54"
|
||||
integrity sha512-XxZn+QpvrBI1FOcg6dIpxUPgWCPuNXvMD72aaRaUQv1eD4e/Qy8i/hFTe0BUmD60p/QA6bh1avmuPTfNjqVWRw==
|
||||
dependencies:
|
||||
define-properties "^1.1.3"
|
||||
es-abstract "^1.17.5"
|
||||
|
||||
string_decoder@^1.0.0, string_decoder@^1.1.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
|
||||
@@ -11396,7 +11485,7 @@ toposort@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/toposort/-/toposort-1.0.7.tgz#2e68442d9f64ec720b8cc89e6443ac6caa950029"
|
||||
integrity sha1-LmhELZ9k7HILjMieZEOsbKqVACk=
|
||||
|
||||
tough-cookie@^2.3.3, tough-cookie@^2.3.4:
|
||||
tough-cookie@^2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.5.0:
|
||||
version "2.5.0"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.5.0.tgz#cd9fb2a0aa1d5a12b473bd9fb96fa3dcff65ade2"
|
||||
integrity sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==
|
||||
@@ -11404,14 +11493,6 @@ tough-cookie@^2.3.3, tough-cookie@^2.3.4:
|
||||
psl "^1.1.28"
|
||||
punycode "^2.1.1"
|
||||
|
||||
tough-cookie@~2.4.3:
|
||||
version "2.4.3"
|
||||
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781"
|
||||
integrity sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==
|
||||
dependencies:
|
||||
psl "^1.1.24"
|
||||
punycode "^1.4.1"
|
||||
|
||||
tr46@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09"
|
||||
@@ -12138,9 +12219,9 @@ websocket-driver@>=0.5.1:
|
||||
websocket-extensions ">=0.1.1"
|
||||
|
||||
websocket-extensions@>=0.1.1:
|
||||
version "0.1.3"
|
||||
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29"
|
||||
integrity sha512-nqHUnMXmBzT0w570r2JpJxfiSD1IzoI+HGVdd3aZ0yNi3ngvQ4jv1dtHt5VGxfI2yj5yqImPhOK4vmIh2xMbGg==
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.4.tgz#7f8473bc839dfd87608adb95d7eb075211578a42"
|
||||
integrity sha512-OqedPIGOfsDlo31UNwYbCFMSaO9m9G/0faIHj5/dZFDMFqPTcx6UwqyOy3COEaEOg/9VsGIpdqn62W5KhoKSpg==
|
||||
|
||||
whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3:
|
||||
version "1.0.5"
|
||||
|
||||
Reference in New Issue
Block a user