-
Notifications
You must be signed in to change notification settings - Fork 332
/
paper-select-menu-inner.js
109 lines (98 loc) · 3.5 KB
/
paper-select-menu-inner.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
import { filterBy } from '@ember/object/computed';
import { run } from '@ember/runloop';
import layout from '../templates/components/paper-select-menu-inner';
import PaperMenuContentInner from './paper-menu-content-inner';
import {
indexOfOption,
optionAtIndex,
countOptions
} from 'ember-power-select/utils/group-utils';
function advanceSelectableOption(options, currentOption, step) {
let resultsLength = countOptions(options);
let startIndex = Math.min(Math.max(indexOfOption(options, currentOption) + step, 0), resultsLength - 1);
let { disabled, option } = optionAtIndex(options, startIndex);
while (option && disabled) {
let next = optionAtIndex(options, startIndex += step);
disabled = next.disabled;
option = next.option;
}
return option;
}
export default PaperMenuContentInner.extend({
layout,
tagName: 'md-select-menu',
classNames: ['md-default-theme'],
classNameBindings: ['searchEnabled:md-overflow'],
enabledOptions: filterBy('childComponents', 'disabled', false),
didInsertElement() {
run.next(() => {
let focusTarget = this.element.querySelector('md-option[aria-selected="true"]');
if (!focusTarget || !focusTarget.length) {
focusTarget = this.get('enabledOptions.firstObject.element');
let newHighlighted = advanceSelectableOption(this.dropdown.results, this.dropdown.highlighted, -1);
this.dropdown.actions.highlight(newHighlighted, null);
} else {
focusTarget = focusTarget[0];
}
if (focusTarget) {
focusTarget.focus();
}
});
},
keyDown(ev) {
switch (ev.which) {
case this.get('constants.KEYCODE.ESCAPE'): {
this.dropdown.actions.close();
break;
}
case this.get('constants.KEYCODE.LEFT_ARROW'):
case this.get('constants.KEYCODE.UP_ARROW'): {
ev.preventDefault();
this.focusOption(ev, -1);
let newHighlighted = advanceSelectableOption(this.dropdown.results, this.dropdown.highlighted, -1);
this.dropdown.actions.highlight(newHighlighted, ev);
this.dropdown.actions.scrollTo(newHighlighted);
break;
}
case this.get('constants.KEYCODE.RIGHT_ARROW'):
case this.get('constants.KEYCODE.DOWN_ARROW'): {
ev.preventDefault();
this.focusOption(ev, 1);
let newHighlighted2 = advanceSelectableOption(this.dropdown.results, this.dropdown.highlighted, 1);
this.dropdown.actions.highlight(newHighlighted2, ev);
this.dropdown.actions.scrollTo(newHighlighted2);
break;
}
case this.get('constants.KEYCODE.ENTER'): {
ev.preventDefault();
this.dropdown.actions.choose(this.dropdown.highlighted);
break;
}
}
},
focusOption(e, direction) {
let currentItem = e.target.closest('md-option');
let children = this.get('enabledMenuItems');
let items = children.map((child) => child.element);
let currentIndex = items.indexOf(currentItem[0]);
// Traverse through our elements in the specified direction (+/-1) and try to
// focus them until we find one that accepts focus
for (let i = currentIndex + direction; i >= 0 && i < items.length; i = i + direction) {
let focusTarget = items[i];
let didFocus = this.attemptFocus(focusTarget);
if (didFocus) {
break;
}
}
},
attemptFocus(el) {
if (el && el.getAttribute('tabindex') !== -1) {
el.focus();
if (document.activeElement === el) {
return true;
} else {
return false;
}
}
}
});