Allow QA view to be larger than viewport height if necessary (#1790)

Closes #1789

### Changes
- Converts stylesheet in js to css now that it doesn't use any runtime
values
- Removes fixed height on QA container, and instead sets a min height
- Applies `contain: size` to page list & tab content so they don't cause
the QA container to stretch
- Also updates instances of `h-{n} w-{n}` to `size-{n}`
- Removes leftover outlines on text and resource comparison areas from
early QA prototyping
This commit is contained in:
Emma Segal-Grossman 2024-05-14 17:26:06 -04:00 committed by GitHub
parent ed189efef4
commit d6f2fee279
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
18 changed files with 123 additions and 80 deletions

View File

@ -0,0 +1,27 @@
const plugin = require("tailwindcss/plugin");
module.exports = plugin(
({ matchUtilities, theme }) => {
matchUtilities(
{
contain: (value) => ({
contain: value,
}),
},
{ values: theme("contain") },
);
},
{
theme: {
contain: {
none: "none",
strict: "strict",
content: "content",
size: "size",
"inline-size": "inline-size",
layout: "layout",
style: "style",
paint: "paint",
},
},
},
);

View File

@ -0,0 +1,14 @@
const plugin = require("tailwindcss/plugin");
module.exports = plugin(function ({ addUtilities }) {
addUtilities({
".content-auto": {
"content-visibility": "auto",
},
".content-hidden": {
"content-visibility": "hidden",
},
".content-visible": {
"content-visibility": "visible",
},
});
});

View File

@ -18,7 +18,7 @@ export class BetaIcon extends TailwindElement {
<sl-icon
name="stars"
label="Beta"
class="h-4 w-4 text-theme-green"
class="size-4 text-theme-green"
></sl-icon>
</sl-tooltip>`;
}
@ -44,7 +44,7 @@ export class BetaBadge extends TailwindElement {
<sl-icon
name="stars"
label="Beta feature"
class="h-4 w-4 align-middle"
class="size-4 align-middle"
></sl-icon
>&nbsp;${msg("Beta")}
</span>

View File

@ -161,7 +161,7 @@ export class FileUploader extends TailwindElement {
</main>
</section>
</div>
<input class="invisible h-0 w-0" type="submit" />
<input class="invisible size-0" type="submit" />
</form>
<div slot="footer" class="flex justify-between">
<sl-button

View File

@ -78,7 +78,7 @@ export class NewBrowserProfileDialog extends LiteElement {
(this.crawlerChannel = e.detail.value!)}
></btrix-select-crawler>
</div>
<input class="invisible h-0 w-0" type="submit" />
<input class="invisible size-0" type="submit" />
</form>
<div slot="footer" class="flex justify-between">
<sl-button

View File

@ -95,7 +95,7 @@ export class CollectionMetadataDialog extends LiteElement {
`,
)}
<input class="invisible h-0 w-0" type="submit" />
<input class="invisible size-0" type="submit" />
</form>
<div slot="footer" class="flex items-center justify-end gap-3">
<sl-button

View File

