Skip to content

feat(actiongroup): full fidelity styles - #6484

Open
rise-erpelding wants to merge 16 commits into
swc-2212/migrate-action-groupfrom
swc-2216/action-group-full-fidelity
Open

feat(actiongroup): full fidelity styles#6484
rise-erpelding wants to merge 16 commits into
swc-2212/migrate-action-groupfrom
swc-2216/action-group-full-fidelity

Conversation

@rise-erpelding

@rise-erpelding rise-erpelding commented Jul 8, 2026

Copy link
Copy Markdown
Collaborator

Description

Phase 5 (styling / full fidelity) of the swc-action-group migration, per SWC-2216.

  • Stories: Extended action-group.stories.ts to full Phase 5 scope: Anatomy, Sizes, Orientations, Static colors, Disabled, Compact (horizontal and vertical shown side by side), Quiet (demonstrates the compact-join being disabled when both are set), Justified.
  • action-group.css: Built out from the Phase 5 stub — flex layout with size-based gap (spacing-100 default, spacing-75 at xs/s, translated from spectrum-two's actiongroup/index.css); orientation="vertical" column stacking; justified equal-fill via flex: 1 1 0%; compact border-join implemented via a CSS custom-property cascade onto --swc-action-button-border-*-radius (interior corners zeroed per child position, outer corners left at the button's natural radius); compact has no effect when quiet is also set, matching 1st-gen. Focus-ring stacking in compact mode uses :focus-within rather than :focus-visibledelegatesFocus retargets :focus/:focus-within onto the custom-element host in Chromium but not :focus-visible, so the original :focus-visible selector never matched and the z-index escalation was dead, letting a focused button's ring get covered by an adjacent button's border (resolves SWC-1342).
  • ActionGroup.ts: Wrapped the slot in an internal .swc-ActionGroup element per the migration plan's Phase 5 checklist; added the @cssprop --swc-action-group-gap doc tag.
  • action-button.css / ActionButton.ts (prerequisite, per migration plan): Exposed four logical corner-radius custom properties (--swc-action-button-border-{start-start,start-end,end-start,end-end}-radius), each falling back to the existing --swc-action-button-border-radius, so action-group's compact mode can override individual corners without hardcoding a size-specific token. Also added inline-size: 100% to .swc-ActionButton — the shadow-DOM <button> was shrink-wrapping to its own content regardless of how wide an ancestor flex layout stretched the custom-element host, so vertical and vertical + compact action groups rendered with visibly unequal button widths even though the (invisible) host boxes were already stretched correctly.

Motivation and context

Implements SWC-2216 (Phase 5: styling) of the Action Group 2nd-gen migration epic (SWC-2212), translating the spectrum-two S2 source (components/actiongroup/index.css) into the 2nd-gen token-based CSS structure per the approved migration plan. This is the last functional gap before Phase 6 (testing) and Phase 7 (documentation) — API and accessibility semantics were completed in SWC-2215.

Related issue(s)

  • SWC-2212: Gen2 migration: Action Group (epic)
  • SWC-2216: Migrate rendering and styles (Phase 5)
  • SWC-1342: sp-action-group sets z-index on focused button, hiding focus indicator (resolved)

