From 151ff557351c64d539cd097389bffab704d6f8de Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 18 May 2026 23:24:07 +0000 Subject: [PATCH] feat(ui): D.5d migrate ResultsSectionHeader to SectionHeader primitive MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PR 9 of 16 in the UI consistency overhaul. Promotes every section header in AnalysisResults to the SectionHeader primitive via a single internal change — the local ResultsSectionHeader helper is now a thin wrapper that delegates to . Affected sections (every ResultsSectionHeader call site): - Interpretation panel (:1024) - Idle / "waiting on interpretation" panel (:1214) - Style Profile (:1227) - Audio Observations (:1369) - Project Setup (:1436) - Track Layout (:1466) - Routing Blueprint (:1529) - Warp Guide (:1601) - (second warp section :1643) - Arrangement (:1689) - Sonic Elements & Reconstruction (:1891) - Mix & Master Chain (already migrated in D.5b but still uses the helper) - Patch Framework (already migrated in D.5c but still uses the helper) What changes visually: - The static accent dot in each section header () becomes the pulsing `.led-indicator--active` glyph. This is the same LED affordance used on every DeviceRack title strip in PRs #66-#74, so all section landmarks now share one vocabulary. - The outer underline + flex layout is preserved verbatim (border-b border-border pb-2 + flex items-center justify-between gap-3), so spacing doesn't shift. What's preserved verbatim: - The ResultsSectionHeader prop API (title, rightSlot, titleRole, titleClassName, className) — every existing call site continues to work without changes. - All

elements with data-text-role={titleRole} — analysisResultsUi.test.ts:465-466 assertions (data-text-role="section-title" + ">Mix & Master Chain

) continue to match. - data-text-role="item-title" assertions inside each section. - All data-testid hooks (interpretation-panel, interpretation- warnings, mix-chain-applied-progress, patches-applied-progress, measurements-section, etc.). - The `border-b border-border pb-2` outer container class so spacing is identical. Deferred (not in D.5d scope): - Per-section DeviceRack wraps were considered (per the plan's "Section wrappers → " item) but would have created duplicate title strips wherever a section also has a ResultsSectionHeader — the rack title strip + the SectionHeader h2 would both render section identity. Each affected section would need a custom "drop the SectionHeader, rely only on the rack name" call which doesn't fit a single mechanical change. Save for a focused follow-up if/when the rack chrome is wanted on these surfaces. Verified: lint clean, 628/628 unit tests passing, build clean (AnalysisResults chunk 254 KB / 63 KB gz — marginally smaller than PR 8 due to less inline JSX in the section header). https://claude.ai/code/session_01WNtYcWXwn4mVnnjxqT7uAe --- apps/ui/src/components/AnalysisResults.tsx | 38 +++++++++++++--------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/apps/ui/src/components/AnalysisResults.tsx b/apps/ui/src/components/AnalysisResults.tsx index e6c46f81..5d31ec6e 100644 --- a/apps/ui/src/components/AnalysisResults.tsx +++ b/apps/ui/src/components/AnalysisResults.tsx @@ -321,27 +321,33 @@ interface ResultsSectionHeaderProps { className?: string; } +/** + * Thin wrapper around the SectionHeader primitive — preserves the + * (title, rightSlot, titleRole, titleClassName, className) API the rest of + * AnalysisResults expects while letting the primitive own the actual layout + * + LED indicator + data-text-role propagation. The static accent dot + * (``) is upgraded to the + * pulsing `.led-indicator--active` glyph that every other DeviceRack / + * SectionHeader in the migration uses. + */ function ResultsSectionHeader({ title, - rightSlot = null, + rightSlot, titleRole, - titleClassName = '', - className = '', + titleClassName, + className, }: ResultsSectionHeaderProps) { - const resolvedTitleClassName = titleRole - ? textRoleClassName(titleRole, `flex items-center gap-2 ${titleClassName}`.trim()) - : ['text-sm font-mono uppercase tracking-wider text-text-secondary flex items-center gap-2', titleClassName] - .filter(Boolean) - .join(' '); - return ( -
-

- - {title} -

- {rightSlot ?
{rightSlot}
: null} -
+ ); }