PluginProbe
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor / 2.0.8
Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor v2.0.8
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 / data-table / index.js

index.js in Blockenberg — 600+ Advanced Gutenberg Blocks & AI Agent for WordPress Block Editor 2.0.8, at blocks/data-table/index.js

686 lines 31.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 ( function () {
2 var el = wp.element.createElement;
3 var Fragment = wp.element.Fragment;
4 var __ = wp.i18n.__;
5 var registerBlockType = wp.blocks.registerBlockType;
6 var InspectorControls = wp.blockEditor.InspectorControls;
7 var useBlockProps = wp.blockEditor.useBlockProps;
8 var PanelBody = wp.components.PanelBody;
9 var PanelColorSettings = wp.blockEditor.PanelColorSettings;
10 var Button = wp.components.Button;
11 var ToggleControl = wp.components.ToggleControl;
12 var RangeControl = wp.components.RangeControl;
13 var SelectControl = wp.components.SelectControl;
14 var TextControl = wp.components.TextControl;
15 var TextareaControl = wp.components.TextareaControl;
16
17 var _dtTC, _dtTV;
18 function _tc() { return _dtTC || (_dtTC = window.bkbgTypographyControl); }
19 function _tv(obj, prefix) { var fn = _dtTV || (_dtTV = window.bkbgTypoCssVars); return fn ? fn(obj, prefix) : {}; }
20
21 registerBlockType('blockenberg/data-table', {
22 title: __('Data Table', 'blockenberg'),
23 icon: 'editor-table',
24 category: 'bkbg-charts',
25 description: __('Interactive data table with sorting, search, pagination and export.', 'blockenberg'),
26
27 edit: function (props) {
28 var attributes = props.attributes;
29 var setAttributes = props.setAttributes;
30 var a = attributes;
31
32 // Update cell
33 function updateCell(rowIndex, colIndex, value) {
34 var newRows = a.rows.map(function (row, ri) {
35 if (ri === rowIndex) {
36 return row.map(function (cell, ci) {
37 return ci === colIndex ? value : cell;
38 });
39 }
40 return row;
41 });
42 setAttributes({ rows: newRows });
43 }
44
45 // Update header
46 function updateHeader(colIndex, value) {
47 var newHeaders = a.headers.map(function (h, i) {
48 return i === colIndex ? value : h;
49 });
50 setAttributes({ headers: newHeaders });
51 }
52
53 // Add row at end
54 function addRow() {
55 var newRow = new Array(a.columns).fill('');
56 setAttributes({ rows: a.rows.concat([newRow]) });
57 }
58
59 // Insert row at specific position
60 function insertRow(index, position) {
61 var newRow = new Array(a.columns).fill('');
62 var newRows = a.rows.slice();
63 var insertAt = position === 'before' ? index : index + 1;
64 newRows.splice(insertAt, 0, newRow);
65 setAttributes({ rows: newRows });
66 }
67
68 // Remove row
69 function removeRow(index) {
70 if (a.rows.length <= 1) return;
71 setAttributes({ rows: a.rows.filter(function (_, i) { return i !== index; }) });
72 }
73
74 // Add column at end
75 function addColumn() {
76 var newHeaders = a.headers.concat([__('Column', 'blockenberg') + ' ' + (a.columns + 1)]);
77 var newRows = a.rows.map(function (row) {
78 return row.concat(['']);
79 });
80 setAttributes({
81 columns: a.columns + 1,
82 headers: newHeaders,
83 rows: newRows
84 });
85 }
86
87 // Insert column at specific position
88 function insertColumn(index, position) {
89 var insertAt = position === 'before' ? index : index + 1;
90 var newHeaders = a.headers.slice();
91 newHeaders.splice(insertAt, 0, __('Column', 'blockenberg'));
92 var newRows = a.rows.map(function (row) {
93 var newRow = row.slice();
94 newRow.splice(insertAt, 0, '');
95 return newRow;
96 });
97 setAttributes({
98 columns: a.columns + 1,
99 headers: newHeaders,
100 rows: newRows
101 });
102 }
103
104 // Remove column
105 function removeColumn(index) {
106 if (a.columns <= 1) return;
107 var newHeaders = a.headers.filter(function (_, i) { return i !== index; });
108 var newRows = a.rows.map(function (row) {
109 return row.filter(function (_, i) { return i !== index; });
110 });
111 setAttributes({
112 columns: a.columns - 1,
113 headers: newHeaders,
114 rows: newRows
115 });
116 }
117
118 // Move row
119 function moveRow(index, direction) {
120 var newIndex = index + direction;
121 if (newIndex < 0 || newIndex >= a.rows.length) return;
122 var newRows = a.rows.slice();
123 var temp = newRows[index];
124 newRows[index] = newRows[newIndex];
125 newRows[newIndex] = temp;
126 setAttributes({ rows: newRows });
127 }
128
129 // Move column
130 function moveColumn(index, direction) {
131 var newIndex = index + direction;
132 if (newIndex < 0 || newIndex >= a.columns) return;
133 var newHeaders = a.headers.slice();
134 var tempH = newHeaders[index];
135 newHeaders[index] = newHeaders[newIndex];
136 newHeaders[newIndex] = tempH;
137 var newRows = a.rows.map(function (row) {
138 var newRow = row.slice();
139 var temp = newRow[index];
140 newRow[index] = newRow[newIndex];
141 newRow[newIndex] = temp;
142 return newRow;
143 });
144 setAttributes({ headers: newHeaders, rows: newRows });
145 }
146
147 // Import CSV
148 function importCsv(csvText) {
149 if (!csvText.trim()) return;
150 // Normalize line endings
151 var normalizedText = csvText.replace(/\r\n/g, '\n').replace(/\r/g, '\n');
152 var lines = normalizedText.trim().split('\n');
153 if (lines.length < 1) return;
154
155 var parseRow = function(line) {
156 var result = [];
157 var current = '';
158 var inQuotes = false;
159 for (var i = 0; i < line.length; i++) {
160 var char = line[i];
161 if (char === '"') {
162 if (inQuotes && line[i + 1] === '"') {
163 // Escaped quote inside quoted field
164 current += '"';
165 i++;
166 } else {
167 inQuotes = !inQuotes;
168 }
169 } else if (char === ',' && !inQuotes) {
170 result.push(current.trim());
171 current = '';
172 } else {
173 current += char;
174 }
175 }
176 result.push(current.trim());
177 return result;
178 };
179
180 var headers = parseRow(lines[0]);
181 var rows = [];
182 for (var i = 1; i < lines.length; i++) {
183 if (lines[i].trim()) {
184 rows.push(parseRow(lines[i]));
185 }
186 }
187 if (rows.length === 0) {
188 rows = [new Array(headers.length).fill('')];
189 }
190 setAttributes({
191 columns: headers.length,
192 headers: headers,
193 rows: rows
194 });
195 }
196
197 // Style options
198 var styleOptions = [
199 { label: __('Default', 'blockenberg'), value: 'default' },
200 { label: __('Bordered', 'blockenberg'), value: 'bordered' },
201 { label: __('Minimal', 'blockenberg'), value: 'minimal' }
202 ];
203
204 var responsiveOptions = [
205 { label: __('Horizontal Scroll', 'blockenberg'), value: 'scroll' },
206 { label: __('Stack on Mobile', 'blockenberg'), value: 'stack' }
207 ];
208
209 var alignOptions = [
210 { label: __('Left', 'blockenberg'), value: 'left' },
211 { label: __('Center', 'blockenberg'), value: 'center' },
212 { label: __('Right', 'blockenberg'), value: 'right' }
213 ];
214
215 var captionPosOptions = [
216 { label: __('Top', 'blockenberg'), value: 'top' },
217 { label: __('Bottom', 'blockenberg'), value: 'bottom' }
218 ];
219
220 var fontWeightOptions = [
221 { label: '400', value: 400 },
222 { label: '500', value: 500 },
223 { label: '600', value: 600 },
224 { label: '700', value: 700 }
225 ];
226
227 // State for CSV import
228 var csvInput = wp.element.useState('');
229 var csvText = csvInput[0];
230 var setCsvText = csvInput[1];
231
232 // Inspector
233 var inspector = el(InspectorControls, {},
234 // Features
235 el(PanelBody, { title: __('Features', 'blockenberg'), initialOpen: true },
236 el(ToggleControl, {
237 label: __('Enable Search', 'blockenberg'),
238 checked: a.searchEnabled,
239 __nextHasNoMarginBottom: true,
240 onChange: function (v) { setAttributes({ searchEnabled: v }); }
241 }),
242 a.searchEnabled && el(TextControl, {
243 label: __('Search Placeholder', 'blockenberg'),
244 value: a.searchPlaceholder,
245 onChange: function (v) { setAttributes({ searchPlaceholder: v }); }
246 }),
247 el(ToggleControl, {
248 label: __('Enable Sorting', 'blockenberg'),
249 checked: a.sortingEnabled,
250 __nextHasNoMarginBottom: true,
251 onChange: function (v) { setAttributes({ sortingEnabled: v }); }
252 }),
253 el(ToggleControl, {
254 label: __('Enable Pagination', 'blockenberg'),
255 checked: a.paginationEnabled,
256 __nextHasNoMarginBottom: true,
257 onChange: function (v) { setAttributes({ paginationEnabled: v }); }
258 }),
259 a.paginationEnabled && el(RangeControl, {
260 label: __('Items Per Page', 'blockenberg'),
261 value: a.itemsPerPage,
262 min: 5,
263 max: 100,
264 step: 5,
265 onChange: function (v) { setAttributes({ itemsPerPage: v }); }
266 }),
267 el(ToggleControl, {
268 label: __('Enable Export', 'blockenberg'),
269 checked: a.exportEnabled,
270 __nextHasNoMarginBottom: true,
271 onChange: function (v) { setAttributes({ exportEnabled: v }); }
272 }),
273 a.exportEnabled && el(TextControl, {
274 label: __('Export Button Text', 'blockenberg'),
275 value: a.exportCsvText,
276 onChange: function (v) { setAttributes({ exportCsvText: v }); }
277 })
278 ),
279
280 // Layout
281 el(PanelBody, { title: __('Layout', 'blockenberg'), initialOpen: false },
282 el(ToggleControl, {
283 label: __('Sticky Header', 'blockenberg'),
284 checked: a.stickyHeader,
285 __nextHasNoMarginBottom: true,
286 onChange: function (v) { setAttributes({ stickyHeader: v }); }
287 }),
288 el(ToggleControl, {
289 label: __('Sticky First Column', 'blockenberg'),
290 checked: a.stickyFirstColumn,
291 __nextHasNoMarginBottom: true,
292 onChange: function (v) { setAttributes({ stickyFirstColumn: v }); }
293 }),
294 el(ToggleControl, {
295 label: __('Zebra Striping', 'blockenberg'),
296 checked: a.zebraStriping,
297 __nextHasNoMarginBottom: true,
298 onChange: function (v) { setAttributes({ zebraStriping: v }); }
299 }),
300 el(ToggleControl, {
301 label: __('Row Hover Highlight', 'blockenberg'),
302 checked: a.rowHoverHighlight,
303 __nextHasNoMarginBottom: true,
304 onChange: function (v) { setAttributes({ rowHoverHighlight: v }); }
305 }),
306 el(SelectControl, {
307 label: __('Responsive Mode', 'blockenberg'),
308 value: a.responsiveMode,
309 options: responsiveOptions,
310 onChange: function (v) { setAttributes({ responsiveMode: v }); }
311 }),
312 el(TextControl, {
313 label: __('Caption', 'blockenberg'),
314 value: a.caption,
315 onChange: function (v) { setAttributes({ caption: v }); }
316 }),
317 a.caption && el(SelectControl, {
318 label: __('Caption Position', 'blockenberg'),
319 value: a.captionPosition,
320 options: captionPosOptions,
321 onChange: function (v) { setAttributes({ captionPosition: v }); }
322 })
323 ),
324
325 // Style
326 el(PanelBody, { title: __('Style', 'blockenberg'), initialOpen: false },
327 el(SelectControl, {
328 label: __('Table Style', 'blockenberg'),
329 value: a.tableStyle,
330 options: styleOptions,
331 onChange: function (v) { setAttributes({ tableStyle: v }); }
332 }),
333 el(RangeControl, {
334 label: __('Cell Padding', 'blockenberg'),
335 value: a.cellPadding,
336 min: 6,
337 max: 24,
338 onChange: function (v) { setAttributes({ cellPadding: v }); }
339 }),
340 el(RangeControl, {
341 label: __('Border Width', 'blockenberg'),
342 value: a.borderWidth,
343 min: 0,
344 max: 3,
345 onChange: function (v) { setAttributes({ borderWidth: v }); }
346 }),
347 el(RangeControl, {
348 label: __('Border Radius', 'blockenberg'),
349 value: a.borderRadius,
350 min: 0,
351 max: 16,
352 onChange: function (v) { setAttributes({ borderRadius: v }); }
353 })
354 ),
355
356 // Typography
357 el(PanelBody, { title: __('Typography', 'blockenberg'), initialOpen: false },
358 _tc() && el(_tc(), { label: __('Header', 'blockenberg'), value: a.typoHeader, onChange: function (v) { setAttributes({ typoHeader: v }); } }),
359 _tc() && el(_tc(), { label: __('Cell', 'blockenberg'), value: a.typoCell, onChange: function (v) { setAttributes({ typoCell: v }); } })
360 ),
361
362 // Colors
363 el(PanelColorSettings, {
364 title: __('Header Colors', 'blockenberg'),
365 initialOpen: false,
366 colorSettings: [
367 { value: a.headerBg, onChange: function (c) { setAttributes({ headerBg: c }); }, label: __('Background', 'blockenberg') },
368 { value: a.headerColor, onChange: function (c) { setAttributes({ headerColor: c }); }, label: __('Text', 'blockenberg') },
369 { value: a.headerBorderColor, onChange: function (c) { setAttributes({ headerBorderColor: c }); }, label: __('Border', 'blockenberg') }
370 ]
371 }),
372
373 el(PanelColorSettings, {
374 title: __('Cell Colors', 'blockenberg'),
375 initialOpen: false,
376 colorSettings: [
377 { value: a.cellBg, onChange: function (c) { setAttributes({ cellBg: c }); }, label: __('Background', 'blockenberg') },
378 { value: a.cellBgAlt, onChange: function (c) { setAttributes({ cellBgAlt: c }); }, label: __('Alt Background', 'blockenberg') },
379 { value: a.cellColor, onChange: function (c) { setAttributes({ cellColor: c }); }, label: __('Text', 'blockenberg') },
380 { value: a.cellBorderColor, onChange: function (c) { setAttributes({ cellBorderColor: c }); }, label: __('Border', 'blockenberg') },
381 { value: a.hoverBg, onChange: function (c) { setAttributes({ hoverBg: c }); }, label: __('Hover Background', 'blockenberg') },
382 { value: a.accentColor, onChange: function (c) { setAttributes({ accentColor: c }); }, label: __('Accent', 'blockenberg') }
383 ]
384 }),
385
386 // Import
387 el(PanelBody, { title: __('Import Data', 'blockenberg'), initialOpen: false },
388 el(TextareaControl, {
389 label: __('Paste CSV Data', 'blockenberg'),
390 help: __('First row will be used as headers.', 'blockenberg'),
391 value: csvText,
392 onChange: function (v) { setCsvText(v); },
393 rows: 6
394 }),
395 el('div', { className: 'bkbg-dt-import-actions' },
396 el(Button, {
397 variant: 'secondary',
398 onClick: function () { importCsv(csvText); },
399 disabled: !csvText.trim()
400 }, __('Import CSV', 'blockenberg')),
401 el(Button, {
402 variant: 'tertiary',
403 onClick: function () { setCsvText(''); }
404 }, __('Clear', 'blockenberg'))
405 )
406 )
407 );
408
409 // CSS variables
410 var wrapStyle = Object.assign({
411 '--bkbg-dt-header-bg': a.headerBg,
412 '--bkbg-dt-header-color': a.headerColor,
413 '--bkbg-dt-header-border': a.headerBorderColor,
414 '--bkbg-dt-cell-bg': a.cellBg,
415 '--bkbg-dt-cell-bg-alt': a.cellBgAlt,
416 '--bkbg-dt-cell-color': a.cellColor,
417 '--bkbg-dt-cell-border': a.cellBorderColor,
418 '--bkbg-dt-hover-bg': a.hoverBg,
419 '--bkbg-dt-accent': a.accentColor,
420 /* legacy fallback vars */
421 '--bkbg-dt-header-font-size': a.headerFontSize + 'px',
422 '--bkbg-dt-header-font-weight': a.headerFontWeight,
423 '--bkbg-dt-cell-font-size': a.cellFontSize + 'px',
424 '--bkbg-dt-cell-font-weight': a.cellFontWeight,
425 '--bkbg-dt-cell-padding': a.cellPadding + 'px',
426 '--bkbg-dt-brd-w': a.borderWidth + 'px',
427 '--bkbg-dt-radius': a.borderRadius + 'px'
428 }, _tv(a.typoHeader || {}, '--bkbg-dt-hdr-'), _tv(a.typoCell || {}, '--bkbg-dt-cel-'));
429
430 // Build editor table
431 var headerCells = a.headers.map(function (header, colIndex) {
432 return el('th', { className: 'bkbg-dt-th bkbg-dt-editor-th', key: 'th-' + colIndex },
433 el('input', {
434 className: 'bkbg-dt-editor-input',
435 type: 'text',
436 value: header,
437 onChange: function (e) { updateHeader(colIndex, e.target.value); },
438 placeholder: __('Header', 'blockenberg')
439 }),
440 el('div', { className: 'bkbg-dt-col-actions' },
441 el(Button, {
442 icon: 'table-col-before',
443 label: __('Insert column before', 'blockenberg'),
444 onClick: function () { insertColumn(colIndex, 'before'); },
445 isSmall: true
446 }),
447 el(Button, {
448 icon: 'arrow-left-alt2',
449 label: __('Move left', 'blockenberg'),
450 onClick: function () { moveColumn(colIndex, -1); },
451 disabled: colIndex === 0,
452 isSmall: true
453 }),
454 el(Button, {
455 icon: 'arrow-right-alt2',
456 label: __('Move right', 'blockenberg'),
457 onClick: function () { moveColumn(colIndex, 1); },
458 disabled: colIndex === a.columns - 1,
459 isSmall: true
460 }),
461 el(Button, {
462 icon: 'table-col-after',
463 label: __('Insert column after', 'blockenberg'),
464 onClick: function () { insertColumn(colIndex, 'after'); },
465 isSmall: true
466 }),
467 el(Button, {
468 icon: 'trash',
469 label: __('Remove column', 'blockenberg'),
470 onClick: function () { removeColumn(colIndex); },
471 isDestructive: true,
472 isSmall: true,
473 disabled: a.columns <= 1
474 })
475 )
476 );
477 });
478
479 var bodyRows = a.rows.map(function (row, rowIndex) {
480 var cells = row.map(function (cell, colIndex) {
481 return el('td', { className: 'bkbg-dt-td bkbg-dt-editor-td', key: 'td-' + colIndex },
482 el('input', {
483 className: 'bkbg-dt-editor-input',
484 type: 'text',
485 value: cell,
486 onChange: function (e) { updateCell(rowIndex, colIndex, e.target.value); },
487 placeholder: ''
488 })
489 );
490 });
491
492 return el('tr', { className: 'bkbg-dt-editor-tr', key: 'tr-' + rowIndex },
493 cells,
494 el('td', { className: 'bkbg-dt-row-actions' },
495 el(Button, {
496 icon: 'table-row-before',
497 label: __('Insert row before', 'blockenberg'),
498 onClick: function () { insertRow(rowIndex, 'before'); },
499 isSmall: true
500 }),
501 el(Button, {
502 icon: 'arrow-up-alt2',
503 label: __('Move up', 'blockenberg'),
504 onClick: function () { moveRow(rowIndex, -1); },
505 disabled: rowIndex === 0,
506 isSmall: true
507 }),
508 el(Button, {
509 icon: 'arrow-down-alt2',
510 label: __('Move down', 'blockenberg'),
511 onClick: function () { moveRow(rowIndex, 1); },
512 disabled: rowIndex === a.rows.length - 1,
513 isSmall: true
514 }),
515 el(Button, {
516 icon: 'table-row-after',
517 label: __('Insert row after', 'blockenberg'),
518 onClick: function () { insertRow(rowIndex, 'after'); },
519 isSmall: true
520 }),
521 el(Button, {
522 icon: 'trash',
523 label: __('Remove row', 'blockenberg'),
524 onClick: function () { removeRow(rowIndex); },
525 isDestructive: true,
526 isSmall: true,
527 disabled: a.rows.length <= 1
528 })
529 )
530 );
531 });
532
533 var blockProps = useBlockProps({
534 className: 'bkbg-editor-wrap',
535 'data-block-label': 'Data Table'
536 });
537
538 return el('div', blockProps,
539 inspector,
540 el('div', {
541 className: 'bkbg-dt-wrap',
542 style: wrapStyle,
543 'data-style': a.tableStyle,
544 'data-zebra': a.zebraStriping ? '1' : '0',
545 'data-hover': a.rowHoverHighlight ? '1' : '0'
546 },
547 el('div', { className: 'bkbg-dt-container' },
548 el('table', { className: 'bkbg-dt-editor-table' },
549 el('thead', {},
550 el('tr', {}, headerCells)
551 ),
552 el('tbody', {}, bodyRows)
553 )
554 )
555 ),
556 el('div', { className: 'bkbg-editor-actions' },
557 el(Button, { variant: 'secondary', icon: 'plus-alt2', onClick: addRow }, __('Add Row', 'blockenberg')),
558 el(Button, { variant: 'secondary', icon: 'plus-alt2', onClick: addColumn }, __('Add Column', 'blockenberg'))
559 )
560 );
561 },
562
563 save: function (props) {
564 var a = props.attributes;
565
566 var wrapStyle = Object.assign({
567 '--bkbg-dt-header-bg': a.headerBg,
568 '--bkbg-dt-header-color': a.headerColor,
569 '--bkbg-dt-header-border': a.headerBorderColor,
570 '--bkbg-dt-cell-bg': a.cellBg,
571 '--bkbg-dt-cell-bg-alt': a.cellBgAlt,
572 '--bkbg-dt-cell-color': a.cellColor,
573 '--bkbg-dt-cell-border': a.cellBorderColor,
574 '--bkbg-dt-hover-bg': a.hoverBg,
575 '--bkbg-dt-accent': a.accentColor,
576 /* legacy fallback vars */
577 '--bkbg-dt-header-font-size': a.headerFontSize + 'px',
578 '--bkbg-dt-header-font-weight': a.headerFontWeight,
579 '--bkbg-dt-cell-font-size': a.cellFontSize + 'px',
580 '--bkbg-dt-cell-font-weight': a.cellFontWeight,
581 '--bkbg-dt-cell-padding': a.cellPadding + 'px',
582 '--bkbg-dt-brd-w': a.borderWidth + 'px',
583 '--bkbg-dt-radius': a.borderRadius + 'px'
584 }, _tv(a.typoHeader || {}, '--bkbg-dt-hdr-'), _tv(a.typoCell || {}, '--bkbg-dt-cel-'));
585
586 // Search icon SVG
587 var searchIcon = el('svg', {
588 className: 'bkbg-dt-search-icon',
589 viewBox: '0 0 24 24',
590 fill: 'none',
591 stroke: 'currentColor',
592 strokeWidth: '2'
593 },
594 el('circle', { cx: '11', cy: '11', r: '8' }),
595 el('path', { d: 'M21 21l-4.35-4.35' })
596 );
597
598 // Export icon
599 var exportIcon = el('svg', { viewBox: '0 0 24 24', fill: 'none', stroke: 'currentColor', strokeWidth: '2' },
600 el('path', { d: 'M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4' }),
601 el('polyline', { points: '7 10 12 15 17 10' }),
602 el('line', { x1: '12', y1: '15', x2: '12', y2: '3' })
603 );
604
605 // Sort icon
606 var sortIcon = el('span', { className: 'bkbg-dt-sort-icon' },
607 el('svg', { viewBox: '0 0 24 24', fill: 'currentColor' },
608 el('path', { d: 'M7 10l5 5 5-5z' })
609 )
610 );
611
612 // Controls bar
613 var controls = (a.searchEnabled || a.exportEnabled) && el('div', { className: 'bkbg-dt-controls' },
614 a.searchEnabled && el('div', { className: 'bkbg-dt-search' },
615 searchIcon,
616 el('input', {
617 type: 'text',
618 className: 'bkbg-dt-search-input',
619 placeholder: a.searchPlaceholder,
620 'data-search': '1'
621 })
622 ),
623 a.exportEnabled && el('div', { className: 'bkbg-dt-export-btns' },
624 el('button', { className: 'bkbg-dt-btn', 'data-export': 'csv' },
625 exportIcon,
626 a.exportCsvText
627 )
628 )
629 );
630
631 // Table header
632 var headerCells = a.headers.map(function (header, index) {
633 return el('th', {
634 className: 'bkbg-dt-th',
635 key: 'th-' + index,
636 'data-col': index
637 },
638 header,
639 a.sortingEnabled && sortIcon
640 );
641 });
642
643 // Table body
644 var bodyRows = a.rows.map(function (row, rowIndex) {
645 var cells = row.map(function (cell, colIndex) {
646 return el('td', {
647 className: 'bkbg-dt-td',
648 key: 'td-' + colIndex,
649 'data-label': a.headers[colIndex] || ''
650 }, cell);
651 });
652 return el('tr', { className: 'bkbg-dt-tr', key: 'tr-' + rowIndex }, cells);
653 });
654
655 // Caption
656 var caption = a.caption && el('caption', { className: 'bkbg-dt-caption' }, a.caption);
657
658 return el('div', {
659 className: 'bkbg-dt-wrap',
660 style: wrapStyle,
661 'data-style': a.tableStyle,
662 'data-sortable': a.sortingEnabled ? '1' : '0',
663 'data-paginate': a.paginationEnabled ? '1' : '0',
664 'data-per-page': a.itemsPerPage,
665 'data-zebra': a.zebraStriping ? '1' : '0',
666 'data-hover': a.rowHoverHighlight ? '1' : '0',
667 'data-sticky-header': a.stickyHeader ? '1' : '0',
668 'data-sticky-col': a.stickyFirstColumn ? '1' : '0',
669 'data-responsive': a.responsiveMode,
670 'data-caption-pos': a.captionPosition
671 },
672 controls,
673 el('div', { className: 'bkbg-dt-container' },
674 el('table', { className: 'bkbg-dt-table' },
675 caption,
676 el('thead', { className: 'bkbg-dt-thead' },
677 el('tr', {}, headerCells)
678 ),
679 el('tbody', { className: 'bkbg-dt-tbody' }, bodyRows)
680 )
681 )
682 );
683 }
684 });
685 }() );
686