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 / product-showcase / frontend.js

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

98 lines 4.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 document.querySelectorAll('.bkbg-ps-wrapper').forEach(function (wrapper) {
5 /* ── Gallery thumbnails → main image swap ─────────────────── */
6 var mainImg = wrapper.querySelector('.bkbg-ps-main-img');
7 var thumbBtns = wrapper.querySelectorAll('.bkbg-ps-thumb-btn');
8
9 thumbBtns.forEach(function (btn, idx) {
10 btn.addEventListener('click', function () {
11 var src = btn.getAttribute('data-src');
12 if (mainImg && src) {
13 mainImg.src = src;
14 mainImg.alt = btn.getAttribute('data-alt') || '';
15 }
16 thumbBtns.forEach(function (b, i) {
17 b.classList.toggle('is-active', i === idx);
18 });
19 });
20 });
21
22 /* ── Variant pills ────────────────────────────────────────── */
23 var variantPills = wrapper.querySelectorAll('.bkbg-ps-variant-pill');
24 variantPills.forEach(function (pill) {
25 pill.addEventListener('click', function () {
26 variantPills.forEach(function (p) { p.classList.remove('is-active'); });
27 pill.classList.add('is-active');
28 });
29 });
30
31 /* ── Size pills ───────────────────────────────────────────── */
32 var sizePills = wrapper.querySelectorAll('.bkbg-ps-size-pill');
33 sizePills.forEach(function (pill) {
34 pill.addEventListener('click', function () {
35 sizePills.forEach(function (p) { p.classList.remove('is-active'); });
36 pill.classList.add('is-active');
37 });
38 });
39
40 /* ── Description / Specs / Reviews tabs ──────────────────── */
41 var tabNav = wrapper.querySelector('.bkbg-ps-tab-nav');
42 var tabBtns = wrapper.querySelectorAll('.bkbg-ps-tab-btn');
43 var tabPanels = wrapper.querySelectorAll('.bkbg-ps-tab-panel');
44
45 function showTab(idx) {
46 tabBtns.forEach(function (b, i) {
47 b.classList.toggle('is-active', i === idx);
48 b.setAttribute('aria-selected', i === idx ? 'true' : 'false');
49 });
50 tabPanels.forEach(function (p, i) {
51 p.classList.toggle('is-active', i === idx);
52 p.setAttribute('aria-hidden', i === idx ? 'false' : 'true');
53 });
54 }
55
56 tabBtns.forEach(function (btn, idx) {
57 btn.addEventListener('click', function () { showTab(idx); });
58 });
59
60 if (tabNav) {
61 tabNav.addEventListener('keydown', function (e) {
62 var active = tabNav.querySelector('[aria-selected="true"]');
63 var idx = Array.prototype.indexOf.call(tabBtns, active);
64 if (e.key === 'ArrowRight') {
65 showTab((idx + 1) % tabBtns.length);
66 tabBtns[(idx + 1) % tabBtns.length].focus();
67 e.preventDefault();
68 } else if (e.key === 'ArrowLeft') {
69 showTab((idx - 1 + tabBtns.length) % tabBtns.length);
70 tabBtns[(idx - 1 + tabBtns.length) % tabBtns.length].focus();
71 e.preventDefault();
72 }
73 });
74 }
75
76 /* ── Entrance animation ───────────────────────────────────── */
77 if ('IntersectionObserver' in window) {
78 var galleryCol = wrapper.querySelector('.bkbg-ps-gallery-col');
79 var infoCol = wrapper.querySelector('.bkbg-ps-info-col');
80 [galleryCol, infoCol].forEach(function (el, i) {
81 if (!el) return;
82 el.style.opacity = '0';
83 el.style.transform = 'translateY(20px)';
84 el.style.transition = 'opacity 0.5s ease ' + (i * 0.12) + 's, transform 0.5s ease ' + (i * 0.12) + 's';
85 });
86 var io = new IntersectionObserver(function (entries) {
87 entries.forEach(function (entry) {
88 if (!entry.isIntersecting) return;
89 entry.target.style.opacity = '1';
90 entry.target.style.transform = 'translateY(0)';
91 io.unobserve(entry.target);
92 });
93 }, { threshold: 0.08 });
94 [galleryCol, infoCol].forEach(function (el) { if (el) io.observe(el); });
95 }
96 });
97 })();
98