import { LitElement, html, css, TemplateResult } from "lit"; import { property } from "lit/decorators.js"; type CellContent = string | TemplateResult; /** * Styled data table * * Usage example: * ```ts * * * ``` */ export class DataTable extends LitElement { static styles = css` :host { display: contents; } .table { display: table; table-layout: fixed; font-family: var(--font-monostyle-family); font-variation-settings: var(--font-monostyle-variation); width: 100%; } .thead { display: table-header-group; } .tbody { display: table-row-group; } .row { display: table-row; } .cell { display: table-cell; vertical-align: middle; } .cell:nth-of-type(n + 2) { border-left: 1px solid var(--sl-panel-border-color); } .cell[role="cell"] { border-top: 1px solid var(--sl-panel-border-color); } .cell.padSmall { padding: var(--sl-spacing-2x-small); } .cell.padded { padding: var(--sl-spacing-x-small); } .thead .row { background-color: var(--sl-color-neutral-50); color: var(--sl-color-neutral-700); font-size: var(--sl-font-size-x-small); line-height: 1rem; text-transform: uppercase; } `; @property({ type: Array }) columns: CellContent[] = []; @property({ type: Array }) rows: Array = []; // Array of CSS widths @property({ type: Array }) columnWidths: string[] = []; render() { return html` ${this.columns.map(this.renderColumnHeader)} ${this.rows.map(this.renderRow)} `; } private renderColumnHeader = (cell: CellContent, index: number) => html` ${cell} `; private renderRow = (cells: CellContent[]) => html` ${cells.map(this.renderCell)} `; private renderCell = (cell: CellContent) => { const shouldPadSmall = typeof cell === "string" ? false : // TODO better logic to check template component cell.strings[0].startsWith(" ${cell} `; }; }