From a6b2ad79b7897dd48b9f94f79c9adc0f4e5d15fb Mon Sep 17 00:00:00 2001 From: Dotta Date: Thu, 20 Aug 2026 12:17:33 -0500 Subject: [PATCH] fix(runner): align devtools tab icons --- .../issue-thread/issue-thread.spec.ts | 9 +++++++ .../issue-thread/src/DevtoolsInspector.tsx | 24 +++++++++---------- .../devtools/issue-thread/src/Icons.tsx | 11 +++++++-- .../issue-thread/src/issue-thread.css | 14 +++++++++-- 4 files changed, 42 insertions(+), 16 deletions(-) diff --git a/packages/paperclip-runner/devtools/issue-thread/issue-thread.spec.ts b/packages/paperclip-runner/devtools/issue-thread/issue-thread.spec.ts index 88f08663eec..7e53e90175d 100644 --- a/packages/paperclip-runner/devtools/issue-thread/issue-thread.spec.ts +++ b/packages/paperclip-runner/devtools/issue-thread/issue-thread.spec.ts @@ -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(); diff --git a/packages/paperclip-runner/devtools/issue-thread/src/DevtoolsInspector.tsx b/packages/paperclip-runner/devtools/issue-thread/src/DevtoolsInspector.tsx index 4d52d20fee1..45e64ce73b7 100644 --- a/packages/paperclip-runner/devtools/issue-thread/src/DevtoolsInspector.tsx +++ b/packages/paperclip-runner/devtools/issue-thread/src/DevtoolsInspector.tsx @@ -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
- {TABS.map(({ id, glyph, label }) => ( - + {TABS.map(({ id, icon, label }) => ( + ))}
{tab === "timeline" ? ( diff --git a/packages/paperclip-runner/devtools/issue-thread/src/Icons.tsx b/packages/paperclip-runner/devtools/issue-thread/src/Icons.tsx index beb11baa2af..2ce971dc737 100644 --- a/packages/paperclip-runner/devtools/issue-thread/src/Icons.tsx +++ b/packages/paperclip-runner/devtools/issue-thread/src/Icons.tsx @@ -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 = { 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 }) { diff --git a/packages/paperclip-runner/devtools/issue-thread/src/issue-thread.css b/packages/paperclip-runner/devtools/issue-thread/src/issue-thread.css index 37a511d112f..10fe90aba9a 100644 --- a/packages/paperclip-runner/devtools/issue-thread/src/issue-thread.css +++ b/packages/paperclip-runner/devtools/issue-thread/src/issue-thread.css @@ -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); }