Skip to content

chore(action-button): migrate api and typescript code#6346

Open
cdransf wants to merge 4 commits into
cdransf/s2-action-button-migrationfrom
cdransf/s2-action-button-migration-api-typescript
Open

chore(action-button): migrate api and typescript code#6346
cdransf wants to merge 4 commits into
cdransf/s2-action-button-migrationfrom
cdransf/s2-action-button-migration-api-typescript

Conversation

@cdransf
Copy link
Copy Markdown
Member

@cdransf cdransf commented May 27, 2026

Description

Phase 3 of the swc-action-button 1st-gen → 2nd-gen washing machine migration. This PR migrates the public API and TypeScript to the 2nd-gen ActionButton class, adds runtime deprecation warnings to 1st-gen, and cleans up the structural artifact left by Phase 2 (removing the intermediate ActionButtonBase class from core so the package exports types only, as the migration plan specifies).

2nd-gen ActionButton.ts

  • value promoted to a getter/setter pair. When the stored value is empty, textContent.trim() is used as the effective value, matching the 1st-gen identity contract for swc-action-group membership.
  • aria-haspopup and aria-expanded forwarding: private @property fields observe those attributes on the host and forward them into the inner <button>, enabling popup disclosure patterns without a MutationObserver.
  • @cssprop entries updated to use logical property names (--swc-action-button-min-block-size, --swc-action-button-border-radius); two incorrect entries (--swc-action-button-edge-to-text, --swc-action-button-edge-to-visual) removed.
  • size override (added in structural fix) moves the full xsxl range onto the SWC class via VALID_SIZES static, a getter/setter, and a _size backing field. An update() override counteracts SizedMixin's auto-reflect of size="m" for cases where no size was explicitly set.

1st-gen ActionButton.ts

  • @deprecated JSDoc added to emphasized, hold-affordance, selected, and toggles.
  • Runtime window.__swc.warn({ level: 'deprecation' }) calls added inside existing code paths in updated() for each deprecated property.

Structural fix (squashed from Phase 2 branch)

  • Deleted ActionButton.base.ts from core/components/action-button/; the package now exports types only, matching the migration plan architecture table.
  • ActionButton.ts (SWC) extends ButtonBase directly.

Motivation and context

This is Phase 3 of the action button migration as tracked in the 2nd-gen component migration workstream. The migration plan was merged in #6327 and the structural foundation was established in the Phase 2 PR.

The value getter/setter fallback and the aria-haspopup/aria-expanded forwarding are required for swc-action-group integration and popup disclosure patterns respectively; both are specified in the migration plan.

SWC-2043

Related issue(s)

  • Depends on Phase 2 structural PR (branch cdransf/s2-action-button-migration-structure)

Screenshots (if appropriate)

N/A — TypeScript and API changes only; no visual output in this phase.

Author's checklist

  • I have read the CONTRIBUTING and PULL_REQUESTS documents.
  • I have reviewed 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

  • value fallback behavior

    1. Render a <swc-action-button> with no value attribute set and text content "Edit"
    2. Read element.value in the console
    3. Expect "Edit" (falls back to textContent.trim())
  • value explicit set

    1. Render a <swc-action-button value="edit-action">Edit</swc-action-button>
    2. Read element.value in the console
    3. Expect "edit-action" (explicit value takes precedence)
  • aria-haspopup / aria-expanded forwarding

    1. Render <swc-action-button aria-haspopup="menu" aria-expanded="false">Open menu</swc-action-button>
    2. Inspect the inner <button> in DevTools
    3. Expect aria-haspopup="menu" and aria-expanded="false" present on the inner <button>
  • Size attribute absent by default

    1. Render <swc-action-button>Edit</swc-action-button> with no size attribute
    2. Inspect the host element
    3. Expect no size attribute on the host (the SizedMixin workaround suppresses auto-reflect of size="m")
  • 1st-gen deprecation warnings

    1. Enable debug mode (window.__swc = { DEBUG: true })
    2. Set emphasized, selected, toggles, or hold-affordance on a <sp-action-button>
    3. Expect a deprecation-level window.__swc.warn console message for each property

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. Go to the swc-action-button Storybook stories (Playground story)
    2. Press Tab to move focus to the button; confirm focus ring is visible
    3. Press Enter or Space; confirm the button activates (click handler fires)
    4. Set disabled on the button; confirm it is no longer reachable via Tab
    5. Set aria-haspopup="menu" and aria-expanded="false" on the host; confirm focus and activation still work normally
  • Screen reader (required — document steps below)

    1. Open the Playground story with VoiceOver (macOS) or NVDA (Windows)
    2. Tab to the button; confirm it is announced as "button" with its visible label
    3. With disabled set, confirm the button is announced as dimmed/unavailable
    4. With aria-haspopup="menu" and aria-expanded="false" set on the host, confirm the inner button is announced with "has popup, menu" and "collapsed"
    5. With pending set, confirm aria-disabled="true" and the pending accessible name are announced

