2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-06-13 08:32:26 +03:00
This commit is contained in:
Jeff Sagal
2022-07-26 22:04:12 -07:00
parent 98c278b2bb
commit 6d59e6fd02
122 changed files with 6151 additions and 9892 deletions
+2
View File
@@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto
+8
View File
@@ -0,0 +1,8 @@
node_modules
*.log*
.nuxt
.nitro
.cache
.output
.env
dist
@@ -1,17 +0,0 @@
<template>
<v-select>
<template v-slot:no-options="{ search, searching }">
<template v-if="searching">
No results found for <em>{{ search }}</em
>.
</template>
<em v-else style="opacity: 0.5">Start typing to search for a country.</em>
</template>
</v-select>
</template>
<script>
export default {
name: 'BetterNoOptions',
}
</script>
@@ -1,21 +0,0 @@
<template>
<div>
<v-select
v-model="selected"
placeholder="choose a country"
:components="{ Deselect }"
:options="['Canada', 'United States']"
/>
</div>
</template>
<script>
export default {
data: () => ({
selected: 'Canada',
Deselect: {
render: (createElement) => createElement('span', '❌'),
},
}),
}
</script>
-30
View File
@@ -1,30 +0,0 @@
<template>
<p
:data-height="height"
data-theme-id="32252"
:data-slug-hash="url"
data-default-tab="result"
data-user="sagalbot"
class="codepen"
></p>
</template>
<script>
import mountCodePen from '../utils/codePen'
export default {
props: {
url: {
type: String,
required: true,
},
height: {
type: [String, Number],
default: 250,
},
},
mounted() {
mountCodePen()
},
}
</script>
@@ -1,64 +0,0 @@
<template>
<ul>
<li
v-for="{ login, avatar_url, html_url, contributions } in contributors"
:key="login"
>
<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>
@@ -1,16 +0,0 @@
<template>
<v-select :options="options"></v-select>
</template>
<script>
import countryCodes from '../data/countryCodes'
export default {
name: 'CountrySelect',
data: () => ({
options: countryCodes,
}),
}
</script>
<style scoped></style>
@@ -1,26 +0,0 @@
<template>
<div>
<v-select
class="style-chooser"
placeholder="Choose a Styling Option"
:options="['Components', 'CSS / Variables', 'Slots']"
/>
</div>
</template>
<style>
.style-chooser .vs__search::placeholder,
.style-chooser .vs__dropdown-toggle,
.style-chooser .vs__dropdown-menu {
background: #dfe5fb;
border: none;
color: #394066;
text-transform: lowercase;
font-variant: small-caps;
}
.style-chooser .vs__clear,
.style-chooser .vs__open-indicator {
fill: #394066;
}
</style>
@@ -1,31 +0,0 @@
<template>
<div style="background: #282c34; padding: 1rem; border-radius: 0.3rem">
<v-select :options="countries" />
</div>
</template>
<script>
import countries from '../data/countries.js'
export default {
data: () => ({ countries }),
}
</script>
<style scoped>
>>> {
--vs-controls-color: #664cc3;
--vs-border-color: #664cc3;
--vs-dropdown-bg: #282c34;
--vs-dropdown-color: #cc99cd;
--vs-dropdown-option-color: #cc99cd;
--vs-selected-bg: #664cc3;
--vs-selected-color: #eeeeee;
--vs-search-input-color: #eeeeee;
--vs-dropdown-option--active-bg: #664cc3;
--vs-dropdown-option--active-color: #eeeeee;
}
</style>
@@ -1,19 +0,0 @@
<template>
<v-select
:options="['Vue.js', 'React', 'Angular']"
:components="{ Deselect, OpenIndicator }"
/>
</template>
<script>
export default {
data: () => ({
Deselect: {
render: (createElement) => createElement('span', '❌'),
},
OpenIndicator: {
render: (createElement) => createElement('span', '🔽'),
},
}),
}
</script>
@@ -1,26 +0,0 @@
<template>
<v-select
taggable
multiple
no-drop
:map-keydown="handlers"
placeholder="enter an email"
/>
</template>
<script>
export default {
name: 'CustomHandlers',
methods: {
handlers: (map, vm) => ({
...map,
50: (e) => {
e.preventDefault()
if (e.key === '@' && vm.search.length > 0) {
vm.search = `${vm.search}@gmail.com`
}
},
}),
},
}
</script>
-35
View File
@@ -1,35 +0,0 @@
<template>
<v-select
:filter="fuseSearch"
:options="books"
:get-option-label="(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>
@@ -1,74 +0,0 @@
<template>
<v-select
:options="paginated"
:filterable="false"
@open="onOpen"
@close="onClose"
@search="(query) => (search = query)"
>
<template #list-footer>
<li v-show="hasNextPage" ref="load" class="loader">
Loading more options...
</li>
</template>
</v-select>
</template>
<script>
import countries from '../data/countries'
export default {
name: 'InfiniteScroll',
data: () => ({
observer: null,
limit: 10,
search: '',
}),
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
},
},
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)
},
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>
@@ -1,21 +0,0 @@
<template>
<v-select
v-model="selected"
multiple
placeholder="Choose up to 3 books!"
label="title"
:options="books"
:selectable="() => selected.length < 3"
/>
</template>
<script>
import books from '../data/books'
export default {
data() {
return { selected: [] }
},
computed: {
books: () => books,
},
}
</script>
@@ -1,46 +0,0 @@
<template>
<table>
<tr>
<th>Name</th>
<th>Country</th>
</tr>
<tr v-for="person in people" :key="person.name">
<td>{{ person.name }}</td>
<td>
<v-select
:options="options"
:value="person.country"
@input="(country) => updateCountry(person, country)"
/>
</td>
</tr>
</table>
</template>
<script>
import countries from '../data/countries'
export default {
data: () => ({
people: [
{ name: 'John', country: '' },
{ name: 'Jane', country: '' },
],
}),
computed: {
options: () => countries,
},
methods: {
updateCountry(person, country) {
person.country = country
},
},
}
</script>
<style scoped>
table {
display: table;
width: 100%;
}
</style>
@@ -1,21 +0,0 @@
<template>
<div>
<v-select
v-model="selected"
multiple
:options="['Canada', 'United States']"
:components="{ Deselect }"
/>
</div>
</template>
<script>
export default {
data: () => ({
selected: ['Canada'],
Deselect: {
render: (createElement) => createElement('span', '❌'),
},
}),
}
</script>
@@ -1,18 +0,0 @@
<template>
<div>
<v-select
:options="['Canada', 'United States']"
:components="{ OpenIndicator }"
/>
</div>
</template>
<script>
export default {
data: () => ({
OpenIndicator: {
render: (createElement) => createElement('span', '🔽'),
},
}),
}
</script>
@@ -1,29 +0,0 @@
<template>
<v-select
v-model="country"
:options="countries"
:dropdown-should-open="dropdownShouldOpen"
/>
</template>
<script>
import countries from '../data/countries.js'
export default {
data() {
return {
countries,
country: null,
}
},
methods: {
dropdownShouldOpen(VueSelect) {
if (this.country !== null) {
return VueSelect.open
}
return VueSelect.search.length !== 0 && VueSelect.open
},
},
}
</script>
-65
View File
@@ -1,65 +0,0 @@
<template>
<v-select
:options="paginated"
:filterable="false"
@search="(query) => (search = query)"
>
<li slot="list-footer" class="pagination">
<button :disabled="!hasPrevPage" @click="offset -= limit">Prev</button>
<button :disabled="!hasNextPage" @click="offset += limit">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.toLocaleLowerCase().includes(this.search.toLocaleLowerCase())
)
},
paginated() {
return this.filtered.slice(this.offset, this.limit + this.offset)
},
hasNextPage() {
const nextOffset = this.offset + this.limit
return Boolean(
this.filtered.slice(nextOffset, this.limit + nextOffset).length
)
},
hasPrevPage() {
const prevOffset = this.offset - this.limit
return Boolean(
this.filtered.slice(prevOffset, this.limit + prevOffset).length
)
},
},
methods: {
onSearch(query) {
this.search = query
this.offset = 0
},
},
}
</script>
<style scoped>
.pagination {
display: flex;
margin: 0.25rem 0.25rem 0;
}
.pagination button {
flex-grow: 1;
}
.pagination button:hover {
cursor: pointer;
}
</style>
@@ -1,92 +0,0 @@
<template>
<div>
<v-select
:options="countries"
append-to-body
:calculate-position="withPopper"
/>
<label for="position" style="display: block; margin: 1rem 0">
<input
id="position"
v-model="placement"
type="checkbox"
true-value="top"
false-value="bottom"
/>
Position dropdown above
</label>
</div>
</template>
<script>
import countries from '../data/countries'
import { createPopper } from '@popperjs/core'
export default {
data: () => ({ countries, placement: 'top' }),
methods: {
withPopper(dropdownList, component, { width }) {
/**
* We need to explicitly define the dropdown width since
* it is usually inherited from the parent with CSS.
*/
dropdownList.style.width = width
/**
* Here we position the dropdownList relative to the $refs.toggle Element.
*
* The 'offset' modifier aligns the dropdown so that the $refs.toggle and
* the dropdownList overlap by 1 pixel.
*
* The 'toggleClass' modifier adds a 'drop-up' class to the Vue Select
* wrapper so that we can set some styles for when the dropdown is placed
* above.
*/
const popper = createPopper(component.$refs.toggle, dropdownList, {
placement: this.placement,
modifiers: [
{
name: 'offset',
options: {
offset: [0, -1],
},
},
{
name: 'toggleClass',
enabled: true,
phase: 'write',
fn({ state }) {
component.$el.classList.toggle(
'drop-up',
state.placement === 'top'
)
},
},
],
})
/**
* 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()
},
},
}
</script>
<style>
.v-select.drop-up.vs--open .vs__dropdown-toggle {
border-radius: 0 0 4px 4px;
border-top-color: transparent;
border-bottom-color: rgba(60, 60, 60, 0.26);
}
[data-popper-placement='top'] {
border-radius: 4px 4px 0 0;
border-top-style: solid;
border-bottom-style: none;
box-shadow: 0 -3px 6px rgba(0, 0, 0, 0.15);
}
</style>
@@ -1,20 +0,0 @@
<template>
<v-select
v-model="selected"
:reduce="(option) => option.id"
:options="[
{ label: 'One', id: 1 },
{ label: 'Two', id: 2 },
]"
/>
</template>
<script>
export default {
data() {
return {
selected: 3,
}
},
}
</script>
@@ -1,61 +0,0 @@
<template>
<div class="flex">
<div>
<v-select
v-model="selected"
label="country"
:reduce="(opt) => opt.meta.id"
:options="options"
/>
</div>
<div>
<pre><code>v-model value: {{ selected || 'null' }}</code></pre>
</div>
</div>
</template>
<script>
export default {
name: 'ReducerNestedValue',
data: () => ({
selected: null,
options: [
{
country: 'canada',
meta: {
id: '1',
code: 'ca',
},
},
],
}),
}
</script>
<style scoped>
.flex {
margin-bottom: 2rem;
border: 1px solid #eaecef;
/*padding: 1rem;*/
display: flex;
justify-content: center;
align-items: center;
}
.flex > div {
flex-grow: 1;
width: 50%;
padding: 0 1rem;
}
pre {
margin: 0;
background: #fff;
}
code {
color: #635762 !important;
color: #5b2d2d !important;
/*color: #7ec699 !important;*/
}
</style>
-375
View File
@@ -1,375 +0,0 @@
<template>
<div id="sandbox-wrap">
<div id="config">
<div v-if="!hideHelp" class="list-item">
<p>
Use the controls below to adjust the props used by the vue-select
components.
</p>
<p>
The API provides more props than are shown here, these are some
commonly adjusted settings.
</p>
</div>
<h5 class="list-item">Basic Features</h5>
<div class="list-item">
<label for="multiple">
<input
id="multiple"
v-model="configuration.multiple"
type="checkbox"
/>
<code
>:multiple="{{ configuration.multiple ? 'true' : 'false' }}"</code
>
</label>
</div>
<div class="list-item">
<label for="disabled">
<input
id="disabled"
v-model="configuration.disabled"
type="checkbox"
/>
<code
>:disabled="{{ configuration.disabled ? 'true' : 'false' }}"</code
>
</label>
</div>
<div class="list-item">
<label for="clearable">
<input
id="clearable"
v-model="configuration.clearable"
type="checkbox"
/>
<code
>:clearable="{{ configuration.clearable ? 'true' : 'false' }}"</code
>
</label>
</div>
<div class="list-item">
<label for="searchable">
<input
id="searchable"
v-model="configuration.searchable"
type="checkbox"
/>
<code
>:searchable="{{
configuration.searchable ? 'true' : 'false'
}}"</code
>
</label>
</div>
<div class="list-item">
<label for="filterable">
<input
id="filterable"
v-model="configuration.filterable"
type="checkbox"
/>
<code
>:filterable="{{
configuration.searchable ? 'true' : 'false'
}}"</code
>
</label>
</div>
<h5 class="list-item">Tagging</h5>
<div class="list-item">
<label for="taggable">
<input
id="taggable"
v-model="configuration.taggable"
type="checkbox"
/>
<code
>:taggable="{{ configuration.taggable ? 'true' : 'false' }}"</code
>
</label>
</div>
<div class="list-item">
<label for="noDrop">
<input id="noDrop" v-model="configuration.noDrop" type="checkbox" />
<code>:no-drop="{{ configuration.noDrop ? 'true' : 'false' }}"</code>
</label>
</div>
<div class="list-item">
<label for="pushTags">
<input
id="pushTags"
v-model="configuration.pushTags"
type="checkbox"
/>
<code
>:push-tags="{{ configuration.pushTags ? 'true' : 'false' }}"</code
>
</label>
</div>
<h5 class="list-item">UX</h5>
<div class="list-item">
<label for="selectOnTab">
<input
id="selectOnTab"
v-model="configuration.selectOnTab"
type="checkbox"
/>
<code
>:select-on-tab="{{
configuration.selectOnTab ? 'true' : 'false'
}}"</code
>
</label>
</div>
<div class="list-item">
<label for="closeOnSelect">
<input
id="closeOnSelect"
v-model="configuration.closeOnSelect"
type="checkbox"
/>
<code
>:close-on-select="{{
configuration.closeOnSelect ? 'true' : 'false'
}}"</code
>
</label>
</div>
<h5 class="list-item">Localization / i18n</h5>
<div class="list-item">
<label for="rtl">
<input
id="rtl"
v-model="configuration.dir"
type="radio"
value="rtl"
/>
<code>dir="rtl"</code>
</label>
<label for="ltr">
<input
id="ltr"
v-model="configuration.dir"
type="radio"
value="ltr"
/>
<code>dir="ltr"</code>
</label>
</div>
</div>
<div id="sandbox">
<slot v-bind="configuration">
<div class="example">
<v-select
v-bind="configuration"
placeholder="country objects"
></v-select>
</div>
<div class="example">
<v-select
v-bind="configuration"
placeholder="country objects, using option scoped slots"
>
<template slot="selected-option" slot-scope="{ label, value }">
{{ label }} -- {{ value }}
</template>
<template slot="option" slot-scope="{ label, value }">
{{ label }} ({{ value }})
</template>
</v-select>
</div>
<div class="example">
<v-select
v-bind="configuration"
:options="['cat', 'dog', 'bear']"
placeholder="string options, option slots"
>
<template slot="selected-option" slot-scope="{ label }">
{{ label }}
</template>
<template slot="option" slot-scope="{ label }">
{{ label }}
</template>
</v-select>
</div>
<div class="example">
<v-select
v-bind="configuration"
:options="[1, 5, 10]"
placeholder="options=[1,5,10]"
></v-select>
</div>
<div class="example">
<v-select
v-bind="configuration"
label="title"
:options="optionDataSets.books"
:filter="fuseSearch"
placeholder="advanced filtering w/ fuse.js + scoped slots"
>
<template slot="option" slot-scope="option">
<strong>{{ option.title }}</strong
><br />
<em>{{
`${option.author.firstName} ${option.author.lastName}`
}}</em>
</template>
</v-select>
</div>
<div class="example">
<v-select
v-bind="configuration"
placeholder="search github repositories.."
label="full_name"
:options="ajaxRes"
@search="search"
>
</v-select>
</div>
<div class="example">
<v-select
v-bind="configuration"
:options="[]"
placeholder="options=[]"
></v-select>
</div>
</slot>
</div>
</div>
</template>
<script>
import Fuse from 'fuse.js'
import debounce from 'lodash/debounce'
import vSelect from '../../../src/components/Select.vue'
import countries from '../data/countryCodes'
import books from '../data/books'
const defaultConfig = () => ({
options: countries,
multiple: false,
dir: 'ltr',
clearable: true,
searchable: true,
filterable: true,
noDrop: false,
closeOnSelect: true,
disabled: false,
selectOntab: false,
placeholder: 'Select a Country...',
})
export default {
components: { vSelect },
props: {
hideHelp: {
type: Boolean,
default: false,
},
},
data() {
return {
configuration: defaultConfig(),
value: null,
ajaxRes: [],
people: [],
optionDataSet: 'countries',
optionDataSets: {
countries,
books,
},
}
},
methods: {
search(search, loading) {
loading(true)
this.getRepositories(search, loading, this)
},
searchPeople(search, loading) {
loading(true)
this.getPeople(loading, this)
},
getPeople: debounce((loading, vm) => {
vm.$http.get(`https://reqres.in/api/users?per_page=10`).then((res) => {
vm.people = res.data.data
loading(false)
})
}, 250),
getRepositories: debounce((search, loading, vm) => {
vm.$http
.get(`https://api.github.com/search/repositories?q=${search}`)
.then((res) => {
vm.ajaxRes = res.data.items
loading(false)
})
}, 250),
},
}
</script>
<style scoped>
#sandbox-wrap {
min-height: 100%;
display: grid;
grid-template-columns: auto 75%;
grid-template-rows: auto;
grid-template-areas: 'sidebar component';
}
#config {
grid-area: sidebar;
border-right: 1px solid #eaecef;
display: flex;
flex-direction: column;
justify-content: center;
}
#sandbox {
grid-area: component;
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
}
.list-item {
margin-top: 0;
margin-bottom: 1rem;
padding: 1rem 1rem 0;
}
.list-item:not(:first-child) {
border-top: 1px solid #eaecef;
}
.example {
margin-bottom: 2rem;
}
.v-select {
width: 25em;
}
</style>
-9
View File
@@ -1,9 +0,0 @@
<template>
<v-select append-to-body>
<template #footer>
<div style="opacity: 0.8">
Bottom of the component, in the footer slot!
</div>
</template>
</v-select>
</template>
-7
View File
@@ -1,7 +0,0 @@
<template>
<v-select>
<template #header>
<div style="opacity: 0.8">Top of the component, in the header slot!</div>
</template>
</v-select>
</template>
@@ -1,7 +0,0 @@
<template>
<v-select>
<template #list-footer>
<li style="text-align: center">Bottom of the list!</li>
</template>
</v-select>
</template>
@@ -1,7 +0,0 @@
<template>
<v-select>
<template #list-header>
<li style="text-align: center">Top of the list!</li>
</template>
</v-select>
</template>
@@ -1,8 +0,0 @@
<template>
<v-select>
<!-- eslint-disable-next-line vue/no-unused-vars -->
<template #no-options="{ search, searching, loading }">
This is the no options slot.
</template>
</v-select>
</template>
@@ -1,7 +0,0 @@
<template>
<v-select>
<template #open-indicator="{ attributes }">
<span v-bind="attributes">🔽</span>
</template>
</v-select>
</template>
-24
View File
@@ -1,24 +0,0 @@
<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>
-12
View File
@@ -1,12 +0,0 @@
<template>
<v-select>
<template #search="{ attributes, events }">
<input
maxlength="1"
class="vs__search"
v-bind="attributes"
v-on="events"
/>
</template>
</v-select>
</template>
@@ -1,28 +0,0 @@
<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: 0.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>
@@ -1,26 +0,0 @@
<template>
<!-- eslint-disable vue/no-unused-vars -->
<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>
-13
View File
@@ -1,13 +0,0 @@
<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>
@@ -1,25 +0,0 @@
<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>
-150
View File
@@ -1,150 +0,0 @@
<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>
-56
View File
@@ -1,56 +0,0 @@
<template>
<ul>
<li v-for="{ createdAt, login, avatarUrl } in sponsors" :key="login">
<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>
-4
View File
@@ -1,4 +0,0 @@
<template>
<!-- tag on 188/comma & 13/return -->
<v-select no-drop taggable multiple :select-on-key-codes="[188, 13]" />
</template>
@@ -1,16 +0,0 @@
<template>
<v-select
placeholder="Choose a book to read"
label="title"
:options="books"
:selectable="(option) => !option.author.lastName.includes('Woodhouse')"
/>
</template>
<script>
import books from '../data/books'
export default {
computed: {
books: () => books,
},
}
</script>
@@ -1,51 +0,0 @@
<template>
<form @submit.stop="onSubmit">
<v-select v-model="selected" :options="books" label="title">
<template #search="{ attributes, events }">
<input
:required="!selected"
class="vs__search"
v-bind="attributes"
v-on="events"
/>
</template>
</v-select>
<input type="submit" />
</form>
</template>
<script>
import books from '../data/books'
export default {
data: () => ({
books,
selected: null,
}),
methods: {
onSubmit() {
alert('Submitted!')
},
},
}
</script>
<style scoped>
form {
display: flex;
align-items: stretch;
}
.v-select {
width: 75%;
}
input[type='submit'] {
margin-left: 1rem;
background: #44ae7d;
border: none;
border-radius: 3px;
color: #fff;
width: 20%;
}
</style>
-20
View File
@@ -1,20 +0,0 @@
const { description } = require('./config/meta')
const head = require('./config/head')
const plugins = require('./config/plugins')
const themeConfig = require('./config/themeConfig')
const { resolve } = require('path')
module.exports = {
title: 'Vue Select',
description,
head,
plugins,
themeConfig,
configureWebpack: {
resolve: {
alias: {
'@': resolve(__dirname, '../../src'),
},
},
},
}
-67
View File
@@ -1,67 +0,0 @@
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&amp;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
-1
View File
@@ -1 +0,0 @@
module.exports = process.env.hasOwnProperty('DEPLOY_PREVIEW')
-7
View File
@@ -1,7 +0,0 @@
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',
}
-22
View File
@@ -1,22 +0,0 @@
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'),
]
-77
View File
@@ -1,77 +0,0 @@
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/opening', 'Dropdown Opening'],
['guide/filtering', 'Option Filtering'],
],
},
{
title: 'API',
collapsable: false,
children: [
['api/props', 'Props'],
['api/slots', 'Slots'],
['api/events', 'Events'],
],
},
],
},
}
-164
View File
@@ -1,164 +0,0 @@
/* eslint-disable */
export default [
{
title: "Old Man's War",
author: {
firstName: "John",
lastName: "Scalzi"
}
},
{
title: "The Lock Artist",
author: {
firstName: "Steve",
lastName: "Hamilton"
}
},
{
title: "HTML5",
author: {
firstName: "Remy",
lastName: "Sharp"
}
},
{
title: "Right Ho Jeeves",
author: {
firstName: "P.D",
lastName: "Woodhouse"
}
},
{
title: "The Code of the Wooster",
author: {
firstName: "P.D",
lastName: "Woodhouse"
}
},
{
title: "Thank You Jeeves",
author: {
firstName: "P.D",
lastName: "Woodhouse"
}
},
{
title: "The DaVinci Code",
author: {
firstName: "Dan",
lastName: "Brown"
}
},
{
title: "Angels & Demons",
author: {
firstName: "Dan",
lastName: "Brown"
}
},
{
title: "The Silmarillion",
author: {
firstName: "J.R.R",
lastName: "Tolkien"
}
},
{
title: "Syrup",
author: {
firstName: "Max",
lastName: "Barry"
}
},
{
title: "The Lost Symbol",
author: {
firstName: "Dan",
lastName: "Brown"
}
},
{
title: "The Book of Lies",
author: {
firstName: "Brad",
lastName: "Meltzer"
}
},
{
title: "Lamb",
author: {
firstName: "Christopher",
lastName: "Moore"
}
},
{
title: "Fool",
author: {
firstName: "Christopher",
lastName: "Moore"
}
},
{
title: "Incompetence",
author: {
firstName: "Rob",
lastName: "Grant"
}
},
{
title: "Fat",
author: {
firstName: "Rob",
lastName: "Grant"
}
},
{
title: "Colony",
author: {
firstName: "Rob",
lastName: "Grant"
}
},
{
title: "Backwards, Red Dwarf",
author: {
firstName: "Rob",
lastName: "Grant"
}
},
{
title: "The Grand Design",
author: {
firstName: "Stephen",
lastName: "Hawking"
}
},
{
title: "The Book of Samson",
author: {
firstName: "David",
lastName: "Maine"
}
},
{
title: "The Preservationist",
author: {
firstName: "David",
lastName: "Maine"
}
},
{
title: "Fallen",
author: {
firstName: "David",
lastName: "Maine"
}
},
{
title: "Monster 1959",
author: {
firstName: "David",
lastName: "Maine"
}
}
]
-246
View File
@@ -1,246 +0,0 @@
/* eslint-disable */
export default [
'Afghanistan',
'Åland Islands',
'Albania',
'Algeria',
'American Samoa',
'Andorra',
'Angola',
'Anguilla',
'Antarctica',
'Antigua and Barbuda',
'Argentina',
'Armenia',
'Aruba',
'Australia',
'Austria',
'Azerbaijan',
'Bahamas',
'Bahrain',
'Bangladesh',
'Barbados',
'Belarus',
'Belgium',
'Belize',
'Benin',
'Bermuda',
'Bhutan',
'Bolivia',
'Bosnia and Herzegovina',
'Botswana',
'Bouvet Island',
'Brazil',
'British Indian Ocean Territory',
'Brunei Darussalam',
'Bulgaria',
'Burkina Faso',
'Burundi',
'Cambodia',
'Cameroon',
'Canada',
'Cape Verde',
'Cayman Islands',
'Central African Republic',
'Chad',
'Chile',
'China',
'Christmas Island',
'Cocos (Keeling) Islands',
'Colombia',
'Comoros',
'Congo',
'Congo, The Democratic Republic of The',
'Cook Islands',
'Costa Rica',
'Cote D\'ivoire',
'Croatia',
'Cuba',
'Cyprus',
'Czech Republic',
'Denmark',
'Djibouti',
'Dominica',
'Dominican Republic',
'Ecuador',
'Egypt',
'El Salvador',
'Equatorial Guinea',
'Eritrea',
'Estonia',
'Ethiopia',
'Falkland Islands (Malvinas)',
'Faroe Islands',
'Fiji',
'Finland',
'France',
'French Guiana',
'French Polynesia',
'French Southern Territories',
'Gabon',
'Gambia',
'Georgia',
'Germany',
'Ghana',
'Gibraltar',
'Greece',
'Greenland',
'Grenada',
'Guadeloupe',
'Guam',
'Guatemala',
'Guernsey',
'Guinea',
'Guinea-bissau',
'Guyana',
'Haiti',
'Heard Island and Mcdonald Islands',
'Holy See (Vatican City State)',
'Honduras',
'Hong Kong',
'Hungary',
'Iceland',
'India',
'Indonesia',
'Iran, Islamic Republic of',
'Iraq',
'Ireland',
'Isle of Man',
'Israel',
'Italy',
'Jamaica',
'Japan',
'Jersey',
'Jordan',
'Kazakhstan',
'Kenya',
'Kiribati',
'Korea, Democratic People\'s Republic of',
'Korea, Republic of',
'Kuwait',
'Kyrgyzstan',
'Lao People\'s Democratic Republic',
'Latvia',
'Lebanon',
'Lesotho',
'Liberia',
'Libyan Arab Jamahiriya',
'Liechtenstein',
'Lithuania',
'Luxembourg',
'Macao',
'Macedonia, The Former Yugoslav Republic of',
'Madagascar',
'Malawi',
'Malaysia',
'Maldives',
'Mali',
'Malta',
'Marshall Islands',
'Martinique',
'Mauritania',
'Mauritius',
'Mayotte',
'Mexico',
'Micronesia, Federated States of',
'Moldova, Republic of',
'Monaco',
'Mongolia',
'Montenegro',
'Montserrat',
'Morocco',
'Mozambique',
'Myanmar',
'Namibia',
'Nauru',
'Nepal',
'Netherlands',
'Netherlands Antilles',
'New Caledonia',
'New Zealand',
'Nicaragua',
'Niger',
'Nigeria',
'Niue',
'Norfolk Island',
'Northern Mariana Islands',
'Norway',
'Oman',
'Pakistan',
'Palau',
'Palestinian Territory, Occupied',
'Panama',
'Papua New Guinea',
'Paraguay',
'Peru',
'Philippines',
'Pitcairn',
'Poland',
'Portugal',
'Puerto Rico',
'Qatar',
'Reunion',
'Romania',
'Russian Federation',
'Rwanda',
'Saint Helena',
'Saint Kitts and Nevis',
'Saint Lucia',
'Saint Pierre and Miquelon',
'Saint Vincent and The Grenadines',
'Samoa',
'San Marino',
'Sao Tome and Principe',
'Saudi Arabia',
'Senegal',
'Serbia',
'Seychelles',
'Sierra Leone',
'Singapore',
'Slovakia',
'Slovenia',
'Solomon Islands',
'Somalia',
'South Africa',
'South Georgia and The South Sandwich Islands',
'Spain',
'Sri Lanka',
'Sudan',
'Suriname',
'Svalbard and Jan Mayen',
'Swaziland',
'Sweden',
'Switzerland',
'Syrian Arab Republic',
'Taiwan, Province of China',
'Tajikistan',
'Tanzania, United Republic of',
'Thailand',
'Timor-leste',
'Togo',
'Tokelau',
'Tonga',
'Trinidad and Tobago',
'Tunisia',
'Turkey',
'Turkmenistan',
'Turks and Caicos Islands',
'Tuvalu',
'Uganda',
'Ukraine',
'United Arab Emirates',
'United Kingdom',
'United States',
'United States Minor Outlying Islands',
'Uruguay',
'Uzbekistan',
'Vanuatu',
'Venezuela',
'Viet Nam',
'Virgin Islands, British',
'Virgin Islands, U.S.',
'Wallis and Futuna',
'Western Sahara',
'Yemen',
'Zambia',
'Zimbabwe'];
-247
View File
@@ -1,247 +0,0 @@
/* eslint-disable */
export default [
{value: "AF", label: "Afghanistan"},
{value: "AX", label: "Åland Islands"},
{value: "AL", label: "Albania"},
{value: "DZ", label: "Algeria"},
{value: "AS", label: "American Samoa"},
{value: "AD", label: "Andorra"},
{value: "AO", label: "Angola"},
{value: "AI", label: "Anguilla"},
{value: "AQ", label: "Antarctica"},
{value: "AG", label: "Antigua and Barbuda"},
{value: "AR", label: "Argentina"},
{value: "AM", label: "Armenia"},
{value: "AW", label: "Aruba"},
{value: "AU", label: "Australia"},
{value: "AT", label: "Austria"},
{value: "AZ", label: "Azerbaijan"},
{value: "BS", label: "Bahamas"},
{value: "BH", label: "Bahrain"},
{value: "BD", label: "Bangladesh"},
{value: "BB", label: "Barbados"},
{value: "BY", label: "Belarus"},
{value: "BE", label: "Belgium"},
{value: "BZ", label: "Belize"},
{value: "BJ", label: "Benin"},
{value: "BM", label: "Bermuda"},
{value: "BT", label: "Bhutan"},
{value: "BO", label: "Bolivia"},
{value: "BA", label: "Bosnia and Herzegovina"},
{value: "BW", label: "Botswana"},
{value: "BV", label: "Bouvet Island"},
{value: "BR", label: "Brazil"},
{value: "IO", label: "British Indian Ocean Territory"},
{value: "BN", label: "Brunei Darussalam"},
{value: "BG", label: "Bulgaria"},
{value: "BF", label: "Burkina Faso"},
{value: "BI", label: "Burundi"},
{value: "KH", label: "Cambodia"},
{value: "CM", label: "Cameroon"},
{value: "CA", label: "Canada"},
{value: "CV", label: "Cape Verde"},
{value: "KY", label: "Cayman Islands"},
{value: "CF", label: "Central African Republic"},
{value: "TD", label: "Chad"},
{value: "CL", label: "Chile"},
{value: "CN", label: "China"},
{value: "CX", label: "Christmas Island"},
{value: "CC", label: "Cocos (Keeling) Islands"},
{value: "CO", label: "Colombia"},
{value: "KM", label: "Comoros"},
{value: "CG", label: "Congo"},
{value: "CD", label: "Congo, The Democratic Republic of The"},
{value: "CK", label: "Cook Islands"},
{value: "CR", label: "Costa Rica"},
{value: "CI", label: "Cote D'ivoire"},
{value: "HR", label: "Croatia"},
{value: "CU", label: "Cuba"},
{value: "CY", label: "Cyprus"},
{value: "CZ", label: "Czech Republic"},
{value: "DK", label: "Denmark"},
{value: "DJ", label: "Djibouti"},
{value: "DM", label: "Dominica"},
{value: "DO", label: "Dominican Republic"},
{value: "EC", label: "Ecuador"},
{value: "EG", label: "Egypt"},
{value: "SV", label: "El Salvador"},
{value: "GQ", label: "Equatorial Guinea"},
{value: "ER", label: "Eritrea"},
{value: "EE", label: "Estonia"},
{value: "ET", label: "Ethiopia"},
{value: "FK", label: "Falkland Islands (Malvinas)"},
{value: "FO", label: "Faroe Islands"},
{value: "FJ", label: "Fiji"},
{value: "FI", label: "Finland"},
{value: "FR", label: "France"},
{value: "GF", label: "French Guiana"},
{value: "PF", label: "French Polynesia"},
{value: "TF", label: "French Southern Territories"},
{value: "GA", label: "Gabon"},
{value: "GM", label: "Gambia"},
{value: "GE", label: "Georgia"},
{value: "DE", label: "Germany"},
{value: "GH", label: "Ghana"},
{value: "GI", label: "Gibraltar"},
{value: "GR", label: "Greece"},
{value: "GL", label: "Greenland"},
{value: "GD", label: "Grenada"},
{value: "GP", label: "Guadeloupe"},
{value: "GU", label: "Guam"},
{value: "GT", label: "Guatemala"},
{value: "GG", label: "Guernsey"},
{value: "GN", label: "Guinea"},
{value: "GW", label: "Guinea-bissau"},
{value: "GY", label: "Guyana"},
{value: "HT", label: "Haiti"},
{value: "HM", label: "Heard Island and Mcdonald Islands"},
{value: "VA", label: "Holy See (Vatican City State)"},
{value: "HN", label: "Honduras"},
{value: "HK", label: "Hong Kong"},
{value: "HU", label: "Hungary"},
{value: "IS", label: "Iceland"},
{value: "IN", label: "India"},
{value: "ID", label: "Indonesia"},
{value: "IR", label: "Iran, Islamic Republic of"},
{value: "IQ", label: "Iraq"},
{value: "IE", label: "Ireland"},
{value: "IM", label: "Isle of Man"},
{value: "IL", label: "Israel"},
{value: "IT", label: "Italy"},
{value: "JM", label: "Jamaica"},
{value: "JP", label: "Japan"},
{value: "JE", label: "Jersey"},
{value: "JO", label: "Jordan"},
{value: "KZ", label: "Kazakhstan"},
{value: "KE", label: "Kenya"},
{value: "KI", label: "Kiribati"},
{value: "KP", label: "Korea, Democratic People's Republic of"},
{value: "KR", label: "Korea, Republic of"},
{value: "KW", label: "Kuwait"},
{value: "KG", label: "Kyrgyzstan"},
{value: "LA", label: "Lao People's Democratic Republic"},
{value: "LV", label: "Latvia"},
{value: "LB", label: "Lebanon"},
{value: "LS", label: "Lesotho"},
{value: "LR", label: "Liberia"},
{value: "LY", label: "Libyan Arab Jamahiriya"},
{value: "LI", label: "Liechtenstein"},
{value: "LT", label: "Lithuania"},
{value: "LU", label: "Luxembourg"},
{value: "MO", label: "Macao"},
{value: "MK", label: "Macedonia, The Former Yugoslav Republic of"},
{value: "MG", label: "Madagascar"},
{value: "MW", label: "Malawi"},
{value: "MY", label: "Malaysia"},
{value: "MV", label: "Maldives"},
{value: "ML", label: "Mali"},
{value: "MT", label: "Malta"},
{value: "MH", label: "Marshall Islands"},
{value: "MQ", label: "Martinique"},
{value: "MR", label: "Mauritania"},
{value: "MU", label: "Mauritius"},
{value: "YT", label: "Mayotte"},
{value: "MX", label: "Mexico"},
{value: "FM", label: "Micronesia, Federated States of"},
{value: "MD", label: "Moldova, Republic of"},
{value: "MC", label: "Monaco"},
{value: "MN", label: "Mongolia"},
{value: "ME", label: "Montenegro"},
{value: "MS", label: "Montserrat"},
{value: "MA", label: "Morocco"},
{value: "MZ", label: "Mozambique"},
{value: "MM", label: "Myanmar"},
{value: "NA", label: "Namibia"},
{value: "NR", label: "Nauru"},
{value: "NP", label: "Nepal"},
{value: "NL", label: "Netherlands"},
{value: "AN", label: "Netherlands Antilles"},
{value: "NC", label: "New Caledonia"},
{value: "NZ", label: "New Zealand"},
{value: "NI", label: "Nicaragua"},
{value: "NE", label: "Niger"},
{value: "NG", label: "Nigeria"},
{value: "NU", label: "Niue"},
{value: "NF", label: "Norfolk Island"},
{value: "MP", label: "Northern Mariana Islands"},
{value: "NO", label: "Norway"},
{value: "OM", label: "Oman"},
{value: "PK", label: "Pakistan"},
{value: "PW", label: "Palau"},
{value: "PS", label: "Palestinian Territory, Occupied"},
{value: "PA", label: "Panama"},
{value: "PG", label: "Papua New Guinea"},
{value: "PY", label: "Paraguay"},
{value: "PE", label: "Peru"},
{value: "PH", label: "Philippines"},
{value: "PN", label: "Pitcairn"},
{value: "PL", label: "Poland"},
{value: "PT", label: "Portugal"},
{value: "PR", label: "Puerto Rico"},
{value: "QA", label: "Qatar"},
{value: "RE", label: "Reunion"},
{value: "RO", label: "Romania"},
{value: "RU", label: "Russian Federation"},
{value: "RW", label: "Rwanda"},
{value: "SH", label: "Saint Helena"},
{value: "KN", label: "Saint Kitts and Nevis"},
{value: "LC", label: "Saint Lucia"},
{value: "PM", label: "Saint Pierre and Miquelon"},
{value: "VC", label: "Saint Vincent and The Grenadines"},
{value: "WS", label: "Samoa"},
{value: "SM", label: "San Marino"},
{value: "ST", label: "Sao Tome and Principe"},
{value: "SA", label: "Saudi Arabia"},
{value: "SN", label: "Senegal"},
{value: "RS", label: "Serbia"},
{value: "SC", label: "Seychelles"},
{value: "SL", label: "Sierra Leone"},
{value: "SG", label: "Singapore"},
{value: "SK", label: "Slovakia"},
{value: "SI", label: "Slovenia"},
{value: "SB", label: "Solomon Islands"},
{value: "SO", label: "Somalia"},
{value: "ZA", label: "South Africa"},
{value: "GS", label: "South Georgia and The South Sandwich Islands"},
{value: "ES", label: "Spain"},
{value: "LK", label: "Sri Lanka"},
{value: "SD", label: "Sudan"},
{value: "SR", label: "Suriname"},
{value: "SJ", label: "Svalbard and Jan Mayen"},
{value: "SZ", label: "Swaziland"},
{value: "SE", label: "Sweden"},
{value: "CH", label: "Switzerland"},
{value: "SY", label: "Syrian Arab Republic"},
{value: "TW", label: "Taiwan, Province of China"},
{value: "TJ", label: "Tajikistan"},
{value: "TZ", label: "Tanzania, United Republic of"},
{value: "TH", label: "Thailand"},
{value: "TL", label: "Timor-leste"},
{value: "TG", label: "Togo"},
{value: "TK", label: "Tokelau"},
{value: "TO", label: "Tonga"},
{value: "TT", label: "Trinidad and Tobago"},
{value: "TN", label: "Tunisia"},
{value: "TR", label: "Turkey"},
{value: "TM", label: "Turkmenistan"},
{value: "TC", label: "Turks and Caicos Islands"},
{value: "TV", label: "Tuvalu"},
{value: "UG", label: "Uganda"},
{value: "UA", label: "Ukraine"},
{value: "AE", label: "United Arab Emirates"},
{value: "GB", label: "United Kingdom"},
{value: "US", label: "United States"},
{value: "UM", label: "United States Minor Outlying Islands"},
{value: "UY", label: "Uruguay"},
{value: "UZ", label: "Uzbekistan"},
{value: "VU", label: "Vanuatu"},
{value: "VE", label: "Venezuela"},
{value: "VN", label: "Viet Nam"},
{value: "VG", label: "Virgin Islands, British"},
{value: "VI", label: "Virgin Islands, U.S."},
{value: "WF", label: "Wallis and Futuna"},
{value: "EH", label: "Western Sahara"},
{value: "YE", label: "Yemen"},
{value: "ZM", label: "Zambia"},
{value: "ZW", label: "Zimbabwe"},
];
-19
View File
@@ -1,19 +0,0 @@
import vSelect from '../../src/components/Select'
export default ({ Vue, options, router, siteData }) => {
Vue.component('v-select', vSelect)
/**
* Remove service workers.
*/
if (typeof navigator !== 'undefined' && 'serviceWorker' in navigator) {
navigator.serviceWorker.getRegistrations().then((registrations) => {
registrations.forEach((registration) => {
registration
.unregister()
.then(() => console.log('Service worker unregistered.'))
.catch(() => console.log('Error unregistering service worker.'))
})
})
}
}
@@ -1,65 +0,0 @@
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 []
}
}
-5
View File
@@ -1,5 +0,0 @@
const clientDynamicModules = require('./clientDynamicModules')
module.exports = {
clientDynamicModules: async () => await clientDynamicModules(),
}
@@ -1,54 +0,0 @@
<script>
/**
* @see https://ethical-ad-client.readthedocs.io/en/latest/
*/
export default {
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()
}
},
},
mounted() {
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)
},
},
render(h) {
return h('div', {
attrs: {
id: 'ads',
'data-ea-publisher': 'vue-select',
'data-ea-type': 'image',
},
class: 'flat horizontal',
})
},
}
</script>
<style scoped>
#ads {
display: flex;
justify-content: center;
align-items: center;
width: 100%;
min-height: 264px;
}
</style>
-3
View File
@@ -1,3 +0,0 @@
module.exports = {
extend: '@vuepress/theme-default',
}
-22
View File
@@ -1,22 +0,0 @@
<template>
<ParentLayout></ParentLayout>
</template>
<script>
import ParentLayout from '@parent-theme/layouts/Layout.vue'
export default {
components: {
ParentLayout,
},
}
</script>
<style>
#ads {
border-bottom: 1px solid #eaecef;
}
#ads + .sidebar-links {
padding-top: 1rem;
}
</style>
-175
View File
@@ -1,175 +0,0 @@
export default () => {
document.getElementsByClassName ||
(document.getElementsByClassName = function (e) {
var n,
t,
r,
a = document,
o = []
if (a.querySelectorAll) return a.querySelectorAll('.' + e)
if (a.evaluate)
for (
t = ".//*[contains(concat(' ', @class, ' '), ' " + e + " ')]",
n = a.evaluate(t, a, null, 0, null);
(r = n.iterateNext());
)
o.push(r)
else
for (
n = a.getElementsByTagName('*'),
t = new RegExp('(^|\\s)' + e + '(\\s|$)'),
r = 0;
r < n.length;
r++
)
t.test(n[r].className) && o.push(n[r])
return o
}),
(function () {
function e() {
function e() {
for (
var e = document.getElementsByClassName('codepen'),
t = e.length - 1;
t > -1;
t--
) {
var u = a(e[t])
if (
0 !== Object.keys(u).length &&
((u = o(u)), (u.user = n(u, e[t])), r(u))
) {
var c = i(u),
l = s(u, c)
f(e[t], l)
}
}
m()
}
function n(e, n) {
if ('string' == typeof e.user) return e.user
for (var t = 0, r = n.children.length; t < r; t++) {
var a = n.children[t],
o = a.href || '',
i = o.match(/codepen\.(io|dev)\/(\w+)\/pen\//i)
if (i) return i[2]
}
return 'anon'
}
function r(e) {
return e['slug-hash']
}
function a(e) {
for (var n = {}, t = e.attributes, r = 0, a = t.length; r < a; r++) {
var o = t[r].name
0 === o.indexOf('data-') && (n[o.replace('data-', '')] = t[r].value)
}
return n
}
function o(e) {
return (
e.href && (e['slug-hash'] = e.href),
e.type && (e['default-tab'] = e.type),
e.safe &&
('true' === e.safe
? (e.animations = 'run')
: (e.animations = 'stop-after-5')),
e
)
}
function i(e) {
var n = u(e),
t = e.user ? e.user : 'anon',
r = '?' + l(e),
a = e.preview && 'true' === e.preview ? 'embed/preview' : 'embed',
o = [n, t, a, e['slug-hash'] + r].join('/')
return o.replace(/\/\//g, '//')
}
function u(e) {
return e.host
? c(e.host)
: 'file:' === document.location.protocol
? 'https://codepen.io'
: '//codepen.io'
}
function c(e) {
return e.match(/^\/\//) || !e.match(/https?:/)
? document.location.protocol + '//' + e
: e
}
function l(e) {
var n = ''
for (var t in e)
'' !== n && (n += '&'), (n += t + '=' + encodeURIComponent(e[t]))
return n
}
function s(e, n) {
var r
e['pen-title']
? (r = e['pen-title'])
: ((r = 'CodePen Embed ' + t), t++)
var a = {
id: 'cp_embed_' + e['slug-hash'].replace('/', '_'),
src: n,
scrolling: 'no',
frameborder: '0',
height: d(e),
allowTransparency: 'true',
allowfullscreen: 'true',
allowpaymentrequest: 'true',
name: 'CodePen Embed',
title: r,
class: 'cp_embed_iframe ' + (e['class'] ? e['class'] : ''),
style: 'width: ' + p + '; overflow: hidden;',
},
o = '<iframe '
for (var i in a) o += i + '="' + a[i] + '" '
return (o += '></iframe>')
}
function d(e) {
return e.height ? e.height : 300
}
function f(e, n) {
if (e.parentNode) {
var t = document.createElement('div')
;(t.className = 'cp_embed_wrapper'),
(t.innerHTML = n),
e.parentNode.replaceChild(t, e)
} else e.innerHTML = n
}
function m() {
'function' == typeof __CodePenIFrameAddedToPage &&
__CodePenIFrameAddedToPage()
}
var p = '100%'
e()
}
function n(e) {
;/in/.test(document.readyState)
? setTimeout('window.__cp_domReady(' + e + ')', 9)
: e()
}
var t = 1
;(window.__cp_domReady = n),
(window.__CPEmbed = e),
n(function () {
new __CPEmbed()
})
})()
}
-44
View File
@@ -1,44 +0,0 @@
<SponsorBanner />
# Vue Select
![Current Release](https://img.shields.io/github/release/sagalbot/vue-select.svg?style=flat-square)
![Release Date](https://img.shields.io/github/release-date/sagalbot/vue-select?style=flat-square)
![Bundle Size](https://flat.badgen.net/bundlephobia/min/vue-select)
![Monthly Downloads](https://img.shields.io/npm/dm/vue-select.svg?style=flat-square)
![Coverage Status](https://coveralls.io/repos/github/sagalbot/vue-select/badge.svg?branch=master)
![MIT License](https://img.shields.io/github/license/sagalbot/vue-select.svg?style=flat-square)
> 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 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>
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
- 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
- Zero dependencies
## Resources
- **[GitHub](https://github.com/sagalbot/vue-select)**
- **[CodePen Template](http://codepen.io/sagalbot/pen/NpwrQO)**
+30
View File
@@ -0,0 +1,30 @@
<script setup lang="ts">
import { useHead } from "#head";
import Hero from "~/components/Hero.vue";
import ApplicationHeader from "~/components/ApplicationHeader.vue";
import SidebarNavigation from "~/components/SidebarNavigation.vue";
import PageContent from "~/components/PageContent.vue";
import { useContent } from "#imports";
useHead({
title: "Vue Select",
bodyAttrs: {
class: "bg-white dark:bg-slate-900",
},
});
const { page } = useContent();
</script>
<template>
<div>
<ApplicationHeader />
<Hero v-if="page?.hero" />
<div
class="relative mx-auto flex max-w-8xl justify-center sm:px-2 lg:px-8 xl:px-12"
>
<SidebarNavigation />
<PageContent />
</div>
</div>
</template>
Binary file not shown.
Binary file not shown.
+93
View File
@@ -0,0 +1,93 @@
Copyright 2018 The Lexend Project Authors (https://github.com/googlefonts/lexend), with Reserved Font Name “RevReading Lexend”.
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
https://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 214 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 219 KiB

+23
View File
@@ -0,0 +1,23 @@
@font-face {
font-family: 'Lexend';
font-style: normal;
font-weight: 100 900;
font-display: swap;
src: url(~/assets/fonts/lexend.woff2) format('woff2');
}
@font-face {
font-family: 'Inter';
font-weight: 100 900;
font-display: block;
font-style: normal;
font-named-instance: 'Regular';
src: url('~/assets/fonts/Inter-roman.var.woff2') format('woff2');
}
@font-face {
font-family: 'Inter';
font-weight: 100 900;
font-display: block;
font-style: italic;
font-named-instance: 'Italic';
src: url('~/assets/fonts/Inter-italic.var.woff2') format('woff2');
}
+116
View File
@@ -0,0 +1,116 @@
<script setup lang="ts">
import { NuxtLink } from "#components";
import ColorThemeSwitcher from "~/components/ThemeSwitcher.vue";
import { useWindowScroll } from "@vueuse/core";
const { y } = useWindowScroll();
const isScrolled = computed(() => y.value !== 0);
</script>
<template>
<header
:class="[
'sticky top-0 z-50 flex flex-wrap items-center justify-between bg-white px-4 py-5 shadow-md shadow-slate-900/5 transition duration-500 dark:shadow-none sm:px-6 lg:px-8',
isScrolled
? 'dark:bg-slate-900/95 dark:backdrop-blur dark:[@supports(backdrop-filter:blur(0))]:bg-slate-900/75'
: 'dark:bg-transparent',
]"
>
<div class="mr-6 flex lg:hidden">
<button type="button" class="relative" aria-label="Open navigation">
<svg
aria-hidden="true"
viewBox="0 0 24 24"
fill="none"
stroke-width="2"
stroke-linecap="round"
class="h-6 w-6 stroke-slate-500"
>
<path d="M4 7h16M4 12h16M4 17h16"></path>
</svg>
</button>
<div
style="
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
display: none;
"
></div>
</div>
<div class="relative flex flex-grow basis-0 items-center">
<NuxtLink aria-label="Home page" href="/">
<svg
aria-hidden="true"
viewBox="0 0 36 36"
fill="none"
class="h-9 w-9 fill-slate-700 dark:fill-sky-100"
>
<g
fill="none"
stroke="#38BDF8"
stroke-linejoin="round"
stroke-width="3"
>
<path d="M10.308 5L18 17.5 10.308 30 2.615 17.5 10.308 5z"></path>
<path
d="M18 17.5L10.308 5h15.144l7.933 12.5M18 17.5h15.385L25.452 30H10.308L18 17.5z"
></path>
</g>
</svg>
</NuxtLink>
</div>
<div class="-my-5 mr-6 sm:mr-8 md:mr-0">
<button
type="button"
class="group flex h-6 w-6 items-center justify-center sm:justify-start md:h-auto md:w-80 md:flex-none md:rounded-lg md:py-2.5 md:pl-4 md:pr-3.5 md:text-sm md:ring-1 md:ring-slate-200 md:hover:ring-slate-300 dark:md:bg-slate-800/75 dark:md:ring-inset dark:md:ring-white/5 dark:md:hover:bg-slate-700/40 dark:md:hover:ring-slate-500 lg:w-96"
>
<svg
aria-hidden="true"
viewBox="0 0 20 20"
class="h-5 w-5 flex-none fill-slate-400 group-hover:fill-slate-500 dark:fill-slate-500 md:group-hover:fill-slate-400"
>
<path
d="M16.293 17.707a1 1 0 0 0 1.414-1.414l-1.414 1.414ZM9 14a5 5 0 0 1-5-5H2a7 7 0 0 0 7 7v-2ZM4 9a5 5 0 0 1 5-5V2a7 7 0 0 0-7 7h2Zm5-5a5 5 0 0 1 5 5h2a7 7 0 0 0-7-7v2Zm8.707 12.293-3.757-3.757-1.414 1.414 3.757 3.757 1.414-1.414ZM14 9a4.98 4.98 0 0 1-1.464 3.536l1.414 1.414A6.98 6.98 0 0 0 16 9h-2Zm-1.464 3.536A4.98 4.98 0 0 1 9 14v2a6.98 6.98 0 0 0 4.95-2.05l-1.414-1.414Z"
></path>
</svg>
<span
class="sr-only md:not-sr-only md:ml-2 md:text-slate-500 md:dark:text-slate-400"
>
Search docs</span
>
<kbd
class="ml-auto hidden font-medium text-slate-400 dark:text-slate-500 md:block"
>
<kbd class="font-sans"></kbd>
<kbd class="font-sans">K</kbd>
</kbd>
</button>
</div>
<div class="relative flex basis-0 justify-end gap-6 sm:gap-8 md:flex-grow">
<ColorThemeSwitcher />
<a
class="group"
aria-label="GitHub"
href="https://github.com/sagalbot/vue-select"
>
<svg
aria-hidden="true"
viewBox="0 0 16 16"
class="h-6 w-6 fill-slate-400 group-hover:fill-slate-500 dark:group-hover:fill-slate-300"
>
<path
d="M8 0C3.58 0 0 3.58 0 8C0 11.54 2.29 14.53 5.47 15.59C5.87 15.66 6.02 15.42 6.02 15.21C6.02 15.02 6.01 14.39 6.01 13.72C4 14.09 3.48 13.23 3.32 12.78C3.23 12.55 2.84 11.84 2.5 11.65C2.22 11.5 1.82 11.13 2.49 11.12C3.12 11.11 3.57 11.7 3.72 11.94C4.44 13.15 5.59 12.81 6.05 12.6C6.12 12.08 6.33 11.73 6.56 11.53C4.78 11.33 2.92 10.64 2.92 7.58C2.92 6.71 3.23 5.99 3.74 5.43C3.66 5.23 3.38 4.41 3.82 3.31C3.82 3.31 4.49 3.1 6.02 4.13C6.66 3.95 7.34 3.86 8.02 3.86C8.7 3.86 9.38 3.95 10.02 4.13C11.55 3.09 12.22 3.31 12.22 3.31C12.66 4.41 12.38 5.23 12.3 5.43C12.81 5.99 13.12 6.7 13.12 7.58C13.12 10.65 11.25 11.33 9.47 11.53C9.76 11.78 10.01 12.26 10.01 13.01C10.01 14.08 10 14.94 10 15.21C10 15.42 10.15 15.67 10.55 15.59C13.71 14.53 16 11.53 16 8C16 3.58 12.42 0 8 0Z"
></path>
</svg>
</a>
</div>
</header>
</template>
+31
View File
@@ -0,0 +1,31 @@
<script setup lang="ts">
import { computed, useAttrs } from "#imports";
import { NuxtLink } from "#components";
const props = withDefaults(
defineProps<{
variant?: "primary" | "secondary";
}>(),
{
variant: "primary",
}
);
const styles = computed(
() =>
({
primary:
"rounded-full bg-sky-300 py-2 px-4 text-sm font-semibold text-slate-900 hover:bg-sky-200 focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-sky-300/50 active:bg-sky-500",
secondary:
"rounded-full bg-slate-800 py-2 px-4 text-sm font-medium text-white hover:bg-slate-700 focus:outline-none focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-white/50 active:text-slate-400",
}[props.variant])
);
const hasTo = computed<boolean>(() => Object.keys(useAttrs()).includes("to"));
const component = computed(() => (hasTo.value ? NuxtLink : "button"));
</script>
<template>
<Component :is="component" :class="styles"><slot></slot></Component>
</template>
+93
View File
@@ -0,0 +1,93 @@
<script setup lang="ts">
import Button from "~/components/Button.vue";
import TimelineSvg from "~/components/TimelineSvg.vue";
</script>
<template>
<div
class="overflow-hidden bg-slate-900 dark:-mb-32 dark:mt-[-4.5rem] dark:pb-32 dark:pt-[4.5rem] dark:lg:mt-[-4.75rem] dark:lg:pt-[4.75rem]"
>
<div class="py-16 sm:px-2 lg:relative lg:py-20 lg:px-0">
<div
class="mx-auto grid max-w-2xl grid-cols-1 items-center gap-y-16 gap-x-8 px-4 lg:max-w-8xl lg:grid-cols-2 lg:px-8 xl:gap-x-16 xl:px-12"
>
<div class="relative z-10 md:text-center lg:text-left">
<img
alt=""
src="~/assets/img/blur-cyan.png"
decoding="async"
class="absolute bottom-full right-full -mr-72 -mb-56 opacity-50"
width="530"
height="530"
/>
<div class="relative">
<p
class="inline bg-gradient-to-r from-indigo-200 via-sky-400 to-indigo-200 bg-clip-text font-display text-5xl tracking-tight text-transparent"
>
The complete Vue.js combobox solution.
</p>
<p class="mt-3 text-2xl tracking-tight text-slate-400">
Everything you wish <code>&lt;select&gt;</code> could do, wrapped
up in a lightweight, extendable Vue component.
</p>
<div class="mt-8 flex gap-4 md:justify-center lg:justify-start">
<Button variant="primary"> Get started </Button>
<Button
to="https://github.com/sagalbot/vue-select"
variant="secondary"
target="_blank"
>
View on Github
</Button>
</div>
</div>
</div>
<div class="relative lg:static xl:pl-10">
<div
class="absolute inset-x-[-50vw] -top-32 -bottom-48 [mask-image:linear-gradient(transparent,white,white)] dark:[mask-image:linear-gradient(transparent,white,transparent)] lg:left-[calc(50%+14rem)] lg:right-0 lg:-top-32 lg:-bottom-32 lg:[mask-image:none] lg:dark:[mask-image:linear-gradient(white,white,transparent)]"
>
<TimelineSvg
class="absolute top-1/2 left-1/2 -translate-y-1/2 -translate-x-1/2 lg:left-0 lg:translate-x-0 lg:translate-y-[-60%]"
/>
</div>
<div class="relative">
<img
alt=""
src="~/assets/img/blur-cyan.png"
decoding="async"
class="absolute -top-64 -right-64"
width="530"
height="530"
/><img
alt=""
src="~/assets/img/blur-indigo.png"
decoding="async"
class="absolute -bottom-40 -right-44"
width="567"
height="567"
/>
<div
class="absolute inset-0 rounded-2xl bg-gradient-to-tr from-sky-300 via-sky-300/70 to-blue-300 opacity-10 blur-lg"
></div>
<div
class="absolute inset-0 rounded-2xl bg-gradient-to-tr from-sky-300 via-sky-300/70 to-blue-300 opacity-10"
></div>
<div
class="relative rounded-2xl bg-[#0A101F]/80 ring-1 ring-white/10 backdrop-blur"
>
<div
class="absolute -top-px left-20 right-11 h-px bg-gradient-to-r from-sky-300/0 via-sky-300/70 to-sky-300/0"
></div>
<div
class="absolute -bottom-px left-11 right-20 h-px bg-gradient-to-r from-blue-400/0 via-blue-400 to-blue-400/0"
></div>
<div class="pl-4 pt-4">
<div class="mt-6 flex items-start px-1 text-sm"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</template>
+36
View File
@@ -0,0 +1,36 @@
<script setup lang="ts">
import ContentFooterNavigation from "~/components/PageContentFooterNavigation.vue";
import PageContentHeader from "~/components/PageContentHeader.vue";
import PageTableOfContents from "~/components/PageTableOfContents.vue";
</script>
<template>
<div
class="min-w-0 max-w-2xl flex-auto px-4 py-16 lg:max-w-none lg:pr-0 lg:pl-8 xl:px-16"
>
<article>
<PageContentHeader />
<div
:class="[
'prose prose-slate max-w-none dark:prose-invert dark:text-slate-400',
// headings
'prose-headings:scroll-mt-28 prose-headings:font-display prose-headings:font-normal lg:prose-headings:scroll-mt-[8.5rem]',
// lead
'prose-lead:text-slate-500 dark:prose-lead:text-slate-400',
// links
'prose-a:font-semibold dark:prose-a:text-sky-400',
// link underline
'prose-a:no-underline prose-a:shadow-[inset_0_-2px_0_0_var(--tw-prose-background,#fff),inset_0_calc(-1*(var(--tw-prose-underline-size,4px)+2px))_0_0_var(--tw-prose-underline,theme(colors.sky.300))] hover:prose-a:[--tw-prose-underline-size:6px] dark:[--tw-prose-background:theme(colors.slate.900)] dark:prose-a:shadow-[inset_0_calc(-1*var(--tw-prose-underline-size,2px))_0_0_var(--tw-prose-underline,theme(colors.sky.800))] dark:hover:prose-a:[--tw-prose-underline-size:6px]',
// pre
'prose-pre:rounded-xl prose-pre:border-2 prose-pre:bg-white dark:prose-pre:border-0 dark:prose-pre:bg-slate-800/60 dark:prose-pre:shadow-lg dark:prose-pre:shadow-none dark:prose-pre:ring-1 dark:prose-pre:ring-slate-300/10',
// hr
'dark:prose-hr:border-slate-800',
]"
>
<ContentDoc :path="$route.path" />
</div>
</article>
<ContentFooterNavigation />
</div>
<PageTableOfContents />
</template>
@@ -0,0 +1,20 @@
<template>
<dl class="mt-12 flex border-t border-slate-200 pt-6 dark:border-slate-800">
<div class="ml-auto text-right">
<dt
class="font-display text-sm font-medium text-slate-900 dark:text-white"
>
Next
</dt>
<dd class="mt-1">
<a
class="text-base font-semibold text-slate-500 hover:text-slate-600 dark:text-slate-400 dark:hover:text-slate-300"
href="/docs/installation"
>
Installation
<span aria-hidden="true"></span></a
>
</dd>
</div>
</dl>
</template>
+21
View File
@@ -0,0 +1,21 @@
<script setup lang="ts">
import { useContent } from "#imports";
const { page } = useContent();
</script>
<template>
<header class="mb-9 space-y-1">
<p
v-if="page?.section"
class="font-display text-sm font-medium text-sky-500"
>
{{ page?.section }}
</p>
<h1
class="font-display text-3xl tracking-tight text-slate-900 dark:text-white"
>
{{ page?.title }}
</h1>
</header>
</template>
+45
View File
@@ -0,0 +1,45 @@
<script setup lang="ts">
import { computed } from "#imports";
const { toc, page } = useContent();
const shouldRender = computed(() => page.value.hideToc !== true);
</script>
<template>
<div
v-if="shouldRender && toc.links"
class="hidden xl:sticky xl:top-[4.5rem] xl:-mr-6 xl:block xl:h-[calc(100vh-4.5rem)] xl:flex-none xl:overflow-y-auto xl:py-16 xl:pr-6"
>
<nav aria-labelledby="on-this-page-title" class="w-56">
<h2
id="on-this-page-title"
class="font-display text-sm font-medium text-slate-900 dark:text-white"
>
On this page
</h2>
<ol role="list" class="mt-4 space-y-3 text-sm">
<li v-for="link in toc?.links" :key="link.id">
<h3>
<a class="text-slate-900 dark:text-white" :href="`#${link.id}`">
{{ link.text }}
</a>
</h3>
<ol
v-if="link.children"
role="list"
class="mt-2 space-y-3 pl-5 text-slate-500 dark:text-slate-400"
>
<li v-for="childLink in link.children" :key="childLink.id">
<a
class="hover:text-slate-600 dark:hover:text-slate-300"
:href="`#${childLink.id}`"
>
{{ childLink.text }}
</a>
</li>
</ol>
</li>
</ol>
</nav>
</div>
</template>
+114
View File
@@ -0,0 +1,114 @@
<script lang="ts" setup>
const navigation = [
{
title: "Community",
links: [
{ title: "Sponsors 🎉", href: "/sponsors" },
{ title: "Contributors", href: "/contributors" },
],
},
{
title: "Getting Started",
links: [
{ href: "/guide/install", title: "Installation" },
{ href: "/guide/options", title: "Dropdown Options" },
{ href: "/guide/values", title: "Selecting Values" },
{ href: "/guide/upgrading", title: "Upgrading 2.x to 3.x" },
],
},
{
title: "Templating & Styling",
links: [
{ href: "/guide/components", title: "Child Components" },
{ href: "/guide/css", title: "CSS & Selectors" },
{ href: "/guide/slots", title: "Slots" },
],
},
{
title: "Accessibility",
links: [
{ href: "/guide/accessibility", title: "WAI-ARIA Spec" },
{ href: "/guide/localization", title: "Localization" },
],
},
{
title: "Use Cases",
links: [
{ href: "/guide/validation", title: "Validation" },
{ href: "/guide/selectable", title: "Limiting Selections" },
{ href: "/guide/pagination", title: "Pagination" },
{ href: "/guide/infinite-scroll", title: "Infinite Scroll" },
{ href: "/guide/vuex", title: "Vuex" },
{ href: "/guide/ajax", title: "AJAX" },
{ href: "/guide/loops", title: "Using in Loops" },
],
},
{
title: "Customizing",
links: [
{ href: "/guide/keydown", title: "Keydown Events" },
{ href: "/guide/positioning", title: "Dropdown Position" },
{ href: "/guide/opening", title: "Dropdown Opening" },
{ href: "/guide/filtering", title: "Option Filtering" },
],
},
{
title: "API",
links: [
{ href: "/api/props", title: "Props" },
{ href: "/api/slots", title: "Slots" },
{ href: "/api/events", title: "Events" },
],
},
];
const router = { pathname: "" };
</script>
<template>
<div class="hidden lg:relative lg:block lg:flex-none">
<div
class="absolute inset-y-0 right-0 w-[50vw] bg-slate-50 dark:hidden"
></div>
<div
class="sticky top-[4.5rem] -ml-0.5 h-[calc(100vh-4.5rem)] overflow-y-auto py-16 pl-0.5"
>
<div
class="absolute top-16 bottom-0 right-0 hidden h-12 w-px bg-gradient-to-t from-slate-800 dark:block"
></div>
<div
class="absolute top-28 bottom-0 right-0 hidden w-px bg-slate-800 dark:block"
></div>
<nav class="w-64 pr-8 text-base lg:text-sm xl:w-72 xl:pr-16">
<ul role="list" class="space-y-9">
<li v-for="section in navigation" key="section.title">
<h2 class="font-display font-medium text-slate-900 dark:text-white">
{{ section.title }}
</h2>
<ul
role="list"
class="mt-2 space-y-2 border-l-2 border-slate-100 dark:border-slate-800 lg:mt-4 lg:space-y-4 lg:border-slate-200"
>
<li
v-for="link in section?.links"
key="link.href"
class="relative"
>
<NuxtLink
:href="link.href"
:class="[
'block w-full pl-3.5 before:pointer-events-none before:absolute before:-left-1 before:top-1/2 before:h-1.5 before:w-1.5 before:-translate-y-1/2 before:rounded-full',
link.href === router.pathname
? 'font-semibold text-sky-500 before:bg-sky-500'
: 'text-slate-500 before:hidden before:bg-slate-300 hover:text-slate-600 hover:before:block dark:text-slate-400 dark:before:bg-slate-700 dark:hover:text-slate-300',
]"
>
{{ link.title }}
</NuxtLink>
</li>
</ul>
</li>
</ul>
</nav>
</div>
</div>
</template>
+80
View File
@@ -0,0 +1,80 @@
<script setup lang="ts">
import {
Listbox,
ListboxButton,
ListboxLabel,
ListboxOption,
ListboxOptions,
} from "@headlessui/vue";
import LightIcon from "~/components/icons/LightIcon.vue";
import DarkIcon from "~/components/icons/DarkIcon.vue";
import SystemIcon from "~/components/icons/SystemIcon.vue";
const themes = [
{ name: "Light", value: "light", icon: LightIcon },
{ name: "Dark", value: "dark", icon: DarkIcon },
{ name: "System", value: "system", icon: SystemIcon },
];
const colorMode = useColorMode();
</script>
<template>
<div class="relative z-10">
<ClientOnly>
<Listbox as="div" v-model="colorMode.preference">
<ListboxLabel class="sr-only">Theme</ListboxLabel>
<ListboxButton
class="flex h-6 w-6 items-center justify-center rounded-lg shadow-md shadow-black/5 ring-1 ring-black/5 dark:bg-slate-700 dark:ring-inset dark:ring-white/5"
>
<LightIcon
v-show="colorMode.value === 'light'"
class="h-4 w-4 fill-sky-400"
/>
<DarkIcon
v-show="colorMode.value === 'dark'"
class="h-4 w-4 fill-sky-400"
/>
</ListboxButton>
<ListboxOptions
class="absolute top-full left-1/2 mt-3 w-36 -translate-x-1/2 space-y-1 rounded-xl bg-white p-3 text-sm font-medium shadow-md shadow-black/5 ring-1 ring-black/5 dark:bg-slate-800 dark:ring-white/5"
>
<ListboxOption
as="template"
v-slot="{ active, selected }"
v-for="{ name, value, icon } in themes"
:key="value"
:value="value"
>
<li
:class="[
'flex cursor-pointer select-none items-center rounded-[0.625rem] p-1',
{
'text-sky-500': selected,
'text-slate-900 dark:text-white': active && !selected,
'text-slate-700 dark:text-slate-400': !active && !selected,
'bg-slate-100 dark:bg-slate-900/40': active,
},
]"
>
<div
class="rounded-md bg-white p-1 shadow ring-1 ring-slate-900/5 dark:bg-slate-700 dark:ring-inset dark:ring-white/5"
>
<Component
:is="icon"
:class="[
'h-4 w-4',
selected
? 'fill-sky-400 dark:fill-sky-400'
: 'fill-slate-400',
]"
/>
</div>
<div class="ml-3">{{ name }}</div>
</li>
</ListboxOption>
</ListboxOptions>
</Listbox>
</ClientOnly>
</div>
</template>
+186
View File
@@ -0,0 +1,186 @@
<template>
<svg
aria-hidden="true"
viewBox="0 0 668 1069"
width="668"
height="1069"
fill="none"
>
<defs>
<clipPath id=":R1l6:-clip-path">
<path
fill="#fff"
transform="rotate(-180 334 534.4)"
d="M0 0h668v1068.8H0z"
></path>
</clipPath>
</defs>
<g opacity=".4" clip-path="url(#:R1l6:-clip-path)" stroke-width="4">
<path
opacity=".3"
d="M584.5 770.4v-474M484.5 770.4v-474M384.5 770.4v-474M283.5 769.4v-474M183.5 768.4v-474M83.5 767.4v-474"
stroke="#334155"
></path>
<path
d="M83.5 221.275v6.587a50.1 50.1 0 0 0 22.309 41.686l55.581 37.054a50.102 50.102 0 0 1 22.309 41.686v6.587M83.5 716.012v6.588a50.099 50.099 0 0 0 22.309 41.685l55.581 37.054a50.102 50.102 0 0 1 22.309 41.686v6.587M183.7 584.5v6.587a50.1 50.1 0 0 0 22.31 41.686l55.581 37.054a50.097 50.097 0 0 1 22.309 41.685v6.588M384.101 277.637v6.588a50.1 50.1 0 0 0 22.309 41.685l55.581 37.054a50.1 50.1 0 0 1 22.31 41.686v6.587M384.1 770.288v6.587a50.1 50.1 0 0 1-22.309 41.686l-55.581 37.054A50.099 50.099 0 0 0 283.9 897.3v6.588"
stroke="#334155"
></path>
<path
d="M384.1 770.288v6.587a50.1 50.1 0 0 1-22.309 41.686l-55.581 37.054A50.099 50.099 0 0 0 283.9 897.3v6.588M484.3 594.937v6.587a50.1 50.1 0 0 1-22.31 41.686l-55.581 37.054A50.1 50.1 0 0 0 384.1 721.95v6.587M484.3 872.575v6.587a50.1 50.1 0 0 1-22.31 41.686l-55.581 37.054a50.098 50.098 0 0 0-22.309 41.686v6.582M584.501 663.824v39.988a50.099 50.099 0 0 1-22.31 41.685l-55.581 37.054a50.102 50.102 0 0 0-22.309 41.686v6.587M283.899 945.637v6.588a50.1 50.1 0 0 1-22.309 41.685l-55.581 37.05a50.12 50.12 0 0 0-22.31 41.69v6.59M384.1 277.637c0 19.946 12.763 37.655 31.686 43.962l137.028 45.676c18.923 6.308 31.686 24.016 31.686 43.962M183.7 463.425v30.69c0 21.564 13.799 40.709 34.257 47.529l134.457 44.819c18.922 6.307 31.686 24.016 31.686 43.962M83.5 102.288c0 19.515 13.554 36.412 32.604 40.645l235.391 52.309c19.05 4.234 32.605 21.13 32.605 40.646M83.5 463.425v-58.45M183.699 542.75V396.625M283.9 1068.8V945.637M83.5 363.225v-141.95M83.5 179.524v-77.237M83.5 60.537V0M384.1 630.425V277.637M484.301 830.824V594.937M584.5 1068.8V663.825M484.301 555.275V452.988M584.5 622.075V452.988M384.1 728.537v-56.362M384.1 1068.8v-20.88M384.1 1006.17V770.287M283.9 903.888V759.85M183.699 1066.71V891.362M83.5 1068.8V716.012M83.5 674.263V505.175"
stroke="#334155"
></path>
<circle
cx="83.5"
cy="384.1"
r="10.438"
transform="rotate(-180 83.5 384.1)"
fill="#1E293B"
stroke="#334155"
></circle>
<circle
cx="83.5"
cy="200.399"
r="10.438"
transform="rotate(-180 83.5 200.399)"
stroke="#334155"
></circle>
<circle
cx="83.5"
cy="81.412"
r="10.438"
transform="rotate(-180 83.5 81.412)"
stroke="#334155"
></circle>
<circle
cx="183.699"
cy="375.75"
r="10.438"
transform="rotate(-180 183.699 375.75)"
fill="#1E293B"
stroke="#334155"
></circle>
<circle
cx="183.699"
cy="563.625"
r="10.438"
transform="rotate(-180 183.699 563.625)"
fill="#1E293B"
stroke="#334155"
></circle>
<circle
cx="384.1"
cy="651.3"
r="10.438"
transform="rotate(-180 384.1 651.3)"
fill="#1E293B"
stroke="#334155"
></circle>
<circle
cx="484.301"
cy="574.062"
r="10.438"
transform="rotate(-180 484.301 574.062)"
fill="#0EA5E9"
fill-opacity=".42"
stroke="#0EA5E9"
></circle>
<circle
cx="384.1"
cy="749.412"
r="10.438"
transform="rotate(-180 384.1 749.412)"
fill="#1E293B"
stroke="#334155"
></circle>
<circle
cx="384.1"
cy="1027.05"
r="10.438"
transform="rotate(-180 384.1 1027.05)"
stroke="#334155"
></circle>
<circle
cx="283.9"
cy="924.763"
r="10.438"
transform="rotate(-180 283.9 924.763)"
stroke="#334155"
></circle>
<circle
cx="183.699"
cy="870.487"
r="10.438"
transform="rotate(-180 183.699 870.487)"
stroke="#334155"
></circle>
<circle
cx="283.9"
cy="738.975"
r="10.438"
transform="rotate(-180 283.9 738.975)"
fill="#1E293B"
stroke="#334155"
></circle>
<circle
cx="83.5"
cy="695.138"
r="10.438"
transform="rotate(-180 83.5 695.138)"
fill="#1E293B"
stroke="#334155"
></circle>
<circle
cx="83.5"
cy="484.3"
r="10.438"
transform="rotate(-180 83.5 484.3)"
fill="#0EA5E9"
fill-opacity=".42"
stroke="#0EA5E9"
></circle>
<circle
cx="484.301"
cy="432.112"
r="10.438"
transform="rotate(-180 484.301 432.112)"
fill="#1E293B"
stroke="#334155"
></circle>
<circle
cx="584.5"
cy="432.112"
r="10.438"
transform="rotate(-180 584.5 432.112)"
fill="#1E293B"
stroke="#334155"
></circle>
<circle
cx="584.5"
cy="642.95"
r="10.438"
transform="rotate(-180 584.5 642.95)"
fill="#1E293B"
stroke="#334155"
></circle>
<circle
cx="484.301"
cy="851.699"
r="10.438"
transform="rotate(-180 484.301 851.699)"
stroke="#334155"
></circle>
<circle
cx="384.1"
cy="256.763"
r="10.438"
transform="rotate(-180 384.1 256.763)"
stroke="#334155"
></circle>
</g>
</svg>
</template>
<script>
export default {
name: "TimelineSvg",
};
</script>
+44
View File
@@ -0,0 +1,44 @@
<script setup lang="ts">
import { computed } from "#imports";
const props = withDefaults(
defineProps<{
type?: "note" | "warning";
title: string;
}>(),
{
type: "note",
}
);
const styles = computed(() => {
return {
note: {
container:
"bg-sky-50 dark:bg-slate-800/60 dark:ring-1 dark:ring-slate-300/10",
title: "text-sky-900 dark:text-sky-400",
body: "text-sky-800 [--tw-prose-background:theme(colors.sky.50)] prose-a:text-sky-900 prose-code:text-sky-900 dark:text-slate-300 dark:prose-code:text-slate-300",
},
warning: {
container:
"bg-amber-50 dark:bg-slate-800/60 dark:ring-1 dark:ring-slate-300/10",
title: "text-amber-900 dark:text-amber-500",
body: "text-amber-800 [--tw-prose-underline:theme(colors.amber.400)] [--tw-prose-background:theme(colors.amber.50)] prose-a:text-amber-900 prose-code:text-amber-900 dark:text-slate-300 dark:[--tw-prose-underline:theme(colors.sky.700)] dark:prose-code:text-slate-300",
},
}[props.type];
});
</script>
<template>
<div :class="['my-8 flex rounded-3xl p-6', styles.container]">
<!-- <IconComponent class="h-8 w-8 flex-none" />-->
<div class="ml-4 flex-auto">
<p :class="['m-0 font-display text-xl', styles.title]">
{{ title }}
</p>
<div :class="['prose mt-2.5', styles.body]">
<slot />
</div>
</div>
</div>
</template>
+3
View File
@@ -0,0 +1,3 @@
<template>
<p class="lead"><Markdown :use="$slots.default" unwrap="p" /></p>
</template>
+7
View File
@@ -0,0 +1,7 @@
<template>
<h2 :id="id"><slot /></h2>
</template>
<script setup lang="ts">
defineProps<{ id: string }>();
</script>
+7
View File
@@ -0,0 +1,7 @@
<template>
<h3 :id="id"><slot /></h3>
</template>
<script setup lang="ts">
defineProps<{ id: string }>();
</script>
+7
View File
@@ -0,0 +1,7 @@
<template>
<h4 :id="id"><slot /></h4>
</template>
<script setup lang="ts">
defineProps<{ id: string }>();
</script>
+7
View File
@@ -0,0 +1,7 @@
<template>
<h5 :id="id"><slot /></h5>
</template>
<script setup lang="ts">
defineProps<{ id: string }>();
</script>
+7
View File
@@ -0,0 +1,7 @@
<template>
<h6 :id="id"><slot /></h6>
</template>
<script setup lang="ts">
defineProps<{ id: string }>();
</script>
+29
View File
@@ -0,0 +1,29 @@
<script setup lang="ts">
defineProps<{
icon: string;
href: string;
title: string;
}>();
</script>
<template>
<div
class="group relative rounded-xl border border-slate-200 dark:border-slate-800"
>
<div
class="absolute -inset-px rounded-xl border-2 border-transparent opacity-0 [background:linear-gradient(var(--quick-links-hover-bg,theme(colors.sky.50)),var(--quick-links-hover-bg,theme(colors.sky.50)))_padding-box,linear-gradient(to_top,theme(colors.indigo.400),theme(colors.cyan.400),theme(colors.sky.500))_border-box] group-hover:opacity-100 dark:[--quick-links-hover-bg:theme(colors.slate.800)]"
/>
<div class="relative overflow-hidden rounded-xl p-6">
<!-- <Icon :icon="icon" class="h-8 w-8" />-->
<h2 class="mt-4 font-display text-base text-slate-900 dark:text-white">
<NuxtLink :href="href">
<span class="absolute -inset-px rounded-xl" />
{{ title }}
</NuxtLink>
</h2>
<p class="mt-1 text-sm text-slate-700 dark:text-slate-400">
<Markdown :use="$slots.default" unwrap="p" />
</p>
</div>
</div>
</template>
+7
View File
@@ -0,0 +1,7 @@
<script setup lang="ts"></script>
<template>
<div class="not-prose my-12 grid grid-cols-1 gap-6 sm:grid-cols-2">
<slot> </slot>
</div>
</template>
+11
View File
@@ -0,0 +1,11 @@
<script setup lang="ts"></script>
<template>
<svg aria-hidden="true" viewBox="0 0 16 16">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M7.23 3.333C7.757 2.905 7.68 2 7 2a6 6 0 1 0 0 12c.68 0 .758-.905.23-1.332A5.989 5.989 0 0 1 5 8c0-1.885.87-3.568 2.23-4.668ZM12 5a1 1 0 0 1 1 1 1 1 0 0 0 1 1 1 1 0 1 1 0 2 1 1 0 0 0-1 1 1 1 0 1 1-2 0 1 1 0 0 0-1-1 1 1 0 1 1 0-2 1 1 0 0 0 1-1 1 1 0 0 1 1-1Z"
/>
</svg>
</template>
+9
View File
@@ -0,0 +1,9 @@
<template>
<svg aria-hidden="true" viewBox="0 0 16 16">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M7 1a1 1 0 0 1 2 0v1a1 1 0 1 1-2 0V1Zm4 7a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm2.657-5.657a1 1 0 0 0-1.414 0l-.707.707a1 1 0 0 0 1.414 1.414l.707-.707a1 1 0 0 0 0-1.414Zm-1.415 11.313-.707-.707a1 1 0 0 1 1.415-1.415l.707.708a1 1 0 0 1-1.415 1.414ZM16 7.999a1 1 0 0 0-1-1h-1a1 1 0 1 0 0 2h1a1 1 0 0 0 1-1ZM7 14a1 1 0 1 1 2 0v1a1 1 0 1 1-2 0v-1Zm-2.536-2.464a1 1 0 0 0-1.414 0l-.707.707a1 1 0 0 0 1.414 1.414l.707-.707a1 1 0 0 0 0-1.414Zm0-8.486A1 1 0 0 1 3.05 4.464l-.707-.707a1 1 0 0 1 1.414-1.414l.707.707ZM3 8a1 1 0 0 0-1-1H1a1 1 0 0 0 0 2h1a1 1 0 0 0 1-1Z"
/>
</svg>
</template>
+11
View File
@@ -0,0 +1,11 @@
<script setup lang="ts"></script>
<template>
<svg aria-hidden="true" viewBox="0 0 16 16">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M1 4a3 3 0 0 1 3-3h8a3 3 0 0 1 3 3v4a3 3 0 0 1-3 3h-1.5l.31 1.242c.084.333.36.573.63.808.091.08.182.158.264.24A1 1 0 0 1 11 15H5a1 1 0 0 1-.704-1.71c.082-.082.173-.16.264-.24.27-.235.546-.475.63-.808L5.5 11H4a3 3 0 0 1-3-3V4Zm3-1a1 1 0 0 0-1 1v4a1 1 0 0 0 1 1h8a1 1 0 0 0 1-1V4a1 1 0 0 0-1-1H4Z"
/>
</svg>
</template>
+11 -11
View File
@@ -32,7 +32,7 @@ Otherwise content in this slot will affect it's positioning.
- `deselect {function}` - function to deselect an option
<SlotFooter />
<<< @/.vuepress/components/SlotFooter.vue
<<< @/.vitepress/components/SlotFooter.vue
## `header` <Badge text="3.8.0+" />
@@ -45,7 +45,7 @@ Displayed at the top of the component, above `.vs__dropdown-toggle`.
- `deselect {function}` - function to deselect an option
<SlotHeader />
<<< @/.vuepress/components/SlotHeader.vue
<<< @/.vitepress/components/SlotHeader.vue
## `list-footer` <Badge text="3.8.0+" />
@@ -58,7 +58,7 @@ so this slot should contain a root `<li>`.
- `filteredOptions {array}` - options filtered by the search text
<SlotListFooter />
<<< @/.vuepress/components/SlotListFooter.vue
<<< @/.vitepress/components/SlotListFooter.vue
## `list-header` <Badge text="3.8.0+" />
@@ -71,7 +71,7 @@ so this slot should contain a root `<li>`.
- `filteredOptions {array}` - options filtered by the search text
<SlotListHeader />
<<< @/.vuepress/components/SlotListHeader.vue
<<< @/.vitepress/components/SlotListHeader.vue
## `no-options`
@@ -83,7 +83,7 @@ The no options slot is displayed above `list-footer` in the dropdown when
- `searching {boolean}` - is the component searching
<SlotNoOptions />
<<< @/.vuepress/components/SlotNoOptions.vue
<<< @/.vitepress/components/SlotNoOptions.vue
## `open-indicator`
@@ -98,7 +98,7 @@ attributes: {
```
<SlotOpenIndicator />
<<< @/.vuepress/components/SlotOpenIndicator.vue
<<< @/.vitepress/components/SlotOpenIndicator.vue
## `option`
@@ -107,7 +107,7 @@ The current option within the dropdown, contained within `<li>`.
- `option {Object}` - The currently iterated option from `filteredOptions`
<SlotOption />
<<< @/.vuepress/components/SlotOption.vue
<<< @/.vitepress/components/SlotOption.vue
## `search`
@@ -151,7 +151,7 @@ If you want the default styling, you'll need to add `.vs__search` to the input y
```
<SlotSearch />
<<< @/.vuepress/components/SlotSearch.vue{5-6}
<<< @/.vitepress/components/SlotSearch.vue{5-6}
## `selected-option`
@@ -162,7 +162,7 @@ This slot doesn't exist if `selected-option-container` is implemented.
- `option {Object}` - A selected option
<SlotSelectedOption />
<<< @/.vuepress/components/SlotSelectedOption.vue
<<< @/.vitepress/components/SlotSelectedOption.vue
## `selected-option-container`
@@ -176,13 +176,13 @@ or have fine grain control over the markup.
- `multiple {Boolean}` - If the component supports the selection of multiple values
<SlotSelectedOptionContainer />
<<< @/.vuepress/components/SlotSelectedOptionContainer.vue
<<< @/.vitepress/components/SlotSelectedOptionContainer.vue
## `spinner`
- `loading {Boolean}` - if the component is in a loading state
<SlotSpinner />
<<< @/.vuepress/components/SlotSpinner.vue
<<< @/.vitepress/components/SlotSpinner.vue
</div>
@@ -55,10 +55,9 @@ these use cases.
4. **List with inline autocomplete**
> This is the same as list with automatic selection with one additional feature. The portion of
the selected suggestion that has not been typed by the user, a completion string, appears inline
after the input cursor in the textbox. The inline completion string is visually highlighted and
has a selected state.
🚧 Vue Select does not yet support this configuration, but it is on the roadmap
[#865](https://github.com/sagalbot/vue-select/issues/865). 🚧
> This is the same as list with automatic selection with one additional feature. The portion of the selected suggestion that has not been typed by the user, a completion string, appears inline after the input cursor in the textbox. The inline completion string is visually highlighted and has a selected state.
:::callout{type="warning"}
Vue Select does not yet support this configuration, but it is on the roadmap
[#865](https://github.com/sagalbot/vue-select/issues/865).
:::
@@ -24,7 +24,7 @@ about [CSS Custom Properties.](https://developer.mozilla.org/en-US/docs/Web/CSS/
<CssVariables style="margin-top: 1rem;" />
<<< @/.vuepress/components/CssVariables.vue
<<< @/.vitepress/components/CssVariables.vue
### Available CSS Variables <Badge type="primary">3.18+</Badge>
@@ -62,7 +62,7 @@ instances of Vue Select, or add your own classname if you just want to affect on
<CssSpecificity />
<<< @/.vuepress/components/CssSpecificity.vue
<<< @/.vitepress/components/CssSpecificity.vue
## Dropdown Transition
@@ -74,7 +74,6 @@ transition name is `vs__fade`. There's a couple ways to override or change this
negate the default CSS. If you want to remove it entirely, you can set it to an empty string.
```html
<v-select transition="" />
```
@@ -16,4 +16,4 @@ You can use the `filter` and `filterBy` props to hook right into something like
<FuseFilter />
<<< @/.vuepress/components/FuseFilter.vue
<<< @/.vitepress/components/FuseFilter.vue
@@ -1,3 +1,7 @@
<script setup>
import InfiniteScroll from '@/components/InfiniteScroll.vue'
</script>
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.
@@ -20,4 +24,4 @@ the scroll position.
<InfiniteScroll />
<<< @/.vuepress/components/InfiniteScroll.vue
<<< @/.vitepress/components/InfiniteScroll.vue
@@ -1,3 +1,7 @@
<script setup>
import CodePen from '../vitepress/components/CodePen.vue'
</script>
## Yarn / NPM
Install with yarn or npm:
@@ -9,7 +9,7 @@
<TagOnComma />
<<< @/.vuepress/components/TagOnComma.vue
<<< @/.vitepress/components/TagOnComma.vue
## mapKeyDown <Badge text="v3.3.0+" />
@@ -69,5 +69,5 @@ This is example listens for the `@` key, and autocompletes an email address with
<CustomHandlers />
<<< @/.vuepress/components/CustomHandlers.vue
<<< @/.vitepress/components/CustomHandlers.vue

Some files were not shown because too many files have changed in this diff Show More