22// Based loosely on https://adamwathan.me/renderless-components-in-vuejs/
33import { Vue } from '../../vue'
44import { NAME_FORM_TAGS } from '../../constants/components'
5- import { EVENT_NAME_TAG_STATE , EVENT_OPTIONS_PASSIVE } from '../../constants/events'
5+ import {
6+ EVENT_NAME_BLUR ,
7+ EVENT_NAME_FOCUS ,
8+ EVENT_NAME_FOCUSIN ,
9+ EVENT_NAME_FOCUSOUT ,
10+ EVENT_NAME_TAG_STATE ,
11+ EVENT_OPTIONS_PASSIVE
12+ } from '../../constants/events'
613import { CODE_BACKSPACE , CODE_DELETE , CODE_ENTER } from '../../constants/key-codes'
714import {
815 PROP_TYPE_ARRAY ,
@@ -24,7 +31,7 @@ import { identity } from '../../utils/identity'
2431import { isEvent , isNumber , isString } from '../../utils/inspect'
2532import { looseEqual } from '../../utils/loose-equal'
2633import { makeModelMixin } from '../../utils/model'
27- import { pick , sortKeys } from '../../utils/object'
34+ import { omit , pick , sortKeys } from '../../utils/object'
2835import { hasPropFunction , makeProp , makePropsConfigurable } from '../../utils/props'
2936import { escapeRegExp , toString , trim , trimLeft } from '../../utils/string'
3037import { formControlMixin , props as formControlProps } from '../../mixins/form-control'
@@ -154,7 +161,8 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
154161 // Tags that were removed
155162 removedTags : [ ] ,
156163 // Populated when tags are parsed
157- tagsState : cleanTagsState ( )
164+ tagsState : cleanTagsState ( ) ,
165+ focusState : null
158166 }
159167 } ,
160168 computed : {
@@ -180,9 +188,11 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
180188 } ,
181189 computedInputHandlers ( ) {
182190 return {
183- ...this . bvListeners ,
184- input : this . onInputInput ,
191+ ...omit ( this . bvListeners , [ EVENT_NAME_FOCUSIN , EVENT_NAME_FOCUSOUT ] ) ,
192+ blur : this . onInputBlur ,
185193 change : this . onInputChange ,
194+ focus : this . onInputFocus ,
195+ input : this . onInputInput ,
186196 keydown : this . onInputKeydown ,
187197 reset : this . reset
188198 }
@@ -411,11 +421,39 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
411421 } )
412422 }
413423 } ,
414- onFocusin ( ) {
424+ onInputFocus ( event ) {
425+ if ( this . focusState !== 'out' ) {
426+ this . focusState = 'in'
427+ this . $nextTick ( ( ) => {
428+ requestAF ( ( ) => {
429+ if ( this . hasFocus ) {
430+ this . $emit ( EVENT_NAME_FOCUS , event )
431+ this . focusState = null
432+ }
433+ } )
434+ } )
435+ }
436+ } ,
437+ onInputBlur ( event ) {
438+ if ( this . focusState !== 'in' ) {
439+ this . focusState = 'out'
440+ this . $nextTick ( ( ) => {
441+ requestAF ( ( ) => {
442+ if ( ! this . hasFocus ) {
443+ this . $emit ( EVENT_NAME_BLUR , event )
444+ this . focusState = null
445+ }
446+ } )
447+ } )
448+ }
449+ } ,
450+ onFocusin ( event ) {
415451 this . hasFocus = true
452+ this . $emit ( EVENT_NAME_FOCUSIN , event )
416453 } ,
417- onFocusout ( ) {
454+ onFocusout ( event ) {
418455 this . hasFocus = false
456+ this . $emit ( EVENT_NAME_FOCUSOUT , event )
419457 } ,
420458 handleAutofocus ( ) {
421459 this . $nextTick ( ( ) => {
0 commit comments