@cdransf cdransf requested a review from a team as a code owner May 27, 2026 17:55
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented May 27, 2026

⚠️ No Changeset found

Latest commit: a711de4

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.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

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

@cdransf cdransf self-assigned this May 27, 2026
@cdransf cdransf added Component:Action button 2nd gen These issues or PRs map to our 2nd generation work to modernizing infrastructure. labels May 27, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 27, 2026

📚 Branch Preview Links

🔍 First Generation 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-6346

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.

@cdransf cdransf force-pushed the cdransf/s2-action-button-migration-api-typescript branch from 424b999 to c61ea0f Compare May 27, 2026 18:22
@cdransf cdransf force-pushed the cdransf/s2-action-button-migration-structure branch from 9aef2fa to a7f319d Compare May 27, 2026 20:23
@cdransf cdransf force-pushed the cdransf/s2-action-button-migration-api-typescript branch 2 times, most recently from 3241537 to bcb60f2 Compare May 27, 2026 20:37
@cdransf cdransf force-pushed the cdransf/s2-action-button-migration-api-typescript branch from ad79936 to bcb60f2 Compare May 28, 2026 15:23
Base automatically changed from cdransf/s2-action-button-migration-structure to cdransf/s2-action-button-migration May 28, 2026 16:07
@cdransf cdransf force-pushed the cdransf/s2-action-button-migration-api-typescript branch 2 times, most recently from 7edc2cb to 516540b Compare May 28, 2026 17:09
Comment thread 2nd-gen/packages/swc/components/action-button/ActionButton.ts Outdated
Comment thread 2nd-gen/packages/swc/components/action-button/ActionButton.ts Outdated
Comment thread 2nd-gen/packages/swc/components/action-button/ActionButton.ts Outdated
| TBD | Badge slot and corner-overlay lockup (A6) | Icon+Badge and Avatar+Badge produce a distinct visual lockup. Badge text accessible name composition requires a11y review (@nikkimk) before shipping. | [A6](#additive--ships-when-ready-zero-breakage-for-consumers-already-on-2nd-gen) |
| TBD | Avatar slot and accessible name composition (A7) | Avatar accessible name and its relationship to the button's composite accessible name requires a11y review (@nikkimk) before shipping. | [A7](#additive--ships-when-ready-zero-breakage-for-consumers-already-on-2nd-gen) |
| TBD (under SWC-2039) | Cross-root ARIA mapping | Shared with `swc-button` dependency on `ElementInternals` / tooling path. | [Deferred semantics note](#deferred-semantics-note-2nd-gen) |
| Phase 4 | `aria-haspopup` / `aria-expanded` host-attribute retention | Phase 3 forwards these to the inner `<button>` via `@property` observation but does not remove the originals from the host element. ATs in browse mode may read them from the host. Proper fix (guard flag + `attributeChangedCallback` override, or `MutationObserver`) should be addressed in Phase 4 alongside a11y review. | [2nd-gen API decisions — passthrough host attributes](#properties--attributes) |
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.

[nit] My understanding is that AT would skip any ARIA that isn't compatible with the role. So since the host won't have the button role, these ARIA attributes also won't be doing any harm. What might be interesting is if having or not having them would cause issues with us testing relationships such as with Menu.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Ah yeah, it will ignore those — stripping those attributes keeps the host clean for tooling and avoids any ambiguity if the host is given a role in the future. ✨

@5t3ph 5t3ph self-assigned this May 28, 2026
@cdransf cdransf added Status:Ready for review PR ready for review or re-review. Status:Addressing feedback PR owner is addressing review comments and will change label back to "Ready for review" when ready. and removed Status:Ready for review PR ready for review or re-review. labels May 28, 2026
@cdransf cdransf force-pushed the cdransf/s2-action-button-migration-api-typescript branch from b54227d to 2d4586e Compare May 28, 2026 21:51
@cdransf cdransf requested a review from 5t3ph May 28, 2026 21:51
@cdransf cdransf added Status:Ready for re-review PR has had its feedback addressed and is once again ready for review. and removed Status:Addressing feedback PR owner is addressing review comments and will change label back to "Ready for review" when ready. labels May 28, 2026
@cdransf cdransf force-pushed the cdransf/s2-action-button-migration branch from 589d0c6 to 4f6ac56 Compare May 29, 2026 15:36
@cdransf cdransf force-pushed the cdransf/s2-action-button-migration-api-typescript branch from 2d4586e to 8ef7445 Compare May 29, 2026 15:36
@cdransf cdransf force-pushed the cdransf/s2-action-button-migration branch from 4f6ac56 to 578f5dd Compare May 29, 2026 19:20
@cdransf cdransf force-pushed the cdransf/s2-action-button-migration-api-typescript branch from 8ef7445 to a711de4 Compare May 29, 2026 19:25
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 button Status:Ready for re-review PR has had its feedback addressed and is once again ready for review.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants