Commit 06a74f9ed76645f476b4818aaaad136798a76012
1 parent
f7f65c84
Allow select to navigate AutoComplete custom children
Showing
1 changed file
with
42 additions
and
9 deletions
Show diff stats
src/components/select/select.vue
@@ -92,6 +92,20 @@ | @@ -92,6 +92,20 @@ | ||
92 | } | 92 | } |
93 | }; | 93 | }; |
94 | 94 | ||
95 | + const findOptionsInVNode = (node) => { | ||
96 | + const opts = node.componentOptions; | ||
97 | + if (opts && opts.tag === 'Option') return [node]; | ||
98 | + if (!node.children) return []; | ||
99 | + const options = node.children.reduce( | ||
100 | + (arr, el) => [...arr, ...findOptionsInVNode(el)], [] | ||
101 | + ).filter(Boolean); | ||
102 | + return options.length > 0 ? options : []; | ||
103 | + }; | ||
104 | + | ||
105 | + const extractOptions = (options) => options.reduce((options, slotEntry) => { | ||
106 | + return options.concat(findOptionsInVNode(slotEntry)); | ||
107 | + }, []); | ||
108 | + | ||
95 | export default { | 109 | export default { |
96 | name: 'iSelect', | 110 | name: 'iSelect', |
97 | mixins: [ Emitter, Locale ], | 111 | mixins: [ Emitter, Locale ], |
@@ -275,16 +289,39 @@ | @@ -275,16 +289,39 @@ | ||
275 | }, | 289 | }, |
276 | selectOptions() { | 290 | selectOptions() { |
277 | const selectOptions = []; | 291 | const selectOptions = []; |
292 | + const slotOptions = (this.slotOptions || []); | ||
278 | let optionCounter = -1; | 293 | let optionCounter = -1; |
279 | const currentIndex = this.focusIndex; | 294 | const currentIndex = this.focusIndex; |
280 | const selectedValues = this.values.map(({value}) => value); | 295 | const selectedValues = this.values.map(({value}) => value); |
281 | - if (this.autoComplete) return this.slotOptions; | 296 | + if (this.autoComplete) { |
297 | + const copyChildren = (node, fn) => { | ||
298 | + return { | ||
299 | + ...node, | ||
300 | + children: (node.children || []).map(fn).map(child => copyChildren(child, fn)) | ||
301 | + }; | ||
302 | + }; | ||
303 | + const autoCompleteOptions = extractOptions(slotOptions); | ||
304 | + const selectedSlotOption = autoCompleteOptions[currentIndex]; | ||
305 | + | ||
306 | + return slotOptions.map(node => copyChildren(node, (child) => { | ||
307 | + if (child !== selectedSlotOption) return child; | ||
308 | + return { | ||
309 | + ...child, | ||
310 | + componentOptions: { | ||
311 | + ...child.componentOptions, | ||
312 | + propsData: { | ||
313 | + ...child.componentOptions.propsData, | ||
314 | + isFocused: true, | ||
315 | + } | ||
316 | + } | ||
317 | + }; | ||
318 | + })); | ||
319 | + } | ||
282 | 320 | ||
283 | - for (let option of (this.slotOptions || [])) { | 321 | + for (let option of slotOptions) { |
284 | 322 | ||
285 | const cOptions = option.componentOptions; | 323 | const cOptions = option.componentOptions; |
286 | if (!cOptions) continue; | 324 | if (!cOptions) continue; |
287 | - | ||
288 | if (cOptions.tag.match(optionGroupRegexp)){ | 325 | if (cOptions.tag.match(optionGroupRegexp)){ |
289 | let children = cOptions.children; | 326 | let children = cOptions.children; |
290 | 327 | ||
@@ -315,11 +352,7 @@ | @@ -315,11 +352,7 @@ | ||
315 | return selectOptions; | 352 | return selectOptions; |
316 | }, | 353 | }, |
317 | flatOptions(){ | 354 | flatOptions(){ |
318 | - return this.selectOptions.reduce((options, option) => { | ||
319 | - const isOptionGroup = option.componentOptions.tag.match(optionGroupRegexp); | ||
320 | - if (isOptionGroup) return options.concat(option.componentOptions.children || []); | ||
321 | - else return options.concat(option); | ||
322 | - }, []); | 355 | + return extractOptions(this.selectOptions); |
323 | }, | 356 | }, |
324 | selectTabindex(){ | 357 | selectTabindex(){ |
325 | return this.disabled || this.filterable ? -1 : 0; | 358 | return this.disabled || this.filterable ? -1 : 0; |
@@ -595,7 +628,7 @@ | @@ -595,7 +628,7 @@ | ||
595 | } | 628 | } |
596 | }, | 629 | }, |
597 | focusIndex(index){ | 630 | focusIndex(index){ |
598 | - if (index < 0) return; | 631 | + if (index < 0 || this.autoComplete) return; |
599 | // update scroll | 632 | // update scroll |
600 | const optionValue = this.flatOptions[index].componentOptions.propsData.value; | 633 | const optionValue = this.flatOptions[index].componentOptions.propsData.value; |
601 | const optionInstance = findChild(this, ({$options}) => { | 634 | const optionInstance = findChild(this, ({$options}) => { |