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 / filterable-cards / frontend.js

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

238 lines 11.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 (function () {
2 function typoCssVarsForEl(typo, prefix, el) {
3 if (!typo || typeof typo !== 'object') 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 ['size', 'lineHeight', 'letterSpacing', 'wordSpacing'].forEach(function (prop) {
10 var unit = typo[prop + 'Unit'] || 'px';
11 var d = typo[prop + 'Desktop'], t = typo[prop + 'Tablet'], m = typo[prop + 'Mobile'];
12 var css = { size: 'font-size', lineHeight: 'line-height', letterSpacing: 'letter-spacing', wordSpacing: 'word-spacing' }[prop];
13 if (d !== undefined && d !== '') el.style.setProperty(prefix + css + '-d', d + unit);
14 if (t !== undefined && t !== '') el.style.setProperty(prefix + css + '-t', t + unit);
15 if (m !== undefined && m !== '') el.style.setProperty(prefix + css + '-m', m + unit);
16 });
17 }
18
19 function init() {
20 document.querySelectorAll('.bkbg-fc-app').forEach(function (appEl) {
21 if (appEl.dataset.rendered) return;
22 appEl.dataset.rendered = '1';
23 var opts;
24 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
25 var o = Object.assign({
26 cards: [], columns: 3, layout: 'grid', filterStyle: 'buttons',
27 allLabel: 'All', showImages: true, showDescriptions: true,
28 showLabels: true, showLinks: true, animateFilter: true,
29 imageRatio: '3:2', cardRadius: 10, gap: 24,
30 paddingTop: 0, paddingBottom: 0, bgColor: '',
31 cardBg: '#ffffff', cardBorder: '#e5e7eb',
32 titleColor: '#111827', descColor: '#6b7280',
33 labelBg: '#ede9fe', labelColor: '#6366f1', linkColor: '#6366f1',
34 filterBtnBg: '#f3f4f6', filterBtnColor: '#374151',
35 filterBtnActiveBg: '#6366f1', filterBtnActiveColor: '#ffffff',
36 accentColor: '#6366f1'
37 }, opts);
38
39 var cards = o.cards || [];
40 if (!cards.length) { appEl.style.display = 'none'; return; }
41
42 function mk(tag, cls, style) {
43 var n = document.createElement(tag);
44 if (cls) n.className = cls;
45 if (style) Object.assign(n.style, style);
46 return n;
47 }
48
49 var ratioMap = { '16:9': '56.25%', '4:3': '75%', '3:2': '66.66%', '1:1': '100%' };
50 var imgPadding = ratioMap[o.imageRatio] || '66.66%';
51
52 /* unique categories */
53 var cats = [];
54 cards.forEach(function (c) { if (c.category && cats.indexOf(c.category) < 0) cats.push(c.category); });
55
56 /* Section */
57 var section = mk('div', 'bkbg-fc-section bkbg-fcards-wrap', {
58 background: o.bgColor || '',
59 paddingTop: o.paddingTop + 'px',
60 paddingBottom: o.paddingBottom + 'px'
61 });
62 typoCssVarsForEl(o.typoTitle, '--bkbg-fcards-tt-', section);
63 typoCssVarsForEl(o.typoDesc, '--bkbg-fcards-td-', section);
64 typoCssVarsForEl(o.typoFilter, '--bkbg-fcards-tf-', section);
65
66 /* filter bar */
67 var filterWrap = mk('div', 'bkbg-fc-filter bkbg-fc-filter--' + o.filterStyle);
68 var activeFilter = o.allLabel;
69 var cardEls = [];
70
71 function applyFilter(cat) {
72 activeFilter = cat;
73 /* update button states */
74 filterWrap.querySelectorAll('.bkbg-fc-btn').forEach(function (btn) {
75 var isActive = btn.dataset.cat === cat;
76 btn.style.background = isActive ? o.filterBtnActiveBg : o.filterBtnBg;
77 btn.style.color = isActive ? o.filterBtnActiveColor : o.filterBtnColor;
78 btn.classList.toggle('active', isActive);
79 });
80
81 cardEls.forEach(function (info) {
82 var visible = (cat === o.allLabel) || (info.card.category === cat);
83 if (o.animateFilter) {
84 if (visible) {
85 info.el.style.display = '';
86 requestAnimationFrame(function () { info.el.classList.remove('bkbg-fc-fading'); });
87 } else {
88 info.el.classList.add('bkbg-fc-fading');
89 setTimeout(function () {
90 if (activeFilter !== o.allLabel && info.card.category !== activeFilter) {
91 info.el.style.display = 'none';
92 }
93 }, 380);
94 }
95 } else {
96 info.el.style.display = visible ? '' : 'none';
97 }
98 });
99 }
100
101 if (o.filterStyle === 'dropdown') {
102 var sel = document.createElement('select');
103 sel.className = 'bkbg-fc-dropdown';
104 Object.assign(sel.style, {
105 background: o.filterBtnBg, color: o.filterBtnColor,
106 border: '1px solid ' + o.cardBorder, borderRadius: '8px',
107 padding: '9px 36px 9px 14px', cursor: 'pointer'
108 });
109 var allOpt = document.createElement('option');
110 allOpt.value = o.allLabel; allOpt.textContent = o.allLabel;
111 sel.appendChild(allOpt);
112 cats.forEach(function (cat) {
113 var opt = document.createElement('option');
114 opt.value = cat; opt.textContent = cat;
115 sel.appendChild(opt);
116 });
117 sel.addEventListener('change', function () { applyFilter(sel.value); });
118 filterWrap.appendChild(sel);
119 } else {
120 var btnsWrap = mk('div', 'bkbg-fc-btns');
121 var allCats = [o.allLabel].concat(cats);
122 allCats.forEach(function (cat) {
123 var btn = mk('div', 'bkbg-fc-btn' + (cat === o.allLabel ? ' active' : ''), {
124 background: cat === o.allLabel ? o.filterBtnActiveBg : o.filterBtnBg,
125 color: cat === o.allLabel ? o.filterBtnActiveColor : o.filterBtnColor,
126 borderRadius: o.filterStyle === 'tabs' ? '6px 6px 0 0' : '999px'
127 });
128 btn.dataset.cat = cat;
129 btn.textContent = cat;
130 btn.addEventListener('click', function () { applyFilter(cat); });
131 btnsWrap.appendChild(btn);
132 });
133 filterWrap.appendChild(btnsWrap);
134 }
135
136 section.appendChild(filterWrap);
137
138 /* Grid */
139 var colCount = parseInt(o.columns, 10) || 3;
140 var gridStyle = {
141 display: 'grid',
142 gap: o.gap + 'px'
143 };
144 gridStyle.gridTemplateColumns = o.layout === 'list' ? '1fr' : ('repeat(' + colCount + ', 1fr)');
145
146 var grid = mk('div', 'bkbg-fc-grid bkbg-fc-' + o.layout, gridStyle);
147
148 cards.forEach(function (card) {
149 var wrap = mk('div', 'bkbg-fc-card-wrap', {
150 background: card.featured ? '' : o.cardBg,
151 border: '1px solid ' + (card.featured ? o.accentColor : o.cardBorder),
152 borderRadius: o.cardRadius + 'px',
153 position: 'relative',
154 overflow: 'hidden',
155 flexDirection: o.layout === 'list' ? 'row' : 'column'
156 });
157
158 if (card.featured) {
159 var ftime = mk('div', 'bkbg-fc-featured-bar', { background: o.accentColor });
160 wrap.style.background = o.cardBg;
161 wrap.appendChild(ftime);
162 }
163
164 /* image */
165 if (o.showImages) {
166 var imgBox = mk('div', 'bkbg-fc-card-img', {
167 paddingTop: o.layout === 'list' ? '' : imgPadding,
168 width: o.layout === 'list' ? '200px' : '100%',
169 height: o.layout === 'list' ? 'auto' : undefined,
170 flexShrink: o.layout === 'list' ? '0' : undefined,
171 minHeight: o.layout === 'list' ? '140px' : undefined
172 });
173 if (card.imageUrl) {
174 var img = document.createElement('img');
175 img.src = card.imageUrl;
176 img.alt = card.imageAlt || card.title || '';
177 imgBox.appendChild(img);
178 } else {
179 var ph = mk('div', 'bkbg-fc-card-placeholder');
180 ph.textContent = 'No image';
181 imgBox.appendChild(ph);
182 }
183 wrap.appendChild(imgBox);
184 }
185
186 /* body */
187 var body = mk('div', 'bkbg-fc-card-body');
188
189 /* meta row: category + label */
190 var meta = mk('div', 'bkbg-fc-meta');
191 if (card.category) {
192 var catEl = mk('span', 'bkbg-fc-cat', { color: o.descColor });
193 catEl.textContent = card.category;
194 meta.appendChild(catEl);
195 }
196 if (o.showLabels && card.label) {
197 var labelEl = mk('span', 'bkbg-fc-label', { background: o.labelBg, color: o.labelColor });
198 labelEl.textContent = card.label;
199 meta.appendChild(labelEl);
200 }
201 body.appendChild(meta);
202
203 /* title */
204 var titleEl = mk('h3', 'bkbg-fc-card-title', { color: o.titleColor });
205 titleEl.innerHTML = card.title || '';
206 body.appendChild(titleEl);
207
208 /* description */
209 if (o.showDescriptions && card.description) {
210 var desc = mk('p', 'bkbg-fc-card-desc', { color: o.descColor });
211 desc.innerHTML = card.description;
212 body.appendChild(desc);
213 }
214
215 /* link */
216 if (o.showLinks && card.link) {
217 var lnk = document.createElement('a');
218 lnk.className = 'bkbg-fc-card-link';
219 lnk.href = card.link;
220 lnk.style.color = o.linkColor;
221 lnk.textContent = (card.linkLabel || 'Learn More') + '';
222 body.appendChild(lnk);
223 }
224
225 wrap.appendChild(body);
226 grid.appendChild(wrap);
227 cardEls.push({ el: wrap, card: card });
228 });
229
230 section.appendChild(grid);
231 appEl.parentNode.insertBefore(section, appEl);
232 });
233 }
234
235 if (document.readyState !== 'loading') { init(); }
236 else { document.addEventListener('DOMContentLoaded', init); }
237 })();
238