mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-26 10:26:26 +01:00
fix(runner): align devtools tab icons
This commit is contained in:
1 parent
04b1aa2ac9
commit
a6b2ad79b7
4 files changed
+42
-16
No files matched your search
@@ -722,6 +722,15 @@ test.describe("Capability clean-room chat", () => {
|
||||
const tabs = panel.getByRole("tab");
|
||||
await expect(tabs.first()).toHaveText(/Evidence/);
|
||||
await expect(tabs.nth(1)).toHaveText(/Timeline/);
|
||||
await expect(panel.locator(".pit-devtools-tabs .pit-icon")).toHaveCount(8);
|
||||
const centerOffsets = await tabs.evaluateAll((elements) => elements.map((element) => {
|
||||
const icon = element.querySelector(".pit-tab-glyph")?.getBoundingClientRect();
|
||||
const label = element.querySelector(".pit-tab-glyph + span")?.getBoundingClientRect();
|
||||
return icon === undefined || label === undefined
|
||||
? Number.POSITIVE_INFINITY
|
||||
: Math.abs((icon.top + icon.height / 2) - (label.top + label.height / 2));
|
||||
}));
|
||||
expect(Math.max(...centerOffsets)).toBeLessThanOrEqual(1);
|
||||
await expect(tabs.first()).toHaveAttribute("aria-selected", "true");
|
||||
await expect(panel.locator("#evidence-turn-selector")).toBeVisible();
|
||||
await panel.getByRole("tab", { name: /Timeline/ }).click();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
|
||||
import type { CapabilityDevtoolsSnapshot } from "../../../src/devtools";
|
||||
import { Icon } from "./Icons";
|
||||
import { Icon, type IconName } from "./Icons";
|
||||
|
||||
export type CapabilityDevtoolsTab = "evidence" | "timeline" | "state" | "diff" | "documents" | "protocol" | "runtime" | "authority";
|
||||
type Json = null | boolean | number | string | Json[] | { [key: string]: Json };
|
||||
@@ -55,15 +55,15 @@ function download(snapshot: CapabilityDevtoolsSnapshot) {
|
||||
URL.revokeObjectURL(url);
|
||||
}
|
||||
|
||||
const TABS: ReadonlyArray<{ id: CapabilityDevtoolsTab; glyph: string; label: string }> = [
|
||||
{ id: "evidence", glyph: "◎", label: "Evidence" },
|
||||
{ id: "timeline", glyph: "◫", label: "Timeline" },
|
||||
{ id: "state", glyph: "{}", label: "State" },
|
||||
{ id: "diff", glyph: "±", label: "Diff" },
|
||||
{ id: "documents", glyph: "▤", label: "Documents" },
|
||||
{ id: "protocol", glyph: "⇄", label: "Protocol" },
|
||||
{ id: "runtime", glyph: ">_", label: "Runtime" },
|
||||
{ id: "authority", glyph: "◇", label: "Authority" },
|
||||
const TABS: ReadonlyArray<{ id: CapabilityDevtoolsTab; icon: IconName; label: string }> = [
|
||||
{ id: "evidence", icon: "evidence", label: "Evidence" },
|
||||
{ id: "timeline", icon: "timeline", label: "Timeline" },
|
||||
{ id: "state", icon: "state", label: "State" },
|
||||
{ id: "diff", icon: "diff", label: "Diff" },
|
||||
{ id: "documents", icon: "documents", label: "Documents" },
|
||||
{ id: "protocol", icon: "protocol", label: "Protocol" },
|
||||
{ id: "runtime", icon: "terminal", label: "Runtime" },
|
||||
{ id: "authority", icon: "authority", label: "Authority" },
|
||||
];
|
||||
|
||||
function documentsOf(state: Json): Array<{ id: string; key: string; title: string; revisions: Array<{ id: string; revision: number; body: string; changeSummary: string | null; createdAt: string }> }> {
|
||||
@@ -124,8 +124,8 @@ export function DevtoolsInspector({ snapshot, onFork, tab, onTabChange }: { snap
|
||||
<button className="pit-button" type="button" onClick={() => onFork(revision)}><Icon name="branch" /> Fork r{revision}</button>
|
||||
</div>
|
||||
<div className="pit-devtools-tabs" role="tablist" aria-label="Developer tools">
|
||||
{TABS.map(({ id, glyph, label }) => (
|
||||
<button key={id} type="button" role="tab" aria-selected={tab === id} className="pit-tab" onClick={() => onTabChange(id)}><span className="pit-tab-glyph" aria-hidden="true">{glyph}</span>{label}</button>
|
||||
{TABS.map(({ id, icon, label }) => (
|
||||
<button key={id} type="button" role="tab" aria-selected={tab === id} className="pit-tab" onClick={() => onTabChange(id)}><span className="pit-tab-glyph"><Icon name={icon} /></span><span>{label}</span></button>
|
||||
))}
|
||||
</div>
|
||||
{tab === "timeline" ? (
|
||||
|
||||
@@ -1,19 +1,26 @@
|
||||
export type IconName =
|
||||
| "activity" | "branch" | "close" | "download" | "evidence" | "pause"
|
||||
| "play" | "reset" | "spark" | "stop" | "terminal";
|
||||
| "activity" | "authority" | "branch" | "close" | "diff" | "documents"
|
||||
| "download" | "evidence" | "pause" | "play" | "protocol" | "reset"
|
||||
| "spark" | "state" | "stop" | "terminal" | "timeline";
|
||||
|
||||
const PATHS: Record<IconName, string> = {
|
||||
activity: "M3 12h3l2-6 4 12 3-9 2 5h4",
|
||||
authority: "M12 3l7 4v5c0 4.6-2.8 7.6-7 9-4.2-1.4-7-4.4-7-9V7zM9 12l2 2 4-4",
|
||||
branch: "M6 3v12a3 3 0 0 0 3 3h6M15 18l-3-3m3 3-3 3M6 7h6a3 3 0 0 0 3-3V3",
|
||||
close: "M5 5l14 14M19 5 5 19",
|
||||
diff: "M8 5v14M4 9h8M17 7v10M14 12h6",
|
||||
documents: "M6 3h9l3 3v15H6zM15 3v4h4M9 11h6M9 15h6",
|
||||
download: "M12 3v12m-5-5 5 5 5-5M5 21h14",
|
||||
evidence: "M4 5h16v14H4zM8 9h8M8 13h5",
|
||||
pause: "M8 5v14M16 5v14",
|
||||
play: "M8 5v14l11-7z",
|
||||
protocol: "M4 8h14m-3-3 3 3-3 3M20 16H6m3-3-3 3 3 3",
|
||||
reset: "M5 8a8 8 0 1 1-1 7M5 8V3m0 5h5",
|
||||
spark: "M12 2l1.7 5.3L19 9l-5.3 1.7L12 16l-1.7-5.3L5 9l5.3-1.7zM19 16l.8 2.2L22 19l-2.2.8L19 22l-.8-2.2L16 19l2.2-.8z",
|
||||
state: "M9 4H6a2 2 0 0 0-2 2v3M15 4h3a2 2 0 0 1 2 2v3M9 20H6a2 2 0 0 1-2-2v-3M15 20h3a2 2 0 0 0 2-2v-3M9 9h6v6H9z",
|
||||
stop: "M7 7h10v10H7z",
|
||||
terminal: "M5 7l4 5-4 5m7 0h7",
|
||||
timeline: "M5 5v14M5 8h5M5 13h9M5 18h13",
|
||||
};
|
||||
|
||||
export function Icon({ name }: { name: IconName }) {
|
||||
|
||||
@@ -1824,8 +1824,13 @@ textarea {
|
||||
}
|
||||
|
||||
.pit-tab {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
flex: 0 0 auto;
|
||||
min-height: var(--pit-touch-target);
|
||||
gap: var(--pit-space-1);
|
||||
line-height: 1;
|
||||
gap: var(--pit-space-2);
|
||||
border: 0;
|
||||
border-bottom: var(--pit-space-1) solid transparent;
|
||||
border-radius: 0;
|
||||
@@ -1840,10 +1845,15 @@ textarea {
|
||||
border-bottom-color: var(--pit-accent);
|
||||
background: var(--pit-accent-surface);
|
||||
color: var(--pit-foreground);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.pit-tab-glyph {
|
||||
font-family: var(--pit-font-mono);
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
width: var(--pit-space-4);
|
||||
height: var(--pit-space-4);
|
||||
color: var(--pit-live);
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user