├── .babelrc
├── .browserslistrc
├── .gitignore
├── .prettierignore
├── .prettierrc
├── LICENSE
├── README.md
├── build
├── base
│ └── plugins
│ │ └── index.js
├── rollup.config.dev.js
└── rollup.config.prod.js
├── demo
├── App.vue
├── index.html
└── index.js
├── package-lock.json
├── package.json
├── postcss.config.js
├── src
├── components
│ └── VueAccessibleSelect
│ │ └── VueAccessibleSelect.vue
├── config
│ └── index.js
├── index.js
└── styles
│ ├── core.scss
│ └── themes
│ └── default.scss
└── types
└── index.d.ts
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [["@babel/preset-env"]]
3 | }
4 |
--------------------------------------------------------------------------------
/.browserslistrc:
--------------------------------------------------------------------------------
1 | > 1%
2 | last 2 versions
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules
3 | dist/*
4 | demo/demo*
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | dist
--------------------------------------------------------------------------------
/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": false,
3 | "singleQuote": true,
4 | "trailingComma": "es5"
5 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Andrew Vasilchuk
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # vue-accessible-select
2 |
3 | > Vue.js accessible select component made according to [WAI-ARIA practices](https://www.w3.org/TR/wai-aria-practices/#Listbox).
4 |
5 | ## ✨ Features
6 |
7 | - fully accessible;
8 | - ⌨️ keyboard navigation (`Page Up/Down`, `Home`, `End`, `Esc`);
9 | - 🔣 type-ahead to select option that starts with typed symbols;
10 | - 💅 style agnostic, so you can style it whatever you like (but including `core.scss` is highly encouraged).
11 |
12 | ## Demo
13 |
14 | [](https://codesandbox.io/s/vue-accessible-select-qse3r?fontsize=14)
15 |
16 | ## 💿 Installation
17 |
18 | ### 📦 Via NPM
19 |
20 | ```bash
21 | $ npm install vue-accessible-select --save
22 | ```
23 |
24 | ### 🧶 Via Yarn
25 |
26 | ```bash
27 | $ yarn add vue-accessible-select
28 | ```
29 |
30 | ## Initialization
31 |
32 | ### As a plugin
33 |
34 | It must be called before `new Vue()`.
35 |
36 | ```js
37 | import Vue from 'vue'
38 | import VueAccessibleSelect from 'vue-accessible-select'
39 |
40 | Vue.use(VueAccessibleSelect)
41 | ```
42 |
43 | ### As a global component
44 |
45 | ```javascript
46 | import Vue from 'vue'
47 | import { VueAccessibleSelect } from 'vue-accessible-select'
48 |
49 | Vue.component('VueAccessibleSelect', VueAccessibleSelect)
50 | ```
51 |
52 | ### As a local component
53 |
54 | ```javascript
55 | import { VueAccessibleSelect } from 'vue-accessible-select'
56 |
57 | export default {
58 | name: 'YourAwesomeComponent',
59 | components: {
60 | VueAccessibleSelect,
61 | },
62 | }
63 | ```
64 |
65 | > ℹ️ Note to set global options (for example `transition` for each select component), you should do the following:
66 |
67 | ```js
68 | import { config } from 'vue-accessible-select'
69 |
70 | config.transition = {
71 | name: 'foo',
72 | }
73 | ```
74 |
75 | > ⚠️ Options passed locally via `props` will always take precedence over global config options.
76 |
77 | Default `config.js`:
78 |
79 | ```js
80 | export default {
81 | transition: null,
82 | }
83 | ```
84 |
85 | ## 🚀 Usage
86 |
87 | ### Template
88 |
89 | ```html
90 |
91 |
99 |
100 | ```
101 |
102 | ### Script
103 |
104 | ```js
105 | export default {
106 | // ...
107 | data() {
108 | return {
109 | value: undefined,
110 | options: [
111 | {
112 | value: 0,
113 | label: '🍇 Grape',
114 | },
115 | {
116 | value: { foo: 'bar' },
117 | label: '🍉 Watermelon',
118 | },
119 | {
120 | value: { foo: 'bar' },
121 | label: '🥝 Kiwi',
122 | },
123 | {
124 | value: false,
125 | label: '🥭 Mango',
126 | },
127 | {
128 | value: true,
129 | label: '🍓 Strawberry',
130 | },
131 | {
132 | value: 'lemon',
133 | label: '🍋 Lemon',
134 | },
135 | ],
136 | }
137 | },
138 | // ...
139 | }
140 | ```
141 |
142 | ### 🎨 Styles
143 |
144 | Then don't forget to include core styles. Also library is sipped with default theme styles you can use.
145 |
146 | `SASS`:
147 |
148 | ```scss
149 | // recommended
150 | @import 'vue-accessible-select/src/styles/core.scss';
151 |
152 | // optional
153 | @import 'vue-accessible-select/src/styles/themes/default.scss';
154 | ```
155 |
156 | Or already compiled `CSS`:
157 |
158 | ```css
159 | /* recommended */
160 | @import 'vue-accessible-select/dist/styles/core.scss';
161 |
162 | /* optional */
163 | @import 'vue-accessible-select/dist/styles/themes/default.scss';
164 | ```
165 |
166 | > ⚠️ Note that when you import already compiled CSS you don't have ability to override `SASS` variables during build process, so it is preferable to use `.scss` file.
167 |
168 | When importing `core.scss`, there are `SASS` variables you can override during build process:
169 |
170 | ```scss
171 | $v-select-menu-position-top: 100% !default;
172 | $v-select-arrow-size: 8px !default;
173 | ```
174 |
175 | ### API
176 |
177 | #### ⚙️ Props
178 |
179 | `` accepts some `props`:
180 |
181 | | Prop | Description |
182 | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
183 | | `options: array` | `required` Array of select options. Should be an array of objects that match the following pattern `{ value: any, label: string }` |
184 | | `value: any` | `required` Current value of select. When value is `undefined`, it is considered that select has no current value. |
185 | | `label: string` | Select label |
186 | | `placeholder: string` | Select placeholder |
187 | | `disabled: boolean` | Whether select is disabled |
188 | | `transition: object` | Through this object you can configure the transition of `.v-select__menu` entrance and leave. Should match the following pattern `{ name: string, mode: string? }` |
189 |
190 | #### 🕳️ Slots
191 |
192 | `` provides you with some `slots` and `scopedSlots` you can use to fit your needs.
193 |
194 | | Slot | Scope | Description |
195 | | ------------- | ------------------- | ---------------- |
196 | | `label` | | Label slot |
197 | | `prepend` | | Prepend slot |
198 | | `placeholder` | `{ placeholder }` | Placeholder slot |
199 | | `selected` | `{ value, option }` | Selected slot |
200 | | `arrow` | | Arrow slot |
201 | | `option` | `{ value, option }` | Option slot |
202 | | `no-options` | | No options slot |
203 |
204 | #### Example of possible usage of `slots` and `scopedSlots`
205 |
206 | ```html
207 |
208 |
209 | 😋 Just a label slot:
210 |
211 |
212 |
215 |
216 | 🎃 I am a placeholder slot
219 | 🔥 Woooow, {{ option.label }}
222 | Option: {{ option.label }}
225 | Keine Optionen
228 |
229 | ```
230 |
231 | ## ⌨️ Keyboard shortcuts
232 |
233 | `` is fully accessible when it comes to keyboard interaction.
234 |
235 | Here is some useful keys and their appropriate actions:
236 |
237 | - `Down Arrow` – Moves focus and selection to the next option.
238 | - `Up Arrow` – Moves focus and selection to the previous option.
239 | - `Home` – Moves focus and selection to the first option.
240 | - `End` – Moves focus and selection to the last option.
241 | - `Esc` – Closes menu.
242 |
243 | Type ahead:
244 |
245 | - Type a character: focus and selection moves to the next option with a label that starts with the typed character;
246 | - Type multiple characters in rapid succession: focus and selection moves to the next option with a label that starts with the string of characters typed.
247 |
248 | ## Powered by
249 |
250 | - `Rollup` (and plugins);
251 | - `SASS` and `node-sass`;
252 | - `PostCSS`;
253 | - `Autoprefixer`.
254 |
255 | ## 🔒 License
256 |
257 | [MIT](http://opensource.org/licenses/MIT)
258 |
--------------------------------------------------------------------------------
/build/base/plugins/index.js:
--------------------------------------------------------------------------------
1 | import resolve from '@rollup/plugin-node-resolve'
2 | import commonjs from '@rollup/plugin-commonjs'
3 | import vue from 'rollup-plugin-vue'
4 |
5 | export default [resolve(), commonjs(), vue({ needMap: false })]
6 |
--------------------------------------------------------------------------------
/build/rollup.config.dev.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import serve from 'rollup-plugin-serve'
3 | import livereload from 'rollup-plugin-livereload'
4 | import replace from '@rollup/plugin-replace'
5 |
6 | import plugins from './base/plugins/index'
7 |
8 | export default {
9 | input: path.join(__dirname, '../demo/index.js'),
10 | output: {
11 | file: path.join(__dirname, '../demo/demo.js'),
12 | format: 'iife',
13 | sourcemap: true,
14 | },
15 | plugins: [
16 | replace({
17 | 'process.env.NODE_ENV': JSON.stringify('development'),
18 | }),
19 | serve({
20 | open: true,
21 | contentBase: path.join(__dirname, '../demo'),
22 | port: 8080,
23 | }),
24 | livereload({
25 | verbose: true,
26 | watch: path.join(__dirname, '../demo'),
27 | }),
28 | ].concat(plugins),
29 | }
30 |
--------------------------------------------------------------------------------
/build/rollup.config.prod.js:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import replace from '@rollup/plugin-replace'
3 | import { babel } from '@rollup/plugin-babel'
4 | import { terser } from 'rollup-plugin-terser'
5 |
6 | import plugins from './base/plugins/index.js'
7 |
8 | const name = 'VueAccessibleSelect'
9 |
10 | export default [
11 | {
12 | input: path.join(__dirname, '../src/index.js'),
13 | output: [
14 | {
15 | file: 'dist/vue-accessible-select.js',
16 | format: 'umd',
17 | name,
18 | },
19 | {
20 | file: 'dist/vue-accessible-select.common.js',
21 | format: 'cjs',
22 | },
23 | {
24 | file: 'dist/vue-accessible-select.esm.js',
25 | format: 'esm',
26 | },
27 | ],
28 | plugins: [
29 | replace({
30 | 'process.env.NODE_ENV': JSON.stringify('production'),
31 | }),
32 | ].concat(plugins),
33 | },
34 | {
35 | input: path.join(__dirname, '../src/index.js'),
36 | output: {
37 | file: 'dist/vue-accessible-select.min.js',
38 | format: 'umd',
39 | name,
40 | },
41 | plugins: [
42 | replace({
43 | 'process.env.NODE_ENV': JSON.stringify('production'),
44 | }),
45 | babel(),
46 | terser(),
47 | ].concat(plugins),
48 | },
49 | ]
50 |
--------------------------------------------------------------------------------
/demo/App.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
vue-accessible-select
4 |
54 |
55 |
56 |
57 |
108 |
109 |
--------------------------------------------------------------------------------
/demo/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | vue-accessible-select
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/demo/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App.vue'
3 | import VueAccessibleSelectPlugin from '../src'
4 |
5 | Vue.config.productionTip = false
6 |
7 | Vue.use(VueAccessibleSelectPlugin)
8 |
9 | new Vue({
10 | el: '#app',
11 | render: h => h(App),
12 | })
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "vue-accessible-select",
3 | "version": "1.2.1",
4 | "private": false,
5 | "description": "Vue.js component for accessible selects",
6 | "keywords": [
7 | "accessibility",
8 | "select",
9 | "vue",
10 | "vue-accessible-select",
11 | "vue-select"
12 | ],
13 | "homepage": "https://github.com/andrewvasilchuk/vue-accessible-select#readme",
14 | "bugs": {
15 | "url": "https://github.com/andrewvasilchuk/vue-accessible-select/issues"
16 | },
17 | "repository": {
18 | "type": "git",
19 | "url": "https://github.com/andrewvasilchuk/vue-accessible-select"
20 | },
21 | "license": "MIT",
22 | "author": "Andrew Vasilchuk ",
23 | "files": [
24 | "src",
25 | "dist",
26 | "types/*.d.ts"
27 | ],
28 | "main": "dist/vue-accessible-select.js",
29 | "unpkg": "dist/vue-accessible-select.min.js",
30 | "module": "dist/vue-accessible-select.esm.js",
31 | "types": "types/index.d.ts",
32 | "scripts": {
33 | "prepare": "npm run build",
34 | "build": "rimraf dist/* && rollup -c build/rollup.config.prod.js && npm run build:css && npm run postcss",
35 | "build:css": "node-sass ./src -o ./dist --output-style compressed -x",
36 | "dev": "rollup -c build/rollup.config.dev.js --watch",
37 | "postcss": "postcss ./dist/**/*.css -r --no-map",
38 | "test:unit": "jest"
39 | },
40 | "devDependencies": {
41 | "@babel/core": "^7.16.7",
42 | "@babel/preset-env": "^7.16.7",
43 | "@rollup/plugin-babel": "^5.3.0",
44 | "@rollup/plugin-commonjs": "^21.0.1",
45 | "@rollup/plugin-node-resolve": "^13.1.3",
46 | "@rollup/plugin-replace": "^3.0.1",
47 | "autoprefixer": "^10.4.2",
48 | "babel-core": "^7.0.0-bridge.0",
49 | "node-sass": "^7.0.1",
50 | "postcss": "^8.4.5",
51 | "postcss-cli": "^9.1.0",
52 | "pug": "^3.0.2",
53 | "rimraf": "^3.0.2",
54 | "rollup": "^2.63.0",
55 | "rollup-plugin-livereload": "^2.0.5",
56 | "rollup-plugin-postcss": "^4.0.2",
57 | "rollup-plugin-serve": "^1.1.0",
58 | "rollup-plugin-terser": "^7.0.2",
59 | "rollup-plugin-vue": "^4.7.2",
60 | "vue": "^2.6.14",
61 | "vue-template-compiler": "^2.6.14"
62 | },
63 | "peerDependencies": {
64 | "vue": "^2.6.14"
65 | },
66 | "dependencies": {
67 | "keycode-js": "^3.1.0"
68 | }
69 | }
70 |
--------------------------------------------------------------------------------
/postcss.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | plugins: [require('autoprefixer')],
3 | }
4 |
--------------------------------------------------------------------------------
/src/components/VueAccessibleSelect/VueAccessibleSelect.vue:
--------------------------------------------------------------------------------
1 |
2 | .v-select(:class="className")
3 | span.v-select__label(
4 | v-if="hasSlot('label') || label"
5 | :id="labelId"
6 | )
7 | slot(name="label") {{ label }}:
8 | .v-select__inner
9 | button.v-select__btn(
10 | :id="buttonId"
11 | ref="button"
12 | :disabled="disabled"
13 | :aria-expanded="ariaExpanded"
14 | :aria-labelledby="`${labelId ? labelId : ''} ${buttonId}`"
15 | type="button"
16 | aria-haspopup="listbox"
17 | @click="toggle"
18 | @blur="buttonBlurHandler"
19 | )
20 | span.v-select__prepend(v-if="hasSlot('prepend')")
21 | slot(name="prepend")
22 | span.v-select__placeholder(v-if="(placeholder || hasSlot('placeholder')) && value === undefined || !optionsHasValue")
23 | slot(
24 | name="placeholder"
25 | :placeholder="placeholder"
26 | ) {{ placeholder }}
27 | span.v-select__selected
28 | slot(
29 | v-if="value !== undefined && optionsHasValue"
30 | :value="value"
31 | :option="currentOption"
32 | name="selected"
33 | ) {{ currentOption ? currentOption.label : value }}
34 | span.v-select__arrow
35 | slot(name="arrow")
36 | svg(viewBox="0 0 255 255")
37 | path(d="M0 64l128 127L255 64z")
38 | transition(
39 | :name="transition ? transition.name : ''"
40 | :mode="transition ? transition.mode : ''"
41 | )
42 | .v-select__menu(v-if="open")
43 | ul.v-select__list(
44 | v-if="options && options.length"
45 | ref="list"
46 | :aria-activedescendant="value && getOptionId(value)"
47 | :aria-labelledby="labelId"
48 | role="listbox"
49 | tabindex="-1"
50 | @keydown="keydownHandler"
51 | @keyup.35="setLastSelected"
52 | @keyup.36="setFirstSelected"
53 | @keyup.esc="escapeHandler"
54 | @keyup="printHandler"
55 | @blur="menuBlurHandler"
56 | )
57 | li.v-select__option(
58 | v-for="(option, index) in options" :key="index"
59 | :id="getOptionId(option)" role="option"
60 | ref="options"
61 | :class="{ 'v-select__option--selected': isSelected(option) }"
62 | @click="clickHandler(option)" :aria-selected="isSelected(option) ? 'true': 'false'"
63 | )
64 | slot(
65 | name="option"
66 | :option="option"
67 | :value="value"
68 | )
69 | span {{ option.label }}
70 | template(v-else)
71 | .v-select__no-options
72 | slot(name="no-optioms")
73 | span No options provided
74 |
75 |
76 |
332 |
--------------------------------------------------------------------------------
/src/config/index.js:
--------------------------------------------------------------------------------
1 | export default {
2 | transition: null,
3 | }
4 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import VueAccessibleSelect from './components/VueAccessibleSelect/VueAccessibleSelect.vue'
2 |
3 | import config from './config'
4 |
5 | const Plugin = {
6 | install(Vue) {
7 | // Make sure that plugin can be installed only once
8 | if (this.installed) {
9 | return
10 | }
11 |
12 | Vue.component('VueAccessibleSelect', VueAccessibleSelect)
13 | },
14 | }
15 |
16 | export default Plugin
17 |
18 | export { VueAccessibleSelect, config }
19 |
--------------------------------------------------------------------------------
/src/styles/core.scss:
--------------------------------------------------------------------------------
1 | // v-select__menu styles
2 | $v-select-menu-position-top: 100% !default;
3 |
4 | // v-select__arrow styles
5 | $v-select-arrow-size: 8px !default;
6 |
7 | .v-select {
8 | &__inner {
9 | position: relative;
10 | }
11 |
12 | &__menu {
13 | position: absolute;
14 | top: $v-select-menu-position-top;
15 | left: 0;
16 | width: 100%;
17 | }
18 |
19 | &__list {
20 | padding-left: 0;
21 | margin: {
22 | top: 0;
23 | bottom: 0;
24 | }
25 | list-style: none;
26 | overflow: auto;
27 | }
28 |
29 | &__arrow {
30 | margin-left: auto;
31 |
32 | svg {
33 | display: inline-block;
34 | width: $v-select-arrow-size;
35 | height: $v-select-arrow-size;
36 | vertical-align: middle;
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/styles/themes/default.scss:
--------------------------------------------------------------------------------
1 | // v-select__label styles
2 | $v-select-label-display: inline-block !default;
3 | $v-select-label-margin-bottom: 8px !default;
4 | $v-select-label-font-size: 14px !default;
5 |
6 | // v-select__btn styles
7 | $v-select-btn-display: flex !default;
8 | $v-select-btn-width: 100% !default;
9 | $v-select-btn-height: 38px !default;
10 | $v-select-btn-horizontal-padding: 16px !default;
11 | $v-select-btn-vertical-padding: 0 !default;
12 | $v-select-btn-border-width: 1px !default;
13 | $v-select-btn-border-style: solid !default;
14 | $v-select-btn-border-color: #ced4da !default;
15 | $v-select-btn-border-radius: 4px !default;
16 | $v-select-btn-background-color: #fff !default;
17 | $v-select-btn-border-color-focus: #80bdff !default;
18 | $v-select-btn-box-shadow-focus: 0 0 0 4px rgba(0, 128, 255, 0.24) !default;
19 | $v-select-btn-font-size: 100% !default;
20 |
21 | // v-select__menu styles
22 | $v-select-menu-vertical-padding: 8px !default;
23 | $v-select-menu-border-width: 1px !default;
24 | $v-select-menu-border-style: solid !default;
25 | $v-select-menu-border-color: rgba(0, 0, 0, 0.15) !default;
26 | $v-select-menu-border-radius: 4px !default;
27 | $v-select-menu-background-color: #fff !default;
28 |
29 | // v-select__list styles
30 | $v-select-list-max-height: 160px !default;
31 |
32 | // v-select__option styles
33 | $v-select-option-padding: 4px 16px !default;
34 | $v-select-option-background-color-hover: #f8f9fa !default;
35 | $v-select-option-color-selected: #fff !default;
36 | $v-select-option-background-color-selected: #007bff !default;
37 |
38 | .v-select {
39 | $block: &;
40 |
41 | &__label {
42 | display: $v-select-label-display;
43 | margin-bottom: $v-select-label-margin-bottom;
44 | font-size: $v-select-label-font-size;
45 | }
46 |
47 | &__btn {
48 | display: $v-select-btn-display;
49 | width: $v-select-btn-width;
50 | height: $v-select-btn-height;
51 | padding: $v-select-btn-vertical-padding $v-select-btn-horizontal-padding;
52 | border: $v-select-btn-border-width $v-select-btn-border-style $v-select-btn-border-color;
53 | border-radius: $v-select-btn-border-radius;
54 | background-color: $v-select-btn-background-color;
55 | font-size: $v-select-btn-font-size;
56 |
57 | @if $v-select-btn-display == flex {
58 | align-items: center;
59 | }
60 |
61 | &:focus {
62 | outline: 0;
63 | border-color: $v-select-btn-border-color-focus;
64 | box-shadow: $v-select-btn-box-shadow-focus;
65 | }
66 | }
67 |
68 | &__menu {
69 | padding: {
70 | top: $v-select-menu-vertical-padding;
71 | bottom: $v-select-menu-vertical-padding;
72 | }
73 | border: $v-select-menu-border-width $v-select-menu-border-style $v-select-menu-border-color;
74 | border-radius: $v-select-menu-border-radius;
75 | background-color: $v-select-menu-background-color;
76 | }
77 |
78 | &__list {
79 | max-height: $v-select-list-max-height;
80 |
81 | &:focus {
82 | outline: 0;
83 | }
84 | }
85 |
86 | &__option {
87 | padding: $v-select-option-padding;
88 | cursor: pointer;
89 |
90 | &:hover:not(#{$block}__option--selected) {
91 | background-color: $v-select-option-background-color-hover;
92 | }
93 |
94 | &--selected {
95 | background-color: $v-select-option-background-color-selected;
96 | color: $v-select-option-color-selected;
97 | }
98 | }
99 | }
--------------------------------------------------------------------------------
/types/index.d.ts:
--------------------------------------------------------------------------------
1 | import { PluginFunction } from 'vue'
2 |
3 | declare const VueAccessibleSelect: VueAccessibleSelect
4 |
5 | export default VueAccessibleSelect
6 |
7 | export interface VueAccessibleSelect {
8 | install: PluginFunction
9 | }
10 |
11 | export interface VueAccessibleSelectOption {
12 | value: any
13 | label: string
14 | }
15 |
16 | export type VueAccessibleSelectOptions = VueAccessibleSelectOption[]
17 |
--------------------------------------------------------------------------------