Skip to content

feat(infield-button): Phase 2 — file structure, API, TypeScript, and accessibility#6492

Merged
Rajdeepc merged 2 commits into
mainfrom
rajdeepc/feat-infield-button-migration-phase-2
Jul 13, 2026
Merged

feat(infield-button): Phase 2 — file structure, API, TypeScript, and accessibility#6492
Rajdeepc merged 2 commits into
mainfrom
rajdeepc/feat-infield-button-migration-phase-2

Conversation

@Rajdeepc

Copy link
Copy Markdown
Contributor

Description

Scaffolds the 2nd-gen infield-button component for Phase 2 of the 1st-gen → 2nd-gen component migration. This PR creates the core and SWC file structure, establishes the base class architecture, and wires the package exports so the element is importable — but contains no production styling (that comes in Phase 5).

Motivation and context

Infield buttons are embedded inside form fields (e.g. number-field increment/decrement controls). Their migration has specific architectural constraints captured in the migration plan (PR #6441):

  • Non-focusable by design: Infield buttons are pointer-only. They are not in the tab order and not independently keyboard-focusable. The parent field owns all keyboard behavior and the visible focus ring. This is implemented by setting delegatesFocus: false on the shadow root and tabindex="-1" on the inner <button>.
  • Parent-delegated sizing: No default size is assumed. The parent field always sets the size attribute. Valid sizes are s, m, l, xl.
  • Quiet property on the base class: The quiet attribute reflects to the host for CSS :host([quiet]) targeting in Phase 5.
  • Core/SWC split: InfieldButtonBase lives in core so other form-field components can extend it without inheriting the SWC visual surface.

Related issue(s)

Screenshots (if appropriate)

N/A — scaffold only, no visual output yet.

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

  • InfieldButtonBase extends ButtonBase correctly; VALID_SIZES restricted to ['s','m','l','xl']

    1. Import InfieldButtonBase from @spectrum-web-components/core/components/infield-button
    2. Confirm InfieldButtonBase.VALID_SIZES equals ['s','m','l','xl']
    3. Confirm InfieldButtonBase.shadowRootOptions.delegatesFocus is false
  • Element registers and renders without errors

    1. Import @adobe/spectrum-wc/components/infield-button/swc-infield-button.js
    2. Place <swc-infield-button accessible-label="Increment" size="m"><sp-icon-chevron100 slot="icon"></sp-icon-chevron100></swc-infield-button> in the DOM
    3. Confirm the element renders with an inner <button tabindex="-1">
    4. Confirm Tab does not focus the button
  • quiet attribute reflects to host

    1. Set quiet property to true on the element
    2. Confirm [quiet] attribute is present on the host element

Device review

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

Accessibility testing checklist

This PR scaffolds the structural foundation only. No user-facing interaction surface is added beyond what is already covered by ButtonBase. Full accessibility testing will occur in Phase 4 (migration-a11y).

  • Keyboard — infield buttons intentionally have tabindex="-1" on the inner <button> and delegatesFocus: false on the shadow root. They must not be reachable via Tab. The parent field owns keyboard behavior.
  • Screen readeraccessible-label is forwarded to aria-label on the inner <button> via the inherited ButtonBase binding. Phase 4 will verify the full announcement behavior in context.

Creates the base class, types, concrete component, stub CSS, and entry
points for the infield-button 2nd-gen migration. The base class extends
ButtonBase with a restricted size set (s/m/l/xl), quiet property, and
delegatesFocus: false (buttons are pointer-only, not in tab order).
Wires the core package.json exports for the new component.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@Rajdeepc Rajdeepc requested a review from a team as a code owner July 10, 2026 13:26
@changeset-bot

changeset-bot Bot commented Jul 10, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 131388f

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

@github-actions

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-6492

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.

@Rajdeepc Rajdeepc self-assigned this Jul 10, 2026
@Rajdeepc Rajdeepc added 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. and removed ready-for-review labels Jul 10, 2026
@Rajdeepc Rajdeepc changed the title feat(infield-button): Phase 2 — scaffold core and SWC file structure feat(infield-button): Phase 2 — file structure, API, TypeScript, and accessibility Jul 10, 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.

One minor consideration, otherwise looks good!

?disabled=${this.disabled}
aria-label=${ifDefined(this.accessibleLabel)}
>
<slot name="icon"></slot>

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.

Do we need this to be named, or can it be a default slot?

@Rajdeepc Rajdeepc Jul 13, 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.

Yes, it needs to stay named. ButtonBase composes ObserveSlotPresence(SpectrumElement, '[slot="icon"]'), so hasIcon (i.e. this.slotContentIsPresent) only fires when content is assigned to the named slot. You are right a default-slot icon would make it permanently false, which in turn would silence the dev-mode accessible-label warning in ButtonBase.update() that guards against unlabelled icon buttons.
I am keeping it named also stays consistent with every other ButtonBase subclass and matches the 1st-gen consumer API, so there's one less migration burden either way.

@nikkimk nikkimk 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.

lgtm

@Rajdeepc Rajdeepc added the run_vrt Triggers the Chromatic VRT run for 2nd-gen label Jul 13, 2026
@Rajdeepc Rajdeepc merged commit 466a0e7 into main Jul 13, 2026
36 checks passed
@Rajdeepc Rajdeepc deleted the rajdeepc/feat-infield-button-migration-phase-2 branch July 13, 2026 06:47
@Rajdeepc Rajdeepc restored the rajdeepc/feat-infield-button-migration-phase-2 branch July 13, 2026 06:49
@Rajdeepc

Rajdeepc commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

This PR was mistakenly merged to main instead of the intended base branch swc-2105/infield-button. The changes have been reverted from main. Continued in #6498.
@5t3ph @nikkimk

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. 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.

3 participants