Commit 06a74f9ed76645f476b4818aaaad136798a76012

Authored by Sergio Crisostomo
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}) => {