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 { html, css, type TemplateResult } from "lit";
import { LitElement, html, css } from "lit";
import { customElement, property } from "lit/decorators.js"; import { customElement, property } from "lit/decorators.js";
import { TailwindElement } from "@/classes/TailwindElement";
type CellContent = string | TemplateResult<1>; type CellContent = string | TemplateResult<1>;
/** /**
@ -21,60 +22,15 @@ type CellContent = string | TemplateResult<1>;
* ``` * ```
*/ */
@customElement("btrix-data-table") @customElement("btrix-data-table")
export class DataTable extends LitElement { export class DataTable extends TailwindElement {
// postcss-lit-disable-next-line // postcss-lit-disable-next-line
static styles = css` static styles = css`
:host { btrix-table {
display: contents; --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);
.table { --btrix-cell-padding-left: var(--sl-spacing-x-small);
display: table; --btrix-cell-padding-right: var(--sl-spacing-x-small);
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;
} }
`; `;
@ -84,51 +40,46 @@ export class DataTable extends LitElement {
@property({ type: Array }) @property({ type: Array })
rows: Array<CellContent[]> = []; 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 }) @property({ type: Array })
columnWidths: string[] = []; columnWidths: string[] = [];
render() { render() {
const gridAutoColumnsStyle = `--btrix-table-grid-auto-columns: ${
this.columnWidths.length
? this.columnWidths.join(" ")
: "minmax(max-content, auto)"
}`;
return html` return html`
<div role="table" class="table"> <btrix-table
<div role="rowgroup" class="thead"> class="border rounded overflow-auto"
<div role="row" class="row"> style=${gridAutoColumnsStyle}
${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]}`
: ""}
> >
${cell} <btrix-table-head class="border-b rounded-t bg-neutral-50">
</div> ${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"; import { ifDefined } from "lit/directives/if-defined.js";
const DEFAULT_PANEL_ID = "default-panel"; const DEFAULT_PANEL_ID = "default-panel";
// Match witch tailwind 4xl max width // Breakpoint in pixels for 2-column layout
// https://tailwindcss.com/docs/max-width const TWO_COL_SCREEN_MIN = 1032;
const SCREEN_LG_PX = 896;
/** /**
* Tab list * Tab list
@ -90,15 +89,15 @@ export class TabList extends LitElement {
"header" "header"
"main"; "main";
grid-template-columns: 1fr; 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 { .container {
grid-template-areas: grid-template-areas:
". header" ". header"
"menu main"; "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; 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 { .navWrapper {
overflow: initial; overflow: initial;
} }
@ -141,7 +140,7 @@ export class TabList extends LitElement {
margin-left: var(--track-width); 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 { .tablist {
display: block; display: block;
} }
@ -166,7 +165,7 @@ export class TabList extends LitElement {
background-color: var(--sl-color-blue-500); 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, .tablist,
.show-indicator .track, .show-indicator .track,
.show-indicator .indicator { .show-indicator .indicator {

View File

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

View File

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

View File

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

View File

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

View File

@ -538,7 +538,7 @@ export class WorkflowDetail extends LiteElement {
<a <a
slot="nav" slot="nav"
href=${`${window.location.pathname}#${tabName}`} 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-selected=${isActive}
aria-disabled=${disabled} aria-disabled=${disabled}
@click=${(e: MouseEvent) => { @click=${(e: MouseEvent) => {

View File

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