| 1 |
(function () { |
| 2 |
'use strict'; |
| 3 |
|
| 4 |
function typoCssVarsForEl(typo, prefix, el) { |
| 5 |
if (!typo || typeof typo !== 'object') return; |
| 6 |
var map = { |
| 7 |
family: 'font-family', weight: 'font-weight', transform: 'text-transform', |
| 8 |
style: 'font-style', decoration: 'text-decoration', |
| 9 |
sizeDesktop: 'font-size-d', sizeTablet: 'font-size-t', sizeMobile: 'font-size-m', sizeUnit: 'font-size-unit', |
| 10 |
lineHeightDesktop: 'line-height-d', lineHeightTablet: 'line-height-t', lineHeightMobile: 'line-height-m', lineHeightUnit: 'line-height-unit', |
| 11 |
letterSpacingDesktop: 'letter-spacing-d', letterSpacingTablet: 'letter-spacing-t', letterSpacingMobile: 'letter-spacing-m', letterSpacingUnit: 'letter-spacing-unit', |
| 12 |
wordSpacingDesktop: 'word-spacing-d', wordSpacingTablet: 'word-spacing-t', wordSpacingMobile: 'word-spacing-m', wordSpacingUnit: 'word-spacing-unit' |
| 13 |
}; |
| 14 |
Object.keys(map).forEach(function (k) { |
| 15 |
if (typo[k] !== undefined && typo[k] !== '') { |
| 16 |
var v = typo[k]; |
| 17 |
if (typeof v === 'number') { |
| 18 |
var css = map[k]; |
| 19 |
var unit = ''; |
| 20 |
if (css.indexOf('font-size') === 0 && css !== 'font-size-unit') unit = typo.sizeUnit || 'px'; |
| 21 |
else if (css.indexOf('line-height') === 0 && css !== 'line-height-unit') unit = typo.lineHeightUnit || ''; |
| 22 |
else if (css.indexOf('letter-spacing') === 0 && css !== 'letter-spacing-unit') unit = typo.letterSpacingUnit || 'px'; |
| 23 |
else if (css.indexOf('word-spacing') === 0 && css !== 'word-spacing-unit') unit = typo.wordSpacingUnit || 'px'; |
| 24 |
v = v + unit; |
| 25 |
} |
| 26 |
el.style.setProperty(prefix + map[k], v); |
| 27 |
} |
| 28 |
}); |
| 29 |
} |
| 30 |
|
| 31 |
function mk(tag, cls, styles) { |
| 32 |
var d = document.createElement(tag); |
| 33 |
if (cls) d.className = cls; |
| 34 |
if (styles) Object.keys(styles).forEach(function (k) { d.style[k] = styles[k]; }); |
| 35 |
return d; |
| 36 |
} |
| 37 |
function tx(tag, cls, text, styles) { |
| 38 |
var d = mk(tag, cls, styles); |
| 39 |
d.textContent = text; |
| 40 |
return d; |
| 41 |
} |
| 42 |
function ap(p) { |
| 43 |
Array.prototype.slice.call(arguments, 1).forEach(function (c) { if (c) p.appendChild(c); }); |
| 44 |
return p; |
| 45 |
} |
| 46 |
|
| 47 |
// ── build one speaker card ─────────────────────────────────────── |
| 48 |
function buildCard(spk, a) { |
| 49 |
var card = mk('div', '', { |
| 50 |
background: a.cardBgColor || '#ffffff', |
| 51 |
border: '1px solid ' + (a.cardBorderColor || '#e2e8f0'), |
| 52 |
borderRadius: (a.borderRadius || 16) + 'px', |
| 53 |
padding: '24px', |
| 54 |
display: 'flex', flexDirection: 'column' |
| 55 |
}); |
| 56 |
|
| 57 |
// Avatar |
| 58 |
var sz = a.avatarSize || 64; |
| 59 |
var avatar = tx('div', '', spk.avatarInitials || '?', { |
| 60 |
width: sz + 'px', height: sz + 'px', borderRadius: '50%', |
| 61 |
background: spk.avatarBg || '#6366f1', color: '#ffffff', |
| 62 |
display: 'flex', alignItems: 'center', justifyContent: 'center', |
| 63 |
fontSize: Math.round(sz * 0.35) + 'px', fontWeight: '700', |
| 64 |
flexShrink: '0', marginBottom: '14px', |
| 65 |
lineHeight: sz + 'px', textAlign: 'center' |
| 66 |
}); |
| 67 |
|
| 68 |
var nameEl = tx('div', 'bkbg-esp-name', spk.name || '', { |
| 69 |
color: a.nameColor || '#0f172a', |
| 70 |
marginBottom: '4px' |
| 71 |
}); |
| 72 |
var jobEl = tx('div', 'bkbg-esp-body', spk.title || '', { |
| 73 |
color: a.jobTitleColor || '#6366f1', |
| 74 |
fontWeight: '600', marginBottom: '2px' |
| 75 |
}); |
| 76 |
var compEl = tx('div', 'bkbg-esp-body bkbg-esp-company', '@ ' + (spk.company || ''), { |
| 77 |
color: a.companyColor || '#64748b', |
| 78 |
marginBottom: '12px' |
| 79 |
}); |
| 80 |
|
| 81 |
ap(card, avatar, nameEl, jobEl, compEl); |
| 82 |
|
| 83 |
// Bio |
| 84 |
if (a.showBio && spk.bio) { |
| 85 |
var bioEl = tx('p', 'bkbg-esp-body', spk.bio, { |
| 86 |
color: a.bioColor || '#374151', |
| 87 |
margin: '0 0 14px' |
| 88 |
}); |
| 89 |
ap(card, bioEl); |
| 90 |
} |
| 91 |
|
| 92 |
// Session block |
| 93 |
if (a.showSession && spk.session) { |
| 94 |
var sessBox = mk('div', '', { |
| 95 |
background: a.sessionBg || '#f0f9ff', |
| 96 |
border: '1px solid ' + (a.sessionBorderColor || '#bae6fd'), |
| 97 |
borderRadius: '10px', padding: '10px 12px', marginBottom: '12px' |
| 98 |
}); |
| 99 |
var timeEl = tx('div', 'bkbg-esp-session-time', '\uD83D\uDD50 ' + (spk.sessionTime || ''), { |
| 100 |
color: a.sessionTimeColor || '#0369a1', |
| 101 |
marginBottom: '4px' |
| 102 |
}); |
| 103 |
var titleEl = tx('div', 'bkbg-esp-body', spk.session, { |
| 104 |
fontWeight: '600', |
| 105 |
color: a.sessionTitleColor || '#0c4a6e' |
| 106 |
}); |
| 107 |
ap(sessBox, timeEl, titleEl); |
| 108 |
ap(card, sessBox); |
| 109 |
} |
| 110 |
|
| 111 |
// Twitter |
| 112 |
if (a.showTwitter && spk.twitterHandle) { |
| 113 |
var twEl = tx('div', 'bkbg-esp-body bkbg-esp-twitter', '\uD835\uDD4F ' + spk.twitterHandle, { |
| 114 |
color: a.twitterColor || '#0ea5e9' |
| 115 |
}); |
| 116 |
ap(card, twEl); |
| 117 |
} |
| 118 |
|
| 119 |
return card; |
| 120 |
} |
| 121 |
|
| 122 |
// ── build full block ───────────────────────────────────────────── |
| 123 |
function buildBlock(appEl) { |
| 124 |
if (appEl.dataset.rendered) return; |
| 125 |
appEl.dataset.rendered = '1'; |
| 126 |
|
| 127 |
var a; |
| 128 |
try { a = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { a = {}; } |
| 129 |
|
| 130 |
// Wrapper styles |
| 131 |
appEl.className += ' bkbg-esp-wrap'; |
| 132 |
appEl.style.background = a.bgColor || '#f8fafc'; |
| 133 |
appEl.style.border = '1px solid ' + (a.borderColor || '#e2e8f0'); |
| 134 |
appEl.style.borderRadius = (a.borderRadius || 16) + 'px'; |
| 135 |
appEl.style.overflow = 'hidden'; |
| 136 |
|
| 137 |
typoCssVarsForEl(a.typoTitle, '--bkbg-esp-ttl-', appEl); |
| 138 |
typoCssVarsForEl(a.typoSubtitle, '--bkbg-esp-sub-', appEl); |
| 139 |
typoCssVarsForEl(a.typoName, '--bkbg-esp-nm-', appEl); |
| 140 |
typoCssVarsForEl(a.typoBody, '--bkbg-esp-bd-', appEl); |
| 141 |
|
| 142 |
// Header |
| 143 |
var header = mk('div', '', { |
| 144 |
background: a.headerBgColor || '#ffffff', |
| 145 |
borderBottom: '1px solid ' + (a.borderColor || '#e2e8f0'), |
| 146 |
padding: '32px 32px 24px' |
| 147 |
}); |
| 148 |
var titleEl = tx('h2', 'bkbg-esp-title', a.eventTitle || 'Speaker Lineup', { |
| 149 |
color: a.titleColor || '#0f172a', |
| 150 |
margin: '0 0 8px', padding: '0' |
| 151 |
}); |
| 152 |
ap(header, titleEl); |
| 153 |
if (a.showSubtitle && a.eventSubtitle) { |
| 154 |
var subEl = tx('p', 'bkbg-esp-subtitle', a.eventSubtitle, { |
| 155 |
color: a.subtitleColor || '#64748b', |
| 156 |
margin: '0' |
| 157 |
}); |
| 158 |
ap(header, subEl); |
| 159 |
} |
| 160 |
ap(appEl, header); |
| 161 |
|
| 162 |
// Grid body |
| 163 |
var cols = (a.layout === 'grid') ? (a.columns || 2) : 1; |
| 164 |
var body = mk('div', '', { |
| 165 |
display: 'grid', |
| 166 |
gridTemplateColumns: 'repeat(' + cols + ', 1fr)', |
| 167 |
gap: '20px', padding: '28px' |
| 168 |
}); |
| 169 |
(a.speakers || []).forEach(function (spk) { |
| 170 |
ap(body, buildCard(spk, a)); |
| 171 |
}); |
| 172 |
ap(appEl, body); |
| 173 |
} |
| 174 |
|
| 175 |
function init() { |
| 176 |
document.querySelectorAll('.bkbg-event-speaker-app').forEach(buildBlock); |
| 177 |
} |
| 178 |
if (document.readyState !== 'loading') { init(); } else { document.addEventListener('DOMContentLoaded', init); } |
| 179 |
})(); |
| 180 |
|