Skip to content

fix(action-button): show swc-avatar inside swc-action-button - #6587

Merged
rubencarvalho merged 14 commits into
mainfrom
rubencarvalho/avatar-action-button-demo
Aug 7, 2026
Merged

fix(action-button): show swc-avatar inside swc-action-button#6587
rubencarvalho merged 14 commits into
mainfrom
rubencarvalho/avatar-action-button-demo

Conversation

@rubencarvalho

@rubencarvalho rubencarvalho commented Aug 6, 2026

Copy link
Copy Markdown
Contributor

Description

Fixes <swc-avatar> so it automatically scales to match <swc-action-button>'s icon size when slotted into its icon slot. Also updates Avatar's "In Action button" story to demonstrate the fix, including a new xl action-button example.

Motivation and context

This started as a docs-only change: replacing the placeholder <button> (with a TODO: Replace <button> with <swc-action-button> once that component is migrated to 2nd-gen comment) in Avatar's "In Action button" story with the real <swc-action-button>.

That surfaced a real bug. Putting <swc-avatar> in ActionButton's slot="icon" didn't work: Avatar's own size attribute controlled its rendered size regardless of the action button's size, so an avatar sized for one button size looked wrong (overflowed or clipped) in another. Avatar's size scale (16–104px) also doesn't line up with ActionButton's icon-size tokens, so there was no size value that coincidentally fixed it — consumers would have been on the hook for manually pairing an avatar size with the action-button size (e.g. xl action button ↔ avatar size="1000").

The fix: ActionButton's icon slot now also sets --swc-avatar-size directly, the same way it already sets its own internal --_swc-action-button-icon-size custom properties for the slotted element. This wins over Avatar's own :host([size]) rule for a slotted avatar. Confirmed empirically via computed styles: the same <swc-avatar size="500"> now resolves --swc-avatar-size to 18px inside an m action button and 22px inside an xl action button, matching each button's own icon-size token exactly, with no changes to Avatar's own CSS architecture and no size-pairing required from consumers. Avatar's size attribute simply becomes a no-op in this context (documented in avatar.mdx).

