108108 isOptionDeselectable(option) && index === typeAheadPointer,
109109 'vs__dropdown-option--selected': isOptionSelected(option),
110110 'vs__dropdown-option--highlight': index === typeAheadPointer,
111+ 'vs__dropdown-option--kb-focus': hasKeyboardFocusBorder(index),
111112 'vs__dropdown-option--disabled': !selectable(option),
112113 }"
113114 :aria-selected =" optionAriaSelected(option)"
114- @mouseover = " selectable (option) ? (typeAheadPointer = index) : null "
115+ @mousemove = " onMouseMove (option, index)"
115116 @click.prevent.stop =" selectable(option) ? select(option) : null"
116117 >
117118 <slot name =" option" v-bind =" normalizeOptionForSlot(option)" >
@@ -661,6 +662,15 @@ export default {
661662 },
662663 },
663664
665+ /**
666+ * Display a visible border around dropdown options
667+ * which have keyboard focus.
668+ */
669+ keyboardFocusBorder: {
670+ type: Boolean ,
671+ default: false ,
672+ },
673+
664674 /**
665675 * A unique identifier used to generate IDs in HTML.
666676 * Must be unique for every instance of the component.
@@ -676,6 +686,7 @@ export default {
676686 search: ' ' ,
677687 open: false ,
678688 isComposing: false ,
689+ isKeyboardNavigation: false ,
679690 pushedTags: [],
680691 // eslint-disable-next-line vue/no-reserved-keys
681692 _value: [], // Internal value managed by Vue Select if no `value` prop is passed
@@ -1135,6 +1146,19 @@ export default {
11351146 return this .isOptionSelected (option) && this .deselectFromDropdown
11361147 },
11371148
1149+ /**
1150+ * Check if the option at the given index should display a
1151+ * keyboard focus border.
1152+ * @param {Number} index
1153+ * @return {Boolean}
1154+ */
1155+ hasKeyboardFocusBorder (index ) {
1156+ if (this .keyboardFocusBorder && this .isKeyboardNavigation ) {
1157+ return index === this .typeAheadPointer
1158+ }
1159+ return false
1160+ },
1161+
11381162 /**
11391163 * Determine if two option objects are matching.
11401164 *
@@ -1324,6 +1348,20 @@ export default {
13241348 this .mousedown = false
13251349 },
13261350
1351+ /**
1352+ * Event-Handler for option mousemove
1353+ * @param {Object|String} option
1354+ * @param {Number} index
1355+ * @return {void}
1356+ */
1357+ onMouseMove (option , index ) {
1358+ this .isKeyboardNavigation = false
1359+ if (! this .selectable (option)) {
1360+ return
1361+ }
1362+ this .typeAheadPointer = index
1363+ },
1364+
13271365 /**
13281366 * Search <input> KeyBoardEvent handler.
13291367 * @param {KeyboardEvent} e
@@ -1349,6 +1387,7 @@ export default {
13491387 // up.prevent
13501388 38 : (e ) => {
13511389 e .preventDefault ()
1390+ this .isKeyboardNavigation = true
13521391 if (! this .open ) {
13531392 this .open = true
13541393 return
@@ -1358,6 +1397,7 @@ export default {
13581397 // down.prevent
13591398 40 : (e ) => {
13601399 e .preventDefault ()
1400+ this .isKeyboardNavigation = true
13611401 if (! this .open ) {
13621402 this .open = true
13631403 return
0 commit comments