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:
parent
b252931c71
commit
894fc63835
@ -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>
|
||||
<btrix-table
|
||||
class="border rounded overflow-auto"
|
||||
style=${gridAutoColumnsStyle}
|
||||
>
|
||||
<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 renderColumnHeader = (cell: CellContent, index: number) => html`
|
||||
<div
|
||||
role="columnheader"
|
||||
class="cell padded"
|
||||
style=${this.columnWidths[index]
|
||||
? `width: ${this.columnWidths[index]}`
|
||||
: ""}
|
||||
>
|
||||
${cell}
|
||||
</div>
|
||||
`;
|
||||
|
||||
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>
|
||||
`;
|
||||
};
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
}
|
||||
`;
|
||||
|
||||
|
||||
@ -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>
|
||||
|
||||
|
||||
@ -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-data-table
|
||||
.columns=${usageTableCols}
|
||||
.rows=${rows}
|
||||
></btrix-data-table>
|
||||
</btrix-details>
|
||||
`;
|
||||
}
|
||||
|
||||
@ -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,18 +297,20 @@ export class OrgSettings extends LiteElement {
|
||||
${msg("Pending Invites")}
|
||||
</h3>
|
||||
|
||||
<div class="rounded border overflow-hidden">
|
||||
<btrix-data-table
|
||||
.columns=${[msg("Email"), msg("Role"), ""]}
|
||||
.rows=${this.pendingInvites.map((user) => [
|
||||
user.email,
|
||||
this.renderUserRole(user),
|
||||
this.renderRemoveInviteButton(user),
|
||||
])}
|
||||
.columnWidths=${columnWidths}
|
||||
>
|
||||
</btrix-data-table>
|
||||
</div>
|
||||
<btrix-data-table
|
||||
.columns=${[
|
||||
msg("Email"),
|
||||
msg("Role"),
|
||||
html`<span class="sr-only">${msg("Remove")}</span>`,
|
||||
]}
|
||||
.rows=${this.pendingInvites.map((user) => [
|
||||
user.email,
|
||||
this.renderUserRole(user),
|
||||
this.renderRemoveInviteButton(user),
|
||||
])}
|
||||
.columnWidths=${columnWidths}
|
||||
>
|
||||
</btrix-data-table>
|
||||
</section>
|
||||
`
|
||||
)}
|
||||
|
||||
@ -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) => {
|
||||
|
||||
@ -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) { ... }
|
||||
},
|
||||
|
||||
Loading…
Reference in New Issue
Block a user