source: imaps-frontend/node_modules/bootstrap/js/src/util/focustrap.js

main
Last change on this file was d565449, checked in by stefan toskovski <stefantoska84@…>, 4 weeks ago

Update repo after prototype presentation

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