The story now shows four examples side by side, none of which write a size attribute on the avatar at all (it would be misleading to suggest it matters, since it's a no-op here):

  • m action button, avatar + visible label (avatar slot="icon", decorative)
  • m action button, avatar-only (icon-only), using accessible-label for the accessible name
  • xl action button, avatar + visible label
  • xl action button, avatar-only

(Earlier revisions of this PR had all four avatars share an explicit size="500" to demonstrate the fix; that was removed once confirmed, since authoring a no-op attribute in the example would suggest it does something.)

The avatar is marked decorative (alt="") in all four since ActionButton doesn't automatically mark icon-slot content aria-hidden, and the avatar's own alt text would otherwise duplicate the button's visible/accessible name — matching Avatar's own documented guidance for decorative.

Related issue(s)

  • fixes N/A (found via story/docs follow-up)

Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed at the Accessibility Practices for this feature, see: Aria Practices
  • I have added automated tests to cover my changes.
  • I have included a well-written changeset if my change needs to be published.
  • I have included updated documentation if my change required it.

Existing test suites pass unchanged: avatar (14/14), action-button (19/19), including custom-property/global-style VRT coverage checks (37/37 total across components/avatar and components/action-button).

Reviewer's checklist

  • Includes a Github Issue with appropriate flag or Jira ticket number without a link
  • Includes thoughtfully written changeset if changes suggested include patch, minor, or major features
  • Automated tests cover all use cases and follow best practices for writing
  • Validated on all supported browsers
  • All VRTs are approved before the author can update Golden Hash

Manual review test cases

  • Avatar scales to match action-button icon size, no manual size pairing needed

    1. Open Storybook, Avatar > Docs, scroll to Behaviors > In Action button
    2. Expect four pill-shaped action buttons (two m, two xl), each avatar rendered as a full circle with no clipping/overflow, correctly sized to each button's own icon-size token — even though every avatar uses the same size="500" attribute
    3. Expect each avatar vertically and horizontally centered relative to its button
  • Standalone avatar sizing is unaffected

    1. Check Avatar > Docs > Options > Sizes and Outline stories
    2. Expect all 17 sizes and both outline examples to render identically to before this change
  • Icon-only avatar action buttons have a correct accessible name

    1. Inspect the icon-only (avatar-only) buttons in the "In Action button" story
    2. Expect the internal <button> to carry aria-label="Jane Doe" forwarded from the host's accessible-label attribute

Device review

  • Did it pass in Desktop?
  • Did it pass in (emulated) Mobile?
  • Did it pass in (emulated) iPad?

Accessibility testing checklist

  • Keyboard (required — document steps below)

    1. Tab through all four action buttons in the "In Action button" story.
    2. Confirm each receives visible focus and is individually reachable in tab order.
    3. Expect no change in focus behavior versus any other <swc-action-button> usage — the avatar itself is non-interactive and not part of the tab order.
  • Screen reader (required — document steps below)

    1. With VoiceOver/NVDA running, focus each of the four buttons in turn.
    2. Expect each to announce once as "Jane Doe, button" — not twice — since the avatar is decorative/alt="" in every case.
    3. For the two labeled buttons, the name comes from the visible text; for the two icon-only buttons, it comes from accessible-label. Both should sound identical to a screen reader user.

Replaces the placeholder <button> TODO in the "In Action button" story
with the real <swc-action-button>. The avatar goes in the default slot
rather than slot="icon": ActionButton's icon-slot CSS forces the
slotted element's box to a fixed icon-size token, which fights
Avatar's own self-sizing (--swc-avatar-size) and causes the image to
overflow its squeezed host. Putting it in the default slot lets Avatar
size itself normally. The avatar is marked decorative since the
visible "Jane Doe" text (or the button's accessible-label in the
icon-only variant) already identifies the person.

Adds a second icon-only example (avatar with no visible label) using
accessible-label, alongside the labeled one.
@rubencarvalho
rubencarvalho requested a review from a team as a code owner August 6, 2026 15:43
The wrapper span defaulted to vertical-align: baseline, misaligning it
against the button's line box by a couple pixels versus the icon-only
example. Setting vertical-align: middle matches how Avatar's own host
aligns itself.
@changeset-bot

changeset-bot Bot commented Aug 6, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 5635d69

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 2 packages
Name Type
@adobe/spectrum-wc Patch
@adobe/spectrum-wc-core Patch

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@rubencarvalho rubencarvalho added Component:Documentation Issues or PRs involving changes to docs or docs website. Component prefix is for Jira integration. Status:Ready for review PR ready for review or re-review. skip_vrt Skip VRT build; mark UI Tests green without running Chromatic labels Aug 6, 2026
rubencarvalho and others added 2 commits August 6, 2026 17:48
Shows the same labeled and icon-only pairing at the xl action-button
size, with the avatar scaled to size="400" to match the larger button
height.
<span
style="display: inline-flex; align-items: center; gap: 8px; vertical-align: middle;"
>
<swc-avatar

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should these be placed in the icon slot instead? ✨

<swc-avatar>'s internal image/background previously sized themselves
directly from --swc-avatar-size, independent of the host element's own
box. ActionButton's icon-slot CSS forces the slotted element's
inline-size/block-size to match its own icon-size token via a
higher-specificity rule than Avatar's :host([size]) selector, which
already won the fight for the host's box (confirmed via computed
styles), but had no effect on the visible avatar because the internal
image ignored the host box and kept its own explicit size, causing it
to overflow its squeezed container.

