8000 chore(utils/dom): add new utils for focus/blur handling (#5346) · bootstrap-vue/bootstrap-vue@0009784 · GitHub
[go: up one dir, main page]

Skip to content

Commit 0009784

Browse files
chore(utils/dom): add new utils for focus/blur handling (#5346)
* feat(utils/dom): add new utils for focus/blur handling * Update sidebar.js * Update sidebar.js * Update dom.js * Update dom.js * Update dom.js * Update dom.js * Update dom.js Co-authored-by: Troy Morehouse <troymore@nbnet.nb.ca>
1 parent 9e1e394 commit 0009784

File tree

27 files changed

+191
-221
lines changed

27 files changed

+191
-221
lines changed

src/components/button-toolbar/button-toolbar.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import Vue from '../../utils/vue'
2-
import { isVisible, selectAll } from '../../utils/dom'
3-
import normalizeSlotMixin from '../../mixins/normalize-slot'
42
import KeyCodes from '../../utils/key-codes'
3+
import { attemptFocus, isVisible, selectAll } from '../../utils/dom'
4+
import normalizeSlotMixin from '../../mixins/normalize-slot'
55

66
const ITEM_SELECTOR = [
77
'.btn:not(.disabled):not([disabled]):not(.dropdown-item)',
@@ -58,32 +58,29 @@ export const BButtonToolbar = /*#__PURE__*/ Vue.extend({
5858
shift ? this.focusLast(evt) : this.focusNext(evt)
5959
}
6060
},
61-
setItemFocus(item) {
62-
item && item.focus && item.focus()
63-
},
6461
focusFirst() {
6562
const items = this.getItems()
66-
this.setItemFocus(items[0])
63+
attemptFocus(items[0])
6764
},
6865
focusPrev(evt) {
6966
let items = this.getItems()
7067
const index = items.indexOf(evt.target)
7168
if (index > -1) {
7269
items = items.slice(0, index).reverse()
73-
this.setItemFocus(items[0])
70+
attemptFocus(items[0])
7471
}
7572
},
7673
focusNext(evt) {
7774
let items = this.getItems()
7875
const index = items.indexOf(evt.target)
7976
if (index > -1) {
8077
items = items.slice(index + 1)
81-
this.setItemFocus(items[0])
78+
attemptFocus(items[0])
8279
}
8380
},
8481
focusLast() {
8582
const items = this.getItems().reverse()
86-
this.setItemFocus(items[0])
83+
attemptFocus(items[0])
8784
},
8885
getItems() {
8986
const items = selectAll(ITEM_SELECTOR, this.$el)

src/components/calendar/calendar.js

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import {
2121
parseYMD,
2222
resolveLocale
2323
} from '../../utils/date'
24-
import { requestAF } from '../../utils/dom'
24+
import { attemptBlur, attemptFocus, requestAF } from '../../utils/dom'
2525
import { isArray, isFunction, isPlainObject, isString } from '../../utils/inspect'
2626
import { isLocaleRTL } from '../../utils/locale'
2727
import { mathMax } from '../../utils/math'
@@ -618,15 +618,13 @@ export const BCalendar = Vue.extend({
618618
// Public method(s)
619619
focus() {
620620
if (!this.disabled) {
621-
try {
622-
this.$refs.grid.focus()
623-
} catch {}
621+
attemptFocus(this.$refs.grid)
624622
}
625623
},
626624
blur() {
627-
try {
628-
this.$refs.grid.blur()
629-
} catch {}
625+
if (!this.disabled) {
626+
attemptBlur(this.$refs.grid)
627+
}
630628
},
631629
// Private methods
632630
setLive(on) {

src/components/carousel/carousel.js

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,14 @@ import KeyCodes from '../../utils/key-codes'
33
import noop from '../../utils/noop'
44
import observeDom from '../../utils/observe-dom'
55
import { getComponentConfig } from '../../utils/config'
6-
import { selectAll, reflow, addClass, removeClass, setAttr } from '../../utils/dom'
6+
import {
7+
addClass,
8+
getActiveElement,
9+
reflow,
10+
removeClass,
11+
selectAll,
12+
setAttr
13+
} from '../../utils/dom'
714
import { isBrowser, hasTouchSupport, hasPointerEventSupport } from '../../utils/env'
815
import { EVENT_OPTIONS_NO_CAPTURE, eventOn, eventOff } from '../../utils/events'
916
import { isUndefined } from '../../utils/inspect'
@@ -302,7 +309,7 @@ export const BCarousel = /*#__PURE__*/ Vue.extend({
302309
// Restart auto rotate slides when focus/hover leaves the carousel
303310
/* istanbul ignore next */
304311
restart() /* istanbul ignore next: difficult to test */ {
305-
if (!this.$el.contains(document.activeElement)) {
312+
if (!this.$el.contains(getActiveElement())) {
306313
this.start()
307314
}
308315
},

src/components/form-datepicker/form-datepicker.js

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { arrayIncludes } from '../../utils/array'
33
import { BVFormBtnLabelControl, dropdownProps } from '../../utils/bv-form-btn-label-control'
44
import { getComponentConfig } from '../../utils/config'
55
import { createDate, constrainDate, formatYMD, parseYMD } from '../../utils/date'
6+
import { attemptBlur, attemptFocus } from '../../utils/dom'
67
import { isUndefinedOrNull } from '../../utils/inspect'
78
import { pick } from '../../utils/object'
89
import idMixin from '../../mixins/id'
@@ -377,16 +378,12 @@ export const BFormDatepicker = /*#__PURE__*/ Vue.extend({
377378
// Public methods
378379
focus() {
379380
if (!this.disabled) {
380-
try {
381-
this.$refs.control.focus()
382-
} catch {}
381+
attemptFocus(this.$refs.control)
383382
}
384383
},
385384
blur() {
386385
if (!this.disabled) {
387-
try {
388-
this.$refs.control.blur()
389-
} catch {}
386+
attemptBlur(this.$refs.control)
390387
}
391388
},
392389
// Private methods
@@ -435,9 +432,7 @@ export const BFormDatepicker = /*#__PURE__*/ Vue.extend({
435432
},
436433
onShown() {
437434
this.$nextTick(() => {
438-
try {
439-
this.$refs.calendar.focus()
440-
} catch {}
435+
attemptFocus(this.$refs.calendar)
441436
this.$emit('shown')
442437
})
443438
},

src/components/form-group/form-group.js

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
import memoize from '../../utils/memoize'
22
import { arrayIncludes } from '../../utils/array'
33
import { getBreakpointsUpCached } from '../../utils/config'
4-
import { select, selectAll, isVisible, setAttr, removeAttr, getAttr } from '../../utils/dom'
4+
import {
5+
select,
6+
selectAll,
7+
isVisible,
8+
setAttr,
9+
removeAttr,
10+
getAttr,
11+
attemptFocus
12+
} from '../../utils/dom'
513
import { isBrowser } from '../../utils/env'
614
import { isBoolean } from '../../utils/inspect'
715
import { toInteger } from '../../utils/number'
@@ -361,11 +369,9 @@ export const BFormGroup = {
361369
return
362370
}
363371
const inputs = selectAll(SELECTOR, this.$refs.content).filter(isVisible)
364-
if (inputs && inputs.length === 1 && inputs[0].focus) {
365-
// if only a single input, focus it, emulating label behaviour
366-
try {
367-
inputs[0].focus()
368-
} catch {}
372+
// If only a single input, focus it, emulating label behaviour
373+
if (inputs && inputs.length === 1) {
374+
attemptFocus(inputs[0])
369375
}
370376
},
371377
setInputDescribedBy(add, remove) {

src/components/form-input/form-input.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Vue from '../../utils/vue'
22
import { arrayIncludes } from '../../utils/array'
3+
import { attemptBlur } from '../../utils/dom'
34
import { eventOn, eventOff, eventOnOff } from '../../utils/events'
45
import formMixin from '../../mixins/form'
56
import formSelectionMixin from '../../mixins/form-selection'
@@ -150,7 +151,7 @@ export const BFormInput = /*#__PURE__*/ Vue.extend({
150151
},
151152
stopWheel(evt) {
152153
evt.preventDefault()
153-
this.$el.blur()
154+
attemptBlur(this.$el)
154155
}
155156
},
156157
render(h) {

src/components/form-rating/form-rating.js

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Vue from '../../utils/vue'
22
import { arrayIncludes, concat } from '../../utils/array'
33
import { getComponentConfig } from '../../utils/config'
4+
import { attemptBlur, attemptFocus } from '../../utils/dom'
45
import { isNull } from '../../utils/inspect'
56
import { isLocaleRTL } from '../../utils/locale'
67
import { mathMax, mathMin } from '../../utils/math'
@@ -262,16 +263,12 @@ export const BFormRating = /*#__PURE__*/ Vue.extend({
262263
// --- Public methods ---
263264
focus() {
264265
if (!this.disabled) {
265-
try {
266-
this.$el.focus()
267-
} catch {}
266+
attemptFocus(this.$el)
268267
}
269268
},
270269
blur() {
271270
if (!this.disabled) {
272-
try {
273-
this.$el.blur()
274-
} catch {}
271+
attemptBlur(this.$el)
275272
}
276273
},
277274
// --- Private methods ---

src/components/form-select/form-select.js

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import Vue from '../../utils/vue'
22
import { from as arrayFrom, isArray } from '../../utils/array'
3+
import { attemptBlur, attemptFocus } from '../../utils/dom'
34
import { htmlOrText } from '../../utils/html'
45
import idMixin from '../../mixins/id'
56
import formMixin from '../../mixins/form'
@@ -83,10 +84,10 @@ export const BFormSelect = /*#__PURE__*/ Vue.extend({
8384
},
8485
methods: {
8586
focus() {
86-
this.$refs.input.focus()
87+
attemptFocus(this.$refs.input)
8788
},
8889
blur() {
89-
this.$refs.input.blur()
90+
attemptBlur(this.$refs.input)
9091
}
9192
},
9293
render(h) {

src/components/form-spinbutton/form-spinbutton.js

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import KeyCodes from '../../utils/key-codes'
33
import identity from '../../utils/identity'
44
import { arrayIncludes, concat } from '../../utils/array'
55
import { getComponentConfig } from '../../utils/config'
6+
import { attemptBlur, attemptFocus } from '../../utils/dom'
67
import { eventOnOff } from '../../utils/events'
78
import { isFunction, isNull } from '../../utils/inspect'
89
import { isLocaleRTL } from '../../utils/locale'
@@ -306,16 +307,12 @@ export const BFormSpinbutton = /*#__PURE__*/ Vue.extend({
306307
// --- Public methods ---
307308
focus() {
308309
if (!this.disabled) {
309-
try {
310-
this.$refs.spinner.focus()
311-
} catch {}
310+
attemptFocus(this.$refs.spinner)
312311
}
313312
},
314313
blur() {
315314
if (!this.disabled) {
316-
try {
317-
this.$refs.spinner.blur()
318-
} catch {}
315+
attemptBlur(this.$refs.spinner)
319316
}
320317
},
321318
// --- Private methods ---
@@ -500,10 +497,8 @@ export const BFormSpinbutton = /*#__PURE__*/ Vue.extend({
500497
if (!disabled && !readonly) {
501498
evt.preventDefault()
502499
this.setMouseup(true)
503-
try {
504-
// Since we `preventDefault()`, we must manually focus the button
505-
evt.currentTarget.focus()
506-
} catch {}
500+
// Since we `preventDefault()`, we must manually focus the button
501+
attemptFocus(evt.currentTarget)
507502
this.handleStepRepeat(evt, stepper)
508503
}
509504
}

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

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ 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 { matches, requestAF, select } from '../../utils/dom'
9+
import { attemptBlur, attemptFocus, matches, requestAF, select } from '../../utils/dom'
1010
import { isEvent, isFunction, isString } from '../../utils/inspect'
1111
import { escapeRegExp, toString, trim, trimLeft } from '../../utils/string'
1212
import idMixin from '../../mixins/id'
@@ -440,15 +440,13 @@ export const BFormTags = /*#__PURE__*/ Vue.extend({
440440
// --- Public methods ---
441441
focus() {
442442
if (!this.disabled) {
443-
try {
444-
this.getInput().focus()
445-
} catch {}
443+
attemptFocus(this.getInput())
446444
}
447445
},
448446
blur() {
449-
try {
450-
this.getInput().blur()
451-
} catch {}
447+
if (!this.disabled) {
448+
attemptBlur(this.getInput())
449+
}
452450
},
453451
// --- Private methods ---
454452
splitTags(newTag) {

0 commit comments

Comments
 (0)
0