source: trip-planner-front/node_modules/bootstrap/js/src/util/focustrap.js@ 6a3a178

Last change on this file since 6a3a178 was 6a3a178, checked in by Ema <ema_spirova@…>, 3 years ago

initial commit

  • Property mode set to 100644
File size: 2.4 KB
Line 
1/**
2 * --------------------------------------------------------------------------
3 * Bootstrap (v5.1.3): util/focustrap.js
4 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)
5 * --------------------------------------------------------------------------
6 */
7
8import EventHandler from '../dom/event-handler'
9import SelectorEngine from '../dom/selector-engine'
10import { typeCheckConfig } from './index'
11
12const Default = {
13 trapElement: null, // The element to trap focus inside of
14 autofocus: true
15}
16
17const DefaultType = {
18 trapElement: 'element',
19 autofocus: 'boolean'
20}
21
22const NAME = 'focustrap'
23const DATA_KEY = 'bs.focustrap'
24const EVENT_KEY = `.${DATA_KEY}`
25const EVENT_FOCUSIN = `focusin${EVENT_KEY}`
26const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`
27
28const TAB_KEY = 'Tab'
29const TAB_NAV_FORWARD = 'forward'
30const TAB_NAV_BACKWARD = 'backward'
31
32class FocusTrap {
33 constructor(config) {
34 this._config = this._getConfig(config)
35 this._isActive = false
36 this._lastTabNavDirection = null
37 }
38
39 activate() {
40 const { trapElement, autofocus } = this._config
41
42 if (this._isActive) {
43 return
44 }
45
46 if (autofocus) {
47 trapElement.focus()
48 }
49
50 EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop
51 EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event))
52 EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event))
53
54 this._isActive = true
55 }
56
57 deactivate() {
58 if (!this._isActive) {
59 return
60 }
61
62 this._isActive = false
63 EventHandler.off(document, EVENT_KEY)
64 }
65
66 // Private
67
68 _handleFocusin(event) {
69 const { target } = event
70 const { trapElement } = this._config
71
72 if (target === document || target === trapElement || trapElement.contains(target)) {
73 return
74 }
75
76 const elements = SelectorEngine.focusableChildren(trapElement)
77
78 if (elements.length === 0) {
79 trapElement.focus()
80 } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
81 elements[elements.length - 1].focus()
82 } else {
83 elements[0].focus()
84 }
85 }
86
87 _handleKeydown(event) {
88 if (event.key !== TAB_KEY) {
89 return
90 }
91
92 this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD
93 }
94
95 _getConfig(config) {
96 config = {
97 ...Default,
98 ...(typeof config === 'object' ? config : {})
99 }
100 typeCheckConfig(NAME, config, DefaultType)
101 return config
102 }
103}
104
105export default FocusTrap
Note: See TracBrowser for help on using the repository browser.