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

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

352 lines 16.0 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 ensureCells(row, colCount) {
5 var cells = (row.cells || []).slice();
6 while (cells.length < colCount) cells.push('');
7 return cells.slice(0, colCount);
8 }
9
10 function iconChar(type) {
11 if (type === 'plus') return '+';
12 if (type === 'arrow') return '';
13 return '';
14 }
15
16 function iconOpenClass(type) {
17 if (type === 'plus') return 'is-open-plus';
18 if (type === 'arrow') return 'is-open-arrow';
19 return 'is-open'; /* chevron */
20 }
21
22 function typoCssVarsForEl(typo, prefix, el) {
23 if (!typo) return;
24 if (typo.family) el.style.setProperty(prefix + 'font-family', "'" + typo.family + "', sans-serif");
25 if (typo.weight) el.style.setProperty(prefix + 'font-weight', typo.weight);
26 if (typo.transform) el.style.setProperty(prefix + 'text-transform', typo.transform);
27 if (typo.style) el.style.setProperty(prefix + 'font-style', typo.style);
28 if (typo.decoration) el.style.setProperty(prefix + 'text-decoration', typo.decoration);
29 var su = typo.sizeUnit || 'px';
30 if (typo.sizeDesktop !== '' && typo.sizeDesktop != null) el.style.setProperty(prefix + 'font-size-d', typo.sizeDesktop + su);
31 if (typo.sizeTablet !== '' && typo.sizeTablet != null) el.style.setProperty(prefix + 'font-size-t', typo.sizeTablet + su);
32 if (typo.sizeMobile !== '' && typo.sizeMobile != null) el.style.setProperty(prefix + 'font-size-m', typo.sizeMobile + su);
33 var lhu = typo.lineHeightUnit || 'px';
34 if (typo.lineHeightDesktop !== '' && typo.lineHeightDesktop != null) el.style.setProperty(prefix + 'line-height-d', typo.lineHeightDesktop + lhu);
35 if (typo.lineHeightTablet !== '' && typo.lineHeightTablet != null) el.style.setProperty(prefix + 'line-height-t', typo.lineHeightTablet + lhu);
36 if (typo.lineHeightMobile !== '' && typo.lineHeightMobile != null) el.style.setProperty(prefix + 'line-height-m', typo.lineHeightMobile + lhu);
37 var lsu = typo.letterSpacingUnit || 'px';
38 if (typo.letterSpacingDesktop !== '' && typo.letterSpacingDesktop != null) { el.style.setProperty(prefix + 'letter-spacing-d', typo.letterSpacingDesktop + lsu); el.style.setProperty(prefix + 'letter-spacing', typo.letterSpacingDesktop + lsu); }
39 if (typo.letterSpacingTablet !== '' && typo.letterSpacingTablet != null) el.style.setProperty(prefix + 'letter-spacing-t', typo.letterSpacingTablet + lsu);
40 if (typo.letterSpacingMobile !== '' && typo.letterSpacingMobile != null) el.style.setProperty(prefix + 'letter-spacing-m', typo.letterSpacingMobile + lsu);
41 var wsu = typo.wordSpacingUnit || 'px';
42 if (typo.wordSpacingDesktop !== '' && typo.wordSpacingDesktop != null) { el.style.setProperty(prefix + 'word-spacing-d', typo.wordSpacingDesktop + wsu); el.style.setProperty(prefix + 'word-spacing', typo.wordSpacingDesktop + wsu); }
43 if (typo.wordSpacingTablet !== '' && typo.wordSpacingTablet != null) el.style.setProperty(prefix + 'word-spacing-t', typo.wordSpacingTablet + wsu);
44 if (typo.wordSpacingMobile !== '' && typo.wordSpacingMobile != null) el.style.setProperty(prefix + 'word-spacing-m', typo.wordSpacingMobile + wsu);
45 }
46
47 function buildTable(appEl, o) {
48 var wrap = document.createElement('div');
49 wrap.className = 'bkbg-actbl-wrap';
50 wrap.style.paddingTop = (o.paddingTop || 0) + 'px';
51 wrap.style.paddingBottom = (o.paddingBottom || 0) + 'px';
52 wrap.style.maxWidth = o.maxWidth + 'px';
53 wrap.style.margin = '0 auto';
54 wrap.style.background = o.bgColor;
55
56 /* Typography CSS vars */
57 wrap.style.setProperty('--bkbg-actbl-header-sz', o.headerSize + 'px');
58 wrap.style.setProperty('--bkbg-actbl-cell-sz', o.cellSize + 'px');
59 wrap.style.setProperty('--bkbg-actbl-detail-sz', o.detailSize + 'px');
60 typoCssVarsForEl(o.headerTypo, '--bkbg-actbl-header-', wrap);
61 typoCssVarsForEl(o.cellTypo, '--bkbg-actbl-cell-', wrap);
62 typoCssVarsForEl(o.detailTypo, '--bkbg-actbl-detail-', wrap);
63
64 var table = document.createElement('table');
65 table.className = 'bkbg-actbl-table';
66 table.style.borderRadius = o.borderRadius + 'px';
67 table.style.overflow = 'hidden';
68 table.style.border = '1px solid ' + o.borderColor;
69 table.style.boxShadow = '0 1px 4px rgba(0,0,0,0.05)';
70
71 var colCount = o.columns.length;
72 var iconPos = o.expandIconPosition || 'right';
73 var showNums = o.showRowNumbers;
74 var dur = (o.animDuration || 240) + 'ms';
75
76 /* ── THEAD ── */
77 var thead = document.createElement('thead');
78 thead.className = 'bkbg-actbl-thead';
79 var headRow = document.createElement('tr');
80 headRow.style.background = o.headerBg;
81
82 function makeHeaderCell(text, extraStyle) {
83 var th = document.createElement('th');
84 th.style.padding = o.cellPaddingV + 'px ' + o.cellPaddingH + 'px';
85 th.style.fontSize = o.headerSize + 'px';
86 th.style.color = o.headerColor;
87 th.style.borderBottom = '1px solid ' + o.borderColor;
88 th.style.textAlign = 'left';
89 if (extraStyle) Object.assign(th.style, extraStyle);
90 th.textContent = text || '';
91 return th;
92 }
93
94 if (showNums) headRow.appendChild(makeHeaderCell('#', { textAlign: 'center', width: '36px', opacity: '0.7' }));
95 if (iconPos === 'left') headRow.appendChild(makeHeaderCell('', { width: '36px' }));
96
97 o.columns.forEach(function (col) {
98 var th = makeHeaderCell(col.label, {
99 textAlign: col.align || 'left',
100 width: col.width || ''
101 });
102 headRow.appendChild(th);
103 });
104
105 if (iconPos === 'right') headRow.appendChild(makeHeaderCell('', { width: '36px' }));
106 thead.appendChild(headRow);
107 table.appendChild(thead);
108
109 /* ── TBODY ── */
110 var tbody = document.createElement('tbody');
111 var openStates = {};
112
113 /* Pre-open if needed (none by default) */
114
115 o.rows.forEach(function (row, ri) {
116 var cells = ensureCells(row, colCount);
117 var isHighlight = row.highlight;
118 var rowBg = isHighlight
119 ? o.highlightRowBg
120 : (o.stripedRows && ri % 2 === 1 ? o.rowAltBg : o.rowBg);
121
122 /* main row */
123 var tr = document.createElement('tr');
124 tr.className = 'bkbg-actbl-row' + (isHighlight ? ' is-highlight' : '');
125 tr.style.background = rowBg;
126 tr.style.borderLeft = isHighlight ? '3px solid ' + o.highlightRowBorder : '3px solid transparent';
127 tr.style.transition = 'background 0.15s';
128
129 tr.addEventListener('mouseenter', function () { tr.style.background = o.rowHoverBg; });
130 tr.addEventListener('mouseleave', function () { tr.style.background = isHighlight ? o.highlightRowBg : rowBg; });
131
132 /* row number cell */
133 if (showNums) {
134 var numTd = document.createElement('td');
135 numTd.className = 'bkbg-actbl-rownum';
136 numTd.style.padding = o.cellPaddingV + 'px ' + o.cellPaddingH + 'px';
137 numTd.style.fontSize = (o.cellSize - 1) + 'px';
138 numTd.style.color = o.rowColor;
139 numTd.style.borderBottom = '1px solid ' + o.borderColor;
140 numTd.textContent = ri + 1;
141 tr.appendChild(numTd);
142 }
143
144 /* left icon */
145 var leftIconTd = null;
146 if (iconPos === 'left') {
147 leftIconTd = document.createElement('td');
148 leftIconTd.className = 'bkbg-actbl-icon';
149 leftIconTd.style.padding = o.cellPaddingV + 'px ' + o.cellPaddingH + 'px';
150 leftIconTd.style.color = o.iconColor;
151 leftIconTd.style.borderBottom = '1px solid ' + o.borderColor;
152 var lIcon = document.createElement('span');
153 lIcon.className = 'bkbg-actbl-icon-inner';
154 lIcon.textContent = iconChar(o.expandIcon);
155 leftIconTd.appendChild(lIcon);
156 tr.appendChild(leftIconTd);
157 }
158
159 /* data cells */
160 cells.forEach(function (cell, ci) {
161 var td = document.createElement('td');
162 td.style.padding = o.cellPaddingV + 'px ' + o.cellPaddingH + 'px';
163 td.style.fontSize = o.cellSize + 'px';
164 td.style.color = o.rowColor;
165 td.style.textAlign = (o.columns[ci] && o.columns[ci].align) || 'left';
166 td.style.borderBottom = '1px solid ' + o.borderColor;
167 if (ci === 0) td.style.fontWeight = '600';
168
169 if (ci === 0 && row.badge) {
170 var badge = document.createElement('span');
171 badge.className = 'bkbg-actbl-badge';
172 badge.style.background = row.badgeColor || '#6366f1';
173 badge.textContent = row.badge;
174 td.appendChild(badge);
175 }
176
177 var textNode = document.createTextNode(cell || '');
178 td.appendChild(textNode);
179 tr.appendChild(td);
180 });
181
182 /* right icon */
183 var rightIconTd = null;
184 if (iconPos === 'right') {
185 rightIconTd = document.createElement('td');
186 rightIconTd.className = 'bkbg-actbl-icon';
187 rightIconTd.style.padding = o.cellPaddingV + 'px ' + o.cellPaddingH + 'px';
188 rightIconTd.style.color = o.iconColor;
189 rightIconTd.style.borderBottom = '1px solid ' + o.borderColor;
190 var rIcon = document.createElement('span');
191 rIcon.className = 'bkbg-actbl-icon-inner';
192 rIcon.textContent = iconChar(o.expandIcon);
193 rightIconTd.appendChild(rIcon);
194 tr.appendChild(rightIconTd);
195 }
196
197 tbody.appendChild(tr);
198
199 /* detail row */
200 var detailTr = document.createElement('tr');
201 detailTr.className = 'bkbg-actbl-detail-row';
202 var detailTd = document.createElement('td');
203 var totalCols = colCount + (showNums ? 1 : 0) + 1; /* +1 for icon col */
204 detailTd.colSpan = totalCols;
205 detailTd.style.padding = '0';
206 detailTd.style.border = 'none';
207
208 var detailInner = document.createElement('div');
209 detailInner.className = 'bkbg-actbl-detail-inner';
210 detailInner.style.transition = 'max-height ' + dur + ' ease, opacity ' + dur;
211
212 var detailContent = document.createElement('div');
213 detailContent.className = 'bkbg-actbl-detail-content';
214 detailContent.style.background = o.detailBg;
215 detailContent.style.borderBottom = '1px solid ' + o.detailBorderColor;
216 detailContent.style.borderLeft = '3px solid ' + (isHighlight ? o.highlightRowBorder : o.borderColor);
217 detailContent.style.color = o.detailColor;
218 detailContent.style.fontSize = o.detailSize + 'px';
219 detailContent.style.paddingLeft = (o.cellPaddingH + 8) + 'px';
220
221 if (row.detailTitle) {
222 var dtTitle = document.createElement('div');
223 dtTitle.className = 'bkbg-actbl-detail-title';
224 dtTitle.style.color = o.detailColor;
225 dtTitle.textContent = row.detailTitle;
226 detailContent.appendChild(dtTitle);
227 }
228
229 if ((row.detailType || 'list') === 'list') {
230 var ul = document.createElement('ul');
231 ul.className = 'bkbg-actbl-detail-list';
232 (row.detailItems || []).forEach(function (item) {
233 var li = document.createElement('li');
234 li.textContent = item;
235 li.style.color = o.detailColor;
236 ul.appendChild(li);
237 });
238 detailContent.appendChild(ul);
239 } else {
240 var p = document.createElement('p');
241 p.className = 'bkbg-actbl-detail-text';
242 p.textContent = row.detailText || '';
243 detailContent.appendChild(p);
244 }
245
246 detailInner.appendChild(detailContent);
247 detailTd.appendChild(detailInner);
248 detailTr.appendChild(detailTd);
249 tbody.appendChild(detailTr);
250
251 /* ── toggle logic ── */
252 var allIcons = [];
253 if (leftIconTd) allIcons.push(leftIconTd.querySelector('.bkbg-actbl-icon-inner'));
254 if (rightIconTd) allIcons.push(rightIconTd.querySelector('.bkbg-actbl-icon-inner'));
255
256 function openRow() {
257 openStates[ri] = true;
258 tr.classList.add('is-open');
259 allIcons.forEach(function (ic) { ic.classList.add(iconOpenClass(o.expandIcon)); });
260 detailInner.classList.add('is-open');
261 detailInner.style.maxHeight = detailContent.scrollHeight + 40 + 'px';
262 }
263
264 function closeRow() {
265 openStates[ri] = false;
266 tr.classList.remove('is-open');
267 allIcons.forEach(function (ic) { ic.classList.remove(iconOpenClass(o.expandIcon)); });
268 detailInner.classList.remove('is-open');
269 detailInner.style.maxHeight = '0';
270 }
271
272 tr.addEventListener('click', function () {
273 if (openStates[ri]) {
274 closeRow();
275 } else {
276 if (!o.allowMultiple) {
277 /* close all others */
278 Object.keys(openStates).forEach(function (k) {
279 if (openStates[k]) {
280 var event = new CustomEvent('bkbg-actbl-close', { detail: { idx: parseInt(k, 10) } });
281 table.dispatchEvent(event);
282 }
283 });
284 }
285 openRow();
286 }
287 });
288
289 table.addEventListener('bkbg-actbl-close', function (e) {
290 if (e.detail.idx === ri) closeRow();
291 });
292 });
293
294 table.appendChild(tbody);
295 wrap.appendChild(table);
296
297 appEl.parentNode.insertBefore(wrap, appEl);
298 appEl.style.display = 'none';
299 }
300
301 function init() {
302 document.querySelectorAll('.bkbg-actbl-app').forEach(function (appEl) {
303 if (appEl.dataset.rendered) return;
304 appEl.dataset.rendered = '1';
305
306 var opts;
307 try { opts = JSON.parse(appEl.dataset.opts || '{}'); } catch (e) { opts = {}; }
308
309 var o = Object.assign({
310 columns: [],
311 rows: [],
312 allowMultiple: false,
313 showRowNumbers: false,
314 stripedRows: true,
315 stickyHeader: false,
316 expandIconPosition: 'right',
317 expandIcon: 'chevron',
318 animDuration: 240,
319 borderRadius: 10,
320 cellPaddingV: 14,
321 cellPaddingH: 16,
322 headerSize: 13,
323 cellSize: 14,
324 detailSize: 14,
325 maxWidth: 900,
326 paddingTop: 0,
327 paddingBottom: 0,
328 bgColor: '#ffffff',
329 headerBg: '#f8fafc',
330 headerColor: '#374151',
331 rowBg: '#ffffff',
332 rowAltBg: '#f9fafb',
333 rowHoverBg: '#f0f4ff',
334 rowColor: '#1f2937',
335 highlightRowBg: '#f0f0ff',
336 highlightRowBorder: '#6366f1',
337 detailBg: '#f8fafc',
338 detailColor: '#374151',
339 detailBorderColor: '#e5e7eb',
340 borderColor: '#e5e7eb',
341 iconColor: '#9ca3af',
342 titleColor: '#111827'
343 }, opts);
344
345 buildTable(appEl, o);
346 });
347 }
348
349 if (document.readyState !== 'loading') { init(); }
350 else { document.addEventListener('DOMContentLoaded', init); }
351 })();
352