107107 isOptionDeselectable(option) && index === typeAheadPointer,
108108 'vs__dropdown-option--selected': isOptionSelected(option),
109109 'vs__dropdown-option--highlight': index === typeAheadPointer,
110+ 'vs__dropdown-option--kb-focus': hasKeyboardFocusBorder(index),
110111 'vs__dropdown-option--disabled': !selectable(option),
111112 }"
112113 :aria-selected =" index === typeAheadPointer ? true : null"
113- @mouseover =" selectable (option) ? (typeAheadPointer = index) : null "
114+ @mouseover =" onMouseOver (option, index)"
114115 @click.prevent.stop =" selectable(option) ? select(option) : null"
115116 >
116117 <slot name =" option" v-bind =" normalizeOptionForSlot(option)" >
@@ -660,6 +661,15 @@ export default {
660661 },
661662 },
662663
664+ /**
665+ * Display a visible border around dropdown options
666+ * which have keyboard focus.
667+ */
668+ keyboardFocusBorder: {
669+ type: Boolean ,
670+ default: false ,
671+ },
672+
663673 /**
664674 * A unique identifier used to generate IDs in HTML.
665675 * Must be unique for every instance of the component.
@@ -675,6 +685,7 @@ export default {
675685 search: ' ' ,
676686 open: false ,
677687 isComposing: false ,
688+ isKeyboardNavigation: false ,
678689 pushedTags: [],
679690 // eslint-disable-next-line vue/no-reserved-keys
680691 _value: [], // Internal value managed by Vue Select if no `value` prop is passed
@@ -1134,6 +1145,19 @@ export default {
11341145 return this .isOptionSelected (option) && this .deselectFromDropdown
11351146 },
11361147
1148+ /**
1149+ * Check if the option at the given index should display a
1150+ * keyboard focus border.
1151+ * @param {Number} index
1152+ * @return {Boolean}
1153+ */
1154+ hasKeyboardFocusBorder (index ) {
1155+ if (this .keyboardFocusBorder && this .isKeyboardNavigation ) {
1156+ return index === this .typeAheadPointer
1157+ }
1158+ return false
1159+ },
1160+
11371161 /**
11381162 * Determine if two option objects are matching.
11391163 *
@@ -1309,6 +1333,20 @@ export default {
13091333 this .mousedown = false
13101334 },
13111335
1336+ /**
1337+ * Event-Handler for option mouseover
1338+ * @param {Object|String} option
1339+ * @param {Number} index
1340+ * @return {void}
1341+ */
1342+ onMouseOver (option , index ) {
1343+ this .isKeyboardNavigation = false
1344+ if (! this .selectable (option)) {
1345+ return
1346+ }
1347+ this .typeAheadPointer = index
1348+ },
1349+
13121350 /**
13131351 * Search <input> KeyBoardEvent handler.
13141352 * @param {KeyboardEvent} e
@@ -1330,6 +1368,7 @@ export default {
13301368 // up.prevent
13311369 38 : (e ) => {
13321370 e .preventDefault ()
1371+ this .isKeyboardNavigation = true
13331372 if (! this .open ) {
13341373 this .open = true
13351374 return
@@ -1339,6 +1378,7 @@ export default {
13391378 // down.prevent
13401379 40 : (e ) => {
13411380 e .preventDefault ()
1381+ this .isKeyboardNavigation = true
13421382 if (! this .open ) {
13431383 this .open = true
13441384 return
0 commit comments