bootstrap-italia 2.14.0 → 2.15.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/bootstrap-italia.min.css +1 -1
- package/dist/css/bootstrap-italia.min.css.map +1 -1
- package/dist/js/bootstrap-italia.bundle.min.js +10 -10
- package/dist/js/bootstrap-italia.min.js +4 -4
- package/dist/plugins/navbar-collapsible.js +120 -139
- package/dist/plugins/navbar-collapsible.js.map +1 -1
- package/dist/plugins/navscroll.js +27 -3
- package/dist/plugins/navscroll.js.map +1 -1
- package/dist/plugins/util/focustrap.js +23 -3
- package/dist/plugins/util/focustrap.js.map +1 -1
- package/dist/version.js +1 -1
- package/dist/version.js.map +1 -1
- package/package.json +1 -1
- package/src/js/plugins/navbar-collapsible.js +120 -141
- package/src/js/plugins/navscroll.js +27 -3
- package/src/js/plugins/util/focustrap.js +23 -3
- package/src/js/version.js +1 -1
- package/src/scss/base/_variables.scss +2 -2
- package/src/scss/base/_version.scss +1 -1
- package/src/scss/components/_carousel.scss +1 -1
- package/src/scss/components/_navigation.scss +21 -6
- package/dist/plugins/util/pageScroll.js +0 -45
- package/dist/plugins/util/pageScroll.js.map +0 -1
|
@@ -31,11 +31,13 @@ const TAB_NAV_BACKWARD = 'backward';
|
|
|
31
31
|
const Default = {
|
|
32
32
|
autofocus: true,
|
|
33
33
|
trapElement: null, // The element to trap focus inside of
|
|
34
|
+
initialFocus: null, // The inside element (optional) to set the focus after trapped
|
|
34
35
|
};
|
|
35
36
|
|
|
36
37
|
const DefaultType = {
|
|
37
38
|
autofocus: 'boolean',
|
|
38
39
|
trapElement: 'element',
|
|
40
|
+
initialFocus: '(null|element|string|function)',
|
|
39
41
|
};
|
|
40
42
|
|
|
41
43
|
/**
|
|
@@ -48,6 +50,7 @@ class FocusTrap extends Config {
|
|
|
48
50
|
this._config = this._getConfig(config);
|
|
49
51
|
this._isActive = false;
|
|
50
52
|
this._lastTabNavDirection = null;
|
|
53
|
+
this._affectedElements = [];
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
// Getters
|
|
@@ -70,7 +73,7 @@ class FocusTrap extends Config {
|
|
|
70
73
|
}
|
|
71
74
|
|
|
72
75
|
if (this._config.autofocus) {
|
|
73
|
-
this.
|
|
76
|
+
this._setInitialFocus();
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
EventHandler.off(document, EVENT_KEY); // guard against infinite focus loop
|
|
@@ -84,12 +87,30 @@ class FocusTrap extends Config {
|
|
|
84
87
|
if (!this._isActive) {
|
|
85
88
|
return
|
|
86
89
|
}
|
|
87
|
-
|
|
88
90
|
this._isActive = false;
|
|
91
|
+
|
|
89
92
|
EventHandler.off(document, EVENT_KEY);
|
|
90
93
|
}
|
|
91
94
|
|
|
92
95
|
// Private
|
|
96
|
+
_setInitialFocus() {
|
|
97
|
+
if (this._config.initialFocus) {
|
|
98
|
+
let target;
|
|
99
|
+
if (typeof this._config.initialFocus === 'function') {
|
|
100
|
+
target = this._config.initialFocus();
|
|
101
|
+
} else {
|
|
102
|
+
target = this._config.initialFocus;
|
|
103
|
+
}
|
|
104
|
+
if (target && typeof target.focus === 'function') {
|
|
105
|
+
target.focus();
|
|
106
|
+
} else {
|
|
107
|
+
this._config.trapElement.focus();
|
|
108
|
+
}
|
|
109
|
+
} else {
|
|
110
|
+
this._config.trapElement.focus();
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
93
114
|
_handleFocusin(event) {
|
|
94
115
|
const { trapElement } = this._config;
|
|
95
116
|
|
|
@@ -98,7 +119,6 @@ class FocusTrap extends Config {
|
|
|
98
119
|
}
|
|
99
120
|
|
|
100
121
|
const elements = SelectorEngine.focusableChildren(trapElement);
|
|
101
|
-
|
|
102
122
|
if (elements.length === 0) {
|
|
103
123
|
trapElement.focus();
|
|
104
124
|
} else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"focustrap.js","sources":["../../../src/js/plugins/util/focustrap.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap Italia (https://italia.github.io/bootstrap-italia/)\n * Authors: https://github.com/italia/bootstrap-italia/blob/main/AUTHORS\n * Licensed under BSD-3-Clause license (https://github.com/italia/bootstrap-italia/blob/main/LICENSE)\n * This a fork of Bootstrap: Initial license and original file name below\n * Bootstrap (v5.2.3): util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler'\nimport SelectorEngine from '../dom/selector-engine'\nimport Config from './config'\n\n/**\n * Constants\n */\n\nconst NAME = 'focustrap'\nconst DATA_KEY = 'bs.focustrap'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`\n\nconst TAB_KEY = 'Tab'\nconst TAB_NAV_FORWARD = 'forward'\nconst TAB_NAV_BACKWARD = 'backward'\n\nconst Default = {\n autofocus: true,\n trapElement: null, // The element to trap focus inside of\n}\n\nconst DefaultType = {\n autofocus: 'boolean',\n trapElement: 'element',\n}\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n this._isActive = false\n this._lastTabNavDirection = null\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n activate() {\n if (this._isActive) {\n return\n }\n\n if (this._config.autofocus) {\n this.
|
|
1
|
+
{"version":3,"file":"focustrap.js","sources":["../../../src/js/plugins/util/focustrap.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap Italia (https://italia.github.io/bootstrap-italia/)\n * Authors: https://github.com/italia/bootstrap-italia/blob/main/AUTHORS\n * Licensed under BSD-3-Clause license (https://github.com/italia/bootstrap-italia/blob/main/LICENSE)\n * This a fork of Bootstrap: Initial license and original file name below\n * Bootstrap (v5.2.3): util/focustrap.js\n * Licensed under MIT (https://github.com/twbs/bootstrap/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\nimport EventHandler from '../dom/event-handler'\nimport SelectorEngine from '../dom/selector-engine'\nimport Config from './config'\n\n/**\n * Constants\n */\n\nconst NAME = 'focustrap'\nconst DATA_KEY = 'bs.focustrap'\nconst EVENT_KEY = `.${DATA_KEY}`\nconst EVENT_FOCUSIN = `focusin${EVENT_KEY}`\nconst EVENT_KEYDOWN_TAB = `keydown.tab${EVENT_KEY}`\n\nconst TAB_KEY = 'Tab'\nconst TAB_NAV_FORWARD = 'forward'\nconst TAB_NAV_BACKWARD = 'backward'\n\nconst Default = {\n autofocus: true,\n trapElement: null, // The element to trap focus inside of\n initialFocus: null, // The inside element (optional) to set the focus after trapped\n}\n\nconst DefaultType = {\n autofocus: 'boolean',\n trapElement: 'element',\n initialFocus: '(null|element|string|function)',\n}\n\n/**\n * Class definition\n */\n\nclass FocusTrap extends Config {\n constructor(config) {\n super()\n this._config = this._getConfig(config)\n this._isActive = false\n this._lastTabNavDirection = null\n this._affectedElements = []\n }\n\n // Getters\n static get Default() {\n return Default\n }\n\n static get DefaultType() {\n return DefaultType\n }\n\n static get NAME() {\n return NAME\n }\n\n // Public\n activate() {\n if (this._isActive) {\n return\n }\n\n if (this._config.autofocus) {\n this._setInitialFocus()\n }\n\n EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop\n EventHandler.on(document, EVENT_FOCUSIN, (event) => this._handleFocusin(event))\n EventHandler.on(document, EVENT_KEYDOWN_TAB, (event) => this._handleKeydown(event))\n\n this._isActive = true\n }\n\n deactivate() {\n if (!this._isActive) {\n return\n }\n this._isActive = false\n\n EventHandler.off(document, EVENT_KEY)\n }\n\n // Private\n _setInitialFocus() {\n if (this._config.initialFocus) {\n let target\n if (typeof this._config.initialFocus === 'function') {\n target = this._config.initialFocus()\n } else {\n target = this._config.initialFocus\n }\n if (target && typeof target.focus === 'function') {\n target.focus()\n } else {\n this._config.trapElement.focus()\n }\n } else {\n this._config.trapElement.focus()\n }\n }\n\n _handleFocusin(event) {\n const { trapElement } = this._config\n\n if (event.target === document || event.target === trapElement || trapElement.contains(event.target)) {\n return\n }\n\n const elements = SelectorEngine.focusableChildren(trapElement)\n if (elements.length === 0) {\n trapElement.focus()\n } else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {\n elements[elements.length - 1].focus()\n } else {\n elements[0].focus()\n }\n }\n\n _handleKeydown(event) {\n if (event.key !== TAB_KEY) {\n return\n }\n\n this._lastTabNavDirection = event.shiftKey ? TAB_NAV_BACKWARD : TAB_NAV_FORWARD\n }\n}\n\nexport default FocusTrap\n"],"names":[],"mappings":"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"}
|
package/dist/version.js
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
|
|
9
9
|
// NOTE:bootstrap italia version variable, useful to check for the current version
|
|
10
10
|
|
|
11
|
-
const BOOTSTRAP_ITALIA_VERSION = '2.
|
|
11
|
+
const BOOTSTRAP_ITALIA_VERSION = '2.15.1';
|
|
12
12
|
|
|
13
13
|
export { BOOTSTRAP_ITALIA_VERSION as default };
|
|
14
14
|
//# sourceMappingURL=version.js.map
|
package/dist/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sources":["../src/js/version.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap Italia (https://italia.github.io/bootstrap-italia/)\n * Authors: https://github.com/italia/bootstrap-italia/blob/main/AUTHORS\n * Licensed under BSD-3-Clause license (https://github.com/italia/bootstrap-italia/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n// NOTE:bootstrap italia version variable, useful to check for the current version\n\nconst BOOTSTRAP_ITALIA_VERSION = '2.
|
|
1
|
+
{"version":3,"file":"version.js","sources":["../src/js/version.js"],"sourcesContent":["/**\n * --------------------------------------------------------------------------\n * Bootstrap Italia (https://italia.github.io/bootstrap-italia/)\n * Authors: https://github.com/italia/bootstrap-italia/blob/main/AUTHORS\n * Licensed under BSD-3-Clause license (https://github.com/italia/bootstrap-italia/blob/main/LICENSE)\n * --------------------------------------------------------------------------\n */\n\n// NOTE:bootstrap italia version variable, useful to check for the current version\n\nconst BOOTSTRAP_ITALIA_VERSION = '2.15.1'\nexport default BOOTSTRAP_ITALIA_VERSION\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEK,MAAC,wBAAwB,GAAG;;;;"}
|
package/package.json
CHANGED
|
@@ -7,14 +7,13 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import BaseComponent from './base-component.js'
|
|
10
|
-
|
|
11
10
|
import { getElementFromSelector, isVisible, reflow } from './util/index'
|
|
12
11
|
import EventHandler from './dom/event-handler'
|
|
13
12
|
import SelectorEngine from './dom/selector-engine'
|
|
14
|
-
|
|
15
13
|
import { isScreenMobile } from './util/device'
|
|
16
|
-
import
|
|
17
|
-
import
|
|
14
|
+
import ScrollBarHelper from './util/scrollbar'
|
|
15
|
+
import FocusTrap from './util/focustrap'
|
|
16
|
+
import Backdrop from './util/backdrop'
|
|
18
17
|
|
|
19
18
|
const NAME = 'navbarcollapsible'
|
|
20
19
|
const DATA_KEY = 'bs.navbarcollapsible'
|
|
@@ -23,7 +22,6 @@ const DATA_API_KEY = '.data-api'
|
|
|
23
22
|
|
|
24
23
|
const EVENT_CLICK_DATA_API = `click${EVENT_KEY}${DATA_API_KEY}`
|
|
25
24
|
const EVENT_CLICK = `click${EVENT_KEY}`
|
|
26
|
-
const EVENT_KEYUP = `keyup${EVENT_KEY}`
|
|
27
25
|
const EVENT_KEYDOWN = `keydown${EVENT_KEY}`
|
|
28
26
|
const EVENT_HIDE = `hide${EVENT_KEY}`
|
|
29
27
|
const EVENT_HIDDEN = `hidden${EVENT_KEY}`
|
|
@@ -31,54 +29,88 @@ const EVENT_SHOW = `show${EVENT_KEY}`
|
|
|
31
29
|
const EVENT_SHOWN = `shown${EVENT_KEY}`
|
|
32
30
|
const EVENT_RESIZE = `resize${EVENT_KEY}`
|
|
33
31
|
|
|
34
|
-
const
|
|
32
|
+
const CLASS_NAME_OPEN = 'navbar-open'
|
|
35
33
|
const CLASS_NAME_SHOW = 'show'
|
|
36
34
|
const CLASS_NAME_EXPANDED = 'expanded'
|
|
37
35
|
|
|
38
36
|
const SELECTOR_DATA_TOGGLE = '[data-bs-toggle="navbarcollapsible"]'
|
|
39
|
-
|
|
40
|
-
//const SELECTOR_NAVBAR = '.navbar-collapsable'
|
|
41
37
|
const SELECTOR_BTN_CLOSE = '.close-div button'
|
|
42
38
|
const SELECTOR_BTN_MENU_CLOSE = '.close-menu'
|
|
43
39
|
const SELECTOR_BTN_BACK = '.it-back-button'
|
|
44
|
-
const SELECTOR_OVERLAY = '.overlay'
|
|
45
40
|
const SELECTOR_MENU_WRAPPER = '.menu-wrapper'
|
|
46
41
|
const SELECTOR_NAVLINK = '.nav-link'
|
|
47
42
|
const SELECTOR_MEGAMENUNAVLINK = '.nav-item .list-item'
|
|
48
43
|
const SELECTOR_HEADINGLINK = '.it-heading-link'
|
|
49
44
|
const SELECTOR_FOOTERLINK = '.it-footer-link'
|
|
50
45
|
|
|
46
|
+
const Default = {
|
|
47
|
+
backdrop: true,
|
|
48
|
+
focus: true,
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
const DefaultType = {
|
|
52
|
+
backdrop: '(boolean|string)',
|
|
53
|
+
focus: 'boolean',
|
|
54
|
+
}
|
|
55
|
+
|
|
51
56
|
class NavBarCollapsible extends BaseComponent {
|
|
52
|
-
constructor(element) {
|
|
53
|
-
super(element)
|
|
57
|
+
constructor(element, config) {
|
|
58
|
+
super(element, config)
|
|
59
|
+
|
|
60
|
+
this._mainElement = SelectorEngine.findOne('main')
|
|
61
|
+
this._isNavbarOutsideMain = this._mainElement && !this._mainElement.contains(this._element)
|
|
62
|
+
this._parentElement = this._element.parentNode
|
|
54
63
|
|
|
55
64
|
this._isShown = this._element.classList.contains(CLASS_NAME_EXPANDED)
|
|
56
|
-
this._isTransitioning = false
|
|
57
65
|
|
|
58
|
-
this.
|
|
59
|
-
|
|
66
|
+
if (!this._element.getAttribute('tabindex')) {
|
|
67
|
+
this._element.setAttribute('tabindex', '-1')
|
|
68
|
+
}
|
|
60
69
|
|
|
61
|
-
this.
|
|
70
|
+
this._backdrop = this._initializeBackDrop()
|
|
71
|
+
this._focustrap = this._initializeFocusTrap()
|
|
72
|
+
this._scrollBar = new ScrollBarHelper()
|
|
73
|
+
this._isTransitioning = false
|
|
74
|
+
this._isMobile = isScreenMobile()
|
|
62
75
|
|
|
63
76
|
this._btnClose = SelectorEngine.findOne(SELECTOR_BTN_CLOSE, this._element)
|
|
64
77
|
this._btnBack = SelectorEngine.findOne(SELECTOR_BTN_BACK, this._element)
|
|
65
78
|
this._menuWrapper = SelectorEngine.findOne(SELECTOR_MENU_WRAPPER, this._element)
|
|
66
|
-
|
|
67
|
-
this._setOverlay()
|
|
79
|
+
|
|
68
80
|
this._menuItems = SelectorEngine.find(
|
|
69
81
|
[SELECTOR_NAVLINK, SELECTOR_MEGAMENUNAVLINK, SELECTOR_HEADINGLINK, SELECTOR_FOOTERLINK, SELECTOR_BTN_MENU_CLOSE].join(','),
|
|
70
82
|
this._element
|
|
71
83
|
)
|
|
72
84
|
|
|
85
|
+
this._toggleButton =
|
|
86
|
+
SelectorEngine.findOne(`${SELECTOR_DATA_TOGGLE}[data-bs-target="#${this._element.id}"]`) ||
|
|
87
|
+
SelectorEngine.findOne(`${SELECTOR_DATA_TOGGLE}[href="#${this._element.id}"]`)
|
|
88
|
+
|
|
89
|
+
if (this._toggleButton) {
|
|
90
|
+
if (!this._toggleButton.getAttribute('aria-expanded')) {
|
|
91
|
+
this._toggleButton.setAttribute('aria-expanded', this._isShown ? 'true' : 'false')
|
|
92
|
+
}
|
|
93
|
+
}
|
|
73
94
|
this._bindEvents()
|
|
74
95
|
}
|
|
96
|
+
|
|
75
97
|
// Getters
|
|
98
|
+
static get Default() {
|
|
99
|
+
return Default
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static get DefaultType() {
|
|
103
|
+
return DefaultType
|
|
104
|
+
}
|
|
76
105
|
|
|
77
106
|
static get NAME() {
|
|
78
107
|
return NAME
|
|
79
108
|
}
|
|
80
109
|
|
|
81
110
|
// Public
|
|
111
|
+
toggle(relatedTarget) {
|
|
112
|
+
this._isShown ? this.hide() : this.show(relatedTarget)
|
|
113
|
+
}
|
|
82
114
|
|
|
83
115
|
show(relatedTarget) {
|
|
84
116
|
if (this._isShown || this._isTransitioning) {
|
|
@@ -93,14 +125,22 @@ class NavBarCollapsible extends BaseComponent {
|
|
|
93
125
|
return
|
|
94
126
|
}
|
|
95
127
|
|
|
128
|
+
this._isShown = true
|
|
129
|
+
this._isTransitioning = true
|
|
130
|
+
this._scrollBar.hide()
|
|
131
|
+
|
|
96
132
|
if (this._btnBack) {
|
|
97
133
|
this._btnBack.classList.add(CLASS_NAME_SHOW)
|
|
98
134
|
}
|
|
99
135
|
|
|
100
|
-
|
|
136
|
+
document.body.classList.add(CLASS_NAME_OPEN)
|
|
101
137
|
|
|
102
|
-
|
|
138
|
+
this._backdrop.show()
|
|
103
139
|
this._showElement()
|
|
140
|
+
|
|
141
|
+
if (this._toggleButton) {
|
|
142
|
+
this._toggleButton.setAttribute('aria-expanded', 'true')
|
|
143
|
+
}
|
|
104
144
|
}
|
|
105
145
|
|
|
106
146
|
hide() {
|
|
@@ -116,45 +156,64 @@ class NavBarCollapsible extends BaseComponent {
|
|
|
116
156
|
|
|
117
157
|
this._isShown = false
|
|
118
158
|
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
if (isAnimated) {
|
|
122
|
-
this._isTransitioning = true
|
|
123
|
-
}
|
|
159
|
+
this._isTransitioning = true
|
|
160
|
+
this._focustrap.deactivate()
|
|
124
161
|
|
|
125
162
|
if (this._btnBack) {
|
|
126
163
|
this._btnBack.classList.remove(CLASS_NAME_SHOW)
|
|
127
164
|
}
|
|
128
|
-
if (this._overlay) {
|
|
129
|
-
this._overlay.classList.remove(CLASS_NAME_SHOW)
|
|
130
|
-
}
|
|
131
165
|
|
|
132
166
|
this._element.classList.remove(CLASS_NAME_EXPANDED)
|
|
133
167
|
|
|
134
|
-
|
|
135
|
-
this._queueCallback(() => this._hideElement(), this._menuWrapper, isAnimated)
|
|
136
|
-
}
|
|
168
|
+
this._backdrop.hide()
|
|
137
169
|
|
|
138
|
-
|
|
139
|
-
|
|
170
|
+
this._queueCallback(() => this._hideElement(), this._menuWrapper, this._isAnimated())
|
|
171
|
+
|
|
172
|
+
if (this._toggleButton) {
|
|
173
|
+
this._toggleButton.setAttribute('aria-expanded', 'false')
|
|
174
|
+
}
|
|
140
175
|
}
|
|
141
176
|
|
|
142
177
|
dispose() {
|
|
143
178
|
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
144
179
|
EventHandler.off(window, EVENT_RESIZE)
|
|
145
|
-
|
|
180
|
+
EventHandler.off(document, EVENT_KEYDOWN)
|
|
146
181
|
}
|
|
182
|
+
this._backdrop.dispose()
|
|
183
|
+
|
|
184
|
+
this._focustrap.deactivate()
|
|
185
|
+
super.dispose()
|
|
147
186
|
}
|
|
148
187
|
|
|
149
|
-
|
|
188
|
+
_initializeBackDrop() {
|
|
189
|
+
return new Backdrop({
|
|
190
|
+
isVisible: Boolean(this._config.backdrop), // 'static' option will be translated to true, and booleans will keep their value,
|
|
191
|
+
isAnimated: this._isAnimated(),
|
|
192
|
+
className: 'navbar-backdrop',
|
|
193
|
+
rootElement: this._parentElement,
|
|
194
|
+
clickCallback: () => {
|
|
195
|
+
this.hide()
|
|
196
|
+
},
|
|
197
|
+
})
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
_initializeFocusTrap() {
|
|
201
|
+
return new FocusTrap({
|
|
202
|
+
trapElement: this._element,
|
|
203
|
+
initialFocus: () => this._btnClose || this._element.querySelector('button, [href], input, select, textarea, [tabindex]:not([tabindex="-1"])'),
|
|
204
|
+
})
|
|
205
|
+
}
|
|
150
206
|
|
|
207
|
+
// Private
|
|
151
208
|
_bindEvents() {
|
|
152
209
|
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
|
|
153
210
|
EventHandler.on(window, EVENT_RESIZE, () => this._onResize())
|
|
211
|
+
EventHandler.on(document, EVENT_KEYDOWN, (evt) => {
|
|
212
|
+
if (this._isShown && evt.key === 'Escape') {
|
|
213
|
+
this.hide()
|
|
214
|
+
}
|
|
215
|
+
})
|
|
154
216
|
|
|
155
|
-
if (this._overlay) {
|
|
156
|
-
EventHandler.on(this._overlay, EVENT_CLICK, () => this.hide())
|
|
157
|
-
}
|
|
158
217
|
EventHandler.on(this._btnClose, EVENT_CLICK, (evt) => {
|
|
159
218
|
evt.preventDefault()
|
|
160
219
|
this.hide()
|
|
@@ -163,11 +222,8 @@ class NavBarCollapsible extends BaseComponent {
|
|
|
163
222
|
evt.preventDefault()
|
|
164
223
|
this.hide()
|
|
165
224
|
})
|
|
166
|
-
|
|
167
225
|
this._menuItems.forEach((item) => {
|
|
168
226
|
EventHandler.on(item, EVENT_KEYDOWN, (evt) => this._isMobile && this._onMenuItemKeyDown(evt))
|
|
169
|
-
EventHandler.on(item, EVENT_KEYUP, (evt) => this._isMobile && this._onMenuItemKeyUp(evt))
|
|
170
|
-
EventHandler.on(item, EVENT_CLICK, (evt) => this._isMobile && this._onMenuItemClick(evt))
|
|
171
227
|
})
|
|
172
228
|
}
|
|
173
229
|
}
|
|
@@ -176,30 +232,14 @@ class NavBarCollapsible extends BaseComponent {
|
|
|
176
232
|
this._isMobile = isScreenMobile()
|
|
177
233
|
}
|
|
178
234
|
|
|
179
|
-
_onMenuItemKeyUp(evt) {
|
|
180
|
-
if (evt.key === 'Shift') {
|
|
181
|
-
this._isKeyShift = false
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
235
|
_onMenuItemKeyDown(evt) {
|
|
185
|
-
if (evt.key === '
|
|
186
|
-
this.
|
|
187
|
-
}
|
|
188
|
-
if (evt.key === 'Tab') {
|
|
189
|
-
evt.preventDefault()
|
|
190
|
-
this._focusNext()
|
|
236
|
+
if (evt.key === 'Escape') {
|
|
237
|
+
this.hide()
|
|
191
238
|
}
|
|
192
239
|
}
|
|
193
|
-
/**
|
|
194
|
-
* Update the last focused element when an interactive element is clicked
|
|
195
|
-
*/
|
|
196
|
-
_onMenuItemClick(evt) {
|
|
197
|
-
this.currItemIdx = getElementIndex(evt.currentTarget, this._menuItems)
|
|
198
|
-
}
|
|
199
240
|
|
|
200
241
|
_isAnimated() {
|
|
201
|
-
|
|
202
|
-
return true //this._element.classList.contains(CLASS_NAME_EXPANDED)
|
|
242
|
+
return true
|
|
203
243
|
}
|
|
204
244
|
|
|
205
245
|
_isElementHidden(element) {
|
|
@@ -207,108 +247,47 @@ class NavBarCollapsible extends BaseComponent {
|
|
|
207
247
|
}
|
|
208
248
|
|
|
209
249
|
_showElement() {
|
|
210
|
-
const isAnimated = this._isAnimated()
|
|
211
|
-
|
|
212
250
|
this._element.style.display = 'block'
|
|
213
|
-
this._element.
|
|
214
|
-
|
|
215
|
-
//this._element.setAttribute('role', 'dialog')
|
|
216
|
-
if (this._overlay) {
|
|
217
|
-
this._overlay.style.display = 'block'
|
|
251
|
+
if (!this._element.getAttribute('aria-label') && !this._element.getAttribute('aria-labelledby')) {
|
|
252
|
+
this._element.setAttribute('aria-label', 'Menu')
|
|
218
253
|
}
|
|
254
|
+
this._element.setAttribute('aria-modal', true)
|
|
255
|
+
this._element.setAttribute('role', 'dialog')
|
|
219
256
|
|
|
220
|
-
if (
|
|
221
|
-
|
|
257
|
+
if (this._mainElement && this._isNavbarOutsideMain) {
|
|
258
|
+
this._mainElement.setAttribute('inert', '')
|
|
222
259
|
}
|
|
223
260
|
|
|
261
|
+
reflow(this._element)
|
|
262
|
+
|
|
224
263
|
this._element.classList.add(CLASS_NAME_EXPANDED)
|
|
225
|
-
if (this._overlay) {
|
|
226
|
-
this._overlay.classList.add(CLASS_NAME_SHOW)
|
|
227
|
-
}
|
|
228
264
|
|
|
229
265
|
const transitionComplete = () => {
|
|
230
|
-
this.
|
|
231
|
-
|
|
232
|
-
if (firstItem.item) {
|
|
233
|
-
firstItem.item.focus()
|
|
234
|
-
this._currItemIdx = firstItem.index
|
|
266
|
+
if (this._config.focus) {
|
|
267
|
+
this._focustrap.activate()
|
|
235
268
|
}
|
|
269
|
+
this._isTransitioning = false
|
|
236
270
|
EventHandler.trigger(this._element, EVENT_SHOWN)
|
|
237
271
|
}
|
|
238
272
|
|
|
239
|
-
this._queueCallback(transitionComplete, this._menuWrapper,
|
|
273
|
+
this._queueCallback(transitionComplete, this._menuWrapper, this._isAnimated())
|
|
240
274
|
}
|
|
241
275
|
|
|
242
276
|
_hideElement() {
|
|
243
|
-
if (this._overlay) {
|
|
244
|
-
this._overlay.style.display = 'none'
|
|
245
|
-
}
|
|
246
|
-
|
|
247
277
|
this._element.style.display = 'none'
|
|
248
|
-
this._element.
|
|
249
|
-
this._element.removeAttribute('
|
|
250
|
-
//this._element.removeAttribute('aria-modal')
|
|
251
|
-
//this._element.removeAttribute('role')
|
|
252
|
-
this._isTransitioning = false
|
|
253
|
-
EventHandler.trigger(this._element, EVENT_HIDDEN)
|
|
254
|
-
}
|
|
278
|
+
this._element.removeAttribute('aria-modal')
|
|
279
|
+
this._element.removeAttribute('role')
|
|
255
280
|
|
|
256
|
-
|
|
257
|
-
this._overlay = SelectorEngine.findOne(SELECTOR_OVERLAY, this._element)
|
|
258
|
-
if (this._isAnimated) {
|
|
259
|
-
this._overlay.classList.add(CLASS_NAME_FADE)
|
|
260
|
-
}
|
|
261
|
-
}
|
|
281
|
+
document.body.classList.remove(CLASS_NAME_OPEN)
|
|
262
282
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
*/
|
|
266
|
-
_focusNext() {
|
|
267
|
-
let nextIdx = this._currItemIdx + (this._isKeyShift ? -1 : 1)
|
|
268
|
-
if (nextIdx < 0) {
|
|
269
|
-
nextIdx = this._menuItems.length - 1
|
|
270
|
-
} else if (nextIdx >= this._menuItems.length) {
|
|
271
|
-
nextIdx = 0
|
|
272
|
-
}
|
|
273
|
-
const target = this._getNextVisibleItem(nextIdx, this._isKeyShift)
|
|
274
|
-
if (target.item) {
|
|
275
|
-
target.item.focus()
|
|
276
|
-
this._currItemIdx = target.index
|
|
277
|
-
}
|
|
278
|
-
}
|
|
279
|
-
/**
|
|
280
|
-
* Get the next focusable element from a starting point
|
|
281
|
-
* @param {int} start - the index of the array of the elements as starting point (included)
|
|
282
|
-
* @param {boolean} wayTop - the array search direction (true: bottom to top, false: top to bottom)
|
|
283
|
-
* @returns {Object} the item found and its index in the array
|
|
284
|
-
*/
|
|
285
|
-
_getNextVisibleItem(start, wayTop) {
|
|
286
|
-
let found = null
|
|
287
|
-
let foundIdx = null
|
|
288
|
-
|
|
289
|
-
let i = start
|
|
290
|
-
let incr = wayTop ? -1 : 1
|
|
291
|
-
let firstCheck = false
|
|
292
|
-
while (!found && (i != start || !firstCheck)) {
|
|
293
|
-
if (i == start) {
|
|
294
|
-
firstCheck = true
|
|
295
|
-
}
|
|
296
|
-
if (!this._isElementHidden(this._menuItems[i])) {
|
|
297
|
-
found = this._menuItems[i]
|
|
298
|
-
foundIdx = i
|
|
299
|
-
}
|
|
300
|
-
i = i + incr
|
|
301
|
-
if (i < 0) {
|
|
302
|
-
i = this._menuItems.length - 1
|
|
303
|
-
} else if (i >= this._menuItems.length) {
|
|
304
|
-
i = 0
|
|
305
|
-
}
|
|
283
|
+
if (this._mainElement && this._isNavbarOutsideMain) {
|
|
284
|
+
this._mainElement.removeAttribute('inert')
|
|
306
285
|
}
|
|
307
286
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
287
|
+
this._scrollBar.reset()
|
|
288
|
+
this._isTransitioning = false
|
|
289
|
+
|
|
290
|
+
EventHandler.trigger(this._element, EVENT_HIDDEN)
|
|
312
291
|
}
|
|
313
292
|
}
|
|
314
293
|
|
|
@@ -25,6 +25,7 @@ const SELECTOR_TOGGLER = '.custom-navbar-toggler'
|
|
|
25
25
|
const SELECTOR_TOGGLER_ICON = '.it-list'
|
|
26
26
|
const SELECTOR_COLLAPSIBLE = '.navbar-collapsable'
|
|
27
27
|
const SELECTOR_PROGRESS_BAR = '.it-navscroll-progressbar'
|
|
28
|
+
const SELECTOR_MENU_WRAPPER = '.menu-wrapper'
|
|
28
29
|
|
|
29
30
|
const Default = {
|
|
30
31
|
scrollPadding: 10,
|
|
@@ -44,6 +45,11 @@ class NavScroll extends BaseComponent {
|
|
|
44
45
|
this._callbackQueue = []
|
|
45
46
|
this._scrollCb = null
|
|
46
47
|
|
|
48
|
+
const menuWrapper = SelectorEngine.findOne(SELECTOR_MENU_WRAPPER, this._element)
|
|
49
|
+
if (menuWrapper && !menuWrapper.hasAttribute('tabindex')) {
|
|
50
|
+
menuWrapper.setAttribute('tabindex', '-1')
|
|
51
|
+
}
|
|
52
|
+
|
|
47
53
|
this._bindEvents()
|
|
48
54
|
}
|
|
49
55
|
// Getters
|
|
@@ -147,13 +153,31 @@ class NavScroll extends BaseComponent {
|
|
|
147
153
|
}
|
|
148
154
|
|
|
149
155
|
_scrollToHash(hash) {
|
|
150
|
-
|
|
156
|
+
if (!hash || hash === '#') {
|
|
157
|
+
// Validate hash to prevent errors
|
|
158
|
+
return
|
|
159
|
+
}
|
|
160
|
+
const target = this._sectionContainer // Fallback: when container is null, omit the second parameter entirely
|
|
161
|
+
? SelectorEngine.findOne(hash, this._sectionContainer)
|
|
162
|
+
: SelectorEngine.findOne(hash)
|
|
151
163
|
if (target) {
|
|
152
164
|
documentScrollTo(target.offsetTop - this._getScrollPadding(), {
|
|
153
165
|
duration: this._config.duration,
|
|
154
166
|
easing: this._config.easing,
|
|
155
|
-
|
|
156
|
-
|
|
167
|
+
complete: () => {
|
|
168
|
+
const isHeading = target.matches('h1, h2, h3, h4, h5, h6')
|
|
169
|
+
const needsTabIndex = !target.hasAttribute('tabindex')
|
|
170
|
+
if (needsTabIndex) {
|
|
171
|
+
target.setAttribute('tabindex', '-1')
|
|
172
|
+
}
|
|
173
|
+
target.focus({ preventScroll: true }) // preventScroll to avoid double scrolling
|
|
174
|
+
if (needsTabIndex && isHeading) {
|
|
175
|
+
// remove tabIndex for headings after 500ms
|
|
176
|
+
setTimeout(() => {
|
|
177
|
+
target.removeAttribute('tabindex')
|
|
178
|
+
}, 500)
|
|
179
|
+
}
|
|
180
|
+
},
|
|
157
181
|
})
|
|
158
182
|
|
|
159
183
|
if (history.pushState) {
|
|
@@ -30,11 +30,13 @@ const TAB_NAV_BACKWARD = 'backward'
|
|
|
30
30
|
const Default = {
|
|
31
31
|
autofocus: true,
|
|
32
32
|
trapElement: null, // The element to trap focus inside of
|
|
33
|
+
initialFocus: null, // The inside element (optional) to set the focus after trapped
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
const DefaultType = {
|
|
36
37
|
autofocus: 'boolean',
|
|
37
38
|
trapElement: 'element',
|
|
39
|
+
initialFocus: '(null|element|string|function)',
|
|
38
40
|
}
|
|
39
41
|
|
|
40
42
|
/**
|
|
@@ -47,6 +49,7 @@ class FocusTrap extends Config {
|
|
|
47
49
|
this._config = this._getConfig(config)
|
|
48
50
|
this._isActive = false
|
|
49
51
|
this._lastTabNavDirection = null
|
|
52
|
+
this._affectedElements = []
|
|
50
53
|
}
|
|
51
54
|
|
|
52
55
|
// Getters
|
|
@@ -69,7 +72,7 @@ class FocusTrap extends Config {
|
|
|
69
72
|
}
|
|
70
73
|
|
|
71
74
|
if (this._config.autofocus) {
|
|
72
|
-
this.
|
|
75
|
+
this._setInitialFocus()
|
|
73
76
|
}
|
|
74
77
|
|
|
75
78
|
EventHandler.off(document, EVENT_KEY) // guard against infinite focus loop
|
|
@@ -83,12 +86,30 @@ class FocusTrap extends Config {
|
|
|
83
86
|
if (!this._isActive) {
|
|
84
87
|
return
|
|
85
88
|
}
|
|
86
|
-
|
|
87
89
|
this._isActive = false
|
|
90
|
+
|
|
88
91
|
EventHandler.off(document, EVENT_KEY)
|
|
89
92
|
}
|
|
90
93
|
|
|
91
94
|
// Private
|
|
95
|
+
_setInitialFocus() {
|
|
96
|
+
if (this._config.initialFocus) {
|
|
97
|
+
let target
|
|
98
|
+
if (typeof this._config.initialFocus === 'function') {
|
|
99
|
+
target = this._config.initialFocus()
|
|
100
|
+
} else {
|
|
101
|
+
target = this._config.initialFocus
|
|
102
|
+
}
|
|
103
|
+
if (target && typeof target.focus === 'function') {
|
|
104
|
+
target.focus()
|
|
105
|
+
} else {
|
|
106
|
+
this._config.trapElement.focus()
|
|
107
|
+
}
|
|
108
|
+
} else {
|
|
109
|
+
this._config.trapElement.focus()
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
92
113
|
_handleFocusin(event) {
|
|
93
114
|
const { trapElement } = this._config
|
|
94
115
|
|
|
@@ -97,7 +118,6 @@ class FocusTrap extends Config {
|
|
|
97
118
|
}
|
|
98
119
|
|
|
99
120
|
const elements = SelectorEngine.focusableChildren(trapElement)
|
|
100
|
-
|
|
101
121
|
if (elements.length === 0) {
|
|
102
122
|
trapElement.focus()
|
|
103
123
|
} else if (this._lastTabNavDirection === TAB_NAV_BACKWARD) {
|
package/src/js/version.js
CHANGED
|
@@ -1952,8 +1952,8 @@ $crs-dots-margin-left: 38px;
|
|
|
1952
1952
|
$crs-dots-margin-left-desk: $v-gap * 2;
|
|
1953
1953
|
$crs-heading-h-padding: $v-gap * 3;
|
|
1954
1954
|
$crs-heading-h-size: 1.75rem;
|
|
1955
|
-
$crs-landcape-card-padding: $v-gap * 6;
|
|
1956
|
-
$crs-
|
|
1955
|
+
$crs-landcape-card-padding: $v-gap * 6; // Variabile non usata
|
|
1956
|
+
$crs-landscape-bottom: 5px;
|
|
1957
1957
|
|
|
1958
1958
|
// Gridlist **************
|
|
1959
1959
|
$grid-item-df-proportion: 66.81222707423581%;
|