@@ -6,7 +6,15 @@ import identity from '../../utils/identity'
6
6
import looseEqual from '../../utils/loose-equal'
7
7
import { arrayIncludes , concat } from '../../utils/array'
8
8
import { 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'
10
18
import { isEvent , isFunction , isString } from '../../utils/inspect'
11
19
import { escapeRegExp , toString , trim , trimLeft } from '../../utils/string'
12
20
import idMixin from '../../mixins/id'
@@ -178,6 +186,12 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
178
186
type : Boolean ,
179
187
default : false
180
188
} ,
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
+ } ,
181
195
value : {
182
196
// The v-model prop
183
197
type : Array ,
@@ -245,6 +259,13 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
245
259
const joiner = this . computedSeparator . charAt ( 0 )
246
260
return joiner !== ' ' ? `${ joiner } ` : joiner
247
261
} ,
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
+ } ,
248
269
disableAddButton ( ) {
249
270
// If 'Add' button should be disabled
250
271
// If the input contains at least one tag that can
@@ -416,7 +437,13 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
416
437
} ,
417
438
// --- Wrapper event handlers ---
418
439
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
+ ) {
420
447
this . $nextTick ( ( ) => {
421
448
this . focus ( )
422
449
} )
@@ -630,8 +657,7 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
630
657
staticClass : 'list-unstyled mt-n1 mb-0 d-flex flex-wrap align-items-center' ,
631
658
attrs : { id : tagListId }
632
659
} ,
633
- // `concat()` is faster than array spread when args are known to be arrays
634
- concat ( $tags , $field )
660
+ [ $tags , $field ]
635
661
)
636
662
637
663
// Assemble the feedback
@@ -792,12 +818,12 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
792
818
'aria-describedby' : this . safeId ( '_selected_' )
793
819
} ,
794
820
on : {
821
+ click : this . onClick ,
795
822
focusin : this . onFocusin ,
796
- focusout : this . onFocusout ,
797
- click : this . onClick
823
+ focusout : this . onFocusout
798
824
}
799
825
} ,
800
- concat ( $output , $removed , $content , $hidden )
826
+ [ $output , $removed , $content , $hidden ]
801
827
)
802
828
}
803
829
} )
0 commit comments