JSFiddle - React, Tailwind, and code Playground

by proticm

HTML

<script src="https://cdn.jsdelivr.net/npm/@plazarjs/core/dist/core.min.js"></script>

CSS

* {
  box-sizing: border-box
}
.p-1 {
  padding: 1rem;
}
table {
  width: 100%;
  border: 1px solid #d3d3d3
}
table th, table td {
    padding: 0.5rem;
}
table th {
  width: 50%;
  background-color: #17a2b8;
  color: #fff;
  padding: 0;
}
table th span {
  display: inline-block;
  padding: 0.5rem;
}
table th span:first-child {
  cursor: pointer
}
table tr:nth-child(odd){
  background-color: #e6f9fc
}
table th:first-child {
  border-right: 1px solid #d3d3d3
}
table td.number {
  text-align: right
}
.focus {
  color: orange
}
input.search {
    display: block;
    border: 1px solid #d3d3d3;
    padding: 0.5rem;
    width: 100%
}

JavaScript

pz.define('grid-component', {
	ownerType: 'component',
  autoLoad: true,
  renderTo: 'body',
  template: '<div class="p-1">' +
  	'<table class="w-100">' +
    	'<thead>' +
      	'<tr>' +
        	'<th data-each="columns">' +
'<span data-attr-[data-dindex]="dataIndex" data-on-click="$root.sort">{text}</span>' +
            '<span data-visible="sorter.asc">&#8679;</span>' +
            '<span data-hidden="sorter.asc">&#8681;</span>' +
          '</th>' +
        '</tr>' +
		'<tr>' + 
			'<td colspan="2"><input class="search" data-value="search" placeholder="Search term" /></td>' +
		'</tr>' +
      '</thead>' +
      '<tbody>' +
      	'<tr data-each="filteredData">' +
        	'<td data-each="$root.columns as column" data-text="$root.getColumnValue" data-attr-class="column.getClass"></td>' +
        '</tr>' +
      '</tbody>' +
  	'</table>' +
  '</div>',
  data: [
		{ name: 'Evander Holyfield', winsByKo: 29  },
	  { name: 'Mike Tyson', winsByKo: 44  },
	  { name: 'Muhammad Ali', winsByKo: 37  },
	  { name: 'Joseph Frazier', winsByKo: 27  }
	],
  viewModel: {
    search: '',
  	columns: [
    	{ dataIndex: 'name', text: 'Name', sorter: { value: 1, asc: true }, getClass: function() { return 'string' } },
      { dataIndex: 'winsByKo', text: 'Wins By KO', sorter: { value: 1, asc: true }, getClass: function() { return 'number' } }
    ],
	filteredData: [],
    getColumnValue: function() {
    	var columnName = this.rootVm.columns[this.view.index].dataIndex();
    	return this.rootVm.filteredData[this.view.parent.index][columnName]();
    },
    sort: function() {
    debugger
    	var sortKey = this.el.getAttribute('data-dindex');
    	var comp = pz.getInstanceOf('grid-component');
      comp.sort(sortKey);
    },
  },
  init: function() {
		var me = this;
		this.viewModel.filteredData = this.data.slice();
  	this.base();
    this.sort('name');
	
    this.viewModel.search.subscribe(function(value) {
      me.filter(value);
    });
  },
  sort: function(sortKey) {
 ...