| 1 |
(function () { |
| 2 |
function typoCssVarsForEl(typo, prefix, el) { |
| 3 |
if (!typo) return; |
| 4 |
if (typo.family) el.style.setProperty(prefix + 'font-family', "'" + typo.family + "', sans-serif"); |
| 5 |
if (typo.weight) el.style.setProperty(prefix + 'font-weight', typo.weight); |
| 6 |
if (typo.transform) el.style.setProperty(prefix + 'text-transform', typo.transform); |
| 7 |
if (typo.style) el.style.setProperty(prefix + 'font-style', typo.style); |
| 8 |
if (typo.decoration) el.style.setProperty(prefix + 'text-decoration', typo.decoration); |
| 9 |
var su = typo.sizeUnit || 'px'; |
| 10 |
if (typo.sizeDesktop !== '' && typo.sizeDesktop != null) el.style.setProperty(prefix + 'font-size-d', typo.sizeDesktop + su); |
| 11 |
if (typo.sizeTablet !== '' && typo.sizeTablet != null) el.style.setProperty(prefix + 'font-size-t', typo.sizeTablet + su); |
| 12 |
if (typo.sizeMobile !== '' && typo.sizeMobile != null) el.style.setProperty(prefix + 'font-size-m', typo.sizeMobile + su); |
| 13 |
var lhu = typo.lineHeightUnit || 'px'; |
| 14 |
if (typo.lineHeightDesktop !== '' && typo.lineHeightDesktop != null) el.style.setProperty(prefix + 'line-height-d', typo.lineHeightDesktop + lhu); |
| 15 |
if (typo.lineHeightTablet !== '' && typo.lineHeightTablet != null) el.style.setProperty(prefix + 'line-height-t', typo.lineHeightTablet + lhu); |
| 16 |
if (typo.lineHeightMobile !== '' && typo.lineHeightMobile != null) el.style.setProperty(prefix + 'line-height-m', typo.lineHeightMobile + lhu); |
| 17 |
var lsu = typo.letterSpacingUnit || 'px'; |
| 18 |
if (typo.letterSpacingDesktop !== '' && typo.letterSpacingDesktop != null) { |
| 19 |
el.style.setProperty(prefix + 'letter-spacing-d', typo.letterSpacingDesktop + lsu); |
| 20 |
el.style.setProperty(prefix + 'letter-spacing', typo.letterSpacingDesktop + lsu); |
| 21 |
} |
| 22 |
if (typo.letterSpacingTablet !== '' && typo.letterSpacingTablet != null) el.style.setProperty(prefix + 'letter-spacing-t', typo.letterSpacingTablet + lsu); |
| 23 |
if (typo.letterSpacingMobile !== '' && typo.letterSpacingMobile != null) el.style.setProperty(prefix + 'letter-spacing-m', typo.letterSpacingMobile + lsu); |
| 24 |
var wsu = typo.wordSpacingUnit || 'px'; |
| 25 |
if (typo.wordSpacingDesktop !== '' && typo.wordSpacingDesktop != null) { |
| 26 |
el.style.setProperty(prefix + 'word-spacing-d', typo.wordSpacingDesktop + wsu); |
| 27 |
el.style.setProperty(prefix + 'word-spacing', typo.wordSpacingDesktop + wsu); |
| 28 |
} |
| 29 |
if (typo.wordSpacingTablet !== '' && typo.wordSpacingTablet != null) el.style.setProperty(prefix + 'word-spacing-t', typo.wordSpacingTablet + wsu); |
| 30 |
if (typo.wordSpacingMobile !== '' && typo.wordSpacingMobile != null) el.style.setProperty(prefix + 'word-spacing-m', typo.wordSpacingMobile + wsu); |
| 31 |
} |
| 32 |
|
| 33 |
function init() { |
| 34 |
document.querySelectorAll('.bkbg-cm-app').forEach(function (appEl) { |
| 35 |
if (appEl.dataset.rendered) return; |
| 36 |
appEl.dataset.rendered = '1'; |
| 37 |
var opts; |
| 38 |
try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; } |
| 39 |
var o = Object.assign({ |
| 40 |
links: [], position: 'inline', menuStyle: 'pills', |
| 41 |
showIcons: true, showNumbers: false, animateScroll: true, |
| 42 |
fixedTop: 50, fixedOffset: 24, menuWidth: 180, borderRadius: 12, |
| 43 |
paddingTop: 0, paddingBottom: 0, |
| 44 |
bgColor: '#ffffff', linkColor: '#374151', activeBg: '#6366f1', |
| 45 |
activeColor: '#ffffff', borderColor: '#e5e7eb', |
| 46 |
shadowColor: 'rgba(0,0,0,0.08)', accentColor: '#6366f1' |
| 47 |
}, opts); |
| 48 |
|
| 49 |
var links = o.links || []; |
| 50 |
if (!links.length) { appEl.style.display = 'none'; return; } |
| 51 |
|
| 52 |
function mk(tag, cls, style) { |
| 53 |
var n = document.createElement(tag); |
| 54 |
if (cls) n.className = cls; |
| 55 |
if (style) Object.assign(n.style, style); |
| 56 |
return n; |
| 57 |
} |
| 58 |
|
| 59 |
var isFixed = o.position === 'fixed-left' || o.position === 'fixed-right'; |
| 60 |
var isDots = o.menuStyle === 'dots'; |
| 61 |
var isTabs = o.menuStyle === 'tabs'; |
| 62 |
var isList = o.menuStyle === 'list'; |
| 63 |
var isPills = o.menuStyle === 'pills'; |
| 64 |
|
| 65 |
/* Nav container */ |
| 66 |
var navClasses = 'bkbg-cm-nav cm-' + o.menuStyle; |
| 67 |
if (isFixed) navClasses += ' cm-' + o.position; |
| 68 |
|
| 69 |
var nav = mk('nav', navClasses, { |
| 70 |
background: o.bgColor, |
| 71 |
border: '1px solid ' + o.borderColor, |
| 72 |
borderRadius: o.borderRadius + 'px', |
| 73 |
boxShadow: '0 2px 16px ' + o.shadowColor, |
| 74 |
maxWidth: o.menuWidth + 'px', |
| 75 |
zIndex: '9999' |
| 76 |
}); |
| 77 |
|
| 78 |
if (isFixed) { |
| 79 |
nav.style.position = 'fixed'; |
| 80 |
nav.style.top = o.fixedTop + 'vh'; |
| 81 |
nav.style.transform = 'translateY(-50%)'; |
| 82 |
if (o.position === 'fixed-left') { nav.style.left = o.fixedOffset + 'px'; } |
| 83 |
else { nav.style.right = o.fixedOffset + 'px'; } |
| 84 |
} |
| 85 |
|
| 86 |
var linkEls = []; |
| 87 |
var dotEls = []; |
| 88 |
var activeIdx = 0; |
| 89 |
|
| 90 |
function setActive(idx) { |
| 91 |
activeIdx = idx; |
| 92 |
linkEls.forEach(function (info, i) { |
| 93 |
var isAct = i === idx; |
| 94 |
if (isDots) { |
| 95 |
info.dot.style.width = isAct ? '22px' : '10px'; |
| 96 |
info.dot.style.background = isAct ? o.activeBg : o.borderColor; |
| 97 |
} else if (isPills) { |
| 98 |
info.el.style.background = isAct ? o.activeBg : 'transparent'; |
| 99 |
info.el.style.color = isAct ? o.activeColor : o.linkColor; |
| 100 |
info.el.style.fontWeight = isAct ? '700' : '500'; |
| 101 |
} else if (isList) { |
| 102 |
info.el.style.color = isAct ? o.accentColor : o.linkColor; |
| 103 |
info.el.style.borderLeftColor = isAct ? o.accentColor : 'transparent'; |
| 104 |
info.el.style.fontWeight = isAct ? '700' : '500'; |
| 105 |
} else if (isTabs) { |
| 106 |
info.el.style.color = isAct ? o.accentColor : o.linkColor; |
| 107 |
info.el.style.borderBottomColor = isAct ? o.accentColor : 'transparent'; |
| 108 |
info.el.style.fontWeight = isAct ? '700' : '500'; |
| 109 |
} |
| 110 |
}); |
| 111 |
} |
| 112 |
|
| 113 |
links.forEach(function (lk, idx) { |
| 114 |
if (isDots) { |
| 115 |
var dot = mk('div', 'bkbg-cm-dot', { |
| 116 |
width: idx === 0 ? '22px' : '10px', |
| 117 |
background: idx === 0 ? o.activeBg : o.borderColor, |
| 118 |
cursor: 'pointer' |
| 119 |
}); |
| 120 |
dot.title = lk.label; |
| 121 |
dot.addEventListener('click', function () { |
| 122 |
scrollToAnchor(lk.anchor); |
| 123 |
setActive(idx); |
| 124 |
}); |
| 125 |
nav.appendChild(dot); |
| 126 |
linkEls.push({ dot: dot }); |
| 127 |
return; |
| 128 |
} |
| 129 |
|
| 130 |
var linkEl = mk('div', 'bkbg-cm-link' + (idx === 0 ? ' active' : ''), { |
| 131 |
color: idx === 0 ? (isPills ? o.activeColor : o.accentColor) : o.linkColor, |
| 132 |
background: idx === 0 && isPills ? o.activeBg : 'transparent', |
| 133 |
fontWeight: idx === 0 ? '700' : '500', |
| 134 |
padding: isPills ? '7px 16px' : isList ? '9px 14px' : '9px 18px', |
| 135 |
borderRadius: isPills ? '8px' : '0', |
| 136 |
borderLeft: isList ? ('3px solid ' + (idx === 0 ? o.accentColor : 'transparent')) : 'none', |
| 137 |
borderBottom: isTabs ? ('2px solid ' + (idx === 0 ? o.accentColor : 'transparent')) : 'none', |
| 138 |
userSelect: 'none' |
| 139 |
}); |
| 140 |
|
| 141 |
if (o.showNumbers) { |
| 142 |
var num = mk('span', 'bkbg-cm-num'); |
| 143 |
num.textContent = (idx + 1) + '.'; |
| 144 |
linkEl.appendChild(num); |
| 145 |
} |
| 146 |
|
| 147 |
if (o.showIcons && lk.icon) { |
| 148 |
var icon = mk('span', 'bkbg-cm-link-icon'); |
| 149 |
var _IP = window.bkbgIconPicker; |
| 150 |
var _iType = lk.iconType || 'custom-char'; |
| 151 |
if (_IP && _iType !== 'custom-char') { |
| 152 |
var _in = _IP.buildFrontendIcon(_iType, lk.icon, lk.iconDashicon, lk.iconImageUrl, lk.iconDashiconColor); |
| 153 |
if (_in) icon.appendChild(_in); |
| 154 |
else icon.textContent = lk.icon; |
| 155 |
} else { |
| 156 |
icon.textContent = lk.icon; |
| 157 |
} |
| 158 |
linkEl.appendChild(icon); |
| 159 |
} |
| 160 |
|
| 161 |
var label = mk('span', ''); |
| 162 |
label.textContent = lk.label; |
| 163 |
linkEl.appendChild(label); |
| 164 |
|
| 165 |
linkEl.addEventListener('click', function () { |
| 166 |
scrollToAnchor(lk.anchor); |
| 167 |
setActive(idx); |
| 168 |
}); |
| 169 |
|
| 170 |
nav.appendChild(linkEl); |
| 171 |
linkEls.push({ el: linkEl }); |
| 172 |
}); |
| 173 |
|
| 174 |
function scrollToAnchor(anchor) { |
| 175 |
var target = document.getElementById(anchor) || document.querySelector('[name="' + anchor + '"]'); |
| 176 |
if (!target) return; |
| 177 |
if (o.animateScroll) { |
| 178 |
target.scrollIntoView({ behavior: 'smooth', block: 'start' }); |
| 179 |
} else { |
| 180 |
target.scrollIntoView(); |
| 181 |
} |
| 182 |
} |
| 183 |
|
| 184 |
/* Apply typography vars (new system) */ |
| 185 |
typoCssVarsForEl(o.typoLink, '--bkcm-link-', nav); |
| 186 |
|
| 187 |
var targets = links.map(function (lk) { |
| 188 |
return document.getElementById(lk.anchor) || document.querySelector('[name="' + lk.anchor + '"]'); |
| 189 |
}); |
| 190 |
|
| 191 |
var obs = new IntersectionObserver(function (entries) { |
| 192 |
entries.forEach(function (entry) { |
| 193 |
if (entry.isIntersecting) { |
| 194 |
var idx = targets.indexOf(entry.target); |
| 195 |
if (idx >= 0) setActive(idx); |
| 196 |
} |
| 197 |
}); |
| 198 |
}, { threshold: 0.3, rootMargin: '-10% 0px -60% 0px' }); |
| 199 |
|
| 200 |
targets.forEach(function (t) { if (t) obs.observe(t); }); |
| 201 |
|
| 202 |
/* Inline: insert nav as a block, fixed: append to body */ |
| 203 |
if (isFixed) { |
| 204 |
document.body.appendChild(nav); |
| 205 |
} else { |
| 206 |
var wrapper = mk('div', 'bkbg-cm-wrap', { |
| 207 |
paddingTop: o.paddingTop + 'px', |
| 208 |
paddingBottom: o.paddingBottom + 'px' |
| 209 |
}); |
| 210 |
wrapper.appendChild(nav); |
| 211 |
appEl.parentNode.insertBefore(wrapper, appEl); |
| 212 |
} |
| 213 |
}); |
| 214 |
} |
| 215 |
|
| 216 |
if (document.readyState !== 'loading') { init(); } |
| 217 |
else { document.addEventListener('DOMContentLoaded', init); } |
| 218 |
})(); |
| 219 |
|