feat(ui): split ActivityBarItem into its glyph and avatar arms (RIG-3738) - #1202
Merged
trunk-io[bot] merged 1 commit intoSep 13, 2026
Conversation
This was referenced Sep 13, 2026
rigel-mintaka
added this pull request to stack #1200
September 13, 2026 02:04
rigel-mintaka
marked this pull request as ready for review
September 13, 2026 02:04
|
Compass engineering docs preview: https://compass-ux-3738-activitybar.compass-eng-docs.pages.dev Deployed from |
mattwilkinsonn
approved these changes
Sep 13, 2026
…738) `ActivityBarItem.icon: string` carried two unrelated things: a fixed chrome symbol on the four static tabs, and a person's initial on the fleet tabs. The name fit neither, and `agentId`/`unreachable` sat on the shared interface though only fleet tabs ever have them. The item now splits at the item, not the field: `GlyphTabItem` carries `name: GlyphName` and renders `<Glyph/>`; `AvatarTabItem` carries `letter` plus the `agentId` and `unreachable` that only it uses. A field-level union was rejected — it keeps a field called `icon` whose value is sometimes a person's initial. The union, the constructors, the render branch and the CSS land together because they must: the activity-bar loop reads both `tab.icon` and `tab.agentId` off the un-narrowed item, so landing the type without the render branch is a strict-mode error and leaves a red commit mid-stack. Narrowing removed a non-null assertion in `AgentUnreachable` — its `agentId` is now required by the type rather than asserted at the use site. `store.ts` is unchanged: `rightTabGroups` holds a genuinely mixed list, so the union is already the right type there. The glyph box is pinned to a whole-pixel offset. An 11px box flex-centered in the tab's 32px content box lands at 10.5px, which smears every 1px `crispEdges` cell across two device pixels; whole-integer margins that fill the axis exactly leave no free space for centering to halve. The SVG is also seated at the box's top edge: an inline-level replaced box rides the text baseline, so without that it renders 2px below the box the margins just placed. `state-dot.css` carries the same rule for the same reason. Measured in Chromium at dpr 1 and 2: the glyph lands at (11, 11) with no overflow; flex centering would put the box at 11.5px, and without the seating rule the glyph sat at y=13. `bridge-colheads.png` is recaptured here rather than with the rest of the baselines, because this is the commit that repaints those pixels. Its clip is computed from the column-head boxes and runs 1050px wide, so it overlaps the activity bar; at 855x41 the 0.001 diff-pixel RATIO allows about 35 pixels and the four glyphs change 99. The full-page captures contain the same changed pixels but pass, their delta swamped by a budget proportional to mostly unchanged area — so they are recaptured later, with the rest. This surface had no tests. It now covers both render arms, the StateDot's presence and absence, the constructors, and the margin arithmetic the whole-pixel offset depends on. Ref: RIG-3738, RIG-3603. Design: docs/designs/ui/compass-glyph-primitives/design.md (DL-367). Co-authored-by: Matt Wilkinson <matt@rigel.build>
rigel-mintaka
force-pushed
the
compass-ux/3738-activitybar-union
branch
from
September 13, 2026 22:06
15ba631 to
e433981
Compare
|
This pull request was merged into |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR is part of a stack containing 5 PRs:
mainActivityBarItem.icon: stringcarried two unrelated things: a fixed chromesymbol on the four static tabs, and a person's initial on the fleet tabs. The
name fit neither, and
agentId/unreachablesat on the shared interfacethough only fleet tabs ever have them.
The item now splits at the item, not the field:
GlyphTabItemcarriesname: GlyphNameand renders<Glyph/>;AvatarTabItemcarriesletterplus the
agentIdandunreachablethat only it uses. A field-level unionwas rejected — it keeps a field called
iconwhose value is sometimes aperson's initial.
The union, the constructors, the render branch and the CSS land together
because they must: the activity-bar loop reads both
tab.iconandtab.agentIdoff the un-narrowed item, so landing the type without therender branch is a strict-mode error and leaves a red commit mid-stack.
Narrowing removed a non-null assertion in
AgentUnreachable— itsagentIdis now required by the type rather than asserted at the use site.
store.tsis unchanged:
rightTabGroupsholds a genuinely mixed list, so the union isalready the right type there.
The glyph box is pinned to a whole-pixel offset. An 11px box flex-centered in
the tab's 32px content box lands at 10.5px, which smears every 1px
crispEdgescell across two device pixels; whole-integer margins that fillthe axis exactly leave no free space for centering to halve. The SVG is also seated at the box's top edge: an inline-level
replaced box rides the text baseline, so without that it renders 2px below
the box the margins just placed.
state-dot.csscarries the same rule forthe same reason. Measured in Chromium at dpr 1 and 2: the glyph lands at
(11, 11) with no overflow; flex centering would put the box at 11.5px, and
without the seating rule the glyph sat at y=13.
bridge-colheads.pngis recaptured here rather than with the rest of thebaselines, because this is the commit that repaints those pixels. Its clip is
computed from the column-head boxes and runs 1050px wide, so it overlaps the
activity bar; at 855x41 the 0.001 diff-pixel RATIO allows about 35 pixels and
the four glyphs change 99. The full-page captures contain the same changed
pixels but pass, their delta swamped by a budget proportional to mostly
unchanged area — so they are recaptured later, with the rest.
This surface had no tests. It now covers both render arms, the StateDot's
presence and absence, the constructors, and the margin arithmetic the
whole-pixel offset depends on.
Ref: RIG-3738, RIG-3603. Design: docs/designs/ui/compass-glyph-primitives/design.md (DL-367).
Co-authored-by: Matt Wilkinson matt@rigel.build