// eslint-disable-next-line max-classes-per-file import { LitElement, html, css } from 'lit-element'; import { DecorateMixin } from '../../utils/DecorateMixin.js'; export class PTable extends DecorateMixin(LitElement) { static get properties() { return { mobile: { reflect: true, type: Boolean, }, data: Object, // Sorted, sliced data, based on user interaction _viewData: Object, }; } static get styles() { return [ ...super.styles, css` /** * Structural css */ [role='row'] { display: flex; } [role='cell'], [role='columnheader'] { flex: 1; } [role='columnheader'] { font-weight: bold; } .c-table__cell__header { display: none; } .c-table__head { background-color: var(--header-bg-color); color: var(--header-color); } .c-table[mobile] .c-table__head { display: none; } .c-table[mobile] .c-table__row { flex-direction: column; } .c-table[mobile] .c-table__cell { display: flex; } .c-table[mobile] .c-table__cell__header, .c-table[mobile] .c-table__cell__text { flex: 1; } .c-table[mobile] .c-table__cell__header { display: block; background-color: var(--header-bg-color); color: var(--header-color); } `, ]; } // eslint-disable-next-line class-methods-use-this _descTemplate() { return html` `; } // eslint-disable-next-line class-methods-use-this _ascTemplate() { return html` `; } _mainTemplate(headers, sortMap, data, m) { if (!(headers && sortMap && data)) { return html``; } return html`
${headers.map( header => html`
`, )}
${data.map( row => html`
${headers.map( header => html`
${header} ${this.renderCellContent(row[header], header)}
`, )}
`, )}
`; } render() { return this._mainTemplate( this._viewDataHeaders, this.__viewDataSortMap, this._viewData, this.mobile, ); } constructor() { super(); this.__viewDataSortMap = {}; } connectedCallback() { if (super.connectedCallback) { super.connectedCallback(); } const mql = window.matchMedia('(max-width: 767px)'); this.mobile = mql.matches; mql.addListener(({ matches }) => { this.mobile = matches; }); } updated(changedProperties) { super.updated(changedProperties); if (changedProperties.has('data')) { this.__computeViewData(this.data); } } /** * @overridable * @param {string} content * @param {string} header */ // eslint-disable-next-line class-methods-use-this, no-unused-vars renderCellContent(content, header) { return content; } __computeViewData(newData) { this._viewData = [...newData]; this._viewDataHeaders = Object.keys(newData[0]); } _sortBy(specifier) { this.__setSortMapValue(specifier); const comparison = (a, b) => { if (this.__viewDataSortMap[specifier] === 'desc') { return b[specifier] > a[specifier]; } return b[specifier] < a[specifier]; }; this._viewData.sort((a, b) => { if (comparison(a, b)) { return 1; } if (b[specifier] === a[specifier]) { return 0; } return -1; }); this.__computeViewData(this._viewData); } __setSortMapValue(specifier) { // initialize to desc first time if (!this.__viewDataSortMap[specifier]) { this.__viewDataSortMap[specifier] = 'desc'; } else { const cur = this.__viewDataSortMap[specifier]; // Toggle asc / desc this.__viewDataSortMap[specifier] = cur === 'desc' ? 'asc' : 'desc'; } } }