Skip to content

Commit 26d5953

Browse files
feat(b-form-tags): add ignoreInputFocusSelector prop to make input focus behavior configurable (closes #5425) (#5429)
* fix(b-form-tags): fix input focus upon clicking on nested element * Update form-tags.js * Add `ignoreInputFocusSelector` prop * Update form-tags.js * Add comment and more selectors to ignoreInputFocusSelector in form-tags.js Co-authored-by: Jacob Müller <jacob.mueller.elz@gmail.com>
1 parent 5ee9830 commit 26d5953

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

src/components/form-tags/form-tags.js

+33-7
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,15 @@ import identity from '../../utils/identity'
66
import looseEqual from '../../utils/loose-equal'
77
import { arrayIncludes, concat } from '../../utils/array'
88
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'
1018
import { isEvent, isFunction, isString } from '../../utils/inspect'
1119
import { escapeRegExp, toString, trim, trimLeft } from '../../utils/string'
1220
import 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
})

src/components/form-tags/package.json

+5
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,11 @@
110110
{
111111
"prop": "noOuterFocus",
112112
"description": "When set, disables the focus styling of the component root element"
113+
},
114+
{
115+
"prop": "ignoreInputFocusSelector",
116+
"version": "2.16.0",
117+
"description": "Ignore certain elements from the click to focus input routine, specified by css selector(s)"
113118
}
114119
],
115120
"slots": [

0 commit comments

Comments
 (0)