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 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 109 export default {
96 110 name: 'iSelect',
97 111 mixins: [ Emitter, Locale ],
... ... @@ -275,16 +289,39 @@
275 289 },
276 290 selectOptions() {
277 291 const selectOptions = [];
  292 + const slotOptions = (this.slotOptions || []);
278 293 let optionCounter = -1;
279 294 const currentIndex = this.focusIndex;
280 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 323 const cOptions = option.componentOptions;
286 324 if (!cOptions) continue;
287   -
288 325 if (cOptions.tag.match(optionGroupRegexp)){
289 326 let children = cOptions.children;
290 327  
... ... @@ -315,11 +352,7 @@
315 352 return selectOptions;
316 353 },
317 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 357 selectTabindex(){
325 358 return this.disabled || this.filterable ? -1 : 0;
... ... @@ -595,7 +628,7 @@
595 628 }
596 629 },
597 630 focusIndex(index){
598   - if (index < 0) return;
  631 + if (index < 0 || this.autoComplete) return;
599 632 // update scroll
600 633 const optionValue = this.flatOptions[index].componentOptions.propsData.value;
601 634 const optionInstance = findChild(this, ({$options}) => {
... ...