feat(ui): show a user icon in the profile menu trigger - #46
Open
a-effort wants to merge 1 commit into
Open
Conversation
The header profile trigger rendered an empty rounded square, since no
avatar data exists to put in it. Fill it with a lucide UserRound behind
an Avatar primitive, so the frame that already reserved the space reads
as a person rather than a gap.
Colors come from the muted / muted-foreground tokens, which index.css
redefines under .dark, so light and dark need no conditional logic here
and no dark: variants. A test asserts the fallback carries no dark:
prefix, to keep a future hardcoded override from creeping back in.
UserAvatar owns the fallback ladder rather than HeaderProfileMenu
inlining an icon, and takes an optional src. The API exposes no avatar
field today, so that leg is unused — but Radix Avatar is what handles
the image load/error swap, which is the part that gets ugly to retrofit
once profile pictures land. The primitive comes from the radix-ui
umbrella package, already a dependency, so this adds none.
Sizing stays size-6 rounded-md with overflow-hidden: an image later
fills the same box and the header geometry does not move. The trigger
button already carries aria-label={displayName}, so the icon is
decorative and adds no second accessible name and no new i18n strings.
Signed-off-by: Anna Effort <anna.effort@ibm.com>
a-effort
requested review from
gandhipratik203 and
gcgoncalves
and
a lite review from Copilot
and removed request for
Copilot
August 19, 2026 04:26
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.
What
Add icon to user settings dropdown:


size-6box + chevronTheming
Colors come from the
muted/muted-foregroundtokens, whichindex.cssredefines under.dark. Lucide icons stroke withcurrentColor, so light and dark need no conditional logic and nodark:variants. They use the same pairing the neighboring GitHub and docs icons in the header already use.A test asserts the fallback className contains no
dark:prefix, so a future hardcoded override trips a test instead of shipping.Structuring for profile pictures later
UserAvatarowns the fallback ladder rather thanHeaderProfileMenuinlining an icon, and takes an optionalsrc.Worth knowing: there is no avatar/picture field anywhere in the API... checked
openapi.json,src/generated/types/contextForge.tsandsrc/types/user.ts. So, profile pictures need a backend field first; this isn't a frontend-only follow-up. The seam is here because Radix Avatar is what handles the image load/error swap, which is the awkward part to retrofit later. An initials leg (fromfull_name) is the middle step that needs no backend at all.The primitive comes from the
radix-uiumbrella package, already a dependency (no new dependencies added). Sizing stayssize-6 rounded-mdwithoverflow-hidden, so an image later fills the same box and the header geometry doesn't move.Accessibility / i18n
The trigger button already carries
aria-label={displayName}, so the icon is decorative:aria-hidden, no second accessible name, and no new i18n strings.Tests
avatar.test.tsx,user-avatar.test.tsxHeaderProfileMenu.test.tsxNote
UserAvatar'ssrcpath can't be exercised in jsdom: Radix builds an off-DOMImageand waits forload, which jsdom never fires, so the<img>never mounts. The test asserts what is meaningful there: passing asrcneither crashes nor blanks the frame and says why inline. Image rendering needs an e2e check once the backend field exists.Based on
fix/vendor-chunk-cycle(#45)... do not merge this first.This change shifts chunk composition enough to trip a latent rollup chunk cycle that #45 fixes. Without #45 the app serves a blank page (
Cannot set properties of undefined (setting 'Activity')). I verified both directions: this commit without #45 fails a module-eval smoke test, with #45 it passes.No CI job runs
npm run build, and E2E drives the Vite dev server wheremanualChunksdoesn't apply, so this PR goes green either way. The ordering has to be enforced by hand. Retarget tomainonce #45 merges; no rebase needed.