PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.7
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.7
2.0.13 2.0.12 2.0.11 2.0.10 2.0.9 trunk 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8
blockenberg / blocks / mega-menu / frontend.js

frontend.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.7, at blocks/mega-menu/frontend.js

311 lines 13.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 'use strict';
3
4 document.querySelectorAll('.bkbg-mm-app').forEach(function (app) {
5 var opts;
6 try { opts = JSON.parse(app.dataset.opts || '{}'); } catch (e) { return; }
7
8 var _typoKeys = { family:'font-family', weight:'font-weight', style:'font-style', decoration:'text-decoration', transform:'text-transform', sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m', lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m', letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m', wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m' };
9 function typoCssVarsForEl(el, typo, prefix) {
10 if (!typo || typeof typo !== 'object') return;
11 Object.keys(_typoKeys).forEach(function (k) {
12 if (typo[k] !== undefined && typo[k] !== '') el.style.setProperty(prefix + _typoKeys[k], typo[k]);
13 });
14 }
15
16 var items = opts.items || [];
17 var logoUrl = opts.logoUrl || '';
18 var logoAlt = opts.logoAlt || 'Logo';
19 var logoWidth = parseInt(opts.logoWidth) || 140;
20 var ctaLabel = opts.ctaLabel || 'Get Started';
21 var ctaUrl = opts.ctaUrl || '#';
22 var showCta = opts.showCta !== false;
23 var ctaStyle = opts.ctaStyle || 'filled';
24 var showIcons = opts.showIcons !== false;
25 var showDescs = opts.showDescriptions !== false;
26 var panelWidth = parseInt(opts.panelWidth) || 820;
27 var panelRadius = parseInt(opts.panelRadius) || 16;
28 var menuHeight = parseInt(opts.menuHeight) || 64;
29 var sticky = opts.sticky !== false;
30 var openOnHover = opts.openOnHover !== false;
31 var menuBg = opts.menuBg || '#ffffff';
32 var menuText = opts.menuText || '#0f172a';
33 var menuBorder = opts.menuBorder || '#e2e8f0';
34 var panelBg = opts.panelBg || '#ffffff';
35 var panelText = opts.panelText || '#0f172a';
36 var accentColor = opts.accentColor || '#6366f1';
37 var ctaBg = opts.ctaBg || '#6366f1';
38 var ctaColor = opts.ctaColor || '#ffffff';
39 var featuredBg = opts.featuredBg || '#ede9fe';
40
41 // CSS vars
42 app.style.setProperty('--mm-accent', accentColor);
43 app.style.setProperty('--mm-menu-bg', menuBg);
44 app.style.setProperty('--mm-text', menuText);
45 app.style.setProperty('--mm-border', menuBorder);
46 app.style.setProperty('--mm-panel-bg', panelBg);
47 app.style.setProperty('--mm-panel-text', panelText);
48 app.style.setProperty('--mm-cta-bg', ctaBg);
49 app.style.setProperty('--mm-cta-clr', ctaColor);
50 app.style.setProperty('--mm-feat-bg', featuredBg);
51 app.style.setProperty('--mm-height', menuHeight + 'px');
52
53 typoCssVarsForEl(app, opts.navTypo, '--bkbg-mm-nv-');
54 typoCssVarsForEl(app, opts.colHeadingTypo, '--bkbg-mm-ch-');
55 typoCssVarsForEl(app, opts.linkTypo, '--bkbg-mm-lk-');
56
57 function el(tag, className) {
58 var d = document.createElement(tag);
59 if (className) d.className = className;
60 return d;
61 }
62
63 // ── Bar ──
64 var bar = el('nav', 'bkbg-mm-bar');
65 bar.style.height = menuHeight + 'px';
66 app.appendChild(bar);
67
68 // Spacer for sticky offset
69 var spacer = el('div', 'bkbg-mm-spacer');
70 spacer.style.height = menuHeight + 'px';
71 app.appendChild(spacer);
72
73 if (sticky) bar.classList.add('bkbg-mm-sticky');
74
75 // Logo
76 var logoLink = el('a', 'bkbg-mm-logo');
77 logoLink.href = '/';
78 if (logoUrl) {
79 var logoImg = el('img');
80 logoImg.src = logoUrl;
81 logoImg.alt = logoAlt;
82 logoImg.style.width = logoWidth + 'px';
83 logoImg.style.maxHeight = (menuHeight - 20) + 'px';
84 logoImg.style.objectFit = 'contain';
85 logoLink.appendChild(logoImg);
86 } else {
87 var logoText = el('span', 'bkbg-mm-logo-text');
88 logoText.textContent = logoAlt;
89 logoLink.appendChild(logoText);
90 }
91 bar.appendChild(logoLink);
92
93 // Nav
94 var nav = el('ul', 'bkbg-mm-nav');
95 bar.appendChild(nav);
96
97 // CTA
98 if (showCta && ctaLabel) {
99 var ctaEl = el('a', 'bkbg-mm-cta bkbg-mm-cta-' + ctaStyle);
100 ctaEl.href = ctaUrl;
101 ctaEl.textContent = ctaLabel;
102 bar.appendChild(ctaEl);
103 }
104
105 // Hamburger
106 var hamburger = el('button', 'bkbg-mm-hamburger');
107 hamburger.setAttribute('aria-label', 'Toggle menu');
108 hamburger.setAttribute('aria-expanded', 'false');
109 [1,2,3].forEach(function() {
110 hamburger.appendChild(el('span', 'bkbg-mm-ham-line'));
111 });
112 bar.appendChild(hamburger);
113
114 // Mobile drawer
115 var drawer = el('div', 'bkbg-mm-drawer');
116 app.appendChild(drawer);
117
118 hamburger.addEventListener('click', function () {
119 var open = drawer.classList.toggle('bkbg-mm-drawer-open');
120 hamburger.classList.toggle('bkbg-mm-open', open);
121 hamburger.setAttribute('aria-expanded', open ? 'true' : 'false');
122 });
123
124 // ── State ──
125 var openPanel = null;
126 var panelEls = [];
127 var navLinkEls = [];
128
129 function closeAll() {
130 panelEls.forEach(function (p) { p.classList.remove('bkbg-mm-panel-open'); });
131 navLinkEls.forEach(function (l) { l.classList.remove('bkbg-mm-active'); });
132 openPanel = null;
133 }
134
135 function openPanelFor(idx) {
136 closeAll();
137 if (panelEls[idx]) {
138 panelEls[idx].classList.add('bkbg-mm-panel-open');
139 navLinkEls[idx].classList.add('bkbg-mm-active');
140 openPanel = idx;
141 }
142 }
143
144 // ── Build nav items ──
145 items.forEach(function (item, idx) {
146 var li = el('li', 'bkbg-mm-nav-item');
147 nav.appendChild(li);
148
149 var link = el('button', 'bkbg-mm-nav-link');
150 link.textContent = item.label || '';
151 li.appendChild(link);
152 navLinkEls.push(link);
153
154 if (!item.hasMega || !(item.columns || []).length) {
155 link.addEventListener('click', function () {
156 if (item.url && item.url !== '#') window.location.href = item.url;
157 });
158 panelEls.push(null);
159
160 // Mobile drawer simple link
161 var dLink = el('a', 'bkbg-mm-drawer-link');
162 dLink.href = item.url || '#';
163 dLink.textContent = item.label;
164 drawer.appendChild(dLink);
165 return;
166 }
167
168 // Chevron
169 var chev = el('span', 'bkbg-mm-chevron');
170 chev.textContent = '';
171 link.appendChild(chev);
172
173 // ── Panel ──
174 var panel = el('div', 'bkbg-mm-panel');
175 panel.style.width = panelWidth + 'px';
176 panel.style.borderRadius = panelRadius + 'px';
177 li.appendChild(panel);
178 panelEls.push(panel);
179
180 var panelInner = el('div', 'bkbg-mm-panel-inner');
181 panel.appendChild(panelInner);
182
183 // Columns
184 var columnsDiv = el('div', 'bkbg-mm-columns');
185 panelInner.appendChild(columnsDiv);
186
187 (item.columns || []).forEach(function (col) {
188 var colDiv = el('div', 'bkbg-mm-col');
189 var heading = el('p', 'bkbg-mm-col-heading');
190 heading.textContent = col.heading || '';
191 colDiv.appendChild(heading);
192
193 var linkList = el('ul', 'bkbg-mm-link-list');
194 (col.links || []).forEach(function (lnk) {
195 var li2 = el('li', 'bkbg-mm-link-item');
196 var a = el('a');
197 a.href = lnk.url || '#';
198
199 if (showIcons && (lnk.icon || lnk.iconType === 'dashicon' || lnk.iconType === 'image')) {
200 var icon = el('span', 'bkbg-mm-link-icon');
201 var _IP = window.bkbgIconPicker;
202 var _it = lnk.iconType || 'custom-char';
203 if (_IP && _it !== 'custom-char') {
204 var _in = _IP.buildFrontendIcon(_it, lnk.icon, lnk.iconDashicon, lnk.iconImageUrl, lnk.iconDashiconColor);
205 if (_in) icon.appendChild(_in); else icon.textContent = lnk.icon || '';
206 } else { icon.textContent = lnk.icon || ''; }
207 a.appendChild(icon);
208 }
209
210 var body = el('div', 'bkbg-mm-link-body');
211 var label = el('span', 'bkbg-mm-link-label');
212 label.textContent = lnk.label || '';
213 body.appendChild(label);
214
215 if (showDescs && lnk.desc) {
216 var desc = el('span', 'bkbg-mm-link-desc');
217 desc.textContent = lnk.desc;
218 body.appendChild(desc);
219 }
220 a.appendChild(body);
221 li2.appendChild(a);
222 linkList.appendChild(li2);
223 });
224 colDiv.appendChild(linkList);
225 columnsDiv.appendChild(colDiv);
226 });
227
228 // Featured panel
229 if (item.showFeatured) {
230 var featDiv = el('div', 'bkbg-mm-featured');
231 if (item.featuredImageUrl) {
232 var featImg = el('img', 'bkbg-mm-feat-img');
233 featImg.src = item.featuredImageUrl;
234 featImg.alt = item.featuredTitle || '';
235 featDiv.appendChild(featImg);
236 } else {
237 var featPh = el('div', 'bkbg-mm-feat-placeholder');
238 featPh.textContent = '';
239 featDiv.appendChild(featPh);
240 }
241 var featBody = el('div', 'bkbg-mm-feat-body');
242 if (item.featuredTitle) {
243 var ft = el('p', 'bkbg-mm-feat-title');
244 ft.textContent = item.featuredTitle;
245 featBody.appendChild(ft);
246 }
247 if (item.featuredDesc) {
248 var fd = el('p', 'bkbg-mm-feat-desc');
249 fd.textContent = item.featuredDesc;
250 featBody.appendChild(fd);
251 }
252 if (item.featuredCta && item.featuredCtaUrl) {
253 var fc = el('a', 'bkbg-mm-feat-cta');
254 fc.href = item.featuredCtaUrl;
255 fc.textContent = item.featuredCta;
256 featBody.appendChild(fc);
257 }
258 featDiv.appendChild(featBody);
259 panelInner.appendChild(featDiv);
260 }
261
262 // Open triggers
263 if (openOnHover) {
264 li.addEventListener('mouseenter', function () { openPanelFor(idx); });
265 li.addEventListener('mouseleave', function () { closeAll(); });
266 }
267 link.addEventListener('click', function (e) {
268 e.stopPropagation();
269 if (openPanel === idx) { closeAll(); } else { openPanelFor(idx); }
270 });
271
272 // Mobile drawer: show columns as flat links
273 var dSection = el('div');
274 var dLink2 = el('a', 'bkbg-mm-drawer-link');
275 dLink2.href = item.url || '#';
276 dLink2.textContent = item.label;
277 dSection.appendChild(dLink2);
278 (item.columns || []).forEach(function (col) {
279 (col.links || []).forEach(function (lnk) {
280 var dSub = el('a', 'bkbg-mm-drawer-sub-link');
281 dSub.href = lnk.url || '#';
282 if (showIcons && (lnk.icon || lnk.iconType === 'dashicon' || lnk.iconType === 'image')) {
283 var _IP2 = window.bkbgIconPicker;
284 var _it2 = lnk.iconType || 'custom-char';
285 if (_IP2 && _it2 !== 'custom-char') {
286 var _in2 = _IP2.buildFrontendIcon(_it2, lnk.icon, lnk.iconDashicon, lnk.iconImageUrl, lnk.iconDashiconColor);
287 if (_in2) { var iconWrap = el('span'); iconWrap.appendChild(_in2); dSub.appendChild(iconWrap); dSub.appendChild(document.createTextNode(' ' + lnk.label)); }
288 else dSub.textContent = (lnk.icon || '') + ' ' + lnk.label;
289 } else dSub.textContent = (lnk.icon || '') + ' ' + lnk.label;
290 }
291 else dSub.textContent = lnk.label;
292 dSection.appendChild(dSub);
293 });
294 });
295 drawer.appendChild(dSection);
296 });
297
298 // Close on outside click
299 document.addEventListener('click', function (e) {
300 if (!bar.contains(e.target)) closeAll();
301 });
302
303 // Sticky scroll shadow
304 if (sticky) {
305 window.addEventListener('scroll', function () {
306 bar.classList.toggle('bkbg-mm-scrolled', window.scrollY > 10);
307 });
308 }
309 });
310 })();
311