diff options
| author | Bobby <[email protected]> | 2024-08-16 20:47:33 -0400 |
|---|---|---|
| committer | GitHub <[email protected]> | 2024-08-16 20:47:33 -0400 |
| commit | 6b28433d9cfde435be8ec2bd6cf91e6324d08865 (patch) | |
| tree | 8343c27b8b95ff5639233e81cf157f92e5688466 /js/dist/util/focustrap.js | |
| parent | d53094ec16ba385faae2973ddee648698b32ab24 (diff) | |
| parent | 048f56f51460df75e92a2f7b472e1c56baeb68f7 (diff) | |
| download | bootstrap-main.tar.xz bootstrap-main.zip | |
Diffstat (limited to 'js/dist/util/focustrap.js')
| -rw-r--r-- | js/dist/util/focustrap.js | 113 |
1 files changed, 113 insertions, 0 deletions
diff --git a/js/dist/util/focustrap.js b/js/dist/util/focustrap.js new file mode 100644 index 000000000..c0deacb7c --- /dev/null +++ b/js/dist/util/focustrap.js @@ -0,0 +1,113 @@ +/*! + * Bootstrap focustrap.js v5.3.3 (https://getbootstrap.com/) + * Copyright 2011-2024 The Bootstrap Authors (https://github.com/twbs/bootstrap/graphs/contributors) + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + */ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory(require('../dom/event-handler.js'), require('../dom/selector-engine.js'), require('./config.js')) : + typeof define === 'function' && define.amd ? define(['../dom/event-handler', '../dom/selector-engine', './config'], factory) : + (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.Focustrap = factory(global.EventHandler, global.SelectorEngine, global.Config)); +})(this, (function (EventHandler, SelectorEngine, Config) { 'use strict'; + + /** + * -------------------------------------------------------------------------- + * Bootstrap util/focustrap.js + * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE) + * -------------------------------------------------------------------------- + */ + + + /** + * Constants + */ + + const NAME = 'focustrap'; + const DATA_KEY = 'bs.focustrap'; + const EVENT_KEY = `.${DATA_KEY}`; + const EVENT_FOCUSIN = `focusin${EVENT_KEY}`; + const EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`; + const TAB_KEY = 'Tab'; + const TAB_NAV_FORWARD = 'forward'; + const TAB_NAV_BACKWARD = 'backward'; + const Default = { + autofocus: true, + trapElement: null // The element to trap focus inside of + }; + const DefaultType = { + autofocus: 'boolean', + trapElement: 'element' + }; + + /** + * Class definition + */ + + class FocusTrap extends Config { + constructor(config) { + super(); + this._config = this._getConfig(config); + this._isActive = false; + this._lastTabNavDirection = null; + } + + // Getters + static get Default() { + return Default; + } + static get DefaultType() { + return DefaultType; + } + static get NAME() { + return NAME; + } + + // Public + activate() { + if (this._isActive) { + return; + } + if (this._config.autofocus) { + this._config.trapElement.focus(); + } + EventHandler.off(document, EVENT_KEY); // guard against infinite focus loop + EventHandler.on(document, EVENT_FOCUSIN, event => this._handleFocusin(event)); + EventHandler.on(document, EVENT_KEYDOWN_TAB, event => this._handleKeydown(event)); + this._isActive = true; + } + deactivate() { + if (!this._isActive) { + return; + } + this._isActive = false; + EventHandler.off(document, EVENT_KEY); + } + + // Private + _handleFocusin(event) { + const { + trapElement + } = this._config; + if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) { + return; + } + const elements = SelectorEngine.focusableChildren(trapElement); + if (elements.length === 0) { + trapElement.focus(); + } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) { + elements[elements.length - 1].focus(); + } else { + elements[0].focus(); + } + } + _handleKeydown(event) { + if (event.key !== TAB_KEY) { + return; + } + this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD; + } + } + + return FocusTrap; + +})); +//# sourceMappingURL=focustrap.js.map |
