Refactor data table to use btrix-table component (#1474)

- Refactors `btrix-data-table` to use `btrix-table`
- Prevent tables from breaking layout at smaller screen size
This commit is contained in:
sua yoo 2024-01-28 21:17:47 -08:00 committed by GitHub
parent b252931c71
commit 894fc63835
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 88 additions and 131 deletions

View File

@ -1,7 +1,8 @@
import type { TemplateResult } from "lit";
import { LitElement, html, css } from "lit";
import { html, css, type TemplateResult } from "lit";
import { customElement, property } from "lit/decorators.js";
import { TailwindElement } from "@/classes/TailwindElement";
type CellContent = string | TemplateResult<1>;
/**
@ -21,60 +22,15 @@ type CellContent = string | TemplateResult<1>;
* ```
*/
@customElement("btrix-data-table")
export class DataTable extends LitElement {
export class DataTable extends TailwindElement {
// postcss-lit-disable-next-line
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;
btrix-table {
--btrix-cell-gap: var(--sl-spacing-x-small);
--btrix-cell-padding-top: var(--sl-spacing-x-small);
--btrix-cell-padding-bottom: var(--sl-spacing-x-small);
--btrix-cell-padding-left: var(--sl-spacing-x-small);
--btrix-cell-padding-right: var(--sl-spacing-x-small);
}
`;
@ -84,51 +40,46 @@ export class DataTable extends LitElement {
@property({ type: Array })
rows: Array<CellContent[]> = [];
// Array of CSS widths
// Array of CSS grid track widths
// https://developer.mozilla.org/en-US/docs/Web/CSS/grid-auto-columns#values
@property({ type: Array })
columnWidths: string[] = [];
render() {
const gridAutoColumnsStyle = `--btrix-table-grid-auto-columns: ${
this.columnWidths.length
? this.columnWidths.join(" ")
: "minmax(max-content, auto)"
}`;
return html`
<div role="table" class="table">
<div role="rowgroup" class="thead">
<div role="row" class="row">
${this.columns.map(this.renderColumnHeader)}
</div>
</div>
<div role="rowgroup" class="tbody">
${this.rows.map(this.renderRow)}
</div>
</div>
`;
}
private renderColumnHeader = (cell: CellContent, index: number) => html`
<div
role="columnheader"
class="cell padded"
style=${this.columnWidths[index]
? `width: ${this.columnWidths[index]}`
: ""}
<btrix-table
class="border rounded overflow-auto"
style=${gridAutoColumnsStyle}
>
${cell}
</div>
<btrix-table-head class="border-b rounded-t bg-neutral-50">
${this.columns.map(
(content, i) => html`
<btrix-table-header-cell class=${i > 0 ? "border-l" : ""}>
${content}
</btrix-table-header-cell>
`
)}
</btrix-table-head>
<btrix-table-body>
${this.rows.map(
(cells, i) => html`
<btrix-table-row class=${i > 0 ? "border-t" : ""}>
${cells.map(
(content, ii) =>
html`<btrix-table-cell class=${ii > 0 ? "border-l" : ""}
>${content}</btrix-table-cell
>`
)}
</btrix-table-row>
`
)}
</btrix-table-body>
</btrix-table>
`;
private renderRow = (cells: CellContent[]) => html`
<div role="row" class="row">${cells.map(this.renderCell)}</div>
`;
private renderCell = (cell: CellContent) => {
const shouldPadSmall =
typeof cell === "string"
? false
: // TODO better logic to check template component
cell.strings[0].startsWith("<sl-");
return html`
<div role="cell" class="cell ${shouldPadSmall ? "padSmall" : "padded"}">
${cell}
</div>
`;
};
}
}

View File

@ -4,9 +4,8 @@ import { property, queryAsync, customElement } from "lit/decorators.js";
import { ifDefined } from "lit/directives/if-defined.js";
const DEFAULT_PANEL_ID = "default-panel";
// Match witch tailwind 4xl max width
// https://tailwindcss.com/docs/max-width
const SCREEN_LG_PX = 896;
// Breakpoint in pixels for 2-column layout
const TWO_COL_SCREEN_MIN = 1032;
/**
* Tab list
@ -90,15 +89,15 @@ export class TabList extends LitElement {
"header"
"main";
grid-template-columns: 1fr;
grid-gap: 1rem;
grid-gap: 1.5rem;
}
@media only screen and (min-width: ${SCREEN_LG_PX}px) {
@media only screen and (min-width: ${TWO_COL_SCREEN_MIN}px) {
.container {
grid-template-areas:
". header"
"menu main";
grid-template-columns: auto minmax(auto, 70rem);
grid-template-columns: 16.5rem 1fr;
}
}
@ -106,7 +105,7 @@ export class TabList extends LitElement {
grid-area: menu;
}
@media only screen and (min-width: ${SCREEN_LG_PX}px) {
@media only screen and (min-width: ${TWO_COL_SCREEN_MIN}px) {
.navWrapper {
overflow: initial;
}
@ -141,7 +140,7 @@ export class TabList extends LitElement {
margin-left: var(--track-width);
}
@media only screen and (min-width: ${SCREEN_LG_PX}px) {
@media only screen and (min-width: ${TWO_COL_SCREEN_MIN}px) {
.tablist {
display: block;
}
@ -166,7 +165,7 @@ export class TabList extends LitElement {
background-color: var(--sl-color-blue-500);
}
@media only screen and (min-width: ${SCREEN_LG_PX}px) {
@media only screen and (min-width: ${TWO_COL_SCREEN_MIN}px) {
.tablist,
.show-indicator .track,
.show-indicator .indicator {

View File

@ -21,7 +21,6 @@ export class TableHead extends LitElement {
color: var(--sl-color-neutral-700);
font-size: var(--sl-font-size-x-small);
line-height: 1;
white-space: nowrap;
}
`;

View File

@ -259,9 +259,9 @@ export class CrawlDetail extends LiteElement {
<div class="mb-4">${this.renderHeader()}</div>
<main>
<section class="grid grid-cols-6 gap-4">
<div class="col-span-6 md:col-span-1">${this.renderNav()}</div>
<div class="col-span-6 md:col-span-5">${sectionContent}</div>
<section class="grid grid-cols-14 gap-6">
<div class="col-span-14 md:col-span-3">${this.renderNav()}</div>
<div class="col-span-14 md:col-span-11">${sectionContent}</div>
</section>
</main>

View File

@ -812,12 +812,10 @@ export class Dashboard extends LiteElement {
return html`
<btrix-details>
<span slot="title">${msg("Usage History")}</span>
<div class="border rounded overflow-hidden">
<btrix-data-table
.columns=${usageTableCols}
.rows=${rows}
></btrix-data-table>
</div>
</btrix-details>
`;
}

View File

@ -159,7 +159,7 @@ export class OrgSettings extends LiteElement {
<a
slot="nav"
href=${`${this.orgBasePath}/${path}`}
class="block font-medium rounded-sm mb-2 mr-2 p-2 transition-all ${isActive
class="block font-medium rounded-sm mb-2 p-2 transition-all ${isActive
? "text-blue-600 bg-blue-50 shadow-sm shadow-blue-800/20"
: "text-neutral-600 hover:bg-neutral-50"}"
@click=${this.navLink}
@ -269,16 +269,20 @@ export class OrgSettings extends LiteElement {
}
private renderMembers() {
const columnWidths = ["100%", "10rem", "1.5rem"];
const columnWidths = ["1fr", "auto", "min-content"];
const rows = Object.entries(this.org.users!).map(([_id, user]) => [
user.name,
this.renderUserRoleSelect(user),
this.renderRemoveMemberButton(user),
]);
return html`
<section class="rounded border overflow-hidden">
<section>
<btrix-data-table
.columns=${[msg("Name"), msg("Role"), ""]}
.columns=${[
msg("Name"),
msg("Role"),
html`<span class="sr-only">${msg("Delete")}</span>`,
]}
.rows=${rows}
.columnWidths=${columnWidths}
>
@ -293,9 +297,12 @@ export class OrgSettings extends LiteElement {
${msg("Pending Invites")}
</h3>
<div class="rounded border overflow-hidden">
<btrix-data-table
.columns=${[msg("Email"), msg("Role"), ""]}
.columns=${[
msg("Email"),
msg("Role"),
html`<span class="sr-only">${msg("Remove")}</span>`,
]}
.rows=${this.pendingInvites.map((user) => [
user.email,
this.renderUserRole(user),
@ -304,7 +311,6 @@ export class OrgSettings extends LiteElement {
.columnWidths=${columnWidths}
>
</btrix-data-table>
</div>
</section>
`
)}

View File

@ -538,7 +538,7 @@ export class WorkflowDetail extends LiteElement {
<a
slot="nav"
href=${`${window.location.pathname}#${tabName}`}
class="block font-medium rounded-sm mb-2 mr-2 p-2 transition-all ${className}"
class="block font-medium rounded-sm mb-2 p-2 transition-all ${className}"
aria-selected=${isActive}
aria-disabled=${disabled}
@click=${(e: MouseEvent) => {

View File

@ -105,8 +105,12 @@ function makeTheme() {
aspectRatio: {
"4/3": "4 / 3", // For Browsertrix watch/replay
},
gridTemplateColumns: {
13: "repeat(13, minmax(0, 1fr))",
14: "repeat(14, minmax(0, 1fr))",
},
screens: {
desktop: "82.5rem",
desktop: "82.5rem", // 14 4.5rem columns with 1.5rem gutter
// Override default of:
// => @media (min-width: 1024px) { ... }
},