swarm ui: one review page
The two review tabs, runs and try-out, are one: /review. It is a column of three sections: try a classification and the classifier settings, each a folded bar (the settings' bar says what they are now), then the recent runs, always open. The settings had been pinned under the try-out form; they are now a section of their own. A new Disclosure primitive is the folding bar, a native details wearing the Panel's classes, so the folded and open sections read as the same surface. /review-runs and /review-tryout are gone, with no redirect.
This commit is contained in:
parent
7b1435eaea
commit
a68d73fa74
19 changed files with 223 additions and 45 deletions
47
frontend/packages/swarm-ui/src/ui/disclosure/Disclosure.css
Normal file
47
frontend/packages/swarm-ui/src/ui/disclosure/Disclosure.css
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* A shut disclosure is only its header row, so it has no divider to draw and
|
||||
no body to space; the divider shows once it is open. */
|
||||
.ui-disclosure-summary {
|
||||
cursor: pointer;
|
||||
list-style: none;
|
||||
border-bottom-color: transparent;
|
||||
}
|
||||
.ui-disclosure-summary::-webkit-details-marker {
|
||||
display: none;
|
||||
}
|
||||
.ui-disclosure[open] > .ui-disclosure-summary {
|
||||
border-bottom-color: var(--border);
|
||||
}
|
||||
.ui-disclosure-summary:hover .ui-panel-title {
|
||||
text-decoration: underline;
|
||||
}
|
||||
.ui-disclosure-summary:focus-visible {
|
||||
outline: 2px solid var(--blue);
|
||||
outline-offset: -2px;
|
||||
border-radius: 0.5em;
|
||||
}
|
||||
.ui-disclosure-hint {
|
||||
min-width: 0;
|
||||
overflow: hidden;
|
||||
color: var(--muted);
|
||||
font-size: 0.9em;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
.ui-disclosure-chevron {
|
||||
margin-left: auto;
|
||||
width: 0.55em;
|
||||
height: 0.55em;
|
||||
flex: none;
|
||||
border-right: 2px solid var(--muted);
|
||||
border-bottom: 2px solid var(--muted);
|
||||
transform: rotate(-45deg);
|
||||
transition: transform 0.15s ease;
|
||||
}
|
||||
.ui-disclosure[open] > .ui-disclosure-summary .ui-disclosure-chevron {
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
.ui-disclosure-chevron {
|
||||
transition: none;
|
||||
}
|
||||
}
|
||||
50
frontend/packages/swarm-ui/src/ui/disclosure/Disclosure.tsx
Normal file
50
frontend/packages/swarm-ui/src/ui/disclosure/Disclosure.tsx
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
// <Disclosure> — a Panel that folds: the header row is the control, and the
|
||||
// body shows only while it is open. For a section a page keeps within reach
|
||||
// but that is not the point of the page, such as a form used now and then.
|
||||
// It is a native `<details>`, so the keyboard and assistive tech get the
|
||||
// open/closed state for free, and it wears the Panel's own classes, so a
|
||||
// Disclosure and a Panel on one page read as the same kind of surface.
|
||||
//
|
||||
// Controlled: `open` and `onToggle`, so a page can open it for the user (a
|
||||
// run started, say). The body stays in the DOM while it is shut, so what was
|
||||
// typed into it survives a fold. `hint` is a short line beside the title that
|
||||
// says what is in there without opening it.
|
||||
import type { ComponentChildren } from "preact";
|
||||
import "../panel/Panel.css";
|
||||
import "./Disclosure.css";
|
||||
|
||||
export function Disclosure({
|
||||
title,
|
||||
icon,
|
||||
hint,
|
||||
open,
|
||||
onToggle,
|
||||
children,
|
||||
}: {
|
||||
title: string;
|
||||
icon?: string;
|
||||
hint?: ComponentChildren;
|
||||
open: boolean;
|
||||
onToggle: (open: boolean) => void;
|
||||
children: ComponentChildren;
|
||||
}) {
|
||||
return (
|
||||
<details
|
||||
class="ui-panel ui-disclosure"
|
||||
open={open}
|
||||
onToggle={(e) => onToggle((e.currentTarget as HTMLDetailsElement).open)}
|
||||
>
|
||||
<summary class="ui-panel-header ui-disclosure-summary">
|
||||
{icon ? (
|
||||
<span class="ui-panel-icon" aria-hidden="true">
|
||||
{icon}
|
||||
</span>
|
||||
) : null}
|
||||
<h2 class="ui-panel-title">{title}</h2>
|
||||
{hint ? <span class="ui-disclosure-hint">{hint}</span> : null}
|
||||
<span class="ui-disclosure-chevron" aria-hidden="true" />
|
||||
</summary>
|
||||
<div class="ui-panel-body">{children}</div>
|
||||
</details>
|
||||
);
|
||||
}
|
||||
Loading…
Reference in a new issue