@madj2k/fe-frontend-kit 2.0.37 → 2.0.38
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/menus/flyout-menu/flyout-menu-2.0.js +82 -50
- package/package.json +1 -1
- package/readme.md +11 -12
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*
|
|
8
8
|
* @author Steffen Kroggel <developer@steffenkroggel.de>
|
|
9
9
|
* @copyright 2025 Steffen Kroggel
|
|
10
|
-
* @version 2.0.
|
|
10
|
+
* @version 2.0.3
|
|
11
11
|
* @license GNU General Public License v3.0
|
|
12
12
|
* @see https://www.gnu.org/licenses/gpl-3.0.en.html
|
|
13
13
|
*
|
|
@@ -50,10 +50,9 @@ class Madj2kFlyoutMenu {
|
|
|
50
50
|
menuContainerClass: "js-flyout-container",
|
|
51
51
|
menuInnerClass: "js-flyout-inner",
|
|
52
52
|
heightCalculationClass: 'calculate',
|
|
53
|
+
hoverParentClass: 'nav-main',
|
|
53
54
|
heightMode: 'full',
|
|
54
55
|
eventMode: 'click',
|
|
55
|
-
eventModeOpen: '',
|
|
56
|
-
eventModeClose: '',
|
|
57
56
|
paddingBehavior: 0,
|
|
58
57
|
paddingViewPortMinWidth: 0,
|
|
59
58
|
animationDuration: 500,
|
|
@@ -77,6 +76,8 @@ class Madj2kFlyoutMenu {
|
|
|
77
76
|
this.settings.$menuContainer = this.settings.$menu.querySelector(`.${this.settings.menuContainerClass}`);
|
|
78
77
|
this.settings.$menuInner = this.settings.$menu.querySelector(`.${this.settings.menuInnerClass}`);
|
|
79
78
|
|
|
79
|
+
// Bind persistent event handlers
|
|
80
|
+
|
|
80
81
|
this.initNoScrollHelper();
|
|
81
82
|
this.resizeAndPositionMenu();
|
|
82
83
|
this.paddingMenu();
|
|
@@ -115,40 +116,102 @@ class Madj2kFlyoutMenu {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
|
|
119
|
+
|
|
120
|
+
/**
|
|
121
|
+
* Handles mouseleave on menu container
|
|
122
|
+
* @param {MouseEvent} e
|
|
123
|
+
*/
|
|
124
|
+
containerLeaveEvent(e) {
|
|
125
|
+
const to = e.relatedTarget;
|
|
126
|
+
const parentContainer = this.$element.closest(this.settings.hoverParentSelector) || null;
|
|
127
|
+
if (to && this.$element.contains(to)) return;
|
|
128
|
+
if (to && parentContainer?.contains(to)) return;
|
|
129
|
+
if (this.$element.classList.contains(this.settings.openStatusClass)) {
|
|
130
|
+
document.dispatchEvent(new CustomEvent('madj2k-flyoutmenu-close'));
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Handles mouseleave on trigger element
|
|
136
|
+
* @param {MouseEvent} e
|
|
137
|
+
*/
|
|
138
|
+
triggerLeaveEvent(e) {
|
|
139
|
+
const to = e.relatedTarget;
|
|
140
|
+
const parentContainer = this.$element.closest('.' + this.settings.hoverParentClass) || null;
|
|
141
|
+
|
|
142
|
+
if (to && this.settings.$menu.contains(to)) return;
|
|
143
|
+
if (to && parentContainer?.contains(to)) return;
|
|
144
|
+
if (this.$element.classList.contains(this.settings.openStatusClass)) {
|
|
145
|
+
document.dispatchEvent(new CustomEvent('madj2k-flyoutmenu-close'));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* Handles touchstart outside the flyout menu
|
|
151
|
+
* @param {TouchEvent} e
|
|
152
|
+
*/
|
|
153
|
+
touchStartEvent(e) {
|
|
154
|
+
const target = e.target;
|
|
155
|
+
if (!target) return;
|
|
156
|
+
if (this.settings.$menuInner.contains(target)) return;
|
|
157
|
+
if (this.$element.classList.contains(this.settings.openStatusClass)) {
|
|
158
|
+
document.dispatchEvent(new CustomEvent('madj2k-flyoutmenu-close'));
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
118
162
|
/**
|
|
119
163
|
* Binds all necessary event listeners
|
|
120
164
|
*/
|
|
121
165
|
bindEvents() {
|
|
122
166
|
if (this.settings.$closeBtn) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
this.settings.$closeBtn.addEventListener(this.settings.eventModeClose, e => this.closeEvent(e));
|
|
126
|
-
} else {
|
|
127
|
-
this.settings.$closeBtn.addEventListener(this.settings.eventMode, e => this.closeEvent(e));
|
|
128
|
-
}
|
|
167
|
+
const closeEvent = this.settings.eventMode === 'mouseover' ? 'mouseenter' : 'click';
|
|
168
|
+
this.settings.$closeBtn.addEventListener(closeEvent, e => this.closeEvent(e));
|
|
129
169
|
this.settings.$closeBtn.addEventListener('keydown', e => this.keyboardEvent(e));
|
|
130
170
|
}
|
|
131
171
|
|
|
132
|
-
if (this.settings.
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
this.$element.addEventListener(this.settings.eventModeClose, e => this.closeEvent(e));
|
|
138
|
-
}
|
|
172
|
+
if (this.settings.eventMode === 'mouseover') {
|
|
173
|
+
this.$element.addEventListener('mouseenter', e => this.openEvent(e));
|
|
174
|
+
this.$element.addEventListener('mouseleave',e => this.triggerLeaveEvent(e));
|
|
175
|
+
this.settings.$menuContainer?.addEventListener('mouseleave', e => this.containerLeaveEvent(e));
|
|
176
|
+
document.addEventListener('touchstart', e => this.touchStartEvent(e), { passive: true });
|
|
139
177
|
} else {
|
|
140
|
-
this.$element.addEventListener(
|
|
178
|
+
this.$element.addEventListener('click', e => this.toggleEvent(e));
|
|
141
179
|
}
|
|
142
180
|
|
|
143
181
|
this.$element.addEventListener('keydown', e => this.keyboardEvent(e));
|
|
144
|
-
|
|
145
182
|
this.settings.$menu.querySelectorAll('a,button,input,textarea,select')
|
|
146
183
|
.forEach(el => el.addEventListener('keydown', e => this.keyboardEvent(e)));
|
|
147
|
-
|
|
148
184
|
document.addEventListener('madj2k-flyoutmenu-close', e => this.closeEvent(e));
|
|
149
185
|
document.addEventListener('madj2k-flyoutmenu-resize', e => this.resizeAndPositionMenuEvent(e));
|
|
150
186
|
}
|
|
151
187
|
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Removes all event listeners (including dynamic hover/touch)
|
|
191
|
+
*/
|
|
192
|
+
destroyEvents() {
|
|
193
|
+
if (this.settings.$closeBtn) {
|
|
194
|
+
const closeEvent = this.settings.eventMode === 'mouseover' ? 'mouseenter' : 'click';
|
|
195
|
+
this.settings.$closeBtn.removeEventListener(closeEvent, e => this.closeEvent(e));
|
|
196
|
+
this.settings.$closeBtn.removeEventListener('keydown', e => this.keyboardEvent(e));
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
if (this.settings.eventMode === 'mouseover') {
|
|
200
|
+
this.$element.removeEventListener('mouseenter', e => this.openEvent(e));
|
|
201
|
+
this.settings.$menuContainer?.removeEventListener('mouseleave', e => this.containerLeaveEvent(e));
|
|
202
|
+
document.removeEventListener('touchstart', e => this.touchStartEvent(e), { passive: true });
|
|
203
|
+
} else {
|
|
204
|
+
this.$element.removeEventListener('click', e => this.toggleEvent(e));
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
this.$element.removeEventListener('keydown', e => this.keyboardEvent(e));
|
|
208
|
+
this.settings.$menu.querySelectorAll('a,button,input,textarea,select')
|
|
209
|
+
.forEach(el => el.removeEventListener('keydown', e => this.keyboardEvent(e)));
|
|
210
|
+
document.removeEventListener('madj2k-flyoutmenu-close', e => this.closeEvent(e));
|
|
211
|
+
document.removeEventListener('madj2k-flyoutmenu-resize', e => this.resizeAndPositionMenuEvent(e));
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
|
|
152
215
|
/**
|
|
153
216
|
* Initializes ResizeObserver to auto-resize menu
|
|
154
217
|
*/
|
|
@@ -172,37 +235,6 @@ class Madj2kFlyoutMenu {
|
|
|
172
235
|
}
|
|
173
236
|
}
|
|
174
237
|
|
|
175
|
-
/**
|
|
176
|
-
* Unbinds all event listeners
|
|
177
|
-
*/
|
|
178
|
-
destroyEvents() {
|
|
179
|
-
if (this.settings.$closeBtn) {
|
|
180
|
-
if (this.settings.eventModeClose) {
|
|
181
|
-
this.settings.$closeBtn.removeEventListener(this.settings.eventModeClose, e => this.closeEvent(e));
|
|
182
|
-
} else {
|
|
183
|
-
this.settings.$closeBtn.removeEventListener(this.settings.eventMode, e => this.closeEvent(e));
|
|
184
|
-
}
|
|
185
|
-
this.settings.$closeBtn.removeEventListener('keydown', e => this.keyboardEvent(e));
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
if (this.settings.eventModeOpen || this.settings.eventModeClose) {
|
|
189
|
-
if (this.settings.eventModeOpen) {
|
|
190
|
-
this.$element.removeEventListener(this.settings.eventModeOpen, e => this.openEvent(e));
|
|
191
|
-
}
|
|
192
|
-
if (this.settings.eventModeClose) {
|
|
193
|
-
this.$element.removeEventListener(this.settings.eventModeClose, e => this.closeEvent(e));
|
|
194
|
-
}
|
|
195
|
-
} else {
|
|
196
|
-
this.$element.removeEventListener(this.settings.eventMode, e => this.toggleEvent(e));
|
|
197
|
-
}
|
|
198
|
-
this.$element.removeEventListener('keydown', e => this.keyboardEvent(e));
|
|
199
|
-
|
|
200
|
-
this.settings.$menu.querySelectorAll('a,button,input,textarea,select')
|
|
201
|
-
.forEach(el => el.removeEventListener('keydown', e => this.keyboardEvent(e)));
|
|
202
|
-
|
|
203
|
-
document.removeEventListener('madj2k-flyoutmenu-close', e => this.closeEvent(e));
|
|
204
|
-
document.removeEventListener('madj2k-flyoutmenu-resize', e => this.resizeAndPositionMenuEvent(e));
|
|
205
|
-
}
|
|
206
238
|
|
|
207
239
|
/**
|
|
208
240
|
* Destroys ResizeObserver
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -105,15 +105,16 @@ Otherwise in the opened menu the scrolling won't work.
|
|
|
105
105
|
|
|
106
106
|
### CSS Class Selectors
|
|
107
107
|
|
|
108
|
-
| Option
|
|
109
|
-
|
|
110
|
-
| contentSectionClass
|
|
111
|
-
| menuClass
|
|
112
|
-
| menuToggleClass
|
|
113
|
-
| menuCloseClass
|
|
114
|
-
| menuContainerClass
|
|
115
|
-
| menuInnerClass
|
|
116
|
-
| heightCalculationClass | string | 'calculate'
|
|
108
|
+
| Option | Type | Default | Description |
|
|
109
|
+
|------------------------|------|-----------------------|-----------------------------------------------------------------|
|
|
110
|
+
| contentSectionClass | string | 'js-main-content' | Content wrapper used when creating no-scroll helper. |
|
|
111
|
+
| menuClass | string | 'js-flyout' | Menu root element class. |
|
|
112
|
+
| menuToggleClass | string | 'js-flyout-toggle' | Class for toggle buttons. |
|
|
113
|
+
| menuCloseClass | string | 'js-flyout-close' | Class for close buttons inside the flyout. |
|
|
114
|
+
| menuContainerClass | string | 'js-flyout-container' | Container used for slide animations (`top` transition). |
|
|
115
|
+
| menuInnerClass | string | 'js-flyout-inner' | Inner content wrapper. Observed via ResizeObserver. |
|
|
116
|
+
| heightCalculationClass | string | 'calculate' | Temporary class used during height determination. |
|
|
117
|
+
| hoverParentClass | string | 'nav-main' | Class of main container of menu (used in eventMode: 'moueover'. |
|
|
117
118
|
|
|
118
119
|
### Height & Size Behavior
|
|
119
120
|
|
|
@@ -135,9 +136,7 @@ Otherwise in the opened menu the scrolling won't work.
|
|
|
135
136
|
|
|
136
137
|
| Option | Type | Default | Description |
|
|
137
138
|
|--------|------|-------------|
|
|
138
|
-
| `eventMode` | `string` | `'click'` | Default event used for toggling the menu.
|
|
139
|
-
| `eventModeOpen` | `string` | `''` | Defines a custom event for opening the menu. |
|
|
140
|
-
| `eventModeClose` | `string` | `''` | Defines a custom event for closing the menu. |
|
|
139
|
+
| `eventMode` | `string` | `'click'` | Default event used for toggling the menu. Can be set to `click` or `mouseover`. |
|
|
141
140
|
|
|
142
141
|
|
|
143
142
|
## Special: blur/gray effect for background
|