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 / feature-video-tabs / frontend.js

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

328 lines 14.6 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 function applyCSS(el, styles) {
5 Object.keys(styles).forEach(function (k) { el.style[k] = styles[k]; });
6 }
7
8 function make(tag, className, styles) {
9 var el = document.createElement(tag);
10 if (className) el.className = className;
11 if (styles) applyCSS(el, styles);
12 return el;
13 }
14
15 function typoCssVarsForEl(typo, prefix, el) {
16 if (!typo) return;
17 if (typo.family) el.style.setProperty(prefix + 'font-family', "'" + typo.family + "', sans-serif");
18 if (typo.weight) el.style.setProperty(prefix + 'font-weight', typo.weight);
19 if (typo.transform) el.style.setProperty(prefix + 'text-transform', typo.transform);
20 if (typo.style) el.style.setProperty(prefix + 'font-style', typo.style);
21 if (typo.decoration) el.style.setProperty(prefix + 'text-decoration', typo.decoration);
22 var su = typo.sizeUnit || 'px';
23 if (typo.sizeDesktop !== '' && typo.sizeDesktop != null) el.style.setProperty(prefix + 'font-size-d', typo.sizeDesktop + su);
24 if (typo.sizeTablet !== '' && typo.sizeTablet != null) el.style.setProperty(prefix + 'font-size-t', typo.sizeTablet + su);
25 if (typo.sizeMobile !== '' && typo.sizeMobile != null) el.style.setProperty(prefix + 'font-size-m', typo.sizeMobile + su);
26 var lhu = typo.lineHeightUnit || '';
27 if (typo.lineHeightDesktop !== '' && typo.lineHeightDesktop != null) el.style.setProperty(prefix + 'line-height-d', typo.lineHeightDesktop + lhu);
28 if (typo.lineHeightTablet !== '' && typo.lineHeightTablet != null) el.style.setProperty(prefix + 'line-height-t', typo.lineHeightTablet + lhu);
29 if (typo.lineHeightMobile !== '' && typo.lineHeightMobile != null) el.style.setProperty(prefix + 'line-height-m', typo.lineHeightMobile + lhu);
30 var lsu = typo.letterSpacingUnit || 'px';
31 if (typo.letterSpacingDesktop !== '' && typo.letterSpacingDesktop != null) el.style.setProperty(prefix + 'letter-spacing-d', typo.letterSpacingDesktop + lsu);
32 if (typo.letterSpacingTablet !== '' && typo.letterSpacingTablet != null) el.style.setProperty(prefix + 'letter-spacing-t', typo.letterSpacingTablet + lsu);
33 if (typo.letterSpacingMobile !== '' && typo.letterSpacingMobile != null) el.style.setProperty(prefix + 'letter-spacing-m', typo.letterSpacingMobile + lsu);
34 var wsu = typo.wordSpacingUnit || 'px';
35 if (typo.wordSpacingDesktop !== '' && typo.wordSpacingDesktop != null) el.style.setProperty(prefix + 'word-spacing-d', typo.wordSpacingDesktop + wsu);
36 if (typo.wordSpacingTablet !== '' && typo.wordSpacingTablet != null) el.style.setProperty(prefix + 'word-spacing-t', typo.wordSpacingTablet + wsu);
37 if (typo.wordSpacingMobile !== '' && typo.wordSpacingMobile != null) el.style.setProperty(prefix + 'word-spacing-m', typo.wordSpacingMobile + wsu);
38 }
39
40 function init() {
41 document.querySelectorAll('.bkbg-fvtb-app').forEach(function (appEl) {
42 if (appEl.dataset.rendered) return;
43 appEl.dataset.rendered = '1';
44
45 var opts;
46 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
47
48 var o = Object.assign({
49 tabs: [],
50 layout: 'right-video',
51 tabStyle: 'pills',
52 defaultActive: 0,
53 autoAdvance: false,
54 autoAdvanceDelay: 5000,
55 videoAutoPlay: true,
56 videoLoop: true,
57 videoMuted: true,
58 aspect: '16/9',
59 videoRadius: 12,
60 videoShadow: true,
61 showIcons: true,
62 showBullets: true,
63 showCta: true,
64 gap: 48,
65 tabAreaWidth: 40,
66 paddingTop: 60,
67 paddingBottom: 60,
68 headlineSize: 26,
69 descSize: 15,
70 bulletSize: 14,
71 tabLabelSize: 14,
72 iconSize: 24,
73 bgColor: '',
74 accentColor: '#6366f1',
75 activeTabBg: '#6366f1',
76 activeTabColor: '#ffffff',
77 idleTabBg: '',
78 idleTabColor: '#374151',
79 headlineColor: '#111827',
80 descColor: '#4b5563',
81 bulletColor: '#374151',
82 bulletDot: '#6366f1',
83 ctaBg: '#6366f1',
84 ctaColor: '#ffffff',
85 videoBg: '#000000'
86 }, opts);
87
88 var tabs = o.tabs;
89 if (!tabs || tabs.length === 0) return;
90
91 var activeIdx = Math.min(o.defaultActive || 0, tabs.length - 1);
92 var autoTimer = null;
93
94 /* ── Aspect ratio ── */
95 var aspParts = (o.aspect || '16/9').split('/');
96 var aspPB = (+aspParts[1] / +aspParts[0] * 100).toFixed(2) + '%';
97
98 /* ── Outer ── */
99 var wrap = make('div', 'bkbg-fvtb-wrap', {
100 paddingTop: o.paddingTop + 'px',
101 paddingBottom: o.paddingBottom + 'px',
102 background: o.bgColor || '',
103 gap: o.gap + 'px'
104 });
105
106 typoCssVarsForEl(o.typoHeadline, '--bkbg-fvtb-th-', wrap);
107 typoCssVarsForEl(o.typoDesc, '--bkbg-fvtb-td-', wrap);
108 typoCssVarsForEl(o.typoTabLabel, '--bkbg-fvtb-tl-', wrap);
109 typoCssVarsForEl(o.typoBullet, '--bkbg-fvtb-tb-', wrap);
110
111 /* ── Tab/content column ── */
112 var leftCol = make('div', 'bkbg-fvtb-left', {
113 width: o.tabAreaWidth + '%',
114 gap: '20px'
115 });
116
117 /* Tab buttons */
118 var tabsEl = make('div', 'bkbg-fvtb-tabs');
119 var tabBtns = [];
120
121 /* Content panels */
122 var contentPanels = [];
123
124 /* Video elements (one per tab) */
125 var videoPanels = [];
126 var videoEls = [];
127
128 /* ── Media column ── */
129 var mediaCol = make('div', 'bkbg-fvtb-media', { flex: 1 });
130 var videoWrap = make('div', 'bkbg-fvtb-video-wrap', {
131 paddingBottom: aspPB,
132 background: o.videoBg,
133 borderRadius: o.videoRadius + 'px',
134 boxShadow: o.videoShadow ? '0 20px 40px rgba(0,0,0,0.15)' : 'none'
135 });
136 mediaCol.appendChild(videoWrap);
137
138 /* ── Build tabs & content ── */
139 function buildTabStyles(isActive, idx) {
140 var tabBg = isActive ? (o.activeTabBg || '#6366f1') : (o.idleTabBg || 'transparent');
141 var tabColor = isActive ? (o.activeTabColor || '#fff') : (o.idleTabColor || '#374151');
142 var btn = tabBtns[idx];
143 applyCSS(btn, { background: tabBg, color: tabColor });
144
145 if (o.tabStyle === 'lines') {
146 applyCSS(btn, {
147 background: 'transparent',
148 borderLeft: '3px solid ' + (isActive ? (o.activeTabBg || '#6366f1') : 'transparent')
149 });
150 btn.style.color = isActive ? (o.activeTabBg || '#6366f1') : (o.idleTabColor || '#374151');
151 }
152 }
153
154 function switchTo(idx) {
155 /* Deactivate all */
156 tabBtns.forEach(function (btn, i) { btn.classList.toggle('is-active', i === idx); buildTabStyles(i === idx, i); });
157 contentPanels.forEach(function (p, i) { p.classList.toggle('is-active', i === idx); });
158 videoPanels.forEach(function (p, i) { p.classList.toggle('is-active', i === idx); });
159
160 /* Pause / play videos */
161 videoEls.forEach(function (vid, i) {
162 if (!vid) return;
163 if (i === idx) {
164 if (o.videoAutoPlay) vid.play().catch(function () {});
165 } else {
166 vid.pause();
167 }
168 });
169
170 activeIdx = idx;
171 }
172
173 tabs.forEach(function (tab, idx) {
174 /* ── Tab button ── */
175 var btn = make('button', 'bkbg-fvtb-tab', {
176 padding: o.tabStyle === 'pills' ? '10px 16px' : (o.tabStyle === 'cards' ? '14px 16px' : '12px 0'),
177 borderRadius: o.tabStyle === 'pills' ? '50px' : (o.tabStyle === 'cards' ? '10px' : '0')
178 });
179 btn.setAttribute('type', 'button');
180
181 if (o.showIcons && tab.icon) {
182 var iconEl = make('span', 'bkbg-fvtb-tab-icon', { fontSize: o.iconSize + 'px' });
183 var _IP = window.bkbgIconPicker;
184 var _iType = tab.iconType || 'custom-char';
185 if (_IP && _iType !== 'custom-char') {
186 var _in = _IP.buildFrontendIcon(_iType, tab.icon, tab.iconDashicon, tab.iconImageUrl, tab.iconDashiconColor);
187 if (_in) iconEl.appendChild(_in); else iconEl.textContent = tab.icon || '';
188 } else {
189 iconEl.textContent = tab.icon || '';
190 }
191 btn.appendChild(iconEl);
192 }
193
194 var labelEl = make('span', 'bkbg-fvtb-tab-label');
195 labelEl.textContent = tab.label || 'Tab ' + (idx + 1);
196 btn.appendChild(labelEl);
197
198 btn.addEventListener('click', function () {
199 if (autoTimer) clearInterval(autoTimer);
200 switchTo(idx);
201 if (o.autoAdvance) startAuto();
202 });
203
204 tabsEl.appendChild(btn);
205 tabBtns.push(btn);
206
207 /* ── Content panel ── */
208 var panel = make('div', 'bkbg-fvtb-content');
209
210 var hl = document.createElement('h3');
211 hl.className = 'bkbg-fvtb-headline';
212 hl.textContent = tab.headline || '';
213 applyCSS(hl, { color: o.headlineColor, margin: '0' });
214 panel.appendChild(hl);
215
216 var desc = make('p', 'bkbg-fvtb-desc', { color: o.descColor });
217 desc.textContent = tab.description || '';
218 panel.appendChild(desc);
219
220 if (o.showBullets && tab.bullets && tab.bullets.length) {
221 var ul = make('ul', 'bkbg-fvtb-bullets');
222 tab.bullets.filter(Boolean).forEach(function (b) {
223 var li = make('li', 'bkbg-fvtb-bullet');
224 var dot = make('span', 'bkbg-fvtb-bullet-dot', { color: o.bulletDot });
225 dot.textContent = '';
226 var txt = make('span', 'bkbg-fvtb-bullet-text', { color: o.bulletColor });
227 txt.textContent = b;
228 li.appendChild(dot);
229 li.appendChild(txt);
230 ul.appendChild(li);
231 });
232 panel.appendChild(ul);
233 }
234
235 if (o.showCta && tab.ctaLabel) {
236 var cta = make('a', 'bkbg-fvtb-cta', {
237 padding: (o.descSize - 2) + 'px ' + (o.descSize + 10) + 'px',
238 background: o.ctaBg,
239 color: o.ctaColor
240 });
241 cta.textContent = tab.ctaLabel;
242 cta.href = tab.ctaUrl || '#';
243 panel.appendChild(cta);
244 }
245
246 leftCol.appendChild(panel);
247 contentPanels.push(panel);
248
249 /* ── Video panel ── */
250 var vPanel = make('div', 'bkbg-fvtb-video-panel');
251
252 var vid = null;
253 if (tab.videoUrl) {
254 vid = document.createElement('video');
255 vid.src = tab.videoUrl;
256 if (tab.videoPoster) vid.poster = tab.videoPoster;
257 vid.muted = true;
258 vid.loop = !!o.videoLoop;
259 vid.playsInline = true;
260 vid.preload = 'metadata';
261 if (o.videoAutoPlay && idx === activeIdx) vid.autoplay = true;
262 vPanel.appendChild(vid);
263 } else if (tab.fallbackImageUrl) {
264 var img = document.createElement('img');
265 img.src = tab.fallbackImageUrl;
266 img.alt = tab.headline || '';
267 vPanel.appendChild(img);
268 } else {
269 var placeholder = make('div', 'bkbg-fvtb-video-placeholder', { position: 'absolute', inset: 0 });
270 var playIcon = make('div', '', { fontSize: '48px', opacity: '0.4' });
271 playIcon.textContent = '';
272 placeholder.appendChild(playIcon);
273 vPanel.appendChild(placeholder);
274 }
275
276 videoWrap.appendChild(vPanel);
277 videoPanels.push(vPanel);
278 videoEls.push(vid);
279 });
280
281 leftCol.insertBefore(tabsEl, leftCol.firstChild);
282
283 /* ── Auto-advance ── */
284 function startAuto() {
285 if (!o.autoAdvance || tabs.length < 2) return;
286 autoTimer = setInterval(function () {
287 var next = (activeIdx + 1) % tabs.length;
288 switchTo(next);
289 }, o.autoAdvanceDelay);
290 }
291
292 /* ── Keyboard ── */
293 tabsEl.setAttribute('role', 'tablist');
294 tabsEl.addEventListener('keydown', function (e) {
295 if (e.key === 'ArrowDown' || e.key === 'ArrowRight') {
296 e.preventDefault();
297 switchTo((activeIdx + 1) % tabs.length);
298 tabBtns[(activeIdx) % tabs.length].focus();
299 } else if (e.key === 'ArrowUp' || e.key === 'ArrowLeft') {
300 e.preventDefault();
301 switchTo((activeIdx - 1 + tabs.length) % tabs.length);
302 tabBtns[activeIdx].focus();
303 }
304 });
305
306 /* ── Assemble ── */
307 var isRightVideo = o.layout !== 'left-video';
308 if (isRightVideo) {
309 wrap.appendChild(leftCol);
310 wrap.appendChild(mediaCol);
311 } else {
312 wrap.appendChild(mediaCol);
313 wrap.appendChild(leftCol);
314 }
315
316 /* ── Activate first tab ── */
317 switchTo(activeIdx);
318 startAuto();
319
320 appEl.parentNode.insertBefore(wrap, appEl);
321 appEl.style.display = 'none';
322 });
323 }
324
325 if (document.readyState !== 'loading') { init(); }
326 else { document.addEventListener('DOMContentLoaded', init); }
327 })();
328