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

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

213 lines 9.7 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 var _typoKeys = {
5 family:'font-family', weight:'font-weight', style:'font-style',
6 decoration:'text-decoration', transform:'text-transform',
7 sizeDesktop:'font-size-d', sizeTablet:'font-size-t', sizeMobile:'font-size-m',
8 lineHeightDesktop:'line-height-d', lineHeightTablet:'line-height-t', lineHeightMobile:'line-height-m',
9 letterSpacingDesktop:'letter-spacing-d', letterSpacingTablet:'letter-spacing-t', letterSpacingMobile:'letter-spacing-m',
10 wordSpacingDesktop:'word-spacing-d', wordSpacingTablet:'word-spacing-t', wordSpacingMobile:'word-spacing-m'
11 };
12 function typoCssVarsForEl(el, obj, prefix) {
13 if (!obj || typeof obj !== 'object') return;
14 Object.keys(_typoKeys).forEach(function (k) {
15 var v = obj[k];
16 if (v === undefined || v === '' || v === null) return;
17 if (k === 'sizeDesktop' || k === 'sizeTablet' || k === 'sizeMobile') v = v + (obj.sizeUnit || 'px');
18 else if (k === 'lineHeightDesktop' || k === 'lineHeightTablet' || k === 'lineHeightMobile') v = v + (obj.lineHeightUnit || '');
19 else if (k === 'letterSpacingDesktop' || k === 'letterSpacingTablet' || k === 'letterSpacingMobile') v = v + (obj.letterSpacingUnit || 'px');
20 else if (k === 'wordSpacingDesktop' || k === 'wordSpacingTablet' || k === 'wordSpacingMobile') v = v + (obj.wordSpacingUnit || 'px');
21 el.style.setProperty(prefix + _typoKeys[k], String(v));
22 });
23 }
24
25 function mk(tag, cls, styles) {
26 var d = document.createElement(tag);
27 if (cls) d.className = cls;
28 if (styles) Object.keys(styles).forEach(function (k) { d.style[k] = styles[k]; });
29 return d;
30 }
31 function mkText(tag, cls, text, styles) {
32 var d = mk(tag, cls, styles);
33 d.textContent = text;
34 return d;
35 }
36
37 function renderRow(spec, sIdx, o, isCard) {
38 var isHighlighted = o.showHighlight && spec.highlight;
39 var isStripe = o.style === 'striped' && sIdx % 2 === 1;
40 var rowBg = isHighlighted ? o.highlightBg : isStripe ? o.stripeBg : o.bgColor;
41 var keyCol = isHighlighted ? o.highlightColor : o.keyColor;
42 var valCol = isHighlighted ? o.highlightColor : o.valueColor;
43 var borderB = '1px solid ' + o.borderColor;
44
45 var tr = mk('tr', 'bkbg-ps-row');
46
47 var keyTd = mk('td', 'bkbg-ps-key', {
48 padding: '10px 16px',
49 color: keyCol, background: rowBg, borderBottom: borderB
50 });
51 keyTd.textContent = spec.key;
52 tr.appendChild(keyTd);
53
54 var valTd = mk('td', 'bkbg-ps-value', {
55 padding: '10px 16px',
56 color: valCol, background: rowBg, borderBottom: borderB
57 });
58 valTd.textContent = spec.value;
59 tr.appendChild(valTd);
60
61 return tr;
62 }
63
64 function renderCardGroup(group, gIdx, o) {
65 var card = mk('div', 'bkbg-ps-card', {
66 borderColor: o.borderColor
67 });
68
69 if (o.showGroupTitles) {
70 var gTitle = mkText('div', 'bkbg-ps-group-title', group.title, {
71 background: o.groupTitleBg, padding: '8px 14px',
72 color: o.groupTitleColor, borderBottom: '1px solid ' + o.borderColor
73 });
74 card.appendChild(gTitle);
75 }
76
77 (group.specs || []).forEach(function (spec, sIdx) {
78 var isHighlighted = o.showHighlight && spec.highlight;
79 var isStripe = o.style === 'striped' && sIdx % 2 === 1;
80 var rowBg = isHighlighted ? o.highlightBg : isStripe ? o.stripeBg : o.bgColor;
81 var keyCol = isHighlighted ? o.highlightColor : o.keyColor;
82 var valCol = isHighlighted ? o.highlightColor : o.valueColor;
83
84 var row = mk('div', '', {
85 display: 'flex', justifyContent: 'space-between', alignItems: 'center',
86 padding: '8px 14px',
87 background: rowBg, borderBottom: '1px solid ' + o.borderColor
88 });
89
90 var keyEl = mkText('span', 'bkbg-ps-key', spec.key, { color: keyCol });
91 var valEl = mkText('span', 'bkbg-ps-value', spec.value, {
92 color: valCol,
93 textAlign: 'right', maxWidth: '55%'
94 });
95
96 row.appendChild(keyEl);
97 row.appendChild(valEl);
98 card.appendChild(row);
99 });
100
101 return card;
102 }
103
104 function init() {
105 document.querySelectorAll('.bkbg-product-spec-app').forEach(function (appEl) {
106 if (appEl.dataset.rendered) return;
107 appEl.dataset.rendered = '1';
108
109 var opts; try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
110
111 var o = {
112 productName: opts.productName || 'Product Name',
113 productTagline: opts.productTagline || '',
114 showHeader: opts.showHeader !== false,
115 showGroupTitles:opts.showGroupTitles !== false,
116 groups: opts.groups || [],
117 layout: opts.layout || 'table',
118 style: opts.style || 'striped',
119 showHighlight: opts.showHighlight !== false,
120 borderRadius: opts.borderRadius !== undefined ? opts.borderRadius : 12,
121 headerTypo: opts.headerTypo || {},
122 groupTitleTypo: opts.groupTitleTypo || {},
123 rowTypo: opts.rowTypo || {},
124 bgColor: opts.bgColor || '#ffffff',
125 borderColor: opts.borderColor || '#e2e8f0',
126 headerBg: opts.headerBg || '#1e293b',
127 headerColor: opts.headerColor || '#ffffff',
128 groupTitleBg: opts.groupTitleBg || '#f1f5f9',
129 groupTitleColor: opts.groupTitleColor || '#475569',
130 keyColor: opts.keyColor || '#64748b',
131 valueColor: opts.valueColor || '#0f172a',
132 stripeBg: opts.stripeBg || '#f8fafc',
133 highlightBg: opts.highlightBg || '#eff6ff',
134 highlightColor: opts.highlightColor || '#1e40af',
135 accentColor: opts.accentColor || '#3b82f6'
136 };
137
138 /* ── Outer wrapper ───────────────────────────────── */
139 var block = mk('div', 'bkbg-ps-block', {
140 border: '1px solid ' + o.borderColor,
141 borderRadius: o.borderRadius + 'px',
142 overflow: 'hidden',
143 boxSizing: 'border-box'
144 });
145
146 /* ── Product header ──────────────────────────────── */
147 if (o.showHeader) {
148 var header = mk('div', 'bkbg-ps-header', {
149 background: o.headerBg,
150 color: o.headerColor,
151 padding: '20px 24px'
152 });
153 var nameEl = mkText('div', 'bkbg-ps-product-name', o.productName, {
154 color: o.headerColor
155 });
156 header.appendChild(nameEl);
157 if (o.productTagline) {
158 var tagEl = mkText('div', 'bkbg-ps-tagline', o.productTagline, { color: o.headerColor });
159 header.appendChild(tagEl);
160 }
161 block.appendChild(header);
162 }
163
164 /* ── Content ─────────────────────────────────────── */
165 if (o.layout === 'cards') {
166 var cardsWrap = mk('div', 'bkbg-ps-cards', {
167 gridTemplateColumns: '1fr 1fr'
168 });
169 o.groups.forEach(function (group, gIdx) {
170 cardsWrap.appendChild(renderCardGroup(group, gIdx, o));
171 });
172 block.appendChild(cardsWrap);
173 } else {
174 /* Table layout (also used for compact) */
175 var table = mk('table', 'bkbg-ps-table');
176 var tbody = document.createElement('tbody');
177
178 o.groups.forEach(function (group, gIdx) {
179 if (o.showGroupTitles) {
180 var titleTr = document.createElement('tr');
181 var titleTd = mk('td', 'bkbg-ps-group-title', {
182 background: o.groupTitleBg, padding: '8px 16px',
183 color: o.groupTitleColor, borderBottom: '1px solid ' + o.borderColor
184 });
185 titleTd.colSpan = 2;
186 titleTd.textContent = group.title;
187 titleTr.appendChild(titleTd);
188 tbody.appendChild(titleTr);
189 }
190
191 (group.specs || []).forEach(function (spec, sIdx) {
192 tbody.appendChild(renderRow(spec, sIdx, o, false));
193 });
194 });
195
196 table.appendChild(tbody);
197 block.appendChild(table);
198 }
199
200 /* ── Insert ──────────────────────────────────────── */
201 typoCssVarsForEl(block, o.headerTypo, '--bkbg-pspec-hd-');
202 typoCssVarsForEl(block, o.groupTitleTypo, '--bkbg-pspec-gt-');
203 typoCssVarsForEl(block, o.rowTypo, '--bkbg-pspec-rw-');
204
205 appEl.parentNode.insertBefore(block, appEl);
206 appEl.style.display = 'none';
207 });
208 }
209
210 if (document.readyState !== 'loading') { init(); }
211 else { document.addEventListener('DOMContentLoaded', init); }
212 })();
213