From b3b8b1b9709b48e34a4ec2e920a1b6454a2604e2 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Mon, 3 Aug 2026 20:46:23 +0000 Subject: [PATCH] Replace trace viewer inline styles with Tailwind Signed-off-by: Cursor Agent --- .changeset/shy-frogs-juggle.md | 5 + .../new-trace-viewer/components/timeline.tsx | 60 +++--- .../components/trace-viewer-skeleton.tsx | 98 ++++++---- .../src/components/new-trace-viewer/icons.tsx | 8 +- .../components/new-trace-viewer/utils.test.ts | 12 +- .../src/components/new-trace-viewer/utils.ts | 48 ++--- .../trace-viewer/components/map.tsx | 11 +- .../components/trace-viewer/components/ui.tsx | 17 +- .../components/trace-viewer/trace-viewer.tsx | 29 +-- .../src/components/workflow-trace-view.tsx | 174 ++---------------- 10 files changed, 153 insertions(+), 309 deletions(-) create mode 100644 .changeset/shy-frogs-juggle.md diff --git a/.changeset/shy-frogs-juggle.md b/.changeset/shy-frogs-juggle.md new file mode 100644 index 0000000000..1bf0488992 --- /dev/null +++ b/.changeset/shy-frogs-juggle.md @@ -0,0 +1,5 @@ +--- +'@workflow/web-shared': patch +--- + +Replace static trace viewer styles with Tailwind theme utilities. diff --git a/packages/web-shared/src/components/new-trace-viewer/components/timeline.tsx b/packages/web-shared/src/components/new-trace-viewer/components/timeline.tsx index bf53182119..731d523c45 100644 --- a/packages/web-shared/src/components/new-trace-viewer/components/timeline.tsx +++ b/packages/web-shared/src/components/new-trace-viewer/components/timeline.tsx @@ -1,7 +1,7 @@ 'use client'; import { ArrowLeft, ArrowRight } from 'lucide-react'; -import type { CSSProperties, ReactNode } from 'react'; +import type { ReactNode } from 'react'; import { Fragment, memo, @@ -31,7 +31,7 @@ import { computeSpanGaps, computeSpanMarkers, computeSpanSegments, - getResourceColor, + getResourceClassNames, getSpanDurationMs, isSpanErrored, } from '../utils'; @@ -65,11 +65,6 @@ const SEGMENT_CLASSES: Record = { received: 'bg-blue-200 border border-blue-500', }; -const TIMELINE_INSET_STYLE: CSSProperties = { - left: TIMELINE_PADDING_PX, - right: TIMELINE_PADDING_PX, -}; - const STRIPED_SEGMENT_STATUSES: ReadonlySet = new Set([ 'pending', 'running', @@ -263,18 +258,18 @@ function BoundaryArrow({ } function PlainBar({ - bg, - border, + className, label, }: { - bg: string; - border: string; + className: string; label: string | null; }): ReactNode { return (
{label ? : null}
@@ -355,14 +350,13 @@ function SegmentBar({
{STRIPED_SEGMENT_STATUSES.has(seg.status) ? ( @@ -460,13 +454,10 @@ const TimelineBar = memo(function TimelineBar({ markers.length > 0 || offscreen.left !== null || offscreen.right !== null; const isErrored = isSpanErrored(span); - const colors = getResourceColor(span.resource); - const fallbackBg = isErrored - ? (colors.errorBg ?? 'var(--ds-red-200)') - : colors.bg; - const fallbackBorder = isErrored - ? (colors.errorBorder ?? 'var(--ds-red-500)') - : colors.border; + const colors = getResourceClassNames(span.resource); + const fallbackClassName = isErrored + ? (colors.errorClassName ?? 'border-red-500 bg-red-200') + : colors.className; const totalLabel = formatDurationPrecise(totalDurationMs); const showTotalLabel = @@ -489,7 +480,7 @@ const TimelineBar = memo(function TimelineBar({ )} onClick={handleClick} > -
+
) : geometry.mode.kind === 'tiny' ? (
) : segments.length > 0 ? ( ) : ( )} @@ -615,10 +604,9 @@ const DeltaMeasureLine = memo(function DeltaMeasureLine({ return ( <>
@@ -784,8 +772,7 @@ export function Timeline({ >
{markers.map((marker) => // Skip the "0s" origin marker since the left edge already implies it. @@ -799,10 +786,7 @@ export function Timeline({ )}
{hover != null && ( -
+
{gapMeasurements.map((gap) => (
diff --git a/packages/web-shared/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx b/packages/web-shared/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx index 7977ace4ae..fa06154a2a 100644 --- a/packages/web-shared/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx +++ b/packages/web-shared/src/components/new-trace-viewer/components/trace-viewer-skeleton.tsx @@ -1,19 +1,62 @@ import { Skeleton } from '../../ui/skeleton'; -import { DEFAULT_START_PX, paneColTemplate } from './pane-constants'; -// Mirrors SplitPane's initial column template so the skeleton lines up with -// the real viewer's first paint. -const COL_TEMPLATE = paneColTemplate(DEFAULT_START_PX); - -const ROWS: { id: string; name: number; off: number; bar: number }[] = [ - { id: 'r0', name: 62, off: 0, bar: 72 }, - { id: 'r1', name: 78, off: 6, bar: 48 }, - { id: 'r2', name: 50, off: 10, bar: 55 }, - { id: 'r3', name: 84, off: 18, bar: 30 }, - { id: 'r4', name: 45, off: 18, bar: 42 }, - { id: 'r5', name: 66, off: 34, bar: 38 }, - { id: 'r6', name: 55, off: 41, bar: 25 }, - { id: 'r7', name: 40, off: 50, bar: 30 }, +const ROWS = [ + { + id: 'r0', + nameClassName: 'w-[62%]', + offsetClassName: 'left-0', + barClassName: 'w-[72%]', + topClassName: 'top-0', + }, + { + id: 'r1', + nameClassName: 'w-[78%]', + offsetClassName: 'left-[6%]', + barClassName: 'w-[48%]', + topClassName: 'top-[3.5px]', + }, + { + id: 'r2', + nameClassName: 'w-1/2', + offsetClassName: 'left-[10%]', + barClassName: 'w-[55%]', + topClassName: 'top-[7px]', + }, + { + id: 'r3', + nameClassName: 'w-[84%]', + offsetClassName: 'left-[18%]', + barClassName: 'w-[30%]', + topClassName: 'top-[10.5px]', + }, + { + id: 'r4', + nameClassName: 'w-[45%]', + offsetClassName: 'left-[18%]', + barClassName: 'w-[42%]', + topClassName: 'top-[14px]', + }, + { + id: 'r5', + nameClassName: 'w-[66%]', + offsetClassName: 'left-[34%]', + barClassName: 'w-[38%]', + topClassName: 'top-[17.5px]', + }, + { + id: 'r6', + nameClassName: 'w-[55%]', + offsetClassName: 'left-[41%]', + barClassName: 'w-1/4', + topClassName: 'top-[21px]', + }, + { + id: 'r7', + nameClassName: 'w-2/5', + offsetClassName: 'left-1/2', + barClassName: 'w-[30%]', + topClassName: 'top-[24.5px]', + }, ]; const HEADER_MARKERS = ['m0', 'm1', 'm2', 'm3']; @@ -36,25 +79,17 @@ export function TraceViewerSkeleton() { {/* Minimap strip: thin density lines tracing the same shape as the bars */}
- {ROWS.map((row, index) => ( + {ROWS.map((row) => ( ))}
{/* Header row: search header | divider | timeline header */} -
+
@@ -70,10 +105,7 @@ export function TraceViewerSkeleton() {
{/* Content row: event list | gutter | timeline */} -
+
{/* Sidebar event rows */}
    @@ -81,10 +113,7 @@ export function TraceViewerSkeleton() {
  • - +
  • @@ -101,8 +130,7 @@ export function TraceViewerSkeleton() {
    diff --git a/packages/web-shared/src/components/new-trace-viewer/icons.tsx b/packages/web-shared/src/components/new-trace-viewer/icons.tsx index 24a031d285..18ee467f9e 100644 --- a/packages/web-shared/src/components/new-trace-viewer/icons.tsx +++ b/packages/web-shared/src/components/new-trace-viewer/icons.tsx @@ -1,10 +1,10 @@ const WorkflowIcon = () => { return (
    0 ? mapWidth : '100%', - height: MAP_HEIGHT, }} >
    0 ? thumbWidth : `calc(100% - ${TIMELINE_PADDING * 2}px)`, - top: 2, - height: MAP_HEIGHT - 4, }} />
    diff --git a/packages/web-shared/src/components/trace-viewer/components/ui.tsx b/packages/web-shared/src/components/trace-viewer/components/ui.tsx index 204b265c2b..44fe3d45d9 100644 --- a/packages/web-shared/src/components/trace-viewer/components/ui.tsx +++ b/packages/web-shared/src/components/trace-viewer/components/ui.tsx @@ -4,10 +4,9 @@ import { clsx } from 'clsx'; import type { AnchorHTMLAttributes, ReactNode } from 'react'; import styles from '../trace-viewer.module.css'; -// Color token mapping helper -const colorTokenMap: Record = { - 'gray-700': 'var(--ds-gray-700)', - 'gray-900': 'var(--ds-gray-900)', +const colorClassNameMap: Partial> = { + 'gray-700': 'text-gray-700', + 'gray-900': 'text-gray-900', }; export function IconCross({ @@ -17,14 +16,15 @@ export function IconCross({ size?: number; color?: string; }): ReactNode { - const style = { color: colorTokenMap[color] || color } as const; + const colorClassName = colorClassNameMap[color]; return ( Cross @@ -67,14 +67,15 @@ export function IconExternalSmall({ size?: number; color?: string; }): ReactNode { - const style = { color: colorTokenMap[color] || color } as const; + const colorClassName = colorClassNameMap[color]; return ( External Small diff --git a/packages/web-shared/src/components/trace-viewer/trace-viewer.tsx b/packages/web-shared/src/components/trace-viewer/trace-viewer.tsx index 9825b4bbba..89c16e0fc8 100644 --- a/packages/web-shared/src/components/trace-viewer/trace-viewer.tsx +++ b/packages/web-shared/src/components/trace-viewer/trace-viewer.tsx @@ -456,12 +456,10 @@ export function TraceViewerTimeline({
    ); @@ -569,16 +557,13 @@ export function TraceViewerPanel({ return (
    -
    +
    {menu.spanName}
    {items.map((item) => ( @@ -1072,67 +984,17 @@ export const WorkflowTraceViewer = ({ aria-label="Next span" onClick={handleSelectNextSpan} disabled={!canSelectNextSpan} - style={{ - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - marginLeft: 2, - width: 24, - height: 24, - padding: 0, - borderRadius: 6, - border: 'none', - background: 'transparent', - color: 'var(--ds-gray-700)', - cursor: canSelectNextSpan ? 'pointer' : 'not-allowed', - opacity: canSelectNextSpan ? 1 : 0.45, - flexShrink: 0, - transition: 'background 0.15s', - }} - onMouseEnter={(e) => { - if (!canSelectNextSpan) return; - e.currentTarget.style.background = 'var(--ds-gray-alpha-100)'; - }} - onMouseLeave={(e) => { - e.currentTarget.style.background = 'transparent'; - }} + className="ml-0.5 flex size-6 flex-shrink-0 cursor-pointer items-center justify-center rounded-md !border-none !bg-transparent p-0 text-gray-700 transition-colors hover:!bg-gray-alpha-100 disabled:cursor-not-allowed disabled:opacity-45" >
    -
    +