| 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 |
|