@irina_grigoreva/accessible-vue-search-select 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +274 -0
- package/dist/accessible-vue-search-select.css +1 -0
- package/dist/accessible-vue-search-select.js +468 -0
- package/dist/accessible-vue-search-select.umd.cjs +1 -0
- package/dist/components/SelectSimpleSearch.vue.d.ts +79 -0
- package/dist/index.d.ts +4 -0
- package/dist/types.d.ts +53 -0
- package/package.json +302 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
# Accessible Vue Search Select
|
|
2
|
+
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
7
|
+
|
|
8
|
+
A reusable and accessible Vue 3 combobox/listbox component built with TypeScript.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- Vue 3.5+ component built with `<script setup lang="ts">`
|
|
15
|
+
- Accessible searchable combobox/listbox pattern
|
|
16
|
+
- `v-model` support for objects and primitive values via `emitValue`
|
|
17
|
+
- Teleported dropdown with optional inline listbox mode
|
|
18
|
+
- Loading, empty, disabled, clearable, and error states
|
|
19
|
+
- Light and dark mode support via CSS custom properties
|
|
20
|
+
- Custom option and selected-value slots
|
|
21
|
+
- Flexible `labelKey`, `valueKey`, and `searchKeys` mapping
|
|
22
|
+
- Configurable `inputId`, `listboxId`, and ARIA labels
|
|
23
|
+
- Stable ARIA relationships:
|
|
24
|
+
- `aria-controls`
|
|
25
|
+
- `aria-expanded`
|
|
26
|
+
- `aria-activedescendant`
|
|
27
|
+
- `aria-selected`
|
|
28
|
+
- Keyboard navigation support
|
|
29
|
+
- Vitest + Vue Test Utils coverage
|
|
30
|
+
- Library build with exported TypeScript types
|
|
31
|
+
|
|
32
|
+
## Demo
|
|
33
|
+
|
|
34
|
+
<video src="./demo/demo.mp4" controls autoplay loop muted playsinline></video>
|
|
35
|
+
|
|
36
|
+
Run the local demo:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
npm install
|
|
40
|
+
npm run dev
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Then open:
|
|
44
|
+
|
|
45
|
+
```text
|
|
46
|
+
http://127.0.0.1:5173/
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
The demo source is in [examples/SelectSimpleSearchDemo.vue](./examples/SelectSimpleSearchDemo.vue).
|
|
50
|
+
|
|
51
|
+
## Installation
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
npm install accessible-vue-search-select
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Import the component and styles:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
import { SelectSimpleSearch } from "accessible-vue-search-select";
|
|
61
|
+
import "accessible-vue-search-select/dist/accessible-vue-search-select.css";
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
For local development in this repository:
|
|
65
|
+
|
|
66
|
+
```bash
|
|
67
|
+
npm install
|
|
68
|
+
npm run typecheck
|
|
69
|
+
npm run test
|
|
70
|
+
npm run build
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
## Basic Usage
|
|
74
|
+
|
|
75
|
+
```vue
|
|
76
|
+
<script setup lang="ts">
|
|
77
|
+
import { ref } from "vue";
|
|
78
|
+
import { SelectSimpleSearch, type SelectOption } from "accessible-vue-search-select";
|
|
79
|
+
import "accessible-vue-search-select/dist/accessible-vue-search-select.css";
|
|
80
|
+
|
|
81
|
+
const selected = ref<SelectOption | null>(null);
|
|
82
|
+
|
|
83
|
+
const states = [
|
|
84
|
+
{ label: "California", value: "ca" },
|
|
85
|
+
{ label: "New York", value: "ny" },
|
|
86
|
+
{ label: "Texas", value: "tx" },
|
|
87
|
+
];
|
|
88
|
+
</script>
|
|
89
|
+
|
|
90
|
+
<template>
|
|
91
|
+
<SelectSimpleSearch
|
|
92
|
+
v-model="selected"
|
|
93
|
+
label="State"
|
|
94
|
+
placeholder="Choose a state"
|
|
95
|
+
:options="states"
|
|
96
|
+
label-key="label"
|
|
97
|
+
value-key="value"
|
|
98
|
+
/>
|
|
99
|
+
</template>
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Primitive `v-model` values:
|
|
103
|
+
|
|
104
|
+
```vue
|
|
105
|
+
<script setup lang="ts">
|
|
106
|
+
import { ref } from "vue";
|
|
107
|
+
|
|
108
|
+
const selectedState = ref<string | number | null>(null);
|
|
109
|
+
</script>
|
|
110
|
+
|
|
111
|
+
<template>
|
|
112
|
+
<SelectSimpleSearch
|
|
113
|
+
v-model="selectedState"
|
|
114
|
+
emit-value
|
|
115
|
+
label="State"
|
|
116
|
+
:options="states"
|
|
117
|
+
/>
|
|
118
|
+
</template>
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Facility-style objects are supported by default:
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
const facilities = [
|
|
125
|
+
{
|
|
126
|
+
id: 1,
|
|
127
|
+
slug: "seattle-storage",
|
|
128
|
+
public_title: "",
|
|
129
|
+
address: {
|
|
130
|
+
city: "Seattle",
|
|
131
|
+
full_address: "8 Pine Street, Seattle, WA",
|
|
132
|
+
},
|
|
133
|
+
},
|
|
134
|
+
];
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
This renders the selected label as `Seattle - Storage Facility`.
|
|
138
|
+
|
|
139
|
+
## Props
|
|
140
|
+
|
|
141
|
+
| Prop | Type | Default | Description |
|
|
142
|
+
| --- | --- | --- | --- |
|
|
143
|
+
| `options` | `SelectOption[]` | `[]` | Options to render. |
|
|
144
|
+
| `modelValue` | `SelectOption \| string \| number \| null` | `null` | Selected value for `v-model`. |
|
|
145
|
+
| `placeholder` | `string` | `"Select an option"` | Input placeholder. |
|
|
146
|
+
| `type` | `string` | `"default"` | Optional compatibility class. |
|
|
147
|
+
| `inlineListbox` | `boolean` | `false` | Render listbox inline instead of teleporting to `body`. |
|
|
148
|
+
| `closeOnBlur` | `boolean` | `false` | Close after input blur. |
|
|
149
|
+
| `label` | `string` | `""` | Visible input label. |
|
|
150
|
+
| `name` | `string` | `"select-simple-search"` | Input name. |
|
|
151
|
+
| `inputId` | `string` | generated | Input id. |
|
|
152
|
+
| `listboxId` | `string` | generated | Listbox id used by `aria-controls` and option ids. |
|
|
153
|
+
| `ariaLabel` | `string` | `"Search options"` | Accessible label when no visible label is provided. |
|
|
154
|
+
| `labelKey` | `string` | `""` | Dot-path used for option labels. |
|
|
155
|
+
| `valueKey` | `string` | `""` | Dot-path used for option values. |
|
|
156
|
+
| `searchKeys` | `string[]` | common label/facility fields | Dot-path fields searched by the input. |
|
|
157
|
+
| `disabled` | `boolean` | `false` | Disable the component. |
|
|
158
|
+
| `clearable` | `boolean` | `true` | Show clear button when selected. |
|
|
159
|
+
| `clearLabel` | `string` | `"Clear selection"` | Clear button accessible label. |
|
|
160
|
+
| `noResultsText` | `string` | `"No results found"` | Empty state text. |
|
|
161
|
+
| `loading` | `boolean` | `false` | Show loading state. |
|
|
162
|
+
| `loadingText` | `string` | `"Loading options..."` | Loading state text. |
|
|
163
|
+
| `maxHeight` | `string` | `"18rem"` | Dropdown max height. |
|
|
164
|
+
| `dropdownClass` | `string` | `""` | Extra dropdown class. |
|
|
165
|
+
| `optionClass` | `string` | `""` | Extra option class. |
|
|
166
|
+
| `hasError` | `boolean` | `false` | Apply error styling and `aria-invalid`. |
|
|
167
|
+
| `facilityFallbackLabel` | `string` | `"Storage Facility"` | Fallback title for legacy facility options without `public_title`. |
|
|
168
|
+
| `emitValue` | `boolean` | `false` | Emit option value instead of the whole option object. |
|
|
169
|
+
| `sortOptions` | `boolean` | `false` | Sort filtered options alphabetically by display label. |
|
|
170
|
+
|
|
171
|
+
## Emits
|
|
172
|
+
|
|
173
|
+
| Event | Payload | Description |
|
|
174
|
+
| --- | --- | --- |
|
|
175
|
+
| `update:modelValue` | `SelectOption \| string \| number \| null` | Emitted for `v-model`. |
|
|
176
|
+
| `change` | `SelectOption \| string \| number \| null` | Emitted when selection changes. |
|
|
177
|
+
| `blur` | none | Emitted after input blur handling. |
|
|
178
|
+
| `clear` | none | Emitted when selection is cleared. |
|
|
179
|
+
| `open` | none | Emitted when listbox opens. |
|
|
180
|
+
| `close` | none | Emitted when listbox closes. |
|
|
181
|
+
|
|
182
|
+
## Slots
|
|
183
|
+
|
|
184
|
+
| Slot | Props | Description |
|
|
185
|
+
| --- | --- | --- |
|
|
186
|
+
| `option` | `{ option, selected, active }` | Custom option rendering. |
|
|
187
|
+
| `selected` | `{ option }` | Custom selected-value rendering. |
|
|
188
|
+
| `no-results` | none | Custom empty state. |
|
|
189
|
+
| `loading` | none | Custom loading state. |
|
|
190
|
+
|
|
191
|
+
Example:
|
|
192
|
+
|
|
193
|
+
```vue
|
|
194
|
+
<SelectSimpleSearch v-model="facility" :options="facilities">
|
|
195
|
+
<template #option="{ option, active, selected }">
|
|
196
|
+
<div :class="{ active, selected }">
|
|
197
|
+
<strong>{{ option.address?.city }}</strong>
|
|
198
|
+
<span>{{ option.public_title || "Storage Facility" }}</span>
|
|
199
|
+
<small>{{ option.address?.full_address }}</small>
|
|
200
|
+
</div>
|
|
201
|
+
</template>
|
|
202
|
+
</SelectSimpleSearch>
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
## Accessibility
|
|
206
|
+
|
|
207
|
+
The component keeps DOM focus on the input and uses `aria-activedescendant` for active-option tracking. The input exposes `role="combobox"`, `aria-expanded`, `aria-controls`, `aria-autocomplete="list"`, and `aria-haspopup="listbox"`.
|
|
208
|
+
|
|
209
|
+
When open, the listbox exists in the DOM with `role="listbox"`. Each option has `role="option"`, a stable `id`, and `aria-selected="true"` or `aria-selected="false"`.
|
|
210
|
+
|
|
211
|
+
For best screen reader support, pass either a visible `label` or an `ariaLabel`.
|
|
212
|
+
|
|
213
|
+
## Dark Mode
|
|
214
|
+
|
|
215
|
+
The component supports dark mode automatically through `prefers-color-scheme`. You can also force a theme by setting `data-theme` on any parent:
|
|
216
|
+
|
|
217
|
+
```html
|
|
218
|
+
<div data-theme="dark">
|
|
219
|
+
<SelectSimpleSearch />
|
|
220
|
+
</div>
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Theme colors are exposed as CSS custom properties on `.select-simple`, so design systems can override them:
|
|
224
|
+
|
|
225
|
+
```css
|
|
226
|
+
.select-simple {
|
|
227
|
+
--select-simple-bg: #ffffff;
|
|
228
|
+
--select-simple-text: #111827;
|
|
229
|
+
--select-simple-border: #9ca3af;
|
|
230
|
+
--select-simple-option-active-bg: #eff6ff;
|
|
231
|
+
--select-simple-option-selected-bg: #dbeafe;
|
|
232
|
+
}
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Keyboard Support
|
|
236
|
+
|
|
237
|
+
| Key | Behavior |
|
|
238
|
+
| --- | --- |
|
|
239
|
+
| `ArrowDown` | Opens the listbox or moves to the next enabled option. |
|
|
240
|
+
| `ArrowUp` | Opens the listbox or moves to the previous enabled option. |
|
|
241
|
+
| `Enter` | Selects the active option while the listbox is open. |
|
|
242
|
+
| `Escape` | Closes the listbox and returns focus to the input. |
|
|
243
|
+
| `Backspace` / `Delete` | Clears the selected value when the selected label is shown. |
|
|
244
|
+
| `Home` / `End` | Preserve native text-input caret behavior. |
|
|
245
|
+
|
|
246
|
+
## License
|
|
247
|
+
|
|
248
|
+
MIT
|
|
249
|
+
|
|
250
|
+
## Publishing
|
|
251
|
+
|
|
252
|
+
Do not publish before running the full package verification:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
npm run lint
|
|
256
|
+
npm run typecheck
|
|
257
|
+
npm run test
|
|
258
|
+
npm run build
|
|
259
|
+
npm pack --dry-run
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
Publish manually when the package contents look correct:
|
|
263
|
+
|
|
264
|
+
```bash
|
|
265
|
+
npm login
|
|
266
|
+
npm publish --access public
|
|
267
|
+
```
|
|
268
|
+
|
|
269
|
+
The package is configured to publish only:
|
|
270
|
+
|
|
271
|
+
- `dist`
|
|
272
|
+
- `README.md`
|
|
273
|
+
- `LICENSE`
|
|
274
|
+
- `package.json`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.select-simple[data-v-58b7f39e],.select-simple-options[data-v-58b7f39e]{--select-simple-bg: #fff;--select-simple-text: #111827;--select-simple-muted: #4b5563;--select-simple-border: #9ca3af;--select-simple-border-subtle: #d1d5db;--select-simple-focus-border: #2563eb;--select-simple-focus-ring: #bfdbfe;--select-simple-clear-hover-bg: #f3f4f6;--select-simple-option-active-bg: #eff6ff;--select-simple-option-selected-bg: #dbeafe;--select-simple-option-hover-bg: #f8fafc;--select-simple-error: #dc2626;--select-simple-shadow: 0 10px 24px rgb(15 23 42 / 14%);position:relative;width:100%;color:var(--select-simple-text)}@media(prefers-color-scheme:dark){.select-simple[data-v-58b7f39e],.select-simple-options[data-v-58b7f39e]{--select-simple-bg: #111827;--select-simple-text: #f9fafb;--select-simple-muted: #cbd5e1;--select-simple-border: #475569;--select-simple-border-subtle: #334155;--select-simple-focus-border: #60a5fa;--select-simple-focus-ring: #1e3a8a;--select-simple-clear-hover-bg: #1f2937;--select-simple-option-active-bg: #1d4ed8;--select-simple-option-selected-bg: #1e40af;--select-simple-option-hover-bg: #1f2937;--select-simple-error: #f87171;--select-simple-shadow: 0 14px 32px rgb(0 0 0 / 34%)}}[data-theme=light]{--select-simple-bg: #fff;--select-simple-text: #111827;--select-simple-muted: #4b5563;--select-simple-border: #9ca3af;--select-simple-border-subtle: #d1d5db;--select-simple-focus-border: #2563eb;--select-simple-focus-ring: #bfdbfe;--select-simple-clear-hover-bg: #f3f4f6;--select-simple-option-active-bg: #eff6ff;--select-simple-option-selected-bg: #dbeafe;--select-simple-option-hover-bg: #f8fafc;--select-simple-error: #dc2626;--select-simple-shadow: 0 10px 24px rgb(15 23 42 / 14%)}[data-theme=dark]{--select-simple-bg: #111827;--select-simple-text: #f9fafb;--select-simple-muted: #cbd5e1;--select-simple-border: #475569;--select-simple-border-subtle: #334155;--select-simple-focus-border: #60a5fa;--select-simple-focus-ring: #1e3a8a;--select-simple-clear-hover-bg: #1f2937;--select-simple-option-active-bg: #1d4ed8;--select-simple-option-selected-bg: #1e40af;--select-simple-option-hover-bg: #1f2937;--select-simple-error: #f87171;--select-simple-shadow: 0 14px 32px rgb(0 0 0 / 34%)}.select-simple-label[data-v-58b7f39e]{display:block;margin-bottom:.375rem;font-weight:600}.select-simple-control[data-v-58b7f39e]{position:relative}.select-simple.has-selected-slot .select-simple-control[data-v-58b7f39e]>:not(input,button){position:absolute;top:50%;left:.75rem;z-index:1;max-width:calc(100% - 3rem);overflow:hidden;pointer-events:none;text-overflow:ellipsis;white-space:nowrap;transform:translateY(-50%)}.select-simple.has-selected-slot:focus-within .select-simple-control[data-v-58b7f39e]>:not(input,button){display:none}.select-simple-input[data-v-58b7f39e]{box-sizing:border-box;width:100%;min-height:2.5rem;padding:.5rem 2.25rem .5rem .75rem;border:1px solid var(--select-simple-border);border-radius:6px;background-color:var(--select-simple-bg);color:var(--select-simple-text);font:inherit}.select-simple.has-selected-slot .select-simple-input[data-v-58b7f39e]{color:transparent}.select-simple.has-selected-slot .select-simple-input[data-v-58b7f39e]:focus{color:var(--select-simple-text)}.select-simple-input[data-v-58b7f39e]:focus{border-color:var(--select-simple-focus-border);outline:2px solid var(--select-simple-focus-ring);outline-offset:1px}.select-simple.disabled[data-v-58b7f39e]{opacity:.65}.select-simple.has-error .select-simple-input[data-v-58b7f39e]{border-color:var(--select-simple-error)}.select-simple-clear[data-v-58b7f39e]{position:absolute;top:50%;right:.5rem;display:inline-flex;width:1.75rem;height:1.75rem;align-items:center;justify-content:center;padding:0;border:0;border-radius:4px;background:transparent;color:var(--select-simple-muted);cursor:pointer;transform:translateY(-50%)}.select-simple-clear[data-v-58b7f39e]:hover{background:var(--select-simple-clear-hover-bg);color:var(--select-simple-text)}.select-simple-overlay[data-v-58b7f39e]{position:fixed;top:0;right:0;bottom:0;left:0;z-index:999;pointer-events:none}.select-simple-options[data-v-58b7f39e]{position:fixed;z-index:1000;box-sizing:border-box;overflow-y:auto;border:1px solid var(--select-simple-border-subtle);border-radius:6px;background-color:var(--select-simple-bg);box-shadow:var(--select-simple-shadow);color:var(--select-simple-text)}[data-v-58b7f39e]::-webkit-scrollbar{width:6px}[data-v-58b7f39e]::-webkit-scrollbar-thumb{background:#0003;border-radius:999px}.select-simple-options-inline[data-v-58b7f39e]{position:relative;z-index:1;width:100%;margin-top:.25rem;box-shadow:none}.select-simple-option[data-v-58b7f39e],.select-simple-status[data-v-58b7f39e]{padding:.625rem .75rem}.select-simple-option[data-v-58b7f39e]{background-color:var(--select-simple-bg);cursor:pointer}.select-simple-option[data-v-58b7f39e]:hover{background-color:var(--select-simple-option-hover-bg)}.select-simple-option.active[data-v-58b7f39e]{background-color:var(--select-simple-option-active-bg)}.select-simple-option.selected[data-v-58b7f39e]{background-color:var(--select-simple-option-selected-bg)}.select-simple-option.disabled[data-v-58b7f39e]{color:var(--select-simple-muted);cursor:not-allowed}.select-simple-option-text[data-v-58b7f39e]{display:grid;gap:.125rem}.select-simple-option-description[data-v-58b7f39e]{color:var(--select-simple-muted);font-size:.875rem}.select-simple-status[data-v-58b7f39e]{color:var(--select-simple-muted)}.sr-only[data-v-58b7f39e]{position:absolute;width:1px;height:1px;padding:0;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
|
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
import { defineComponent as Oe, useId as De, computed as m, ref as f, toRefs as Re, watch as fe, onMounted as Te, onUnmounted as Ee, openBlock as c, createElementBlock as v, normalizeClass as J, unref as o, toDisplayString as _, createCommentVNode as x, createElementVNode as h, renderSlot as M, withDirectives as Ke, vModelText as Me, withModifiers as ve, createBlock as ze, Teleport as Ae, normalizeStyle as Fe, createTextVNode as pe, Fragment as Ne, renderList as je, nextTick as z } from "vue";
|
|
2
|
+
const He = ["for"], Pe = ["id", "name", "disabled", "placeholder", "aria-label", "aria-expanded", "aria-controls", "aria-activedescendant", "aria-invalid", "aria-busy"], Ue = ["aria-label"], qe = {
|
|
3
|
+
class: "sr-only",
|
|
4
|
+
"aria-live": "polite",
|
|
5
|
+
"aria-atomic": "true"
|
|
6
|
+
}, We = {
|
|
7
|
+
key: 0,
|
|
8
|
+
class: "select-simple-overlay"
|
|
9
|
+
}, Ze = ["id"], Ge = {
|
|
10
|
+
key: 0,
|
|
11
|
+
class: "select-simple-status"
|
|
12
|
+
}, Je = ["id", "aria-selected", "aria-disabled", "onClick"], Qe = { class: "select-simple-option-text" }, Xe = {
|
|
13
|
+
key: 0,
|
|
14
|
+
class: "select-simple-option-description"
|
|
15
|
+
}, Ye = {
|
|
16
|
+
key: 2,
|
|
17
|
+
class: "select-simple-status"
|
|
18
|
+
}, el = /* @__PURE__ */ Oe({
|
|
19
|
+
__name: "SelectSimpleSearch",
|
|
20
|
+
props: {
|
|
21
|
+
options: { default: () => [] },
|
|
22
|
+
modelValue: { default: null },
|
|
23
|
+
placeholder: { default: "Select an option" },
|
|
24
|
+
type: { default: "default" },
|
|
25
|
+
inlineListbox: { type: Boolean, default: !1 },
|
|
26
|
+
closeOnBlur: { type: Boolean, default: !1 },
|
|
27
|
+
label: { default: "" },
|
|
28
|
+
name: { default: "select-simple-search" },
|
|
29
|
+
inputId: { default: "" },
|
|
30
|
+
listboxId: { default: "" },
|
|
31
|
+
ariaLabel: { default: "Search options" },
|
|
32
|
+
labelKey: { default: "" },
|
|
33
|
+
valueKey: { default: "" },
|
|
34
|
+
searchKeys: { default: () => [
|
|
35
|
+
"label",
|
|
36
|
+
"name",
|
|
37
|
+
"public_title",
|
|
38
|
+
"address.city",
|
|
39
|
+
"address.full_address",
|
|
40
|
+
"slug",
|
|
41
|
+
"value",
|
|
42
|
+
"id"
|
|
43
|
+
] },
|
|
44
|
+
disabled: { type: Boolean, default: !1 },
|
|
45
|
+
clearable: { type: Boolean, default: !0 },
|
|
46
|
+
clearLabel: { default: "Clear selection" },
|
|
47
|
+
noResultsText: { default: "No results found" },
|
|
48
|
+
loading: { type: Boolean, default: !1 },
|
|
49
|
+
loadingText: { default: "Loading options..." },
|
|
50
|
+
maxHeight: { default: "18rem" },
|
|
51
|
+
dropdownClass: { default: "" },
|
|
52
|
+
optionClass: { default: "" },
|
|
53
|
+
hasError: { type: Boolean, default: !1 },
|
|
54
|
+
facilityFallbackLabel: { default: "Storage Facility" },
|
|
55
|
+
emitValue: { type: Boolean, default: !1 },
|
|
56
|
+
sortOptions: { type: Boolean, default: !1 }
|
|
57
|
+
},
|
|
58
|
+
emits: ["update:modelValue", "change", "blur", "clear", "open", "close"],
|
|
59
|
+
setup(V, { emit: A }) {
|
|
60
|
+
const a = V, d = A, S = De().replace(/[^A-Za-z0-9_-]/g, "-"), F = m(() => a.listboxId || `select-simple-listbox-${S}`), Q = m(() => a.inputId || `select-simple-input-${S}`), X = f(null), N = f(null), $ = f(null), B = f(null), s = f(!1), p = f(""), i = f(-1), j = f(""), Y = f({}), I = f(!1), {
|
|
61
|
+
ariaLabel: be,
|
|
62
|
+
clearLabel: me,
|
|
63
|
+
clearable: ge,
|
|
64
|
+
disabled: H,
|
|
65
|
+
dropdownClass: ye,
|
|
66
|
+
hasError: ee,
|
|
67
|
+
inlineListbox: P,
|
|
68
|
+
label: U,
|
|
69
|
+
loading: le,
|
|
70
|
+
loadingText: he,
|
|
71
|
+
name: we,
|
|
72
|
+
noResultsText: ke,
|
|
73
|
+
optionClass: _e,
|
|
74
|
+
placeholder: xe,
|
|
75
|
+
type: te
|
|
76
|
+
} = Re(a), Le = m(() => {
|
|
77
|
+
const e = { maxHeight: a.maxHeight };
|
|
78
|
+
return a.inlineListbox ? e : { ...e, ...Y.value };
|
|
79
|
+
}), L = m(() => {
|
|
80
|
+
const e = a.modelValue;
|
|
81
|
+
if (e == null)
|
|
82
|
+
return null;
|
|
83
|
+
if (oe(e)) {
|
|
84
|
+
const l = b(e);
|
|
85
|
+
return a.options.find((t) => D(b(t), l)) ?? e;
|
|
86
|
+
}
|
|
87
|
+
return a.options.find((l) => D(b(l), e)) ?? null;
|
|
88
|
+
}), Ce = m(() => L.value ? g(L.value) : ""), O = m(() => a.modelValue !== null && a.modelValue !== void 0), ae = m({
|
|
89
|
+
get() {
|
|
90
|
+
return p.value || Ce.value;
|
|
91
|
+
},
|
|
92
|
+
set(e) {
|
|
93
|
+
p.value = e;
|
|
94
|
+
}
|
|
95
|
+
}), u = m(() => {
|
|
96
|
+
const e = p.value.trim().toLowerCase(), l = e ? a.options.filter(
|
|
97
|
+
(t) => a.searchKeys.some((n) => W(q(t, n)).toLowerCase().includes(e))
|
|
98
|
+
) : a.options;
|
|
99
|
+
return a.sortOptions ? [...l].sort((t, n) => {
|
|
100
|
+
const r = g(t).toLowerCase(), k = g(n).toLowerCase();
|
|
101
|
+
return r.localeCompare(k);
|
|
102
|
+
}) : [...l];
|
|
103
|
+
}), ne = m(() => {
|
|
104
|
+
if (!(a.loading || !s.value || i.value < 0 || i.value >= u.value.length))
|
|
105
|
+
return se(i.value);
|
|
106
|
+
});
|
|
107
|
+
function oe(e) {
|
|
108
|
+
return typeof e == "object" && e !== null;
|
|
109
|
+
}
|
|
110
|
+
function q(e, l) {
|
|
111
|
+
return l.split(".").reduce((t, n) => {
|
|
112
|
+
if (t && typeof t == "object" && n in t)
|
|
113
|
+
return t[n];
|
|
114
|
+
}, e);
|
|
115
|
+
}
|
|
116
|
+
function W(e) {
|
|
117
|
+
return e == null ? "" : String(e);
|
|
118
|
+
}
|
|
119
|
+
function b(e) {
|
|
120
|
+
if (a.valueKey) {
|
|
121
|
+
const l = q(e, a.valueKey);
|
|
122
|
+
if (typeof l == "string" || typeof l == "number")
|
|
123
|
+
return l;
|
|
124
|
+
}
|
|
125
|
+
return e.slug ?? e.value ?? e.id;
|
|
126
|
+
}
|
|
127
|
+
function g(e) {
|
|
128
|
+
var l, t, n;
|
|
129
|
+
if (a.labelKey) {
|
|
130
|
+
const r = W(q(e, a.labelKey)).trim();
|
|
131
|
+
if (r)
|
|
132
|
+
return r;
|
|
133
|
+
}
|
|
134
|
+
if (e.label)
|
|
135
|
+
return e.label;
|
|
136
|
+
if (e.name)
|
|
137
|
+
return e.name;
|
|
138
|
+
if ((l = e.address) != null && l.city || e.public_title) {
|
|
139
|
+
const r = (n = (t = e.address) == null ? void 0 : t.city) == null ? void 0 : n.trim(), k = e.public_title && e.public_title.length > 1 ? e.public_title : a.facilityFallbackLabel;
|
|
140
|
+
return [r, k].filter(Boolean).join(" - ");
|
|
141
|
+
}
|
|
142
|
+
return W(b(e));
|
|
143
|
+
}
|
|
144
|
+
function ie(e) {
|
|
145
|
+
var l;
|
|
146
|
+
return ((l = e.address) == null ? void 0 : l.full_address) ?? "";
|
|
147
|
+
}
|
|
148
|
+
function Ve(e, l) {
|
|
149
|
+
const t = b(e);
|
|
150
|
+
return t !== void 0 ? String(t) : `${g(e)}-${l}`;
|
|
151
|
+
}
|
|
152
|
+
function se(e) {
|
|
153
|
+
return `${F.value}-option-${e}`;
|
|
154
|
+
}
|
|
155
|
+
function D(e, l) {
|
|
156
|
+
return e === void 0 || l === void 0 ? !1 : String(e) === String(l);
|
|
157
|
+
}
|
|
158
|
+
function Z(e) {
|
|
159
|
+
const l = a.modelValue;
|
|
160
|
+
if (l == null)
|
|
161
|
+
return !1;
|
|
162
|
+
if (oe(l)) {
|
|
163
|
+
const t = b(l), n = b(e);
|
|
164
|
+
return D(t, n) || l === e;
|
|
165
|
+
}
|
|
166
|
+
return D(b(e), l);
|
|
167
|
+
}
|
|
168
|
+
function y(e) {
|
|
169
|
+
j.value = "", z(() => {
|
|
170
|
+
j.value = e;
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
function G(e) {
|
|
174
|
+
return `${e} ${e === 1 ? "option" : "options"} available.`;
|
|
175
|
+
}
|
|
176
|
+
function R() {
|
|
177
|
+
if (a.inlineListbox || !N.value)
|
|
178
|
+
return;
|
|
179
|
+
const e = N.value.getBoundingClientRect();
|
|
180
|
+
Y.value = {
|
|
181
|
+
left: `${e.left}px`,
|
|
182
|
+
top: `${e.bottom + 4}px`,
|
|
183
|
+
width: `${e.width}px`
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
async function w() {
|
|
187
|
+
a.disabled || s.value || (I.value = !0, R(), s.value = !0, d("open"), await z(), R(), C(a.loading ? -1 : E()), y(a.loading ? a.loadingText : G(u.value.length)), window.setTimeout(() => {
|
|
188
|
+
I.value = !1;
|
|
189
|
+
}, 0));
|
|
190
|
+
}
|
|
191
|
+
function T() {
|
|
192
|
+
s.value && (s.value = !1, i.value = -1, p.value = "", d("close"));
|
|
193
|
+
}
|
|
194
|
+
function E() {
|
|
195
|
+
return u.value.findIndex((e) => !e.disabled);
|
|
196
|
+
}
|
|
197
|
+
function ue(e, l) {
|
|
198
|
+
const t = u.value;
|
|
199
|
+
if (!t.length)
|
|
200
|
+
return -1;
|
|
201
|
+
let n = e;
|
|
202
|
+
for (let r = 0; r < t.length; r += 1)
|
|
203
|
+
if (n = (n + l + t.length) % t.length, !t[n].disabled)
|
|
204
|
+
return n;
|
|
205
|
+
return -1;
|
|
206
|
+
}
|
|
207
|
+
function C(e) {
|
|
208
|
+
if (i.value = e, e < 0)
|
|
209
|
+
return;
|
|
210
|
+
const l = u.value[e];
|
|
211
|
+
if (!l) {
|
|
212
|
+
i.value = -1;
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
y(`${g(l)}, ${e + 1} of ${u.value.length}.`), Se();
|
|
216
|
+
}
|
|
217
|
+
function Se() {
|
|
218
|
+
z(() => {
|
|
219
|
+
var t;
|
|
220
|
+
const e = ne.value;
|
|
221
|
+
if (!e || !B.value)
|
|
222
|
+
return;
|
|
223
|
+
const l = B.value.querySelector(`#${e}`);
|
|
224
|
+
(t = l == null ? void 0 : l.scrollIntoView) == null || t.call(l, { block: "nearest" });
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
async function $e() {
|
|
228
|
+
if (!a.disabled) {
|
|
229
|
+
if (O.value && p.value.trim() && (d("update:modelValue", null), d("change", null)), !s.value) {
|
|
230
|
+
await w();
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
await z(), R(), C(E()), y(G(u.value.length));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
function Be(e) {
|
|
237
|
+
var l;
|
|
238
|
+
if (!a.disabled) {
|
|
239
|
+
if (e.key === "Escape") {
|
|
240
|
+
e.preventDefault(), T(), (l = $.value) == null || l.focus();
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
if ((e.key === "Backspace" || e.key === "Delete") && O.value && !p.value) {
|
|
244
|
+
e.preventDefault(), de();
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
if (e.key === "ArrowDown") {
|
|
248
|
+
if (e.preventDefault(), !s.value) {
|
|
249
|
+
w();
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
if (a.loading)
|
|
253
|
+
return;
|
|
254
|
+
C(ue(i.value, 1));
|
|
255
|
+
return;
|
|
256
|
+
}
|
|
257
|
+
if (e.key === "ArrowUp") {
|
|
258
|
+
if (e.preventDefault(), !s.value) {
|
|
259
|
+
w();
|
|
260
|
+
return;
|
|
261
|
+
}
|
|
262
|
+
if (a.loading)
|
|
263
|
+
return;
|
|
264
|
+
C(ue(i.value < 0 ? u.value.length : i.value, -1));
|
|
265
|
+
return;
|
|
266
|
+
}
|
|
267
|
+
if (e.key === "Enter") {
|
|
268
|
+
if (!s.value || a.loading)
|
|
269
|
+
return;
|
|
270
|
+
e.preventDefault();
|
|
271
|
+
const t = u.value[i.value];
|
|
272
|
+
t && !t.disabled && re(t);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
function re(e) {
|
|
277
|
+
var t;
|
|
278
|
+
if (a.disabled || e.disabled)
|
|
279
|
+
return;
|
|
280
|
+
const l = a.emitValue ? b(e) ?? e : e;
|
|
281
|
+
d("update:modelValue", l), d("change", l), y(`${g(e)} selected.`), T(), (t = $.value) == null || t.focus();
|
|
282
|
+
}
|
|
283
|
+
function de() {
|
|
284
|
+
var e;
|
|
285
|
+
a.disabled || (d("update:modelValue", null), d("change", null), d("clear"), p.value = "", y("Selection cleared."), w(), (e = $.value) == null || e.focus());
|
|
286
|
+
}
|
|
287
|
+
function Ie() {
|
|
288
|
+
window.setTimeout(() => {
|
|
289
|
+
a.closeOnBlur && T(), d("blur");
|
|
290
|
+
}, 100);
|
|
291
|
+
}
|
|
292
|
+
function ce(e) {
|
|
293
|
+
var r, k;
|
|
294
|
+
const l = e.target;
|
|
295
|
+
if (!l || !s.value)
|
|
296
|
+
return;
|
|
297
|
+
if (I.value) {
|
|
298
|
+
I.value = !1;
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
const t = (r = X.value) == null ? void 0 : r.contains(l), n = (k = B.value) == null ? void 0 : k.contains(l);
|
|
302
|
+
!t && !n && T();
|
|
303
|
+
}
|
|
304
|
+
function K() {
|
|
305
|
+
s.value && R();
|
|
306
|
+
}
|
|
307
|
+
return fe(
|
|
308
|
+
() => a.loading,
|
|
309
|
+
(e) => {
|
|
310
|
+
s.value && (i.value = e ? -1 : E(), y(e ? a.loadingText : G(u.value.length)));
|
|
311
|
+
}
|
|
312
|
+
), fe(u, (e) => {
|
|
313
|
+
var l;
|
|
314
|
+
if (!(!s.value || a.loading)) {
|
|
315
|
+
if (!e.length) {
|
|
316
|
+
i.value = -1, y(a.noResultsText);
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
(i.value < 0 || i.value >= e.length || (l = e[i.value]) != null && l.disabled) && C(E());
|
|
320
|
+
}
|
|
321
|
+
}), Te(() => {
|
|
322
|
+
document.addEventListener("click", ce), window.addEventListener("resize", K), window.addEventListener("scroll", K, !0);
|
|
323
|
+
}), Ee(() => {
|
|
324
|
+
document.removeEventListener("click", ce), window.removeEventListener("resize", K), window.removeEventListener("scroll", K, !0);
|
|
325
|
+
}), (e, l) => (c(), v("div", {
|
|
326
|
+
ref_key: "rootRef",
|
|
327
|
+
ref: X,
|
|
328
|
+
class: J(["select-simple select-simple-search", {
|
|
329
|
+
selected: O.value,
|
|
330
|
+
disabled: o(H),
|
|
331
|
+
"has-error": o(ee),
|
|
332
|
+
open: s.value,
|
|
333
|
+
"has-selected-slot": !!e.$slots.selected && L.value && !p.value
|
|
334
|
+
}])
|
|
335
|
+
}, [
|
|
336
|
+
o(U) ? (c(), v("label", {
|
|
337
|
+
key: 0,
|
|
338
|
+
for: Q.value,
|
|
339
|
+
class: "select-simple-label"
|
|
340
|
+
}, _(o(U)), 9, He)) : x("", !0),
|
|
341
|
+
h("div", {
|
|
342
|
+
ref_key: "controlRef",
|
|
343
|
+
ref: N,
|
|
344
|
+
class: "select-simple-control"
|
|
345
|
+
}, [
|
|
346
|
+
L.value && !p.value ? M(e.$slots, "selected", {
|
|
347
|
+
key: 0,
|
|
348
|
+
option: L.value
|
|
349
|
+
}, void 0, !0) : x("", !0),
|
|
350
|
+
Ke(h("input", {
|
|
351
|
+
id: Q.value,
|
|
352
|
+
ref_key: "inputRef",
|
|
353
|
+
ref: $,
|
|
354
|
+
"onUpdate:modelValue": l[0] || (l[0] = (t) => ae.value = t),
|
|
355
|
+
type: "text",
|
|
356
|
+
class: "select-simple-input",
|
|
357
|
+
role: "combobox",
|
|
358
|
+
name: o(we),
|
|
359
|
+
disabled: o(H),
|
|
360
|
+
placeholder: o(xe),
|
|
361
|
+
"aria-label": o(U) ? void 0 : o(be),
|
|
362
|
+
"aria-expanded": s.value,
|
|
363
|
+
"aria-controls": F.value,
|
|
364
|
+
"aria-activedescendant": ne.value,
|
|
365
|
+
"aria-invalid": o(ee) || void 0,
|
|
366
|
+
"aria-haspopup": "listbox",
|
|
367
|
+
"aria-autocomplete": "list",
|
|
368
|
+
"aria-busy": o(le) || void 0,
|
|
369
|
+
autocomplete: "off",
|
|
370
|
+
onFocus: w,
|
|
371
|
+
onClick: w,
|
|
372
|
+
onInput: $e,
|
|
373
|
+
onKeydown: Be,
|
|
374
|
+
onBlur: Ie
|
|
375
|
+
}, null, 40, Pe), [
|
|
376
|
+
[Me, ae.value]
|
|
377
|
+
]),
|
|
378
|
+
o(ge) && O.value && !o(H) ? (c(), v("button", {
|
|
379
|
+
key: 1,
|
|
380
|
+
type: "button",
|
|
381
|
+
class: "select-simple-clear",
|
|
382
|
+
"aria-label": o(me),
|
|
383
|
+
onClick: ve(de, ["stop"])
|
|
384
|
+
}, [...l[2] || (l[2] = [
|
|
385
|
+
h("svg", {
|
|
386
|
+
width: "16",
|
|
387
|
+
height: "16",
|
|
388
|
+
viewBox: "0 0 16 16",
|
|
389
|
+
"aria-hidden": "true",
|
|
390
|
+
focusable: "false"
|
|
391
|
+
}, [
|
|
392
|
+
h("path", {
|
|
393
|
+
d: "M12 4L4 12M4 4l8 8",
|
|
394
|
+
fill: "none",
|
|
395
|
+
stroke: "currentColor",
|
|
396
|
+
"stroke-linecap": "round",
|
|
397
|
+
"stroke-width": "2"
|
|
398
|
+
})
|
|
399
|
+
], -1)
|
|
400
|
+
])], 8, Ue)) : x("", !0)
|
|
401
|
+
], 512),
|
|
402
|
+
h("div", qe, _(j.value), 1),
|
|
403
|
+
(c(), ze(Ae, {
|
|
404
|
+
to: "body",
|
|
405
|
+
disabled: o(P)
|
|
406
|
+
}, [
|
|
407
|
+
s.value && !o(P) ? (c(), v("div", We)) : x("", !0),
|
|
408
|
+
s.value ? (c(), v("div", {
|
|
409
|
+
key: 1,
|
|
410
|
+
id: F.value,
|
|
411
|
+
ref_key: "listboxRef",
|
|
412
|
+
ref: B,
|
|
413
|
+
role: "listbox",
|
|
414
|
+
class: J(["select-simple-options", [o(te), o(ye), { "select-simple-options-inline": o(P) }]]),
|
|
415
|
+
style: Fe(Le.value)
|
|
416
|
+
}, [
|
|
417
|
+
o(le) ? (c(), v("div", Ge, [
|
|
418
|
+
M(e.$slots, "loading", {}, () => [
|
|
419
|
+
pe(_(o(he)), 1)
|
|
420
|
+
], !0)
|
|
421
|
+
])) : u.value.length ? (c(!0), v(Ne, { key: 1 }, je(u.value, (t, n) => (c(), v("div", {
|
|
422
|
+
id: se(n),
|
|
423
|
+
key: Ve(t, n),
|
|
424
|
+
role: "option",
|
|
425
|
+
class: J(["select-simple-option", [
|
|
426
|
+
o(_e),
|
|
427
|
+
{
|
|
428
|
+
selected: Z(t),
|
|
429
|
+
active: i.value === n,
|
|
430
|
+
disabled: t.disabled,
|
|
431
|
+
highlighted: o(te) === "billing-state" && i.value === n
|
|
432
|
+
}
|
|
433
|
+
]]),
|
|
434
|
+
"aria-selected": Z(t),
|
|
435
|
+
"aria-disabled": t.disabled || void 0,
|
|
436
|
+
onMousedown: l[1] || (l[1] = ve(() => {
|
|
437
|
+
}, ["prevent"])),
|
|
438
|
+
onClick: (r) => re(t)
|
|
439
|
+
}, [
|
|
440
|
+
M(e.$slots, "option", {
|
|
441
|
+
option: t,
|
|
442
|
+
selected: Z(t),
|
|
443
|
+
active: i.value === n
|
|
444
|
+
}, () => [
|
|
445
|
+
h("span", Qe, [
|
|
446
|
+
h("strong", null, _(g(t)), 1),
|
|
447
|
+
ie(t) ? (c(), v("span", Xe, _(ie(t)), 1)) : x("", !0)
|
|
448
|
+
])
|
|
449
|
+
], !0)
|
|
450
|
+
], 42, Je))), 128)) : (c(), v("div", Ye, [
|
|
451
|
+
M(e.$slots, "no-results", {}, () => [
|
|
452
|
+
pe(_(o(ke)), 1)
|
|
453
|
+
], !0)
|
|
454
|
+
]))
|
|
455
|
+
], 14, Ze)) : x("", !0)
|
|
456
|
+
], 8, ["disabled"]))
|
|
457
|
+
], 2));
|
|
458
|
+
}
|
|
459
|
+
}), ll = (V, A) => {
|
|
460
|
+
const a = V.__vccOpts || V;
|
|
461
|
+
for (const [d, S] of A)
|
|
462
|
+
a[d] = S;
|
|
463
|
+
return a;
|
|
464
|
+
}, al = /* @__PURE__ */ ll(el, [["__scopeId", "data-v-58b7f39e"]]);
|
|
465
|
+
export {
|
|
466
|
+
al as SelectSimpleSearch,
|
|
467
|
+
al as default
|
|
468
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(p,e){typeof exports=="object"&&typeof module<"u"?e(exports,require("vue")):typeof define=="function"&&define.amd?define(["exports","vue"],e):(p=typeof globalThis<"u"?globalThis:p||self,e(p.AccessibleVueSearchSelect={},p.Vue))})(this,(function(p,e){"use strict";const ae=["for"],oe=["id","name","disabled","placeholder","aria-label","aria-expanded","aria-controls","aria-activedescendant","aria-invalid","aria-busy"],re=["aria-label"],ie={class:"sr-only","aria-live":"polite","aria-atomic":"true"},se={key:0,class:"select-simple-overlay"},ce=["id"],de={key:0,class:"select-simple-status"},ue=["id","aria-selected","aria-disabled","onClick"],fe={class:"select-simple-option-text"},pe={key:0,class:"select-simple-option-description"},me={key:2,class:"select-simple-status"},F=((w,I)=>{const a=w.__vccOpts||w;for(const[d,v]of I)a[d]=v;return a})(e.defineComponent({__name:"SelectSimpleSearch",props:{options:{default:()=>[]},modelValue:{default:null},placeholder:{default:"Select an option"},type:{default:"default"},inlineListbox:{type:Boolean,default:!1},closeOnBlur:{type:Boolean,default:!1},label:{default:""},name:{default:"select-simple-search"},inputId:{default:""},listboxId:{default:""},ariaLabel:{default:"Search options"},labelKey:{default:""},valueKey:{default:""},searchKeys:{default:()=>["label","name","public_title","address.city","address.full_address","slug","value","id"]},disabled:{type:Boolean,default:!1},clearable:{type:Boolean,default:!0},clearLabel:{default:"Clear selection"},noResultsText:{default:"No results found"},loading:{type:Boolean,default:!1},loadingText:{default:"Loading options..."},maxHeight:{default:"18rem"},dropdownClass:{default:""},optionClass:{default:""},hasError:{type:Boolean,default:!1},facilityFallbackLabel:{default:"Storage Facility"},emitValue:{type:Boolean,default:!1},sortOptions:{type:Boolean,default:!1}},emits:["update:modelValue","change","blur","clear","open","close"],setup(w,{emit:I}){const a=w,d=I,v=e.useId().replace(/[^A-Za-z0-9_-]/g,"-"),D=e.computed(()=>a.listboxId||`select-simple-listbox-${v}`),P=e.computed(()=>a.inputId||`select-simple-input-${v}`),H=e.ref(null),O=e.ref(null),_=e.ref(null),B=e.ref(null),i=e.ref(!1),u=e.ref(""),r=e.ref(-1),T=e.ref(""),U=e.ref({}),x=e.ref(!1),{ariaLabel:be,clearLabel:ge,clearable:ye,disabled:N,dropdownClass:he,hasError:q,inlineListbox:R,label:K,loading:W,loadingText:ke,name:we,noResultsText:ve,optionClass:_e,placeholder:Be,type:Z}=e.toRefs(a),xe=e.computed(()=>{const t={maxHeight:a.maxHeight};return a.inlineListbox?t:{...t,...U.value}}),h=e.computed(()=>{const t=a.modelValue;if(t==null)return null;if(Q(t)){const l=f(t);return a.options.find(n=>V(f(n),l))??t}return a.options.find(l=>V(f(l),t))??null}),Se=e.computed(()=>h.value?m(h.value):""),S=e.computed(()=>a.modelValue!==null&&a.modelValue!==void 0),G=e.computed({get(){return u.value||Se.value},set(t){u.value=t}}),s=e.computed(()=>{const t=u.value.trim().toLowerCase(),l=t?a.options.filter(n=>a.searchKeys.some(o=>z(M(n,o)).toLowerCase().includes(t))):a.options;return a.sortOptions?[...l].sort((n,o)=>{const c=m(n).toLowerCase(),y=m(o).toLowerCase();return c.localeCompare(y)}):[...l]}),J=e.computed(()=>{if(!(a.loading||!i.value||r.value<0||r.value>=s.value.length))return Y(r.value)});function Q(t){return typeof t=="object"&&t!==null}function M(t,l){return l.split(".").reduce((n,o)=>{if(n&&typeof n=="object"&&o in n)return n[o]},t)}function z(t){return t==null?"":String(t)}function f(t){if(a.valueKey){const l=M(t,a.valueKey);if(typeof l=="string"||typeof l=="number")return l}return t.slug??t.value??t.id}function m(t){var l,n,o;if(a.labelKey){const c=z(M(t,a.labelKey)).trim();if(c)return c}if(t.label)return t.label;if(t.name)return t.name;if((l=t.address)!=null&&l.city||t.public_title){const c=(o=(n=t.address)==null?void 0:n.city)==null?void 0:o.trim(),y=t.public_title&&t.public_title.length>1?t.public_title:a.facilityFallbackLabel;return[c,y].filter(Boolean).join(" - ")}return z(f(t))}function X(t){var l;return((l=t.address)==null?void 0:l.full_address)??""}function Ve(t,l){const n=f(t);return n!==void 0?String(n):`${m(t)}-${l}`}function Y(t){return`${D.value}-option-${t}`}function V(t,l){return t===void 0||l===void 0?!1:String(t)===String(l)}function A(t){const l=a.modelValue;if(l==null)return!1;if(Q(l)){const n=f(l),o=f(t);return V(n,o)||l===t}return V(f(t),l)}function b(t){T.value="",e.nextTick(()=>{T.value=t})}function j(t){return`${t} ${t===1?"option":"options"} available.`}function C(){if(a.inlineListbox||!O.value)return;const t=O.value.getBoundingClientRect();U.value={left:`${t.left}px`,top:`${t.bottom+4}px`,width:`${t.width}px`}}async function g(){a.disabled||i.value||(x.value=!0,C(),i.value=!0,d("open"),await e.nextTick(),C(),k(a.loading?-1:E()),b(a.loading?a.loadingText:j(s.value.length)),window.setTimeout(()=>{x.value=!1},0))}function L(){i.value&&(i.value=!1,r.value=-1,u.value="",d("close"))}function E(){return s.value.findIndex(t=>!t.disabled)}function ee(t,l){const n=s.value;if(!n.length)return-1;let o=t;for(let c=0;c<n.length;c+=1)if(o=(o+l+n.length)%n.length,!n[o].disabled)return o;return-1}function k(t){if(r.value=t,t<0)return;const l=s.value[t];if(!l){r.value=-1;return}b(`${m(l)}, ${t+1} of ${s.value.length}.`),Ce()}function Ce(){e.nextTick(()=>{var n;const t=J.value;if(!t||!B.value)return;const l=B.value.querySelector(`#${t}`);(n=l==null?void 0:l.scrollIntoView)==null||n.call(l,{block:"nearest"})})}async function Le(){if(!a.disabled){if(S.value&&u.value.trim()&&(d("update:modelValue",null),d("change",null)),!i.value){await g();return}await e.nextTick(),C(),k(E()),b(j(s.value.length))}}function Ee(t){var l;if(!a.disabled){if(t.key==="Escape"){t.preventDefault(),L(),(l=_.value)==null||l.focus();return}if((t.key==="Backspace"||t.key==="Delete")&&S.value&&!u.value){t.preventDefault(),le();return}if(t.key==="ArrowDown"){if(t.preventDefault(),!i.value){g();return}if(a.loading)return;k(ee(r.value,1));return}if(t.key==="ArrowUp"){if(t.preventDefault(),!i.value){g();return}if(a.loading)return;k(ee(r.value<0?s.value.length:r.value,-1));return}if(t.key==="Enter"){if(!i.value||a.loading)return;t.preventDefault();const n=s.value[r.value];n&&!n.disabled&&te(n)}}}function te(t){var n;if(a.disabled||t.disabled)return;const l=a.emitValue?f(t)??t:t;d("update:modelValue",l),d("change",l),b(`${m(t)} selected.`),L(),(n=_.value)==null||n.focus()}function le(){var t;a.disabled||(d("update:modelValue",null),d("change",null),d("clear"),u.value="",b("Selection cleared."),g(),(t=_.value)==null||t.focus())}function $e(){window.setTimeout(()=>{a.closeOnBlur&&L(),d("blur")},100)}function ne(t){var c,y;const l=t.target;if(!l||!i.value)return;if(x.value){x.value=!1;return}const n=(c=H.value)==null?void 0:c.contains(l),o=(y=B.value)==null?void 0:y.contains(l);!n&&!o&&L()}function $(){i.value&&C()}return e.watch(()=>a.loading,t=>{i.value&&(r.value=t?-1:E(),b(t?a.loadingText:j(s.value.length)))}),e.watch(s,t=>{var l;if(!(!i.value||a.loading)){if(!t.length){r.value=-1,b(a.noResultsText);return}(r.value<0||r.value>=t.length||(l=t[r.value])!=null&&l.disabled)&&k(E())}}),e.onMounted(()=>{document.addEventListener("click",ne),window.addEventListener("resize",$),window.addEventListener("scroll",$,!0)}),e.onUnmounted(()=>{document.removeEventListener("click",ne),window.removeEventListener("resize",$),window.removeEventListener("scroll",$,!0)}),(t,l)=>(e.openBlock(),e.createElementBlock("div",{ref_key:"rootRef",ref:H,class:e.normalizeClass(["select-simple select-simple-search",{selected:S.value,disabled:e.unref(N),"has-error":e.unref(q),open:i.value,"has-selected-slot":!!t.$slots.selected&&h.value&&!u.value}])},[e.unref(K)?(e.openBlock(),e.createElementBlock("label",{key:0,for:P.value,class:"select-simple-label"},e.toDisplayString(e.unref(K)),9,ae)):e.createCommentVNode("",!0),e.createElementVNode("div",{ref_key:"controlRef",ref:O,class:"select-simple-control"},[h.value&&!u.value?e.renderSlot(t.$slots,"selected",{key:0,option:h.value},void 0,!0):e.createCommentVNode("",!0),e.withDirectives(e.createElementVNode("input",{id:P.value,ref_key:"inputRef",ref:_,"onUpdate:modelValue":l[0]||(l[0]=n=>G.value=n),type:"text",class:"select-simple-input",role:"combobox",name:e.unref(we),disabled:e.unref(N),placeholder:e.unref(Be),"aria-label":e.unref(K)?void 0:e.unref(be),"aria-expanded":i.value,"aria-controls":D.value,"aria-activedescendant":J.value,"aria-invalid":e.unref(q)||void 0,"aria-haspopup":"listbox","aria-autocomplete":"list","aria-busy":e.unref(W)||void 0,autocomplete:"off",onFocus:g,onClick:g,onInput:Le,onKeydown:Ee,onBlur:$e},null,40,oe),[[e.vModelText,G.value]]),e.unref(ye)&&S.value&&!e.unref(N)?(e.openBlock(),e.createElementBlock("button",{key:1,type:"button",class:"select-simple-clear","aria-label":e.unref(ge),onClick:e.withModifiers(le,["stop"])},[...l[2]||(l[2]=[e.createElementVNode("svg",{width:"16",height:"16",viewBox:"0 0 16 16","aria-hidden":"true",focusable:"false"},[e.createElementVNode("path",{d:"M12 4L4 12M4 4l8 8",fill:"none",stroke:"currentColor","stroke-linecap":"round","stroke-width":"2"})],-1)])],8,re)):e.createCommentVNode("",!0)],512),e.createElementVNode("div",ie,e.toDisplayString(T.value),1),(e.openBlock(),e.createBlock(e.Teleport,{to:"body",disabled:e.unref(R)},[i.value&&!e.unref(R)?(e.openBlock(),e.createElementBlock("div",se)):e.createCommentVNode("",!0),i.value?(e.openBlock(),e.createElementBlock("div",{key:1,id:D.value,ref_key:"listboxRef",ref:B,role:"listbox",class:e.normalizeClass(["select-simple-options",[e.unref(Z),e.unref(he),{"select-simple-options-inline":e.unref(R)}]]),style:e.normalizeStyle(xe.value)},[e.unref(W)?(e.openBlock(),e.createElementBlock("div",de,[e.renderSlot(t.$slots,"loading",{},()=>[e.createTextVNode(e.toDisplayString(e.unref(ke)),1)],!0)])):s.value.length?(e.openBlock(!0),e.createElementBlock(e.Fragment,{key:1},e.renderList(s.value,(n,o)=>(e.openBlock(),e.createElementBlock("div",{id:Y(o),key:Ve(n,o),role:"option",class:e.normalizeClass(["select-simple-option",[e.unref(_e),{selected:A(n),active:r.value===o,disabled:n.disabled,highlighted:e.unref(Z)==="billing-state"&&r.value===o}]]),"aria-selected":A(n),"aria-disabled":n.disabled||void 0,onMousedown:l[1]||(l[1]=e.withModifiers(()=>{},["prevent"])),onClick:c=>te(n)},[e.renderSlot(t.$slots,"option",{option:n,selected:A(n),active:r.value===o},()=>[e.createElementVNode("span",fe,[e.createElementVNode("strong",null,e.toDisplayString(m(n)),1),X(n)?(e.openBlock(),e.createElementBlock("span",pe,e.toDisplayString(X(n)),1)):e.createCommentVNode("",!0)])],!0)],42,ue))),128)):(e.openBlock(),e.createElementBlock("div",me,[e.renderSlot(t.$slots,"no-results",{},()=>[e.createTextVNode(e.toDisplayString(e.unref(ve)),1)],!0)]))],14,ce)):e.createCommentVNode("",!0)],8,["disabled"]))],2))}}),[["__scopeId","data-v-58b7f39e"]]);p.SelectSimpleSearch=F,p.default=F,Object.defineProperties(p,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
import { SelectOption, SelectSimpleSearchProps } from '../types';
|
|
2
|
+
declare function __VLS_template(): {
|
|
3
|
+
attrs: Partial<{}>;
|
|
4
|
+
slots: {
|
|
5
|
+
selected?(_: {
|
|
6
|
+
option: SelectOption;
|
|
7
|
+
}): any;
|
|
8
|
+
loading?(_: {}): any;
|
|
9
|
+
option?(_: {
|
|
10
|
+
option: SelectOption;
|
|
11
|
+
selected: boolean;
|
|
12
|
+
active: boolean;
|
|
13
|
+
}): any;
|
|
14
|
+
'no-results'?(_: {}): any;
|
|
15
|
+
};
|
|
16
|
+
refs: {
|
|
17
|
+
rootRef: HTMLDivElement;
|
|
18
|
+
controlRef: HTMLDivElement;
|
|
19
|
+
inputRef: HTMLInputElement;
|
|
20
|
+
listboxRef: HTMLDivElement;
|
|
21
|
+
};
|
|
22
|
+
rootEl: HTMLDivElement;
|
|
23
|
+
};
|
|
24
|
+
type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
|
|
25
|
+
declare const __VLS_component: import('vue').DefineComponent<SelectSimpleSearchProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
|
|
26
|
+
"update:modelValue": (value: import('..').ModelValue) => any;
|
|
27
|
+
change: (value: import('..').ModelValue) => any;
|
|
28
|
+
blur: () => any;
|
|
29
|
+
clear: () => any;
|
|
30
|
+
open: () => any;
|
|
31
|
+
close: () => any;
|
|
32
|
+
}, string, import('vue').PublicProps, Readonly<SelectSimpleSearchProps> & Readonly<{
|
|
33
|
+
"onUpdate:modelValue"?: ((value: import('..').ModelValue) => any) | undefined;
|
|
34
|
+
onChange?: ((value: import('..').ModelValue) => any) | undefined;
|
|
35
|
+
onBlur?: (() => any) | undefined;
|
|
36
|
+
onClear?: (() => any) | undefined;
|
|
37
|
+
onOpen?: (() => any) | undefined;
|
|
38
|
+
onClose?: (() => any) | undefined;
|
|
39
|
+
}>, {
|
|
40
|
+
label: string;
|
|
41
|
+
name: string;
|
|
42
|
+
disabled: boolean;
|
|
43
|
+
options: SelectOption[];
|
|
44
|
+
modelValue: import('..').ModelValue;
|
|
45
|
+
placeholder: string;
|
|
46
|
+
type: string;
|
|
47
|
+
inlineListbox: boolean;
|
|
48
|
+
closeOnBlur: boolean;
|
|
49
|
+
inputId: string;
|
|
50
|
+
listboxId: string;
|
|
51
|
+
ariaLabel: string;
|
|
52
|
+
labelKey: string;
|
|
53
|
+
valueKey: string;
|
|
54
|
+
searchKeys: string[];
|
|
55
|
+
clearable: boolean;
|
|
56
|
+
clearLabel: string;
|
|
57
|
+
noResultsText: string;
|
|
58
|
+
loading: boolean;
|
|
59
|
+
loadingText: string;
|
|
60
|
+
maxHeight: string;
|
|
61
|
+
dropdownClass: string;
|
|
62
|
+
optionClass: string;
|
|
63
|
+
hasError: boolean;
|
|
64
|
+
facilityFallbackLabel: string;
|
|
65
|
+
emitValue: boolean;
|
|
66
|
+
sortOptions: boolean;
|
|
67
|
+
}, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
|
|
68
|
+
rootRef: HTMLDivElement;
|
|
69
|
+
controlRef: HTMLDivElement;
|
|
70
|
+
inputRef: HTMLInputElement;
|
|
71
|
+
listboxRef: HTMLDivElement;
|
|
72
|
+
}, HTMLDivElement>;
|
|
73
|
+
declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
|
|
74
|
+
export default _default;
|
|
75
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
76
|
+
new (): {
|
|
77
|
+
$slots: S;
|
|
78
|
+
};
|
|
79
|
+
};
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { default as SelectSimpleSearch } from './components/SelectSimpleSearch.vue';
|
|
2
|
+
export { SelectSimpleSearch };
|
|
3
|
+
export default SelectSimpleSearch;
|
|
4
|
+
export type { ModelValue, SelectOption, SelectPrimitive, SelectSimpleSearchEmits, SelectSimpleSearchProps, } from './types';
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export type SelectPrimitive = string | number;
|
|
2
|
+
export interface SelectOption {
|
|
3
|
+
id?: SelectPrimitive;
|
|
4
|
+
value?: SelectPrimitive;
|
|
5
|
+
slug?: string;
|
|
6
|
+
label?: string;
|
|
7
|
+
name?: string;
|
|
8
|
+
disabled?: boolean;
|
|
9
|
+
address?: {
|
|
10
|
+
city?: string;
|
|
11
|
+
full_address?: string;
|
|
12
|
+
};
|
|
13
|
+
public_title?: string;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export type ModelValue = SelectOption | SelectPrimitive | null;
|
|
17
|
+
export interface SelectSimpleSearchProps {
|
|
18
|
+
options?: SelectOption[];
|
|
19
|
+
modelValue?: ModelValue;
|
|
20
|
+
placeholder?: string;
|
|
21
|
+
type?: string;
|
|
22
|
+
inlineListbox?: boolean;
|
|
23
|
+
closeOnBlur?: boolean;
|
|
24
|
+
label?: string;
|
|
25
|
+
name?: string;
|
|
26
|
+
inputId?: string;
|
|
27
|
+
listboxId?: string;
|
|
28
|
+
ariaLabel?: string;
|
|
29
|
+
labelKey?: string;
|
|
30
|
+
valueKey?: string;
|
|
31
|
+
searchKeys?: string[];
|
|
32
|
+
disabled?: boolean;
|
|
33
|
+
clearable?: boolean;
|
|
34
|
+
clearLabel?: string;
|
|
35
|
+
noResultsText?: string;
|
|
36
|
+
loading?: boolean;
|
|
37
|
+
loadingText?: string;
|
|
38
|
+
maxHeight?: string;
|
|
39
|
+
dropdownClass?: string;
|
|
40
|
+
optionClass?: string;
|
|
41
|
+
hasError?: boolean;
|
|
42
|
+
facilityFallbackLabel?: string;
|
|
43
|
+
emitValue?: boolean;
|
|
44
|
+
sortOptions?: boolean;
|
|
45
|
+
}
|
|
46
|
+
export interface SelectSimpleSearchEmits {
|
|
47
|
+
(event: "update:modelValue", value: ModelValue): void;
|
|
48
|
+
(event: "change", value: ModelValue): void;
|
|
49
|
+
(event: "blur"): void;
|
|
50
|
+
(event: "clear"): void;
|
|
51
|
+
(event: "open"): void;
|
|
52
|
+
(event: "close"): void;
|
|
53
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@irina_grigoreva/accessible-vue-search-select",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Accessible Vue 3 searchable select component with keyboard navigation, ARIA combobox/listbox support, TypeScript, slots, and teleported dropdowns.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"vue",
|
|
7
|
+
"vue3",
|
|
8
|
+
"typescript",
|
|
9
|
+
"accessibility",
|
|
10
|
+
"a11y",
|
|
11
|
+
"combobox",
|
|
12
|
+
"listbox",
|
|
13
|
+
"select",
|
|
14
|
+
"searchable-select",
|
|
15
|
+
"ui-component"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://github.com/irina-grigoreva/accessible-vue-search-select#readme",
|
|
18
|
+
"bugs": {
|
|
19
|
+
"url": "https://github.com/irina-grigoreva/accessible-vue-search-select/issues"
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "git+https://github.com/irina-grigoreva/accessible-vue-search-select.git"
|
|
24
|
+
},
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"author": "Irina Grigoreva",
|
|
27
|
+
"type": "module",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/accessible-vue-search-select.js",
|
|
32
|
+
"require": "./dist/accessible-vue-search-select.umd.cjs"
|
|
33
|
+
},
|
|
34
|
+
"./dist/accessible-vue-search-select.css": "./dist/accessible-vue-search-select.css",
|
|
35
|
+
"./style.css": "./dist/accessible-vue-search-select.css"
|
|
36
|
+
},
|
|
37
|
+
"main": "./dist/accessible-vue-search-select.umd.cjs",
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"directories": {
|
|
40
|
+
"doc": "docs",
|
|
41
|
+
"example": "examples",
|
|
42
|
+
"test": "tests"
|
|
43
|
+
},
|
|
44
|
+
"files": [
|
|
45
|
+
"dist",
|
|
46
|
+
"README.md",
|
|
47
|
+
"LICENSE"
|
|
48
|
+
],
|
|
49
|
+
"scripts": {
|
|
50
|
+
"build": "vue-tsc --noEmit && vite build",
|
|
51
|
+
"dev": "vite",
|
|
52
|
+
"lint": "eslint .",
|
|
53
|
+
"test": "vitest run",
|
|
54
|
+
"test:watch": "vitest",
|
|
55
|
+
"typecheck": "vue-tsc --noEmit",
|
|
56
|
+
"preview": "vite preview",
|
|
57
|
+
"prepublishOnly": "npm run lint && npm run typecheck && npm run test && npm run build"
|
|
58
|
+
},
|
|
59
|
+
"dependencies": {
|
|
60
|
+
"abbrev": "^2.0.0",
|
|
61
|
+
"acorn": "^8.16.0",
|
|
62
|
+
"acorn-jsx": "^5.3.2",
|
|
63
|
+
"agent-base": "^7.1.4",
|
|
64
|
+
"ajv": "^6.15.0",
|
|
65
|
+
"ajv-formats": "^3.0.1",
|
|
66
|
+
"alien-signals": "^1.0.13",
|
|
67
|
+
"ansi-regex": "^6.2.2",
|
|
68
|
+
"ansi-styles": "^6.2.3",
|
|
69
|
+
"argparse": "^2.0.1",
|
|
70
|
+
"assertion-error": "^2.0.1",
|
|
71
|
+
"asynckit": "^0.4.0",
|
|
72
|
+
"balanced-match": "^1.0.2",
|
|
73
|
+
"boolbase": "^1.0.0",
|
|
74
|
+
"brace-expansion": "^2.1.0",
|
|
75
|
+
"cac": "^6.7.14",
|
|
76
|
+
"call-bind-apply-helpers": "^1.0.2",
|
|
77
|
+
"callsites": "^3.1.0",
|
|
78
|
+
"chai": "^5.3.3",
|
|
79
|
+
"chalk": "^4.1.2",
|
|
80
|
+
"check-error": "^2.1.3",
|
|
81
|
+
"color-convert": "^2.0.1",
|
|
82
|
+
"color-name": "^1.1.4",
|
|
83
|
+
"combined-stream": "^1.0.8",
|
|
84
|
+
"commander": "^10.0.1",
|
|
85
|
+
"compare-versions": "^6.1.1",
|
|
86
|
+
"concat-map": "^0.0.1",
|
|
87
|
+
"confbox": "^0.2.4",
|
|
88
|
+
"config-chain": "^1.1.13",
|
|
89
|
+
"cross-spawn": "^7.0.6",
|
|
90
|
+
"cssesc": "^3.0.0",
|
|
91
|
+
"cssstyle": "^4.6.0",
|
|
92
|
+
"csstype": "^3.2.3",
|
|
93
|
+
"data-urls": "^5.0.0",
|
|
94
|
+
"de-indent": "^1.0.2",
|
|
95
|
+
"debug": "^4.4.3",
|
|
96
|
+
"decimal.js": "^10.6.0",
|
|
97
|
+
"deep-eql": "^5.0.2",
|
|
98
|
+
"deep-is": "^0.1.4",
|
|
99
|
+
"delayed-stream": "^1.0.0",
|
|
100
|
+
"diff": "^8.0.4",
|
|
101
|
+
"dunder-proto": "^1.0.1",
|
|
102
|
+
"eastasianwidth": "^0.2.0",
|
|
103
|
+
"editorconfig": "^1.0.7",
|
|
104
|
+
"emoji-regex": "^9.2.2",
|
|
105
|
+
"entities": "^7.0.1",
|
|
106
|
+
"es-define-property": "^1.0.1",
|
|
107
|
+
"es-errors": "^1.3.0",
|
|
108
|
+
"es-module-lexer": "^1.7.0",
|
|
109
|
+
"es-object-atoms": "^1.1.1",
|
|
110
|
+
"es-set-tostringtag": "^2.1.0",
|
|
111
|
+
"esbuild": "^0.25.12",
|
|
112
|
+
"escape-string-regexp": "^4.0.0",
|
|
113
|
+
"eslint-scope": "^8.4.0",
|
|
114
|
+
"eslint-visitor-keys": "^4.2.1",
|
|
115
|
+
"espree": "^10.4.0",
|
|
116
|
+
"esquery": "^1.7.0",
|
|
117
|
+
"esrecurse": "^4.3.0",
|
|
118
|
+
"estraverse": "^5.3.0",
|
|
119
|
+
"estree-walker": "^2.0.2",
|
|
120
|
+
"esutils": "^2.0.3",
|
|
121
|
+
"expect-type": "^1.3.0",
|
|
122
|
+
"exsolve": "^1.0.8",
|
|
123
|
+
"fast-deep-equal": "^3.1.3",
|
|
124
|
+
"fast-json-stable-stringify": "^2.1.0",
|
|
125
|
+
"fast-levenshtein": "^2.0.6",
|
|
126
|
+
"fast-uri": "^3.1.2",
|
|
127
|
+
"fdir": "^6.5.0",
|
|
128
|
+
"file-entry-cache": "^8.0.0",
|
|
129
|
+
"find-up": "^5.0.0",
|
|
130
|
+
"flat-cache": "^4.0.1",
|
|
131
|
+
"flatted": "^3.4.2",
|
|
132
|
+
"foreground-child": "^3.3.1",
|
|
133
|
+
"form-data": "^4.0.5",
|
|
134
|
+
"fs-extra": "^11.3.5",
|
|
135
|
+
"function-bind": "^1.1.2",
|
|
136
|
+
"get-intrinsic": "^1.3.0",
|
|
137
|
+
"get-proto": "^1.0.1",
|
|
138
|
+
"glob": "^10.5.0",
|
|
139
|
+
"glob-parent": "^6.0.2",
|
|
140
|
+
"globals": "^14.0.0",
|
|
141
|
+
"gopd": "^1.2.0",
|
|
142
|
+
"graceful-fs": "^4.2.11",
|
|
143
|
+
"has-flag": "^4.0.0",
|
|
144
|
+
"has-symbols": "^1.1.0",
|
|
145
|
+
"has-tostringtag": "^1.0.2",
|
|
146
|
+
"hasown": "^2.0.3",
|
|
147
|
+
"he": "^1.2.0",
|
|
148
|
+
"html-encoding-sniffer": "^4.0.0",
|
|
149
|
+
"http-proxy-agent": "^7.0.2",
|
|
150
|
+
"https-proxy-agent": "^7.0.6",
|
|
151
|
+
"iconv-lite": "^0.6.3",
|
|
152
|
+
"ignore": "^5.3.2",
|
|
153
|
+
"import-fresh": "^3.3.1",
|
|
154
|
+
"import-lazy": "^4.0.0",
|
|
155
|
+
"imurmurhash": "^0.1.4",
|
|
156
|
+
"ini": "^1.3.8",
|
|
157
|
+
"is-core-module": "^2.16.2",
|
|
158
|
+
"is-extglob": "^2.1.1",
|
|
159
|
+
"is-fullwidth-code-point": "^3.0.0",
|
|
160
|
+
"is-glob": "^4.0.3",
|
|
161
|
+
"is-potential-custom-element-name": "^1.0.1",
|
|
162
|
+
"isexe": "^2.0.0",
|
|
163
|
+
"jackspeak": "^3.4.3",
|
|
164
|
+
"jju": "^1.4.0",
|
|
165
|
+
"js-beautify": "^1.15.4",
|
|
166
|
+
"js-cookie": "^3.0.7",
|
|
167
|
+
"js-tokens": "^9.0.1",
|
|
168
|
+
"js-yaml": "^4.1.1",
|
|
169
|
+
"json-buffer": "^3.0.1",
|
|
170
|
+
"json-schema-traverse": "^0.4.1",
|
|
171
|
+
"json-stable-stringify-without-jsonify": "^1.0.1",
|
|
172
|
+
"jsonfile": "^6.2.1",
|
|
173
|
+
"keyv": "^4.5.4",
|
|
174
|
+
"kolorist": "^1.8.0",
|
|
175
|
+
"levn": "^0.4.1",
|
|
176
|
+
"local-pkg": "^1.1.2",
|
|
177
|
+
"locate-path": "^6.0.0",
|
|
178
|
+
"lodash": "^4.18.1",
|
|
179
|
+
"lodash.merge": "^4.6.2",
|
|
180
|
+
"loupe": "^3.2.1",
|
|
181
|
+
"lru-cache": "^10.4.3",
|
|
182
|
+
"magic-string": "^0.30.21",
|
|
183
|
+
"math-intrinsics": "^1.1.0",
|
|
184
|
+
"mime-db": "^1.52.0",
|
|
185
|
+
"mime-types": "^2.1.35",
|
|
186
|
+
"minimatch": "^9.0.9",
|
|
187
|
+
"minipass": "^7.1.3",
|
|
188
|
+
"mlly": "^1.8.2",
|
|
189
|
+
"ms": "^2.1.3",
|
|
190
|
+
"muggle-string": "^0.4.1",
|
|
191
|
+
"nanoid": "^3.3.12",
|
|
192
|
+
"natural-compare": "^1.4.0",
|
|
193
|
+
"nopt": "^7.2.1",
|
|
194
|
+
"nth-check": "^2.1.1",
|
|
195
|
+
"nwsapi": "^2.2.23",
|
|
196
|
+
"optionator": "^0.9.4",
|
|
197
|
+
"p-limit": "^3.1.0",
|
|
198
|
+
"p-locate": "^5.0.0",
|
|
199
|
+
"package-json-from-dist": "^1.0.1",
|
|
200
|
+
"parent-module": "^1.0.1",
|
|
201
|
+
"parse5": "^7.3.0",
|
|
202
|
+
"path-browserify": "^1.0.1",
|
|
203
|
+
"path-exists": "^4.0.0",
|
|
204
|
+
"path-key": "^3.1.1",
|
|
205
|
+
"path-parse": "^1.0.7",
|
|
206
|
+
"path-scurry": "^1.11.1",
|
|
207
|
+
"pathe": "^2.0.3",
|
|
208
|
+
"pathval": "^2.0.1",
|
|
209
|
+
"picocolors": "^1.1.1",
|
|
210
|
+
"picomatch": "^4.0.4",
|
|
211
|
+
"pkg-types": "^2.3.1",
|
|
212
|
+
"postcss": "^8.5.14",
|
|
213
|
+
"postcss-selector-parser": "^6.1.2",
|
|
214
|
+
"prelude-ls": "^1.2.1",
|
|
215
|
+
"proto-list": "^1.2.4",
|
|
216
|
+
"punycode": "^2.3.1",
|
|
217
|
+
"quansync": "^0.2.11",
|
|
218
|
+
"require-from-string": "^2.0.2",
|
|
219
|
+
"resolve": "^1.22.12",
|
|
220
|
+
"resolve-from": "^4.0.0",
|
|
221
|
+
"rollup": "^4.60.4",
|
|
222
|
+
"rrweb-cssom": "^0.7.1",
|
|
223
|
+
"safer-buffer": "^2.1.2",
|
|
224
|
+
"saxes": "^6.0.0",
|
|
225
|
+
"semver": "^7.8.0",
|
|
226
|
+
"shebang-command": "^2.0.0",
|
|
227
|
+
"shebang-regex": "^3.0.0",
|
|
228
|
+
"siginfo": "^2.0.0",
|
|
229
|
+
"signal-exit": "^4.1.0",
|
|
230
|
+
"source-map": "^0.6.1",
|
|
231
|
+
"source-map-js": "^1.2.1",
|
|
232
|
+
"sprintf-js": "^1.0.3",
|
|
233
|
+
"stackback": "^0.0.2",
|
|
234
|
+
"std-env": "^3.10.0",
|
|
235
|
+
"string-argv": "^0.3.2",
|
|
236
|
+
"string-width": "^5.1.2",
|
|
237
|
+
"string-width-cjs": "^4.2.3",
|
|
238
|
+
"strip-ansi": "^7.2.0",
|
|
239
|
+
"strip-ansi-cjs": "^6.0.1",
|
|
240
|
+
"strip-json-comments": "^3.1.1",
|
|
241
|
+
"strip-literal": "^3.1.0",
|
|
242
|
+
"supports-color": "^7.2.0",
|
|
243
|
+
"supports-preserve-symlinks-flag": "^1.0.0",
|
|
244
|
+
"symbol-tree": "^3.2.4",
|
|
245
|
+
"tinybench": "^2.9.0",
|
|
246
|
+
"tinyexec": "^0.3.2",
|
|
247
|
+
"tinyglobby": "^0.2.16",
|
|
248
|
+
"tinypool": "^1.1.1",
|
|
249
|
+
"tinyrainbow": "^2.0.0",
|
|
250
|
+
"tinyspy": "^4.0.4",
|
|
251
|
+
"tldts": "^6.1.86",
|
|
252
|
+
"tldts-core": "^6.1.86",
|
|
253
|
+
"tough-cookie": "^5.1.2",
|
|
254
|
+
"tr46": "^5.1.1",
|
|
255
|
+
"ts-api-utils": "^2.5.0",
|
|
256
|
+
"type-check": "^0.4.0",
|
|
257
|
+
"type-fest": "^0.20.2",
|
|
258
|
+
"ufo": "^1.6.4",
|
|
259
|
+
"undici-types": "^7.24.6",
|
|
260
|
+
"universalify": "^2.0.1",
|
|
261
|
+
"uri-js": "^4.4.1",
|
|
262
|
+
"util-deprecate": "^1.0.2",
|
|
263
|
+
"vite-node": "^3.2.4",
|
|
264
|
+
"vscode-uri": "^3.1.0",
|
|
265
|
+
"vue-component-type-helpers": "^3.3.0",
|
|
266
|
+
"vue-eslint-parser": "^9.4.3",
|
|
267
|
+
"w3c-xmlserializer": "^5.0.0",
|
|
268
|
+
"webidl-conversions": "^7.0.0",
|
|
269
|
+
"whatwg-encoding": "^3.1.1",
|
|
270
|
+
"whatwg-mimetype": "^4.0.0",
|
|
271
|
+
"whatwg-url": "^14.2.0",
|
|
272
|
+
"which": "^2.0.2",
|
|
273
|
+
"why-is-node-running": "^2.3.0",
|
|
274
|
+
"word-wrap": "^1.2.5",
|
|
275
|
+
"wrap-ansi": "^8.1.0",
|
|
276
|
+
"wrap-ansi-cjs": "^7.0.0",
|
|
277
|
+
"ws": "^8.20.1",
|
|
278
|
+
"xml-name-validator": "^5.0.0",
|
|
279
|
+
"xmlchars": "^2.2.0",
|
|
280
|
+
"yocto-queue": "^0.1.0"
|
|
281
|
+
},
|
|
282
|
+
"devDependencies": {
|
|
283
|
+
"@eslint/js": "^9.27.0",
|
|
284
|
+
"@types/node": "^25.9.0",
|
|
285
|
+
"@vitejs/plugin-vue": "^5.2.4",
|
|
286
|
+
"@vue/test-utils": "^2.4.6",
|
|
287
|
+
"eslint": "^9.27.0",
|
|
288
|
+
"eslint-plugin-vue": "^9.33.0",
|
|
289
|
+
"jsdom": "^25.0.1",
|
|
290
|
+
"typescript": "^5.8.3",
|
|
291
|
+
"typescript-eslint": "^8.32.1",
|
|
292
|
+
"vite": "^6.3.5",
|
|
293
|
+
"vite-plugin-dts": "^4.5.4",
|
|
294
|
+
"vitest": "^3.1.4",
|
|
295
|
+
"vue": "^3.5.16",
|
|
296
|
+
"vue-tsc": "^2.2.10"
|
|
297
|
+
},
|
|
298
|
+
"peerDependencies": {
|
|
299
|
+
"vue": "^3.5.0"
|
|
300
|
+
},
|
|
301
|
+
"module": "./dist/accessible-vue-search-select.js"
|
|
302
|
+
}
|