@ -9,7 +9,7 @@ import { cached } from "@/utils/weakCache";
export const iconFor = cached(
(severity: Severity | ReviewStatus, classList?: string) => {
const baseClasses = tw`h-4 w-4`;
const baseClasses = tw`size-4`;
switch (severity) {
// Severity
case "severe":

View File

@ -96,7 +96,7 @@ export const pageDetails = (page: ArchivedItemQAPage) =>
<div class="mb-3 flex text-xs leading-4">
<sl-icon
name="chat-square-text-fill"
class="mr-2 h-4 w-4 flex-none text-blue-600"
class="mr-2 size-4 flex-none text-blue-600"
></sl-icon>
${page.notes[page.notes.length - 1].text}
</div>`

View File

@ -114,7 +114,7 @@ export class QaPageGroup extends TailwindElement {
<div
class="${this.expanded
? "h-auto"
: "h-0"} overflow-hidden [contain:content] [content-visibility:auto]"
: "h-0"} overflow-hidden contain-content content-auto"
${ref(this.contentContainer)}
>
<slot></slot>

View File

@ -186,7 +186,7 @@ export class QaPage extends TailwindElement {
<div
class="contentContainer ${this.selected
? "h-auto"
: "h-0"} overflow-hidden [contain:content] [content-visibility:auto]"
: "h-0"} overflow-hidden contain-content content-auto"
>
<div
class="z-10 -mt-2 ml-6 mr-2 rounded-b-lg border border-solid border-gray-200 bg-neutral-0 px-4 pb-1 pt-4"

View File

@ -472,7 +472,7 @@ export class ArchivedItemDetail extends TailwindElement {
this.activeTab = section;
}}
><sl-icon
class="h-4 w-4 shrink-0"
class="size-4 shrink-0"
name=${icon}
aria-hidden="true"
library=${iconLibrary}
@ -953,7 +953,7 @@ ${this.crawl?.description}
html` <sl-tooltip content=${msg("Backed up")}>
<sl-icon
name="clouds-fill"
class="mr-2 h-4 w-4 shrink-0 align-text-bottom text-success"
class="mr-2 size-4 shrink-0 align-text-bottom text-success"
></sl-icon>
</sl-tooltip>`,
)}

View File

@ -447,7 +447,7 @@ export class ArchivedItemDetailQA extends TailwindElement {
};
private readonly renderLoadingDetail = () =>
html`<div class="min-w-32"><sl-spinner class="h-4 w-4"></sl-spinner></div>`;
html`<div class="min-w-32"><sl-spinner class="size-4"></sl-spinner></div>`;
private renderAnalysis(qaRuns: QARun[]) {
const isRunning =
@ -611,7 +611,7 @@ export class ArchivedItemDetailQA extends TailwindElement {
(threshold) => html`
<div class="flex items-center gap-2">
<dt
class="h-4 w-4 flex-shrink-0 rounded"
class="size-4 flex-shrink-0 rounded"
style="background-color: ${threshold.cssColor}"
>
<span class="sr-only">${threshold.lowerBoundary}</span>

View File

@ -0,0 +1,52 @@
article > * {
min-height: 0;
}
.qa-grid {
grid-template:
"header"
"pageToolbar"
"tabGroup"
"pageList";
grid-template-columns: 100%;
grid-template-rows: repeat(5, max-content);
}
/* Tailwind 'lg' responsive size */
@media only screen and (min-width: 1024px) {
.qa-grid {
grid-template:
"header header"
"pageToolbar pageList"
"tabGroup pageList";
grid-template-columns: 1fr 35rem;
grid-template-rows: repeat(2, min-content) 1fr;
}
}
.grid--header {
grid-area: header;
}
.grid--pageToolbar {
grid-area: pageToolbar;
}
.grid--tabGroup {
grid-area: tabGroup;
}
.grid--pageList {
grid-area: pageList;
}
sl-image-comparer::part(divider) {
--divider-width: 1rem;
border-left: 1px solid var(--sl-panel-border-color);
border-right: 1px solid var(--sl-panel-border-color);
box-shadow: var(--sl-shadow-large);
}
sl-image-comparer::part(handle) {
background-color: transparent;
}

View File

@ -2,7 +2,7 @@ import { localized, msg, str } from "@lit/localize";
import type { SlRequestCloseEvent, SlTextarea } from "@shoelace-style/shoelace";
import { serialize } from "@shoelace-style/shoelace/dist/utilities/form.js";
import { merge } from "immutable";
import { html, nothing, type PropertyValues } from "lit";
import { html, nothing, unsafeCSS, type PropertyValues } from "lit";
import { customElement, property, query, state } from "lit/decorators.js";
import { cache } from "lit/directives/cache.js";
import { choose } from "lit/directives/choose.js";
@ -12,7 +12,7 @@ import { when } from "lit/directives/when.js";
import { throttle } from "lodash/fp";
import queryString from "query-string";
import { styles } from "./styles";
import stylesheet from "./archived-item-qa.stylesheet.css";
import type * as QATypes from "./types";
import { renderResources } from "./ui/resources";
import { renderScreenshots } from "./ui/screenshots";
@ -48,6 +48,8 @@ import { tw } from "@/utils/tailwind";
const DEFAULT_PAGE_SIZE = 100;
const styles = unsafeCSS(stylesheet);
type PageResource = {
status?: number;
mime?: string;
@ -394,7 +396,7 @@ export class ArchivedItemQA extends TailwindElement {
</h1>
</div>
<article class="qa-grid grid gap-x-6 gap-y-0 snap-start">
<article class="qa-grid min-h-screen grid gap-x-6 gap-y-0 lg:snap-start">
<header
class="grid--header flex flex-wrap items-center justify-between gap-1 border-b py-2"
>
@ -563,7 +565,7 @@ export class ArchivedItemQA extends TailwindElement {
${msg("Pages")}
</h3>
<btrix-qa-page-list
class="flex flex-col"
class="flex flex-col lg:contain-size"
.qaRunId=${this.qaRunId}
.itemPageId=${this.itemPageId}
.pages=${this.pages}
@ -935,7 +937,7 @@ export class ArchivedItemQA extends TailwindElement {
return html`
<section
aria-labelledby="${this.tab}-tab"
class="flex-1 overflow-hidden lg:pb-3"
class="flex-1 overflow-hidden lg:pb-3 lg:contain-size"
>
${cache(choosePanel())}
</section>

View File

@ -1,59 +0,0 @@
import { css } from "lit";
export const styles = css`
article > * {
min-height: 0;
}
.qa-grid {
grid-template:
"header"
"pageToolbar"
"tabGroup"
"pageList";
grid-template-columns: 100%;
grid-template-rows: repeat(5, max-content);
}
/* Tailwind 'lg' responsive size */
@media only screen and (min-width: 1024px) {
.qa-grid {
/* TODO calculate screen space instead of hardcoding */
height: 100vh;
/* overflow: hidden; */
grid-template:
"header header"
"pageToolbar pageList"
"tabGroup pageList";
grid-template-columns: 1fr 35rem;
grid-template-rows: repeat(2, min-content) 1fr;
}
}
.grid--header {
grid-area: header;
}
.grid--pageToolbar {
grid-area: pageToolbar;
}
.grid--tabGroup {
grid-area: tabGroup;
}
.grid--pageList {
grid-area: pageList;
}
sl-image-comparer::part(divider) {
--divider-width: 1rem;
border-left: 1px solid var(--sl-panel-border-color);
border-right: 1px solid var(--sl-panel-border-color);
box-shadow: var(--sl-shadow-large);
}
sl-image-comparer::part(handle) {
background-color: transparent;
}
`;

View File

@ -100,7 +100,7 @@ export function renderResources(crawlData: ReplayData, qaData: ReplayData) {
// </div>`;
return html`
<div class="flex h-full flex-col outline">
<div class="flex h-full flex-col">
<div class="flex-1 overflow-auto overscroll-contain">
${crawlData?.resources && qaData?.resources
? renderDiff(crawlData.resources, qaData.resources)

View File

@ -72,7 +72,7 @@ export function renderText(crawlData: ReplayData, qaData: ReplayData) {
</div>`;
return html`
<div class=${tw`flex h-full flex-col outline`}>
<div class=${tw`flex h-full flex-col`}>
<div class=${tw`mb-2 flex font-semibold`}>
<h3 id="crawlTextHeading" class=${tw`flex-1`}>
${msg("Text extracted during crawl")}

View File

@ -1,5 +1,8 @@
const { tailwindTransform } = require("postcss-lit");
const containPlugin = require("./plugins/contain");
const contentVisibilityPlugin = require("./plugins/content-visibility");
const PRIMARY_COLOR = "#0891B2";
const primary = {
@ -158,5 +161,9 @@ module.exports = {
include: ["./src/**/*.{ts,js}"],
},
plugins: [require("@tailwindcss/container-queries")],
plugins: [
require("@tailwindcss/container-queries"),
containPlugin,
contentVisibilityPlugin,
],
};