|
5 | 5 | :class="classList.container"
|
6 | 6 | :id="searchable ? undefined : id"
|
7 | 7 | :dir="rtl ? 'rtl' : undefined"
|
| 8 | + @focusin="handleFocusIn" |
| 9 | + @focusout="handleFocusOut" |
| 10 | + @keydown="handleKeydown" |
| 11 | + @keyup="handleKeyup" |
| 12 | + @mousedown="handleMousedown" |
| 13 | + |
8 | 14 | :aria-owns="ariaOwns"
|
9 |
| - :aria-expanded="isOpen" |
10 | 15 | :aria-label="ariaLabel"
|
11 | 16 | :aria-placeholder="ariaPlaceholder"
|
| 17 | + :aria-expanded="isOpen" |
12 | 18 | :aria-activedescendant="ariaActiveDescendant"
|
13 |
| - @focusin="activate" |
14 |
| - @focusout="deactivate" |
15 |
| - @keydown="handleKeydown" |
16 |
| - @keyup="handleKeyup" |
17 |
| - @focus="handleFocus" |
18 |
| - @mousedown="handleMousedown" |
19 |
| - role="combobox" |
| 19 | + :aria-multiselectable="ariaMultiselectable" |
| 20 | + role="listbox" |
20 | 21 | >
|
21 | 22 | <!-- Search -->
|
22 | 23 | <template v-if="mode !== 'tags' && searchable && !disabled">
|
|
28 | 29 | :autocomplete="autocomplete"
|
29 | 30 | :id="searchable ? id : undefined"
|
30 | 31 | v-bind="attrs"
|
31 |
| - :aria-owns="ariaOwns" |
32 |
| - :aria-expanded="isOpen" |
33 |
| - :aria-label="ariaLabel" |
34 |
| - :aria-placeholder="ariaPlaceholder" |
35 |
| - :aria-activedescendant="ariaActiveDescendant" |
36 | 32 | @input="handleSearchInput"
|
37 | 33 | @keypress="handleKeypress"
|
38 | 34 | @paste.stop="handlePaste"
|
39 | 35 | ref="input"
|
40 |
| - role="combobox" |
| 36 | + |
| 37 | + :aria-owns="ariaOwns" |
| 38 | + :aria-label="ariaLabel" |
| 39 | + :aria-placeholder="ariaPlaceholder" |
| 40 | + :aria-expanded="isOpen" |
| 41 | + :aria-activedescendant="ariaActiveDescendant" |
| 42 | + :aria-multiselectable="ariaMultiselectable" |
| 43 | + role="listbox" |
41 | 44 | />
|
42 | 45 | </template>
|
43 | 46 |
|
|
56 | 59 | tabindex="-1"
|
57 | 60 | @keyup.enter="handleTagRemove(option, $event)"
|
58 | 61 | :key="key"
|
| 62 | + |
| 63 | + :aria-label="ariaTagLabel(option[label])" |
59 | 64 | >
|
60 | 65 | {{ option[label] }}
|
61 | 66 | <span
|
|
82 | 87 | :id="searchable ? id : undefined"
|
83 | 88 | :autocomplete="autocomplete"
|
84 | 89 | v-bind="attrs"
|
85 |
| - :aria-owns="ariaOwns" |
86 |
| - :aria-expanded="isOpen" |
87 |
| - :aria-label="ariaLabel" |
88 |
| - :aria-placeholder="ariaPlaceholder" |
89 |
| - :aria-activedescendant="ariaActiveDescendant" |
90 | 90 | @input="handleSearchInput"
|
91 | 91 | @keypress="handleKeypress"
|
92 | 92 | @paste.stop="handlePaste"
|
93 | 93 | ref="input"
|
94 |
| - role="combobox" |
| 94 | + |
| 95 | + :aria-owns="ariaOwns" |
| 96 | + :aria-label="ariaLabel" |
| 97 | + :aria-placeholder="ariaPlaceholder" |
| 98 | + :aria-expanded="isOpen" |
| 99 | + :aria-activedescendant="ariaActiveDescendant" |
| 100 | + :aria-multiselectable="ariaMultiselectable" |
| 101 | + role="listbox" |
95 | 102 | />
|
96 | 103 | </div>
|
97 | 104 | </div>
|
|
100 | 107 | <!-- Single label -->
|
101 | 108 | <template v-if="mode == 'single' && hasSelected && !search && iv">
|
102 | 109 | <slot name="singlelabel" :value="iv">
|
103 |
| - <div :class="classList.singleLabel"> |
| 110 | + <div :class="classList.singleLabel" aria-hidden="true"> |
104 | 111 | <span :class="classList.singleLabelText" v-html="iv[label]"></span>
|
105 | 112 | </div>
|
106 | 113 | </slot>
|
|
109 | 116 | <!-- Multiple label -->
|
110 | 117 | <template v-if="mode == 'multiple' && hasSelected && !search">
|
111 | 118 | <slot name="multiplelabel" :values="iv">
|
112 |
| - <div :class="classList.multipleLabel" v-html="multipleLabelText"></div> |
| 119 | + <div :class="classList.multipleLabel" v-html="multipleLabelText" aria-hidden="true"></div> |
113 | 120 | </slot>
|
114 | 121 | </template>
|
115 | 122 |
|
116 | 123 | <!-- Placeholder -->
|
117 | 124 | <template v-if="placeholder && !hasSelected && !search">
|
118 | 125 | <slot name="placeholder">
|
119 |
| - <div :class="classList.placeholder"> |
| 126 | + <div :class="classList.placeholder" aria-hidden="true"> |
120 | 127 | {{ placeholder }}
|
121 | 128 | </div>
|
122 | 129 | </slot>
|
123 | 130 | </template>
|
124 | 131 |
|
125 | 132 | <!-- Spinner -->
|
126 | 133 | <slot v-if="loading || resolving" name="spinner">
|
127 |
| - <span :class="classList.spinner"></span> |
| 134 | + <span :class="classList.spinner" aria-hidden="true"></span> |
128 | 135 | </slot>
|
129 | 136 |
|
130 | 137 | <!-- Clear -->
|
131 | 138 | <slot v-if="hasSelected && !disabled && canClear && !busy" name="clear" :clear="clear">
|
132 | 139 | <span
|
133 | 140 | tabindex="0"
|
| 141 | + role="button" |
| 142 | + aria-label="❎" |
134 | 143 | :class="classList.clear"
|
135 | 144 | @click="clear"
|
136 | 145 | @keyup.enter="clear"
|
|
139 | 148 |
|
140 | 149 | <!-- Caret -->
|
141 | 150 | <slot v-if="caret && showOptions" name="caret">
|
142 |
| - <span :class="classList.caret" @click="handleCaretClick"></span> |
| 151 | + <span :class="classList.caret" @click="handleCaretClick" aria-hidden="true"></span> |
143 | 152 | </slot>
|
144 | 153 |
|
145 | 154 | <!-- Options -->
|
|
149 | 158 | >
|
150 | 159 | <slot name="beforelist" :options="fo"></slot>
|
151 | 160 |
|
152 |
| - <ul :class="classList.options" :id="ariaOwns" role="listbox"> |
| 161 | + <ul :class="classList.options" :id="ariaOwns"> |
153 | 162 | <template v-if="groups">
|
154 | 163 | <li
|
155 | 164 | v-for="(group, i, key) in fg"
|
156 | 165 | :class="classList.group"
|
157 | 166 | :key="key"
|
| 167 | + |
| 168 | + :id="ariaGroupId(group, i)" |
| 169 | + :aria-label="ariaGroupLabel(group)" |
| 170 | + :aria-selected="isSelected(group)" |
| 171 | + role="option" |
158 | 172 | >
|
159 | 173 | <div
|
160 | 174 | :class="classList.groupLabel(group)"
|
161 | 175 | :data-pointed="isPointed(group)"
|
162 |
| - @mouseenter="setPointer(group)" |
| 176 | + @mouseenter="setPointer(group, i)" |
163 | 177 | @click="handleGroupClick(group)"
|
164 |
| - role="none" |
165 | 178 | >
|
166 | 179 | <slot name="grouplabel" :group="group" :is-selected="isSelected" :is-pointed="isPointed">
|
167 | 180 | <span v-html="group[groupLabel]"></span>
|
|
170 | 183 |
|
171 | 184 | <ul
|
172 | 185 | :class="classList.groupOptions"
|
| 186 | + |
173 | 187 | :aria-label="ariaGroupLabel(group)"
|
174 | 188 | role="group"
|
175 | 189 | >
|
176 | 190 | <li
|
177 | 191 | v-for="(option, i, key) in group.__VISIBLE__"
|
178 | 192 | :class="classList.option(option, group)"
|
179 |
| - :key="key" |
180 | 193 | :data-pointed="isPointed(option)"
|
181 | 194 | :data-selected="isSelected(option) || undefined"
|
182 |
| - :id="ariaOptionId(option)" |
183 |
| - :aria-label="ariaOptionLabel(option)" |
| 195 | + :key="key" |
184 | 196 | @mouseenter="setPointer(option)"
|
185 | 197 | @click="handleOptionClick(option)"
|
| 198 | + |
| 199 | + :id="ariaOptionId(option)" |
| 200 | + :aria-selected="isSelected(option)" |
| 201 | + :aria-label="ariaOptionLabel(option)" |
186 | 202 | role="option"
|
187 | 203 | >
|
188 | 204 | <slot name="option" :option="option" :is-selected="isSelected" :is-pointed="isPointed" :search="search">
|
|
195 | 211 | <template v-else>
|
196 | 212 | <li
|
197 | 213 | v-for="(option, i, key) in fo"
|
198 |
| - :id="ariaOptionId(option)" |
199 |
| - :aria-label="ariaOptionLabel(option)" |
200 | 214 | :class="classList.option(option)"
|
201 |
| - :key="key" |
202 | 215 | :data-pointed="isPointed(option)"
|
203 | 216 | :data-selected="isSelected(option) || undefined"
|
| 217 | + :key="key" |
204 | 218 | @mouseenter="setPointer(option)"
|
205 | 219 | @click="handleOptionClick(option)"
|
| 220 | + |
| 221 | + :id="ariaOptionId(option)" |
| 222 | + :aria-selected="isSelected(option)" |
| 223 | + :aria-label="ariaOptionLabel(option)" |
206 | 224 | role="option"
|
207 | 225 | >
|
208 | 226 | <slot name="option" :option="option" :isSelected="isSelected" :is-pointed="isPointed" :search="search">
|
|
0 commit comments