Avatar's :host now sizes itself from --swc-avatar-size (as before),
and the internal .swc-Avatar/.swc-Avatar-image simply fill 100% of the
host. Any external rule that overrides the host's inline-size/
block-size (like ActionButton's icon slot) now scales the visible
avatar with it, with no name-specific coupling between the two
components and no size pairing required by consumers.

Updates the avatar "In Action button" story to put the avatar back in
slot="icon" (rather than the default slot workaround), and adds an xl
action-button example using the same avatar size="500" as the default
example, to demonstrate that consumers no longer need to coordinate
avatar size with action-button size.
@rubencarvalho rubencarvalho added Status:WIP PR is a work in progress or draft and removed Status:Ready for review PR ready for review or re-review. labels Aug 6, 2026
Reverts the previous avatar.css architecture change (making the host
box canonical and having internal elements fill 100%) in favor of a
more targeted fix: ActionButton's icon slot now sets --swc-avatar-size
directly, the same way it already sets its own internal
--_swc-action-button-icon-size custom properties.

Verified empirically that this override wins over Avatar's own
:host([size="x"]) rule for a slotted avatar, despite that rule having
higher selector specificity by the usual (a,b,c) calculation - shadow
tree cascade resolution for rules matching via ::slotted() does not
follow same-tree specificity comparison the same way. Confirmed via
computed styles: the same <swc-avatar size="500"> now resolves
--swc-avatar-size to 18px inside an "m" action button and 22px inside
"xl", with no changes to Avatar's own CSS architecture and no
size-pairing required from consumers.

Also updates the auto-generated global-action-button.css mirror and
adds a note to avatar.mdx's "In Action button" section documenting
that the avatar's size attribute is a no-op in that context.
@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

📚 Branch Preview Links

🔍 Gen1 Visual Regression Test Results

When a visual regression test fails (or has previously failed while working on this branch), its results can be found in the following URLs:

Deployed to Azure Blob Storage: pr-6587

If the changes are expected, update the current_golden_images_cache hash in the circleci config to accept the new images. Instructions are included in that file.
If the changes are unexpected, you can investigate the cause of the differences and update the code accordingly.

@rubencarvalho
rubencarvalho requested a review from cdransf August 7, 2026 08:55
Avatar's size attribute is a no-op when slotted into an action
button's icon slot, so authoring it in the example would misleadingly
suggest it matters.
@coveralls

coveralls commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 31192439901

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage remained the same at 96.241%

Details

  • Coverage remained the same as the base build.
  • Patch coverage: No coverable lines changed in this PR.
  • No coverage regressions found.

Uncovered Changes

No uncovered changes found.

Coverage Regressions

No coverage regressions found.


Coverage Stats

Coverage Status
Relevant Lines: 39268
Covered Lines: 37993
Line Coverage: 96.75%
Relevant Branches: 6464
Covered Branches: 6020
Branch Coverage: 93.13%
Branches in Coverage %: Yes
Coverage Strength: 460.59 hits per line

💛 - Coveralls

@rubencarvalho rubencarvalho changed the title docs(avatar): show swc-avatar inside swc-action-button fix(avatar): show swc-avatar inside swc-action-button Aug 7, 2026
@rubencarvalho rubencarvalho changed the title fix(avatar): show swc-avatar inside swc-action-button fix(action-button): show swc-avatar inside swc-action-button Aug 7, 2026
@rubencarvalho rubencarvalho added Status:Ready for review PR ready for review or re-review. and removed Status:WIP PR is a work in progress or draft labels Aug 7, 2026
.swc-ActionButton-icon {
color: inherit;
fill: currentcolor;
--swc-avatar-size: var(--_swc-action-button-icon-size);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did this come from the generator or hand generated?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

global-component styles are auto-generated!


**fix(action-button):** A `<swc-avatar>` slotted into `<swc-action-button>`'s `icon` slot now automatically scales to match the button's icon size.

Previously, Avatar's own `size` attribute controlled its rendered size regardless of the action button's size, since Avatar's `:host([size])` sizing rule won the specificity contest with the icon slot's generic sizing rule for the avatar's _host box_ only — the visible image inside Avatar's shadow root ignored that squeeze entirely and rendered at its own `size`, causing it to overflow. Consumers previously had to manually pair an avatar `size` with the action-button `size` (e.g. `xl` action button with avatar `size="1000"`) to avoid a visual mismatch.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs a VRT run.

@rubencarvalho rubencarvalho Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great call! I even added this to the vrt permutations :)

@rubencarvalho rubencarvalho Aug 7, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm glad that I did because I found another bug!!!!

Lit still leaves its child-part boundary marker, a comment node <!--?lit$…$--> with non-empty data as a direct light-DOM child of <swc-action-button>. With no slot attribute, it lands in the default slot.

Then in slot-text-controller.ts, checkInitialContent() classifies nodes as element-or-text:

if (el.tagName) {  }              // elements
if (this.slotName) return false;   // named slots
return node.textContent ? node.textContent.trim().length > 0 : false;  // ← comment falls here

A comment node has no tagName, so it hits the last branch, and node.textContent returns the comment's data (?lit$…$) → trims to non-empty → hasLabel = true → iconOnly = false.

@rubencarvalho rubencarvalho added run_vrt Triggers the Chromatic VRT run for 2nd-gen and removed skip_vrt Skip VRT build; mark UI Tests green without running Chromatic labels Aug 7, 2026

@5t3ph 5t3ph left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, nice updates to VRTs.

One nit on placement of the avatar size cp.


/* Lets a slotted <swc-avatar> track the icon slot's own size instead of
requiring consumers to pair its size attribute with the button's size. */
--swc-avatar-size: var(--_swc-action-button-icon-size);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps make this more explicitly scoped to ::slotted(swc-avatar)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

applied the recommendation!

@rubencarvalho
rubencarvalho enabled auto-merge (squash) August 7, 2026 15:33
@rubencarvalho
rubencarvalho merged commit 4a30997 into main Aug 7, 2026
31 of 32 checks passed
@rubencarvalho
rubencarvalho deleted the rubencarvalho/avatar-action-button-demo branch August 7, 2026 15:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Component:Documentation Issues or PRs involving changes to docs or docs website. Component prefix is for Jira integration. run_vrt Triggers the Chromatic VRT run for 2nd-gen Status:Ready for review PR ready for review or re-review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants