@@ -6,7 +6,15 @@ import identity from '../../utils/identity'
66import looseEqual from '../../utils/loose-equal'
77import { arrayIncludes , concat } from '../../utils/array'
88import { getComponentConfig } from '../../utils/config'
9- import { attemptBlur , attemptFocus , matches , requestAF , select } from '../../utils/dom'
9+ import {
10+ attemptBlur ,
11+ attemptFocus ,
12+ closest ,
13+ isActiveElement ,
14+ matches ,
15+ requestAF ,
16+ select
17+ } from '../../utils/dom'
1018import { isEvent , isFunction , isString } from '../../utils/inspect'
1119import { escapeRegExp , toString , trim , trimLeft } from '../../utils/string'
1220import idMixin from '../../mixins/id'
@@ -178,6 +186,12 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
178186 type : Boolean ,
179187 default : false
180188 } ,
189+ ignoreInputFocusSelector : {
190+ // Disable the input focus behavior when clicking
191+ // on element matching the selector (or selectors)
192+ type : [ Array , String ] ,
193+ default : ( ) => [ '.b-form-tag' , 'button' , 'input' , 'select' ]
194+ } ,
181195 value : {
182196 // The v-model prop
183197 type : Array ,
@@ -245,6 +259,13 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
245259 const joiner = this . computedSeparator . charAt ( 0 )
246260 return joiner !== ' ' ? `${ joiner } ` : joiner
247261 } ,
262+ computeIgnoreInputFocusSelector ( ) {
263+ // Normalize to an single selector with selectors separated by `,`
264+ return concat ( this . ignoreInputFocusSelector )
265+ . filter ( identity )
266+ . join ( ',' )
267+ . trim ( )
268+ } ,
248269 disableAddButton ( ) {
249270 // If 'Add' button should be disabled
250271 // If the input contains at least one tag that can
@@ -416,7 +437,13 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
416437 } ,
417438 // --- Wrapper event handlers ---
418439 onClick ( evt ) {
419- if ( ! this . disabled && isEvent ( evt ) && evt . target === evt . currentTarget ) {
440+ const ignoreFocusSelector = this . computeIgnoreInputFocusSelector
441+ const { target } = evt
442+ if (
443+ ! this . disabled &&
444+ ! isActiveElement ( target ) &&
445+ ( ! ignoreFocusSelector || ! closest ( ignoreFocusSelector , target , true ) )
446+ ) {
420447 this . $nextTick ( ( ) => {
421448 this . focus ( )
422449 } )
@@ -630,8 +657,7 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
630657 staticClass : 'list-unstyled mt-n1 mb-0 d-flex flex-wrap align-items-center' ,
631658 attrs : { id : tagListId }
632659 } ,
633- // `concat()` is faster than array spread when args are known to be arrays
634- concat ( $tags , $field )
660+ [ $tags , $field ]
635661 )
636662
637663 // Assemble the feedback
@@ -792,12 +818,12 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
792818 'aria-describedby' : this . safeId ( '_selected_' )
793819 } ,
794820 on : {
821+ click : this . onClick ,
795822 focusin : this . onFocusin ,
796- focusout : this . onFocusout ,
797- click : this . onClick
823+ focusout : this . onFocusout
798824 }
799825 } ,
800- concat ( $output , $removed , $content , $hidden )
826+ [ $output , $removed , $content , $hidden ]
801827 )
802828 }
803829} )
0 commit comments