Archived item nav button quickfix (#1543)

Navigation buttons weren't being laid out properly and were overflowing
in unintentional ways, this fixes that, and then also updates navigation
buttons & puts them into use everywhere elements service the purpose of
navigation buttons were used instead!


<img width="452" alt="Screenshot 2024-02-24 at 10 37 41 PM"
src="https://github.com/webrecorder/browsertrix-cloud/assets/5727389/a77ed1be-3f95-4e03-a4d8-e3740229621e">
<img width="519" alt="Screenshot 2024-02-24 at 10 38 06 PM"
src="https://github.com/webrecorder/browsertrix-cloud/assets/5727389/684bc9a4-bec2-4258-b264-662dc441e75f">
<img width="273" alt="Screenshot 2024-02-24 at 10 38 20 PM"
src="https://github.com/webrecorder/browsertrix-cloud/assets/5727389/863d9d9a-121e-4682-8c12-eaf94ae69c7c">
<img width="410" alt="Screenshot 2024-02-24 at 10 38 25 PM"
src="https://github.com/webrecorder/browsertrix-cloud/assets/5727389/b321375c-d063-4c00-b876-36a592c85a35">
<img width="200" alt="Screenshot 2024-02-24 at 10 38 37 PM"
src="https://github.com/webrecorder/browsertrix-cloud/assets/5727389/62bbb5d1-d4f3-4ba3-8cd5-035242424f3a">
This commit is contained in:
Emma Segal-Grossman 2024-02-25 02:04:53 -05:00 committed by GitHub
parent ae59617e02
commit f6e82d9335
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 122 additions and 109 deletions

View File

@ -38,6 +38,12 @@ export class Button extends TailwindElement {
@property({ type: String, reflect: true }) @property({ type: String, reflect: true })
role: ARIAMixin["role"] = "tab"; role: ARIAMixin["role"] = "tab";
@property({ type: String })
size: "small" | "medium" | "large" = "medium";
@property({ type: String })
align: "left" | "center" | "right" = "left";
protected willUpdate(changedProperties: PropertyValueMap<this>) { protected willUpdate(changedProperties: PropertyValueMap<this>) {
if (changedProperties.has("active")) { if (changedProperties.has("active")) {
this.ariaSelected = this.active ? "true" : null; this.ariaSelected = this.active ? "true" : null;
@ -60,10 +66,20 @@ export class Button extends TailwindElement {
return html`<${tag} return html`<${tag}
type=${this.type === "submit" ? "submit" : "button"} type=${this.type === "submit" ? "submit" : "button"}
class=${[ class=${[
tw`flex w-full cursor-pointer items-center justify-start gap-2 rounded-sm px-2 py-4 font-medium outline-primary-600 transition hover:transition-none focus-visible:outline focus-visible:outline-3 focus-visible:outline-offset-1 disabled:cursor-not-allowed disabled:bg-transparent disabled:opacity-50`, tw`flex w-full cursor-pointer items-center gap-2 rounded font-medium leading-[16px] outline-primary-600 transition hover:transition-none focus-visible:outline focus-visible:outline-3 focus-visible:outline-offset-1 disabled:cursor-not-allowed disabled:bg-transparent disabled:opacity-50`,
this.icon ? tw`min-h-6 min-w-6` : tw`h-6`, this.icon ? tw`min-h-6 min-w-6` : tw``,
{
small: this.icon ? tw`min-h-6 p-0` : tw`min-h-6 px-2 py-0`,
medium: tw`p-2`,
large: tw`px-2 py-4`,
}[this.size],
{
left: "justify-start",
center: "justify-center",
right: "justify-end",
}[this.align],
this.active this.active
? tw`bg-blue-100 text-blue-600 shadow-sm shadow-blue-900/40 hover:bg-blue-100` ? tw`bg-blue-100 text-blue-600 shadow-sm shadow-blue-900/20 hover:bg-blue-100`
: tw`text-neutral-600 hover:bg-blue-50`, : tw`text-neutral-600 hover:bg-blue-50`,
] ]
.filter(Boolean) .filter(Boolean)

View File

@ -298,13 +298,14 @@ export class Pagination extends LitElement {
private readonly renderPageButton = (page: number) => { private readonly renderPageButton = (page: number) => {
const isCurrent = page === this.page; const isCurrent = page === this.page;
return html`<li aria-current=${ifDefined(isCurrent ? "page" : undefined)}> return html`<li aria-current=${ifDefined(isCurrent ? "page" : undefined)}>
<btrix-button <btrix-navigation-button
icon icon
variant=${isCurrent ? "primary" : "neutral"} .active=${isCurrent}
?raised=${isCurrent} .size=${"small"}
.align=${"center"}
@click=${() => this.onPageChange(page)} @click=${() => this.onPageChange(page)}
aria-disabled=${isCurrent} aria-disabled=${isCurrent}
>${page}</btrix-button >${page}</btrix-navigation-button
> >
</li>`; </li>`;
}; };

View File

@ -133,6 +133,7 @@ export class TabList extends LitElement {
margin: 0; margin: 0;
list-style: none; list-style: none;
padding: 0; padding: 0;
gap: 0.5rem;
} }
.show-indicator .tablist { .show-indicator .tablist {
@ -141,7 +142,7 @@ export class TabList extends LitElement {
@media only screen and (min-width: ${TWO_COL_SCREEN_MIN_CSS}) { @media only screen and (min-width: ${TWO_COL_SCREEN_MIN_CSS}) {
.tablist { .tablist {
display: block; flex-direction: column;
} }
} }
@ -165,7 +166,6 @@ export class TabList extends LitElement {
} }
@media only screen and (min-width: ${TWO_COL_SCREEN_MIN_CSS}) { @media only screen and (min-width: ${TWO_COL_SCREEN_MIN_CSS}) {
.tablist,
.show-indicator .track, .show-indicator .track,
.show-indicator .indicator { .show-indicator .indicator {
display: block; display: block;

View File

@ -274,10 +274,10 @@ export class CollectionItemsDialog extends TailwindElement {
const { icon, label } = this.tabLabels[tab]; const { icon, label } = this.tabLabels[tab];
return html` return html`
<btrix-button <btrix-navigation-button
@click=${() => (this.activeTab = tab)} @click=${() => (this.activeTab = tab)}
variant=${isSelected ? "primary" : "neutral"} .active=${isSelected}
?raised=${isSelected} size="small"
aria-selected="${isSelected}" aria-selected="${isSelected}"
role="tab" role="tab"
aria-controls="tabPanel-${tab}" aria-controls="tabPanel-${tab}"
@ -286,7 +286,7 @@ export class CollectionItemsDialog extends TailwindElement {
> >
<sl-icon name=${icon}></sl-icon> <sl-icon name=${icon}></sl-icon>
<span>${label}</span> <span>${label}</span>
</btrix-button> </btrix-navigation-button>
`; `;
}; };

View File

@ -260,8 +260,14 @@ 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-14 gap-6"> <section class="grid gap-6 md:grid-cols-14">
<div class="col-span-14 md:col-span-3">${this.renderNav()}</div> <div class="col-span-14 grid border-b md:col-span-3 md:border-b-0 ">
<div
class="-mx-3 box-border flex overflow-x-auto px-3 md:mx-0 md:block md:px-0"
>
${this.renderNav()}
</div>
</div>
<div class="col-span-14 md:col-span-11">${sectionContent}</div> <div class="col-span-14 md:col-span-11">${sectionContent}</div>
</section> </section>
</main> </main>
@ -317,83 +323,79 @@ export class CrawlDetail extends LiteElement {
const isActive = section === this.sectionName; const isActive = section === this.sectionName;
const baseUrl = window.location.pathname.split("#")[0]; const baseUrl = window.location.pathname.split("#")[0];
return html` return html`
<li class="relative grow" role="menuitem" aria-selected="${isActive}"> <btrix-navigation-button
<a class="whitespace-nowrap md:whitespace-normal"
class="${isActive .active=${isActive}
? "text-blue-600 bg-blue-100 shadow-sm shadow-blue-800/20" href=${`${baseUrl}${window.location.search}#${section}`}
: "text-neutral-600 hover:bg-blue-50"} flex h-full flex-col items-center gap-2 rounded-md p-2 font-semibold md:flex-row" @click=${() => {
href=${`${baseUrl}${window.location.search}#${section}`} this.sectionName = section;
@click=${() => (this.sectionName = section)} }}
> ><sl-icon
<sl-icon class="h-4 w-4 shrink-0"
class="h-4 w-4 shrink-0" name=${icon}
name=${icon} aria-hidden="true"
aria-hidden="true" library=${iconLibrary}
library=${iconLibrary} ></sl-icon>
></sl-icon> ${label}</btrix-navigation-button
${label} >
</a>
</li>
`; `;
}; };
return html` return html`
<nav class="sticky top-0 border-b pb-4 md:mt-10 md:border-b-0"> <nav
<ul class="sticky top-0 flex flex-row gap-2 pb-4 text-center md:mt-10 md:flex-col md:text-start"
class="flex flex-row gap-2 text-center md:flex-col md:text-start" role="menu"
role="menu" >
> ${renderNavItem({
${renderNavItem({ section: "overview",
section: "overview", iconLibrary: "default",
iconLibrary: "default", icon: "info-circle-fill",
icon: "info-circle-fill", label: msg("Overview"),
label: msg("Overview"), })}
})} ${renderNavItem({
${renderNavItem({ section: "replay",
section: "replay", iconLibrary: "app",
iconLibrary: "app", icon: "link-replay",
icon: "link-replay", label: msg("Replay"),
label: msg("Replay"), })}
})} ${renderNavItem({
${renderNavItem({ section: "files",
section: "files", iconLibrary: "default",
iconLibrary: "default", icon: "folder-fill",
icon: "folder-fill", label: msg("Files"),
label: msg("Files"), })}
})} ${when(
${when( this.itemType === "crawl",
this.itemType === "crawl", () => html`
() => html` ${renderNavItem({
${renderNavItem({ section: "logs",
section: "logs", iconLibrary: "default",
iconLibrary: "default", icon: "terminal-fill",
icon: "terminal-fill", label: msg("Error Logs"),
label: msg("Error Logs"), })}
})} ${renderNavItem({
${renderNavItem({ section: "config",
section: "config", iconLibrary: "default",
iconLibrary: "default", icon: "file-code-fill",
icon: "file-code-fill", label: msg("Crawl Settings"),
label: msg("Crawl Settings"), })}
})} `,
`, )}
)}
</ul>
</nav> </nav>
`; `;
} }
private renderHeader() { private renderHeader() {
return html` return html`
<header class="mb-3 items-center gap-2 border-b pb-3 md:flex"> <header class="mb-3 flex flex-wrap items-center gap-2 border-b pb-3">
<h1 <h1
class="mb-2 grid min-w-0 flex-1 truncate text-xl font-semibold leading-7 md:mb-0" class="grid min-w-0 flex-auto truncate text-xl font-semibold leading-7"
> >
${this.renderName()} ${this.renderName()}
</h1> </h1>
<div <div
class="${this.isActive class="${this.isActive
? "justify-between" ? "justify-between"
: "justify-end"} grid grid-flow-col gap-2" : "justify-end ml-auto"} grid grid-flow-col gap-2"
> >
${this.isActive ${this.isActive
? html` ? html`

View File

@ -119,21 +119,21 @@ export class ArchivedItemQA extends TailwindElement {
</header> </header>
<section class="main outline"> <section class="main outline">
<nav> <nav>
<btrix-button <btrix-navigation-button
id="screenshot-tab" id="screenshot-tab"
href=${`${crawlBaseUrl}/review/screenshots`} href=${`${crawlBaseUrl}/review/screenshots`}
variant=${this.tab === "screenshots" ? "primary" : "neutral"} .active=${this.tab === "screenshots"}
?raised=${this.tab === "screenshots"} size="small"
@click=${this.navigate.link} @click=${this.navigate.link}
>${msg("Screenshots")}</btrix-button >${msg("Screenshots")}</btrix-navigation-button
> >
<btrix-button <btrix-navigation-button
id="replay-tab" id="replay-tab"
href=${`${crawlBaseUrl}/review/replay`} href=${`${crawlBaseUrl}/review/replay`}
variant=${this.tab === "replay" ? "primary" : "neutral"} .active=${this.tab === "replay"}
?raised=${this.tab === "replay"} size="small"
@click=${this.navigate.link} @click=${this.navigate.link}
>${msg("Replay")}</btrix-button >${msg("Replay")}</btrix-navigation-button
> >
</nav> </nav>
<div role="region" aria-labelledby="${this.tab}-tab"> <div role="region" aria-labelledby="${this.tab}-tab">

View File

@ -195,7 +195,7 @@ export class CrawlsList extends LiteElement {
return html` return html`
<main> <main>
<header class="contents"> <header class="contents">
<div class="mb-3 flex justify-between gap-2 border-b pb-3"> <div class="mb-3 flex flex-wrap justify-between gap-2 border-b pb-3">
<h1 class="mb-2 text-xl font-semibold leading-8 md:mb-0"> <h1 class="mb-2 text-xl font-semibold leading-8 md:mb-0">
${msg("Archived Items")} ${msg("Archived Items")}
</h1> </h1>
@ -222,18 +222,18 @@ export class CrawlsList extends LiteElement {
<div class="mb-3 flex gap-2"> <div class="mb-3 flex gap-2">
${listTypes.map(({ label, itemType, icon }) => { ${listTypes.map(({ label, itemType, icon }) => {
const isSelected = itemType === this.itemType; const isSelected = itemType === this.itemType;
return html` <btrix-button return html` <btrix-navigation-button
variant=${isSelected ? "primary" : "neutral"} .active=${isSelected}
?raised=${isSelected}
aria-selected="${isSelected}" aria-selected="${isSelected}"
href=${`${this.orgBasePath}/items${ href=${`${this.orgBasePath}/items${
itemType ? `/${itemType}` : "" itemType ? `/${itemType}` : ""
}`} }`}
@click=${this.navLink} @click=${this.navLink}
size="small"
> >
${icon ? html`<sl-icon name=${icon}></sl-icon>` : ""} ${icon ? html`<sl-icon name=${icon}></sl-icon>` : ""}
<span>${label}</span> <span>${label}</span>
</btrix-button>`; </btrix-navigation-button>`;
})} })}
</div> </div>
<div <div

View File

@ -383,9 +383,8 @@ export class CollectionDetail extends LiteElement {
${TABS.map((tabName) => { ${TABS.map((tabName) => {
const isSelected = tabName === this.collectionTab; const isSelected = tabName === this.collectionTab;
return html` return html`
<btrix-button <btrix-navigation-button
variant=${isSelected ? "primary" : "neutral"} .active=${isSelected}
?raised=${isSelected}
aria-selected="${isSelected}" aria-selected="${isSelected}"
href=${`${this.orgBasePath}/collections/view/${this.collectionId}/${tabName}`} href=${`${this.orgBasePath}/collections/view/${this.collectionId}/${tabName}`}
@click=${this.navLink} @click=${this.navLink}
@ -394,7 +393,7 @@ export class CollectionDetail extends LiteElement {
name=${this.tabLabels[tabName].icon.name} name=${this.tabLabels[tabName].icon.name}
library=${this.tabLabels[tabName].icon.library} library=${this.tabLabels[tabName].icon.library}
></sl-icon> ></sl-icon>
${this.tabLabels[tabName].text}</btrix-button ${this.tabLabels[tabName].text}</btrix-navigation-button
> >
`; `;
})} })}

View File

@ -365,8 +365,10 @@ export class Org extends LiteElement {
private renderOrgNavBar() { private renderOrgNavBar() {
return html` return html`
<div class="mx-auto box-border w-full max-w-screen-desktop px-3"> <div
<nav class="-ml-3 flex items-end overflow-x-auto"> class="mx-auto box-border w-full max-w-screen-desktop overflow-x-hidden"
>
<nav class="-mx-3 flex items-end overflow-x-auto px-3">
${this.renderNavTab({ ${this.renderNavTab({
tabName: "home", tabName: "home",
label: msg("Overview"), label: msg("Overview"),

View File

@ -159,17 +159,15 @@ export class OrgSettings extends LiteElement {
private renderTab(name: Tab, path: string) { private renderTab(name: Tab, path: string) {
const isActive = name === this.activePanel; const isActive = name === this.activePanel;
return html` return html`
<a <btrix-navigation-button
slot="nav" slot="nav"
href=${`${this.orgBasePath}/${path}`} href=${`${this.orgBasePath}/${path}`}
class="${isActive .active=${isActive}
? "text-blue-600 bg-blue-50 shadow-sm shadow-blue-800/20"
: "text-neutral-600 hover:bg-neutral-50"} mb-2 block rounded-sm p-2 font-medium transition-all"
@click=${this.navLink} @click=${this.navLink}
aria-selected=${isActive} aria-selected=${isActive}
> >
${this.tabLabels[name]} ${this.tabLabels[name]}
</a> </btrix-navigation-button>
`; `;
} }

View File

@ -530,17 +530,12 @@ export class WorkflowDetail extends LiteElement {
private renderTab(tabName: Tab, { disabled = false } = {}) { private renderTab(tabName: Tab, { disabled = false } = {}) {
const isActive = tabName === this.activePanel; const isActive = tabName === this.activePanel;
let className = "text-neutral-600 hover:bg-neutral-50";
if (isActive) {
className = "text-blue-600 bg-blue-50 shadow-sm shadow-blue-800/20";
} else if (disabled) {
className = "text-neutral-300 cursor-not-allowed";
}
return html` return html`
<a <btrix-navigation-button
slot="nav" slot="nav"
href=${`${window.location.pathname}#${tabName}`} href=${`${window.location.pathname}#${tabName}`}
class="${className} mb-2 block rounded-sm p-2 font-medium transition-all" .active=${isActive}
.disabled=${disabled}
aria-selected=${isActive} aria-selected=${isActive}
aria-disabled=${disabled} aria-disabled=${disabled}
@click=${(e: MouseEvent) => { @click=${(e: MouseEvent) => {
@ -548,7 +543,7 @@ export class WorkflowDetail extends LiteElement {
}} }}
> >
${this.tabLabels[tabName]} ${this.tabLabels[tabName]}
</a> </btrix-navigation-button>
`; `;
} }