Screenshots (if appropriate)

  • Storybook — Compact story: horizontal and vertical variants side by side, showing joined borders with outer-corner-only rounding.
  • Storybook — Orientations, Sizes, Static colors, Justified stories.

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.

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

  • Compact join renders with correct corner radii

    1. Open the Action Group Compact story in the 2nd-gen Storybook (yarn storybook from 2nd-gen/)
    2. Inspect both the horizontal and vertical groups
    3. Expect: shared borders between adjacent buttons collapse to a single 1px line; only the outer corners of the strip are rounded; interior corners are square
  • Compact focus ring is never clipped by a neighbor

    1. In the Compact story, Tab into the horizontal group, then press to move through each button
    2. Repeat for the vertical group with
    3. Expect: at every position (first, middle, last), the focused button's complete rectangular focus ring is visible and unobstructed by the adjacent button's border
  • Vertical and vertical + compact groups have equal-width buttons

    1. In the Orientations story and the vertical group in the Compact story, compare button widths visually and via DevTools (getBoundingClientRect() on each swc-action-button's inner <button>)
    2. Expect: all buttons in a given vertical group are the same width, matching the widest label
  • Quiet disables the compact join

    1. Open the Quiet story
    2. Compare the quiet-only group to the quiet + compact group
    3. Expect: both render identically — no border join, no corner-radius reset, regardless of compact
  • Justified fills the available width

    1. Open the Justified story
    2. Expect: all three buttons expand equally to fill the constrained container width, with even gaps
  • Standalone and horizontal action-button usage is unaffected

    1. Open the Action Button stories (all variants) and the Action Group Playground/Overview stories in default (horizontal) orientation
    2. Expect: no width or layout regression from the inline-size: 100% change on .swc-ActionButton — standalone buttons and horizontal groups still size to content, not to 100% of some ancestor

Device review

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

Accessibility testing checklist

Required: Complete each applicable item and document your testing steps (replace the placeholders with your component-specific instructions).

  • Keyboard (required — document steps below) — What to test for: Focus order is logical; Tab reaches the component and all interactive descendants; Enter/Space activate where appropriate; arrow keys work for tabs, menus, sliders, etc.; no focus traps; Escape dismisses when applicable; focus indicator is visible.

    1. Open the Action Group Compact story in 2nd-gen Storybook
    2. Tab into the horizontal group — expect: focus lands on the first button with a fully visible focus ring
    3. Press to move to the second, then third button — expect: at each step, the focused button's ring is complete and not covered by either neighbor
    4. Repeat steps 2–3 in the vertical group using
    5. No regression to Tab/Arrow behavior established in SWC-2215 (one Tab stop into the strip; arrow keys move among items; wraps at the ends)
  • Screen reader (required — document steps below) — What to test for: Role and name are announced correctly; state changes (e.g. expanded, selected) are announced; labels and relationships are clear; no unnecessary or duplicate announcements.

    1. Open the Action Group Compact and Justified stories with VoiceOver (macOS) or NVDA (Windows)
    2. Navigate through the group — expect: no change in announcements from the non-styled group (styling-only phase); group and button roles/names announce exactly as established in SWC-2215

@changeset-bot

changeset-bot Bot commented Jul 8, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: aface6f

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

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

Comment thread 2nd-gen/packages/swc/components/action-button/action-button.css
@rise-erpelding
rise-erpelding changed the base branch from main to swc-2212/migrate-action-group July 8, 2026 16:04
@github-actions

github-actions Bot commented Jul 8, 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-6484

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.

@coveralls

Copy link
Copy Markdown
Collaborator

Coverage Report for CI Build 28956788727

Warning

No base build found for commit a969bf6 on swc-2212/migrate-action-group.
Coverage changes can't be calculated without a base build.
If a base build is processing, this comment will update automatically when it completes.

Coverage: 96.262%

Details

  • Patch coverage: 86 of 86 lines across 1 file are fully covered (100%).

Uncovered Changes

No uncovered changes found.

Coverage Regressions

Requires a base build to compare against. How to fix this →


Coverage Stats

Coverage Status
Relevant Lines: 39252
Covered Lines: 37986
Line Coverage: 96.77%
Relevant Branches: 6466
Covered Branches: 6023
Branch Coverage: 93.15%
Branches in Coverage %: Yes
Coverage Strength: 460.37 hits per line

💛 - Coveralls

@rise-erpelding
rise-erpelding force-pushed the swc-2212/migrate-action-group branch from 91f0ed3 to e109f49 Compare July 14, 2026 12:31
@rise-erpelding
rise-erpelding force-pushed the swc-2212/migrate-action-group branch from 65536e6 to 685f924 Compare July 27, 2026 18:02
@rise-erpelding
rise-erpelding force-pushed the swc-2216/action-group-full-fidelity branch 5 times, most recently from 528f6f7 to ca47cee Compare July 27, 2026 18:35

export const Sizes: Story = {
render: () => html`
render: (args) => html`

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

The common convention in most of our other migrated components is to thread the args.

Comment on lines +79 to +84
* Note: this property does NOT set `aria-orientation` on the host.
* `aria-orientation` is only a supported ARIA attribute on roles that
* expose it (`toolbar`, `listbox`, `menu`, etc.) — `role="group"` does
* not, regardless of the roving-tabindex keyboard model implemented in
* JS. Setting it fails axe's `aria-allowed-attr` rule. Matches the same
* decision already made for `swc-button-group`.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is an a11y change after it surfaced that button group also does not set aria-orientation, @nikkimk would you be able to confirm that this change makes sense?

gap: var(--swc-action-button-gap, token("base-gap-medium"));
align-items: center;
justify-content: center;
inline-size: 100%;

@rise-erpelding rise-erpelding Jul 28, 2026

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I would love opinions about this change. It stretches the action group buttons when the action group is vertical so that all the buttons are the same width. An align-items: stretch on the .swc-ActionGroup doesn't work without it (or, doesn't have a visible effect) because it can't reach into the inner shadow DOM of the action button.

The inline-size: 100% isn't changing any stories on action button as far as I'm aware (but I will run VRTs to confirm), it only has an effect here in a vertical action group where the align-items: stretch on action group (no align-items: stretch is explicitly set, but that is the default behavior when we set .swc-ActionGroup to display: flex).

Or, TL;DR, in pictures, here's the vertical action group with inline-size: 100%:

Image

And without inline-size: 100%:

Image

And even more notable, without inline-size: 100% and with the compact variant set:

Image

I would think we'd prefer the aligned version with inline-size: 100, but also want to note that React's doesn't line up nicely either:

Image

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.

I don't have any objections on that. I think setting inline-size: 100% makes sense to fill the space in a flex box for each button. Playing with parent container width so far in the storybook container doesn't change the action button visually

@rise-erpelding
rise-erpelding marked this pull request as ready for review July 29, 2026 18:16
@rise-erpelding
rise-erpelding requested a review from a team as a code owner July 29, 2026 18:16
@rise-erpelding rise-erpelding added Component:Action group Status:Ready for review PR ready for review or re-review. 2nd gen These issues or PRs map to our 2nd generation work to modernizing infrastructure. labels Jul 29, 2026
@rise-erpelding
rise-erpelding force-pushed the swc-2212/migrate-action-group branch from 2022776 to 8abe6f3 Compare July 29, 2026 18:36
@rise-erpelding
rise-erpelding force-pushed the swc-2216/action-group-full-fidelity branch from 21f85fd to 8a31a60 Compare July 29, 2026 18:36
@aramos-adobe aramos-adobe self-assigned this Jul 29, 2026
Comment thread 2nd-gen/packages/swc/components/action-group/action-group.css Outdated

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.

The outline in transition-property shows the black outline for a quick glance here. Removing it doesn't show this.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

I added a commit to remove it, but this prevents it from transitioning so there's no animation on it. No animation feels like maybe it's slightly better than flash of black outline 🤷‍♀️

The black outline is a known issue that needs more digging, since action button has it but other button components don't and it's unclear why, it's documented in SWC-2308

};
Quiet.storyName = 'Quiet (compact join disabled)';

export const Justified: Story = {

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.

When adding extra text in one of the buttons it breaks the justified layout here.

ActionButton group in RSP shows in truncation in the horizontal layout (and it also show in vertical layout but doesn't), but we don't have truncation support for swc-action-button even though swc-button has an opt-in adding truncate property.

I think maaayyybee truncate prop should be automatically for swc-action-group, because adding it for every button manually would be alot for a consumer.

Screenshot 2026-07-30 at 2.34.00 PM.png

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

It does seem like addressing this might be dependent on adding truncated behavior to action button? So that the buttons are able to shrink as needed.

Although, FWIW, I see Gen 1's justified action group also breaks like this when the buttons aren't all able to fit on one line, although the container has to be really small before it breaks.
image

}

/* ── Sub-elements ─────────────────────────────────── */

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.

:host([truncate]) .swc-ActionButton-label {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

You also probably have to add a truncate boolean property to ActionButton class as well

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Hmmm, we don't have truncate available on action button, do we? I think I'd want to do some more research on this or possibly defer an API change to action button for now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

2nd gen These issues or PRs map to our 2nd generation work to modernizing infrastructure. Component:Action group Status:Ready for review PR ready for review or re-review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants