2
0
mirror of https://github.com/tenrok/vue-select.git synced 2026-05-17 02:29:37 +03:00

docs: overhaul slot docs (#1099)

* docs: sort slots alphabetically
This commit is contained in:
Jeff Sagal
2020-03-11 09:16:07 -07:00
committed by GitHub
parent 1ec5d0dd8a
commit a820f06d61
12 changed files with 275 additions and 132 deletions
+7
View File
@@ -0,0 +1,7 @@
<template>
<v-select append-to-body>
<template #footer>
<div style="opacity: .8">Bottom of the component, in the footer slot!</div>
</template>
</v-select>
</template>
+7
View File
@@ -0,0 +1,7 @@
<template>
<v-select>
<template #header>
<div style="opacity: .8">Top of the component, in the header slot!</div>
</template>
</v-select>
</template>
@@ -0,0 +1,7 @@
<template>
<v-select>
<template #list-footer>
<li style="text-align: center">Bottom of the list!</li>
</template>
</v-select>
</template>
@@ -0,0 +1,7 @@
<template>
<v-select>
<template #list-header>
<li style="text-align: center">Top of the list!</li>
</template>
</v-select>
</template>
@@ -0,0 +1,7 @@
<template>
<v-select>
<template #no-options="{ search, searching, loading }">
This is the no options slot.
</template>
</v-select>
</template>
@@ -0,0 +1,7 @@
<template>
<v-select>
<template #open-indicator="{ attributes }">
<span v-bind="attributes">🔽</span>
</template>
</v-select>
</template>
+24
View File
@@ -0,0 +1,24 @@
<template>
<v-select :options="books" label="title">
<template #option="{ title, author }">
<h3 style="margin: 0">{{ title }}</h3>
<em>{{ author.firstName }} {{ author.lastName }}</em>
</template>
</v-select>
</template>
<script>
export default {
data: () => ({
books: [
{
title: "Old Man's War",
author: {
firstName: "John",
lastName: "Scalzi"
}
}
]
})
}
</script>
+12
View File
@@ -0,0 +1,12 @@
<template>
<v-select>
<template #search="{ attributes, events }">
<input
maxlength="1"
class="vs__search"
v-bind="attributes"
v-on="events"
>
</template>
</v-select>
</template>
@@ -0,0 +1,26 @@
<template>
<v-select v-model="selected" :options="books" label="title">
<template #selected-option="{ title, author }">
<div style="display: flex; align-items: baseline;">
<strong>{{ title }}</strong>
<em style="margin-left: .5rem;">by {{ author.firstName }} {{ author.lastName }}</em>
</div>
</template>
</v-select>
</template>
<script>
const book = {
title: "Old Man's War",
author: {
firstName: "John",
lastName: "Scalzi"
}
};
export default {
data: () => ({
books: [book],
selected: book
})
}
</script>
@@ -0,0 +1,23 @@
<template>
<v-select :options="books" label="title">
<template #selected-option-container="{ option, deselect, multiple, disabled }">
<div class="vs__selected">{{ option.title }}</div>
</template>
</v-select>
</template>
<script>
export default {
data: () => ({
books: [
{
title: "Old Man's War",
author: {
firstName: "John",
lastName: "Scalzi"
}
}
]
})
}
</script>
@@ -0,0 +1,9 @@
<template>
<v-select :loading="true">
<template #spinner="{ loading }">
<div v-if="loading" style="border-left-color: rgba(88,151,251,0.71)" class="vs__spinner">
The .vs__spinner class will hide the text for me.
</div>
</template>
</v-select>
</template>
+139 -132
View File
@@ -3,23 +3,22 @@ Vue Select leverages scoped slots to allow for total customization of the presen
Slots can be used to change the look and feel of the UI, or to simply swap out text.
:::
## Wrapper
<style>
.slot-docs h2 {
border-top: 1px solid #f0f0f0;
border-bottom: none;
margin-top: 2rem;
padding-top: 2rem;
}
.slot-docs h2:first-child {
border-top: none;
margin-top: 0;
}
</style>
### `header` <Badge text="3.8.0+" />
<div class="slot-docs">
Displayed at the top of the component, above `.vs__dropdown-toggle`.
- `search {string}` - the current search query
- `loading {boolean}` - is the component loading
- `searching {boolean}` - is the component searching
- `filteredOptions {array}` - options filtered by the search text
- `deselect {function}` - function to deselect an option
```html
<slot name="header" v-bind="scope.header" />
```
### `footer` <Badge text="3.8.0+" />
## `footer` <Badge text="3.8.0+" />
Displayed at the bottom of the component, below `.vs__dropdown-toggle`.
@@ -32,113 +31,23 @@ Otherwise content in this slot will affect it's positioning.
- `filteredOptions {array}` - options filtered by the search text
- `deselect {function}` - function to deselect an option
```html
<slot name="footer" v-bind="scope.footer" />
```
<SlotFooter />
<<< @/.vuepress/components/SlotFooter.vue
## Selected Option(s)
## `header` <Badge text="3.8.0+" />
### `selected-option`
#### Scope:
- `option {Object}` - A selected option
```html
<slot
name="selected-option"
v-bind="(typeof option === 'object')?option:{[label]: option}"
>
{{ getOptionLabel(option) }}
</slot>
```
### `selected-option-container`
#### Scope:
- `option {Object}` - A selected option
- `deselect {Function}` - Method used to deselect a given option when `multiple` is true
- `disabled {Boolean}` - Determine if the component is disabled
- `multiple {Boolean}` - If the component supports the selection of multiple values
```html
<slot
v-for="option in valueAsArray"
name="selected-option-container"
:option="(typeof option === 'object')?option:{[label]: option}"
:deselect="deselect"
:multiple="multiple"
:disabled="disabled"
>
<span class="selected-tag" v-bind:key="option.index">
<slot
name="selected-option"
v-bind="(typeof option === 'object')?option:{[label]: option}"
>
{{ getOptionLabel(option) }}
</slot>
<button
v-if="multiple"
:disabled="disabled"
@click="deselect(option)"
type="button"
class="close"
aria-label="Remove option"
>
<span aria-hidden="true">&times;</span>
</button>
</span>
</slot>
```
## Component Actions
### `spinner`
#### Scope:
- `loading {Boolean}` - if the component is in a loading state
```html
<slot name="spinner" v-bind="scope.spinner">
<div class="vs__spinner" v-show="mutableLoading">Loading...</div>
</slot>
```
### `open-indicator`
```js
attributes : {
'ref': 'openIndicator',
'role': 'presentation',
'class': 'vs__open-indicator',
}
```
```vue
<slot name="open-indicator" v-bind="scope.openIndicator">
<component :is="childComponents.OpenIndicator" v-if="!noDrop" v-bind="scope.openIndicator.attributes"/>
</slot>
```
## Dropdown
### `list-header` <Badge text="3.8.0+" />
Displayed as the first item in the dropdown. No content by default. Parent element is the `<ul>`,
so this slot should contain a root `<li>`.
Displayed at the top of the component, above `.vs__dropdown-toggle`.
- `search {string}` - the current search query
- `loading {boolean}` - is the component loading
- `searching {boolean}` - is the component searching
- `filteredOptions {array}` - options filtered by the search text
- `deselect {function}` - function to deselect an option
```html
<slot name="list-header" v-bind="scope.listHeader" />
```
<SlotHeader />
<<< @/.vuepress/components/SlotHeader.vue
### `list-footer` <Badge text="3.8.0+" />
## `list-footer` <Badge text="3.8.0+" />
Displayed as the last item in the dropdown. No content by default. Parent element is the `<ul>`,
so this slot should contain a root `<li>`.
@@ -148,34 +57,132 @@ so this slot should contain a root `<li>`.
- `searching {boolean}` - is the component searching
- `filteredOptions {array}` - options filtered by the search text
```html
<slot name="footer" v-bind="scope.listFooter" />
<SlotListFooter />
<<< @/.vuepress/components/SlotListFooter.vue
## `list-header` <Badge text="3.8.0+" />
Displayed as the first item in the dropdown. No content by default. Parent element is the `<ul>`,
so this slot should contain a root `<li>`.
- `search {string}` - the current search query
- `loading {boolean}` - is the component loading
- `searching {boolean}` - is the component searching
- `filteredOptions {array}` - options filtered by the search text
<SlotListHeader />
<<< @/.vuepress/components/SlotListHeader.vue
## `no-options`
The no options slot is displayed above `list-footer` in the dropdown when
`filteredOptions.length === 0`.
- `search {string}` - the current search query
- `loading {boolean}` - is the component loading
- `searching {boolean}` - is the component searching
<SlotNoOptions />
<<< @/.vuepress/components/SlotNoOptions.vue
## `open-indicator`
The open indicator is the caret icon on the component used to indicate dropdown status.
```js
attributes: {
'ref': 'openIndicator',
'role': 'presentation',
'class': 'vs__open-indicator',
}
```
### `option`
<SlotOpenIndicator />
<<< @/.vuepress/components/SlotOpenIndicator.vue
## `option`
The current option within the dropdown, contained within `<li>`.
- `option {Object}` - The currently iterated option from `filteredOptions`
```html
<slot
name="option"
v-bind="(typeof option === 'object')?option:{[label]: option}"
>
{{ getOptionLabel(option) }}
</slot>
<SlotOption />
<<< @/.vuepress/components/SlotOption.vue
## `search`
The search input has a lot of bindings, but they're grouped into `attributes` and `events`. Most
of the time, you will just be binding those two with `v-on="events"` and `v-bind="attributes"`.
If you want the default styling, you'll need to add `.vs__search` to the input you provide.
```js
/**
* Attributes to be bound to a search input.
*/
attributes: {
'disabled': this.disabled,
'placeholder': this.searchPlaceholder,
'tabindex': this.tabindex,
'readonly': !this.searchable,
'id': this.inputId,
'aria-autocomplete': 'list',
'aria-labelledby': `vs${this.uid}__combobox`,
'aria-controls': `vs${this.uid}__listbox`,
'aria-activedescendant': this.typeAheadPointer > -1
? `vs${this.uid}__option-${this.typeAheadPointer}`
: '',
'ref': 'search',
'type': 'search',
'autocomplete': this.autocomplete,
'value': this.search,
},
/**
* Events that this element should handle.
*/
events: {
'compositionstart': () => this.isComposing = true,
'compositionend': () => this.isComposing = false,
'keydown': this.onSearchKeyDown,
'blur': this.onSearchBlur,
'focus': this.onSearchFocus,
'input': (e) => this.search = e.target.value,
}
```
### `no-options`
<SlotSearch />
<<< @/.vuepress/components/SlotSearch.vue{5-6}
The no options slot is displayed in the dropdown when `filteredOptions.length === 0`.
## `selected-option`
- `search {String}` - the current search text
- `searching {Boolean}` - if the component has search text
The text displayed within `selected-option-container`.
```vue
<slot name="no-options" v-bind="scope.noOptions">
Sorry, no matching options.
</slot>
```
This slot doesn't exist if `selected-option-container` is implemented.
- `option {Object}` - A selected option
<SlotSelectedOption />
<<< @/.vuepress/components/SlotSelectedOption.vue
## `selected-option-container`
This is the root element where `v-for="option in selectedValue"`. Most of the time you'll want to
use `selected-option`, but this container is useful if you want to disable the deselect button,
or have fine grain control over the markup.
- `option {Object}` - Currently iterated selected option
- `deselect {Function}` - Method used to deselect a given option when `multiple` is true
- `disabled {Boolean}` - Determine if the component is disabled
- `multiple {Boolean}` - If the component supports the selection of multiple values
<SlotSelectedOptionContainer />
<<< @/.vuepress/components/SlotSelectedOptionContainer.vue
## `spinner`
- `loading {Boolean}` - if the component is in a loading state
<SlotSpinner />
<<< @/.vuepress/components/SlotSpinner.vue
</div>